Merge remote-tracking branch 'origin/main' into plugin-ctrlc

This commit is contained in:
Andy Gayton 2024-06-26 10:02:46 -04:00
commit 7ff8d66d86
74 changed files with 4080 additions and 360 deletions

View File

@ -161,7 +161,7 @@ jobs:
# REF: https://github.com/marketplace/actions/gh-release
# Create a release only in nushell/nightly repo
- name: Publish Archive
uses: softprops/action-gh-release@v2.0.5
uses: softprops/action-gh-release@v2.0.6
if: ${{ startsWith(github.repository, 'nushell/nightly') }}
with:
prerelease: true

View File

@ -91,7 +91,7 @@ jobs:
# REF: https://github.com/marketplace/actions/gh-release
- name: Publish Archive
uses: softprops/action-gh-release@v2.0.5
uses: softprops/action-gh-release@v2.0.6
if: ${{ startsWith(github.ref, 'refs/tags/') }}
with:
draft: true

View File

@ -10,4 +10,4 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Check spelling
uses: crate-ci/typos@v1.22.7
uses: crate-ci/typos@v1.22.9

78
Cargo.lock generated
View File

@ -2769,7 +2769,7 @@ dependencies = [
[[package]]
name = "nu"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"assert_cmd",
"crossterm",
@ -2822,7 +2822,7 @@ dependencies = [
[[package]]
name = "nu-cli"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"chrono",
"crossterm",
@ -2857,7 +2857,7 @@ dependencies = [
[[package]]
name = "nu-cmd-base"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"indexmap",
"miette",
@ -2869,7 +2869,7 @@ dependencies = [
[[package]]
name = "nu-cmd-extra"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"fancy-regex",
"heck 0.5.0",
@ -2894,7 +2894,7 @@ dependencies = [
[[package]]
name = "nu-cmd-lang"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"itertools 0.12.1",
"nu-engine",
@ -2906,7 +2906,7 @@ dependencies = [
[[package]]
name = "nu-cmd-plugin"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"itertools 0.12.1",
"nu-engine",
@ -2917,7 +2917,7 @@ dependencies = [
[[package]]
name = "nu-color-config"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-ansi-term",
"nu-engine",
@ -2929,7 +2929,7 @@ dependencies = [
[[package]]
name = "nu-command"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"alphanumeric-sort",
"base64 0.22.1",
@ -3038,7 +3038,7 @@ dependencies = [
[[package]]
name = "nu-derive-value"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"convert_case",
"proc-macro-error",
@ -3049,7 +3049,7 @@ dependencies = [
[[package]]
name = "nu-engine"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-glob",
"nu-path",
@ -3059,7 +3059,7 @@ dependencies = [
[[package]]
name = "nu-explore"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"ansi-str",
"anyhow",
@ -3084,14 +3084,14 @@ dependencies = [
[[package]]
name = "nu-glob"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"doc-comment",
]
[[package]]
name = "nu-json"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"linked-hash-map",
"num-traits",
@ -3101,7 +3101,7 @@ dependencies = [
[[package]]
name = "nu-lsp"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"assert-json-diff",
"crossbeam-channel",
@ -3122,7 +3122,7 @@ dependencies = [
[[package]]
name = "nu-parser"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"bytesize",
"chrono",
@ -3138,7 +3138,7 @@ dependencies = [
[[package]]
name = "nu-path"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"dirs-next",
"omnipath",
@ -3147,7 +3147,7 @@ dependencies = [
[[package]]
name = "nu-plugin"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"log",
"nix",
@ -3162,7 +3162,7 @@ dependencies = [
[[package]]
name = "nu-plugin-core"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"interprocess",
"log",
@ -3176,7 +3176,7 @@ dependencies = [
[[package]]
name = "nu-plugin-engine"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"log",
"nu-engine",
@ -3191,7 +3191,7 @@ dependencies = [
[[package]]
name = "nu-plugin-protocol"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"bincode",
"nu-protocol",
@ -3203,7 +3203,7 @@ dependencies = [
[[package]]
name = "nu-plugin-test-support"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-ansi-term",
"nu-cmd-lang",
@ -3221,7 +3221,7 @@ dependencies = [
[[package]]
name = "nu-pretty-hex"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"heapless",
"nu-ansi-term",
@ -3230,7 +3230,7 @@ dependencies = [
[[package]]
name = "nu-protocol"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"brotli",
"byte-unit",
@ -3263,7 +3263,7 @@ dependencies = [
[[package]]
name = "nu-std"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"log",
"miette",
@ -3274,7 +3274,7 @@ dependencies = [
[[package]]
name = "nu-system"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"chrono",
"itertools 0.12.1",
@ -3292,7 +3292,7 @@ dependencies = [
[[package]]
name = "nu-table"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"fancy-regex",
"nu-ansi-term",
@ -3306,7 +3306,7 @@ dependencies = [
[[package]]
name = "nu-term-grid"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-utils",
"unicode-width",
@ -3314,7 +3314,7 @@ dependencies = [
[[package]]
name = "nu-test-support"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-glob",
"nu-path",
@ -3326,7 +3326,7 @@ dependencies = [
[[package]]
name = "nu-utils"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"crossterm_winapi",
"log",
@ -3352,7 +3352,7 @@ dependencies = [
[[package]]
name = "nu_plugin_example"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-cmd-lang",
"nu-plugin",
@ -3362,7 +3362,7 @@ dependencies = [
[[package]]
name = "nu_plugin_formats"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"eml-parser",
"ical",
@ -3375,7 +3375,7 @@ dependencies = [
[[package]]
name = "nu_plugin_gstat"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"git2",
"nu-plugin",
@ -3384,7 +3384,7 @@ dependencies = [
[[package]]
name = "nu_plugin_inc"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"nu-plugin",
"nu-protocol",
@ -3393,7 +3393,7 @@ dependencies = [
[[package]]
name = "nu_plugin_polars"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"chrono",
"chrono-tz 0.9.0",
@ -3424,7 +3424,7 @@ dependencies = [
[[package]]
name = "nu_plugin_query"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"gjson",
"nu-plugin",
@ -3436,7 +3436,7 @@ dependencies = [
[[package]]
name = "nu_plugin_stress_internals"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"interprocess",
"serde",
@ -3562,7 +3562,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "nuon"
version = "0.94.3"
version = "0.95.1"
dependencies = [
"chrono",
"fancy-regex",
@ -6493,9 +6493,9 @@ checksum = "425a23c7b7145bc7620c9c445817c37b1f78b6790aee9f208133f3c028975b60"
[[package]]
name = "uuid"
version = "1.8.0"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
dependencies = [
"getrandom",
"serde",

View File

@ -11,7 +11,7 @@ license = "MIT"
name = "nu"
repository = "https://github.com/nushell/nushell"
rust-version = "1.77.2"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -172,7 +172,7 @@ uu_mv = "0.0.26"
uu_whoami = "0.0.26"
uu_uname = "0.0.26"
uucore = "0.0.26"
uuid = "1.8.0"
uuid = "1.9.1"
v_htmlescape = "0.15.0"
wax = "0.6"
which = "6.0.0"
@ -180,22 +180,22 @@ windows = "0.54"
winreg = "0.52"
[dependencies]
nu-cli = { path = "./crates/nu-cli", version = "0.94.3" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.94.3" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.94.3" }
nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.94.3", optional = true }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.94.3" }
nu-command = { path = "./crates/nu-command", version = "0.94.3" }
nu-engine = { path = "./crates/nu-engine", version = "0.94.3" }
nu-explore = { path = "./crates/nu-explore", version = "0.94.3" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.94.3" }
nu-parser = { path = "./crates/nu-parser", version = "0.94.3" }
nu-path = { path = "./crates/nu-path", version = "0.94.3" }
nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.94.3" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.94.3" }
nu-std = { path = "./crates/nu-std", version = "0.94.3" }
nu-system = { path = "./crates/nu-system", version = "0.94.3" }
nu-utils = { path = "./crates/nu-utils", version = "0.94.3" }
nu-cli = { path = "./crates/nu-cli", version = "0.95.1" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.95.1" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.95.1" }
nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.95.1", optional = true }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.95.1" }
nu-command = { path = "./crates/nu-command", version = "0.95.1" }
nu-engine = { path = "./crates/nu-engine", version = "0.95.1" }
nu-explore = { path = "./crates/nu-explore", version = "0.95.1" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.95.1" }
nu-parser = { path = "./crates/nu-parser", version = "0.95.1" }
nu-path = { path = "./crates/nu-path", version = "0.95.1" }
nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.95.1" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.95.1" }
nu-std = { path = "./crates/nu-std", version = "0.95.1" }
nu-system = { path = "./crates/nu-system", version = "0.95.1" }
nu-utils = { path = "./crates/nu-utils", version = "0.95.1" }
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
@ -225,9 +225,9 @@ nix = { workspace = true, default-features = false, features = [
] }
[dev-dependencies]
nu-test-support = { path = "./crates/nu-test-support", version = "0.94.3" }
nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.94.3" }
nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.94.3" }
nu-test-support = { path = "./crates/nu-test-support", version = "0.95.1" }
nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.95.1" }
nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.95.1" }
assert_cmd = "2.0"
dirs-next = { workspace = true }
tango-bench = "0.5"
@ -310,4 +310,4 @@ bench = false
# Run individual benchmarks like `cargo bench -- <regex>` e.g. `cargo bench -- parse`
[[bench]]
name = "benchmarks"
harness = false
harness = false

View File

@ -5,27 +5,27 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cli"
edition = "2021"
license = "MIT"
name = "nu-cli"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-command = { path = "../nu-command", version = "0.94.3" }
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }
nu-command = { path = "../nu-command", version = "0.95.1" }
nu-test-support = { path = "../nu-test-support", version = "0.95.1" }
rstest = { workspace = true, default-features = false }
tempfile = { workspace = true }
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.3", optional = true }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.95.1", optional = true }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
nu-color-config = { path = "../nu-color-config", version = "0.95.1" }
nu-ansi-term = { workspace = true }
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
@ -46,4 +46,4 @@ which = { workspace = true }
[features]
plugin = ["nu-plugin-engine"]
system-clipboard = ["reedline/system_clipboard"]
system-clipboard = ["reedline/system_clipboard"]

View File

@ -5,17 +5,17 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-base"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-base"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
indexmap = { workspace = true }
miette = { workspace = true }
[dev-dependencies]
[dev-dependencies]

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-extra"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-extra"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,13 +13,13 @@ version = "0.94.3"
bench = false
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-json = { version = "0.94.3", path = "../nu-json" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-pretty-hex = { version = "0.94.3", path = "../nu-pretty-hex" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-json = { version = "0.95.1", path = "../nu-json" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-pretty-hex = { version = "0.95.1", path = "../nu-pretty-hex" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
# Potential dependencies for extras
heck = { workspace = true }
@ -33,6 +33,6 @@ v_htmlescape = { workspace = true }
itertools = { workspace = true }
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-command = { path = "../nu-command", version = "0.94.3" }
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }
nu-command = { path = "../nu-command", version = "0.95.1" }
nu-test-support = { path = "../nu-test-support", version = "0.95.1" }

View File

@ -6,16 +6,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-lang"
edition = "2021"
license = "MIT"
name = "nu-cmd-lang"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
itertools = { workspace = true }
shadow-rs = { version = "0.28", default-features = false }
@ -28,4 +28,4 @@ mimalloc = []
trash-support = []
sqlite = []
static-link-openssl = []
system-clipboard = []
system-clipboard = []

View File

@ -1,4 +1,5 @@
use nu_engine::command_prelude::*;
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Break;
@ -18,6 +19,15 @@ impl Command for Break {
.category(Category::Core)
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
_engine_state: &EngineState,

View File

@ -1,4 +1,5 @@
use nu_engine::command_prelude::*;
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Continue;
@ -18,6 +19,14 @@ impl Command for Continue {
.category(Category::Core)
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
_engine_state: &EngineState,

View File

@ -2,7 +2,7 @@ use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
};
use nu_protocol::{
engine::StateWorkingSet,
engine::{CommandType, StateWorkingSet},
eval_const::{eval_const_subexpression, eval_constant, eval_constant_with_input},
};
@ -41,6 +41,15 @@ impl Command for If {
.category(Category::Core)
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn is_const(&self) -> bool {
true
}

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Loop;
@ -20,6 +21,15 @@ impl Command for Loop {
.category(Category::Core)
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,7 +1,7 @@
use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
};
use nu_protocol::engine::Matcher;
use nu_protocol::engine::{CommandType, Matcher};
#[derive(Clone)]
pub struct Match;
@ -27,6 +27,15 @@ impl Command for Match {
.category(Category::Core)
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,5 +1,4 @@
use nu_engine::{command_prelude::*, get_full_help};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct Scope;
@ -20,10 +19,6 @@ impl Command for Scope {
"Commands for getting info about what is in scope."
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,5 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, EvalBlockFn};
use nu_protocol::engine::Closure;
use nu_protocol::engine::{Closure, CommandType};
#[derive(Clone)]
pub struct Try;
@ -31,6 +31,15 @@ impl Command for Try {
.category(Category::Core)
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct While;
@ -29,6 +30,15 @@ impl Command for While {
vec!["loop"]
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -5,16 +5,16 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-plugin"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-plugin"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.95.1" }
itertools = { workspace = true }
[dev-dependencies]
[dev-dependencies]

View File

@ -5,18 +5,18 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-color-confi
edition = "2021"
license = "MIT"
name = "nu-color-config"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-json = { path = "../nu-json", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-json = { path = "../nu-json", version = "0.95.1" }
nu-ansi-term = { workspace = true }
serde = { workspace = true, features = ["derive"] }
[dev-dependencies]
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
nu-test-support = { path = "../nu-test-support", version = "0.95.1" }

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-command"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-command"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,21 +13,21 @@ version = "0.94.3"
bench = false
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.3" }
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-glob = { path = "../nu-glob", version = "0.94.3" }
nu-json = { path = "../nu-json", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-system = { path = "../nu-system", version = "0.94.3" }
nu-table = { path = "../nu-table", version = "0.94.3" }
nu-term-grid = { path = "../nu-term-grid", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.95.1" }
nu-color-config = { path = "../nu-color-config", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-glob = { path = "../nu-glob", version = "0.95.1" }
nu-json = { path = "../nu-json", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-system = { path = "../nu-system", version = "0.95.1" }
nu-table = { path = "../nu-table", version = "0.95.1" }
nu-term-grid = { path = "../nu-term-grid", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
nu-ansi-term = { workspace = true }
nuon = { path = "../nuon", version = "0.94.3" }
nuon = { path = "../nuon", version = "0.95.1" }
alphanumeric-sort = { workspace = true }
base64 = { workspace = true }
@ -136,8 +136,8 @@ sqlite = ["rusqlite"]
trash-support = ["trash"]
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }
nu-test-support = { path = "../nu-test-support", version = "0.95.1" }
dirs-next = { workspace = true }
mockito = { workspace = true, default-features = false }
@ -145,4 +145,4 @@ quickcheck = { workspace = true }
quickcheck_macros = { workspace = true }
rstest = { workspace = true, default-features = false }
pretty_assertions = { workspace = true }
tempfile = { workspace = true }
tempfile = { workspace = true }

View File

@ -1,4 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, redirect_env};
use nu_protocol::engine::CommandType;
#[derive(Clone)]
pub struct ExportEnv;
@ -23,6 +24,15 @@ impl Command for ExportEnv {
"Run a block and preserve its environment in a current scope."
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -2,6 +2,7 @@ use nu_engine::{
command_prelude::*, find_in_dirs_env, get_dirs_var_from_call, get_eval_block_with_early_return,
redirect_env,
};
use nu_protocol::engine::CommandType;
use std::path::PathBuf;
/// Source a file for environment variables.
@ -28,6 +29,15 @@ impl Command for SourceEnv {
"Source the environment from a source file into the current environment."
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn run(
&self,
engine_state: &EngineState,

View File

@ -1,5 +1,5 @@
use nu_engine::{command_prelude::*, ClosureEval};
use nu_protocol::engine::Closure;
use nu_protocol::engine::{Closure, CommandType};
#[derive(Clone)]
pub struct Where;
@ -19,6 +19,10 @@ tables, known as "row conditions". On the other hand, reading the condition from
not supported."#
}
fn command_type(&self) -> CommandType {
CommandType::Keyword
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("where")
.input_output_types(vec![

View File

@ -64,7 +64,9 @@ impl Command for External {
let expanded_name = match &name {
// Expand tilde and ndots on the name if it's a bare string / glob (#13000)
Value::Glob { no_expand, .. } if !*no_expand => expand_ndots(expand_tilde(&*name_str)),
Value::Glob { no_expand, .. } if !*no_expand => {
expand_ndots_safe(expand_tilde(&*name_str))
}
_ => Path::new(&*name_str).to_owned(),
};
@ -294,7 +296,7 @@ fn expand_glob(
// For an argument that doesn't include the GLOB_CHARS, just do the `expand_tilde`
// and `expand_ndots` expansion
if !arg.contains(GLOB_CHARS) {
let path = expand_ndots(expand_tilde(arg));
let path = expand_ndots_safe(expand_tilde(arg));
return Ok(vec![path.into()]);
}
@ -582,6 +584,21 @@ fn escape_cmd_argument(arg: &Spanned<OsString>) -> Result<Cow<'_, OsStr>, ShellE
}
}
/// Expand ndots, but only if it looks like it probably contains them, because there is some lossy
/// path normalization that happens.
fn expand_ndots_safe(path: impl AsRef<Path>) -> PathBuf {
let string = path.as_ref().to_string_lossy();
// Use ndots if it contains at least `...`, since that's the minimum trigger point, and don't
// use it if it contains ://, because that looks like a URL scheme and the path normalization
// will mess with that.
if string.contains("...") && !string.contains("://") {
expand_ndots(path)
} else {
path.as_ref().to_owned()
}
}
#[cfg(test)]
mod test {
use super::*;
@ -610,7 +627,7 @@ mod test {
assert_eq!(actual, expected);
let actual = expand_glob("./a.txt", cwd, Span::unknown(), &None).unwrap();
let expected: Vec<OsString> = vec![Path::new(".").join("a.txt").into()];
let expected = &["./a.txt"];
assert_eq!(actual, expected);
let actual = expand_glob("[*.txt", cwd, Span::unknown(), &None).unwrap();

View File

@ -229,6 +229,38 @@ fn external_command_escape_args() {
})
}
#[test]
fn external_command_ndots_args() {
let actual = nu!(r#"
nu --testbin cococo foo/. foo/.. foo/... foo/./bar foo/../bar foo/.../bar ./bar ../bar .../bar
"#);
assert_eq!(
actual.out,
if cfg!(windows) {
// Windows is a bit weird right now, where if ndots has to fix something it's going to
// change everything to backslashes too. Would be good to fix that
r"foo/. foo/.. foo\..\.. foo/./bar foo/../bar foo\..\..\bar ./bar ../bar ..\..\bar"
} else {
r"foo/. foo/.. foo/../.. foo/./bar foo/../bar foo/../../bar ./bar ../bar ../../bar"
}
);
}
#[test]
fn external_command_url_args() {
// If ndots is not handled correctly, we can lose the double forward slashes that are needed
// here
let actual = nu!(r#"
nu --testbin cococo http://example.com http://example.com/.../foo //foo
"#);
assert_eq!(
actual.out,
"http://example.com http://example.com/.../foo //foo"
);
}
#[test]
#[cfg_attr(
not(target_os = "linux"),

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-derive-value"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-derive-value"
version = "0.94.3"
version = "0.95.1"
[lib]
proc-macro = true
@ -18,4 +18,4 @@ proc-macro2 = { workspace = true }
syn = { workspace = true }
quote = { workspace = true }
proc-macro-error = { workspace = true }
convert_case = { workspace = true }
convert_case = { workspace = true }

View File

@ -5,16 +5,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-engine"
edition = "2021"
license = "MIT"
name = "nu-engine"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", features = ["plugin"], version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-glob = { path = "../nu-glob", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", features = ["plugin"], version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-glob = { path = "../nu-glob", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
[features]
plugin = []
plugin = []

View File

@ -5,21 +5,21 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-explore"
edition = "2021"
license = "MIT"
name = "nu-explore"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-table = { path = "../nu-table", version = "0.94.3" }
nu-json = { path = "../nu-json", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-color-config = { path = "../nu-color-config", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-table = { path = "../nu-table", version = "0.95.1" }
nu-json = { path = "../nu-json", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
nu-ansi-term = { workspace = true }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.94.3" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.95.1" }
anyhow = { workspace = true }
log = { workspace = true }
@ -32,4 +32,4 @@ ansi-str = { workspace = true }
unicode-width = { workspace = true }
lscolors = { workspace = true, default-features = false, features = [
"nu-ansi-term",
] }
] }

View File

@ -1,6 +1,6 @@
[package]
name = "nu-glob"
version = "0.94.3"
version = "0.95.1"
authors = ["The Nushell Project Developers", "The Rust Project Developers"]
license = "MIT/Apache-2.0"
description = """
@ -14,4 +14,4 @@ categories = ["filesystem"]
bench = false
[dev-dependencies]
doc-comment = "0.3"
doc-comment = "0.3"

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-json"
edition = "2021"
license = "MIT"
name = "nu-json"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -23,5 +23,5 @@ serde = { workspace = true }
serde_json = { workspace = true }
[dev-dependencies]
# nu-path = { path="../nu-path", version = "0.94.3" }
# serde_json = "1.0"
# nu-path = { path="../nu-path", version = "0.95.1" }
# serde_json = "1.0"

View File

@ -3,14 +3,14 @@ authors = ["The Nushell Project Developers"]
description = "Nushell's integrated LSP server"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-lsp"
name = "nu-lsp"
version = "0.94.3"
version = "0.95.1"
edition = "2021"
license = "MIT"
[dependencies]
nu-cli = { path = "../nu-cli", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-cli = { path = "../nu-cli", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
reedline = { workspace = true }
@ -23,8 +23,8 @@ serde = { workspace = true }
serde_json = { workspace = true }
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-command = { path = "../nu-command", version = "0.94.3" }
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }
nu-command = { path = "../nu-command", version = "0.95.1" }
nu-test-support = { path = "../nu-test-support", version = "0.95.1" }
assert-json-diff = "2.0"
assert-json-diff = "2.0"

View File

@ -5,17 +5,17 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-parser"
edition = "2021"
license = "MIT"
name = "nu-parser"
version = "0.94.3"
version = "0.95.1"
exclude = ["/fuzz"]
[lib]
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-plugin-engine = { path = "../nu-plugin-engine", optional = true, version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-plugin-engine = { path = "../nu-plugin-engine", optional = true, version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
bytesize = { workspace = true }
chrono = { default-features = false, features = ['std'], workspace = true }
@ -27,4 +27,4 @@ serde_json = { workspace = true }
rstest = { workspace = true, default-features = false }
[features]
plugin = ["nu-plugin-engine"]
plugin = ["nu-plugin-engine"]

View File

@ -8,7 +8,6 @@ mod parse_keywords;
mod parse_patterns;
mod parse_shape_specs;
mod parser;
mod parser_path;
mod type_check;
pub use deparse::{escape_for_script_arg, escape_quote_string};
@ -18,8 +17,8 @@ pub use flatten::{
pub use known_external::KnownExternal;
pub use lex::{lex, lex_signature, Token, TokenContents};
pub use lite_parser::{lite_parse, LiteBlock, LiteCommand};
pub use nu_protocol::parser_path::*;
pub use parse_keywords::*;
pub use parser_path::*;
pub use parser::{
is_math_expression_like, parse, parse_block, parse_expression, parse_external_call,

View File

@ -2,7 +2,6 @@ use crate::{
exportable::Exportable,
parse_block,
parser::{parse_redirection, redirecting_builtin_error},
parser_path::ParserPath,
type_check::{check_block_input_output, type_compatible},
};
use itertools::Itertools;
@ -15,6 +14,7 @@ use nu_protocol::{
},
engine::{StateWorkingSet, DEFAULT_OVERLAY_NAME},
eval_const::eval_constant,
parser_path::ParserPath,
Alias, BlockId, DeclId, Module, ModuleId, ParseError, PositionalArg, ResolvedImportPattern,
Span, Spanned, SyntaxShape, Type, Value, VarId,
};
@ -42,32 +42,44 @@ use crate::{
};
/// These parser keywords can be aliased
pub const ALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[b"overlay hide", b"overlay new", b"overlay use"];
pub const ALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[
b"if",
b"match",
b"try",
b"overlay",
b"overlay hide",
b"overlay new",
b"overlay use",
];
pub const RESERVED_VARIABLE_NAMES: [&str; 3] = ["in", "nu", "env"];
/// These parser keywords cannot be aliased (either not possible, or support not yet added)
pub const UNALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[
b"export",
b"def",
b"export def",
b"for",
b"extern",
b"export extern",
b"alias",
b"export alias",
b"export-env",
b"const",
b"def",
b"extern",
b"module",
b"use",
b"export",
b"export alias",
b"export const",
b"export def",
b"export extern",
b"export module",
b"export use",
b"hide",
// b"overlay",
// b"overlay hide",
// b"overlay new",
// b"overlay use",
b"for",
b"loop",
b"while",
b"return",
b"break",
b"continue",
b"let",
b"const",
b"mut",
b"hide",
b"export-env",
b"source-env",
b"source",
b"where",
b"register",
@ -1192,7 +1204,7 @@ pub fn parse_export_in_block(
"export alias" => parse_alias(working_set, lite_command, None),
"export def" => parse_def(working_set, lite_command, None).0,
"export const" => parse_const(working_set, &lite_command.parts[1..]),
"export use" => parse_use(working_set, lite_command).0,
"export use" => parse_use(working_set, lite_command, None).0,
"export module" => parse_module(working_set, lite_command, None).0,
"export extern" => parse_extern(working_set, lite_command, None),
_ => {
@ -1211,6 +1223,7 @@ pub fn parse_export_in_module(
working_set: &mut StateWorkingSet,
lite_command: &LiteCommand,
module_name: &[u8],
parent_module: &mut Module,
) -> (Pipeline, Vec<Exportable>) {
let spans = &lite_command.parts[..];
@ -1416,7 +1429,8 @@ pub fn parse_export_in_module(
pipe: lite_command.pipe,
redirection: lite_command.redirection.clone(),
};
let (pipeline, exportables) = parse_use(working_set, &lite_command);
let (pipeline, exportables) =
parse_use(working_set, &lite_command, Some(parent_module));
let export_use_decl_id = if let Some(id) = working_set.find_decl(b"export use") {
id
@ -1759,7 +1773,7 @@ pub fn parse_module_block(
))
}
b"use" => {
let (pipeline, _) = parse_use(working_set, command);
let (pipeline, _) = parse_use(working_set, command, Some(&mut module));
block.pipelines.push(pipeline)
}
@ -1774,7 +1788,7 @@ pub fn parse_module_block(
}
b"export" => {
let (pipe, exportables) =
parse_export_in_module(working_set, command, module_name);
parse_export_in_module(working_set, command, module_name, &mut module);
for exportable in exportables {
match exportable {
@ -1884,6 +1898,48 @@ pub fn parse_module_block(
(block, module, module_comments)
}
fn module_needs_reloading(working_set: &StateWorkingSet, module_id: ModuleId) -> bool {
let module = working_set.get_module(module_id);
fn submodule_need_reloading(working_set: &StateWorkingSet, submodule_id: ModuleId) -> bool {
let submodule = working_set.get_module(submodule_id);
let submodule_changed = if let Some((file_path, file_id)) = &submodule.file {
let existing_contents = working_set.get_contents_of_file(*file_id);
let file_contents = file_path.read(working_set);
if let (Some(existing), Some(new)) = (existing_contents, file_contents) {
existing != new
} else {
false
}
} else {
false
};
if submodule_changed {
true
} else {
module_needs_reloading(working_set, submodule_id)
}
}
let export_submodule_changed = module
.submodules
.iter()
.any(|(_, submodule_id)| submodule_need_reloading(working_set, *submodule_id));
if export_submodule_changed {
return true;
}
let private_submodule_changed = module
.imported_modules
.iter()
.any(|submodule_id| submodule_need_reloading(working_set, *submodule_id));
private_submodule_changed
}
/// Parse a module from a file.
///
/// The module name is inferred from the stem of the file, unless specified in `name_override`.
@ -1922,23 +1978,26 @@ fn parse_module_file(
// Check if we've parsed the module before.
if let Some(module_id) = working_set.find_module_by_span(new_span) {
return Some(module_id);
if !module_needs_reloading(working_set, module_id) {
return Some(module_id);
}
}
// Add the file to the stack of files being processed.
if let Err(e) = working_set.files.push(path.path_buf(), path_span) {
if let Err(e) = working_set.files.push(path.clone().path_buf(), path_span) {
working_set.error(e);
return None;
}
// Parse the module
let (block, module, module_comments) =
let (block, mut module, module_comments) =
parse_module_block(working_set, new_span, module_name.as_bytes());
// Remove the file from the stack of files being processed.
working_set.files.pop();
let _ = working_set.add_block(Arc::new(block));
module.file = Some((path, file_id));
let module_id = working_set.add_module(&module_name, module, module_comments);
Some(module_id)
@ -2228,6 +2287,7 @@ pub fn parse_module(
pub fn parse_use(
working_set: &mut StateWorkingSet,
lite_command: &LiteCommand,
parent_module: Option<&mut Module>,
) -> (Pipeline, Vec<Exportable>) {
let spans = &lite_command.parts;
@ -2373,12 +2433,14 @@ pub fn parse_use(
);
};
let mut imported_modules = vec![];
let (definitions, errors) = module.resolve_import_pattern(
working_set,
module_id,
&import_pattern.members,
None,
name_span,
&mut imported_modules,
);
working_set.parse_errors.extend(errors);
@ -2420,6 +2482,9 @@ pub fn parse_use(
import_pattern.constants = constants.iter().map(|(_, id)| *id).collect();
if let Some(m) = parent_module {
m.track_imported_modules(&imported_modules)
}
// Extend the current scope with the module's exportables
working_set.use_decls(definitions.decls);
working_set.use_modules(definitions.modules);
@ -2853,6 +2918,7 @@ pub fn parse_overlay_use(working_set: &mut StateWorkingSet, call: Box<Call>) ->
&[],
Some(final_overlay_name.as_bytes()),
call.head,
&mut vec![],
)
} else {
origin_module.resolve_import_pattern(
@ -2863,6 +2929,7 @@ pub fn parse_overlay_use(working_set: &mut StateWorkingSet, call: Box<Call>) ->
}],
Some(final_overlay_name.as_bytes()),
call.head,
&mut vec![],
)
}
} else {

View File

@ -934,15 +934,12 @@ pub fn parse_internal_call(
let output = signature.get_output_type();
// storing the var ID for later due to borrowing issues
let lib_dirs_var_id = if decl.is_builtin() {
match decl.name() {
"use" | "overlay use" | "source-env" | "nu-check" => {
find_dirs_var(working_set, LIB_DIRS_VAR)
}
_ => None,
let lib_dirs_var_id = match decl.name() {
"use" | "overlay use" | "source-env" if decl.is_keyword() => {
find_dirs_var(working_set, LIB_DIRS_VAR)
}
} else {
None
"nu-check" if decl.is_builtin() => find_dirs_var(working_set, LIB_DIRS_VAR),
_ => None,
};
// The index into the positional parameter in the definition
@ -5380,7 +5377,7 @@ pub fn parse_builtin_commands(
}
b"alias" => parse_alias(working_set, lite_command, None),
b"module" => parse_module(working_set, lite_command, None).0,
b"use" => parse_use(working_set, lite_command).0,
b"use" => parse_use(working_set, lite_command, None).0,
b"overlay" => {
if let Some(redirection) = lite_command.redirection.as_ref() {
working_set.error(redirecting_builtin_error("overlay", redirection));

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-path"
edition = "2021"
license = "MIT"
name = "nu-path"
version = "0.94.3"
version = "0.95.1"
exclude = ["/fuzz"]
[lib]
@ -18,4 +18,4 @@ dirs-next = { workspace = true }
omnipath = { workspace = true }
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))'.dependencies]
pwd = { workspace = true }
pwd = { workspace = true }

161
crates/nu-path/src/form.rs Normal file
View File

@ -0,0 +1,161 @@
use std::ffi::OsStr;
mod private {
use std::ffi::OsStr;
// This trait should not be extended by external crates in order to uphold safety guarantees.
// As such, this trait is put inside a private module to prevent external impls.
// This ensures that all possible [`PathForm`]s can only be defined here and will:
// - be zero sized (enforced anyways by the `repr(transparent)` on `Path`)
// - have a no-op [`Drop`] implementation
pub trait Sealed: 'static {
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(path: &P) -> bool;
}
}
/// A marker trait for the different kinds of path forms.
/// Each form has its own invariants that are guaranteed be upheld.
/// The list of path forms are:
/// - [`Any`]: a path with no invariants. It may be a relative or an absolute path.
/// - [`Relative`]: a strictly relative path.
/// - [`Absolute`]: a strictly absolute path.
/// - [`Canonical`]: a path that must be in canonicalized form.
pub trait PathForm: private::Sealed {}
impl PathForm for Any {}
impl PathForm for Relative {}
impl PathForm for Absolute {}
impl PathForm for Canonical {}
/// A path whose form is unknown. It could be a relative, absolute, or canonical path.
///
/// The path is not guaranteed to be normalized. It may contain unresolved symlinks,
/// trailing slashes, dot components (`..` or `.`), and repeated path separators.
pub struct Any;
impl private::Sealed for Any {
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(_: &P) -> bool {
true
}
}
/// A strictly relative path.
///
/// The path is not guaranteed to be normalized. It may contain unresolved symlinks,
/// trailing slashes, dot components (`..` or `.`), and repeated path separators.
pub struct Relative;
impl private::Sealed for Relative {
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(path: &P) -> bool {
std::path::Path::new(path).is_relative()
}
}
/// An absolute path.
///
/// The path is not guaranteed to be normalized. It may contain unresolved symlinks,
/// trailing slashes, dot components (`..` or `.`), and repeated path separators.
pub struct Absolute;
impl private::Sealed for Absolute {
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(path: &P) -> bool {
std::path::Path::new(path).is_absolute()
}
}
// A canonical path.
//
// An absolute path with all intermediate components normalized and symbolic links resolved.
pub struct Canonical;
impl private::Sealed for Canonical {
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(_: &P) -> bool {
true
}
}
/// A marker trait for [`PathForm`]s that may be relative paths.
/// This includes only the [`Any`] and [`Relative`] path forms.
///
/// [`push`](crate::PathBuf::push) and [`join`](crate::Path::join)
/// operations only support [`MaybeRelative`] path forms as input.
pub trait MaybeRelative: PathForm {}
impl MaybeRelative for Any {}
impl MaybeRelative for Relative {}
/// A marker trait for [`PathForm`]s that may be absolute paths.
/// This includes the [`Any`], [`Absolute`], and [`Canonical`] path forms.
pub trait MaybeAbsolute: PathForm {}
impl MaybeAbsolute for Any {}
impl MaybeAbsolute for Absolute {}
impl MaybeAbsolute for Canonical {}
/// A marker trait for [`PathForm`]s that are absolute paths.
/// This includes only the [`Absolute`] and [`Canonical`] path forms.
///
/// Only [`PathForm`]s that implement this trait can be easily converted to [`std::path::Path`]
/// or [`std::path::PathBuf`]. This is to encourage/force other Nushell crates to account for
/// the emulated current working directory, instead of using the [`std::env::current_dir`].
pub trait IsAbsolute: PathForm {}
impl IsAbsolute for Absolute {}
impl IsAbsolute for Canonical {}
/// A marker trait that signifies one [`PathForm`] can be used as or trivially converted to
/// another [`PathForm`].
///
/// The list of possible conversions are:
/// - [`Relative`], [`Absolute`], or [`Canonical`] into [`Any`].
/// - [`Canonical`] into [`Absolute`].
/// - Any form into itself.
pub trait PathCast<Form: PathForm>: PathForm {}
impl<Form: PathForm> PathCast<Form> for Form {}
impl PathCast<Any> for Relative {}
impl PathCast<Any> for Absolute {}
impl PathCast<Any> for Canonical {}
impl PathCast<Absolute> for Canonical {}
/// A trait used to specify the output [`PathForm`] of a path join operation.
///
/// The output path forms based on the left hand side path form are as follows:
///
/// | Left hand side | Output form |
/// | --------------:|:------------ |
/// | [`Any`] | [`Any`] |
/// | [`Relative`] | [`Any`] |
/// | [`Absolute`] | [`Absolute`] |
/// | [`Canonical`] | [`Absolute`] |
pub trait PathJoin: PathForm {
type Output: PathForm;
}
impl PathJoin for Any {
type Output = Self;
}
impl PathJoin for Relative {
type Output = Any;
}
impl PathJoin for Absolute {
type Output = Self;
}
impl PathJoin for Canonical {
type Output = Absolute;
}
/// A marker trait for [`PathForm`]s that support setting the file name or extension.
///
/// This includes the [`Any`], [`Relative`], and [`Absolute`] path forms.
/// [`Canonical`] paths do not support this, since appending file names and extensions that contain
/// path separators can cause the path to no longer be canonical.
pub trait PathSet: PathForm {}
impl PathSet for Any {}
impl PathSet for Relative {}
impl PathSet for Absolute {}
/// A marker trait for [`PathForm`]s that support pushing [`MaybeRelative`] paths.
///
/// This includes only [`Any`] and [`Absolute`] path forms.
/// Pushing onto a [`Relative`] path could cause it to become [`Absolute`],
/// which is why they do not support pushing.
/// In the future, a `push_rel` and/or a `try_push` method could be added as an alternative.
/// Similarly, [`Canonical`] paths may become uncanonical if a non-canonical path is pushed onto it.
pub trait PathPush: PathSet {}
impl PathPush for Any {}
impl PathPush for Absolute {}

View File

@ -2,12 +2,15 @@ mod assert_path_eq;
mod components;
pub mod dots;
pub mod expansions;
pub mod form;
mod helpers;
mod path;
mod tilde;
mod trailing_slash;
pub use components::components;
pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs};
pub use helpers::{cache_dir, config_dir, data_dir, get_canonicalized_path, home_dir};
pub use path::*;
pub use tilde::expand_tilde;
pub use trailing_slash::{has_trailing_slash, strip_trailing_slash};

3095
crates/nu-path/src/path.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,14 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin-core
edition = "2021"
license = "MIT"
name = "nu-plugin-core"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3", default-features = false }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1", default-features = false }
rmp-serde = { workspace = true }
serde = { workspace = true }
@ -25,4 +25,4 @@ default = ["local-socket"]
local-socket = ["interprocess", "nu-plugin-protocol/local-socket"]
[target.'cfg(target_os = "windows")'.dependencies]
windows = { workspace = true }
windows = { workspace = true }

View File

@ -5,17 +5,17 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin-engi
edition = "2021"
license = "MIT"
name = "nu-plugin-engine"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-system = { path = "../nu-system", version = "0.94.3" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3" }
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.3", default-features = false }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-system = { path = "../nu-system", version = "0.95.1" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1", default-features = false }
serde = { workspace = true }
log = { workspace = true }
@ -31,4 +31,4 @@ local-socket = ["nu-plugin-core/local-socket"]
windows = { workspace = true, features = [
# For setting process creation flags
"Win32_System_Threading",
] }
] }

View File

@ -5,14 +5,14 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin-prot
edition = "2021"
license = "MIT"
name = "nu-plugin-protocol"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
bincode = "1.3"
serde = { workspace = true, features = ["derive"] }
@ -21,4 +21,4 @@ typetag = "0.2"
[features]
default = ["local-socket"]
local-socket = []
local-socket = []

View File

@ -1,6 +1,6 @@
[package]
name = "nu-plugin-test-support"
version = "0.94.3"
version = "0.95.1"
edition = "2021"
license = "MIT"
description = "Testing support for Nushell plugins"
@ -12,17 +12,17 @@ bench = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3", features = ["plugin"] }
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-parser = { path = "../nu-parser", version = "0.94.3", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.3" }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.3" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.95.1", features = ["plugin"] }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
nu-parser = { path = "../nu-parser", version = "0.95.1", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1" }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.95.1" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }
nu-ansi-term = { workspace = true }
similar = "2.5"
[dev-dependencies]
typetag = "0.2"
serde = "1.0"
serde = "1.0"

View File

@ -5,16 +5,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin"
edition = "2021"
license = "MIT"
name = "nu-plugin"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3" }
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.3", default-features = false }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.95.1" }
nu-plugin-core = { path = "../nu-plugin-core", version = "0.95.1", default-features = false }
log = { workspace = true }
thiserror = "1.0"
@ -29,4 +29,4 @@ local-socket = ["nu-plugin-core/local-socket"]
[target.'cfg(target_family = "unix")'.dependencies]
# For setting the process group ID (EnterForeground / LeaveForeground)
nix = { workspace = true, default-features = false, features = ["process"] }
nix = { workspace = true, default-features = false, features = ["process"] }

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-pretty-hex"
edition = "2021"
license = "MIT"
name = "nu-pretty-hex"
version = "0.94.3"
version = "0.95.1"
[lib]
doctest = false
@ -18,4 +18,4 @@ nu-ansi-term = { workspace = true }
[dev-dependencies]
heapless = { version = "0.8", default-features = false }
rand = "0.8"
rand = "0.8"

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-protocol"
edition = "2021"
license = "MIT"
name = "nu-protocol"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,10 +13,10 @@ version = "0.94.3"
bench = false
[dependencies]
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-system = { path = "../nu-system", version = "0.94.3" }
nu-derive-value = { path = "../nu-derive-value", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-system = { path = "../nu-system", version = "0.95.1" }
nu-derive-value = { path = "../nu-derive-value", version = "0.95.1" }
brotli = { workspace = true, optional = true }
byte-unit = { version = "5.1", features = [ "serde" ] }
@ -47,11 +47,11 @@ plugin = [
serde_json = { workspace = true }
strum = "0.26"
strum_macros = "0.26"
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
nu-test-support = { path = "../nu-test-support", version = "0.95.1" }
pretty_assertions = { workspace = true }
rstest = { workspace = true }
tempfile = { workspace = true }
os_pipe = { workspace = true }
[package.metadata.docs.rs]
all-features = true
all-features = true

View File

@ -81,7 +81,9 @@ pub(super) fn build_usage(comment_lines: &[&[u8]]) -> (String, String) {
usage.push_str(&comment_line);
}
if let Some((brief_usage, extra_usage)) = usage.split_once("\n\n") {
if let Some((brief_usage, extra_usage)) = usage.split_once("\r\n\r\n") {
(brief_usage.to_string(), extra_usage.to_string())
} else if let Some((brief_usage, extra_usage)) = usage.split_once("\n\n") {
(brief_usage.to_string(), extra_usage.to_string())
} else {
(usage, String::default())

View File

@ -194,31 +194,11 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
// if not, use the default /usr/share/nushell/vendor/autoload
// check to see if NU_VENDOR_AUTOLOAD_DIR env var is set, if not, use the default
Value::string(
option_env!("NU_VENDOR_AUTOLOAD_DIR")
.map(String::from)
.unwrap_or_else(|| {
if cfg!(windows) {
let all_user_profile = match engine_state.get_env_var("ALLUSERPROFILE") {
Some(v) => format!(
"{}\\nushell\\vendor\\autoload",
v.coerce_string().unwrap_or("C:\\ProgramData".into())
),
None => "C:\\ProgramData\\nushell\\vendor\\autoload".into(),
};
all_user_profile
} else {
// In non-Windows environments, if NU_VENDOR_AUTOLOAD_DIR is not set
// check to see if PREFIX env var is set, and use it as PREFIX/nushell/vendor/autoload
// otherwise default to /usr/share/nushell/vendor/autoload
option_env!("PREFIX").map(String::from).map_or_else(
|| "/usr/local/share/nushell/vendor/autoload".into(),
|prefix| format!("{}/share/nushell/vendor/autoload", prefix),
)
}
}),
span,
),
if let Some(path) = get_vendor_autoload_dir(engine_state) {
Value::string(path.to_string_lossy(), span)
} else {
Value::error(ShellError::ConfigDirNotFound { span: Some(span) }, span)
},
);
record.push("temp-path", {
@ -275,6 +255,41 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
Value::record(record, span)
}
pub fn get_vendor_autoload_dir(engine_state: &EngineState) -> Option<PathBuf> {
// pseudo code
// if env var NU_VENDOR_AUTOLOAD_DIR is set, in any platform, use it
// if not, if windows, use ALLUSERPROFILE\nushell\vendor\autoload
// if not, if non-windows, if env var PREFIX is set, use PREFIX/share/nushell/vendor/autoload
// if not, use the default /usr/share/nushell/vendor/autoload
// check to see if NU_VENDOR_AUTOLOAD_DIR env var is set, if not, use the default
Some(
option_env!("NU_VENDOR_AUTOLOAD_DIR")
.map(String::from)
.unwrap_or_else(|| {
if cfg!(windows) {
let all_user_profile = match engine_state.get_env_var("ALLUSERPROFILE") {
Some(v) => format!(
"{}\\nushell\\vendor\\autoload",
v.coerce_string().unwrap_or("C:\\ProgramData".into())
),
None => "C:\\ProgramData\\nushell\\vendor\\autoload".into(),
};
all_user_profile
} else {
// In non-Windows environments, if NU_VENDOR_AUTOLOAD_DIR is not set
// check to see if PREFIX env var is set, and use it as PREFIX/nushell/vendor/autoload
// otherwise default to /usr/share/nushell/vendor/autoload
option_env!("PREFIX").map(String::from).map_or_else(
|| "/usr/local/share/nushell/vendor/autoload".into(),
|prefix| format!("{}/share/nushell/vendor/autoload", prefix),
)
}
})
.into(),
)
}
fn eval_const_call(
working_set: &StateWorkingSet,
call: &Call,

View File

@ -11,6 +11,7 @@ mod example;
mod id;
mod lev_distance;
mod module;
pub mod parser_path;
mod pipeline;
#[cfg(feature = "plugin")]
mod plugin;

View File

@ -1,8 +1,9 @@
use crate::{
ast::ImportPatternMember, engine::StateWorkingSet, BlockId, DeclId, ModuleId, ParseError, Span,
Value, VarId,
ast::ImportPatternMember, engine::StateWorkingSet, BlockId, DeclId, FileId, ModuleId,
ParseError, Span, Value, VarId,
};
use crate::parser_path::ParserPath;
use indexmap::IndexMap;
pub struct ResolvedImportPattern {
@ -35,6 +36,8 @@ pub struct Module {
pub env_block: Option<BlockId>, // `export-env { ... }` block
pub main: Option<DeclId>, // `export def main`
pub span: Option<Span>,
pub imported_modules: Vec<ModuleId>, // use other_module.nu
pub file: Option<(ParserPath, FileId)>,
}
impl Module {
@ -47,6 +50,8 @@ impl Module {
env_block: None,
main: None,
span: None,
imported_modules: vec![],
file: None,
}
}
@ -59,6 +64,8 @@ impl Module {
env_block: None,
main: None,
span: Some(span),
imported_modules: vec![],
file: None,
}
}
@ -82,6 +89,12 @@ impl Module {
self.env_block = Some(block_id);
}
pub fn track_imported_modules(&mut self, module_id: &[ModuleId]) {
for m in module_id {
self.imported_modules.push(*m)
}
}
pub fn has_decl(&self, name: &[u8]) -> bool {
if name == self.name && self.main.is_some() {
return true;
@ -90,6 +103,9 @@ impl Module {
self.decls.contains_key(name)
}
/// Resolve `members` from given module, which is indicated by `self_id` to import.
///
/// When resolving, all modules are recorded in `imported_modules`.
pub fn resolve_import_pattern(
&self,
working_set: &StateWorkingSet,
@ -97,7 +113,9 @@ impl Module {
members: &[ImportPatternMember],
name_override: Option<&[u8]>, // name under the module was stored (doesn't have to be the same as self.name)
backup_span: Span,
imported_modules: &mut Vec<ModuleId>,
) -> (ResolvedImportPattern, Vec<ParseError>) {
imported_modules.push(self_id);
let final_name = name_override.unwrap_or(&self.name).to_vec();
let (head, rest) = if let Some((head, rest)) = members.split_first() {
@ -112,8 +130,14 @@ impl Module {
let submodule = working_set.get_module(*id);
let span = submodule.span.or(self.span).unwrap_or(backup_span);
let (sub_results, sub_errors) =
submodule.resolve_import_pattern(working_set, *id, &[], None, span);
let (sub_results, sub_errors) = submodule.resolve_import_pattern(
working_set,
*id,
&[],
None,
span,
imported_modules,
);
errors.extend(sub_errors);
for (sub_name, sub_decl_id) in sub_results.decls {
@ -212,6 +236,7 @@ impl Module {
rest,
None,
self.span.unwrap_or(backup_span),
imported_modules,
)
} else {
(
@ -234,6 +259,7 @@ impl Module {
&[],
None,
self.span.unwrap_or(backup_span),
imported_modules,
);
decls.extend(sub_results.decls);
@ -287,6 +313,7 @@ impl Module {
rest,
None,
self.span.unwrap_or(backup_span),
imported_modules,
);
decls.extend(sub_results.decls);

View File

@ -1,4 +1,4 @@
use nu_protocol::engine::{StateWorkingSet, VirtualPath};
use crate::engine::{StateWorkingSet, VirtualPath};
use std::{
ffi::OsStr,
path::{Path, PathBuf},

View File

@ -5,12 +5,12 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-std"
edition = "2021"
license = "MIT"
name = "nu-std"
version = "0.94.3"
version = "0.95.1"
[dependencies]
nu-parser = { version = "0.94.3", path = "../nu-parser" }
nu-protocol = { version = "0.94.3", path = "../nu-protocol" }
nu-engine = { version = "0.94.3", path = "../nu-engine" }
nu-parser = { version = "0.95.1", path = "../nu-parser" }
nu-protocol = { version = "0.95.1", path = "../nu-protocol" }
nu-engine = { version = "0.95.1", path = "../nu-engine" }
miette = { workspace = true, features = ["fancy-no-backtrace"] }
log = "0.4"
log = "0.4"

View File

@ -3,7 +3,7 @@ authors = ["The Nushell Project Developers", "procs creators"]
description = "Nushell system querying"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-system"
name = "nu-system"
version = "0.94.3"
version = "0.95.1"
edition = "2021"
license = "MIT"
@ -45,4 +45,4 @@ windows = { workspace = true, features = [
"Win32_System_SystemInformation",
"Win32_System_Threading",
"Win32_UI_Shell",
]}
]}

View File

@ -5,20 +5,20 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-table"
edition = "2021"
license = "MIT"
name = "nu-table"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-color-config = { path = "../nu-color-config", version = "0.95.1" }
nu-ansi-term = { workspace = true }
once_cell = { workspace = true }
fancy-regex = { workspace = true }
tabled = { workspace = true, features = ["color"], default-features = false }
[dev-dependencies]
# nu-test-support = { path="../nu-test-support", version = "0.94.3" }
# nu-test-support = { path="../nu-test-support", version = "0.95.1" }

View File

@ -5,12 +5,12 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-term-grid"
edition = "2021"
license = "MIT"
name = "nu-term-grid"
version = "0.94.3"
version = "0.95.1"
[lib]
bench = false
[dependencies]
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
unicode-width = { workspace = true }
unicode-width = { workspace = true }

View File

@ -5,17 +5,17 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-test-suppor
edition = "2021"
license = "MIT"
name = "nu-test-support"
version = "0.94.3"
version = "0.95.1"
[lib]
doctest = false
bench = false
[dependencies]
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-glob = { path = "../nu-glob", version = "0.94.3" }
nu-utils = { path = "../nu-utils", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.95.1" }
nu-glob = { path = "../nu-glob", version = "0.95.1" }
nu-utils = { path = "../nu-utils", version = "0.95.1" }
num-format = { workspace = true }
which = { workspace = true }
tempfile = { workspace = true }
tempfile = { workspace = true }

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-utils"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-utils"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
@ -29,4 +29,4 @@ unicase = "2.7.0"
crossterm_winapi = "0.9"
[target.'cfg(unix)'.dependencies]
nix = { workspace = true, default-features = false, features = ["user", "fs"] }
nix = { workspace = true, default-features = false, features = ["user", "fs"] }

View File

@ -1,6 +1,6 @@
# Nushell Config File
#
# version = "0.94.3"
# version = "0.95.1"
# For more information on defining custom themes, see
# https://www.nushell.sh/book/coloring_and_theming.html
@ -888,4 +888,4 @@ $env.config = {
event: { edit: selectall }
}
]
}
}

View File

@ -1,6 +1,6 @@
# Nushell Environment Config File
#
# version = "0.94.3"
# version = "0.95.1"
def create_left_prompt [] {
let dir = match (do --ignore-shell-errors { $env.PWD | path relative-to $nu.home-path }) {
@ -98,4 +98,4 @@ $env.NU_PLUGIN_DIRS = [
# $env.PATH = ($env.PATH | uniq)
# To load from a custom file you can use:
# source ($nu.default-config-dir | path join 'custom.nu')
# source ($nu.default-config-dir | path join 'custom.nu')

View File

@ -10,10 +10,10 @@ name = "nu_plugin_custom_values"
bench = false
[dependencies]
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
serde = { workspace = true, default-features = false }
typetag = "0.2"
[dev-dependencies]
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.95.1" }

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_exam
edition = "2021"
license = "MIT"
name = "nu_plugin_example"
version = "0.94.3"
version = "0.95.1"
[[bin]]
name = "nu_plugin_example"
@ -15,9 +15,9 @@ bench = false
bench = false
[dependencies]
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
[dev-dependencies]
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.95.1" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }

View File

@ -5,12 +5,12 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_form
edition = "2021"
license = "MIT"
name = "nu_plugin_formats"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
indexmap = { workspace = true }
eml-parser = "0.1"
@ -18,4 +18,4 @@ ical = "0.11"
rust-ini = "0.21.0"
[dev-dependencies]
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.95.1" }

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_gsta
edition = "2021"
license = "MIT"
name = "nu_plugin_gstat"
version = "0.94.3"
version = "0.95.1"
[lib]
doctest = false
@ -16,7 +16,7 @@ name = "nu_plugin_gstat"
bench = false
[dependencies]
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
git2 = "0.19"
git2 = "0.19"

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_inc"
edition = "2021"
license = "MIT"
name = "nu_plugin_inc"
version = "0.94.3"
version = "0.95.1"
[lib]
doctest = false
@ -16,7 +16,7 @@ name = "nu_plugin_inc"
bench = false
[dependencies]
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1", features = ["plugin"] }
semver = "1.0"
semver = "1.0"

View File

@ -6,7 +6,7 @@
# it also allows us to test the plugin interface with something manually implemented in a scripting
# language without adding any extra dependencies to our tests.
const NUSHELL_VERSION = "0.94.3"
const NUSHELL_VERSION = "0.95.1"
const PLUGIN_VERSION = "0.1.0" # bump if you change commands!
def main [--stdio] {
@ -265,4 +265,4 @@ def start_plugin [] {
}) |
each { from json | handle_input } |
ignore
}
}

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu_plugin_polars"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_polars"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -17,9 +17,9 @@ bench = false
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-path = { path = "../nu-path", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-path = { path = "../nu-path", version = "0.95.1" }
# Potential dependencies for extras
chrono = { workspace = true, features = ["std", "unstable-locales"], default-features = false }
@ -36,7 +36,7 @@ polars-ops = { version = "0.40"}
polars-plan = { version = "0.40", features = ["regex"]}
polars-utils = { version = "0.40"}
typetag = "0.2"
uuid = { version = "1.7", features = ["v4", "serde"] }
uuid = { version = "1.9", features = ["v4", "serde"] }
[dependencies.polars]
features = [
@ -73,9 +73,9 @@ optional = false
version = "0.40"
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-command = { path = "../nu-command", version = "0.94.3" }
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
tempfile.workspace = true
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-command = { path = "../nu-command", version = "0.95.1" }
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.95.1" }
tempfile.workspace = true

View File

@ -27,7 +27,7 @@ import sys
import json
NUSHELL_VERSION = "0.94.3"
NUSHELL_VERSION = "0.95.1"
PLUGIN_VERSION = "0.1.0" # bump if you change commands!
@ -258,4 +258,4 @@ if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "--stdio":
plugin()
else:
print("Run me from inside nushell!")
print("Run me from inside nushell!")

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_quer
edition = "2021"
license = "MIT"
name = "nu_plugin_query"
version = "0.94.3"
version = "0.95.1"
[lib]
doctest = false
@ -16,10 +16,10 @@ name = "nu_plugin_query"
bench = false
[dependencies]
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-plugin = { path = "../nu-plugin", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
gjson = "0.8"
scraper = { default-features = false, version = "0.19" }
sxd-document = "0.3"
sxd-xpath = "0.4"
sxd-xpath = "0.4"

View File

@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_stre
edition = "2021"
license = "MIT"
name = "nu_plugin_stress_internals"
version = "0.94.3"
version = "0.95.1"
[[bin]]
name = "nu_plugin_stress_internals"
@ -16,4 +16,4 @@ bench = false
# assumptions about the serialized format
serde = { workspace = true }
serde_json = { workspace = true }
interprocess = { workspace = true }
interprocess = { workspace = true }

View File

@ -5,16 +5,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nuon"
edition = "2021"
license = "MIT"
name = "nuon"
version = "0.94.3"
version = "0.95.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-parser = { path = "../nu-parser", version = "0.94.3" }
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
nu-engine = { path = "../nu-engine", version = "0.94.3" }
nu-parser = { path = "../nu-parser", version = "0.95.1" }
nu-protocol = { path = "../nu-protocol", version = "0.95.1" }
nu-engine = { path = "../nu-engine", version = "0.95.1" }
once_cell = { workspace = true }
fancy-regex = { workspace = true }
[dev-dependencies]
chrono = { workspace = true }
chrono = { workspace = true }

View File

@ -9,8 +9,9 @@ use nu_protocol::{
};
use nu_utils::{get_default_config, get_default_env};
use std::{
fs,
fs::File,
io::Write,
io::{Result, Write},
panic::{catch_unwind, AssertUnwindSafe},
path::Path,
sync::Arc,
@ -176,6 +177,46 @@ pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut
}
}
fn read_and_sort_directory(path: &Path) -> Result<Vec<String>> {
let mut entries = Vec::new();
for entry in fs::read_dir(path)? {
let entry = entry?;
let file_name = entry.file_name();
let file_name_str = file_name.into_string().unwrap_or_default();
entries.push(file_name_str);
}
entries.sort();
Ok(entries)
}
pub(crate) fn read_vendor_autoload_files(engine_state: &mut EngineState, stack: &mut Stack) {
warn!(
"read_vendor_autoload_files() {}:{}:{}",
file!(),
line!(),
column!()
);
// read and source vendor_autoload_files file if exists
if let Some(autoload_dir) = nu_protocol::eval_const::get_vendor_autoload_dir(engine_state) {
warn!("read_vendor_autoload_files: {}", autoload_dir.display());
if autoload_dir.exists() {
let entries = read_and_sort_directory(&autoload_dir);
if let Ok(entries) = entries {
for entry in entries {
let path = autoload_dir.join(entry);
warn!("AutoLoading: {:?}", path);
eval_config_contents(path, engine_state, stack);
}
}
}
}
}
fn eval_default_config(
engine_state: &mut EngineState,
stack: &mut Stack,
@ -236,6 +277,8 @@ pub(crate) fn setup_config(
if is_login_shell {
read_loginshell_file(engine_state, stack);
}
// read and auto load vendor autoload files
read_vendor_autoload_files(engine_state, stack);
}));
if result.is_err() {
eprintln!(

View File

@ -1,4 +1,4 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::fs::Stub::{FileWithContent, FileWithContentToBeTrimmed};
use nu_test_support::playground::Playground;
use nu_test_support::{nu, nu_repl_code};
use pretty_assertions::assert_eq;
@ -760,3 +760,162 @@ fn nested_list_export_works() {
let actual = nu!(&inp.join("; "));
assert_eq!(actual.out, "bacon");
}
#[test]
fn reload_submodules() {
Playground::setup("reload_submodule_changed_file", |dirs, sandbox| {
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export module animals.nu"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
// should also verify something unchanged if `use voice`.
let inp = [
"use voice.nu",
r#""export def cat [] {'meow'}" | save -f animals.nu"#,
"use voice",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
// should also works if we use members directly.
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export module animals.nu"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu animals cat",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu animals cat",
"(cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
});
}
#[test]
fn use_submodules() {
Playground::setup("use_submodules", |dirs, sandbox| {
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
// should also verify something unchanged if `use voice`.
let inp = [
"use voice.nu",
r#""export def cat [] {'meow'}" | save -f animals.nu"#,
"use voice",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
// also verify something is changed when using members.
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu cat"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu *"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu [cat]"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
});
}
#[test]
fn use_nested_submodules() {
Playground::setup("use_submodules", |dirs, sandbox| {
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu"#),
FileWithContent("animals.nu", r#"export use nested_animals.nu"#),
FileWithContent("nested_animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f nested_animals.nu"#,
"use voice.nu",
"(voice animals nested_animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu"#),
FileWithContent("animals.nu", r#"export use nested_animals.nu cat"#),
FileWithContent("nested_animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f nested_animals.nu"#,
"use voice.nu",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
sandbox.with_files(&[
FileWithContent("animals.nu", r#"export use nested_animals.nu cat"#),
FileWithContent("nested_animals.nu", "export def cat [] { 'meow' }"),
]);
let inp = [
"module voice { export module animals.nu }",
"use voice",
r#""export def cat [] {'woem'}" | save -f nested_animals.nu"#,
"use voice.nu",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
})
}

View File

@ -261,6 +261,22 @@ fn commands_have_usage() -> TestResult {
)
}
#[test]
fn commands_from_crlf_source_have_short_usage() -> TestResult {
run_test_contains(
"# This is a test\r\n#\r\n# To see if I have cool usage\r\ndef foo [] {}\r\nscope commands | where name == foo | get usage.0",
"This is a test",
)
}
#[test]
fn commands_from_crlf_source_have_extra_usage() -> TestResult {
run_test_contains(
"# This is a test\r\n#\r\n# To see if I have cool usage\r\ndef foo [] {}\r\nscope commands | where name == foo | get extra_usage.0",
"To see if I have cool usage",
)
}
#[test]
fn equals_separates_long_flag() -> TestResult {
run_test(

View File

@ -17,6 +17,7 @@ extend-ignore-re = [
"--find ba\\b",
"0x\\[ba be\\]",
"\\)BaR'",
"fo<66>.txt",
]
[type.rust.extend-words]