mirror of
https://github.com/nushell/nushell.git
synced 2025-07-02 23:51:49 +02:00
Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
d297199d7c | |||
17a433996e | |||
b9bb4692a4 | |||
d05dcdda02 | |||
27fe356214 | |||
fc44df1e45 | |||
77f915befe | |||
a5f7600f6f | |||
7eb8634ad7 | |||
452d8c06e9 | |||
48f535f02e | |||
43c10b0625 | |||
328b09fe04 | |||
15d49e4096 | |||
3ef53fe2cd | |||
7d8e759e98 | |||
69b3be61a4 | |||
79476a5cb2 | |||
f449baf8de | |||
5ff4bcfb7a | |||
98537ce8b7 | |||
d2a00a2daa | |||
f22938fc4a | |||
1e67ae8e94 | |||
c012d648fb | |||
67acaae53c | |||
e3da546e23 | |||
e5b136f70d | |||
058ef69da3 | |||
2a483531a4 | |||
05202671db | |||
8509873043 | |||
57a2d695e2 | |||
0b5ab1ef22 | |||
2eac79569c | |||
ac578b8491 | |||
5183fd25bb | |||
10f5a8ef78 |
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -23,8 +23,25 @@ A clear and concise description of what you expected to happen.
|
|||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Configuration (please complete the following information):**
|
**Configuration (please complete the following information):**
|
||||||
- OS (e.g. Windows):
|
|
||||||
- Nu version (you can use the `version` command to find out):
|
|
||||||
- Optional features (if any):
|
|
||||||
|
|
||||||
Add any other context about the problem here.
|
Run `version | pivot` and paste the output to show OS, features, etc.
|
||||||
|
|
||||||
|
```
|
||||||
|
> version | pivot
|
||||||
|
╭───┬────────────────────┬───────────────────────────────────────────────────────────────────────╮
|
||||||
|
│ # │ Column0 │ Column1 │
|
||||||
|
├───┼────────────────────┼───────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ 0 │ version │ 0.24.1 │
|
||||||
|
│ 1 │ build_os │ macos-x86_64 │
|
||||||
|
│ 2 │ rust_version │ rustc 1.48.0 │
|
||||||
|
│ 3 │ cargo_version │ cargo 1.48.0 │
|
||||||
|
│ 4 │ pkg_version │ 0.24.1 │
|
||||||
|
│ 5 │ build_time │ 2020-12-18 09:54:09 │
|
||||||
|
│ 6 │ build_rust_channel │ release │
|
||||||
|
│ 7 │ features │ ctrlc, default, directories, dirs, git, ichwh, ptree, rich-benchmark, │
|
||||||
|
│ │ │ rustyline, term, uuid, which, zip │
|
||||||
|
╰───┴────────────────────┴───────────────────────────────────────────────────────────────────────╯
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
**Add any other context about the problem here.**
|
||||||
|
562
Cargo.lock
generated
562
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
56
Cargo.toml
56
Cargo.toml
@ -10,7 +10,7 @@ license = "MIT"
|
|||||||
name = "nu"
|
name = "nu"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/nushell/nushell"
|
repository = "https://github.com/nushell/nushell"
|
||||||
version = "0.24.0"
|
version = "0.25.0"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["crates/*/"]
|
members = ["crates/*/"]
|
||||||
@ -18,33 +18,33 @@ members = ["crates/*/"]
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cli = {version = "0.24.0", path = "./crates/nu-cli"}
|
nu-cli = {version = "0.25.0", path = "./crates/nu-cli"}
|
||||||
nu-data = {version = "0.24.0", path = "./crates/nu-data"}
|
nu-data = {version = "0.25.0", path = "./crates/nu-data"}
|
||||||
nu-errors = {version = "0.24.0", path = "./crates/nu-errors"}
|
nu-errors = {version = "0.25.0", path = "./crates/nu-errors"}
|
||||||
nu-parser = {version = "0.24.0", path = "./crates/nu-parser"}
|
nu-parser = {version = "0.25.0", path = "./crates/nu-parser"}
|
||||||
nu-plugin = {version = "0.24.0", path = "./crates/nu-plugin"}
|
nu-plugin = {version = "0.25.0", path = "./crates/nu-plugin"}
|
||||||
nu-protocol = {version = "0.24.0", path = "./crates/nu-protocol"}
|
nu-protocol = {version = "0.25.0", path = "./crates/nu-protocol"}
|
||||||
nu-source = {version = "0.24.0", path = "./crates/nu-source"}
|
nu-source = {version = "0.25.0", path = "./crates/nu-source"}
|
||||||
nu-value-ext = {version = "0.24.0", path = "./crates/nu-value-ext"}
|
nu-value-ext = {version = "0.25.0", path = "./crates/nu-value-ext"}
|
||||||
|
|
||||||
nu_plugin_binaryview = {version = "0.24.0", path = "./crates/nu_plugin_binaryview", optional = true}
|
nu_plugin_binaryview = {version = "0.25.0", path = "./crates/nu_plugin_binaryview", optional = true}
|
||||||
nu_plugin_chart = {version = "0.24.0", path = "./crates/nu_plugin_chart", optional = true}
|
nu_plugin_chart = {version = "0.25.0", path = "./crates/nu_plugin_chart", optional = true}
|
||||||
nu_plugin_fetch = {version = "0.24.0", path = "./crates/nu_plugin_fetch", optional = true}
|
nu_plugin_fetch = {version = "0.25.0", path = "./crates/nu_plugin_fetch", optional = true}
|
||||||
nu_plugin_from_bson = {version = "0.24.0", path = "./crates/nu_plugin_from_bson", optional = true}
|
nu_plugin_from_bson = {version = "0.25.0", path = "./crates/nu_plugin_from_bson", optional = true}
|
||||||
nu_plugin_from_sqlite = {version = "0.24.0", path = "./crates/nu_plugin_from_sqlite", optional = true}
|
nu_plugin_from_sqlite = {version = "0.25.0", path = "./crates/nu_plugin_from_sqlite", optional = true}
|
||||||
nu_plugin_inc = {version = "0.24.0", path = "./crates/nu_plugin_inc", optional = true}
|
nu_plugin_inc = {version = "0.25.0", path = "./crates/nu_plugin_inc", optional = true}
|
||||||
nu_plugin_match = {version = "0.24.0", path = "./crates/nu_plugin_match", optional = true}
|
nu_plugin_match = {version = "0.25.0", path = "./crates/nu_plugin_match", optional = true}
|
||||||
nu_plugin_post = {version = "0.24.0", path = "./crates/nu_plugin_post", optional = true}
|
nu_plugin_post = {version = "0.25.0", path = "./crates/nu_plugin_post", optional = true}
|
||||||
nu_plugin_ps = {version = "0.24.0", path = "./crates/nu_plugin_ps", optional = true}
|
nu_plugin_ps = {version = "0.25.0", path = "./crates/nu_plugin_ps", optional = true}
|
||||||
nu_plugin_s3 = {version = "0.24.0", path = "./crates/nu_plugin_s3", optional = true}
|
nu_plugin_s3 = {version = "0.25.0", path = "./crates/nu_plugin_s3", optional = true}
|
||||||
nu_plugin_start = {version = "0.24.0", path = "./crates/nu_plugin_start", optional = true}
|
nu_plugin_start = {version = "0.25.0", path = "./crates/nu_plugin_start", optional = true}
|
||||||
nu_plugin_sys = {version = "0.24.0", path = "./crates/nu_plugin_sys", optional = true}
|
nu_plugin_sys = {version = "0.25.0", path = "./crates/nu_plugin_sys", optional = true}
|
||||||
nu_plugin_textview = {version = "0.24.0", path = "./crates/nu_plugin_textview", optional = true}
|
nu_plugin_textview = {version = "0.25.0", path = "./crates/nu_plugin_textview", optional = true}
|
||||||
nu_plugin_to_bson = {version = "0.24.0", path = "./crates/nu_plugin_to_bson", optional = true}
|
nu_plugin_to_bson = {version = "0.25.0", path = "./crates/nu_plugin_to_bson", optional = true}
|
||||||
nu_plugin_to_sqlite = {version = "0.24.0", path = "./crates/nu_plugin_to_sqlite", optional = true}
|
nu_plugin_to_sqlite = {version = "0.25.0", path = "./crates/nu_plugin_to_sqlite", optional = true}
|
||||||
nu_plugin_tree = {version = "0.24.0", path = "./crates/nu_plugin_tree", optional = true}
|
nu_plugin_tree = {version = "0.25.0", path = "./crates/nu_plugin_tree", optional = true}
|
||||||
nu_plugin_xpath = {version = "0.24.0", path = "./crates/nu_plugin_xpath", optional = true}
|
nu_plugin_xpath = {version = "0.25.0", path = "./crates/nu_plugin_xpath", optional = true}
|
||||||
nu_plugin_selector = {version = "0.24.0", path = "./crates/nu_plugin_selector", optional = true}
|
nu_plugin_selector = {version = "0.25.0", path = "./crates/nu_plugin_selector", optional = true}
|
||||||
|
|
||||||
# Required to bootstrap the main binary
|
# Required to bootstrap the main binary
|
||||||
clap = "2.33.3"
|
clap = "2.33.3"
|
||||||
@ -56,7 +56,7 @@ itertools = "0.9.0"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
dunce = "1.0.1"
|
dunce = "1.0.1"
|
||||||
nu-test-support = {version = "0.24.0", path = "./crates/nu-test-support"}
|
nu-test-support = {version = "0.25.0", path = "./crates/nu-test-support"}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ To install Nu via cargo (make sure you have installed [rustup](https://rustup.rs
|
|||||||
cargo install nu
|
cargo install nu
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also build Nu yourself with all the bells and whistles (be sure to have installed the [dependencies](https://www.nushell.sh/book/en/installation.html#dependencies) for your platform), once you have checked out this repo with git:
|
You can also build Nu yourself with all the bells and whistles (be sure to have installed the [dependencies](https://www.nushell.sh/book/installation.html#dependencies) for your platform), once you have checked out this repo with git:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo build --workspace --features=extra
|
cargo build --workspace --features=extra
|
||||||
@ -234,7 +234,7 @@ Here we use the variable `$it` to refer to the value being piped to the external
|
|||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
Nu has early support for configuring the shell. You can refer to the book for a list of [all supported variables](https://www.nushell.sh/book/en/configuration.html).
|
Nu has early support for configuring the shell. You can refer to the book for a list of [all supported variables](https://www.nushell.sh/book/configuration.html).
|
||||||
|
|
||||||
To set one of these variables, you can use `config set`. For example:
|
To set one of these variables, you can use `config set`. For example:
|
||||||
|
|
||||||
|
@ -1,28 +1,31 @@
|
|||||||
[package]
|
[package]
|
||||||
authors = ["The Nu Project Contributors"]
|
authors = ["The Nu Project Contributors"]
|
||||||
|
build = "build.rs"
|
||||||
description = "CLI for nushell"
|
description = "CLI for nushell"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-cli"
|
name = "nu-cli"
|
||||||
version = "0.24.0"
|
version = "0.25.0"
|
||||||
build = "build.rs"
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-data = {version = "0.24.0", path = "../nu-data"}
|
nu-data = {version = "0.25.0", path = "../nu-data"}
|
||||||
nu-errors = {version = "0.24.0", path = "../nu-errors"}
|
nu-errors = {version = "0.25.0", path = "../nu-errors"}
|
||||||
nu-json = {version = "0.24.0", path = "../nu-json"}
|
nu-json = {version = "0.25.0", path = "../nu-json"}
|
||||||
nu-parser = {version = "0.24.0", path = "../nu-parser"}
|
nu-parser = {version = "0.25.0", path = "../nu-parser"}
|
||||||
nu-plugin = {version = "0.24.0", path = "../nu-plugin"}
|
nu-plugin = {version = "0.25.0", path = "../nu-plugin"}
|
||||||
nu-protocol = {version = "0.24.0", path = "../nu-protocol"}
|
nu-protocol = {version = "0.25.0", path = "../nu-protocol"}
|
||||||
nu-source = {version = "0.24.0", path = "../nu-source"}
|
nu-source = {version = "0.25.0", path = "../nu-source"}
|
||||||
nu-table = {version = "0.24.0", path = "../nu-table"}
|
nu-stream = {version = "0.25.0", path = "../nu-stream"}
|
||||||
nu-test-support = {version = "0.24.0", path = "../nu-test-support"}
|
nu-table = {version = "0.25.0", path = "../nu-table"}
|
||||||
nu-value-ext = {version = "0.24.0", path = "../nu-value-ext"}
|
nu-test-support = {version = "0.25.0", path = "../nu-test-support"}
|
||||||
|
nu-value-ext = {version = "0.25.0", path = "../nu-value-ext"}
|
||||||
|
|
||||||
|
Inflector = "0.11"
|
||||||
ansi_term = "0.12.1"
|
ansi_term = "0.12.1"
|
||||||
|
arboard = {version = "1.1.0", optional = true}
|
||||||
async-recursion = "0.3.1"
|
async-recursion = "0.3.1"
|
||||||
async-trait = "0.1.40"
|
async-trait = "0.1.40"
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
@ -33,7 +36,6 @@ calamine = "0.16.1"
|
|||||||
chrono = {version = "0.4.15", features = ["serde"]}
|
chrono = {version = "0.4.15", features = ["serde"]}
|
||||||
chrono-tz = "0.5.3"
|
chrono-tz = "0.5.3"
|
||||||
clap = "2.33.3"
|
clap = "2.33.3"
|
||||||
clipboard = {version = "0.5.0", optional = true}
|
|
||||||
codespan-reporting = "0.9.5"
|
codespan-reporting = "0.9.5"
|
||||||
csv = "1.1.3"
|
csv = "1.1.3"
|
||||||
ctrlc = {version = "3.1.6", optional = true}
|
ctrlc = {version = "3.1.6", optional = true}
|
||||||
@ -47,17 +49,16 @@ encoding_rs = "0.8.24"
|
|||||||
filesize = "0.2.0"
|
filesize = "0.2.0"
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
futures = {version = "0.3.5", features = ["compat", "io-compat"]}
|
futures = {version = "0.3.5", features = ["compat", "io-compat"]}
|
||||||
futures_codec = "0.4.1"
|
|
||||||
futures-util = "0.3.5"
|
futures-util = "0.3.5"
|
||||||
|
futures_codec = "0.4.1"
|
||||||
getset = "0.1.1"
|
getset = "0.1.1"
|
||||||
git2 = {version = "0.13.11", default_features = false, optional = true}
|
git2 = {version = "0.13.11", default_features = false, optional = true}
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
heim = {version = "0.1.0-beta.3", optional = true}
|
heim = {version = "0.1.0-rc.1", optional = true}
|
||||||
htmlescape = "0.3.1"
|
htmlescape = "0.3.1"
|
||||||
ical = "0.6.0"
|
ical = "0.6.0"
|
||||||
ichwh = {version = "0.3.4", optional = true}
|
ichwh = {version = "0.3.4", optional = true}
|
||||||
indexmap = {version = "1.6.0", features = ["serde-1"]}
|
indexmap = {version = "1.6.0", features = ["serde-1"]}
|
||||||
Inflector = "0.11"
|
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
lazy_static = "1.*"
|
lazy_static = "1.*"
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
@ -96,7 +97,7 @@ titlecase = "1.0"
|
|||||||
toml = "0.5.6"
|
toml = "0.5.6"
|
||||||
trash = {version = "1.2.0", optional = true}
|
trash = {version = "1.2.0", optional = true}
|
||||||
unicode-segmentation = "1.6.0"
|
unicode-segmentation = "1.6.0"
|
||||||
uom = {version = "0.28.0", features = ["f64", "try-from"]}
|
uom = {version = "0.30.0", features = ["f64", "try-from"]}
|
||||||
url = "2.1.1"
|
url = "2.1.1"
|
||||||
uuid_crate = {package = "uuid", version = "0.8.1", features = ["v4"], optional = true}
|
uuid_crate = {package = "uuid", version = "0.8.1", features = ["v4"], optional = true}
|
||||||
which = {version = "4.0.2", optional = true}
|
which = {version = "4.0.2", optional = true}
|
||||||
@ -115,17 +116,17 @@ users = "0.10.0"
|
|||||||
[dependencies.rusqlite]
|
[dependencies.rusqlite]
|
||||||
features = ["bundled", "blob"]
|
features = ["bundled", "blob"]
|
||||||
optional = true
|
optional = true
|
||||||
version = "0.24.0"
|
version = "0.24.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
shadow-rs = "0.3.20"
|
shadow-rs = "0.5"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
quickcheck = "0.9.2"
|
quickcheck = "0.9.2"
|
||||||
quickcheck_macros = "0.9.1"
|
quickcheck_macros = "0.9.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
clipboard-cli = ["clipboard"]
|
clipboard-cli = ["arboard"]
|
||||||
rich-benchmark = ["heim"]
|
rich-benchmark = ["heim"]
|
||||||
rustyline-support = ["rustyline"]
|
rustyline-support = ["rustyline"]
|
||||||
stable = []
|
stable = []
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
fn main() -> shadow_rs::SdResult<()> {
|
fn main() -> shadow_rs::SdResult<()> {
|
||||||
let src_path = std::env::var("CARGO_MANIFEST_DIR")?;
|
shadow_rs::new()
|
||||||
let out_path = std::env::var("OUT_DIR")?;
|
|
||||||
shadow_rs::Shadow::build(src_path, out_path)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
use crate::commands::classified::block::run_block;
|
use crate::commands::classified::block::run_block;
|
||||||
use crate::commands::classified::maybe_text_codec::{MaybeTextCodec, StringOrBinary};
|
use crate::commands::default_context::create_default_context;
|
||||||
use crate::evaluation_context::EvaluationContext;
|
use crate::evaluation_context::EvaluationContext;
|
||||||
use crate::path::canonicalize;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::script::{print_err, run_script_standalone};
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub(crate) use crate::script::{process_script, LineResult};
|
||||||
|
|
||||||
#[cfg(feature = "rustyline-support")]
|
#[cfg(feature = "rustyline-support")]
|
||||||
use crate::shell::Helper;
|
use crate::shell::Helper;
|
||||||
use crate::EnvironmentSyncer;
|
use crate::EnvironmentSyncer;
|
||||||
use futures_codec::FramedRead;
|
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{ClassifiedCommand, Expression, InternalCommand, Literal, NamedArguments};
|
use nu_parser::ParserScope;
|
||||||
use nu_protocol::{Primitive, ReturnSuccess, Scope, UntaggedValue, Value};
|
use nu_protocol::{UntaggedValue, Value};
|
||||||
|
|
||||||
use log::{debug, trace};
|
|
||||||
#[cfg(feature = "rustyline-support")]
|
#[cfg(feature = "rustyline-support")]
|
||||||
use rustyline::{
|
use rustyline::{
|
||||||
self,
|
self,
|
||||||
@ -22,8 +24,7 @@ use rustyline::{
|
|||||||
};
|
};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::sync::atomic::Ordering;
|
|
||||||
|
|
||||||
pub fn search_paths() -> Vec<std::path::PathBuf> {
|
pub fn search_paths() -> Vec<std::path::PathBuf> {
|
||||||
use std::env;
|
use std::env;
|
||||||
@ -56,250 +57,8 @@ pub fn search_paths() -> Vec<std::path::PathBuf> {
|
|||||||
search_paths
|
search_paths
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Box<dyn Error>> {
|
pub async fn run_script_file(
|
||||||
let mut context = EvaluationContext::basic()?;
|
file_contents: String,
|
||||||
|
|
||||||
{
|
|
||||||
use crate::commands::*;
|
|
||||||
|
|
||||||
context.add_commands(vec![
|
|
||||||
whole_stream_command(NuPlugin),
|
|
||||||
// System/file operations
|
|
||||||
whole_stream_command(Exec),
|
|
||||||
whole_stream_command(Pwd),
|
|
||||||
whole_stream_command(Ls),
|
|
||||||
whole_stream_command(Du),
|
|
||||||
whole_stream_command(Cd),
|
|
||||||
whole_stream_command(Remove),
|
|
||||||
whole_stream_command(Open),
|
|
||||||
whole_stream_command(Config),
|
|
||||||
whole_stream_command(ConfigGet),
|
|
||||||
whole_stream_command(ConfigSet),
|
|
||||||
whole_stream_command(ConfigSetInto),
|
|
||||||
whole_stream_command(ConfigClear),
|
|
||||||
whole_stream_command(ConfigLoad),
|
|
||||||
whole_stream_command(ConfigRemove),
|
|
||||||
whole_stream_command(ConfigPath),
|
|
||||||
whole_stream_command(Help),
|
|
||||||
whole_stream_command(History),
|
|
||||||
whole_stream_command(Save),
|
|
||||||
whole_stream_command(Touch),
|
|
||||||
whole_stream_command(Cpy),
|
|
||||||
whole_stream_command(Date),
|
|
||||||
whole_stream_command(DateListTimeZone),
|
|
||||||
whole_stream_command(DateNow),
|
|
||||||
whole_stream_command(DateToTable),
|
|
||||||
whole_stream_command(DateToTimeZone),
|
|
||||||
whole_stream_command(DateFormat),
|
|
||||||
whole_stream_command(Cal),
|
|
||||||
whole_stream_command(Mkdir),
|
|
||||||
whole_stream_command(Mv),
|
|
||||||
whole_stream_command(Kill),
|
|
||||||
whole_stream_command(Version),
|
|
||||||
whole_stream_command(Clear),
|
|
||||||
whole_stream_command(Describe),
|
|
||||||
whole_stream_command(Which),
|
|
||||||
whole_stream_command(Debug),
|
|
||||||
whole_stream_command(Alias),
|
|
||||||
whole_stream_command(WithEnv),
|
|
||||||
whole_stream_command(Do),
|
|
||||||
whole_stream_command(Sleep),
|
|
||||||
// Statistics
|
|
||||||
whole_stream_command(Size),
|
|
||||||
whole_stream_command(Count),
|
|
||||||
whole_stream_command(Benchmark),
|
|
||||||
// Metadata
|
|
||||||
whole_stream_command(Tags),
|
|
||||||
// Shells
|
|
||||||
whole_stream_command(Next),
|
|
||||||
whole_stream_command(Previous),
|
|
||||||
whole_stream_command(Shells),
|
|
||||||
whole_stream_command(Enter),
|
|
||||||
whole_stream_command(Exit),
|
|
||||||
// Viz
|
|
||||||
whole_stream_command(Chart),
|
|
||||||
// Viewers
|
|
||||||
whole_stream_command(Autoview),
|
|
||||||
whole_stream_command(Table),
|
|
||||||
// Text manipulation
|
|
||||||
whole_stream_command(Hash),
|
|
||||||
whole_stream_command(HashBase64),
|
|
||||||
whole_stream_command(Split),
|
|
||||||
whole_stream_command(SplitColumn),
|
|
||||||
whole_stream_command(SplitRow),
|
|
||||||
whole_stream_command(SplitChars),
|
|
||||||
whole_stream_command(Lines),
|
|
||||||
whole_stream_command(Echo),
|
|
||||||
whole_stream_command(Parse),
|
|
||||||
whole_stream_command(Str),
|
|
||||||
whole_stream_command(StrToDecimal),
|
|
||||||
whole_stream_command(StrToInteger),
|
|
||||||
whole_stream_command(StrDowncase),
|
|
||||||
whole_stream_command(StrUpcase),
|
|
||||||
whole_stream_command(StrCapitalize),
|
|
||||||
whole_stream_command(StrFindReplace),
|
|
||||||
whole_stream_command(StrFrom),
|
|
||||||
whole_stream_command(StrSubstring),
|
|
||||||
whole_stream_command(StrSet),
|
|
||||||
whole_stream_command(StrToDatetime),
|
|
||||||
whole_stream_command(StrContains),
|
|
||||||
whole_stream_command(StrIndexOf),
|
|
||||||
whole_stream_command(StrTrim),
|
|
||||||
whole_stream_command(StrTrimLeft),
|
|
||||||
whole_stream_command(StrTrimRight),
|
|
||||||
whole_stream_command(StrStartsWith),
|
|
||||||
whole_stream_command(StrEndsWith),
|
|
||||||
whole_stream_command(StrCollect),
|
|
||||||
whole_stream_command(StrLength),
|
|
||||||
whole_stream_command(StrLPad),
|
|
||||||
whole_stream_command(StrReverse),
|
|
||||||
whole_stream_command(StrRPad),
|
|
||||||
whole_stream_command(StrCamelCase),
|
|
||||||
whole_stream_command(StrPascalCase),
|
|
||||||
whole_stream_command(StrKebabCase),
|
|
||||||
whole_stream_command(StrSnakeCase),
|
|
||||||
whole_stream_command(StrScreamingSnakeCase),
|
|
||||||
whole_stream_command(BuildString),
|
|
||||||
whole_stream_command(Ansi),
|
|
||||||
whole_stream_command(Char),
|
|
||||||
// Column manipulation
|
|
||||||
whole_stream_command(Move),
|
|
||||||
whole_stream_command(Reject),
|
|
||||||
whole_stream_command(Select),
|
|
||||||
whole_stream_command(Get),
|
|
||||||
whole_stream_command(Update),
|
|
||||||
whole_stream_command(Insert),
|
|
||||||
whole_stream_command(IntoInt),
|
|
||||||
whole_stream_command(SplitBy),
|
|
||||||
// Row manipulation
|
|
||||||
whole_stream_command(Reverse),
|
|
||||||
whole_stream_command(Append),
|
|
||||||
whole_stream_command(Prepend),
|
|
||||||
whole_stream_command(SortBy),
|
|
||||||
whole_stream_command(GroupBy),
|
|
||||||
whole_stream_command(GroupByDate),
|
|
||||||
whole_stream_command(First),
|
|
||||||
whole_stream_command(Last),
|
|
||||||
whole_stream_command(Every),
|
|
||||||
whole_stream_command(Nth),
|
|
||||||
whole_stream_command(Drop),
|
|
||||||
whole_stream_command(Format),
|
|
||||||
whole_stream_command(FileSize),
|
|
||||||
whole_stream_command(Where),
|
|
||||||
whole_stream_command(If),
|
|
||||||
whole_stream_command(Compact),
|
|
||||||
whole_stream_command(Default),
|
|
||||||
whole_stream_command(Skip),
|
|
||||||
whole_stream_command(SkipUntil),
|
|
||||||
whole_stream_command(SkipWhile),
|
|
||||||
whole_stream_command(Keep),
|
|
||||||
whole_stream_command(KeepUntil),
|
|
||||||
whole_stream_command(KeepWhile),
|
|
||||||
whole_stream_command(Range),
|
|
||||||
whole_stream_command(Rename),
|
|
||||||
whole_stream_command(Uniq),
|
|
||||||
whole_stream_command(Each),
|
|
||||||
whole_stream_command(EachGroup),
|
|
||||||
whole_stream_command(EachWindow),
|
|
||||||
whole_stream_command(Empty),
|
|
||||||
// Table manipulation
|
|
||||||
whole_stream_command(Flatten),
|
|
||||||
whole_stream_command(Move),
|
|
||||||
whole_stream_command(Merge),
|
|
||||||
whole_stream_command(Shuffle),
|
|
||||||
whole_stream_command(Wrap),
|
|
||||||
whole_stream_command(Pivot),
|
|
||||||
whole_stream_command(Headers),
|
|
||||||
whole_stream_command(Reduce),
|
|
||||||
// Data processing
|
|
||||||
whole_stream_command(Histogram),
|
|
||||||
whole_stream_command(Autoenv),
|
|
||||||
whole_stream_command(AutoenvTrust),
|
|
||||||
whole_stream_command(AutoenvUnTrust),
|
|
||||||
whole_stream_command(Math),
|
|
||||||
whole_stream_command(MathAbs),
|
|
||||||
whole_stream_command(MathAverage),
|
|
||||||
whole_stream_command(MathEval),
|
|
||||||
whole_stream_command(MathMedian),
|
|
||||||
whole_stream_command(MathMinimum),
|
|
||||||
whole_stream_command(MathMode),
|
|
||||||
whole_stream_command(MathMaximum),
|
|
||||||
whole_stream_command(MathStddev),
|
|
||||||
whole_stream_command(MathSummation),
|
|
||||||
whole_stream_command(MathVariance),
|
|
||||||
whole_stream_command(MathProduct),
|
|
||||||
whole_stream_command(MathRound),
|
|
||||||
whole_stream_command(MathFloor),
|
|
||||||
whole_stream_command(MathCeil),
|
|
||||||
// File format output
|
|
||||||
whole_stream_command(To),
|
|
||||||
whole_stream_command(ToCSV),
|
|
||||||
whole_stream_command(ToHTML),
|
|
||||||
whole_stream_command(ToJSON),
|
|
||||||
whole_stream_command(ToMarkdown),
|
|
||||||
whole_stream_command(ToTOML),
|
|
||||||
whole_stream_command(ToTSV),
|
|
||||||
whole_stream_command(ToURL),
|
|
||||||
whole_stream_command(ToYAML),
|
|
||||||
whole_stream_command(ToXML),
|
|
||||||
// File format input
|
|
||||||
whole_stream_command(From),
|
|
||||||
whole_stream_command(FromCSV),
|
|
||||||
whole_stream_command(FromEML),
|
|
||||||
whole_stream_command(FromTSV),
|
|
||||||
whole_stream_command(FromSSV),
|
|
||||||
whole_stream_command(FromINI),
|
|
||||||
whole_stream_command(FromJSON),
|
|
||||||
whole_stream_command(FromODS),
|
|
||||||
whole_stream_command(FromTOML),
|
|
||||||
whole_stream_command(FromURL),
|
|
||||||
whole_stream_command(FromXLSX),
|
|
||||||
whole_stream_command(FromXML),
|
|
||||||
whole_stream_command(FromYAML),
|
|
||||||
whole_stream_command(FromYML),
|
|
||||||
whole_stream_command(FromIcs),
|
|
||||||
whole_stream_command(FromVcf),
|
|
||||||
// "Private" commands (not intended to be accessed directly)
|
|
||||||
whole_stream_command(RunExternalCommand { interactive }),
|
|
||||||
// Random value generation
|
|
||||||
whole_stream_command(Random),
|
|
||||||
whole_stream_command(RandomBool),
|
|
||||||
whole_stream_command(RandomDice),
|
|
||||||
#[cfg(feature = "uuid_crate")]
|
|
||||||
whole_stream_command(RandomUUID),
|
|
||||||
whole_stream_command(RandomInteger),
|
|
||||||
whole_stream_command(RandomDecimal),
|
|
||||||
whole_stream_command(RandomChars),
|
|
||||||
// Path
|
|
||||||
whole_stream_command(PathBasename),
|
|
||||||
whole_stream_command(PathCommand),
|
|
||||||
whole_stream_command(PathDirname),
|
|
||||||
whole_stream_command(PathExists),
|
|
||||||
whole_stream_command(PathExpand),
|
|
||||||
whole_stream_command(PathExtension),
|
|
||||||
whole_stream_command(PathFilestem),
|
|
||||||
whole_stream_command(PathType),
|
|
||||||
// Url
|
|
||||||
whole_stream_command(UrlCommand),
|
|
||||||
whole_stream_command(UrlScheme),
|
|
||||||
whole_stream_command(UrlPath),
|
|
||||||
whole_stream_command(UrlHost),
|
|
||||||
whole_stream_command(UrlQuery),
|
|
||||||
whole_stream_command(Seq),
|
|
||||||
whole_stream_command(SeqDates),
|
|
||||||
]);
|
|
||||||
|
|
||||||
#[cfg(feature = "clipboard-cli")]
|
|
||||||
{
|
|
||||||
context.add_commands(vec![whole_stream_command(crate::commands::clip::Clip)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run_vec_of_pipelines(
|
|
||||||
pipelines: Vec<String>,
|
|
||||||
redirect_stdin: bool,
|
redirect_stdin: bool,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let mut syncer = EnvironmentSyncer::new();
|
let mut syncer = EnvironmentSyncer::new();
|
||||||
@ -321,9 +80,7 @@ pub async fn run_vec_of_pipelines(
|
|||||||
|
|
||||||
let _ = run_startup_commands(&mut context, &config).await;
|
let _ = run_startup_commands(&mut context, &config).await;
|
||||||
|
|
||||||
for pipeline in pipelines {
|
run_script_standalone(file_contents, redirect_stdin, &context, true).await?;
|
||||||
run_pipeline_standalone(pipeline, redirect_stdin, &mut context, true).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -368,9 +125,15 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let _ = run_startup_commands(&mut context, &configuration).await;
|
let _ = run_startup_commands(&mut context, &configuration).await;
|
||||||
|
|
||||||
|
// Give ourselves a scope to work in
|
||||||
|
context.scope.enter_scope();
|
||||||
|
|
||||||
let history_path = crate::commands::history::history_path(&configuration);
|
let history_path = crate::commands::history::history_path(&configuration);
|
||||||
let _ = rl.load_history(&history_path);
|
let _ = rl.load_history(&history_path);
|
||||||
|
|
||||||
|
let mut session_text = String::new();
|
||||||
|
let mut line_start: usize = 0;
|
||||||
|
|
||||||
let skip_welcome_message = configuration
|
let skip_welcome_message = configuration
|
||||||
.var("skip_welcome_message")
|
.var("skip_welcome_message")
|
||||||
.map(|x| x.is_true())
|
.map(|x| x.is_true())
|
||||||
@ -401,10 +164,13 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
|
|||||||
if let Some(prompt) = configuration.var("prompt") {
|
if let Some(prompt) = configuration.var("prompt") {
|
||||||
let prompt_line = prompt.as_string()?;
|
let prompt_line = prompt.as_string()?;
|
||||||
|
|
||||||
let (result, err) = nu_parser::lite_parse(&prompt_line, 0);
|
context.scope.enter_scope();
|
||||||
|
let (prompt_block, err) = nu_parser::parse(&prompt_line, 0, &context.scope);
|
||||||
|
|
||||||
if err.is_some() {
|
if err.is_some() {
|
||||||
use crate::git::current_branch;
|
use crate::git::current_branch;
|
||||||
|
context.scope.exit_scope();
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
"\x1b[32m{}{}\x1b[m> ",
|
"\x1b[32m{}{}\x1b[m> ",
|
||||||
cwd,
|
cwd,
|
||||||
@ -414,18 +180,12 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let prompt_block = nu_parser::classify_block(&result, context.registry());
|
// let env = context.get_env();
|
||||||
|
|
||||||
let env = context.get_env();
|
let run_result = run_block(&prompt_block, &context, InputStream::empty()).await;
|
||||||
|
context.scope.exit_scope();
|
||||||
|
|
||||||
match run_block(
|
match run_result {
|
||||||
&prompt_block.block,
|
|
||||||
&mut context,
|
|
||||||
InputStream::empty(),
|
|
||||||
Scope::from_env(env),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(result) => match result.collect_string(Tag::unknown()).await {
|
Ok(result) => match result.collect_string(Tag::unknown()).await {
|
||||||
Ok(string_result) => {
|
Ok(string_result) => {
|
||||||
let errors = context.get_errors();
|
let errors = context.get_errors();
|
||||||
@ -482,8 +242,23 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
|
|||||||
initial_command = None;
|
initial_command = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(line) = &readline {
|
||||||
|
line_start = session_text.len();
|
||||||
|
session_text.push_str(line);
|
||||||
|
session_text.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
let line = match convert_rustyline_result_to_string(readline) {
|
let line = match convert_rustyline_result_to_string(readline) {
|
||||||
LineResult::Success(s) => process_line(&s, &mut context, false, true).await,
|
LineResult::Success(_) => {
|
||||||
|
process_script(
|
||||||
|
&session_text[line_start..],
|
||||||
|
&context,
|
||||||
|
false,
|
||||||
|
line_start,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
x => x,
|
x => x,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -509,7 +284,7 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
|
|||||||
LineResult::Success(line) => {
|
LineResult::Success(line) => {
|
||||||
rl.add_history_entry(&line);
|
rl.add_history_entry(&line);
|
||||||
let _ = rl.save_history(&history_path);
|
let _ = rl.save_history(&history_path);
|
||||||
context.maybe_print_errors(Text::from(line));
|
context.maybe_print_errors(Text::from(session_text.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LineResult::ClearHistory => {
|
LineResult::ClearHistory => {
|
||||||
@ -522,10 +297,10 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
|
|||||||
let _ = rl.save_history(&history_path);
|
let _ = rl.save_history(&history_path);
|
||||||
|
|
||||||
context.with_host(|_host| {
|
context.with_host(|_host| {
|
||||||
print_err(err, &Text::from(line.clone()));
|
print_err(err, &Text::from(session_text.clone()));
|
||||||
});
|
});
|
||||||
|
|
||||||
context.maybe_print_errors(Text::from(line.clone()));
|
context.maybe_print_errors(Text::from(session_text.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LineResult::CtrlC => {
|
LineResult::CtrlC => {
|
||||||
@ -610,8 +385,7 @@ async fn run_startup_commands(
|
|||||||
} => {
|
} => {
|
||||||
for pipeline in pipelines {
|
for pipeline in pipelines {
|
||||||
if let Ok(pipeline_string) = pipeline.as_string() {
|
if let Ok(pipeline_string) = pipeline.as_string() {
|
||||||
let _ =
|
let _ = run_script_standalone(pipeline_string, false, context, false).await;
|
||||||
run_pipeline_standalone(pipeline_string, false, context, false).await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -626,50 +400,6 @@ async fn run_startup_commands(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_pipeline_standalone(
|
|
||||||
pipeline: String,
|
|
||||||
redirect_stdin: bool,
|
|
||||||
context: &mut EvaluationContext,
|
|
||||||
exit_on_error: bool,
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
let line = process_line(&pipeline, context, redirect_stdin, false).await;
|
|
||||||
|
|
||||||
match line {
|
|
||||||
LineResult::Success(line) => {
|
|
||||||
let error_code = {
|
|
||||||
let errors = context.current_errors.clone();
|
|
||||||
let errors = errors.lock();
|
|
||||||
|
|
||||||
if errors.len() > 0 {
|
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
context.maybe_print_errors(Text::from(line));
|
|
||||||
if error_code != 0 && exit_on_error {
|
|
||||||
std::process::exit(error_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LineResult::Error(line, err) => {
|
|
||||||
context.with_host(|_host| {
|
|
||||||
print_err(err, &Text::from(line.clone()));
|
|
||||||
});
|
|
||||||
|
|
||||||
context.maybe_print_errors(Text::from(line));
|
|
||||||
if exit_on_error {
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "rustyline-support")]
|
#[cfg(feature = "rustyline-support")]
|
||||||
fn default_rustyline_editor_configuration() -> Editor<Helper> {
|
fn default_rustyline_editor_configuration() -> Editor<Helper> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -851,272 +581,42 @@ fn rustyline_hinter(config: &dyn nu_data::config::Conf) -> Option<rustyline::hin
|
|||||||
Some(rustyline::hint::HistoryHinter {})
|
Some(rustyline::hint::HistoryHinter {})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chomp_newline(s: &str) -> &str {
|
pub async fn parse_and_eval(line: &str, ctx: &EvaluationContext) -> Result<String, ShellError> {
|
||||||
if let Some(s) = s.strip_suffix('\n') {
|
// FIXME: do we still need this?
|
||||||
s
|
|
||||||
} else {
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum LineResult {
|
|
||||||
Success(String),
|
|
||||||
Error(String, ShellError),
|
|
||||||
Break,
|
|
||||||
CtrlC,
|
|
||||||
CtrlD,
|
|
||||||
ClearHistory,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn parse_and_eval(line: &str, ctx: &mut EvaluationContext) -> Result<String, ShellError> {
|
|
||||||
let line = if let Some(s) = line.strip_suffix('\n') {
|
let line = if let Some(s) = line.strip_suffix('\n') {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
line
|
line
|
||||||
};
|
};
|
||||||
|
|
||||||
let (lite_result, err) = nu_parser::lite_parse(&line, 0);
|
// TODO ensure the command whose examples we're testing is actually in the pipeline
|
||||||
|
ctx.scope.enter_scope();
|
||||||
|
let (classified_block, err) = nu_parser::parse(&line, 0, &ctx.scope);
|
||||||
if let Some(err) = err {
|
if let Some(err) = err {
|
||||||
|
ctx.scope.exit_scope();
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO ensure the command whose examples we're testing is actually in the pipeline
|
|
||||||
let classified_block = nu_parser::classify_block(&lite_result, ctx.registry());
|
|
||||||
|
|
||||||
let input_stream = InputStream::empty();
|
let input_stream = InputStream::empty();
|
||||||
let env = ctx.get_env();
|
let env = ctx.get_env();
|
||||||
|
ctx.scope.add_env(env);
|
||||||
|
|
||||||
run_block(
|
let result = run_block(&classified_block, ctx, input_stream).await;
|
||||||
&classified_block.block,
|
ctx.scope.exit_scope();
|
||||||
ctx,
|
|
||||||
input_stream,
|
|
||||||
Scope::from_env(env),
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.collect_string(Tag::unknown())
|
|
||||||
.await
|
|
||||||
.map(|x| x.item)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Process the line by parsing the text to turn it into commands, classify those commands so that we understand what is being called in the pipeline, and then run this pipeline
|
result?.collect_string(Tag::unknown()).await.map(|x| x.item)
|
||||||
pub async fn process_line(
|
|
||||||
line: &str,
|
|
||||||
ctx: &mut EvaluationContext,
|
|
||||||
redirect_stdin: bool,
|
|
||||||
cli_mode: bool,
|
|
||||||
) -> LineResult {
|
|
||||||
if line.trim() == "" {
|
|
||||||
LineResult::Success(line.to_string())
|
|
||||||
} else {
|
|
||||||
let line = chomp_newline(line);
|
|
||||||
ctx.raw_input = line.to_string();
|
|
||||||
|
|
||||||
let (result, err) = nu_parser::lite_parse(&line, 0);
|
|
||||||
|
|
||||||
if let Some(err) = err {
|
|
||||||
return LineResult::Error(line.to_string(), err.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("=== Parsed ===");
|
|
||||||
debug!("{:#?}", result);
|
|
||||||
|
|
||||||
let classified_block = nu_parser::classify_block(&result, ctx.registry());
|
|
||||||
|
|
||||||
debug!("{:#?}", classified_block);
|
|
||||||
//println!("{:#?}", pipeline);
|
|
||||||
|
|
||||||
if let Some(failure) = classified_block.failed {
|
|
||||||
return LineResult::Error(line.to_string(), failure.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// There's a special case to check before we process the pipeline:
|
|
||||||
// If we're giving a path by itself
|
|
||||||
// ...and it's not a command in the path
|
|
||||||
// ...and it doesn't have any arguments
|
|
||||||
// ...and we're in the CLI
|
|
||||||
// ...then change to this directory
|
|
||||||
if cli_mode
|
|
||||||
&& classified_block.block.block.len() == 1
|
|
||||||
&& classified_block.block.block[0].list.len() == 1
|
|
||||||
{
|
|
||||||
if let ClassifiedCommand::Internal(InternalCommand {
|
|
||||||
ref name, ref args, ..
|
|
||||||
}) = classified_block.block.block[0].list[0]
|
|
||||||
{
|
|
||||||
let internal_name = name;
|
|
||||||
let name = args
|
|
||||||
.positional
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|potionals| {
|
|
||||||
potionals.get(0).map(|e| {
|
|
||||||
if let Expression::Literal(Literal::String(ref s)) = e.expr {
|
|
||||||
&s
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.unwrap_or("");
|
|
||||||
|
|
||||||
if internal_name == "run_external"
|
|
||||||
&& args
|
|
||||||
.positional
|
|
||||||
.as_ref()
|
|
||||||
.map(|ref v| v.len() == 1)
|
|
||||||
.unwrap_or(true)
|
|
||||||
&& args
|
|
||||||
.named
|
|
||||||
.as_ref()
|
|
||||||
.map(NamedArguments::is_empty)
|
|
||||||
.unwrap_or(true)
|
|
||||||
&& canonicalize(ctx.shell_manager.path(), name).is_ok()
|
|
||||||
&& Path::new(&name).is_dir()
|
|
||||||
&& !crate::commands::classified::external::did_find_command(&name)
|
|
||||||
{
|
|
||||||
// Here we work differently if we're in Windows because of the expected Windows behavior
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
if name.ends_with(':') {
|
|
||||||
// This looks like a drive shortcut. We need to a) switch drives and b) go back to the previous directory we were viewing on that drive
|
|
||||||
// But first, we need to save where we are now
|
|
||||||
let current_path = ctx.shell_manager.path();
|
|
||||||
|
|
||||||
let split_path: Vec<_> = current_path.split(':').collect();
|
|
||||||
if split_path.len() > 1 {
|
|
||||||
ctx.windows_drives_previous_cwd
|
|
||||||
.lock()
|
|
||||||
.insert(split_path[0].to_string(), current_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = name.to_uppercase();
|
|
||||||
let new_drive: Vec<_> = name.split(':').collect();
|
|
||||||
|
|
||||||
if let Some(val) =
|
|
||||||
ctx.windows_drives_previous_cwd.lock().get(new_drive[0])
|
|
||||||
{
|
|
||||||
ctx.shell_manager.set_path(val.to_string());
|
|
||||||
return LineResult::Success(line.to_string());
|
|
||||||
} else {
|
|
||||||
ctx.shell_manager
|
|
||||||
.set_path(format!("{}\\", name.to_string()));
|
|
||||||
return LineResult::Success(line.to_string());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ctx.shell_manager.set_path(name.to_string());
|
|
||||||
return LineResult::Success(line.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
{
|
|
||||||
ctx.shell_manager.set_path(name.to_string());
|
|
||||||
return LineResult::Success(line.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let input_stream = if redirect_stdin {
|
|
||||||
let file = futures::io::AllowStdIo::new(std::io::stdin());
|
|
||||||
let stream = FramedRead::new(file, MaybeTextCodec::default()).map(|line| {
|
|
||||||
if let Ok(line) = line {
|
|
||||||
let primitive = match line {
|
|
||||||
StringOrBinary::String(s) => Primitive::String(s),
|
|
||||||
StringOrBinary::Binary(b) => Primitive::Binary(b.into_iter().collect()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Value {
|
|
||||||
value: UntaggedValue::Primitive(primitive),
|
|
||||||
tag: Tag::unknown(),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
panic!("Internal error: could not read lines of text from stdin")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stream.to_input_stream()
|
|
||||||
} else {
|
|
||||||
InputStream::empty()
|
|
||||||
};
|
|
||||||
|
|
||||||
trace!("{:#?}", classified_block);
|
|
||||||
let env = ctx.get_env();
|
|
||||||
match run_block(
|
|
||||||
&classified_block.block,
|
|
||||||
ctx,
|
|
||||||
input_stream,
|
|
||||||
Scope::from_env(env),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(input) => {
|
|
||||||
// Running a pipeline gives us back a stream that we can then
|
|
||||||
// work through. At the top level, we just want to pull on the
|
|
||||||
// values to compute them.
|
|
||||||
use futures::stream::TryStreamExt;
|
|
||||||
|
|
||||||
let context = RunnableContext {
|
|
||||||
input,
|
|
||||||
shell_manager: ctx.shell_manager.clone(),
|
|
||||||
host: ctx.host.clone(),
|
|
||||||
ctrl_c: ctx.ctrl_c.clone(),
|
|
||||||
current_errors: ctx.current_errors.clone(),
|
|
||||||
registry: ctx.registry.clone(),
|
|
||||||
name: Tag::unknown(),
|
|
||||||
raw_input: line.to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Ok(mut output_stream) =
|
|
||||||
crate::commands::autoview::command::autoview(context).await
|
|
||||||
{
|
|
||||||
loop {
|
|
||||||
match output_stream.try_next().await {
|
|
||||||
Ok(Some(ReturnSuccess::Value(Value {
|
|
||||||
value: UntaggedValue::Error(e),
|
|
||||||
..
|
|
||||||
}))) => return LineResult::Error(line.to_string(), e),
|
|
||||||
Ok(Some(_item)) => {
|
|
||||||
if ctx.ctrl_c.load(Ordering::SeqCst) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(None) => break,
|
|
||||||
Err(e) => return LineResult::Error(line.to_string(), e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LineResult::Success(line.to_string())
|
|
||||||
}
|
|
||||||
Err(err) => LineResult::Error(line.to_string(), err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_err(err: ShellError, source: &Text) {
|
|
||||||
if let Some(diag) = err.into_diagnostic() {
|
|
||||||
let source = source.to_string();
|
|
||||||
let mut files = codespan_reporting::files::SimpleFiles::new();
|
|
||||||
files.add("shell", source);
|
|
||||||
|
|
||||||
let writer = codespan_reporting::term::termcolor::StandardStream::stderr(
|
|
||||||
codespan_reporting::term::termcolor::ColorChoice::Always,
|
|
||||||
);
|
|
||||||
let config = codespan_reporting::term::Config::default();
|
|
||||||
|
|
||||||
let _ = std::panic::catch_unwind(move || {
|
|
||||||
let _ = codespan_reporting::term::emit(&mut writer.lock(), &config, &files, &diag);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
#[quickcheck]
|
#[quickcheck]
|
||||||
fn quickcheck_parse(data: String) -> bool {
|
fn quickcheck_parse(data: String) -> bool {
|
||||||
let (lite_block, err) = nu_parser::lite_parse(&data, 0);
|
let (tokens, err) = nu_parser::lex(&data, 0);
|
||||||
if err.is_none() {
|
let (lite_block, err2) = nu_parser::group(tokens);
|
||||||
|
if err.is_none() && err2.is_none() {
|
||||||
let context = crate::evaluation_context::EvaluationContext::basic().unwrap();
|
let context = crate::evaluation_context::EvaluationContext::basic().unwrap();
|
||||||
let _ = nu_parser::classify_block(&lite_block, context.registry());
|
let _ = nu_parser::classify_block(&lite_block, &context.scope);
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
use crate::commands::Command;
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
use nu_errors::ShellError;
|
|
||||||
use nu_parser::SignatureRegistry;
|
|
||||||
use nu_protocol::Signature;
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
|
||||||
pub struct CommandRegistry {
|
|
||||||
registry: Arc<Mutex<IndexMap<String, Command>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SignatureRegistry for CommandRegistry {
|
|
||||||
fn has(&self, name: &str) -> bool {
|
|
||||||
let registry = self.registry.lock();
|
|
||||||
registry.contains_key(name)
|
|
||||||
}
|
|
||||||
fn get(&self, name: &str) -> Option<Signature> {
|
|
||||||
let registry = self.registry.lock();
|
|
||||||
registry.get(name).map(|command| command.signature())
|
|
||||||
}
|
|
||||||
fn clone_box(&self) -> Box<dyn SignatureRegistry> {
|
|
||||||
Box::new(self.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommandRegistry {
|
|
||||||
pub fn new() -> CommandRegistry {
|
|
||||||
CommandRegistry {
|
|
||||||
registry: Arc::new(Mutex::new(IndexMap::default())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommandRegistry {
|
|
||||||
pub fn get_command(&self, name: &str) -> Option<Command> {
|
|
||||||
let registry = self.registry.lock();
|
|
||||||
|
|
||||||
registry.get(name).cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expect_command(&self, name: &str) -> Result<Command, ShellError> {
|
|
||||||
self.get_command(name).ok_or_else(|| {
|
|
||||||
ShellError::untagged_runtime_error(format!("Could not load command: {}", name))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has(&self, name: &str) -> bool {
|
|
||||||
let registry = self.registry.lock();
|
|
||||||
|
|
||||||
registry.contains_key(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, name: impl Into<String>, command: Command) {
|
|
||||||
let mut registry = self.registry.lock();
|
|
||||||
registry.insert(name.into(), command);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn names(&self) -> Vec<String> {
|
|
||||||
let registry = self.registry.lock();
|
|
||||||
registry.keys().cloned().collect()
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ pub(crate) mod macros;
|
|||||||
mod from_delimited_data;
|
mod from_delimited_data;
|
||||||
mod to_delimited_data;
|
mod to_delimited_data;
|
||||||
|
|
||||||
pub(crate) mod alias;
|
|
||||||
pub(crate) mod ansi;
|
pub(crate) mod ansi;
|
||||||
pub(crate) mod append;
|
pub(crate) mod append;
|
||||||
pub(crate) mod args;
|
pub(crate) mod args;
|
||||||
@ -29,7 +28,9 @@ pub(crate) mod count;
|
|||||||
pub(crate) mod cp;
|
pub(crate) mod cp;
|
||||||
pub(crate) mod date;
|
pub(crate) mod date;
|
||||||
pub(crate) mod debug;
|
pub(crate) mod debug;
|
||||||
|
pub(crate) mod def;
|
||||||
pub(crate) mod default;
|
pub(crate) mod default;
|
||||||
|
pub(crate) mod default_context;
|
||||||
pub(crate) mod describe;
|
pub(crate) mod describe;
|
||||||
pub(crate) mod do_;
|
pub(crate) mod do_;
|
||||||
pub(crate) mod drop;
|
pub(crate) mod drop;
|
||||||
@ -72,6 +73,8 @@ pub(crate) mod insert;
|
|||||||
pub(crate) mod into_int;
|
pub(crate) mod into_int;
|
||||||
pub(crate) mod keep;
|
pub(crate) mod keep;
|
||||||
pub(crate) mod last;
|
pub(crate) mod last;
|
||||||
|
pub(crate) mod let_;
|
||||||
|
pub(crate) mod let_env;
|
||||||
pub(crate) mod lines;
|
pub(crate) mod lines;
|
||||||
pub(crate) mod ls;
|
pub(crate) mod ls;
|
||||||
pub(crate) mod math;
|
pub(crate) mod math;
|
||||||
@ -95,7 +98,6 @@ pub(crate) mod reject;
|
|||||||
pub(crate) mod rename;
|
pub(crate) mod rename;
|
||||||
pub(crate) mod reverse;
|
pub(crate) mod reverse;
|
||||||
pub(crate) mod rm;
|
pub(crate) mod rm;
|
||||||
pub(crate) mod run_alias;
|
|
||||||
pub(crate) mod run_external;
|
pub(crate) mod run_external;
|
||||||
pub(crate) mod save;
|
pub(crate) mod save;
|
||||||
pub(crate) mod select;
|
pub(crate) mod select;
|
||||||
@ -107,6 +109,7 @@ pub(crate) mod size;
|
|||||||
pub(crate) mod skip;
|
pub(crate) mod skip;
|
||||||
pub(crate) mod sleep;
|
pub(crate) mod sleep;
|
||||||
pub(crate) mod sort_by;
|
pub(crate) mod sort_by;
|
||||||
|
pub(crate) mod source;
|
||||||
pub(crate) mod split;
|
pub(crate) mod split;
|
||||||
pub(crate) mod split_by;
|
pub(crate) mod split_by;
|
||||||
pub(crate) mod str_;
|
pub(crate) mod str_;
|
||||||
@ -137,7 +140,6 @@ pub(crate) use command::{
|
|||||||
whole_stream_command, Command, Example, UnevaluatedCallInfo, WholeStreamCommand,
|
whole_stream_command, Command, Example, UnevaluatedCallInfo, WholeStreamCommand,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use alias::Alias;
|
|
||||||
pub(crate) use ansi::Ansi;
|
pub(crate) use ansi::Ansi;
|
||||||
pub(crate) use append::Command as Append;
|
pub(crate) use append::Command as Append;
|
||||||
pub(crate) use autoenv::Autoenv;
|
pub(crate) use autoenv::Autoenv;
|
||||||
@ -156,6 +158,7 @@ pub(crate) use count::Count;
|
|||||||
pub(crate) use cp::Cpy;
|
pub(crate) use cp::Cpy;
|
||||||
pub(crate) use date::{Date, DateFormat, DateListTimeZone, DateNow, DateToTable, DateToTimeZone};
|
pub(crate) use date::{Date, DateFormat, DateListTimeZone, DateNow, DateToTable, DateToTimeZone};
|
||||||
pub(crate) use debug::Debug;
|
pub(crate) use debug::Debug;
|
||||||
|
pub(crate) use def::Def;
|
||||||
pub(crate) use default::Default;
|
pub(crate) use default::Default;
|
||||||
pub(crate) use describe::Describe;
|
pub(crate) use describe::Describe;
|
||||||
pub(crate) use do_::Do;
|
pub(crate) use do_::Do;
|
||||||
@ -209,6 +212,8 @@ pub(crate) use insert::Command as Insert;
|
|||||||
pub(crate) use into_int::IntoInt;
|
pub(crate) use into_int::IntoInt;
|
||||||
pub(crate) use keep::{Keep, KeepUntil, KeepWhile};
|
pub(crate) use keep::{Keep, KeepUntil, KeepWhile};
|
||||||
pub(crate) use last::Last;
|
pub(crate) use last::Last;
|
||||||
|
pub(crate) use let_::Let;
|
||||||
|
pub(crate) use let_env::LetEnv;
|
||||||
pub(crate) use lines::Lines;
|
pub(crate) use lines::Lines;
|
||||||
pub(crate) use ls::Ls;
|
pub(crate) use ls::Ls;
|
||||||
pub(crate) use math::{
|
pub(crate) use math::{
|
||||||
@ -252,6 +257,7 @@ pub(crate) use size::Size;
|
|||||||
pub(crate) use skip::{Skip, SkipUntil, SkipWhile};
|
pub(crate) use skip::{Skip, SkipUntil, SkipWhile};
|
||||||
pub(crate) use sleep::Sleep;
|
pub(crate) use sleep::Sleep;
|
||||||
pub(crate) use sort_by::SortBy;
|
pub(crate) use sort_by::SortBy;
|
||||||
|
pub(crate) use source::Source;
|
||||||
pub(crate) use split::{Split, SplitChars, SplitColumn, SplitRow};
|
pub(crate) use split::{Split, SplitChars, SplitColumn, SplitRow};
|
||||||
pub(crate) use split_by::SplitBy;
|
pub(crate) use split_by::SplitBy;
|
||||||
pub(crate) use str_::{
|
pub(crate) use str_::{
|
||||||
|
@ -1,221 +0,0 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
|
||||||
use crate::prelude::*;
|
|
||||||
|
|
||||||
use crate::types::deduction::{VarDeclaration, VarSyntaxShapeDeductor};
|
|
||||||
use deduction_to_signature::DeductionToSignature;
|
|
||||||
use log::trace;
|
|
||||||
use nu_data::config;
|
|
||||||
use nu_errors::ShellError;
|
|
||||||
use nu_protocol::{
|
|
||||||
hir::Block, CommandAction, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
use nu_source::Tagged;
|
|
||||||
|
|
||||||
pub struct Alias;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct AliasArgs {
|
|
||||||
pub name: Tagged<String>,
|
|
||||||
pub args: Vec<Value>,
|
|
||||||
pub block: Block,
|
|
||||||
pub infer: Option<bool>,
|
|
||||||
pub save: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl WholeStreamCommand for Alias {
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
"alias"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
|
||||||
Signature::build("alias")
|
|
||||||
.required("name", SyntaxShape::String, "the name of the alias")
|
|
||||||
.required("args", SyntaxShape::Table, "the arguments to the alias")
|
|
||||||
.required(
|
|
||||||
"block",
|
|
||||||
SyntaxShape::Block,
|
|
||||||
"the block to run as the body of the alias",
|
|
||||||
)
|
|
||||||
.switch("infer", "infer argument types (experimental)", Some('i'))
|
|
||||||
.switch("save", "save the alias to your config", Some('s'))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
|
||||||
"Define a shortcut for another command."
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run(
|
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
alias(args, registry).await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
|
||||||
vec![
|
|
||||||
Example {
|
|
||||||
description: "An alias without parameters",
|
|
||||||
example: "alias say-hi [] { echo 'Hello!' }",
|
|
||||||
result: None,
|
|
||||||
},
|
|
||||||
Example {
|
|
||||||
description: "An alias with a single parameter",
|
|
||||||
example: "alias l [x] { ls $x }",
|
|
||||||
result: None,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn alias(
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let mut raw_input = args.raw_input.clone();
|
|
||||||
let (
|
|
||||||
AliasArgs {
|
|
||||||
name,
|
|
||||||
args: list,
|
|
||||||
block,
|
|
||||||
infer,
|
|
||||||
save,
|
|
||||||
},
|
|
||||||
_ctx,
|
|
||||||
) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
if let Some(true) = save {
|
|
||||||
let mut result = nu_data::config::read(name.clone().tag, &None)?;
|
|
||||||
|
|
||||||
// process the alias to remove the --save flag
|
|
||||||
let left_brace = raw_input.find('{').unwrap_or(0);
|
|
||||||
let right_brace = raw_input.rfind('}').unwrap_or_else(|| raw_input.len());
|
|
||||||
let left = raw_input[..left_brace]
|
|
||||||
.replace("--save", "") // TODO using regex (or reconstruct string from AST?)
|
|
||||||
.replace("-si", "-i")
|
|
||||||
.replace("-s ", "")
|
|
||||||
.replace("-is", "-i");
|
|
||||||
let right = raw_input[right_brace..]
|
|
||||||
.replace("--save", "")
|
|
||||||
.replace("-si", "-i")
|
|
||||||
.replace("-s ", "")
|
|
||||||
.replace("-is", "-i");
|
|
||||||
raw_input = format!("{}{}{}", left, &raw_input[left_brace..right_brace], right);
|
|
||||||
|
|
||||||
// create a value from raw_input alias
|
|
||||||
let alias: Value = raw_input.trim().to_string().into();
|
|
||||||
let alias_start = raw_input.find('[').unwrap_or(0); // used to check if the same alias already exists
|
|
||||||
|
|
||||||
// add to startup if alias doesn't exist and replace if it does
|
|
||||||
match result.get_mut("startup") {
|
|
||||||
Some(startup) => {
|
|
||||||
if let UntaggedValue::Table(ref mut commands) = startup.value {
|
|
||||||
if let Some(command) = commands.iter_mut().find(|command| {
|
|
||||||
let cmd_str = command.as_string().unwrap_or_default();
|
|
||||||
cmd_str.starts_with(&raw_input[..alias_start])
|
|
||||||
}) {
|
|
||||||
*command = alias;
|
|
||||||
} else {
|
|
||||||
commands.push(alias);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let table = UntaggedValue::table(&[alias]);
|
|
||||||
result.insert("startup".to_string(), table.into_value(Tag::default()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config::write(&result, &None)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut processed_args: Vec<VarDeclaration> = vec![];
|
|
||||||
for (_, item) in list.iter().enumerate() {
|
|
||||||
match item.as_string() {
|
|
||||||
Ok(var_name) => {
|
|
||||||
let dollar_var_name = format!("${}", var_name);
|
|
||||||
processed_args.push(VarDeclaration {
|
|
||||||
name: dollar_var_name,
|
|
||||||
// type_decl: None,
|
|
||||||
span: item.tag.span,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
return Err(ShellError::labeled_error(
|
|
||||||
"Expected a string",
|
|
||||||
"expected a string",
|
|
||||||
item.tag(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trace!("Found vars: {:?}", processed_args);
|
|
||||||
|
|
||||||
let inferred_shapes = {
|
|
||||||
if let Some(true) = infer {
|
|
||||||
VarSyntaxShapeDeductor::infer_vars(&processed_args, &block, ®istry)?
|
|
||||||
} else {
|
|
||||||
processed_args.into_iter().map(|arg| (arg, None)).collect()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let signature = DeductionToSignature::get(&name.item, &inferred_shapes);
|
|
||||||
trace!("Inferred signature: {:?}", signature);
|
|
||||||
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::action(
|
|
||||||
CommandAction::AddAlias(Box::new(signature), block),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::Alias;
|
|
||||||
use super::ShellError;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
|
||||||
use crate::examples::test as test_examples;
|
|
||||||
|
|
||||||
Ok(test_examples(Alias {})?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod deduction_to_signature {
|
|
||||||
//For now this logic is relativly simple.
|
|
||||||
//For each var, one mandatory positional is added.
|
|
||||||
//As soon as more support for optional positional arguments is arrived,
|
|
||||||
//this logic might be a little bit more tricky.
|
|
||||||
use crate::types::deduction::{Deduction, VarDeclaration};
|
|
||||||
use nu_protocol::{PositionalType, Signature, SyntaxShape};
|
|
||||||
|
|
||||||
pub struct DeductionToSignature {}
|
|
||||||
impl DeductionToSignature {
|
|
||||||
pub fn get(
|
|
||||||
cmd_name: &str,
|
|
||||||
deductions: &[(VarDeclaration, Option<Deduction>)],
|
|
||||||
) -> Signature {
|
|
||||||
let mut signature = Signature::build(cmd_name);
|
|
||||||
for (decl, deduction) in deductions {
|
|
||||||
match deduction {
|
|
||||||
None => signature.positional.push((
|
|
||||||
PositionalType::optional(&decl.name, SyntaxShape::Any),
|
|
||||||
decl.name.clone(),
|
|
||||||
)),
|
|
||||||
Some(deduction) => match deduction {
|
|
||||||
Deduction::VarShapeDeduction(normal_var_deduction) => {
|
|
||||||
signature.positional.push((
|
|
||||||
PositionalType::optional(
|
|
||||||
&decl.name,
|
|
||||||
normal_var_deduction[0].deduction,
|
|
||||||
),
|
|
||||||
decl.name.clone(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signature
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -118,12 +118,8 @@ Format: #
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let (AnsiArgs { color, escape, osc }, _) = args.process().await?;
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let (AnsiArgs { color, escape, osc }, _) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
if let Some(e) = escape {
|
if let Some(e) = escape {
|
||||||
let esc_vec: Vec<char> = e.item.chars().collect();
|
let esc_vec: Vec<char> = e.item.chars().collect();
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -29,12 +28,8 @@ impl WholeStreamCommand for Command {
|
|||||||
"Append a row to the table"
|
"Append a row to the table"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let (Arguments { mut value }, input) = args.process().await?;
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let (Arguments { mut value }, input) = args.process(registry).await?;
|
|
||||||
|
|
||||||
let input: Vec<Value> = input.collect().await;
|
let input: Vec<Value> = input.collect().await;
|
||||||
|
|
||||||
|
@ -61,14 +61,9 @@ The file can contain several optional sections:
|
|||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("autoenv")
|
Signature::build("autoenv")
|
||||||
}
|
}
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&Autoenv, ®istry))
|
UntaggedValue::string(crate::commands::help::get_help(&Autoenv, &args.scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -77,15 +72,15 @@ The file can contain several optional sections:
|
|||||||
vec![Example {
|
vec![Example {
|
||||||
description: "Example .nu-env file",
|
description: "Example .nu-env file",
|
||||||
example: r#"cat .nu-env
|
example: r#"cat .nu-env
|
||||||
[env]
|
[env]
|
||||||
mykey = "myvalue"
|
mykey = "myvalue"
|
||||||
|
|
||||||
[scriptvars]
|
[scriptvars]
|
||||||
myscript = "echo myval"
|
myscript = "echo myval"
|
||||||
|
|
||||||
[scripts]
|
[scripts]
|
||||||
entryscripts = ["touch hello.txt", "touch hello2.txt"]
|
entryscripts = ["touch hello.txt", "touch hello2.txt"]
|
||||||
exitscripts = ["touch bye.txt"]"#,
|
exitscripts = ["touch bye.txt"]"#,
|
||||||
result: None,
|
result: None,
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,11 @@ impl WholeStreamCommand for AutoenvTrust {
|
|||||||
"Trust a .nu-env file in the current or given directory"
|
"Trust a .nu-env file in the current or given directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
|
let ctx = EvaluationContext::from_args(&args);
|
||||||
|
|
||||||
let file_to_trust = match args.call_info.evaluate(registry).await?.args.nth(0) {
|
let file_to_trust = match args.call_info.evaluate(&ctx).await?.args.nth(0) {
|
||||||
Some(Value {
|
Some(Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::String(ref path)),
|
value: UntaggedValue::Primitive(Primitive::String(ref path)),
|
||||||
tag: _,
|
tag: _,
|
||||||
|
@ -26,13 +26,10 @@ impl WholeStreamCommand for AutoenvUnTrust {
|
|||||||
"Untrust a .nu-env file in the current or given directory"
|
"Untrust a .nu-env file in the current or given directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let file_to_untrust = match args.call_info.evaluate(registry).await?.args.nth(0) {
|
let ctx = EvaluationContext::from_args(&args);
|
||||||
|
let file_to_untrust = match args.call_info.evaluate(&ctx).await?.args.nth(0) {
|
||||||
Some(Value {
|
Some(Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::String(ref path)),
|
value: UntaggedValue::Primitive(Primitive::String(ref path)),
|
||||||
tag: _,
|
tag: _,
|
||||||
|
@ -5,7 +5,7 @@ use crate::primitive::get_color_config;
|
|||||||
use nu_data::value::format_leaf;
|
use nu_data::value::format_leaf;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{self, Expression, ExternalRedirection, Literal, SpannedExpression};
|
use nu_protocol::hir::{self, Expression, ExternalRedirection, Literal, SpannedExpression};
|
||||||
use nu_protocol::{Primitive, Scope, Signature, UntaggedValue, Value};
|
use nu_protocol::{Primitive, Signature, UntaggedValue, Value};
|
||||||
use nu_table::TextStyle;
|
use nu_table::TextStyle;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
@ -26,20 +26,15 @@ impl WholeStreamCommand for Command {
|
|||||||
"View the contents of the pipeline as a table or list."
|
"View the contents of the pipeline as a table or list."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
autoview(RunnableContext {
|
autoview(RunnableContext {
|
||||||
input: args.input,
|
input: args.input,
|
||||||
registry: registry.clone(),
|
scope: args.scope.clone(),
|
||||||
shell_manager: args.shell_manager,
|
shell_manager: args.shell_manager,
|
||||||
host: args.host,
|
host: args.host,
|
||||||
ctrl_c: args.ctrl_c,
|
ctrl_c: args.ctrl_c,
|
||||||
current_errors: args.current_errors,
|
current_errors: args.current_errors,
|
||||||
name: args.call_info.name_tag,
|
name: args.call_info.name_tag,
|
||||||
raw_input: args.raw_input,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@ -65,7 +60,7 @@ pub struct RunnableContextWithoutInput {
|
|||||||
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
||||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||||
pub ctrl_c: Arc<AtomicBool>,
|
pub ctrl_c: Arc<AtomicBool>,
|
||||||
pub registry: CommandRegistry,
|
pub scope: Scope,
|
||||||
pub name: Tag,
|
pub name: Tag,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +71,7 @@ impl RunnableContextWithoutInput {
|
|||||||
host: context.host,
|
host: context.host,
|
||||||
ctrl_c: context.ctrl_c,
|
ctrl_c: context.ctrl_c,
|
||||||
current_errors: context.current_errors,
|
current_errors: context.current_errors,
|
||||||
registry: context.registry,
|
scope: context.scope,
|
||||||
name: context.name,
|
name: context.name,
|
||||||
};
|
};
|
||||||
(context.input, new_context)
|
(context.input, new_context)
|
||||||
@ -109,7 +104,7 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
|||||||
|
|
||||||
if let Some(table) = table {
|
if let Some(table) = table {
|
||||||
let command_args = create_default_command_args(&context).with_input(stream);
|
let command_args = create_default_command_args(&context).with_input(stream);
|
||||||
let result = table.run(command_args, &context.registry).await?;
|
let result = table.run(command_args).await?;
|
||||||
result.collect::<Vec<_>>().await;
|
result.collect::<Vec<_>>().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,7 +121,7 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
|||||||
);
|
);
|
||||||
let command_args =
|
let command_args =
|
||||||
create_default_command_args(&context).with_input(stream);
|
create_default_command_args(&context).with_input(stream);
|
||||||
let result = text.run(command_args, &context.registry).await?;
|
let result = text.run(command_args).await?;
|
||||||
result.collect::<Vec<_>>().await;
|
result.collect::<Vec<_>>().await;
|
||||||
} else {
|
} else {
|
||||||
out!("{}", s);
|
out!("{}", s);
|
||||||
@ -149,7 +144,7 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
|||||||
);
|
);
|
||||||
let command_args =
|
let command_args =
|
||||||
create_default_command_args(&context).with_input(stream);
|
create_default_command_args(&context).with_input(stream);
|
||||||
let result = text.run(command_args, &context.registry).await?;
|
let result = text.run(command_args).await?;
|
||||||
result.collect::<Vec<_>>().await;
|
result.collect::<Vec<_>>().await;
|
||||||
} else {
|
} else {
|
||||||
out!("{}\n", s);
|
out!("{}\n", s);
|
||||||
@ -224,7 +219,7 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
|||||||
stream.push_back(x);
|
stream.push_back(x);
|
||||||
let command_args =
|
let command_args =
|
||||||
create_default_command_args(&context).with_input(stream);
|
create_default_command_args(&context).with_input(stream);
|
||||||
let result = binary.run(command_args, &context.registry).await?;
|
let result = binary.run(command_args).await?;
|
||||||
result.collect::<Vec<_>>().await;
|
result.collect::<Vec<_>>().await;
|
||||||
} else {
|
} else {
|
||||||
use pretty_hex::*;
|
use pretty_hex::*;
|
||||||
@ -276,7 +271,12 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
|||||||
|
|
||||||
nu_table::draw_table(&table, term_width, &color_hm);
|
nu_table::draw_table(&table, term_width, &color_hm);
|
||||||
}
|
}
|
||||||
|
Value {
|
||||||
|
value: UntaggedValue::Primitive(Primitive::Nothing),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
Value {
|
Value {
|
||||||
value: ref item, ..
|
value: ref item, ..
|
||||||
} => {
|
} => {
|
||||||
@ -285,7 +285,7 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
|||||||
stream.push_back(x);
|
stream.push_back(x);
|
||||||
let command_args =
|
let command_args =
|
||||||
create_default_command_args(&context).with_input(stream);
|
create_default_command_args(&context).with_input(stream);
|
||||||
let result = table.run(command_args, &context.registry).await?;
|
let result = table.run(command_args).await?;
|
||||||
result.collect::<Vec<_>>().await;
|
result.collect::<Vec<_>>().await;
|
||||||
} else {
|
} else {
|
||||||
out!("{:?}", item);
|
out!("{:?}", item);
|
||||||
@ -318,8 +318,8 @@ fn create_default_command_args(context: &RunnableContextWithoutInput) -> RawComm
|
|||||||
external_redirection: ExternalRedirection::Stdout,
|
external_redirection: ExternalRedirection::Stdout,
|
||||||
},
|
},
|
||||||
name_tag: context.name.clone(),
|
name_tag: context.name.clone(),
|
||||||
scope: Scope::create(),
|
|
||||||
},
|
},
|
||||||
|
scope: Scope::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ use crate::prelude::*;
|
|||||||
use heim::cpu::time;
|
use heim::cpu::time;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::{Block, ClassifiedCommand, Commands, InternalCommand},
|
hir::{Block, CapturedBlock, ClassifiedCommand, Group, InternalCommand, Pipeline},
|
||||||
Dictionary, Scope, Signature, SyntaxShape, UntaggedValue, Value,
|
Dictionary, Signature, SyntaxShape, UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use rand::{
|
use rand::{
|
||||||
distributions::Alphanumeric,
|
distributions::Alphanumeric,
|
||||||
@ -19,8 +19,8 @@ pub struct Benchmark;
|
|||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct BenchmarkArgs {
|
struct BenchmarkArgs {
|
||||||
block: Block,
|
block: CapturedBlock,
|
||||||
passthrough: Option<Block>,
|
passthrough: Option<CapturedBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@ -48,12 +48,8 @@ impl WholeStreamCommand for Benchmark {
|
|||||||
"Runs a block and returns the time it took to execute it"
|
"Runs a block and returns the time it took to execute it"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
benchmark(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
benchmark(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -72,29 +68,25 @@ impl WholeStreamCommand for Benchmark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn benchmark(
|
async fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
let tag = raw_args.call_info.args.span;
|
let tag = raw_args.call_info.args.span;
|
||||||
let mut context = EvaluationContext::from_raw(&raw_args, ®istry);
|
let mut context = EvaluationContext::from_raw(&raw_args);
|
||||||
let scope = raw_args.call_info.scope.clone();
|
let scope = raw_args.scope.clone();
|
||||||
let (BenchmarkArgs { block, passthrough }, input) = raw_args.process(®istry).await?;
|
let (BenchmarkArgs { block, passthrough }, input) = raw_args.process().await?;
|
||||||
|
|
||||||
let env = scope.env();
|
let env = scope.get_env_vars();
|
||||||
let name = generate_free_name(&env);
|
let name = generate_free_name(&env);
|
||||||
let mut env = IndexMap::new();
|
|
||||||
env.insert(name, generate_random_env_value());
|
scope.add_env_var(name, generate_random_env_value());
|
||||||
let scope = Scope::append_env(scope, env);
|
|
||||||
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
|
|
||||||
#[cfg(feature = "rich-benchmark")]
|
#[cfg(feature = "rich-benchmark")]
|
||||||
let start = time().await;
|
let start = time().await;
|
||||||
|
|
||||||
let result = run_block(&block, &mut context, input, scope.clone()).await;
|
context.scope.enter_scope();
|
||||||
|
let result = run_block(&block.block, &context, input).await;
|
||||||
|
context.scope.exit_scope();
|
||||||
let output = result?.into_vec().await;
|
let output = result?.into_vec().await;
|
||||||
|
|
||||||
#[cfg(feature = "rich-benchmark")]
|
#[cfg(feature = "rich-benchmark")]
|
||||||
@ -110,7 +102,7 @@ async fn benchmark(
|
|||||||
|
|
||||||
let real_time = into_big_int(end_time - start_time);
|
let real_time = into_big_int(end_time - start_time);
|
||||||
indexmap.insert("real time".to_string(), real_time);
|
indexmap.insert("real time".to_string(), real_time);
|
||||||
benchmark_output(indexmap, output, passthrough, &tag, &mut context, scope).await
|
benchmark_output(indexmap, output, passthrough, &tag, &mut context).await
|
||||||
}
|
}
|
||||||
// return advanced stats
|
// return advanced stats
|
||||||
#[cfg(feature = "rich-benchmark")]
|
#[cfg(feature = "rich-benchmark")]
|
||||||
@ -129,10 +121,10 @@ async fn benchmark(
|
|||||||
let idle_time = into_big_int(end.idle() - start.idle());
|
let idle_time = into_big_int(end.idle() - start.idle());
|
||||||
indexmap.insert("idle time".to_string(), idle_time);
|
indexmap.insert("idle time".to_string(), idle_time);
|
||||||
|
|
||||||
benchmark_output(indexmap, output, passthrough, &tag, &mut context, scope).await
|
benchmark_output(indexmap, output, passthrough, &tag, &mut context).await
|
||||||
} else {
|
} else {
|
||||||
Err(ShellError::untagged_runtime_error(
|
Err(ShellError::untagged_runtime_error(
|
||||||
"Could not retreive CPU time",
|
"Could not retrieve CPU time",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,10 +132,9 @@ async fn benchmark(
|
|||||||
async fn benchmark_output<T, Output>(
|
async fn benchmark_output<T, Output>(
|
||||||
indexmap: IndexMap<String, BigInt>,
|
indexmap: IndexMap<String, BigInt>,
|
||||||
block_output: Output,
|
block_output: Output,
|
||||||
passthrough: Option<Block>,
|
passthrough: Option<CapturedBlock>,
|
||||||
tag: T,
|
tag: T,
|
||||||
context: &mut EvaluationContext,
|
context: &mut EvaluationContext,
|
||||||
scope: Arc<Scope>,
|
|
||||||
) -> Result<OutputStream, ShellError>
|
) -> Result<OutputStream, ShellError>
|
||||||
where
|
where
|
||||||
T: Into<Tag> + Copy,
|
T: Into<Tag> + Copy,
|
||||||
@ -161,9 +152,12 @@ where
|
|||||||
let benchmark_output = InputStream::one(value);
|
let benchmark_output = InputStream::one(value);
|
||||||
|
|
||||||
// add autoview for an empty block
|
// add autoview for an empty block
|
||||||
let time_block = add_implicit_autoview(time_block);
|
let time_block = add_implicit_autoview(time_block.block);
|
||||||
|
|
||||||
let _ = run_block(&time_block, context, benchmark_output, scope).await?;
|
context.scope.enter_scope();
|
||||||
|
let result = run_block(&time_block, context, benchmark_output).await;
|
||||||
|
context.scope.exit_scope();
|
||||||
|
result?;
|
||||||
context.clear_errors();
|
context.clear_errors();
|
||||||
|
|
||||||
Ok(block_output.into())
|
Ok(block_output.into())
|
||||||
@ -175,15 +169,19 @@ where
|
|||||||
|
|
||||||
fn add_implicit_autoview(mut block: Block) -> Block {
|
fn add_implicit_autoview(mut block: Block) -> Block {
|
||||||
if block.block.is_empty() {
|
if block.block.is_empty() {
|
||||||
block.push({
|
let group = Group::new(
|
||||||
let mut commands = Commands::new(block.span);
|
vec![{
|
||||||
commands.push(ClassifiedCommand::Internal(InternalCommand::new(
|
let mut commands = Pipeline::new(block.span);
|
||||||
"autoview".to_string(),
|
commands.push(ClassifiedCommand::Internal(InternalCommand::new(
|
||||||
block.span,
|
"autoview".to_string(),
|
||||||
block.span,
|
block.span,
|
||||||
)));
|
block.span,
|
||||||
commands
|
)));
|
||||||
});
|
commands
|
||||||
|
}],
|
||||||
|
block.span,
|
||||||
|
);
|
||||||
|
block.push(group);
|
||||||
}
|
}
|
||||||
block
|
block
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,9 @@ impl WholeStreamCommand for BuildString {
|
|||||||
"Builds a string from the arguments"
|
"Builds a string from the arguments"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let (BuildStringArgs { rest }, _) = args.process(®istry).await?;
|
let (BuildStringArgs { rest }, _) = args.process().await?;
|
||||||
|
|
||||||
let mut output_string = String::new();
|
let mut output_string = String::new();
|
||||||
|
|
||||||
|
@ -41,12 +41,8 @@ impl WholeStreamCommand for Cal {
|
|||||||
"Display a calendar."
|
"Display a calendar."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
cal(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
cal(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -70,12 +66,8 @@ impl WholeStreamCommand for Cal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cal(
|
pub async fn cal(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let mut calendar_vec_deque = VecDeque::new();
|
let mut calendar_vec_deque = VecDeque::new();
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
|
@ -32,14 +32,10 @@ impl WholeStreamCommand for Cd {
|
|||||||
"Change to a new path."
|
"Change to a new path."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let shell_manager = args.shell_manager.clone();
|
let shell_manager = args.shell_manager.clone();
|
||||||
let (args, _): (CdArgs, _) = args.process(®istry).await?;
|
let (args, _): (CdArgs, _) = args.process().await?;
|
||||||
shell_manager.cd(args, name)
|
shell_manager.cd(args, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +56,8 @@ impl WholeStreamCommand for Char {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let (CharArgs { name, unicode }, _) = args.process().await?;
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let (CharArgs { name, unicode }, _) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
if unicode {
|
if unicode {
|
||||||
let decoded_char = string_to_unicode_char(&name.item);
|
let decoded_char = string_to_unicode_char(&name.item);
|
||||||
|
@ -20,20 +20,15 @@ impl WholeStreamCommand for Chart {
|
|||||||
"Displays charts."
|
"Displays charts."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
if args.scope.get_command("chart bar").is_none() {
|
||||||
_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
if registry.get_command("chart bar").is_none() {
|
|
||||||
return Err(ShellError::untagged_runtime_error(
|
return Err(ShellError::untagged_runtime_error(
|
||||||
"nu_plugin_chart not installed.",
|
"nu_plugin_chart not installed.",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let registry = registry.clone();
|
|
||||||
Ok(OutputStream::one(Ok(ReturnSuccess::Value(
|
Ok(OutputStream::one(Ok(ReturnSuccess::Value(
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&Chart, ®istry))
|
UntaggedValue::string(crate::commands::help::get_help(&Chart, &args.scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
|
@ -2,39 +2,68 @@ use crate::commands::classified::expr::run_expression_block;
|
|||||||
use crate::commands::classified::internal::run_internal_command;
|
use crate::commands::classified::internal::run_internal_command;
|
||||||
use crate::evaluation_context::EvaluationContext;
|
use crate::evaluation_context::EvaluationContext;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::stream::InputStream;
|
use async_recursion::async_recursion;
|
||||||
use futures::stream::TryStreamExt;
|
use futures::stream::TryStreamExt;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{Block, ClassifiedCommand, Commands};
|
use nu_protocol::hir::{
|
||||||
use nu_protocol::{ReturnSuccess, Scope, UntaggedValue, Value};
|
Block, Call, ClassifiedCommand, Expression, Pipeline, SpannedExpression, Synthetic,
|
||||||
|
};
|
||||||
|
use nu_protocol::{ReturnSuccess, UntaggedValue, Value};
|
||||||
|
use nu_stream::InputStream;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
#[async_recursion]
|
||||||
pub async fn run_block(
|
pub async fn run_block(
|
||||||
block: &Block,
|
block: &Block,
|
||||||
ctx: &mut EvaluationContext,
|
ctx: &EvaluationContext,
|
||||||
mut input: InputStream,
|
mut input: InputStream,
|
||||||
scope: Arc<Scope>,
|
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
let mut output: Result<InputStream, ShellError> = Ok(InputStream::empty());
|
let mut output: Result<InputStream, ShellError> = Ok(InputStream::empty());
|
||||||
for pipeline in &block.block {
|
for (_, definition) in block.definitions.iter() {
|
||||||
|
ctx.scope.add_definition(definition.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
for group in &block.block {
|
||||||
match output {
|
match output {
|
||||||
Ok(inp) if inp.is_empty() => {}
|
Ok(inp) if inp.is_empty() => {}
|
||||||
Ok(inp) => {
|
Ok(inp) => {
|
||||||
let mut output_stream = inp.to_output_stream();
|
// Run autoview on the values we've seen so far
|
||||||
|
// We may want to make this configurable for other kinds of hosting
|
||||||
loop {
|
if let Some(autoview) = ctx.get_command("autoview") {
|
||||||
|
let mut output_stream = match ctx
|
||||||
|
.run_command(
|
||||||
|
autoview,
|
||||||
|
Tag::unknown(),
|
||||||
|
Call::new(
|
||||||
|
Box::new(SpannedExpression::new(
|
||||||
|
Expression::Synthetic(Synthetic::String("autoview".into())),
|
||||||
|
Span::unknown(),
|
||||||
|
)),
|
||||||
|
Span::unknown(),
|
||||||
|
),
|
||||||
|
inp,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
match output_stream.try_next().await {
|
match output_stream.try_next().await {
|
||||||
Ok(Some(ReturnSuccess::Value(Value {
|
Ok(Some(ReturnSuccess::Value(Value {
|
||||||
value: UntaggedValue::Error(e),
|
value: UntaggedValue::Error(e),
|
||||||
..
|
..
|
||||||
}))) => return Err(e),
|
}))) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
Ok(Some(_item)) => {
|
Ok(Some(_item)) => {
|
||||||
if let Some(err) = ctx.get_errors().get(0) {
|
if let Some(err) = ctx.get_errors().get(0) {
|
||||||
ctx.clear_errors();
|
ctx.clear_errors();
|
||||||
return Err(err.clone());
|
return Err(err.clone());
|
||||||
}
|
}
|
||||||
if ctx.ctrl_c.load(Ordering::SeqCst) {
|
if ctx.ctrl_c.load(Ordering::SeqCst) {
|
||||||
break;
|
return Ok(InputStream::empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
@ -42,9 +71,10 @@ pub async fn run_block(
|
|||||||
ctx.clear_errors();
|
ctx.clear_errors();
|
||||||
return Err(err.clone());
|
return Err(err.clone());
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e),
|
Err(e) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,35 +82,131 @@ pub async fn run_block(
|
|||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output = run_pipeline(pipeline, ctx, input, scope.clone()).await;
|
output = Ok(InputStream::empty());
|
||||||
|
for pipeline in &group.pipelines {
|
||||||
|
match output {
|
||||||
|
Ok(inp) if inp.is_empty() => {}
|
||||||
|
Ok(inp) => {
|
||||||
|
let mut output_stream = inp.to_output_stream();
|
||||||
|
|
||||||
input = InputStream::empty();
|
match output_stream.try_next().await {
|
||||||
|
Ok(Some(ReturnSuccess::Value(Value {
|
||||||
|
value: UntaggedValue::Error(e),
|
||||||
|
..
|
||||||
|
}))) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
Ok(Some(_item)) => {
|
||||||
|
if let Some(err) = ctx.get_errors().get(0) {
|
||||||
|
ctx.clear_errors();
|
||||||
|
return Err(err.clone());
|
||||||
|
}
|
||||||
|
if ctx.ctrl_c.load(Ordering::SeqCst) {
|
||||||
|
// This early return doesn't return the result
|
||||||
|
// we have so far, but breaking out of this loop
|
||||||
|
// causes lifetime issues. A future contribution
|
||||||
|
// could attempt to return the current output.
|
||||||
|
// https://github.com/nushell/nushell/pull/2830#discussion_r550319687
|
||||||
|
return Ok(InputStream::empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
if let Some(err) = ctx.get_errors().get(0) {
|
||||||
|
ctx.clear_errors();
|
||||||
|
return Err(err.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output = run_pipeline(pipeline, ctx, input).await;
|
||||||
|
|
||||||
|
input = InputStream::empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_recursion]
|
||||||
async fn run_pipeline(
|
async fn run_pipeline(
|
||||||
commands: &Commands,
|
commands: &Pipeline,
|
||||||
ctx: &mut EvaluationContext,
|
ctx: &EvaluationContext,
|
||||||
mut input: InputStream,
|
mut input: InputStream,
|
||||||
scope: Arc<Scope>,
|
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
for item in commands.list.clone() {
|
for item in commands.list.clone() {
|
||||||
input = match item {
|
input = match item {
|
||||||
ClassifiedCommand::Dynamic(_) => {
|
ClassifiedCommand::Dynamic(call) => {
|
||||||
return Err(ShellError::unimplemented("Dynamic commands"))
|
let mut args = vec![];
|
||||||
|
if let Some(positional) = call.positional {
|
||||||
|
for pos in &positional {
|
||||||
|
let result = run_expression_block(pos, ctx).await?.into_vec().await;
|
||||||
|
args.push(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &call.head.expr {
|
||||||
|
Expression::Block(block) => {
|
||||||
|
ctx.scope.enter_scope();
|
||||||
|
for (param, value) in block.params.positional.iter().zip(args.iter()) {
|
||||||
|
ctx.scope.add_var(param.0.name(), value[0].clone());
|
||||||
|
}
|
||||||
|
let result = run_block(&block, ctx, input).await;
|
||||||
|
ctx.scope.exit_scope();
|
||||||
|
|
||||||
|
let result = result?;
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
Expression::Variable(v, span) => {
|
||||||
|
if let Some(value) = ctx.scope.get_var(v) {
|
||||||
|
match &value.value {
|
||||||
|
UntaggedValue::Block(captured_block) => {
|
||||||
|
ctx.scope.enter_scope();
|
||||||
|
ctx.scope.add_vars(&captured_block.captured.entries);
|
||||||
|
for (param, value) in captured_block
|
||||||
|
.block
|
||||||
|
.params
|
||||||
|
.positional
|
||||||
|
.iter()
|
||||||
|
.zip(args.iter())
|
||||||
|
{
|
||||||
|
ctx.scope.add_var(param.0.name(), value[0].clone());
|
||||||
|
}
|
||||||
|
let result = run_block(&captured_block.block, ctx, input).await;
|
||||||
|
ctx.scope.exit_scope();
|
||||||
|
|
||||||
|
let result = result?;
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(ShellError::labeled_error("Dynamic commands must start with a block (or variable pointing to a block)", "needs to be a block", call.head.span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"Variable not found",
|
||||||
|
"variable not found",
|
||||||
|
span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(ShellError::labeled_error("Dynamic commands must start with a block (or variable pointing to a block)", "needs to be a block", call.head.span));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassifiedCommand::Expr(expr) => {
|
ClassifiedCommand::Expr(expr) => run_expression_block(&*expr, ctx).await?,
|
||||||
run_expression_block(*expr, ctx, scope.clone()).await?
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassifiedCommand::Error(err) => return Err(err.into()),
|
ClassifiedCommand::Error(err) => return Err(err.into()),
|
||||||
|
|
||||||
ClassifiedCommand::Internal(left) => {
|
ClassifiedCommand::Internal(left) => run_internal_command(left, ctx, input).await?,
|
||||||
run_internal_command(left, ctx, input, scope.clone()).await?
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,20 +6,17 @@ use log::{log_enabled, trace};
|
|||||||
use futures::stream::once;
|
use futures::stream::once;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::SpannedExpression;
|
use nu_protocol::hir::SpannedExpression;
|
||||||
use nu_protocol::Scope;
|
|
||||||
|
|
||||||
pub(crate) async fn run_expression_block(
|
pub(crate) async fn run_expression_block(
|
||||||
expr: SpannedExpression,
|
expr: &SpannedExpression,
|
||||||
context: &mut EvaluationContext,
|
ctx: &EvaluationContext,
|
||||||
scope: Arc<Scope>,
|
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
if log_enabled!(log::Level::Trace) {
|
if log_enabled!(log::Level::Trace) {
|
||||||
trace!(target: "nu::run::expr", "->");
|
trace!(target: "nu::run::expr", "->");
|
||||||
trace!(target: "nu::run::expr", "{:?}", expr);
|
trace!(target: "nu::run::expr", "{:?}", expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let registry = context.registry().clone();
|
let output = evaluate_baseline_expr(expr, ctx).await?;
|
||||||
let output = evaluate_baseline_expr(&expr, ®istry, scope).await?;
|
|
||||||
|
|
||||||
Ok(once(async { Ok(output) }).to_input_stream())
|
Ok(once(async { Ok(output) }).to_input_stream())
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,13 @@ use log::trace;
|
|||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::Expression;
|
use nu_protocol::hir::Expression;
|
||||||
use nu_protocol::hir::{ExternalCommand, ExternalRedirection};
|
use nu_protocol::hir::{ExternalCommand, ExternalRedirection};
|
||||||
use nu_protocol::{Primitive, Scope, ShellTypeName, UntaggedValue, Value};
|
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
|
||||||
use nu_source::Tag;
|
use nu_source::Tag;
|
||||||
|
|
||||||
pub(crate) async fn run_external_command(
|
pub(crate) async fn run_external_command(
|
||||||
command: ExternalCommand,
|
command: ExternalCommand,
|
||||||
context: &mut EvaluationContext,
|
context: &mut EvaluationContext,
|
||||||
input: InputStream,
|
input: InputStream,
|
||||||
scope: Arc<Scope>,
|
|
||||||
external_redirection: ExternalRedirection,
|
external_redirection: ExternalRedirection,
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
trace!(target: "nu::run::external", "-> {}", command.name);
|
trace!(target: "nu::run::external", "-> {}", command.name);
|
||||||
@ -36,14 +35,13 @@ pub(crate) async fn run_external_command(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
run_with_stdin(command, context, input, scope, external_redirection).await
|
run_with_stdin(command, context, input, external_redirection).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_with_stdin(
|
async fn run_with_stdin(
|
||||||
command: ExternalCommand,
|
command: ExternalCommand,
|
||||||
context: &mut EvaluationContext,
|
context: &mut EvaluationContext,
|
||||||
input: InputStream,
|
input: InputStream,
|
||||||
scope: Arc<Scope>,
|
|
||||||
external_redirection: ExternalRedirection,
|
external_redirection: ExternalRedirection,
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
let path = context.shell_manager.path();
|
let path = context.shell_manager.path();
|
||||||
@ -53,7 +51,7 @@ async fn run_with_stdin(
|
|||||||
let mut command_args = vec![];
|
let mut command_args = vec![];
|
||||||
for arg in command.args.iter() {
|
for arg in command.args.iter() {
|
||||||
let is_literal = matches!(arg.expr, Expression::Literal(_));
|
let is_literal = matches!(arg.expr, Expression::Literal(_));
|
||||||
let value = evaluate_baseline_expr(arg, &context.registry, scope.clone()).await?;
|
let value = evaluate_baseline_expr(arg, context).await?;
|
||||||
|
|
||||||
// Skip any arguments that don't really exist, treating them as optional
|
// Skip any arguments that don't really exist, treating them as optional
|
||||||
// FIXME: we may want to preserve the gap in the future, though it's hard to say
|
// FIXME: we may want to preserve the gap in the future, though it's hard to say
|
||||||
@ -132,7 +130,7 @@ async fn run_with_stdin(
|
|||||||
&process_args[..],
|
&process_args[..],
|
||||||
input,
|
input,
|
||||||
external_redirection,
|
external_redirection,
|
||||||
scope,
|
&context.scope,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +140,7 @@ fn spawn(
|
|||||||
args: &[String],
|
args: &[String],
|
||||||
input: InputStream,
|
input: InputStream,
|
||||||
external_redirection: ExternalRedirection,
|
external_redirection: ExternalRedirection,
|
||||||
scope: Arc<Scope>,
|
scope: &Scope,
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
let command = command.clone();
|
let command = command.clone();
|
||||||
|
|
||||||
@ -173,7 +171,7 @@ fn spawn(
|
|||||||
trace!(target: "nu::run::external", "cwd = {:?}", &path);
|
trace!(target: "nu::run::external", "cwd = {:?}", &path);
|
||||||
|
|
||||||
process.env_clear();
|
process.env_clear();
|
||||||
process.envs(scope.env());
|
process.envs(scope.get_env_vars());
|
||||||
|
|
||||||
// We want stdout regardless of what
|
// We want stdout regardless of what
|
||||||
// we are doing ($it case or pipe stdin)
|
// we are doing ($it case or pipe stdin)
|
||||||
@ -542,8 +540,6 @@ mod tests {
|
|||||||
#[cfg(feature = "which")]
|
#[cfg(feature = "which")]
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
#[cfg(feature = "which")]
|
#[cfg(feature = "which")]
|
||||||
use nu_protocol::Scope;
|
|
||||||
#[cfg(feature = "which")]
|
|
||||||
use nu_test_support::commands::ExternalBuilder;
|
use nu_test_support::commands::ExternalBuilder;
|
||||||
|
|
||||||
// async fn read(mut stream: OutputStream) -> Option<Value> {
|
// async fn read(mut stream: OutputStream) -> Option<Value> {
|
||||||
@ -568,15 +564,11 @@ mod tests {
|
|||||||
let mut ctx =
|
let mut ctx =
|
||||||
EvaluationContext::basic().expect("There was a problem creating a basic context.");
|
EvaluationContext::basic().expect("There was a problem creating a basic context.");
|
||||||
|
|
||||||
assert!(run_external_command(
|
assert!(
|
||||||
cmd,
|
run_external_command(cmd, &mut ctx, input, ExternalRedirection::Stdout)
|
||||||
&mut ctx,
|
.await
|
||||||
input,
|
.is_err()
|
||||||
Scope::create(),
|
);
|
||||||
ExternalRedirection::Stdout
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.is_err());
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use crate::commands::command::whole_stream_command;
|
use std::sync::atomic::Ordering;
|
||||||
use crate::commands::run_alias::AliasCommand;
|
|
||||||
use crate::commands::UnevaluatedCallInfo;
|
use crate::commands::UnevaluatedCallInfo;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::{log_enabled, trace};
|
use log::{log_enabled, trace};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{ExternalRedirection, InternalCommand};
|
use nu_protocol::hir::{ExternalRedirection, InternalCommand};
|
||||||
use nu_protocol::{CommandAction, Primitive, ReturnSuccess, Scope, UntaggedValue, Value};
|
use nu_protocol::{CommandAction, Primitive, ReturnSuccess, UntaggedValue, Value};
|
||||||
|
|
||||||
pub(crate) async fn run_internal_command(
|
pub(crate) async fn run_internal_command(
|
||||||
command: InternalCommand,
|
command: InternalCommand,
|
||||||
context: &mut EvaluationContext,
|
context: &EvaluationContext,
|
||||||
input: InputStream,
|
input: InputStream,
|
||||||
scope: Arc<Scope>,
|
|
||||||
) -> Result<InputStream, ShellError> {
|
) -> Result<InputStream, ShellError> {
|
||||||
if log_enabled!(log::Level::Trace) {
|
if log_enabled!(log::Level::Trace) {
|
||||||
trace!(target: "nu::run::internal", "->");
|
trace!(target: "nu::run::internal", "->");
|
||||||
@ -19,10 +18,13 @@ pub(crate) async fn run_internal_command(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let objects: InputStream = trace_stream!(target: "nu::trace_stream::internal", "input" = input);
|
let objects: InputStream = trace_stream!(target: "nu::trace_stream::internal", "input" = input);
|
||||||
let internal_command = context.expect_command(&command.name);
|
|
||||||
|
let internal_command = context.scope.expect_command(&command.name);
|
||||||
|
|
||||||
if command.name == "autoenv untrust" {
|
if command.name == "autoenv untrust" {
|
||||||
context.user_recently_used_autoenv_untrust = true;
|
context
|
||||||
|
.user_recently_used_autoenv_untrust
|
||||||
|
.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = {
|
let result = {
|
||||||
@ -31,14 +33,12 @@ pub(crate) async fn run_internal_command(
|
|||||||
internal_command?,
|
internal_command?,
|
||||||
Tag::unknown_anchor(command.name_span),
|
Tag::unknown_anchor(command.name_span),
|
||||||
command.args.clone(),
|
command.args.clone(),
|
||||||
scope.clone(),
|
|
||||||
objects,
|
objects,
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
let head = Arc::new(command.args.head.clone());
|
let head = Arc::new(command.args.head.clone());
|
||||||
//let context = Arc::new(context.clone());
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let command = Arc::new(command);
|
let command = Arc::new(command);
|
||||||
|
|
||||||
@ -47,26 +47,24 @@ pub(crate) async fn run_internal_command(
|
|||||||
.then(move |item| {
|
.then(move |item| {
|
||||||
let head = head.clone();
|
let head = head.clone();
|
||||||
let command = command.clone();
|
let command = command.clone();
|
||||||
let mut context = context.clone();
|
let context = context.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
async move {
|
async move {
|
||||||
match item {
|
match item {
|
||||||
Ok(ReturnSuccess::Action(action)) => match action {
|
Ok(ReturnSuccess::Action(action)) => match action {
|
||||||
CommandAction::ChangePath(path) => {
|
CommandAction::ChangePath(path) => {
|
||||||
context.shell_manager.set_path(path);
|
context.shell_manager.set_path(path);
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
CommandAction::Exit => std::process::exit(0), // TODO: save history.txt
|
CommandAction::Exit => std::process::exit(0), // TODO: save history.txt
|
||||||
CommandAction::Error(err) => {
|
CommandAction::Error(err) => {
|
||||||
context.error(err.clone());
|
context.error(err);
|
||||||
InputStream::one(UntaggedValue::Error(err).into_untagged_value())
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
CommandAction::AutoConvert(tagged_contents, extension) => {
|
CommandAction::AutoConvert(tagged_contents, extension) => {
|
||||||
let contents_tag = tagged_contents.tag.clone();
|
let contents_tag = tagged_contents.tag.clone();
|
||||||
let command_name = format!("from {}", extension);
|
let command_name = format!("from {}", extension);
|
||||||
let command = command.clone();
|
let command = command.clone();
|
||||||
if let Some(converter) = context.registry.get_command(&command_name)
|
if let Some(converter) = context.scope.get_command(&command_name) {
|
||||||
{
|
|
||||||
let new_args = RawCommandArgs {
|
let new_args = RawCommandArgs {
|
||||||
host: context.host.clone(),
|
host: context.host.clone(),
|
||||||
ctrl_c: context.ctrl_c.clone(),
|
ctrl_c: context.ctrl_c.clone(),
|
||||||
@ -81,14 +79,11 @@ pub(crate) async fn run_internal_command(
|
|||||||
external_redirection: ExternalRedirection::Stdout,
|
external_redirection: ExternalRedirection::Stdout,
|
||||||
},
|
},
|
||||||
name_tag: Tag::unknown_anchor(command.name_span),
|
name_tag: Tag::unknown_anchor(command.name_span),
|
||||||
scope,
|
|
||||||
},
|
},
|
||||||
|
scope: context.scope.clone(),
|
||||||
};
|
};
|
||||||
let result = converter
|
let result = converter
|
||||||
.run(
|
.run(new_args.with_input(vec![tagged_contents]))
|
||||||
new_args.with_input(vec![tagged_contents]),
|
|
||||||
&context.registry,
|
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
@ -122,8 +117,8 @@ pub(crate) async fn run_internal_command(
|
|||||||
|
|
||||||
futures::stream::iter(output).to_input_stream()
|
futures::stream::iter(output).to_input_stream()
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(err) => {
|
||||||
context.add_error(e);
|
context.error(err);
|
||||||
InputStream::empty()
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,13 +134,12 @@ pub(crate) async fn run_internal_command(
|
|||||||
context.shell_manager.insert_at_current(Box::new(
|
context.shell_manager.insert_at_current(Box::new(
|
||||||
match HelpShell::for_command(
|
match HelpShell::for_command(
|
||||||
UntaggedValue::string(cmd).into_value(tag),
|
UntaggedValue::string(cmd).into_value(tag),
|
||||||
&context.registry(),
|
&context.scope,
|
||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return InputStream::one(
|
context.error(err);
|
||||||
UntaggedValue::Error(err).into_untagged_value(),
|
return InputStream::empty();
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
@ -153,12 +147,11 @@ pub(crate) async fn run_internal_command(
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
context.shell_manager.insert_at_current(Box::new(
|
context.shell_manager.insert_at_current(Box::new(
|
||||||
match HelpShell::index(&context.registry()) {
|
match HelpShell::index(&context.scope) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return InputStream::one(
|
context.error(err);
|
||||||
UntaggedValue::Error(err).into_untagged_value(),
|
return InputStream::empty();
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
@ -176,21 +169,13 @@ pub(crate) async fn run_internal_command(
|
|||||||
match FilesystemShell::with_location(location) {
|
match FilesystemShell::with_location(location) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return InputStream::one(
|
context.error(err.into());
|
||||||
UntaggedValue::Error(err.into())
|
return InputStream::empty();
|
||||||
.into_untagged_value(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
||||||
}
|
}
|
||||||
CommandAction::AddAlias(sig, block) => {
|
|
||||||
context.add_commands(vec![whole_stream_command(
|
|
||||||
AliasCommand::new(*sig, block),
|
|
||||||
)]);
|
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
||||||
}
|
|
||||||
CommandAction::AddPlugins(path) => {
|
CommandAction::AddPlugins(path) => {
|
||||||
match crate::plugin::scan(vec![std::path::PathBuf::from(path)]) {
|
match crate::plugin::scan(vec![std::path::PathBuf::from(path)]) {
|
||||||
Ok(plugins) => {
|
Ok(plugins) => {
|
||||||
@ -203,39 +188,37 @@ pub(crate) async fn run_internal_command(
|
|||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
|
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
context.error(reason.clone());
|
context.error(reason);
|
||||||
InputStream::one(
|
InputStream::empty()
|
||||||
UntaggedValue::Error(reason).into_untagged_value(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandAction::PreviousShell => {
|
CommandAction::PreviousShell => {
|
||||||
context.shell_manager.prev();
|
context.shell_manager.prev();
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
CommandAction::NextShell => {
|
CommandAction::NextShell => {
|
||||||
context.shell_manager.next();
|
context.shell_manager.next();
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
CommandAction::LeaveShell => {
|
CommandAction::LeaveShell => {
|
||||||
context.shell_manager.remove_at_current();
|
context.shell_manager.remove_at_current();
|
||||||
if context.shell_manager.is_empty() {
|
if context.shell_manager.is_empty() {
|
||||||
std::process::exit(0); // TODO: save history.txt
|
std::process::exit(0); // TODO: save history.txt
|
||||||
}
|
}
|
||||||
InputStream::from_stream(futures::stream::iter(vec![]))
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Ok(ReturnSuccess::Value(Value {
|
Ok(ReturnSuccess::Value(Value {
|
||||||
value: UntaggedValue::Error(err),
|
value: UntaggedValue::Error(err),
|
||||||
tag,
|
..
|
||||||
})) => {
|
})) => {
|
||||||
context.error(err.clone());
|
context.error(err);
|
||||||
InputStream::one(UntaggedValue::Error(err).into_value(tag))
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ReturnSuccess::Value(v)) => InputStream::one(v),
|
Ok(ReturnSuccess::Value(v)) => InputStream::one(v),
|
||||||
@ -255,8 +238,8 @@ pub(crate) async fn run_internal_command(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
context.error(err.clone());
|
context.error(err);
|
||||||
InputStream::one(UntaggedValue::Error(err).into_untagged_value())
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,24 +104,13 @@ impl WholeStreamCommand for PluginFilter {
|
|||||||
&self.config.usage
|
&self.config.usage
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
run_filter(self.path.clone(), (args)).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
run_filter(self.path.clone(), args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_filter(
|
async fn run_filter(path: String, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
path: String,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
trace!("filter_plugin :: {}", path);
|
trace!("filter_plugin :: {}", path);
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
let scope = args.call_info.scope.clone();
|
|
||||||
|
|
||||||
let bos = futures::stream::iter(vec![
|
let bos = futures::stream::iter(vec![
|
||||||
UntaggedValue::Primitive(Primitive::BeginningOfStream).into_untagged_value()
|
UntaggedValue::Primitive(Primitive::BeginningOfStream).into_untagged_value()
|
||||||
@ -130,7 +119,7 @@ async fn run_filter(
|
|||||||
UntaggedValue::Primitive(Primitive::EndOfStream).into_untagged_value()
|
UntaggedValue::Primitive(Primitive::EndOfStream).into_untagged_value()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let args = args.evaluate_once_with_scope(®istry, scope).await?;
|
let args = args.evaluate_once().await?;
|
||||||
|
|
||||||
let real_path = Path::new(&path);
|
let real_path = Path::new(&path);
|
||||||
let ext = real_path.extension();
|
let ext = real_path.extension();
|
||||||
@ -390,22 +379,13 @@ impl WholeStreamCommand for PluginSink {
|
|||||||
&self.config.usage
|
&self.config.usage
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
run_sink(self.path.clone(), args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
run_sink(self.path.clone(), args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_sink(
|
async fn run_sink(path: String, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
path: String,
|
let args = args.evaluate_once().await?;
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let call_info = args.call_info.clone();
|
let call_info = args.call_info.clone();
|
||||||
|
|
||||||
let input: Vec<Value> = args.input.collect().await;
|
let input: Vec<Value> = args.input.collect().await;
|
||||||
|
@ -20,7 +20,7 @@ impl WholeStreamCommand for Clear {
|
|||||||
"Clears the terminal"
|
"Clears the terminal"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(&self, _: CommandArgs, _: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn run(&self, _: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
Command::new("cmd")
|
Command::new("cmd")
|
||||||
.args(&["/C", "cls"])
|
.args(&["/C", "cls"])
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Signature, Value};
|
use nu_protocol::{Signature, Value};
|
||||||
|
|
||||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
use arboard::Clipboard;
|
||||||
|
|
||||||
pub struct Clip;
|
pub struct Clip;
|
||||||
|
|
||||||
@ -23,12 +22,8 @@ impl WholeStreamCommand for Clip {
|
|||||||
"Copy the contents of the pipeline to the copy/paste buffer"
|
"Copy the contents of the pipeline to the copy/paste buffer"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
clip(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
clip(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -47,16 +42,12 @@ impl WholeStreamCommand for Clip {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clip(
|
pub async fn clip(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let values: Vec<Value> = input.collect().await;
|
let values: Vec<Value> = input.collect().await;
|
||||||
|
|
||||||
if let Ok(clip_context) = ClipboardProvider::new() {
|
if let Ok(mut clip_context) = Clipboard::new() {
|
||||||
let mut clip_context: ClipboardContext = clip_context;
|
|
||||||
let mut new_copy_data = String::new();
|
let mut new_copy_data = String::new();
|
||||||
|
|
||||||
if !values.is_empty() {
|
if !values.is_empty() {
|
||||||
@ -81,7 +72,7 @@ pub async fn clip(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match clip_context.set_contents(new_copy_data) {
|
match clip_context.set_text(new_copy_data) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::help::get_help;
|
|
||||||
use crate::deserializer::ConfigDeserializer;
|
use crate::deserializer::ConfigDeserializer;
|
||||||
use crate::evaluate::evaluate_args::evaluate_args;
|
use crate::evaluate::evaluate_args::evaluate_args;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::{commands::help::get_help, run_block};
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use getset::Getters;
|
use getset::Getters;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir;
|
use nu_protocol::hir::{self, Block};
|
||||||
use nu_protocol::{CallInfo, EvaluatedArgs, ReturnSuccess, Scope, Signature, UntaggedValue, Value};
|
use nu_protocol::{CallInfo, EvaluatedArgs, ReturnSuccess, Signature, UntaggedValue, Value};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::Deserialize;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct UnevaluatedCallInfo {
|
pub struct UnevaluatedCallInfo {
|
||||||
pub args: hir::Call,
|
pub args: hir::Call,
|
||||||
pub name_tag: Tag,
|
pub name_tag: Tag,
|
||||||
pub scope: Arc<Scope>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnevaluatedCallInfo {
|
impl UnevaluatedCallInfo {
|
||||||
pub async fn evaluate(self, registry: &CommandRegistry) -> Result<CallInfo, ShellError> {
|
pub async fn evaluate(self, ctx: &EvaluationContext) -> Result<CallInfo, ShellError> {
|
||||||
let args = evaluate_args(&self.args, registry, self.scope.clone()).await?;
|
let args = evaluate_args(&self.args, ctx).await?;
|
||||||
|
|
||||||
Ok(CallInfo {
|
Ok(CallInfo {
|
||||||
args,
|
args,
|
||||||
@ -43,8 +41,8 @@ pub struct CommandArgs {
|
|||||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||||
pub shell_manager: ShellManager,
|
pub shell_manager: ShellManager,
|
||||||
pub call_info: UnevaluatedCallInfo,
|
pub call_info: UnevaluatedCallInfo,
|
||||||
|
pub scope: Scope,
|
||||||
pub input: InputStream,
|
pub input: InputStream,
|
||||||
pub raw_input: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Getters, Clone)]
|
#[derive(Getters, Clone)]
|
||||||
@ -54,6 +52,7 @@ pub struct RawCommandArgs {
|
|||||||
pub ctrl_c: Arc<AtomicBool>,
|
pub ctrl_c: Arc<AtomicBool>,
|
||||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||||
pub shell_manager: ShellManager,
|
pub shell_manager: ShellManager,
|
||||||
|
pub scope: Scope,
|
||||||
pub call_info: UnevaluatedCallInfo,
|
pub call_info: UnevaluatedCallInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,8 +64,8 @@ impl RawCommandArgs {
|
|||||||
current_errors: self.current_errors,
|
current_errors: self.current_errors,
|
||||||
shell_manager: self.shell_manager,
|
shell_manager: self.shell_manager,
|
||||||
call_info: self.call_info,
|
call_info: self.call_info,
|
||||||
|
scope: self.scope,
|
||||||
input: input.into(),
|
input: input.into(),
|
||||||
raw_input: String::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,15 +77,14 @@ impl std::fmt::Debug for CommandArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CommandArgs {
|
impl CommandArgs {
|
||||||
pub async fn evaluate_once(
|
pub async fn evaluate_once(self) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
|
||||||
self,
|
let ctx = EvaluationContext::from_args(&self);
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
|
|
||||||
let host = self.host.clone();
|
let host = self.host.clone();
|
||||||
let ctrl_c = self.ctrl_c.clone();
|
let ctrl_c = self.ctrl_c.clone();
|
||||||
let shell_manager = self.shell_manager.clone();
|
let shell_manager = self.shell_manager.clone();
|
||||||
let input = self.input;
|
let input = self.input;
|
||||||
let call_info = self.call_info.evaluate(registry).await?;
|
let call_info = self.call_info.evaluate(&ctx).await?;
|
||||||
|
let scope = self.scope.clone();
|
||||||
|
|
||||||
Ok(EvaluatedWholeStreamCommandArgs::new(
|
Ok(EvaluatedWholeStreamCommandArgs::new(
|
||||||
host,
|
host,
|
||||||
@ -94,39 +92,12 @@ impl CommandArgs {
|
|||||||
shell_manager,
|
shell_manager,
|
||||||
call_info,
|
call_info,
|
||||||
input,
|
input,
|
||||||
|
scope,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn evaluate_once_with_scope(
|
pub async fn process<'de, T: Deserialize<'de>>(self) -> Result<(T, InputStream), ShellError> {
|
||||||
self,
|
let args = self.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
scope: Arc<Scope>,
|
|
||||||
) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
|
|
||||||
let host = self.host.clone();
|
|
||||||
let ctrl_c = self.ctrl_c.clone();
|
|
||||||
let shell_manager = self.shell_manager.clone();
|
|
||||||
let input = self.input;
|
|
||||||
let call_info = UnevaluatedCallInfo {
|
|
||||||
name_tag: self.call_info.name_tag,
|
|
||||||
args: self.call_info.args,
|
|
||||||
scope: scope.clone(),
|
|
||||||
};
|
|
||||||
let call_info = call_info.evaluate(registry).await?;
|
|
||||||
|
|
||||||
Ok(EvaluatedWholeStreamCommandArgs::new(
|
|
||||||
host,
|
|
||||||
ctrl_c,
|
|
||||||
shell_manager,
|
|
||||||
call_info,
|
|
||||||
input,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn process<'de, T: Deserialize<'de>>(
|
|
||||||
self,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<(T, InputStream), ShellError> {
|
|
||||||
let args = self.evaluate_once(registry).await?;
|
|
||||||
let call_info = args.call_info.clone();
|
let call_info = args.call_info.clone();
|
||||||
|
|
||||||
let mut deserializer = ConfigDeserializer::from_call_info(call_info);
|
let mut deserializer = ConfigDeserializer::from_call_info(call_info);
|
||||||
@ -141,14 +112,13 @@ pub struct RunnableContext {
|
|||||||
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
||||||
pub ctrl_c: Arc<AtomicBool>,
|
pub ctrl_c: Arc<AtomicBool>,
|
||||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||||
pub registry: CommandRegistry,
|
pub scope: Scope,
|
||||||
pub name: Tag,
|
pub name: Tag,
|
||||||
pub raw_input: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunnableContext {
|
impl RunnableContext {
|
||||||
pub fn get_command(&self, name: &str) -> Option<Command> {
|
pub fn get_command(&self, name: &str) -> Option<Command> {
|
||||||
self.registry.get_command(name)
|
self.scope.get_command(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +141,7 @@ impl EvaluatedWholeStreamCommandArgs {
|
|||||||
shell_manager: ShellManager,
|
shell_manager: ShellManager,
|
||||||
call_info: CallInfo,
|
call_info: CallInfo,
|
||||||
input: impl Into<InputStream>,
|
input: impl Into<InputStream>,
|
||||||
|
scope: Scope,
|
||||||
) -> EvaluatedWholeStreamCommandArgs {
|
) -> EvaluatedWholeStreamCommandArgs {
|
||||||
EvaluatedWholeStreamCommandArgs {
|
EvaluatedWholeStreamCommandArgs {
|
||||||
args: EvaluatedCommandArgs {
|
args: EvaluatedCommandArgs {
|
||||||
@ -178,6 +149,7 @@ impl EvaluatedWholeStreamCommandArgs {
|
|||||||
ctrl_c,
|
ctrl_c,
|
||||||
shell_manager,
|
shell_manager,
|
||||||
call_info,
|
call_info,
|
||||||
|
scope,
|
||||||
},
|
},
|
||||||
input: input.into(),
|
input: input.into(),
|
||||||
}
|
}
|
||||||
@ -207,6 +179,7 @@ pub struct EvaluatedCommandArgs {
|
|||||||
pub ctrl_c: Arc<AtomicBool>,
|
pub ctrl_c: Arc<AtomicBool>,
|
||||||
pub shell_manager: ShellManager,
|
pub shell_manager: ShellManager,
|
||||||
pub call_info: CallInfo,
|
pub call_info: CallInfo,
|
||||||
|
pub scope: Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EvaluatedCommandArgs {
|
impl EvaluatedCommandArgs {
|
||||||
@ -247,11 +220,7 @@ pub trait WholeStreamCommand: Send + Sync {
|
|||||||
|
|
||||||
fn usage(&self) -> &str;
|
fn usage(&self) -> &str;
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError>;
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError>;
|
|
||||||
|
|
||||||
fn is_binary(&self) -> bool {
|
fn is_binary(&self) -> bool {
|
||||||
false
|
false
|
||||||
@ -267,6 +236,97 @@ pub trait WholeStreamCommand: Send + Sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom commands are blocks, so we can use the information in the block to also
|
||||||
|
// implement a WholeStreamCommand
|
||||||
|
#[allow(clippy::suspicious_else_formatting)]
|
||||||
|
#[async_trait]
|
||||||
|
impl WholeStreamCommand for Block {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
&self.params.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
self.params.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
let call_info = args.call_info.clone();
|
||||||
|
|
||||||
|
let mut block = self.clone();
|
||||||
|
block.set_redirect(call_info.args.external_redirection);
|
||||||
|
|
||||||
|
let ctx = EvaluationContext::from_args(&args);
|
||||||
|
let evaluated = call_info.evaluate(&ctx).await?;
|
||||||
|
|
||||||
|
let input = args.input;
|
||||||
|
ctx.scope.enter_scope();
|
||||||
|
if let Some(args) = evaluated.args.positional {
|
||||||
|
// FIXME: do not do this
|
||||||
|
for arg in args.into_iter().zip(self.params.positional.iter()) {
|
||||||
|
let name = arg.1 .0.name();
|
||||||
|
|
||||||
|
if name.starts_with('$') {
|
||||||
|
ctx.scope.add_var(name, arg.0);
|
||||||
|
} else {
|
||||||
|
ctx.scope.add_var(format!("${}", name), arg.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(args) = evaluated.args.named {
|
||||||
|
for named in &block.params.named {
|
||||||
|
let name = named.0;
|
||||||
|
if let Some(value) = args.get(name) {
|
||||||
|
if name.starts_with('$') {
|
||||||
|
ctx.scope.add_var(name, value.clone());
|
||||||
|
} else {
|
||||||
|
ctx.scope.add_var(format!("${}", name), value.clone());
|
||||||
|
}
|
||||||
|
} else if name.starts_with('$') {
|
||||||
|
ctx.scope
|
||||||
|
.add_var(name, UntaggedValue::nothing().into_untagged_value());
|
||||||
|
} else {
|
||||||
|
ctx.scope.add_var(
|
||||||
|
format!("${}", name),
|
||||||
|
UntaggedValue::nothing().into_untagged_value(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for named in &block.params.named {
|
||||||
|
let name = named.0;
|
||||||
|
if name.starts_with('$') {
|
||||||
|
ctx.scope
|
||||||
|
.add_var(name, UntaggedValue::nothing().into_untagged_value());
|
||||||
|
} else {
|
||||||
|
ctx.scope.add_var(
|
||||||
|
format!("${}", name),
|
||||||
|
UntaggedValue::nothing().into_untagged_value(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let result = run_block(&block, &ctx, input).await;
|
||||||
|
ctx.scope.exit_scope();
|
||||||
|
result.map(|x| x.to_output_stream())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_binary(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_internal(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Command(Arc<dyn WholeStreamCommand>);
|
pub struct Command(Arc<dyn WholeStreamCommand>);
|
||||||
|
|
||||||
@ -306,19 +366,14 @@ impl Command {
|
|||||||
self.0.examples()
|
self.0.examples()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(
|
pub async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
if args.call_info.switch_present("help") {
|
if args.call_info.switch_present("help") {
|
||||||
let cl = self.0.clone();
|
let cl = self.0.clone();
|
||||||
let registry = registry.clone();
|
|
||||||
Ok(OutputStream::one(Ok(ReturnSuccess::Value(
|
Ok(OutputStream::one(Ok(ReturnSuccess::Value(
|
||||||
UntaggedValue::string(get_help(&*cl, ®istry)).into_value(Tag::unknown()),
|
UntaggedValue::string(get_help(&*cl, &args.scope)).into_value(Tag::unknown()),
|
||||||
))))
|
))))
|
||||||
} else {
|
} else {
|
||||||
self.0.run(args, registry).await
|
self.0.run(args).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures::future;
|
use futures::future;
|
||||||
@ -28,12 +27,8 @@ impl WholeStreamCommand for Compact {
|
|||||||
"Creates a table with non-empty rows"
|
"Creates a table with non-empty rows"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
compact(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
compact(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -45,12 +40,8 @@ impl WholeStreamCommand for Compact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn compact(
|
pub async fn compact(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let (CompactArgs { rest: columns }, input) = args.process().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let (CompactArgs { rest: columns }, input) = args.process(®istry).await?;
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.filter_map(move |item| {
|
.filter_map(move |item| {
|
||||||
future::ready(if columns.is_empty() {
|
future::ready(if columns.is_empty() {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -20,12 +19,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"clear the config"
|
"clear the config"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
clear(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
clear(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -37,10 +32,7 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clear(
|
pub async fn clear(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{CommandArgs, CommandRegistry, OutputStream};
|
use crate::{CommandArgs, OutputStream};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||||
|
|
||||||
@ -20,11 +20,7 @@ impl WholeStreamCommand for Command {
|
|||||||
"Configuration management."
|
"Configuration management."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
let name = args.call_info.name_tag;
|
let name = args.call_info.name_tag;
|
||||||
let result = nu_data::config::read(name_span, &None)?;
|
let result = nu_data::config::read(name_span, &None)?;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -29,12 +28,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Gets a value from the config"
|
"Gets a value from the config"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
get(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
get(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -46,12 +41,9 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_tag = args.call_info.name_tag.clone();
|
let name_tag = args.call_info.name_tag.clone();
|
||||||
let (GetArgs { path }, _) = args.process(®istry).await?;
|
let (GetArgs { path }, _) = args.process().await?;
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -31,22 +30,15 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Loads the config from the path given"
|
"Loads the config from the path given"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
set(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
set(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set(
|
pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
let (LoadArgs { load }, _) = args.process(®istry).await?;
|
let (LoadArgs { load }, _) = args.process().await?;
|
||||||
|
|
||||||
let configuration = load.item().clone();
|
let configuration = load.item().clone();
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -20,12 +19,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"return the path to the config file"
|
"return the path to the config file"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
path(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
path(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -37,10 +32,7 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn path(
|
pub async fn path(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let path = config::default_path()?;
|
let path = config::default_path()?;
|
||||||
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -30,12 +29,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Removes a value from the config"
|
"Removes a value from the config"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
remove(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
remove(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -47,12 +42,9 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove(
|
pub async fn remove(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
let (RemoveArgs { remove }, _) = args.process(®istry).await?;
|
let (RemoveArgs { remove }, _) = args.process().await?;
|
||||||
|
|
||||||
let mut result = nu_data::config::read(name_span, &None)?;
|
let mut result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -28,12 +27,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Sets a value in the config"
|
"Sets a value in the config"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
set(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
set(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -62,12 +57,9 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set(
|
pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_tag = args.call_info.name_tag.clone();
|
let name_tag = args.call_info.name_tag.clone();
|
||||||
let (SetArgs { path, mut value }, _) = args.process(®istry).await?;
|
let (SetArgs { path, mut value }, _) = args.process().await?;
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -30,12 +29,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Sets a value in the config"
|
"Sets a value in the config"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
set_into(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
set_into(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -47,14 +42,11 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_into(
|
pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
let (SetIntoArgs { set_into: v }, input) = args.process(®istry).await?;
|
let (SetIntoArgs { set_into: v }, input) = args.process().await?;
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
@ -30,13 +29,9 @@ impl WholeStreamCommand for Count {
|
|||||||
"Show the total number of rows or items."
|
"Show the total number of rows or items."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let (CountArgs { column }, input) = args.process(®istry).await?;
|
let (CountArgs { column }, input) = args.process().await?;
|
||||||
let rows: Vec<Value> = input.collect().await;
|
let rows: Vec<Value> = input.collect().await;
|
||||||
|
|
||||||
let count = if column {
|
let count = if column {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -36,14 +35,10 @@ impl WholeStreamCommand for Cpy {
|
|||||||
"Copy files."
|
"Copy files."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let shell_manager = args.shell_manager.clone();
|
let shell_manager = args.shell_manager.clone();
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let (args, _) = args.process(®istry).await?;
|
let (args, _) = args.process().await?;
|
||||||
shell_manager.cp(args, name)
|
shell_manager.cp(args, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,15 +19,9 @@ impl WholeStreamCommand for Command {
|
|||||||
"Apply date function"
|
"Apply date function"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&Command, ®istry))
|
UntaggedValue::string(crate::commands::help::get_help(&Command, &args.scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,8 @@ impl WholeStreamCommand for Date {
|
|||||||
"Format a given date using the given format string."
|
"Format a given date using the given format string."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
format(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
format(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -55,13 +51,9 @@ impl WholeStreamCommand for Date {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn format(
|
pub async fn format(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let (FormatArgs { format, table }, input) = args.process(®istry).await?;
|
let (FormatArgs { format, table }, input) = args.process().await?;
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.map(move |value| match value {
|
.map(move |value| match value {
|
||||||
|
@ -21,12 +21,8 @@ impl WholeStreamCommand for Date {
|
|||||||
"List supported time zones."
|
"List supported time zones."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
list_timezone(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
list_timezone(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -45,11 +41,8 @@ impl WholeStreamCommand for Date {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn list_timezone(
|
async fn list_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
let list = TZ_VARIANTS.iter().map(move |tz| {
|
let list = TZ_VARIANTS.iter().map(move |tz| {
|
||||||
|
@ -20,20 +20,13 @@ impl WholeStreamCommand for Date {
|
|||||||
"Get the current date."
|
"Get the current date."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
now(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
now(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn now(
|
pub async fn now(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
let now: DateTime<Local> = Local::now();
|
let now: DateTime<Local> = Local::now();
|
||||||
|
@ -21,12 +21,8 @@ impl WholeStreamCommand for Date {
|
|||||||
"Print the date in a structured table."
|
"Print the date in a structured table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
to_table(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
to_table(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -38,12 +34,8 @@ impl WholeStreamCommand for Date {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn to_table(
|
async fn to_table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -33,12 +33,8 @@ Use `date list-timezone` to list all supported time zones.
|
|||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
to_timezone(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
to_timezone(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -62,13 +58,9 @@ Use `date list-timezone` to list all supported time zones.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn to_timezone(
|
async fn to_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let (DateToTimeZoneArgs { timezone }, input) = args.process(®istry).await?;
|
let (DateToTimeZoneArgs { timezone }, input) = args.process().await?;
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.map(move |value| match value {
|
.map(move |value| match value {
|
||||||
|
55
crates/nu-cli/src/commands/date/utc.rs
Normal file
55
crates/nu-cli/src/commands/date/utc.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
|
||||||
|
use crate::commands::date::utils::date_to_value;
|
||||||
|
use crate::commands::WholeStreamCommand;
|
||||||
|
use nu_protocol::Signature;
|
||||||
|
|
||||||
|
pub struct Date;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl WholeStreamCommand for Date {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"date utc"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("date utc")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"return the current date in utc."
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
utc(args).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn utc(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
let args = args.evaluate_once().await?;
|
||||||
|
let tag = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
|
let no_fmt = "".to_string();
|
||||||
|
|
||||||
|
let value = {
|
||||||
|
let local: DateTime<Utc> = Utc::now();
|
||||||
|
date_to_value(local, tag, no_fmt)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(OutputStream::one(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::Date;
|
||||||
|
use super::ShellError;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||||
|
use crate::examples::test as test_examples;
|
||||||
|
|
||||||
|
Ok(test_examples(Date {})?)
|
||||||
|
}
|
||||||
|
}
|
@ -24,21 +24,13 @@ impl WholeStreamCommand for Debug {
|
|||||||
"Print the Rust debug representation of the values"
|
"Print the Rust debug representation of the values"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
debug_value(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
debug_value(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn debug_value(
|
async fn debug_value(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let (DebugArgs { raw }, input) = args.process().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let (DebugArgs { raw }, input) = args.process(®istry).await?;
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.map(move |v| {
|
.map(move |v| {
|
||||||
if raw {
|
if raw {
|
||||||
|
48
crates/nu-cli/src/commands/def.rs
Normal file
48
crates/nu-cli/src/commands/def.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use crate::commands::WholeStreamCommand;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
use nu_protocol::{hir::CapturedBlock, Signature, SyntaxShape, Value};
|
||||||
|
use nu_source::Tagged;
|
||||||
|
|
||||||
|
pub struct Def;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct DefArgs {
|
||||||
|
pub name: Tagged<String>,
|
||||||
|
pub args: Tagged<Vec<Value>>,
|
||||||
|
pub block: CapturedBlock,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl WholeStreamCommand for Def {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"def"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("def")
|
||||||
|
.required("name", SyntaxShape::String, "the name of the command")
|
||||||
|
.required(
|
||||||
|
"params",
|
||||||
|
SyntaxShape::Table,
|
||||||
|
"the parameters of the command",
|
||||||
|
)
|
||||||
|
.required("block", SyntaxShape::Block, "the body of the command")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Create a command and set it to a definition."
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(&self, _args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
// Currently, we don't do anything here because we should have already
|
||||||
|
// installed the definition as we entered the scope
|
||||||
|
// We just create a command so that we can get proper coloring
|
||||||
|
Ok(OutputStream::empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -34,12 +33,8 @@ impl WholeStreamCommand for Default {
|
|||||||
"Sets a default row's column if missing."
|
"Sets a default row's column if missing."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
default(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
default(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -51,12 +46,8 @@ impl WholeStreamCommand for Default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn default(
|
async fn default(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let (DefaultArgs { column, value }, input) = args.process().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let (DefaultArgs { column, value }, input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.map(move |item| {
|
.map(move |item| {
|
||||||
|
248
crates/nu-cli/src/commands/default_context.rs
Normal file
248
crates/nu-cli/src/commands/default_context.rs
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Box<dyn Error>> {
|
||||||
|
let context = EvaluationContext::basic()?;
|
||||||
|
|
||||||
|
{
|
||||||
|
use crate::commands::*;
|
||||||
|
|
||||||
|
context.add_commands(vec![
|
||||||
|
// Fundamentals
|
||||||
|
whole_stream_command(NuPlugin),
|
||||||
|
whole_stream_command(Let),
|
||||||
|
whole_stream_command(LetEnv),
|
||||||
|
whole_stream_command(Def),
|
||||||
|
whole_stream_command(Source),
|
||||||
|
// System/file operations
|
||||||
|
whole_stream_command(Exec),
|
||||||
|
whole_stream_command(Pwd),
|
||||||
|
whole_stream_command(Ls),
|
||||||
|
whole_stream_command(Du),
|
||||||
|
whole_stream_command(Cd),
|
||||||
|
whole_stream_command(Remove),
|
||||||
|
whole_stream_command(Open),
|
||||||
|
whole_stream_command(Config),
|
||||||
|
whole_stream_command(ConfigGet),
|
||||||
|
whole_stream_command(ConfigSet),
|
||||||
|
whole_stream_command(ConfigSetInto),
|
||||||
|
whole_stream_command(ConfigClear),
|
||||||
|
whole_stream_command(ConfigLoad),
|
||||||
|
whole_stream_command(ConfigRemove),
|
||||||
|
whole_stream_command(ConfigPath),
|
||||||
|
whole_stream_command(Help),
|
||||||
|
whole_stream_command(History),
|
||||||
|
whole_stream_command(Save),
|
||||||
|
whole_stream_command(Touch),
|
||||||
|
whole_stream_command(Cpy),
|
||||||
|
whole_stream_command(Date),
|
||||||
|
whole_stream_command(DateListTimeZone),
|
||||||
|
whole_stream_command(DateNow),
|
||||||
|
whole_stream_command(DateToTable),
|
||||||
|
whole_stream_command(DateToTimeZone),
|
||||||
|
whole_stream_command(DateFormat),
|
||||||
|
whole_stream_command(Cal),
|
||||||
|
whole_stream_command(Mkdir),
|
||||||
|
whole_stream_command(Mv),
|
||||||
|
whole_stream_command(Kill),
|
||||||
|
whole_stream_command(Version),
|
||||||
|
whole_stream_command(Clear),
|
||||||
|
whole_stream_command(Describe),
|
||||||
|
whole_stream_command(Which),
|
||||||
|
whole_stream_command(Debug),
|
||||||
|
whole_stream_command(WithEnv),
|
||||||
|
whole_stream_command(Do),
|
||||||
|
whole_stream_command(Sleep),
|
||||||
|
// Statistics
|
||||||
|
whole_stream_command(Size),
|
||||||
|
whole_stream_command(Count),
|
||||||
|
whole_stream_command(Benchmark),
|
||||||
|
// Metadata
|
||||||
|
whole_stream_command(Tags),
|
||||||
|
// Shells
|
||||||
|
whole_stream_command(Next),
|
||||||
|
whole_stream_command(Previous),
|
||||||
|
whole_stream_command(Shells),
|
||||||
|
whole_stream_command(Enter),
|
||||||
|
whole_stream_command(Exit),
|
||||||
|
// Viz
|
||||||
|
whole_stream_command(Chart),
|
||||||
|
// Viewers
|
||||||
|
whole_stream_command(Autoview),
|
||||||
|
whole_stream_command(Table),
|
||||||
|
// Text manipulation
|
||||||
|
whole_stream_command(Hash),
|
||||||
|
whole_stream_command(HashBase64),
|
||||||
|
whole_stream_command(Split),
|
||||||
|
whole_stream_command(SplitColumn),
|
||||||
|
whole_stream_command(SplitRow),
|
||||||
|
whole_stream_command(SplitChars),
|
||||||
|
whole_stream_command(Lines),
|
||||||
|
whole_stream_command(Echo),
|
||||||
|
whole_stream_command(Parse),
|
||||||
|
whole_stream_command(Str),
|
||||||
|
whole_stream_command(StrToDecimal),
|
||||||
|
whole_stream_command(StrToInteger),
|
||||||
|
whole_stream_command(StrDowncase),
|
||||||
|
whole_stream_command(StrUpcase),
|
||||||
|
whole_stream_command(StrCapitalize),
|
||||||
|
whole_stream_command(StrFindReplace),
|
||||||
|
whole_stream_command(StrFrom),
|
||||||
|
whole_stream_command(StrSubstring),
|
||||||
|
whole_stream_command(StrSet),
|
||||||
|
whole_stream_command(StrToDatetime),
|
||||||
|
whole_stream_command(StrContains),
|
||||||
|
whole_stream_command(StrIndexOf),
|
||||||
|
whole_stream_command(StrTrim),
|
||||||
|
whole_stream_command(StrTrimLeft),
|
||||||
|
whole_stream_command(StrTrimRight),
|
||||||
|
whole_stream_command(StrStartsWith),
|
||||||
|
whole_stream_command(StrEndsWith),
|
||||||
|
whole_stream_command(StrCollect),
|
||||||
|
whole_stream_command(StrLength),
|
||||||
|
whole_stream_command(StrLPad),
|
||||||
|
whole_stream_command(StrReverse),
|
||||||
|
whole_stream_command(StrRPad),
|
||||||
|
whole_stream_command(StrCamelCase),
|
||||||
|
whole_stream_command(StrPascalCase),
|
||||||
|
whole_stream_command(StrKebabCase),
|
||||||
|
whole_stream_command(StrSnakeCase),
|
||||||
|
whole_stream_command(StrScreamingSnakeCase),
|
||||||
|
whole_stream_command(BuildString),
|
||||||
|
whole_stream_command(Ansi),
|
||||||
|
whole_stream_command(Char),
|
||||||
|
// Column manipulation
|
||||||
|
whole_stream_command(Move),
|
||||||
|
whole_stream_command(Reject),
|
||||||
|
whole_stream_command(Select),
|
||||||
|
whole_stream_command(Get),
|
||||||
|
whole_stream_command(Update),
|
||||||
|
whole_stream_command(Insert),
|
||||||
|
whole_stream_command(IntoInt),
|
||||||
|
whole_stream_command(SplitBy),
|
||||||
|
// Row manipulation
|
||||||
|
whole_stream_command(Reverse),
|
||||||
|
whole_stream_command(Append),
|
||||||
|
whole_stream_command(Prepend),
|
||||||
|
whole_stream_command(SortBy),
|
||||||
|
whole_stream_command(GroupBy),
|
||||||
|
whole_stream_command(GroupByDate),
|
||||||
|
whole_stream_command(First),
|
||||||
|
whole_stream_command(Last),
|
||||||
|
whole_stream_command(Every),
|
||||||
|
whole_stream_command(Nth),
|
||||||
|
whole_stream_command(Drop),
|
||||||
|
whole_stream_command(Format),
|
||||||
|
whole_stream_command(FileSize),
|
||||||
|
whole_stream_command(Where),
|
||||||
|
whole_stream_command(If),
|
||||||
|
whole_stream_command(Compact),
|
||||||
|
whole_stream_command(Default),
|
||||||
|
whole_stream_command(Skip),
|
||||||
|
whole_stream_command(SkipUntil),
|
||||||
|
whole_stream_command(SkipWhile),
|
||||||
|
whole_stream_command(Keep),
|
||||||
|
whole_stream_command(KeepUntil),
|
||||||
|
whole_stream_command(KeepWhile),
|
||||||
|
whole_stream_command(Range),
|
||||||
|
whole_stream_command(Rename),
|
||||||
|
whole_stream_command(Uniq),
|
||||||
|
whole_stream_command(Each),
|
||||||
|
whole_stream_command(EachGroup),
|
||||||
|
whole_stream_command(EachWindow),
|
||||||
|
whole_stream_command(Empty),
|
||||||
|
// Table manipulation
|
||||||
|
whole_stream_command(Flatten),
|
||||||
|
whole_stream_command(Move),
|
||||||
|
whole_stream_command(Merge),
|
||||||
|
whole_stream_command(Shuffle),
|
||||||
|
whole_stream_command(Wrap),
|
||||||
|
whole_stream_command(Pivot),
|
||||||
|
whole_stream_command(Headers),
|
||||||
|
whole_stream_command(Reduce),
|
||||||
|
// Data processing
|
||||||
|
whole_stream_command(Histogram),
|
||||||
|
whole_stream_command(Autoenv),
|
||||||
|
whole_stream_command(AutoenvTrust),
|
||||||
|
whole_stream_command(AutoenvUnTrust),
|
||||||
|
whole_stream_command(Math),
|
||||||
|
whole_stream_command(MathAbs),
|
||||||
|
whole_stream_command(MathAverage),
|
||||||
|
whole_stream_command(MathEval),
|
||||||
|
whole_stream_command(MathMedian),
|
||||||
|
whole_stream_command(MathMinimum),
|
||||||
|
whole_stream_command(MathMode),
|
||||||
|
whole_stream_command(MathMaximum),
|
||||||
|
whole_stream_command(MathStddev),
|
||||||
|
whole_stream_command(MathSummation),
|
||||||
|
whole_stream_command(MathVariance),
|
||||||
|
whole_stream_command(MathProduct),
|
||||||
|
whole_stream_command(MathRound),
|
||||||
|
whole_stream_command(MathFloor),
|
||||||
|
whole_stream_command(MathCeil),
|
||||||
|
// File format output
|
||||||
|
whole_stream_command(To),
|
||||||
|
whole_stream_command(ToCSV),
|
||||||
|
whole_stream_command(ToHTML),
|
||||||
|
whole_stream_command(ToJSON),
|
||||||
|
whole_stream_command(ToMarkdown),
|
||||||
|
whole_stream_command(ToTOML),
|
||||||
|
whole_stream_command(ToTSV),
|
||||||
|
whole_stream_command(ToURL),
|
||||||
|
whole_stream_command(ToYAML),
|
||||||
|
whole_stream_command(ToXML),
|
||||||
|
// File format input
|
||||||
|
whole_stream_command(From),
|
||||||
|
whole_stream_command(FromCSV),
|
||||||
|
whole_stream_command(FromEML),
|
||||||
|
whole_stream_command(FromTSV),
|
||||||
|
whole_stream_command(FromSSV),
|
||||||
|
whole_stream_command(FromINI),
|
||||||
|
whole_stream_command(FromJSON),
|
||||||
|
whole_stream_command(FromODS),
|
||||||
|
whole_stream_command(FromTOML),
|
||||||
|
whole_stream_command(FromURL),
|
||||||
|
whole_stream_command(FromXLSX),
|
||||||
|
whole_stream_command(FromXML),
|
||||||
|
whole_stream_command(FromYAML),
|
||||||
|
whole_stream_command(FromYML),
|
||||||
|
whole_stream_command(FromIcs),
|
||||||
|
whole_stream_command(FromVcf),
|
||||||
|
// "Private" commands (not intended to be accessed directly)
|
||||||
|
whole_stream_command(RunExternalCommand { interactive }),
|
||||||
|
// Random value generation
|
||||||
|
whole_stream_command(Random),
|
||||||
|
whole_stream_command(RandomBool),
|
||||||
|
whole_stream_command(RandomDice),
|
||||||
|
#[cfg(feature = "uuid_crate")]
|
||||||
|
whole_stream_command(RandomUUID),
|
||||||
|
whole_stream_command(RandomInteger),
|
||||||
|
whole_stream_command(RandomDecimal),
|
||||||
|
whole_stream_command(RandomChars),
|
||||||
|
// Path
|
||||||
|
whole_stream_command(PathBasename),
|
||||||
|
whole_stream_command(PathCommand),
|
||||||
|
whole_stream_command(PathDirname),
|
||||||
|
whole_stream_command(PathExists),
|
||||||
|
whole_stream_command(PathExpand),
|
||||||
|
whole_stream_command(PathExtension),
|
||||||
|
whole_stream_command(PathFilestem),
|
||||||
|
whole_stream_command(PathType),
|
||||||
|
// Url
|
||||||
|
whole_stream_command(UrlCommand),
|
||||||
|
whole_stream_command(UrlScheme),
|
||||||
|
whole_stream_command(UrlPath),
|
||||||
|
whole_stream_command(UrlHost),
|
||||||
|
whole_stream_command(UrlQuery),
|
||||||
|
whole_stream_command(Seq),
|
||||||
|
whole_stream_command(SeqDates),
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[cfg(feature = "clipboard-cli")]
|
||||||
|
{
|
||||||
|
context.add_commands(vec![whole_stream_command(crate::commands::clip::Clip)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(context)
|
||||||
|
}
|
@ -23,19 +23,12 @@ impl WholeStreamCommand for Describe {
|
|||||||
"Describes the objects in the stream."
|
"Describes the objects in the stream."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
describe(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
describe(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn describe(
|
pub async fn describe(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
Ok(args
|
Ok(args
|
||||||
.input
|
.input
|
||||||
.map(|row| {
|
.map(|row| {
|
||||||
|
@ -2,15 +2,13 @@ use crate::commands::classified::block::run_block;
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{hir::CapturedBlock, hir::ExternalRedirection, Signature, SyntaxShape, Value};
|
||||||
hir::Block, hir::ExternalRedirection, ReturnSuccess, Signature, SyntaxShape, Value,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Do;
|
pub struct Do;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct DoArgs {
|
struct DoArgs {
|
||||||
block: Block,
|
block: CapturedBlock,
|
||||||
ignore_errors: bool,
|
ignore_errors: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +32,8 @@ impl WholeStreamCommand for Do {
|
|||||||
"Runs a block, optionally ignoring errors"
|
"Runs a block, optionally ignoring errors"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
do_(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
do_(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -52,28 +46,23 @@ impl WholeStreamCommand for Do {
|
|||||||
Example {
|
Example {
|
||||||
description: "Run the block and ignore errors",
|
description: "Run the block and ignore errors",
|
||||||
example: r#"do -i { thisisnotarealcommand }"#,
|
example: r#"do -i { thisisnotarealcommand }"#,
|
||||||
result: Some(vec![Value::nothing()]),
|
result: Some(vec![]),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn do_(
|
async fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||||
|
|
||||||
let mut context = EvaluationContext::from_raw(&raw_args, ®istry);
|
let context = EvaluationContext::from_raw(&raw_args);
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let (
|
let (
|
||||||
DoArgs {
|
DoArgs {
|
||||||
ignore_errors,
|
ignore_errors,
|
||||||
mut block,
|
mut block,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = raw_args.process(®istry).await?;
|
) = raw_args.process().await?;
|
||||||
|
|
||||||
let block_redirection = match external_redirection {
|
let block_redirection = match external_redirection {
|
||||||
ExternalRedirection::None => {
|
ExternalRedirection::None => {
|
||||||
@ -93,9 +82,10 @@ async fn do_(
|
|||||||
x => x,
|
x => x,
|
||||||
};
|
};
|
||||||
|
|
||||||
block.set_redirect(block_redirection);
|
block.block.set_redirect(block_redirection);
|
||||||
|
context.scope.enter_scope();
|
||||||
let result = run_block(&block, &mut context, input, scope).await;
|
let result = run_block(&block.block, &context, input).await;
|
||||||
|
context.scope.exit_scope();
|
||||||
|
|
||||||
if ignore_errors {
|
if ignore_errors {
|
||||||
// To properly ignore errors we need to redirect stderr, consume it, and remove
|
// To properly ignore errors we need to redirect stderr, consume it, and remove
|
||||||
@ -107,7 +97,7 @@ async fn do_(
|
|||||||
context.clear_errors();
|
context.clear_errors();
|
||||||
Ok(futures::stream::iter(output).to_output_stream())
|
Ok(futures::stream::iter(output).to_output_stream())
|
||||||
}
|
}
|
||||||
Err(_) => Ok(OutputStream::one(ReturnSuccess::value(Value::nothing()))),
|
Err(_) => Ok(OutputStream::empty()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.map(|x| x.to_output_stream())
|
result.map(|x| x.to_output_stream())
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -30,12 +29,8 @@ impl WholeStreamCommand for Drop {
|
|||||||
"Remove the last number of rows. If you want to remove columns, try 'reject'."
|
"Remove the last number of rows. If you want to remove columns, try 'reject'."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
drop(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
drop(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -57,8 +52,8 @@ impl WholeStreamCommand for Drop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn drop(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let (DropArgs { rows }, input) = args.process(®istry).await?;
|
let (DropArgs { rows }, input) = args.process().await?;
|
||||||
let v: Vec<_> = input.into_vec().await;
|
let v: Vec<_> = input.into_vec().await;
|
||||||
|
|
||||||
let rows_to_drop = if let Some(quantity) = rows {
|
let rows_to_drop = if let Some(quantity) = rows {
|
||||||
|
@ -73,12 +73,8 @@ impl WholeStreamCommand for Du {
|
|||||||
"Find disk usage sizes of specified items"
|
"Find disk usage sizes of specified items"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
du(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
du(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -90,13 +86,12 @@ impl WholeStreamCommand for Du {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn du(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn du(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let ctrl_c = args.ctrl_c.clone();
|
let ctrl_c = args.ctrl_c.clone();
|
||||||
let ctrl_c_copy = ctrl_c.clone();
|
let ctrl_c_copy = ctrl_c.clone();
|
||||||
|
|
||||||
let (args, _): (DuArgs, _) = args.process(®istry).await?;
|
let (args, _): (DuArgs, _) = args.process().await?;
|
||||||
let exclude = args.exclude.map_or(Ok(None), move |x| {
|
let exclude = args.exclude.map_or(Ok(None), move |x| {
|
||||||
Pattern::new(&x.item)
|
Pattern::new(&x.item)
|
||||||
.map(Option::Some)
|
.map(Option::Some)
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::classified::block::run_block;
|
use crate::commands::classified::block::run_block;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@ -6,7 +5,7 @@ use crate::prelude::*;
|
|||||||
use futures::stream::once;
|
use futures::stream::once;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::Block, Scope, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
hir::CapturedBlock, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ pub struct Each;
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EachArgs {
|
pub struct EachArgs {
|
||||||
block: Block,
|
block: CapturedBlock,
|
||||||
numbered: Tagged<bool>,
|
numbered: Tagged<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,12 +37,8 @@ impl WholeStreamCommand for Each {
|
|||||||
"Run a block on each row of the table."
|
"Run a block on each row of the table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
each(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
each(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -73,9 +68,8 @@ impl WholeStreamCommand for Each {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process_row(
|
pub async fn process_row(
|
||||||
block: Arc<Block>,
|
captured_block: Arc<Box<CapturedBlock>>,
|
||||||
scope: Arc<Scope>,
|
context: Arc<EvaluationContext>,
|
||||||
mut context: Arc<EvaluationContext>,
|
|
||||||
input: Value,
|
input: Value,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let input_clone = input.clone();
|
let input_clone = input.clone();
|
||||||
@ -83,24 +77,29 @@ pub async fn process_row(
|
|||||||
// a parameter to the block (so it gets assigned to a variable that can be used inside the block) or
|
// a parameter to the block (so it gets assigned to a variable that can be used inside the block) or
|
||||||
// if it wants the contents as as an input stream
|
// if it wants the contents as as an input stream
|
||||||
|
|
||||||
let input_stream = if !block.params.is_empty() {
|
let input_stream = if !captured_block.block.params.positional.is_empty() {
|
||||||
InputStream::empty()
|
InputStream::empty()
|
||||||
} else {
|
} else {
|
||||||
once(async { Ok(input_clone) }).to_input_stream()
|
once(async { Ok(input_clone) }).to_input_stream()
|
||||||
};
|
};
|
||||||
|
|
||||||
let scope = if !block.params.is_empty() {
|
context.scope.enter_scope();
|
||||||
// FIXME: add check for more than parameter, once that's supported
|
context.scope.add_vars(&captured_block.captured.entries);
|
||||||
Scope::append_var(scope, block.params[0].clone(), input)
|
|
||||||
} else {
|
|
||||||
scope
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(
|
if !captured_block.block.params.positional.is_empty() {
|
||||||
run_block(&block, Arc::make_mut(&mut context), input_stream, scope)
|
// FIXME: add check for more than parameter, once that's supported
|
||||||
.await?
|
context
|
||||||
.to_output_stream(),
|
.scope
|
||||||
)
|
.add_var(captured_block.block.params.positional[0].0.name(), input);
|
||||||
|
} else {
|
||||||
|
context.scope.add_var("$it", input);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = run_block(&captured_block.block, &*context, input_stream).await;
|
||||||
|
|
||||||
|
context.scope.exit_scope();
|
||||||
|
|
||||||
|
Ok(result?.to_output_stream())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
|
pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
|
||||||
@ -111,27 +110,22 @@ pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
|
|||||||
dict.into_value()
|
dict.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn each(
|
async fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
let context = Arc::new(EvaluationContext::from_raw(&raw_args));
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
let (each_args, input): (EachArgs, _) = raw_args.process().await?;
|
||||||
let registry = registry.clone();
|
let block = Arc::new(Box::new(each_args.block));
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&raw_args, ®istry));
|
|
||||||
let (each_args, input): (EachArgs, _) = raw_args.process(®istry).await?;
|
|
||||||
let block = Arc::new(each_args.block);
|
|
||||||
|
|
||||||
if each_args.numbered.item {
|
if each_args.numbered.item {
|
||||||
Ok(input
|
Ok(input
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.then(move |input| {
|
.then(move |input| {
|
||||||
let block = block.clone();
|
let block = block.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let row = make_indexed_item(input.0, input.1);
|
let row = make_indexed_item(input.0, input.1);
|
||||||
|
|
||||||
async {
|
async {
|
||||||
match process_row(block, scope, context, row).await {
|
match process_row(block, context, row).await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => OutputStream::one(Err(e)),
|
Err(e) => OutputStream::one(Err(e)),
|
||||||
}
|
}
|
||||||
@ -143,11 +137,10 @@ async fn each(
|
|||||||
Ok(input
|
Ok(input
|
||||||
.then(move |input| {
|
.then(move |input| {
|
||||||
let block = block.clone();
|
let block = block.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
|
|
||||||
async {
|
async {
|
||||||
match process_row(block, scope, context, input).await {
|
match process_row(block, context, input).await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => OutputStream::one(Err(e)),
|
Err(e) => OutputStream::one(Err(e)),
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ use crate::commands::each::process_row;
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{hir::Block, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{
|
||||||
|
hir::CapturedBlock, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||||
|
};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@ -11,7 +13,7 @@ pub struct EachGroup;
|
|||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EachGroupArgs {
|
pub struct EachGroupArgs {
|
||||||
group_size: Tagged<usize>,
|
group_size: Tagged<usize>,
|
||||||
block: Block,
|
block: CapturedBlock,
|
||||||
//numbered: Tagged<bool>,
|
//numbered: Tagged<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,22 +45,14 @@ impl WholeStreamCommand for EachGroup {
|
|||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let context = Arc::new(EvaluationContext::from_raw(&raw_args));
|
||||||
raw_args: CommandArgs,
|
let (each_args, input): (EachGroupArgs, _) = raw_args.process().await?;
|
||||||
registry: &CommandRegistry,
|
let block = Arc::new(Box::new(each_args.block));
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&raw_args, ®istry));
|
|
||||||
let (each_args, input): (EachGroupArgs, _) = raw_args.process(®istry).await?;
|
|
||||||
let block = Arc::new(each_args.block);
|
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.chunks(each_args.group_size.item)
|
.chunks(each_args.group_size.item)
|
||||||
.then(move |input| {
|
.then(move |input| run_block_on_vec(input, block.clone(), context.clone()))
|
||||||
run_block_on_vec(input, block.clone(), scope.clone(), context.clone())
|
|
||||||
})
|
|
||||||
.flatten()
|
.flatten()
|
||||||
.to_output_stream())
|
.to_output_stream())
|
||||||
}
|
}
|
||||||
@ -66,8 +60,7 @@ impl WholeStreamCommand for EachGroup {
|
|||||||
|
|
||||||
pub(crate) fn run_block_on_vec(
|
pub(crate) fn run_block_on_vec(
|
||||||
input: Vec<Value>,
|
input: Vec<Value>,
|
||||||
block: Arc<Block>,
|
block: Arc<Box<CapturedBlock>>,
|
||||||
scope: Arc<Scope>,
|
|
||||||
context: Arc<EvaluationContext>,
|
context: Arc<EvaluationContext>,
|
||||||
) -> impl Future<Output = OutputStream> {
|
) -> impl Future<Output = OutputStream> {
|
||||||
let value = Value {
|
let value = Value {
|
||||||
@ -76,7 +69,7 @@ pub(crate) fn run_block_on_vec(
|
|||||||
};
|
};
|
||||||
|
|
||||||
async {
|
async {
|
||||||
match process_row(block, scope, context, value).await {
|
match process_row(block, context, value).await {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
// We need to handle this differently depending on whether process_row
|
// We need to handle this differently depending on whether process_row
|
||||||
// returned just 1 value or if it returned multiple as a stream.
|
// returned just 1 value or if it returned multiple as a stream.
|
||||||
|
@ -3,7 +3,7 @@ use crate::commands::WholeStreamCommand;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
//use itertools::Itertools;
|
//use itertools::Itertools;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{hir::Block, Primitive, Signature, SyntaxShape, UntaggedValue};
|
use nu_protocol::{hir::CapturedBlock, Primitive, Signature, SyntaxShape, UntaggedValue};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ pub struct EachWindow;
|
|||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EachWindowArgs {
|
pub struct EachWindowArgs {
|
||||||
window_size: Tagged<usize>,
|
window_size: Tagged<usize>,
|
||||||
block: Block,
|
block: CapturedBlock,
|
||||||
stride: Option<Tagged<usize>>,
|
stride: Option<Tagged<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,16 +50,10 @@ impl WholeStreamCommand for EachWindow {
|
|||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let context = Arc::new(EvaluationContext::from_raw(&raw_args));
|
||||||
raw_args: CommandArgs,
|
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process().await?;
|
||||||
registry: &CommandRegistry,
|
let block = Arc::new(Box::new(each_args.block));
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&raw_args, ®istry));
|
|
||||||
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process(®istry).await?;
|
|
||||||
let block = Arc::new(each_args.block);
|
|
||||||
|
|
||||||
let mut window: Vec<_> = input
|
let mut window: Vec<_> = input
|
||||||
.by_ref()
|
.by_ref()
|
||||||
@ -80,13 +74,12 @@ impl WholeStreamCommand for EachWindow {
|
|||||||
window.push(input);
|
window.push(input);
|
||||||
|
|
||||||
let block = block.clone();
|
let block = block.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let local_window = window.clone();
|
let local_window = window.clone();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
if i % stride == 0 {
|
if i % stride == 0 {
|
||||||
Some(run_block_on_vec(local_window, block, scope, context).await)
|
Some(run_block_on_vec(local_window, block, context).await)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use nu_protocol::{
|
|||||||
|
|
||||||
pub struct Echo;
|
pub struct Echo;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct EchoArgs {
|
pub struct EchoArgs {
|
||||||
pub rest: Vec<Value>,
|
pub rest: Vec<Value>,
|
||||||
}
|
}
|
||||||
@ -27,12 +27,8 @@ impl WholeStreamCommand for Echo {
|
|||||||
"Echo the arguments back to the user."
|
"Echo the arguments back to the user."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
echo(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
echo(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -51,9 +47,8 @@ impl WholeStreamCommand for Echo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn echo(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn echo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let (args, _): (EchoArgs, _) = args.process().await?;
|
||||||
let (args, _): (EchoArgs, _) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let stream = args.rest.into_iter().map(|i| match i.as_string() {
|
let stream = args.rest.into_iter().map(|i| match i.as_string() {
|
||||||
Ok(s) => OutputStream::one(Ok(ReturnSuccess::Value(
|
Ok(s) => OutputStream::one(Ok(ReturnSuccess::Value(
|
||||||
@ -69,7 +64,7 @@ async fn echo(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
value: UntaggedValue::Primitive(Primitive::Range(range)),
|
value: UntaggedValue::Primitive(Primitive::Range(range)),
|
||||||
tag,
|
tag,
|
||||||
} => futures::stream::iter(RangeIterator::new(*range, tag)).to_output_stream(),
|
} => futures::stream::iter(RangeIterator::new(*range, tag)).to_output_stream(),
|
||||||
_ => OutputStream::one(Ok(ReturnSuccess::Value(i.clone()))),
|
x => OutputStream::one(Ok(ReturnSuccess::Value(x))),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::classified::block::run_block;
|
use crate::commands::classified::block::run_block;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::Block, ColumnPath, Primitive, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue,
|
hir::CapturedBlock, ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape,
|
||||||
Value,
|
UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
use nu_value_ext::{as_string, ValueExt};
|
use nu_value_ext::{as_string, ValueExt};
|
||||||
|
|
||||||
use futures::stream::once;
|
use futures::stream::once;
|
||||||
use indexmap::indexmap;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Arguments {
|
pub struct Arguments {
|
||||||
@ -37,12 +35,8 @@ impl WholeStreamCommand for Command {
|
|||||||
"Check for empty values"
|
"Check for empty values"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
is_empty(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
is_empty(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -87,16 +81,12 @@ impl WholeStreamCommand for Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_empty(
|
async fn is_empty(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let name_tag = Arc::new(args.call_info.name_tag.clone());
|
let name_tag = Arc::new(args.call_info.name_tag.clone());
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&args, ®istry));
|
let context = Arc::new(EvaluationContext::from_raw(&args));
|
||||||
let scope = args.call_info.scope.clone();
|
let (Arguments { rest }, input) = args.process().await?;
|
||||||
let (Arguments { rest }, input) = args.process(®istry).await?;
|
let (columns, default_block): (Vec<ColumnPath>, Option<Box<CapturedBlock>>) = arguments(rest)?;
|
||||||
let (columns, default_block): (Vec<ColumnPath>, Option<Block>) = arguments(rest)?;
|
|
||||||
let default_block = Arc::new(default_block);
|
let default_block = Arc::new(default_block);
|
||||||
|
|
||||||
if input.is_empty() {
|
if input.is_empty() {
|
||||||
@ -107,13 +97,12 @@ async fn is_empty(
|
|||||||
return Ok(InputStream::from_stream(stream)
|
return Ok(InputStream::from_stream(stream)
|
||||||
.then(move |input| {
|
.then(move |input| {
|
||||||
let tag = name_tag.clone();
|
let tag = name_tag.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let block = default_block.clone();
|
let block = default_block.clone();
|
||||||
let columns = vec![];
|
let columns = vec![];
|
||||||
|
|
||||||
async {
|
async {
|
||||||
match process_row(scope, context, input, block, columns, tag).await {
|
match process_row(context, input, block, columns, tag).await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => OutputStream::one(Err(e)),
|
Err(e) => OutputStream::one(Err(e)),
|
||||||
}
|
}
|
||||||
@ -126,13 +115,12 @@ async fn is_empty(
|
|||||||
Ok(input
|
Ok(input
|
||||||
.then(move |input| {
|
.then(move |input| {
|
||||||
let tag = name_tag.clone();
|
let tag = name_tag.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let block = default_block.clone();
|
let block = default_block.clone();
|
||||||
let columns = columns.clone();
|
let columns = columns.clone();
|
||||||
|
|
||||||
async {
|
async {
|
||||||
match process_row(scope, context, input, block, columns, tag).await {
|
match process_row(context, input, block, columns, tag).await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => OutputStream::one(Err(e)),
|
Err(e) => OutputStream::one(Err(e)),
|
||||||
}
|
}
|
||||||
@ -142,7 +130,9 @@ async fn is_empty(
|
|||||||
.to_output_stream())
|
.to_output_stream())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arguments(rest: Vec<Value>) -> Result<(Vec<ColumnPath>, Option<Block>), ShellError> {
|
fn arguments(
|
||||||
|
rest: Vec<Value>,
|
||||||
|
) -> Result<(Vec<ColumnPath>, Option<Box<CapturedBlock>>), ShellError> {
|
||||||
let mut rest = rest;
|
let mut rest = rest;
|
||||||
let mut columns = vec![];
|
let mut columns = vec![];
|
||||||
let mut default = None;
|
let mut default = None;
|
||||||
@ -172,10 +162,9 @@ fn arguments(rest: Vec<Value>) -> Result<(Vec<ColumnPath>, Option<Block>), Shell
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn process_row(
|
async fn process_row(
|
||||||
scope: Arc<Scope>,
|
context: Arc<EvaluationContext>,
|
||||||
mut context: Arc<EvaluationContext>,
|
|
||||||
input: Value,
|
input: Value,
|
||||||
default_block: Arc<Option<Block>>,
|
default_block: Arc<Option<Box<CapturedBlock>>>,
|
||||||
column_paths: Vec<ColumnPath>,
|
column_paths: Vec<ColumnPath>,
|
||||||
tag: Arc<Tag>,
|
tag: Arc<Tag>,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
@ -187,16 +176,14 @@ async fn process_row(
|
|||||||
let for_block = input.clone();
|
let for_block = input.clone();
|
||||||
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
||||||
|
|
||||||
let scope = Scope::append_var(scope, "$it", input.clone());
|
context.scope.enter_scope();
|
||||||
|
context.scope.add_vars(&default_block.captured.entries);
|
||||||
|
context.scope.add_var("$it", input.clone());
|
||||||
|
|
||||||
let mut stream = run_block(
|
let stream = run_block(&default_block.block, &*context, input_stream).await;
|
||||||
&default_block,
|
context.scope.exit_scope();
|
||||||
Arc::make_mut(&mut context),
|
|
||||||
input_stream,
|
|
||||||
scope,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
|
let mut stream = stream?;
|
||||||
*results = Some({
|
*results = Some({
|
||||||
let values = stream.drain_vec().await;
|
let values = stream.drain_vec().await;
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::UnevaluatedCallInfo;
|
use crate::commands::UnevaluatedCallInfo;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@ -50,12 +49,8 @@ For a more complete list of encodings please refer to the encoding_rs
|
|||||||
documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"#
|
documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"#
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
enter(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
enter(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -79,19 +74,15 @@ documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn enter(
|
async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
let scope = raw_args.scope.clone();
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let shell_manager = raw_args.shell_manager.clone();
|
let shell_manager = raw_args.shell_manager.clone();
|
||||||
let head = raw_args.call_info.args.head.clone();
|
let head = raw_args.call_info.args.head.clone();
|
||||||
let ctrl_c = raw_args.ctrl_c.clone();
|
let ctrl_c = raw_args.ctrl_c.clone();
|
||||||
let current_errors = raw_args.current_errors.clone();
|
let current_errors = raw_args.current_errors.clone();
|
||||||
let host = raw_args.host.clone();
|
let host = raw_args.host.clone();
|
||||||
let tag = raw_args.call_info.name_tag.clone();
|
let tag = raw_args.call_info.name_tag.clone();
|
||||||
let (EnterArgs { location, encoding }, _) = raw_args.process(®istry).await?;
|
let (EnterArgs { location, encoding }, _) = raw_args.process().await?;
|
||||||
let location_string = location.display().to_string();
|
let location_string = location.display().to_string();
|
||||||
let location_clone = location_string.clone();
|
let location_clone = location_string.clone();
|
||||||
|
|
||||||
@ -101,7 +92,7 @@ async fn enter(
|
|||||||
if spec.len() == 2 {
|
if spec.len() == 2 {
|
||||||
let (_, command) = (spec[0], spec[1]);
|
let (_, command) = (spec[0], spec[1]);
|
||||||
|
|
||||||
if registry.has(command) {
|
if scope.has_command(command) {
|
||||||
return Ok(OutputStream::one(ReturnSuccess::action(
|
return Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
CommandAction::EnterHelpShell(
|
CommandAction::EnterHelpShell(
|
||||||
UntaggedValue::string(command).into_value(Tag::unknown()),
|
UntaggedValue::string(command).into_value(Tag::unknown()),
|
||||||
@ -121,11 +112,12 @@ async fn enter(
|
|||||||
let cwd = shell_manager.path();
|
let cwd = shell_manager.path();
|
||||||
|
|
||||||
let full_path = std::path::PathBuf::from(cwd);
|
let full_path = std::path::PathBuf::from(cwd);
|
||||||
|
let span = location.span();
|
||||||
|
|
||||||
let (file_extension, tagged_contents) = crate::commands::open::fetch(
|
let (file_extension, tagged_contents) = crate::commands::open::fetch(
|
||||||
&full_path,
|
&full_path,
|
||||||
&PathBuf::from(location_clone),
|
&PathBuf::from(location_clone),
|
||||||
tag.span,
|
span,
|
||||||
encoding,
|
encoding,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -134,7 +126,7 @@ async fn enter(
|
|||||||
UntaggedValue::Primitive(Primitive::String(_)) => {
|
UntaggedValue::Primitive(Primitive::String(_)) => {
|
||||||
if let Some(extension) = file_extension {
|
if let Some(extension) = file_extension {
|
||||||
let command_name = format!("from {}", extension);
|
let command_name = format!("from {}", extension);
|
||||||
if let Some(converter) = registry.get_command(&command_name) {
|
if let Some(converter) = scope.get_command(&command_name) {
|
||||||
let new_args = RawCommandArgs {
|
let new_args = RawCommandArgs {
|
||||||
host,
|
host,
|
||||||
ctrl_c,
|
ctrl_c,
|
||||||
@ -149,12 +141,12 @@ async fn enter(
|
|||||||
external_redirection: ExternalRedirection::Stdout,
|
external_redirection: ExternalRedirection::Stdout,
|
||||||
},
|
},
|
||||||
name_tag: tag.clone(),
|
name_tag: tag.clone(),
|
||||||
scope: scope.clone(),
|
|
||||||
},
|
},
|
||||||
|
scope: scope.clone(),
|
||||||
};
|
};
|
||||||
let tag = tagged_contents.tag.clone();
|
let tag = tagged_contents.tag.clone();
|
||||||
let mut result = converter
|
let mut result = converter
|
||||||
.run(new_args.with_input(vec![tagged_contents]), ®istry)
|
.run(new_args.with_input(vec![tagged_contents]))
|
||||||
.await?;
|
.await?;
|
||||||
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
|
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
|
||||||
result.drain_vec().await;
|
result.drain_vec().await;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -37,12 +36,8 @@ impl WholeStreamCommand for Every {
|
|||||||
"Show (or skip) every n-th row, starting from the first one."
|
"Show (or skip) every n-th row, starting from the first one."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
every(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
every(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -68,9 +63,8 @@ impl WholeStreamCommand for Every {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn every(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn every(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let (EveryArgs { stride, skip }, input) = args.process().await?;
|
||||||
let (EveryArgs { stride, skip }, input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let stride = stride.item;
|
let stride = stride.item;
|
||||||
let skip = skip.item;
|
let skip = skip.item;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -30,12 +29,8 @@ impl WholeStreamCommand for Exec {
|
|||||||
"Execute command"
|
"Execute command"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
exec(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
exec(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -55,13 +50,12 @@ impl WholeStreamCommand for Exec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
async fn exec(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
let registry = registry.clone();
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let (args, _): (ExecArgs, _) = args.process(®istry).await?;
|
let (args, _): (ExecArgs, _) = args.process().await?;
|
||||||
|
|
||||||
let mut command = Command::new(args.command.item);
|
let mut command = Command::new(args.command.item);
|
||||||
for tagged_arg in args.rest {
|
for tagged_arg in args.rest {
|
||||||
@ -78,7 +72,7 @@ async fn exec(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
async fn exec(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
Err(ShellError::labeled_error(
|
Err(ShellError::labeled_error(
|
||||||
"Error on exec",
|
"Error on exec",
|
||||||
"exec is not supported on your platform",
|
"exec is not supported on your platform",
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::command::WholeStreamCommand;
|
use crate::commands::command::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -20,12 +19,8 @@ impl WholeStreamCommand for Exit {
|
|||||||
"Exit the current shell (or all shells)"
|
"Exit the current shell (or all shells)"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
exit(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
exit(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -44,12 +39,8 @@ impl WholeStreamCommand for Exit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn exit(
|
pub async fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
|
|
||||||
let command_action = if args.call_info.args.has("now") {
|
let command_action = if args.call_info.args.has("now") {
|
||||||
CommandAction::Exit
|
CommandAction::Exit
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -30,12 +29,8 @@ impl WholeStreamCommand for First {
|
|||||||
"Show only the first number of rows."
|
"Show only the first number of rows."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
first(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
first(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -57,9 +52,8 @@ impl WholeStreamCommand for First {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn first(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let (FirstArgs { rows }, input) = args.process().await?;
|
||||||
let (FirstArgs { rows }, input) = args.process(®istry).await?;
|
|
||||||
let rows_desired = if let Some(quantity) = rows {
|
let rows_desired = if let Some(quantity) = rows {
|
||||||
*quantity
|
*quantity
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -28,12 +27,8 @@ impl WholeStreamCommand for Command {
|
|||||||
"Flatten the table."
|
"Flatten the table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
flatten(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
flatten(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -57,13 +52,9 @@ impl WholeStreamCommand for Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn flatten(
|
async fn flatten(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let registry = registry.clone();
|
let (Arguments { rest: columns }, input) = args.process().await?;
|
||||||
let (Arguments { rest: columns }, input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.map(move |item| {
|
.map(move |item| {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::evaluate::evaluate_baseline_expr;
|
use crate::evaluate::evaluate_baseline_expr;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
@ -32,12 +31,8 @@ impl WholeStreamCommand for Format {
|
|||||||
"Format columns into a string using a simple pattern."
|
"Format columns into a string using a simple pattern."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
format_command(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
format_command(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -49,13 +44,9 @@ impl WholeStreamCommand for Format {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn format_command(
|
async fn format_command(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let ctx = Arc::new(EvaluationContext::from_args(&args));
|
||||||
registry: &CommandRegistry,
|
let (FormatArgs { pattern }, input) = args.process().await?;
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = Arc::new(registry.clone());
|
|
||||||
let scope = args.call_info.scope.clone();
|
|
||||||
let (FormatArgs { pattern }, input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let format_pattern = format(&pattern);
|
let format_pattern = format(&pattern);
|
||||||
let commands = Arc::new(format_pattern);
|
let commands = Arc::new(format_pattern);
|
||||||
@ -64,8 +55,7 @@ async fn format_command(
|
|||||||
.then(move |value| {
|
.then(move |value| {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
let commands = commands.clone();
|
let commands = commands.clone();
|
||||||
let registry = registry.clone();
|
let ctx = ctx.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
for command in &*commands {
|
for command in &*commands {
|
||||||
@ -77,15 +67,13 @@ async fn format_command(
|
|||||||
// FIXME: use the correct spans
|
// FIXME: use the correct spans
|
||||||
let full_column_path = nu_parser::parse_full_column_path(
|
let full_column_path = nu_parser::parse_full_column_path(
|
||||||
&(c.to_string()).spanned(Span::unknown()),
|
&(c.to_string()).spanned(Span::unknown()),
|
||||||
&*registry,
|
&ctx.scope,
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = evaluate_baseline_expr(
|
ctx.scope.enter_scope();
|
||||||
&full_column_path.0,
|
ctx.scope.add_var("$it", value.clone());
|
||||||
®istry,
|
let result = evaluate_baseline_expr(&full_column_path.0, &*ctx).await;
|
||||||
Scope::append_var(scope.clone(), "$it", value.clone()),
|
ctx.scope.exit_scope();
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Ok(c) = result {
|
if let Ok(c) = result {
|
||||||
output
|
output
|
||||||
|
@ -43,12 +43,8 @@ impl WholeStreamCommand for FileSize {
|
|||||||
"Converts a column of filesizes to some specified format"
|
"Converts a column of filesizes to some specified format"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
filesize(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
filesize(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -77,7 +73,7 @@ async fn process_row(
|
|||||||
match replace_for {
|
match replace_for {
|
||||||
Ok(s) => match convert_bytes_to_string_using_format(s, format) {
|
Ok(s) => match convert_bytes_to_string_using_format(s, format) {
|
||||||
Ok(b) => OutputStream::one(ReturnSuccess::value(
|
Ok(b) => OutputStream::one(ReturnSuccess::value(
|
||||||
input.replace_data_at_column_path(&field, b).expect("Given that the existance check was already done, this souldn't trigger never"),
|
input.replace_data_at_column_path(&field, b).expect("Given that the existence check was already done, this shouldn't trigger never"),
|
||||||
)),
|
)),
|
||||||
Err(e) => OutputStream::one(Err(e)),
|
Err(e) => OutputStream::one(Err(e)),
|
||||||
},
|
},
|
||||||
@ -86,12 +82,8 @@ async fn process_row(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn filesize(
|
async fn filesize(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
let (Arguments { field, format }, input) = raw_args.process().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let (Arguments { field, format }, input) = raw_args.process(®istry).await?;
|
|
||||||
let field = Arc::new(field);
|
let field = Arc::new(field);
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
|
@ -19,14 +19,9 @@ impl WholeStreamCommand for From {
|
|||||||
"Parse content (string or binary) as a table (input format based on subcommand, like csv, ini, json, toml)"
|
"Parse content (string or binary) as a table (input format based on subcommand, like csv, ini, json, toml)"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&From, ®istry))
|
UntaggedValue::string(crate::commands::help::get_help(&From, &args.scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,8 @@ impl WholeStreamCommand for FromCSV {
|
|||||||
"Parse text as .csv and create table."
|
"Parse text as .csv and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_csv(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_csv(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -66,11 +62,7 @@ impl WholeStreamCommand for FromCSV {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_csv(
|
async fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
|
|
||||||
let (
|
let (
|
||||||
@ -79,7 +71,7 @@ async fn from_csv(
|
|||||||
separator,
|
separator,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
let sep = match separator {
|
let sep = match separator {
|
||||||
Some(Value {
|
Some(Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::String(s)),
|
value: UntaggedValue::Primitive(Primitive::String(s)),
|
||||||
|
@ -35,12 +35,8 @@ impl WholeStreamCommand for FromEML {
|
|||||||
"Parse text as .eml and create table."
|
"Parse text as .eml and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_eml(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_eml(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,13 +73,9 @@ fn headerfieldvalue_to_value(tag: &Tag, value: &HeaderFieldValue) -> UntaggedVal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_eml(
|
async fn from_eml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let registry = registry.clone();
|
let (eml_args, input): (FromEMLArgs, _) = args.process().await?;
|
||||||
let (eml_args, input): (FromEMLArgs, _) = args.process(®istry).await?;
|
|
||||||
let value = input.collect_string(tag.clone()).await?;
|
let value = input.collect_string(tag.clone()).await?;
|
||||||
|
|
||||||
let body_preview = eml_args
|
let body_preview = eml_args
|
||||||
|
@ -23,21 +23,13 @@ impl WholeStreamCommand for FromIcs {
|
|||||||
"Parse text as .ics and create table."
|
"Parse text as .ics and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_ics(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_ics(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_ics(
|
async fn from_ics(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -20,12 +20,8 @@ impl WholeStreamCommand for FromINI {
|
|||||||
"Parse text as .ini and create table"
|
"Parse text as .ini and create table"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_ini(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_ini(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,12 +60,8 @@ pub fn from_ini_string_to_value(
|
|||||||
Ok(convert_ini_top_to_nu_value(&v, tag))
|
Ok(convert_ini_top_to_nu_value(&v, tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_ini(
|
async fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
let concat_string = input.collect_string(tag.clone()).await?;
|
let concat_string = input.collect_string(tag.clone()).await?;
|
||||||
|
@ -28,12 +28,8 @@ impl WholeStreamCommand for FromJSON {
|
|||||||
"Parse text as .json and create table."
|
"Parse text as .json and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_json(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_json(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,14 +68,10 @@ pub fn from_json_string_to_value(s: String, tag: impl Into<Tag>) -> nu_json::Res
|
|||||||
Ok(convert_json_value_to_nu_value(&v, tag))
|
Ok(convert_json_value_to_nu_value(&v, tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_json(
|
async fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name_tag = args.call_info.name_tag.clone();
|
let name_tag = args.call_info.name_tag.clone();
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
let (FromJSONArgs { objects }, input) = args.process(®istry).await?;
|
let (FromJSONArgs { objects }, input) = args.process().await?;
|
||||||
let concat_string = input.collect_string(name_tag.clone()).await?;
|
let concat_string = input.collect_string(name_tag.clone()).await?;
|
||||||
|
|
||||||
let string_clone: Vec<_> = concat_string.item.lines().map(|x| x.to_string()).collect();
|
let string_clone: Vec<_> = concat_string.item.lines().map(|x| x.to_string()).collect();
|
||||||
|
@ -31,29 +31,21 @@ impl WholeStreamCommand for FromODS {
|
|||||||
"Parse OpenDocument Spreadsheet(.ods) data and create table."
|
"Parse OpenDocument Spreadsheet(.ods) data and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_ods(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_ods(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_ods(
|
async fn from_ods(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let span = tag.span;
|
let span = tag.span;
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
let (
|
let (
|
||||||
FromODSArgs {
|
FromODSArgs {
|
||||||
headerless: _headerless,
|
headerless: _headerless,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
let bytes = input.collect_binary(tag.clone()).await?;
|
let bytes = input.collect_binary(tag.clone()).await?;
|
||||||
let buf: Cursor<Vec<u8>> = Cursor::new(bytes.item);
|
let buf: Cursor<Vec<u8>> = Cursor::new(bytes.item);
|
||||||
let mut ods = Ods::<_>::new(buf).map_err(|_| {
|
let mut ods = Ods::<_>::new(buf).map_err(|_| {
|
||||||
|
@ -46,12 +46,8 @@ impl WholeStreamCommand for FromSSV {
|
|||||||
"Parse text as space-separated values and create a table. The default minimum number of spaces counted as a separator is 2."
|
"Parse text as space-separated values and create a table. The default minimum number of spaces counted as a separator is 2."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_ssv(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_ssv(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,12 +247,8 @@ fn from_ssv_string_to_value(
|
|||||||
Some(UntaggedValue::Table(rows).into_value(&tag))
|
Some(UntaggedValue::Table(rows).into_value(&tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_ssv(
|
async fn from_ssv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let registry = registry.clone();
|
|
||||||
let (
|
let (
|
||||||
FromSSVArgs {
|
FromSSVArgs {
|
||||||
headerless,
|
headerless,
|
||||||
@ -264,7 +256,7 @@ async fn from_ssv(
|
|||||||
minimum_spaces,
|
minimum_spaces,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
let concat_string = input.collect_string(name.clone()).await?;
|
let concat_string = input.collect_string(name.clone()).await?;
|
||||||
let split_at = match minimum_spaces {
|
let split_at = match minimum_spaces {
|
||||||
Some(number) => number.item,
|
Some(number) => number.item,
|
||||||
|
@ -19,12 +19,8 @@ impl WholeStreamCommand for FromTOML {
|
|||||||
"Parse text as .toml and create table."
|
"Parse text as .toml and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_toml(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_toml(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,12 +61,8 @@ pub fn from_toml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value
|
|||||||
Ok(convert_toml_value_to_nu_value(&v, tag))
|
Ok(convert_toml_value_to_nu_value(&v, tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn from_toml(
|
pub async fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -29,22 +29,14 @@ impl WholeStreamCommand for FromTSV {
|
|||||||
"Parse text as .tsv and create table."
|
"Parse text as .tsv and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_tsv(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_tsv(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_tsv(
|
async fn from_tsv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let (FromTSVArgs { headerless }, input) = args.process(®istry).await?;
|
let (FromTSVArgs { headerless }, input) = args.process().await?;
|
||||||
|
|
||||||
from_delimited_data(headerless, '\t', "TSV", input, name).await
|
from_delimited_data(headerless, '\t', "TSV", input, name).await
|
||||||
}
|
}
|
||||||
|
@ -19,21 +19,13 @@ impl WholeStreamCommand for FromURL {
|
|||||||
"Parse url-encoded string as a table."
|
"Parse url-encoded string as a table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_url(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_url(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_url(
|
async fn from_url(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -22,21 +22,13 @@ impl WholeStreamCommand for FromVcf {
|
|||||||
"Parse text as .vcf and create table."
|
"Parse text as .vcf and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_vcf(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_vcf(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_vcf(
|
async fn from_vcf(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -31,28 +31,20 @@ impl WholeStreamCommand for FromXLSX {
|
|||||||
"Parse binary Excel(.xlsx) data and create table."
|
"Parse binary Excel(.xlsx) data and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_xlsx(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_xlsx(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_xlsx(
|
async fn from_xlsx(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let span = tag.span;
|
let span = tag.span;
|
||||||
let registry = registry.clone();
|
|
||||||
let (
|
let (
|
||||||
FromXLSXArgs {
|
FromXLSXArgs {
|
||||||
headerless: _headerless,
|
headerless: _headerless,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
let value = input.collect_binary(tag.clone()).await?;
|
let value = input.collect_binary(tag.clone()).await?;
|
||||||
|
|
||||||
let buf: Cursor<Vec<u8>> = Cursor::new(value.item);
|
let buf: Cursor<Vec<u8>> = Cursor::new(value.item);
|
||||||
|
@ -19,12 +19,8 @@ impl WholeStreamCommand for FromXML {
|
|||||||
"Parse text as .xml and create table."
|
"Parse text as .xml and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_xml(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_xml(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +35,7 @@ fn from_attributes_to_value(attributes: &[roxmltree::Attribute], tag: impl Into<
|
|||||||
collected.into_value()
|
collected.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Value {
|
fn from_node_to_value(n: &roxmltree::Node, tag: impl Into<Tag>) -> Value {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
|
|
||||||
if n.is_element() {
|
if n.is_element() {
|
||||||
@ -99,12 +95,8 @@ pub fn from_xml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value,
|
|||||||
Ok(from_document_to_value(&parsed, tag))
|
Ok(from_document_to_value(&parsed, tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_xml(
|
async fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -19,12 +19,8 @@ impl WholeStreamCommand for FromYAML {
|
|||||||
"Parse text as .yaml/.yml and create table."
|
"Parse text as .yaml/.yml and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_yaml(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_yaml(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +40,8 @@ impl WholeStreamCommand for FromYML {
|
|||||||
"Parse text as .yaml/.yml and create table."
|
"Parse text as .yaml/.yml and create table."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
from_yaml(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
from_yaml(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,12 +133,8 @@ pub fn from_yaml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value
|
|||||||
Ok(convert_yaml_value_to_nu_value(&v, tag)?)
|
Ok(convert_yaml_value_to_nu_value(&v, tag)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_yaml(
|
async fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let args = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let args = args.evaluate_once(®istry).await?;
|
|
||||||
let tag = args.name_tag();
|
let tag = args.name_tag();
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
|
|
||||||
|
@ -34,12 +34,8 @@ impl WholeStreamCommand for Get {
|
|||||||
"Open given cells as text."
|
"Open given cells as text."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
get(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
get(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -58,12 +54,8 @@ impl WholeStreamCommand for Get {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let (GetArgs { rest: column_paths }, mut input) = args.process().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let (GetArgs { rest: column_paths }, mut input) = args.process(®istry).await?;
|
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
let vec = input.drain_vec().await;
|
let vec = input.drain_vec().await;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::utils::suggestions::suggestions;
|
use crate::utils::suggestions::suggestions;
|
||||||
use indexmap::indexmap;
|
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
@ -32,12 +31,8 @@ impl WholeStreamCommand for Command {
|
|||||||
"Create a new table grouped."
|
"Create a new table grouped."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
group_by(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
group_by(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
@ -133,15 +128,10 @@ enum Grouper {
|
|||||||
ByBlock,
|
ByBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn group_by(
|
pub async fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let registry = registry.clone();
|
let context = Arc::new(EvaluationContext::from_raw(&args));
|
||||||
let scope = args.call_info.scope.clone();
|
let (Arguments { grouper }, input) = args.process().await?;
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&args, ®istry));
|
|
||||||
let (Arguments { grouper }, input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let values: Vec<Value> = input.collect().await;
|
let values: Vec<Value> = input.collect().await;
|
||||||
let mut keys: Vec<Result<String, ShellError>> = vec![];
|
let mut keys: Vec<Result<String, ShellError>> = vec![];
|
||||||
@ -157,10 +147,9 @@ pub async fn group_by(
|
|||||||
|
|
||||||
for value in values.iter() {
|
for value in values.iter() {
|
||||||
let run = block.clone();
|
let run = block.clone();
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
|
|
||||||
match crate::commands::each::process_row(run, scope, context, value.clone()).await {
|
match crate::commands::each::process_row(run, context, value.clone()).await {
|
||||||
Ok(mut s) => {
|
Ok(mut s) => {
|
||||||
let collection: Vec<Result<ReturnSuccess, ShellError>> =
|
let collection: Vec<Result<ReturnSuccess, ShellError>> =
|
||||||
s.drain_vec().await;
|
s.drain_vec().await;
|
||||||
|
@ -38,12 +38,8 @@ impl WholeStreamCommand for GroupByDate {
|
|||||||
"creates a table grouped by date."
|
"creates a table grouped by date."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
group_by_date(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
group_by_date(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -63,11 +59,7 @@ enum GroupByColumn {
|
|||||||
Name(Option<Tagged<String>>),
|
Name(Option<Tagged<String>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn group_by_date(
|
pub async fn group_by_date(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let (
|
let (
|
||||||
GroupByDateArgs {
|
GroupByDateArgs {
|
||||||
@ -75,7 +67,7 @@ pub async fn group_by_date(
|
|||||||
format,
|
format,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
let values: Vec<Value> = input.collect().await;
|
let values: Vec<Value> = input.collect().await;
|
||||||
|
|
||||||
if values.is_empty() {
|
if values.is_empty() {
|
||||||
|
@ -65,12 +65,8 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"base64 encode or decode a value"
|
"base64 encode or decode a value"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
operate(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
operate(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -100,12 +96,7 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn operate(
|
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
let name_tag = &args.call_info.name_tag.clone();
|
let name_tag = &args.call_info.name_tag.clone();
|
||||||
|
|
||||||
let (
|
let (
|
||||||
@ -116,7 +107,7 @@ async fn operate(
|
|||||||
rest,
|
rest,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
|
|
||||||
if encode.item && decode.item {
|
if encode.item && decode.item {
|
||||||
return Ok(OutputStream::one(Err(ShellError::labeled_error(
|
return Ok(OutputStream::one(Err(ShellError::labeled_error(
|
||||||
|
@ -22,15 +22,9 @@ impl WholeStreamCommand for Command {
|
|||||||
"Apply hash function."
|
"Apply hash function."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
|
||||||
_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&Command, ®istry))
|
UntaggedValue::string(crate::commands::help::get_help(&Command, &args.scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
@ -23,12 +22,8 @@ impl WholeStreamCommand for Headers {
|
|||||||
"Use the first row of the table as column names"
|
"Use the first row of the table as column names"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
headers(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
headers(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -47,10 +42,7 @@ impl WholeStreamCommand for Headers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn headers(
|
pub async fn headers(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let input = args.input;
|
let input = args.input;
|
||||||
let rows: Vec<Value> = input.collect().await;
|
let rows: Vec<Value> = input.collect().await;
|
||||||
|
|
||||||
|
@ -29,12 +29,8 @@ impl WholeStreamCommand for Help {
|
|||||||
"Display help information about commands."
|
"Display help information about commands."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
help(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
help(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,21 +49,21 @@ pub(crate) fn command_dict(command: Command, tag: impl Into<Tag>) -> Value {
|
|||||||
cmd_dict.into_value()
|
cmd_dict.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn help(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let (HelpArgs { rest }, ..) = args.process(®istry).await?;
|
let scope = args.scope.clone();
|
||||||
|
let (HelpArgs { rest }, ..) = args.process().await?;
|
||||||
|
|
||||||
if !rest.is_empty() {
|
if !rest.is_empty() {
|
||||||
if rest[0].item == "commands" {
|
if rest[0].item == "commands" {
|
||||||
let mut sorted_names = registry.names();
|
let mut sorted_names = scope.get_command_names();
|
||||||
sorted_names.sort();
|
sorted_names.sort();
|
||||||
|
|
||||||
let (mut subcommand_names, command_names) = sorted_names
|
let (mut subcommand_names, command_names) = sorted_names
|
||||||
.into_iter()
|
.into_iter()
|
||||||
// Internal only commands shouldn't be displayed
|
// Internal only commands shouldn't be displayed
|
||||||
.filter(|cmd_name| {
|
.filter(|cmd_name| {
|
||||||
registry
|
scope
|
||||||
.get_command(&cmd_name)
|
.get_command(&cmd_name)
|
||||||
.filter(|command| !command.is_internal())
|
.filter(|command| !command.is_internal())
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -77,13 +73,13 @@ async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
fn process_name(
|
fn process_name(
|
||||||
dict: &mut TaggedDictBuilder,
|
dict: &mut TaggedDictBuilder,
|
||||||
cmd_name: &str,
|
cmd_name: &str,
|
||||||
registry: CommandRegistry,
|
scope: Scope,
|
||||||
rest: Vec<Tagged<String>>,
|
rest: Vec<Tagged<String>>,
|
||||||
name: Tag,
|
name: Tag,
|
||||||
) -> Result<(), ShellError> {
|
) -> Result<(), ShellError> {
|
||||||
let document_tag = rest[0].tag.clone();
|
let document_tag = rest[0].tag.clone();
|
||||||
let value = command_dict(
|
let value = command_dict(
|
||||||
registry.get_command(&cmd_name).ok_or_else(|| {
|
scope.get_command(&cmd_name).ok_or_else(|| {
|
||||||
ShellError::labeled_error(
|
ShellError::labeled_error(
|
||||||
format!("Could not load {}", cmd_name),
|
format!("Could not load {}", cmd_name),
|
||||||
"could not load command",
|
"could not load command",
|
||||||
@ -114,7 +110,7 @@ async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
fn make_subcommands_table(
|
fn make_subcommands_table(
|
||||||
subcommand_names: &mut Vec<String>,
|
subcommand_names: &mut Vec<String>,
|
||||||
cmd_name: &str,
|
cmd_name: &str,
|
||||||
registry: CommandRegistry,
|
scope: Scope,
|
||||||
rest: Vec<Tagged<String>>,
|
rest: Vec<Tagged<String>>,
|
||||||
name: Tag,
|
name: Tag,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
@ -132,7 +128,7 @@ async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
process_name(
|
process_name(
|
||||||
&mut short_desc,
|
&mut short_desc,
|
||||||
&cmd_name,
|
&cmd_name,
|
||||||
registry.clone(),
|
scope.clone(),
|
||||||
rest.clone(),
|
rest.clone(),
|
||||||
name.clone(),
|
name.clone(),
|
||||||
)?;
|
)?;
|
||||||
@ -154,7 +150,7 @@ async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
process_name(
|
process_name(
|
||||||
&mut short_desc,
|
&mut short_desc,
|
||||||
&cmd_name,
|
&cmd_name,
|
||||||
registry.clone(),
|
scope.clone(),
|
||||||
rest.clone(),
|
rest.clone(),
|
||||||
name.clone(),
|
name.clone(),
|
||||||
)?;
|
)?;
|
||||||
@ -163,7 +159,7 @@ async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
make_subcommands_table(
|
make_subcommands_table(
|
||||||
&mut subcommand_names,
|
&mut subcommand_names,
|
||||||
&cmd_name,
|
&cmd_name,
|
||||||
registry.clone(),
|
scope.clone(),
|
||||||
rest.clone(),
|
rest.clone(),
|
||||||
name.clone(),
|
name.clone(),
|
||||||
)?,
|
)?,
|
||||||
@ -174,22 +170,22 @@ async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
Ok(futures::stream::iter(iterator).to_output_stream())
|
Ok(futures::stream::iter(iterator).to_output_stream())
|
||||||
} else if rest[0].item == "generate_docs" {
|
} else if rest[0].item == "generate_docs" {
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(generate_docs(
|
Ok(OutputStream::one(ReturnSuccess::value(generate_docs(
|
||||||
®istry,
|
&scope,
|
||||||
))))
|
))))
|
||||||
} else if rest.len() == 2 {
|
} else if rest.len() == 2 {
|
||||||
// Check for a subcommand
|
// Check for a subcommand
|
||||||
let command_name = format!("{} {}", rest[0].item, rest[1].item);
|
let command_name = format!("{} {}", rest[0].item, rest[1].item);
|
||||||
if let Some(command) = registry.get_command(&command_name) {
|
if let Some(command) = scope.get_command(&command_name) {
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
UntaggedValue::string(get_help(command.stream_command(), ®istry))
|
UntaggedValue::string(get_help(command.stream_command(), &scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(OutputStream::empty())
|
Ok(OutputStream::empty())
|
||||||
}
|
}
|
||||||
} else if let Some(command) = registry.get_command(&rest[0].item) {
|
} else if let Some(command) = scope.get_command(&rest[0].item) {
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
UntaggedValue::string(get_help(command.stream_command(), ®istry))
|
UntaggedValue::string(get_help(command.stream_command(), &scope))
|
||||||
.into_value(Tag::unknown()),
|
.into_value(Tag::unknown()),
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
@ -228,8 +224,8 @@ You can also learn more at https://www.nushell.sh/book/"#;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_help(cmd: &dyn WholeStreamCommand, registry: &CommandRegistry) -> String {
|
pub fn get_help(cmd: &dyn WholeStreamCommand, scope: &Scope) -> String {
|
||||||
get_documentation(cmd, registry, &DocumentationConfig::default())
|
get_documentation(cmd, scope, &DocumentationConfig::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -32,12 +32,8 @@ impl WholeStreamCommand for Histogram {
|
|||||||
"Creates a new table with a histogram based on the column name passed in."
|
"Creates a new table with a histogram based on the column name passed in."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
histogram(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
histogram(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -62,13 +58,9 @@ impl WholeStreamCommand for Histogram {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn histogram(
|
pub async fn histogram(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let (input, args) = args.evaluate_once(®istry).await?.parts();
|
let (input, args) = args.evaluate_once().await?.parts();
|
||||||
|
|
||||||
let values: Vec<Value> = input.collect().await;
|
let values: Vec<Value> = input.collect().await;
|
||||||
|
|
||||||
@ -98,7 +90,7 @@ pub async fn histogram(
|
|||||||
} else if let Some((key, _)) = columns[0].split_last() {
|
} else if let Some((key, _)) = columns[0].split_last() {
|
||||||
key.as_string()
|
key.as_string()
|
||||||
} else {
|
} else {
|
||||||
"frecuency".to_string()
|
"frequency".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let column = if let Some(ref column) = column_grouper {
|
let column = if let Some(ref column) = column_grouper {
|
||||||
@ -157,7 +149,7 @@ pub async fn histogram(
|
|||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
ShellError::labeled_error(
|
ShellError::labeled_error(
|
||||||
"Unable to load group labels",
|
"Unable to load group labels",
|
||||||
"unabled to load group labels",
|
"unable to load group labels",
|
||||||
&name,
|
&name,
|
||||||
)
|
)
|
||||||
})?
|
})?
|
||||||
|
@ -48,22 +48,15 @@ impl WholeStreamCommand for History {
|
|||||||
"Display command history."
|
"Display command history."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
history(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
history(args, registry).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn history(
|
async fn history(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
|
||||||
_registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let config: Box<dyn Conf> = Box::new(NuConfig::new());
|
let config: Box<dyn Conf> = Box::new(NuConfig::new());
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let (Arguments { clear }, _) = args.process(&_registry).await?;
|
let (Arguments { clear }, _) = args.process().await?;
|
||||||
|
|
||||||
let path = history_path(&config);
|
let path = history_path(&config);
|
||||||
|
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::classified::block::run_block;
|
use crate::commands::classified::block::run_block;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::evaluate::evaluate_baseline_expr;
|
use crate::evaluate::evaluate_baseline_expr;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::Block, hir::ClassifiedCommand, Scope, Signature, SyntaxShape, UntaggedValue,
|
hir::CapturedBlock, hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct If;
|
pub struct If;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct IfArgs {
|
pub struct IfArgs {
|
||||||
condition: Block,
|
condition: CapturedBlock,
|
||||||
then_case: Block,
|
then_case: CapturedBlock,
|
||||||
else_case: Block,
|
else_case: CapturedBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@ -27,7 +26,7 @@ impl WholeStreamCommand for If {
|
|||||||
Signature::build("if")
|
Signature::build("if")
|
||||||
.required(
|
.required(
|
||||||
"condition",
|
"condition",
|
||||||
SyntaxShape::Math,
|
SyntaxShape::MathExpression,
|
||||||
"the condition that must match",
|
"the condition that must match",
|
||||||
)
|
)
|
||||||
.required(
|
.required(
|
||||||
@ -46,37 +45,28 @@ impl WholeStreamCommand for If {
|
|||||||
"Run blocks if a condition is true or false."
|
"Run blocks if a condition is true or false."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
if_command(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
if_command(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
vec![
|
vec![
|
||||||
Example {
|
Example {
|
||||||
description: "Run a block if a condition is true",
|
description: "Run a block if a condition is true",
|
||||||
example: "echo 10 | if $it > 5 { echo 'greater than 5' } { echo 'less than or equal to 5' }",
|
example: "let x = 10; if $x > 5 { echo 'greater than 5' } { echo 'less than or equal to 5' }",
|
||||||
result: Some(vec![UntaggedValue::string("greater than 5").into()]),
|
result: Some(vec![UntaggedValue::string("greater than 5").into()]),
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description: "Run a block if a condition is false",
|
description: "Run a block if a condition is false",
|
||||||
example: "echo 1 | if $it > 5 { echo 'greater than 5' } { echo 'less than or equal to 5' }",
|
example: "let x = 1; if $x > 5 { echo 'greater than 5' } { echo 'less than or equal to 5' }",
|
||||||
result: Some(vec![UntaggedValue::string("less than or equal to 5").into()]),
|
result: Some(vec![UntaggedValue::string("less than or equal to 5").into()]),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async fn if_command(
|
async fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = Arc::new(registry.clone());
|
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let tag = raw_args.call_info.name_tag.clone();
|
let tag = raw_args.call_info.name_tag.clone();
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&raw_args, ®istry));
|
let context = Arc::new(EvaluationContext::from_raw(&raw_args));
|
||||||
|
|
||||||
let (
|
let (
|
||||||
IfArgs {
|
IfArgs {
|
||||||
@ -85,18 +75,18 @@ async fn if_command(
|
|||||||
else_case,
|
else_case,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = raw_args.process(®istry).await?;
|
) = raw_args.process().await?;
|
||||||
let condition = {
|
let cond = {
|
||||||
if condition.block.len() != 1 {
|
if condition.block.block.len() != 1 {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"Expected a condition",
|
"Expected a condition",
|
||||||
"expected a condition",
|
"expected a condition",
|
||||||
tag,
|
tag,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
match condition.block[0].list.get(0) {
|
match condition.block.block[0].pipelines.get(0) {
|
||||||
Some(item) => match item {
|
Some(item) => match item.list.get(0) {
|
||||||
ClassifiedCommand::Expr(expr) => expr.clone(),
|
Some(ClassifiedCommand::Expr(expr)) => expr.clone(),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"Expected a condition",
|
"Expected a condition",
|
||||||
@ -115,60 +105,27 @@ async fn if_command(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(input
|
context.scope.enter_scope();
|
||||||
.then(move |input| {
|
context.scope.add_vars(&condition.captured.entries);
|
||||||
let condition = condition.clone();
|
|
||||||
let then_case = then_case.clone();
|
|
||||||
let else_case = else_case.clone();
|
|
||||||
let registry = registry.clone();
|
|
||||||
let scope = Scope::append_var(scope.clone(), "$it", input);
|
|
||||||
let mut context = context.clone();
|
|
||||||
|
|
||||||
async move {
|
//FIXME: should we use the scope that's brought in as well?
|
||||||
//FIXME: should we use the scope that's brought in as well?
|
let condition = evaluate_baseline_expr(&cond, &*context).await;
|
||||||
let condition = evaluate_baseline_expr(&condition, &*registry, scope.clone()).await;
|
match condition {
|
||||||
|
Ok(condition) => match condition.as_bool() {
|
||||||
|
Ok(b) => {
|
||||||
|
let result = if b {
|
||||||
|
run_block(&then_case.block, &*context, input).await
|
||||||
|
} else {
|
||||||
|
run_block(&else_case.block, &*context, input).await
|
||||||
|
};
|
||||||
|
context.scope.exit_scope();
|
||||||
|
|
||||||
match condition {
|
result.map(|x| x.to_output_stream())
|
||||||
Ok(condition) => match condition.as_bool() {
|
|
||||||
Ok(b) => {
|
|
||||||
if b {
|
|
||||||
match run_block(
|
|
||||||
&then_case,
|
|
||||||
Arc::make_mut(&mut context),
|
|
||||||
InputStream::empty(),
|
|
||||||
scope,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(stream) => stream.to_output_stream(),
|
|
||||||
Err(e) => futures::stream::iter(vec![Err(e)].into_iter())
|
|
||||||
.to_output_stream(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match run_block(
|
|
||||||
&else_case,
|
|
||||||
Arc::make_mut(&mut context),
|
|
||||||
InputStream::empty(),
|
|
||||||
scope,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(stream) => stream.to_output_stream(),
|
|
||||||
Err(e) => futures::stream::iter(vec![Err(e)].into_iter())
|
|
||||||
.to_output_stream(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
futures::stream::iter(vec![Err(e)].into_iter()).to_output_stream()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => futures::stream::iter(vec![Err(e)].into_iter()).to_output_stream(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
Err(e) => Ok(futures::stream::iter(vec![Err(e)].into_iter()).to_output_stream()),
|
||||||
.flatten()
|
},
|
||||||
.to_output_stream())
|
Err(e) => Ok(futures::stream::iter(vec![Err(e)].into_iter()).to_output_stream()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::classified::block::run_block;
|
use crate::commands::classified::block::run_block;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ColumnPath, Primitive, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue, Value,
|
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_value_ext::ValueExt;
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
use futures::stream::once;
|
use futures::stream::once;
|
||||||
use indexmap::indexmap;
|
|
||||||
|
|
||||||
pub struct Command;
|
pub struct Command;
|
||||||
|
|
||||||
@ -39,12 +37,8 @@ impl WholeStreamCommand for Command {
|
|||||||
"Insert a new column with a given value."
|
"Insert a new column with a given value."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
insert(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
insert(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -71,8 +65,7 @@ impl WholeStreamCommand for Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn process_row(
|
async fn process_row(
|
||||||
scope: Arc<Scope>,
|
context: Arc<EvaluationContext>,
|
||||||
mut context: Arc<EvaluationContext>,
|
|
||||||
input: Value,
|
input: Value,
|
||||||
mut value: Arc<Value>,
|
mut value: Arc<Value>,
|
||||||
field: Arc<ColumnPath>,
|
field: Arc<ColumnPath>,
|
||||||
@ -87,9 +80,13 @@ async fn process_row(
|
|||||||
let for_block = input.clone();
|
let for_block = input.clone();
|
||||||
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
||||||
|
|
||||||
let scope = Scope::append_var(scope, "$it", input.clone());
|
context.scope.enter_scope();
|
||||||
|
context.scope.add_vars(&block.captured.entries);
|
||||||
|
context.scope.add_var("$it", input.clone());
|
||||||
|
|
||||||
let result = run_block(&block, Arc::make_mut(&mut context), input_stream, scope).await;
|
let result = run_block(&block.block, &*context, input_stream).await;
|
||||||
|
|
||||||
|
context.scope.exit_scope();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(mut stream) => {
|
Ok(mut stream) => {
|
||||||
@ -139,8 +136,9 @@ async fn process_row(
|
|||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::Nothing),
|
value: UntaggedValue::Primitive(Primitive::Nothing),
|
||||||
..
|
..
|
||||||
} => match scope
|
} => match context
|
||||||
.var("$it")
|
.scope
|
||||||
|
.get_var("$it")
|
||||||
.unwrap_or_else(|| UntaggedValue::nothing().into_untagged_value())
|
.unwrap_or_else(|| UntaggedValue::nothing().into_untagged_value())
|
||||||
.insert_data_at_column_path(&field, value.clone())
|
.insert_data_at_column_path(&field, value.clone())
|
||||||
{
|
{
|
||||||
@ -155,26 +153,20 @@ async fn process_row(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn insert(
|
async fn insert(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
raw_args: CommandArgs,
|
let context = Arc::new(EvaluationContext::from_raw(&raw_args));
|
||||||
registry: &CommandRegistry,
|
let (Arguments { column, value }, input) = raw_args.process().await?;
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let scope = raw_args.call_info.scope.clone();
|
|
||||||
let context = Arc::new(EvaluationContext::from_raw(&raw_args, ®istry));
|
|
||||||
let (Arguments { column, value }, input) = raw_args.process(®istry).await?;
|
|
||||||
let value = Arc::new(value);
|
let value = Arc::new(value);
|
||||||
let column = Arc::new(column);
|
let column = Arc::new(column);
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.then(move |input| {
|
.then(move |input| {
|
||||||
let scope = scope.clone();
|
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let value = value.clone();
|
let value = value.clone();
|
||||||
let column = column.clone();
|
let column = column.clone();
|
||||||
|
|
||||||
async {
|
async {
|
||||||
match process_row(scope, context, input, value, column).await {
|
match process_row(context, input, value, column).await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => OutputStream::one(Err(e)),
|
Err(e) => OutputStream::one(Err(e)),
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,8 @@ impl WholeStreamCommand for IntoInt {
|
|||||||
"Convert value to integer"
|
"Convert value to integer"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
into_int(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
into_int(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -43,12 +39,8 @@ impl WholeStreamCommand for IntoInt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn into_int(
|
async fn into_int(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
args: CommandArgs,
|
let (args, _): (IntoIntArgs, _) = args.process().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = registry.clone();
|
|
||||||
let (args, _): (IntoIntArgs, _) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let stream = args.rest.into_iter().map(|i| match i {
|
let stream = args.rest.into_iter().map(|i| match i {
|
||||||
Value {
|
Value {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -30,12 +29,8 @@ impl WholeStreamCommand for Command {
|
|||||||
"Keep the number of rows only"
|
"Keep the number of rows only"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
keep(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
keep(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -59,9 +54,8 @@ impl WholeStreamCommand for Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn keep(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn keep(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let (Arguments { rows }, input) = args.process().await?;
|
||||||
let (Arguments { rows }, input) = args.process(®istry).await?;
|
|
||||||
let rows_desired = if let Some(quantity) = rows {
|
let rows_desired = if let Some(quantity) = rows {
|
||||||
*quantity
|
*quantity
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,7 +3,8 @@ use crate::evaluate::evaluate_baseline_expr;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{hir::ClassifiedCommand, Scope, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_parser::ParserScope;
|
||||||
|
use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
Signature::build("keep until")
|
Signature::build("keep until")
|
||||||
.required(
|
.required(
|
||||||
"condition",
|
"condition",
|
||||||
SyntaxShape::Math,
|
SyntaxShape::RowCondition,
|
||||||
"The condition that must be met to stop keeping rows",
|
"The condition that must be met to stop keeping rows",
|
||||||
)
|
)
|
||||||
.filter()
|
.filter()
|
||||||
@ -27,33 +28,30 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Keeps rows until the condition matches."
|
"Keeps rows until the condition matches."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let ctx = Arc::new(EvaluationContext::from_args(&args));
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = Arc::new(registry.clone());
|
|
||||||
let scope = args.call_info.scope.clone();
|
|
||||||
|
|
||||||
let call_info = args.evaluate_once(®istry).await?;
|
let call_info = args.evaluate_once().await?;
|
||||||
|
|
||||||
let block = call_info.args.expect_nth(0)?.clone();
|
let block = call_info.args.expect_nth(0)?.clone();
|
||||||
|
|
||||||
let condition = Arc::new(match block {
|
let (condition, captured) = match block {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Block(block),
|
value: UntaggedValue::Block(captured_block),
|
||||||
tag,
|
tag,
|
||||||
} => {
|
} => {
|
||||||
if block.block.len() != 1 {
|
if captured_block.block.block.len() != 1 {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"Expected a condition",
|
"Expected a condition",
|
||||||
"expected a condition",
|
"expected a condition",
|
||||||
tag,
|
tag,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
match block.block[0].list.get(0) {
|
match captured_block.block.block[0].pipelines.get(0) {
|
||||||
Some(item) => match item {
|
Some(item) => match item.list.get(0) {
|
||||||
ClassifiedCommand::Expr(expr) => expr.clone(),
|
Some(ClassifiedCommand::Expr(expr)) => {
|
||||||
|
(Arc::new(expr.clone()), captured_block.captured.clone())
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"Expected a condition",
|
"Expected a condition",
|
||||||
@ -78,18 +76,21 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
tag,
|
tag,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
Ok(call_info
|
Ok(call_info
|
||||||
.input
|
.input
|
||||||
.take_while(move |item| {
|
.take_while(move |item| {
|
||||||
let condition = condition.clone();
|
let condition = condition.clone();
|
||||||
let registry = registry.clone();
|
let ctx = ctx.clone();
|
||||||
let scope = Scope::append_var(scope.clone(), "$it", item.clone());
|
ctx.scope.enter_scope();
|
||||||
|
ctx.scope.add_vars(&captured.entries);
|
||||||
|
ctx.scope.add_var("$it", item.clone());
|
||||||
trace!("ITEM = {:?}", item);
|
trace!("ITEM = {:?}", item);
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let result = evaluate_baseline_expr(&*condition, ®istry, scope).await;
|
let result = evaluate_baseline_expr(&*condition, &*ctx).await;
|
||||||
|
ctx.scope.exit_scope();
|
||||||
trace!("RESULT = {:?}", result);
|
trace!("RESULT = {:?}", result);
|
||||||
|
|
||||||
!matches!(result, Ok(ref v) if v.is_true())
|
!matches!(result, Ok(ref v) if v.is_true())
|
||||||
|
@ -3,7 +3,7 @@ use crate::evaluate::evaluate_baseline_expr;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{hir::ClassifiedCommand, Scope, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
Signature::build("keep while")
|
Signature::build("keep while")
|
||||||
.required(
|
.required(
|
||||||
"condition",
|
"condition",
|
||||||
SyntaxShape::Math,
|
SyntaxShape::RowCondition,
|
||||||
"The condition that must be met to keep rows",
|
"The condition that must be met to keep rows",
|
||||||
)
|
)
|
||||||
.filter()
|
.filter()
|
||||||
@ -27,32 +27,29 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
"Keeps rows while the condition matches."
|
"Keeps rows while the condition matches."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
let ctx = Arc::new(EvaluationContext::from_args(&args));
|
||||||
args: CommandArgs,
|
let call_info = args.evaluate_once().await?;
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
let registry = Arc::new(registry.clone());
|
|
||||||
let scope = args.call_info.scope.clone();
|
|
||||||
let call_info = args.evaluate_once(®istry).await?;
|
|
||||||
|
|
||||||
let block = call_info.args.expect_nth(0)?.clone();
|
let block = call_info.args.expect_nth(0)?.clone();
|
||||||
|
|
||||||
let condition = Arc::new(match block {
|
let (condition, captured) = match block {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Block(block),
|
value: UntaggedValue::Block(captured_block),
|
||||||
tag,
|
tag,
|
||||||
} => {
|
} => {
|
||||||
if block.block.len() != 1 {
|
if captured_block.block.block.len() != 1 {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"Expected a condition",
|
"Expected a condition",
|
||||||
"expected a condition",
|
"expected a condition",
|
||||||
tag,
|
tag,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
match block.block[0].list.get(0) {
|
match captured_block.block.block[0].pipelines.get(0) {
|
||||||
Some(item) => match item {
|
Some(item) => match item.list.get(0) {
|
||||||
ClassifiedCommand::Expr(expr) => expr.clone(),
|
Some(ClassifiedCommand::Expr(expr)) => {
|
||||||
|
(Arc::new(expr.clone()), captured_block.captured.clone())
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"Expected a condition",
|
"Expected a condition",
|
||||||
@ -77,18 +74,22 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
tag,
|
tag,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
Ok(call_info
|
Ok(call_info
|
||||||
.input
|
.input
|
||||||
.take_while(move |item| {
|
.take_while(move |item| {
|
||||||
let condition = condition.clone();
|
let condition = condition.clone();
|
||||||
let registry = registry.clone();
|
let ctx = ctx.clone();
|
||||||
let scope = Scope::append_var(scope.clone(), "$it", item.clone());
|
|
||||||
|
ctx.scope.enter_scope();
|
||||||
|
ctx.scope.add_var("$it", item.clone());
|
||||||
|
ctx.scope.add_vars(&captured.entries);
|
||||||
trace!("ITEM = {:?}", item);
|
trace!("ITEM = {:?}", item);
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let result = evaluate_baseline_expr(&*condition, ®istry, scope).await;
|
let result = evaluate_baseline_expr(&*condition, &*ctx).await;
|
||||||
|
ctx.scope.exit_scope();
|
||||||
trace!("RESULT = {:?}", result);
|
trace!("RESULT = {:?}", result);
|
||||||
|
|
||||||
matches!(result, Ok(ref v) if v.is_true())
|
matches!(result, Ok(ref v) if v.is_true())
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::command_registry::CommandRegistry;
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
@ -38,12 +37,8 @@ impl WholeStreamCommand for Kill {
|
|||||||
"Kill a process using the process id."
|
"Kill a process using the process id."
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(
|
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
&self,
|
kill(args).await
|
||||||
args: CommandArgs,
|
|
||||||
registry: &CommandRegistry,
|
|
||||||
) -> Result<OutputStream, ShellError> {
|
|
||||||
kill(args, registry).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -62,9 +57,7 @@ impl WholeStreamCommand for Kill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn kill(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn kill(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
|
||||||
|
|
||||||
let (
|
let (
|
||||||
KillArgs {
|
KillArgs {
|
||||||
pid,
|
pid,
|
||||||
@ -73,7 +66,7 @@ async fn kill(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
|||||||
quiet,
|
quiet,
|
||||||
},
|
},
|
||||||
..,
|
..,
|
||||||
) = args.process(®istry).await?;
|
) = args.process().await?;
|
||||||
let mut cmd = if cfg!(windows) {
|
let mut cmd = if cfg!(windows) {
|
||||||
let mut cmd = Command::new("taskkill");
|
let mut cmd = Command::new("taskkill");
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user