Merge branch 'main' into callgrind-benches
This commit is contained in:
commit
108a9a6878
6
.github/workflows/nightly-build.yml
vendored
6
.github/workflows/nightly-build.yml
vendored
|
@ -36,7 +36,7 @@ jobs:
|
||||||
token: ${{ secrets.WORKFLOW_TOKEN }}
|
token: ${{ secrets.WORKFLOW_TOKEN }}
|
||||||
|
|
||||||
- name: Setup Nushell
|
- name: Setup Nushell
|
||||||
uses: hustcer/setup-nu@v3.10
|
uses: hustcer/setup-nu@v3.11
|
||||||
if: github.repository == 'nushell/nightly'
|
if: github.repository == 'nushell/nightly'
|
||||||
with:
|
with:
|
||||||
version: 0.93.0
|
version: 0.93.0
|
||||||
|
@ -128,7 +128,7 @@ jobs:
|
||||||
rustflags: ''
|
rustflags: ''
|
||||||
|
|
||||||
- name: Setup Nushell
|
- name: Setup Nushell
|
||||||
uses: hustcer/setup-nu@v3.10
|
uses: hustcer/setup-nu@v3.11
|
||||||
with:
|
with:
|
||||||
version: 0.93.0
|
version: 0.93.0
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ jobs:
|
||||||
ref: main
|
ref: main
|
||||||
|
|
||||||
- name: Setup Nushell
|
- name: Setup Nushell
|
||||||
uses: hustcer/setup-nu@v3.10
|
uses: hustcer/setup-nu@v3.11
|
||||||
with:
|
with:
|
||||||
version: 0.93.0
|
version: 0.93.0
|
||||||
|
|
||||||
|
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -76,7 +76,7 @@ jobs:
|
||||||
rustflags: ''
|
rustflags: ''
|
||||||
|
|
||||||
- name: Setup Nushell
|
- name: Setup Nushell
|
||||||
uses: hustcer/setup-nu@v3.10
|
uses: hustcer/setup-nu@v3.11
|
||||||
with:
|
with:
|
||||||
version: 0.93.0
|
version: 0.93.0
|
||||||
|
|
||||||
|
|
2
.github/workflows/typos.yml
vendored
2
.github/workflows/typos.yml
vendored
|
@ -10,4 +10,4 @@ jobs:
|
||||||
uses: actions/checkout@v4.1.6
|
uses: actions/checkout@v4.1.6
|
||||||
|
|
||||||
- name: Check spelling
|
- name: Check spelling
|
||||||
uses: crate-ci/typos@v1.21.0
|
uses: crate-ci/typos@v1.22.0
|
||||||
|
|
73
Cargo.lock
generated
73
Cargo.lock
generated
|
@ -2808,7 +2808,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu"
|
name = "nu"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
@ -2862,7 +2862,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-cli"
|
name = "nu-cli"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
@ -2897,7 +2897,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-cmd-base"
|
name = "nu-cmd-base"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"miette",
|
"miette",
|
||||||
|
@ -2909,7 +2909,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-cmd-extra"
|
name = "nu-cmd-extra"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
|
@ -2934,7 +2934,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-cmd-lang"
|
name = "nu-cmd-lang"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.12.1",
|
"itertools 0.12.1",
|
||||||
"nu-engine",
|
"nu-engine",
|
||||||
|
@ -2946,7 +2946,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-cmd-plugin"
|
name = "nu-cmd-plugin"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.12.1",
|
"itertools 0.12.1",
|
||||||
"nu-engine",
|
"nu-engine",
|
||||||
|
@ -2957,7 +2957,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-color-config"
|
name = "nu-color-config"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
"nu-engine",
|
"nu-engine",
|
||||||
|
@ -2969,7 +2969,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-command"
|
name = "nu-command"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alphanumeric-sort",
|
"alphanumeric-sort",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
@ -3078,7 +3078,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-engine"
|
name = "nu-engine"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-glob",
|
"nu-glob",
|
||||||
"nu-path",
|
"nu-path",
|
||||||
|
@ -3088,7 +3088,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-explore"
|
name = "nu-explore"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi-str",
|
"ansi-str",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -3113,14 +3113,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-glob"
|
name = "nu-glob"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"doc-comment",
|
"doc-comment",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-json"
|
name = "nu-json"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"linked-hash-map",
|
"linked-hash-map",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
@ -3130,7 +3130,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-lsp"
|
name = "nu-lsp"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert-json-diff",
|
"assert-json-diff",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
@ -3151,7 +3151,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-parser"
|
name = "nu-parser"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytesize",
|
"bytesize",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -3167,7 +3167,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-path"
|
name = "nu-path"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"omnipath",
|
"omnipath",
|
||||||
|
@ -3176,7 +3176,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin"
|
name = "nu-plugin"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
|
@ -3191,7 +3191,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-core"
|
name = "nu-plugin-core"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3205,7 +3205,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-engine"
|
name = "nu-plugin-engine"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nu-engine",
|
"nu-engine",
|
||||||
|
@ -3220,7 +3220,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-protocol"
|
name = "nu-plugin-protocol"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
|
@ -3232,7 +3232,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-test-support"
|
name = "nu-plugin-test-support"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
"nu-cmd-lang",
|
"nu-cmd-lang",
|
||||||
|
@ -3250,7 +3250,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-pretty-hex"
|
name = "nu-pretty-hex"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heapless",
|
"heapless",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
|
@ -3259,7 +3259,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-protocol"
|
name = "nu-protocol"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli 5.0.0",
|
"brotli 5.0.0",
|
||||||
"byte-unit",
|
"byte-unit",
|
||||||
|
@ -3290,7 +3290,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-std"
|
name = "nu-std"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"miette",
|
"miette",
|
||||||
|
@ -3301,7 +3301,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-system"
|
name = "nu-system"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"itertools 0.12.1",
|
"itertools 0.12.1",
|
||||||
|
@ -3319,7 +3319,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-table"
|
name = "nu-table"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
|
@ -3333,7 +3333,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-term-grid"
|
name = "nu-term-grid"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
|
@ -3341,7 +3341,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-test-support"
|
name = "nu-test-support"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-glob",
|
"nu-glob",
|
||||||
"nu-path",
|
"nu-path",
|
||||||
|
@ -3353,7 +3353,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-utils"
|
name = "nu-utils"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3379,7 +3379,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_example"
|
name = "nu_plugin_example"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-cmd-lang",
|
"nu-cmd-lang",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
|
@ -3389,7 +3389,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_formats"
|
name = "nu_plugin_formats"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"eml-parser",
|
"eml-parser",
|
||||||
"ical",
|
"ical",
|
||||||
|
@ -3402,7 +3402,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_gstat"
|
name = "nu_plugin_gstat"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"git2",
|
"git2",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
|
@ -3411,7 +3411,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_inc"
|
name = "nu_plugin_inc"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
|
@ -3420,7 +3420,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_polars"
|
name = "nu_plugin_polars"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz 0.9.0",
|
"chrono-tz 0.9.0",
|
||||||
|
@ -3451,7 +3451,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_query"
|
name = "nu_plugin_query"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gjson",
|
"gjson",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
|
@ -3463,7 +3463,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_stress_internals"
|
name = "nu_plugin_stress_internals"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -3589,7 +3589,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nuon"
|
name = "nuon"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
|
@ -6118,6 +6118,7 @@ version = "0.8.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
|
|
42
Cargo.toml
42
Cargo.toml
|
@ -11,7 +11,7 @@ license = "MIT"
|
||||||
name = "nu"
|
name = "nu"
|
||||||
repository = "https://github.com/nushell/nushell"
|
repository = "https://github.com/nushell/nushell"
|
||||||
rust-version = "1.77.2"
|
rust-version = "1.77.2"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -174,22 +174,22 @@ windows = "0.54"
|
||||||
winreg = "0.52"
|
winreg = "0.52"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cli = { path = "./crates/nu-cli", version = "0.94.1" }
|
nu-cli = { path = "./crates/nu-cli", version = "0.94.3" }
|
||||||
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.94.1" }
|
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.94.3" }
|
||||||
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.94.1", optional = true }
|
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.1" }
|
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.94.3" }
|
||||||
nu-command = { path = "./crates/nu-command", version = "0.94.1" }
|
nu-command = { path = "./crates/nu-command", version = "0.94.3" }
|
||||||
nu-engine = { path = "./crates/nu-engine", version = "0.94.1" }
|
nu-engine = { path = "./crates/nu-engine", version = "0.94.3" }
|
||||||
nu-explore = { path = "./crates/nu-explore", version = "0.94.1" }
|
nu-explore = { path = "./crates/nu-explore", version = "0.94.3" }
|
||||||
nu-lsp = { path = "./crates/nu-lsp/", version = "0.94.1" }
|
nu-lsp = { path = "./crates/nu-lsp/", version = "0.94.3" }
|
||||||
nu-parser = { path = "./crates/nu-parser", version = "0.94.1" }
|
nu-parser = { path = "./crates/nu-parser", version = "0.94.3" }
|
||||||
nu-path = { path = "./crates/nu-path", version = "0.94.1" }
|
nu-path = { path = "./crates/nu-path", version = "0.94.3" }
|
||||||
nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.94.1" }
|
nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.94.3" }
|
||||||
nu-protocol = { path = "./crates/nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "./crates/nu-protocol", version = "0.94.3" }
|
||||||
nu-std = { path = "./crates/nu-std", version = "0.94.1" }
|
nu-std = { path = "./crates/nu-std", version = "0.94.3" }
|
||||||
nu-system = { path = "./crates/nu-system", version = "0.94.1" }
|
nu-system = { path = "./crates/nu-system", version = "0.94.3" }
|
||||||
nu-utils = { path = "./crates/nu-utils", version = "0.94.1" }
|
nu-utils = { path = "./crates/nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
|
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
|
||||||
|
|
||||||
|
@ -218,9 +218,9 @@ nix = { workspace = true, default-features = false, features = [
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-test-support = { path = "./crates/nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "./crates/nu-test-support", version = "0.94.3" }
|
||||||
nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.94.1" }
|
nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.94.3" }
|
||||||
nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.94.1" }
|
nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.94.3" }
|
||||||
assert_cmd = "2.0"
|
assert_cmd = "2.0"
|
||||||
dirs-next = { workspace = true }
|
dirs-next = { workspace = true }
|
||||||
tango-bench = "0.5"
|
tango-bench = "0.5"
|
||||||
|
@ -311,4 +311,4 @@ harness = false
|
||||||
# cargo bench --bench iai_benchmarks -- --save-summary=pretty-json
|
# cargo bench --bench iai_benchmarks -- --save-summary=pretty-json
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "iai_benchmarks"
|
name = "iai_benchmarks"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
|
@ -5,27 +5,27 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cli"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-cli"
|
name = "nu-cli"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-command = { path = "../nu-command", version = "0.94.1" }
|
nu-command = { path = "../nu-command", version = "0.94.3" }
|
||||||
nu-test-support = { path = "../nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
|
||||||
rstest = { workspace = true, default-features = false }
|
rstest = { workspace = true, default-features = false }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.1" }
|
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.1", optional = true }
|
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.3", optional = true }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
nu-color-config = { path = "../nu-color-config", version = "0.94.1" }
|
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
|
||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
|
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
|
||||||
|
|
||||||
|
@ -46,4 +46,4 @@ which = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
plugin = ["nu-plugin-engine"]
|
plugin = ["nu-plugin-engine"]
|
||||||
system-clipboard = ["reedline/system_clipboard"]
|
system-clipboard = ["reedline/system_clipboard"]
|
||||||
|
|
|
@ -52,18 +52,16 @@ impl Completer for CustomCompletion {
|
||||||
decl_id: self.decl_id,
|
decl_id: self.decl_id,
|
||||||
head: span,
|
head: span,
|
||||||
arguments: vec![
|
arguments: vec![
|
||||||
Argument::Positional(Expression {
|
Argument::Positional(Expression::new_unknown(
|
||||||
span: Span::unknown(),
|
Expr::String(self.line.clone()),
|
||||||
ty: Type::String,
|
Span::unknown(),
|
||||||
expr: Expr::String(self.line.clone()),
|
Type::String,
|
||||||
custom_completion: None,
|
)),
|
||||||
}),
|
Argument::Positional(Expression::new_unknown(
|
||||||
Argument::Positional(Expression {
|
Expr::Int(line_pos as i64),
|
||||||
span: Span::unknown(),
|
Span::unknown(),
|
||||||
ty: Type::Int,
|
Type::Int,
|
||||||
expr: Expr::Int(line_pos as i64),
|
)),
|
||||||
custom_completion: None,
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
parser_info: HashMap::new(),
|
parser_info: HashMap::new(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,17 +5,17 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-cmd-base"
|
name = "nu-cmd-base"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-base"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-base"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
|
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
miette = { workspace = true }
|
miette = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-cmd-extra"
|
name = "nu-cmd-extra"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-extra"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-extra"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -13,13 +13,13 @@ version = "0.94.1"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.1" }
|
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-json = { version = "0.94.1", path = "../nu-json" }
|
nu-json = { version = "0.94.3", path = "../nu-json" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-pretty-hex = { version = "0.94.1", path = "../nu-pretty-hex" }
|
nu-pretty-hex = { version = "0.94.3", path = "../nu-pretty-hex" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
# Potential dependencies for extras
|
# Potential dependencies for extras
|
||||||
heck = { workspace = true }
|
heck = { workspace = true }
|
||||||
|
@ -37,6 +37,6 @@ extra = ["default"]
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-command = { path = "../nu-command", version = "0.94.1" }
|
nu-command = { path = "../nu-command", version = "0.94.3" }
|
||||||
nu-test-support = { path = "../nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
|
||||||
|
|
|
@ -6,16 +6,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-lang"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-cmd-lang"
|
name = "nu-cmd-lang"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
shadow-rs = { version = "0.28", default-features = false }
|
shadow-rs = { version = "0.28", default-features = false }
|
||||||
|
@ -29,4 +29,4 @@ which-support = []
|
||||||
trash-support = []
|
trash-support = []
|
||||||
sqlite = []
|
sqlite = []
|
||||||
static-link-openssl = []
|
static-link-openssl = []
|
||||||
system-clipboard = []
|
system-clipboard = []
|
||||||
|
|
|
@ -298,9 +298,7 @@ fn bind_args_to(
|
||||||
if let Some(rest_positional) = &signature.rest_positional {
|
if let Some(rest_positional) = &signature.rest_positional {
|
||||||
let mut rest_items = vec![];
|
let mut rest_items = vec![];
|
||||||
|
|
||||||
for result in
|
for result in val_iter {
|
||||||
val_iter.skip(signature.required_positional.len() + signature.optional_positional.len())
|
|
||||||
{
|
|
||||||
rest_items.push(result);
|
rest_items.push(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,16 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-cmd-plugin"
|
name = "nu-cmd-plugin"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-plugin"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-plugin"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.1" }
|
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.3" }
|
||||||
|
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -5,18 +5,18 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-color-confi
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-color-config"
|
name = "nu-color-config"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-json = { path = "../nu-json", version = "0.94.1" }
|
nu-json = { path = "../nu-json", version = "0.94.3" }
|
||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
|
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-test-support = { path = "../nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
|
||||||
|
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-command"
|
name = "nu-command"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-command"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-command"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -13,21 +13,21 @@ version = "0.94.1"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.1" }
|
nu-cmd-base = { path = "../nu-cmd-base", version = "0.94.3" }
|
||||||
nu-color-config = { path = "../nu-color-config", version = "0.94.1" }
|
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-glob = { path = "../nu-glob", version = "0.94.1" }
|
nu-glob = { path = "../nu-glob", version = "0.94.3" }
|
||||||
nu-json = { path = "../nu-json", version = "0.94.1" }
|
nu-json = { path = "../nu-json", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.94.1" }
|
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-system = { path = "../nu-system", version = "0.94.1" }
|
nu-system = { path = "../nu-system", version = "0.94.3" }
|
||||||
nu-table = { path = "../nu-table", version = "0.94.1" }
|
nu-table = { path = "../nu-table", version = "0.94.3" }
|
||||||
nu-term-grid = { path = "../nu-term-grid", version = "0.94.1" }
|
nu-term-grid = { path = "../nu-term-grid", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
nuon = { path = "../nuon", version = "0.94.1" }
|
nuon = { path = "../nuon", version = "0.94.3" }
|
||||||
|
|
||||||
alphanumeric-sort = { workspace = true }
|
alphanumeric-sort = { workspace = true }
|
||||||
base64 = { workspace = true }
|
base64 = { workspace = true }
|
||||||
|
@ -86,7 +86,7 @@ sysinfo = { workspace = true }
|
||||||
tabled = { workspace = true, features = ["color"], default-features = false }
|
tabled = { workspace = true, features = ["color"], default-features = false }
|
||||||
terminal_size = { workspace = true }
|
terminal_size = { workspace = true }
|
||||||
titlecase = { workspace = true }
|
titlecase = { workspace = true }
|
||||||
toml = { workspace = true }
|
toml = { workspace = true, features = ["preserve_order"]}
|
||||||
unicode-segmentation = { workspace = true }
|
unicode-segmentation = { workspace = true }
|
||||||
ureq = { workspace = true, default-features = false, features = ["charset", "gzip", "json", "native-tls"] }
|
ureq = { workspace = true, default-features = false, features = ["charset", "gzip", "json", "native-tls"] }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
|
@ -137,8 +137,8 @@ trash-support = ["trash"]
|
||||||
which-support = []
|
which-support = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-test-support = { path = "../nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
|
||||||
|
|
||||||
dirs-next = { workspace = true }
|
dirs-next = { workspace = true }
|
||||||
mockito = { workspace = true, default-features = false }
|
mockito = { workspace = true, default-features = false }
|
||||||
|
@ -146,4 +146,4 @@ quickcheck = { workspace = true }
|
||||||
quickcheck_macros = { workspace = true }
|
quickcheck_macros = { workspace = true }
|
||||||
rstest = { workspace = true, default-features = false }
|
rstest = { workspace = true, default-features = false }
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
|
|
@ -138,6 +138,7 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int_from_string(a_string: &str, span: Span) -> Result<i64, ShellError> {
|
fn int_from_string(a_string: &str, span: Span) -> Result<i64, ShellError> {
|
||||||
// Get the Locale so we know what the thousands separator is
|
// Get the Locale so we know what the thousands separator is
|
||||||
let locale = get_system_locale();
|
let locale = get_system_locale();
|
||||||
|
@ -148,29 +149,35 @@ fn int_from_string(a_string: &str, span: Span) -> Result<i64, ShellError> {
|
||||||
let clean_string = no_comma_string.trim();
|
let clean_string = no_comma_string.trim();
|
||||||
|
|
||||||
// Hadle negative file size
|
// Hadle negative file size
|
||||||
if let Some(stripped_string) = clean_string.strip_prefix('-') {
|
if let Some(stripped_negative_string) = clean_string.strip_prefix('-') {
|
||||||
match stripped_string.parse::<bytesize::ByteSize>() {
|
match stripped_negative_string.parse::<bytesize::ByteSize>() {
|
||||||
Ok(n) => Ok(-(n.as_u64() as i64)),
|
Ok(n) => Ok(-(n.as_u64() as i64)),
|
||||||
Err(_) => Err(ShellError::CantConvert {
|
Err(_) => Err(string_convert_error(span)),
|
||||||
to_type: "int".into(),
|
}
|
||||||
from_type: "string".into(),
|
} else if let Some(stripped_positive_string) = clean_string.strip_prefix('+') {
|
||||||
span,
|
match stripped_positive_string.parse::<bytesize::ByteSize>() {
|
||||||
help: None,
|
Ok(n) if stripped_positive_string.starts_with(|c: char| c.is_ascii_digit()) => {
|
||||||
}),
|
Ok(n.as_u64() as i64)
|
||||||
|
}
|
||||||
|
_ => Err(string_convert_error(span)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match clean_string.parse::<bytesize::ByteSize>() {
|
match clean_string.parse::<bytesize::ByteSize>() {
|
||||||
Ok(n) => Ok(n.0 as i64),
|
Ok(n) => Ok(n.as_u64() as i64),
|
||||||
Err(_) => Err(ShellError::CantConvert {
|
Err(_) => Err(string_convert_error(span)),
|
||||||
to_type: "int".into(),
|
|
||||||
from_type: "string".into(),
|
|
||||||
span,
|
|
||||||
help: None,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn string_convert_error(span: Span) -> ShellError {
|
||||||
|
ShellError::CantConvert {
|
||||||
|
to_type: "filesize".into(),
|
||||||
|
from_type: "string".into(),
|
||||||
|
span,
|
||||||
|
help: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use nu_engine::command_prelude::*;
|
||||||
use super::msgpack::write_value;
|
use super::msgpack::write_value;
|
||||||
|
|
||||||
const BUFFER_SIZE: usize = 65536;
|
const BUFFER_SIZE: usize = 65536;
|
||||||
const DEFAULT_QUALITY: u32 = 1;
|
const DEFAULT_QUALITY: u32 = 3; // 1 can be very bad
|
||||||
const DEFAULT_WINDOW_SIZE: u32 = 20;
|
const DEFAULT_WINDOW_SIZE: u32 = 20;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -22,7 +22,7 @@ impl Command for ToMsgpackz {
|
||||||
.named(
|
.named(
|
||||||
"quality",
|
"quality",
|
||||||
SyntaxShape::Int,
|
SyntaxShape::Int,
|
||||||
"Quality of brotli compression (default 1)",
|
"Quality of brotli compression (default 3)",
|
||||||
Some('q'),
|
Some('q'),
|
||||||
)
|
)
|
||||||
.named(
|
.named(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Command for ToToml {
|
||||||
vec![Example {
|
vec![Example {
|
||||||
description: "Outputs an TOML string representing the contents of this record",
|
description: "Outputs an TOML string representing the contents of this record",
|
||||||
example: r#"{foo: 1 bar: 'qwe'} | to toml"#,
|
example: r#"{foo: 1 bar: 'qwe'} | to toml"#,
|
||||||
result: Some(Value::test_string("bar = \"qwe\"\nfoo = 1\n")),
|
result: Some(Value::test_string("foo = 1\nbar = \"qwe\"\n")),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ fn toml_into_pipeline_data(
|
||||||
value_type: Type,
|
value_type: Type,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
match toml::to_string(&toml_value) {
|
match toml::to_string_pretty(&toml_value) {
|
||||||
Ok(serde_toml_string) => Ok(Value::string(serde_toml_string, span).into_pipeline_data()),
|
Ok(serde_toml_string) => Ok(Value::string(serde_toml_string, span).into_pipeline_data()),
|
||||||
_ => Ok(Value::error(
|
_ => Ok(Value::error(
|
||||||
ShellError::CantConvert {
|
ShellError::CantConvert {
|
||||||
|
|
|
@ -104,10 +104,9 @@ If nothing is found, an empty string will be returned."#
|
||||||
|
|
||||||
fn path_type(path: &Path, span: Span, args: &Arguments) -> Value {
|
fn path_type(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||||
let path = nu_path::expand_path_with(path, &args.pwd, true);
|
let path = nu_path::expand_path_with(path, &args.pwd, true);
|
||||||
match std::fs::symlink_metadata(path) {
|
let meta = path.symlink_metadata();
|
||||||
Ok(metadata) => Value::string(get_file_type(&metadata), span),
|
let ty = meta.as_ref().map(get_file_type).unwrap_or("");
|
||||||
Err(err) => Value::error(err.into(), span),
|
Value::string(ty, span)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_file_type(md: &std::fs::Metadata) -> &str {
|
fn get_file_type(md: &std::fs::Metadata) -> &str {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use nu_protocol::{
|
||||||
ast::{Expr, Expression},
|
ast::{Expr, Expression},
|
||||||
did_you_mean,
|
did_you_mean,
|
||||||
process::ChildProcess,
|
process::ChildProcess,
|
||||||
ByteStream, OutDest,
|
ByteStream, NuGlob, OutDest,
|
||||||
};
|
};
|
||||||
use nu_system::ForegroundChild;
|
use nu_system::ForegroundChild;
|
||||||
use nu_utils::IgnoreCaseExt;
|
use nu_utils::IgnoreCaseExt;
|
||||||
|
@ -13,7 +13,7 @@ use std::{
|
||||||
io::Write,
|
io::Write,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Stdio,
|
process::Stdio,
|
||||||
sync::Arc,
|
sync::{atomic::AtomicBool, Arc},
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,6 +155,9 @@ impl Command for External {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Log the command we're about to run in case it's useful for debugging purposes.
|
||||||
|
log::trace!("run-external spawning: {command:?}");
|
||||||
|
|
||||||
// Spawn the child process. On Unix, also put the child process to
|
// Spawn the child process. On Unix, also put the child process to
|
||||||
// foreground if we're in an interactive session.
|
// foreground if we're in an interactive session.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -232,6 +235,7 @@ pub fn eval_arguments_from_call(
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
) -> Result<Vec<Spanned<String>>, ShellError> {
|
) -> Result<Vec<Spanned<String>>, ShellError> {
|
||||||
|
let ctrlc = &engine_state.ctrlc;
|
||||||
let cwd = engine_state.cwd(Some(stack))?;
|
let cwd = engine_state.cwd(Some(stack))?;
|
||||||
let mut args: Vec<Spanned<String>> = vec![];
|
let mut args: Vec<Spanned<String>> = vec![];
|
||||||
for (expr, spread) in call.rest_iter(1) {
|
for (expr, spread) in call.rest_iter(1) {
|
||||||
|
@ -240,7 +244,7 @@ pub fn eval_arguments_from_call(
|
||||||
// glob-expansion, and inner-quotes-removal, in that order.
|
// glob-expansion, and inner-quotes-removal, in that order.
|
||||||
for arg in eval_argument(engine_state, stack, expr, spread)? {
|
for arg in eval_argument(engine_state, stack, expr, spread)? {
|
||||||
let tilde_expanded = expand_tilde(&arg);
|
let tilde_expanded = expand_tilde(&arg);
|
||||||
for glob_expanded in expand_glob(&tilde_expanded, &cwd, expr.span)? {
|
for glob_expanded in expand_glob(&tilde_expanded, &cwd, expr.span, ctrlc)? {
|
||||||
let inner_quotes_removed = remove_inner_quotes(&glob_expanded);
|
let inner_quotes_removed = remove_inner_quotes(&glob_expanded);
|
||||||
args.push(inner_quotes_removed.into_owned().into_spanned(expr.span));
|
args.push(inner_quotes_removed.into_owned().into_spanned(expr.span));
|
||||||
}
|
}
|
||||||
|
@ -321,37 +325,75 @@ fn expand_tilde(arg: &str) -> String {
|
||||||
///
|
///
|
||||||
/// Note: This matches the default behavior of Bash, but is known to be
|
/// Note: This matches the default behavior of Bash, but is known to be
|
||||||
/// error-prone. We might want to change this behavior in the future.
|
/// error-prone. We might want to change this behavior in the future.
|
||||||
fn expand_glob(arg: &str, cwd: &Path, span: Span) -> Result<Vec<String>, ShellError> {
|
fn expand_glob(
|
||||||
let Ok(paths) = nu_glob::glob_with_parent(arg, nu_glob::MatchOptions::default(), cwd) else {
|
arg: &str,
|
||||||
|
cwd: &Path,
|
||||||
|
span: Span,
|
||||||
|
interrupt: &Option<Arc<AtomicBool>>,
|
||||||
|
) -> Result<Vec<String>, ShellError> {
|
||||||
|
const GLOB_CHARS: &[char] = &['*', '?', '['];
|
||||||
|
|
||||||
|
// Don't expand something that doesn't include the GLOB_CHARS
|
||||||
|
if !arg.contains(GLOB_CHARS) {
|
||||||
|
return Ok(vec![arg.into()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must use `nu_engine::glob_from` here, in order to ensure we get paths from the correct
|
||||||
|
// dir
|
||||||
|
let glob = NuGlob::Expand(arg.to_owned()).into_spanned(span);
|
||||||
|
let Ok((_prefix, paths)) = nu_engine::glob_from(&glob, cwd, span, None) else {
|
||||||
|
// If an error occurred, return the original input
|
||||||
return Ok(vec![arg.into()]);
|
return Ok(vec![arg.into()]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = vec![];
|
// If the first component of the original `arg` string path was '.', that should be preserved
|
||||||
for path in paths {
|
let relative_to_dot = Path::new(arg).starts_with(".");
|
||||||
let path = path.map_err(|err| ShellError::IOErrorSpanned {
|
|
||||||
msg: format!("{}: {:?}", err.path().display(), err.error()),
|
let paths = paths
|
||||||
span,
|
// Skip over glob failures. These are usually just inaccessible paths.
|
||||||
})?;
|
.flat_map(|path_result| match path_result {
|
||||||
// Strip PWD from the resulting paths if possible.
|
Ok(path) => Some(path),
|
||||||
let path_stripped = if let Ok(remainder) = path.strip_prefix(cwd) {
|
Err(err) => {
|
||||||
// If stripping PWD results in an empty path, return `.` instead.
|
// But internally log them just in case we need to debug this.
|
||||||
if remainder.components().next().is_none() {
|
log::warn!("Error in run_external::expand_glob(): {}", err);
|
||||||
Path::new(".")
|
None
|
||||||
} else {
|
|
||||||
remainder
|
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
&path
|
// Make the paths relative to the cwd
|
||||||
};
|
.map(|path| {
|
||||||
let path_string = path_stripped.to_string_lossy().to_string();
|
path.strip_prefix(cwd)
|
||||||
result.push(path_string);
|
.map(|path| path.to_owned())
|
||||||
}
|
.unwrap_or(path)
|
||||||
|
})
|
||||||
|
// Add './' to relative paths if the original pattern had it
|
||||||
|
.map(|path| {
|
||||||
|
if relative_to_dot && path.is_relative() {
|
||||||
|
Path::new(".").join(path)
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Convert the paths returned to UTF-8 strings.
|
||||||
|
//
|
||||||
|
// FIXME: this fails to return the correct results for non-UTF-8 paths, but we don't support
|
||||||
|
// those in Nushell yet.
|
||||||
|
.map(|path| path.to_string_lossy().into_owned())
|
||||||
|
// Abandon if ctrl-c is pressed
|
||||||
|
.map(|path| {
|
||||||
|
if !nu_utils::ctrl_c::was_pressed(interrupt) {
|
||||||
|
Ok(path)
|
||||||
|
} else {
|
||||||
|
Err(ShellError::InterruptedByUser { span: Some(span) })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<String>, ShellError>>()?;
|
||||||
|
|
||||||
if result.is_empty() {
|
if !paths.is_empty() {
|
||||||
result.push(arg.to_string());
|
Ok(paths)
|
||||||
|
} else {
|
||||||
|
// If we failed to match, return the original input
|
||||||
|
Ok(vec![arg.into()])
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms `--option="value"` into `--option=value`. `value` can be quoted
|
/// Transforms `--option="value"` into `--option=value`. `value` can be quoted
|
||||||
|
@ -565,12 +607,20 @@ fn has_cmd_special_character(s: &str) -> bool {
|
||||||
SPECIAL_CHARS.iter().any(|c| s.contains(*c))
|
SPECIAL_CHARS.iter().any(|c| s.contains(*c))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Escape an argument for CMD internal commands. The result can be safely
|
/// Escape an argument for CMD internal commands. The result can be safely passed to `raw_arg()`.
|
||||||
/// passed to `raw_arg()`.
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn escape_cmd_argument(arg: &Spanned<String>) -> Result<Cow<'_, str>, ShellError> {
|
fn escape_cmd_argument(arg: &Spanned<String>) -> Result<Cow<'_, str>, ShellError> {
|
||||||
let Spanned { item: arg, span } = arg;
|
let Spanned { item: arg, span } = arg;
|
||||||
if arg.contains('"') {
|
if arg.contains(['\r', '\n', '%']) {
|
||||||
|
// \r and \n trunacte the rest of the arguments and % can expand environment variables
|
||||||
|
Err(ShellError::ExternalCommand {
|
||||||
|
label:
|
||||||
|
"Arguments to CMD internal commands cannot contain new lines or percent signs '%'"
|
||||||
|
.into(),
|
||||||
|
help: "some characters currently cannot be securely escaped".into(),
|
||||||
|
span: *span,
|
||||||
|
})
|
||||||
|
} else if arg.contains('"') {
|
||||||
// If `arg` is already quoted by double quotes, confirm there's no
|
// If `arg` is already quoted by double quotes, confirm there's no
|
||||||
// embedded double quotes, then leave it as is.
|
// embedded double quotes, then leave it as is.
|
||||||
if arg.chars().filter(|c| *c == '"').count() == 2
|
if arg.chars().filter(|c| *c == '"').count() == 2
|
||||||
|
@ -582,7 +632,7 @@ fn escape_cmd_argument(arg: &Spanned<String>) -> Result<Cow<'_, str>, ShellError
|
||||||
Err(ShellError::ExternalCommand {
|
Err(ShellError::ExternalCommand {
|
||||||
label: "Arguments to CMD internal commands cannot contain embedded double quotes"
|
label: "Arguments to CMD internal commands cannot contain embedded double quotes"
|
||||||
.into(),
|
.into(),
|
||||||
help: "CMD doesn't support escaping double quotes inside double quotes".into(),
|
help: "this case currently cannot be securely handled".into(),
|
||||||
span: *span,
|
span: *span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -590,6 +640,7 @@ fn escape_cmd_argument(arg: &Spanned<String>) -> Result<Cow<'_, str>, ShellError
|
||||||
// If `arg` contains space or special characters, quote the entire argument by double quotes.
|
// If `arg` contains space or special characters, quote the entire argument by double quotes.
|
||||||
Ok(Cow::Owned(format!("\"{arg}\"")))
|
Ok(Cow::Owned(format!("\"{arg}\"")))
|
||||||
} else {
|
} else {
|
||||||
|
// FIXME?: what if `arg.is_empty()`?
|
||||||
Ok(Cow::Borrowed(arg))
|
Ok(Cow::Borrowed(arg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -598,6 +649,7 @@ fn escape_cmd_argument(arg: &Spanned<String>) -> Result<Cow<'_, str>, ShellError
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use nu_protocol::ast::ListItem;
|
use nu_protocol::ast::ListItem;
|
||||||
|
use nu_test_support::{fs::Stub, playground::Playground};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remove_quotes() {
|
fn test_remove_quotes() {
|
||||||
|
@ -613,12 +665,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eval_argument() {
|
fn test_eval_argument() {
|
||||||
fn expression(expr: Expr) -> Expression {
|
fn expression(expr: Expr) -> Expression {
|
||||||
Expression {
|
Expression::new_unknown(expr, Span::unknown(), Type::Any)
|
||||||
expr,
|
|
||||||
span: Span::unknown(),
|
|
||||||
ty: Type::Any,
|
|
||||||
custom_completion: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(expr: Expr, spread: bool) -> Result<Vec<String>, ShellError> {
|
fn eval(expr: Expr, spread: bool) -> Result<Vec<String>, ShellError> {
|
||||||
|
@ -660,26 +707,38 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_expand_glob() {
|
fn test_expand_glob() {
|
||||||
let tempdir = tempfile::tempdir().unwrap();
|
Playground::setup("test_expand_glob", |dirs, play| {
|
||||||
let cwd = tempdir.path();
|
play.with_files(&[Stub::EmptyFile("a.txt"), Stub::EmptyFile("b.txt")]);
|
||||||
std::fs::File::create(cwd.join("a.txt")).unwrap();
|
|
||||||
std::fs::File::create(cwd.join("b.txt")).unwrap();
|
|
||||||
|
|
||||||
let actual = expand_glob("*.txt", cwd, Span::unknown()).unwrap();
|
let cwd = dirs.test();
|
||||||
let expected = &["a.txt", "b.txt"];
|
|
||||||
assert_eq!(actual, expected);
|
|
||||||
|
|
||||||
let actual = expand_glob("'*.txt'", cwd, Span::unknown()).unwrap();
|
let actual = expand_glob("*.txt", cwd, Span::unknown(), &None).unwrap();
|
||||||
let expected = &["'*.txt'"];
|
let expected = &["a.txt", "b.txt"];
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
let actual = expand_glob(cwd.to_str().unwrap(), cwd, Span::unknown()).unwrap();
|
let actual = expand_glob("./*.txt", cwd, Span::unknown(), &None).unwrap();
|
||||||
let expected = &["."];
|
let expected = vec![
|
||||||
assert_eq!(actual, expected);
|
Path::new(".").join("a.txt").to_string_lossy().into_owned(),
|
||||||
|
Path::new(".").join("b.txt").to_string_lossy().into_owned(),
|
||||||
|
];
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
let actual = expand_glob("[*.txt", cwd, Span::unknown()).unwrap();
|
let actual = expand_glob("'*.txt'", cwd, Span::unknown(), &None).unwrap();
|
||||||
let expected = &["[*.txt"];
|
let expected = &["'*.txt'"];
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
let actual = expand_glob(".", cwd, Span::unknown(), &None).unwrap();
|
||||||
|
let expected = &["."];
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
let actual = expand_glob("./a.txt", cwd, Span::unknown(), &None).unwrap();
|
||||||
|
let expected = &["./a.txt"];
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
let actual = expand_glob("[*.txt", cwd, Span::unknown(), &None).unwrap();
|
||||||
|
let expected = &["[*.txt"];
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -63,8 +63,57 @@ fn into_filesize_negative_filesize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn into_negative_filesize() {
|
fn into_filesize_negative_str_filesize() {
|
||||||
|
let actual = nu!("'-3kib' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.out.contains("-3.0 KiB"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_wrong_negative_str_filesize() {
|
||||||
|
let actual = nu!("'--3kib' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.err.contains("can't convert string to filesize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_negative_str() {
|
||||||
let actual = nu!("'-1' | into filesize");
|
let actual = nu!("'-1' | into filesize");
|
||||||
|
|
||||||
assert!(actual.out.contains("-1 B"));
|
assert!(actual.out.contains("-1 B"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_wrong_negative_str() {
|
||||||
|
let actual = nu!("'--1' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.err.contains("can't convert string to filesize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_positive_str_filesize() {
|
||||||
|
let actual = nu!("'+1Kib' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.out.contains("1.0 KiB"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_wrong_positive_str_filesize() {
|
||||||
|
let actual = nu!("'++1Kib' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.err.contains("can't convert string to filesize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_positive_str() {
|
||||||
|
let actual = nu!("'+1' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.out.contains("1 B"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_filesize_wrong_positive_str() {
|
||||||
|
let actual = nu!("'++1' | into filesize");
|
||||||
|
|
||||||
|
assert!(actual.err.contains("can't convert string to filesize"));
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,16 +5,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-engine"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-engine"
|
name = "nu-engine"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", features = ["plugin"], version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", features = ["plugin"], version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-glob = { path = "../nu-glob", version = "0.94.1" }
|
nu-glob = { path = "../nu-glob", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
plugin = []
|
plugin = []
|
||||||
|
|
|
@ -2,9 +2,9 @@ use crate::eval_call;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Argument, Call, Expr, Expression, RecordItem},
|
ast::{Argument, Call, Expr, Expression, RecordItem},
|
||||||
debugger::WithoutDebug,
|
debugger::WithoutDebug,
|
||||||
engine::{Command, EngineState, Stack},
|
engine::{Command, EngineState, Stack, UNKNOWN_SPAN_ID},
|
||||||
record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Type,
|
record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SpanId,
|
||||||
Value,
|
SyntaxShape, Type, Value,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, fmt::Write};
|
use std::{collections::HashMap, fmt::Write};
|
||||||
|
|
||||||
|
@ -339,8 +339,9 @@ fn get_ansi_color_for_component_or_default(
|
||||||
if let Some(color) = &engine_state.get_config().color_config.get(theme_component) {
|
if let Some(color) = &engine_state.get_config().color_config.get(theme_component) {
|
||||||
let caller_stack = &mut Stack::new().capture();
|
let caller_stack = &mut Stack::new().capture();
|
||||||
let span = Span::unknown();
|
let span = Span::unknown();
|
||||||
|
let span_id = UNKNOWN_SPAN_ID;
|
||||||
|
|
||||||
let argument_opt = get_argument_for_color_value(engine_state, color, span);
|
let argument_opt = get_argument_for_color_value(engine_state, color, span, span_id);
|
||||||
|
|
||||||
// Call ansi command using argument
|
// Call ansi command using argument
|
||||||
if let Some(argument) = argument_opt {
|
if let Some(argument) = argument_opt {
|
||||||
|
@ -371,6 +372,7 @@ fn get_argument_for_color_value(
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
color: &&Value,
|
color: &&Value,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
span_id: SpanId,
|
||||||
) -> Option<Argument> {
|
) -> Option<Argument> {
|
||||||
match color {
|
match color {
|
||||||
Value::Record { val, .. } => {
|
Value::Record { val, .. } => {
|
||||||
|
@ -378,43 +380,43 @@ fn get_argument_for_color_value(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
RecordItem::Pair(
|
RecordItem::Pair(
|
||||||
Expression {
|
Expression::new_existing(
|
||||||
expr: Expr::String(k.clone()),
|
Expr::String(k.clone()),
|
||||||
span,
|
span,
|
||||||
ty: Type::String,
|
span_id,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
},
|
),
|
||||||
Expression {
|
Expression::new_existing(
|
||||||
expr: Expr::String(
|
Expr::String(
|
||||||
v.clone().to_expanded_string("", engine_state.get_config()),
|
v.clone().to_expanded_string("", engine_state.get_config()),
|
||||||
),
|
),
|
||||||
span,
|
span,
|
||||||
ty: Type::String,
|
span_id,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
},
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Some(Argument::Positional(Expression {
|
Some(Argument::Positional(Expression::new_existing(
|
||||||
span: Span::unknown(),
|
Expr::Record(record_exp),
|
||||||
ty: Type::Record(
|
Span::unknown(),
|
||||||
|
UNKNOWN_SPAN_ID,
|
||||||
|
Type::Record(
|
||||||
[
|
[
|
||||||
("fg".to_string(), Type::String),
|
("fg".to_string(), Type::String),
|
||||||
("attr".to_string(), Type::String),
|
("attr".to_string(), Type::String),
|
||||||
]
|
]
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
expr: Expr::Record(record_exp),
|
)))
|
||||||
custom_completion: None,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
Value::String { val, .. } => Some(Argument::Positional(Expression {
|
Value::String { val, .. } => Some(Argument::Positional(Expression::new_existing(
|
||||||
span: Span::unknown(),
|
Expr::String(val.clone()),
|
||||||
ty: Type::String,
|
Span::unknown(),
|
||||||
expr: Expr::String(val.clone()),
|
UNKNOWN_SPAN_ID,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
})),
|
))),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,21 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-explore"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-explore"
|
name = "nu-explore"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-color-config = { path = "../nu-color-config", version = "0.94.1" }
|
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-table = { path = "../nu-table", version = "0.94.1" }
|
nu-table = { path = "../nu-table", version = "0.94.3" }
|
||||||
nu-json = { path = "../nu-json", version = "0.94.1" }
|
nu-json = { path = "../nu-json", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.94.1" }
|
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.94.3" }
|
||||||
|
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
@ -32,4 +32,4 @@ ansi-str = { workspace = true }
|
||||||
unicode-width = { workspace = true }
|
unicode-width = { workspace = true }
|
||||||
lscolors = { workspace = true, default-features = false, features = [
|
lscolors = { workspace = true, default-features = false, features = [
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
] }
|
] }
|
||||||
|
|
|
@ -4,7 +4,6 @@ use nu_ansi_term::{Color, Style};
|
||||||
use nu_engine::env_to_string;
|
use nu_engine::env_to_string;
|
||||||
use nu_protocol::engine::{EngineState, Stack};
|
use nu_protocol::engine::{EngineState, Stack};
|
||||||
use nu_utils::get_ls_colors;
|
use nu_utils::get_ls_colors;
|
||||||
use std::fs::symlink_metadata;
|
|
||||||
|
|
||||||
pub fn create_lscolors(engine_state: &EngineState, stack: &Stack) -> LsColors {
|
pub fn create_lscolors(engine_state: &EngineState, stack: &Stack) -> LsColors {
|
||||||
let colors = stack
|
let colors = stack
|
||||||
|
@ -14,6 +13,7 @@ pub fn create_lscolors(engine_state: &EngineState, stack: &Stack) -> LsColors {
|
||||||
get_ls_colors(colors)
|
get_ls_colors(colors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Colorizes any columns named "name" in the table using LS_COLORS
|
||||||
pub fn lscolorize(header: &[String], data: &mut [Vec<NuText>], lscolors: &LsColors) {
|
pub fn lscolorize(header: &[String], data: &mut [Vec<NuText>], lscolors: &LsColors) {
|
||||||
for (col, col_name) in header.iter().enumerate() {
|
for (col, col_name) in header.iter().enumerate() {
|
||||||
if col_name != "name" {
|
if col_name != "name" {
|
||||||
|
@ -33,14 +33,7 @@ pub fn lscolorize(header: &[String], data: &mut [Vec<NuText>], lscolors: &LsColo
|
||||||
|
|
||||||
fn get_path_style(path: &str, ls_colors: &LsColors) -> Option<Style> {
|
fn get_path_style(path: &str, ls_colors: &LsColors) -> Option<Style> {
|
||||||
let stripped_path = nu_utils::strip_ansi_unlikely(path);
|
let stripped_path = nu_utils::strip_ansi_unlikely(path);
|
||||||
|
let style = ls_colors.style_for_str(stripped_path.as_ref());
|
||||||
let style = match symlink_metadata(stripped_path.as_ref()) {
|
|
||||||
Ok(metadata) => {
|
|
||||||
ls_colors.style_for_path_with_metadata(stripped_path.as_ref(), Some(&metadata))
|
|
||||||
}
|
|
||||||
Err(_) => ls_colors.style_for_path(stripped_path.as_ref()),
|
|
||||||
};
|
|
||||||
|
|
||||||
style.map(lsstyle_to_nu_style)
|
style.map(lsstyle_to_nu_style)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,20 @@ use crate::{
|
||||||
ConfigMap, Frame, Transition, ViewInfo,
|
ConfigMap, Frame, Transition, ViewInfo,
|
||||||
},
|
},
|
||||||
util::create_map,
|
util::create_map,
|
||||||
|
views::cursor::Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::binary_widget::{BinarySettings, BinaryStyle, BinaryWidget};
|
use self::binary_widget::{BinarySettings, BinaryStyle, BinaryWidget};
|
||||||
|
|
||||||
use super::{cursor::XYCursor, Layout, View, ViewConfig};
|
use super::{cursor::WindowCursor2D, Layout, View, ViewConfig};
|
||||||
|
|
||||||
|
/// An interactive view that displays binary data in a hex dump format.
|
||||||
|
/// Not finished; many aspects are still WIP.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BinaryView {
|
pub struct BinaryView {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
cursor: XYCursor,
|
// HACK: we are only using the vertical dimension of the cursor, should we use a plain old WindowCursor?
|
||||||
|
cursor: WindowCursor2D,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +44,7 @@ impl BinaryView {
|
||||||
pub fn new(data: Vec<u8>) -> Self {
|
pub fn new(data: Vec<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data,
|
data,
|
||||||
cursor: XYCursor::default(),
|
cursor: WindowCursor2D::default(),
|
||||||
settings: Settings::default(),
|
settings: Settings::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,12 +99,13 @@ impl View for BinaryView {
|
||||||
|
|
||||||
let count_rows =
|
let count_rows =
|
||||||
BinaryWidget::new(&self.data, self.settings.opts, Default::default()).count_lines();
|
BinaryWidget::new(&self.data, self.settings.opts, Default::default()).count_lines();
|
||||||
self.cursor = XYCursor::new(count_rows, 0);
|
// TODO: refactor View so setup() is fallible and we don't have to panic here
|
||||||
|
self.cursor = WindowCursor2D::new(count_rows, 1).expect("Failed to create XYCursor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_binary_widget(v: &BinaryView) -> BinaryWidget<'_> {
|
fn create_binary_widget(v: &BinaryView) -> BinaryWidget<'_> {
|
||||||
let start_line = v.cursor.row_starts_at();
|
let start_line = v.cursor.window_origin().row;
|
||||||
let count_elements =
|
let count_elements =
|
||||||
BinaryWidget::new(&[], v.settings.opts, Default::default()).count_elements();
|
BinaryWidget::new(&[], v.settings.opts, Default::default()).count_elements();
|
||||||
let index = start_line * count_elements;
|
let index = start_line * count_elements;
|
||||||
|
@ -203,7 +208,7 @@ fn config_get_usize(config: &ConfigMap, key: &str, default: usize) -> usize {
|
||||||
.unwrap_or(default)
|
.unwrap_or(default)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_report(cursor: XYCursor) -> Report {
|
fn create_report(cursor: WindowCursor2D) -> Report {
|
||||||
let covered_percent = report_row_position(cursor);
|
let covered_percent = report_row_position(cursor);
|
||||||
let cursor = report_cursor_position(cursor);
|
let cursor = report_cursor_position(cursor);
|
||||||
let mode = report_mode_name();
|
let mode = report_mode_name();
|
||||||
|
@ -216,8 +221,8 @@ fn report_mode_name() -> String {
|
||||||
String::from("VIEW")
|
String::from("VIEW")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_row_position(cursor: XYCursor) -> String {
|
fn report_row_position(cursor: WindowCursor2D) -> String {
|
||||||
if cursor.row_starts_at() == 0 {
|
if cursor.window_origin().row == 0 {
|
||||||
return String::from("Top");
|
return String::from("Top");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,10 +238,9 @@ fn report_row_position(cursor: XYCursor) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_cursor_position(cursor: XYCursor) -> String {
|
fn report_cursor_position(cursor: WindowCursor2D) -> String {
|
||||||
let rows_seen = cursor.row_starts_at();
|
let Position { row, column } = cursor.window_origin();
|
||||||
let columns_seen = cursor.column_starts_at();
|
format!("{row},{column}")
|
||||||
format!("{rows_seen},{columns_seen}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_percentage(value: usize, max: usize) -> usize {
|
fn get_percentage(value: usize, max: usize) -> usize {
|
||||||
|
|
|
@ -1,71 +1,125 @@
|
||||||
mod windowcursor;
|
mod window_cursor;
|
||||||
mod xycursor;
|
mod window_cursor_2d;
|
||||||
|
|
||||||
pub use windowcursor::WindowCursor;
|
use anyhow::{bail, Result};
|
||||||
pub use xycursor::XYCursor;
|
pub use window_cursor::WindowCursor;
|
||||||
|
pub use window_cursor_2d::{Position, WindowCursor2D};
|
||||||
|
|
||||||
|
/// A 1-dimensional cursor to track a position from 0 to N
|
||||||
|
///
|
||||||
|
/// Say we have a cursor with size=9, at position 3:
|
||||||
|
/// 0 1 2 3 4 5 6 7 8 9
|
||||||
|
/// | | | C | | | | | |
|
||||||
|
///
|
||||||
|
/// After moving forward by 2 steps:
|
||||||
|
/// 0 1 2 3 4 5 6 7 8 9
|
||||||
|
/// | | | | | C | | | |
|
||||||
|
///
|
||||||
|
/// After moving backward by 6 steps (clamped to 0):
|
||||||
|
/// 0 1 2 3 4 5 6 7 8 9
|
||||||
|
/// C | | | | | | | | |
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Cursor {
|
struct Cursor {
|
||||||
index: usize,
|
/// The current position of the cursor
|
||||||
limit: usize,
|
position: usize,
|
||||||
|
/// The number of distinct positions the cursor can be at
|
||||||
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cursor {
|
impl Cursor {
|
||||||
pub fn new(limit: usize) -> Self {
|
/// Constructor to create a new Cursor
|
||||||
Self { index: 0, limit }
|
pub fn new(size: usize) -> Result<Self> {
|
||||||
}
|
if size == 0 {
|
||||||
|
bail!("Size cannot be zero");
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn get_index(&self) -> usize {
|
|
||||||
self.index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cap(&self) -> usize {
|
|
||||||
self.limit - self.index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set(&mut self, i: usize) -> bool {
|
|
||||||
if i >= self.limit {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
Ok(Cursor { position: 0, size })
|
||||||
self.index = i;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn limit(&mut self, i: usize) -> bool {
|
|
||||||
if self.index > self.limit {
|
|
||||||
self.index = self.limit.saturating_sub(1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.limit = i;
|
|
||||||
if self.index >= self.limit {
|
|
||||||
self.index = self.limit.saturating_sub(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The max position the cursor can be at
|
||||||
pub fn end(&self) -> usize {
|
pub fn end(&self) -> usize {
|
||||||
self.limit
|
self.size - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self, i: usize) -> bool {
|
/// Set the position to a specific value within the bounds [0, end]
|
||||||
if self.index + i == self.limit {
|
pub fn set_position(&mut self, pos: usize) {
|
||||||
return false;
|
if pos <= self.end() {
|
||||||
|
self.position = pos;
|
||||||
|
} else {
|
||||||
|
// Clamp the position to end if out of bounds
|
||||||
|
self.position = self.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.index += i;
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev(&mut self, i: usize) -> bool {
|
/// Set the size of the cursor. The position is clamped if it exceeds the new size
|
||||||
if self.index < i {
|
pub fn set_size(&mut self, size: usize) -> Result<()> {
|
||||||
return false;
|
if size == 0 {
|
||||||
|
bail!("Size cannot be zero");
|
||||||
}
|
}
|
||||||
|
self.size = size;
|
||||||
|
if self.position > self.end() {
|
||||||
|
self.position = self.end();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
self.index -= i;
|
/// Move the cursor forward by a specified number of steps
|
||||||
true
|
pub fn move_forward(&mut self, steps: usize) {
|
||||||
|
if self.position + steps <= self.end() {
|
||||||
|
self.position += steps;
|
||||||
|
} else {
|
||||||
|
self.position = self.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move the cursor backward by a specified number of steps
|
||||||
|
pub fn move_backward(&mut self, steps: usize) {
|
||||||
|
if self.position >= steps {
|
||||||
|
self.position -= steps;
|
||||||
|
} else {
|
||||||
|
self.position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cursor_set_position() {
|
||||||
|
// from 0 to 9
|
||||||
|
let mut cursor = Cursor::new(10).unwrap();
|
||||||
|
cursor.set_position(5);
|
||||||
|
assert_eq!(cursor.position, 5);
|
||||||
|
|
||||||
|
cursor.set_position(15);
|
||||||
|
assert_eq!(cursor.position, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cursor_move_forward() {
|
||||||
|
// from 0 to 9
|
||||||
|
let mut cursor = Cursor::new(10).unwrap();
|
||||||
|
assert_eq!(cursor.position, 0);
|
||||||
|
cursor.move_forward(3);
|
||||||
|
assert_eq!(cursor.position, 3);
|
||||||
|
|
||||||
|
cursor.move_forward(10);
|
||||||
|
assert_eq!(cursor.position, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cursor_move_backward() {
|
||||||
|
// from 0 to 9
|
||||||
|
let mut cursor = Cursor::new(10).unwrap();
|
||||||
|
cursor.move_backward(3);
|
||||||
|
assert_eq!(cursor.position, 0);
|
||||||
|
|
||||||
|
cursor.move_forward(5);
|
||||||
|
assert_eq!(cursor.position, 5);
|
||||||
|
cursor.move_backward(3);
|
||||||
|
assert_eq!(cursor.position, 2);
|
||||||
|
cursor.move_backward(3);
|
||||||
|
assert_eq!(cursor.position, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
146
crates/nu-explore/src/views/cursor/window_cursor.rs
Normal file
146
crates/nu-explore/src/views/cursor/window_cursor.rs
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
|
use super::Cursor;
|
||||||
|
use anyhow::{bail, Ok, Result};
|
||||||
|
|
||||||
|
/// WindowCursor provides a mechanism to navigate through a 1-dimensional range
|
||||||
|
/// using a smaller movable window within the view.
|
||||||
|
///
|
||||||
|
/// View: The larger context or total allowable range for navigation.
|
||||||
|
/// Window: The smaller, focused subset of the view.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```plaintext
|
||||||
|
/// 1. Initial view of size 20 with a window of size 5. The absolute cursor position starts at 0.
|
||||||
|
/// View :
|
||||||
|
/// |--------------------|
|
||||||
|
/// Window :
|
||||||
|
/// |X====|
|
||||||
|
///
|
||||||
|
/// 2. After advancing the window by 3, the absolute cursor position becomes 3.
|
||||||
|
/// View :
|
||||||
|
/// |--------------------|
|
||||||
|
/// Window :
|
||||||
|
/// |X====|
|
||||||
|
///
|
||||||
|
/// 3. After advancing the cursor inside the window by 2, the absolute cursor position becomes 5.
|
||||||
|
/// View :
|
||||||
|
/// |--------------------|
|
||||||
|
/// Window :
|
||||||
|
/// |==X==|
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct WindowCursor {
|
||||||
|
view: Cursor,
|
||||||
|
window: Cursor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowCursor {
|
||||||
|
pub fn new(view_size: usize, window_size: usize) -> Result<Self> {
|
||||||
|
if window_size > view_size {
|
||||||
|
bail!("Window size cannot be greater than view size");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
view: Cursor::new(view_size)?,
|
||||||
|
window: Cursor::new(window_size)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn absolute_position(&self) -> usize {
|
||||||
|
self.window_starts_at() + self.window.position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_relative_position(&self) -> usize {
|
||||||
|
self.window.position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_starts_at(&self) -> usize {
|
||||||
|
self.view.position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_size(&self) -> usize {
|
||||||
|
self.window.size
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end(&self) -> usize {
|
||||||
|
self.view.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_window_start_position(&mut self, i: usize) {
|
||||||
|
self.view.set_position(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_window_to_end(&mut self) {
|
||||||
|
self.view.set_position(self.end() - self.window_size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_window_size(&mut self, new_size: usize) -> Result<()> {
|
||||||
|
if new_size > self.view.size {
|
||||||
|
// TODO: should we return an error here or clamp? the Ok is copying existing behavior
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window.set_size(new_size)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_n(&mut self, n: usize) {
|
||||||
|
for _ in 0..n {
|
||||||
|
self.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(&mut self) {
|
||||||
|
if self.absolute_position() >= self.end() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.window_relative_position() == self.window.end() {
|
||||||
|
self.view.move_forward(1);
|
||||||
|
} else {
|
||||||
|
self.window.move_forward(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_window(&mut self) {
|
||||||
|
self.move_cursor_to_end_of_window();
|
||||||
|
|
||||||
|
// move window forward by window size, or less if that would send it off the end of the view
|
||||||
|
let window_end = self.window_starts_at() + self.window_size() - 1;
|
||||||
|
let distance_from_window_end_to_view_end = self.end() - window_end;
|
||||||
|
self.view.move_forward(min(
|
||||||
|
distance_from_window_end_to_view_end,
|
||||||
|
self.window_size(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_n(&mut self, n: usize) {
|
||||||
|
for _ in 0..n {
|
||||||
|
self.prev();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev(&mut self) {
|
||||||
|
if self.window_relative_position() == 0 {
|
||||||
|
self.view.move_backward(1);
|
||||||
|
} else {
|
||||||
|
self.window.move_backward(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_window(&mut self) {
|
||||||
|
self.move_cursor_to_start_of_window();
|
||||||
|
|
||||||
|
// move the whole window back
|
||||||
|
self.view.move_backward(self.window_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_cursor_to_start_of_window(&mut self) {
|
||||||
|
self.window.move_backward(self.window_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_cursor_to_end_of_window(&mut self) {
|
||||||
|
self.window.move_forward(self.window_size());
|
||||||
|
}
|
||||||
|
}
|
172
crates/nu-explore/src/views/cursor/window_cursor_2d.rs
Normal file
172
crates/nu-explore/src/views/cursor/window_cursor_2d.rs
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
use super::WindowCursor;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
/// `WindowCursor2D` manages a 2-dimensional "window" onto a grid of cells, with a cursor that can point to a specific cell.
|
||||||
|
/// For example, consider a 3x3 grid of cells:
|
||||||
|
///
|
||||||
|
/// +---+---+---+
|
||||||
|
/// | a | b | c |
|
||||||
|
/// |---|---|---|
|
||||||
|
/// | d | e | f |
|
||||||
|
/// |---|---|---|
|
||||||
|
/// | g | h | i |
|
||||||
|
/// +---+---+---+
|
||||||
|
///
|
||||||
|
/// A `WindowCursor2D` can be used to track the currently visible section of this grid.
|
||||||
|
/// For example, a 2x2 window onto this grid could initially show the top left 2x2 section:
|
||||||
|
///
|
||||||
|
/// +---+---+
|
||||||
|
/// | a | b |
|
||||||
|
/// |---|---|
|
||||||
|
/// | d | e |
|
||||||
|
/// +---+---+
|
||||||
|
///
|
||||||
|
/// Moving the window down 1 row:
|
||||||
|
///
|
||||||
|
/// +---+---+
|
||||||
|
/// | d | e |
|
||||||
|
/// |---|---|
|
||||||
|
/// | g | h |
|
||||||
|
/// +---+---+
|
||||||
|
///
|
||||||
|
/// Inside the window, the cursor can point to a specific cell.
|
||||||
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
|
pub struct WindowCursor2D {
|
||||||
|
x: WindowCursor,
|
||||||
|
y: WindowCursor,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Position {
|
||||||
|
pub row: usize,
|
||||||
|
pub column: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowCursor2D {
|
||||||
|
pub fn new(count_rows: usize, count_columns: usize) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
x: WindowCursor::new(count_columns, count_columns)?,
|
||||||
|
y: WindowCursor::new(count_rows, count_rows)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_window_size(&mut self, count_rows: usize, count_columns: usize) -> Result<()> {
|
||||||
|
self.x.set_window_size(count_columns)?;
|
||||||
|
self.y.set_window_size(count_rows)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_window_start_position(&mut self, row: usize, col: usize) {
|
||||||
|
self.x.set_window_start_position(col);
|
||||||
|
self.y.set_window_start_position(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The absolute position of the cursor in the grid (0-indexed, row only)
|
||||||
|
pub fn row(&self) -> usize {
|
||||||
|
self.y.absolute_position()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The absolute position of the cursor in the grid (0-indexed, column only)
|
||||||
|
pub fn column(&self) -> usize {
|
||||||
|
self.x.absolute_position()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The absolute position of the cursor in the grid (0-indexed)
|
||||||
|
pub fn position(&self) -> Position {
|
||||||
|
Position {
|
||||||
|
row: self.row(),
|
||||||
|
column: self.column(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn row_limit(&self) -> usize {
|
||||||
|
self.y.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_origin(&self) -> Position {
|
||||||
|
Position {
|
||||||
|
row: self.y.window_starts_at(),
|
||||||
|
column: self.x.window_starts_at(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_relative_position(&self) -> Position {
|
||||||
|
Position {
|
||||||
|
row: self.y.window_relative_position(),
|
||||||
|
column: self.x.window_relative_position(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_width_in_columns(&self) -> usize {
|
||||||
|
self.x.window_size()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_row(&mut self) {
|
||||||
|
self.y.next_n(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_row_page(&mut self) {
|
||||||
|
self.y.next_window()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn row_move_to_end(&mut self) {
|
||||||
|
self.y.move_window_to_end();
|
||||||
|
self.y.move_cursor_to_end_of_window();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn row_move_to_start(&mut self) {
|
||||||
|
self.y.move_cursor_to_start_of_window();
|
||||||
|
self.y.set_window_start_position(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_row(&mut self) {
|
||||||
|
self.y.prev()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_row_page(&mut self) {
|
||||||
|
self.y.prev_window()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_column(&mut self) {
|
||||||
|
self.x.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_column_by(&mut self, i: usize) {
|
||||||
|
self.x.next_n(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_column(&mut self) {
|
||||||
|
self.x.prev()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_column_by(&mut self, i: usize) {
|
||||||
|
self.x.prev_n(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_column_i(&mut self) {
|
||||||
|
self.x
|
||||||
|
.set_window_start_position(self.x.window_starts_at() + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_column_i(&mut self) {
|
||||||
|
if self.x.window_starts_at() == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.x
|
||||||
|
.set_window_start_position(self.x.window_starts_at() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_row_i(&mut self) {
|
||||||
|
self.y
|
||||||
|
.set_window_start_position(self.y.window_starts_at() + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev_row_i(&mut self) {
|
||||||
|
if self.y.window_starts_at() == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.y
|
||||||
|
.set_window_start_position(self.y.window_starts_at() - 1)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,106 +0,0 @@
|
||||||
use super::Cursor;
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub struct WindowCursor {
|
|
||||||
view: Cursor,
|
|
||||||
window: Cursor,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WindowCursor {
|
|
||||||
pub fn new(limit: usize, window: usize) -> Option<Self> {
|
|
||||||
if window > limit {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(Self {
|
|
||||||
view: Cursor::new(limit),
|
|
||||||
window: Cursor::new(window),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn index(&self) -> usize {
|
|
||||||
self.view.index + self.window.index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn offset(&self) -> usize {
|
|
||||||
self.window.index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn starts_at(&self) -> usize {
|
|
||||||
self.view.index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cap(&self) -> usize {
|
|
||||||
self.view.cap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn window(&self) -> usize {
|
|
||||||
self.window.end()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn end(&self) -> usize {
|
|
||||||
self.view.end()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_window_at(&mut self, i: usize) -> bool {
|
|
||||||
self.view.set(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_window(&mut self, i: usize) -> bool {
|
|
||||||
if i > self.view.end() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.window.limit(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(&mut self, i: usize) -> bool {
|
|
||||||
if i > self.cap() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut rest = 0;
|
|
||||||
for y in 0..i {
|
|
||||||
if !self.window.next(1) {
|
|
||||||
rest = i - y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..rest {
|
|
||||||
if self.index() + 1 == self.end() {
|
|
||||||
return rest != i;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.view.next(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_window(&mut self) -> bool {
|
|
||||||
let end_cursor = self.window() - self.offset();
|
|
||||||
self.next(end_cursor);
|
|
||||||
|
|
||||||
let mut index_move = self.window();
|
|
||||||
if index_move + self.starts_at() >= self.end() {
|
|
||||||
index_move = self.end() - self.starts_at();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.next(index_move)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev(&mut self, i: usize) -> bool {
|
|
||||||
for _ in 0..i {
|
|
||||||
if !self.window.prev(1) {
|
|
||||||
self.view.prev(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_window(&mut self) -> bool {
|
|
||||||
self.prev(self.window() + self.offset())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
use super::WindowCursor;
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
|
||||||
pub struct XYCursor {
|
|
||||||
x: WindowCursor,
|
|
||||||
y: WindowCursor,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl XYCursor {
|
|
||||||
pub fn new(count_rows: usize, count_columns: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
x: WindowCursor::new(count_columns, count_columns).expect("..."),
|
|
||||||
y: WindowCursor::new(count_rows, count_rows).expect("..."),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_window(&mut self, count_rows: usize, count_columns: usize) {
|
|
||||||
self.x.set_window(count_columns);
|
|
||||||
self.y.set_window(count_rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_position(&mut self, row: usize, col: usize) {
|
|
||||||
self.x.set_window_at(col);
|
|
||||||
self.y.set_window_at(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn row(&self) -> usize {
|
|
||||||
self.y.index()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn column(&self) -> usize {
|
|
||||||
self.x.index()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn row_limit(&self) -> usize {
|
|
||||||
self.y.end()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn row_starts_at(&self) -> usize {
|
|
||||||
self.y.starts_at()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn column_starts_at(&self) -> usize {
|
|
||||||
self.x.starts_at()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn row_window(&self) -> usize {
|
|
||||||
self.y.offset()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn column_window(&self) -> usize {
|
|
||||||
self.x.offset()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn column_window_size(&self) -> usize {
|
|
||||||
self.x.window()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_row(&mut self) -> bool {
|
|
||||||
self.y.next(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_row_page(&mut self) -> bool {
|
|
||||||
self.y.next_window()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn row_move_to_end(&mut self) -> bool {
|
|
||||||
self.y.next(self.y.cap())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn row_move_to_start(&mut self) -> bool {
|
|
||||||
self.y.prev(self.y.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_row(&mut self) -> bool {
|
|
||||||
self.y.prev(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_row_page(&mut self) -> bool {
|
|
||||||
self.y.prev_window()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_column(&mut self) -> bool {
|
|
||||||
self.x.next(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_column_by(&mut self, i: usize) -> bool {
|
|
||||||
self.x.next(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_column(&mut self) -> bool {
|
|
||||||
self.x.prev(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_column_by(&mut self, i: usize) -> bool {
|
|
||||||
self.x.prev(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_column_i(&mut self) -> bool {
|
|
||||||
self.x.set_window_at(self.x.starts_at() + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_column_i(&mut self) -> bool {
|
|
||||||
if self.x.starts_at() == 0 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.x.set_window_at(self.x.starts_at() - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_row_i(&mut self) -> bool {
|
|
||||||
self.y.set_window_at(self.y.starts_at() + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_row_i(&mut self) -> bool {
|
|
||||||
if self.y.starts_at() == 0 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.y.set_window_at(self.y.starts_at() - 1)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -160,7 +160,7 @@ impl View for InteractiveView<'_> {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.expect("we know that we have a table cause of a flag");
|
.expect("we know that we have a table cause of a flag");
|
||||||
|
|
||||||
let was_at_the_top = table.get_current_position().0 == 0;
|
let was_at_the_top = table.get_cursor_position().row == 0;
|
||||||
|
|
||||||
if was_at_the_top && matches!(key.code, KeyCode::Up | KeyCode::PageUp) {
|
if was_at_the_top && matches!(key.code, KeyCode::Up | KeyCode::PageUp) {
|
||||||
self.view_mode = false;
|
self.view_mode = false;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use super::{colored_text_widget::ColoredTextWidget, cursor::XYCursor, Layout, View, ViewConfig};
|
use super::{
|
||||||
|
colored_text_widget::ColoredTextWidget, cursor::WindowCursor2D, Layout, View, ViewConfig,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
nu_common::{NuSpan, NuText},
|
nu_common::{NuSpan, NuText},
|
||||||
pager::{report::Report, Frame, Transition, ViewInfo},
|
pager::{report::Report, Frame, Transition, ViewInfo},
|
||||||
|
@ -17,7 +19,7 @@ use std::cmp::max;
|
||||||
pub struct Preview {
|
pub struct Preview {
|
||||||
underlying_value: Option<Value>,
|
underlying_value: Option<Value>,
|
||||||
lines: Vec<String>,
|
lines: Vec<String>,
|
||||||
cursor: XYCursor,
|
cursor: WindowCursor2D,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Preview {
|
impl Preview {
|
||||||
|
@ -26,8 +28,9 @@ impl Preview {
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.replace('\t', " ")) // tui: doesn't support TAB
|
.map(|line| line.replace('\t', " ")) // tui: doesn't support TAB
|
||||||
.collect();
|
.collect();
|
||||||
let cursor = XYCursor::new(lines.len(), usize::MAX);
|
|
||||||
|
|
||||||
|
// TODO: refactor so this is fallible and returns a Result instead of panicking
|
||||||
|
let cursor = WindowCursor2D::new(lines.len(), usize::MAX).expect("Failed to create cursor");
|
||||||
Self {
|
Self {
|
||||||
lines,
|
lines,
|
||||||
cursor,
|
cursor,
|
||||||
|
@ -38,10 +41,11 @@ impl Preview {
|
||||||
|
|
||||||
impl View for Preview {
|
impl View for Preview {
|
||||||
fn draw(&mut self, f: &mut Frame, area: Rect, _: ViewConfig<'_>, layout: &mut Layout) {
|
fn draw(&mut self, f: &mut Frame, area: Rect, _: ViewConfig<'_>, layout: &mut Layout) {
|
||||||
self.cursor
|
let _ = self
|
||||||
.set_window(area.height as usize, area.width as usize);
|
.cursor
|
||||||
|
.set_window_size(area.height as usize, area.width as usize);
|
||||||
|
|
||||||
let lines = &self.lines[self.cursor.row_starts_at()..];
|
let lines = &self.lines[self.cursor.window_origin().row..];
|
||||||
for (i, line) in lines.iter().enumerate().take(area.height as usize) {
|
for (i, line) in lines.iter().enumerate().take(area.height as usize) {
|
||||||
let text_widget = ColoredTextWidget::new(line, self.cursor.column());
|
let text_widget = ColoredTextWidget::new(line, self.cursor.column());
|
||||||
let plain_text = text_widget.get_plain_text(area.width as usize);
|
let plain_text = text_widget.get_plain_text(area.width as usize);
|
||||||
|
@ -65,13 +69,13 @@ impl View for Preview {
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Left => {
|
KeyCode::Left => {
|
||||||
self.cursor
|
self.cursor
|
||||||
.prev_column_by(max(1, self.cursor.column_window_size() / 2));
|
.prev_column_by(max(1, self.cursor.window_width_in_columns() / 2));
|
||||||
|
|
||||||
Some(Transition::Ok)
|
Some(Transition::Ok)
|
||||||
}
|
}
|
||||||
KeyCode::Right => {
|
KeyCode::Right => {
|
||||||
self.cursor
|
self.cursor
|
||||||
.next_column_by(max(1, self.cursor.column_window_size() / 2));
|
.next_column_by(max(1, self.cursor.window_width_in_columns() / 2));
|
||||||
|
|
||||||
Some(Transition::Ok)
|
Some(Transition::Ok)
|
||||||
}
|
}
|
||||||
|
@ -128,7 +132,7 @@ impl View for Preview {
|
||||||
//
|
//
|
||||||
// todo: improve somehow?
|
// todo: improve somehow?
|
||||||
|
|
||||||
self.cursor.set_position(row, 0);
|
self.cursor.set_window_start_position(row, 0);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +156,7 @@ fn set_status_end(view: &Preview, info: &mut ViewInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_status_top(view: &Preview, info: &mut ViewInfo) {
|
fn set_status_top(view: &Preview, info: &mut ViewInfo) {
|
||||||
if view.cursor.row_starts_at() == 0 {
|
if view.cursor.window_origin().row == 0 {
|
||||||
info.status = Some(Report::info("TOP"));
|
info.status = Some(Report::info("TOP"));
|
||||||
} else {
|
} else {
|
||||||
info.status = Some(Report::default());
|
info.status = Some(Report::default());
|
||||||
|
|
|
@ -2,7 +2,7 @@ mod table_widget;
|
||||||
|
|
||||||
use self::table_widget::{TableStyle, TableWidget, TableWidgetState};
|
use self::table_widget::{TableStyle, TableWidget, TableWidgetState};
|
||||||
use super::{
|
use super::{
|
||||||
cursor::XYCursor,
|
cursor::{Position, WindowCursor2D},
|
||||||
util::{make_styled_string, nu_style_to_tui},
|
util::{make_styled_string, nu_style_to_tui},
|
||||||
Layout, View, ViewConfig,
|
Layout, View, ViewConfig,
|
||||||
};
|
};
|
||||||
|
@ -133,22 +133,22 @@ impl<'a> RecordView<'a> {
|
||||||
layer.reset_cursor();
|
layer.reset_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_position(&self) -> (usize, usize) {
|
/// Get the current position of the cursor in the table as a whole
|
||||||
|
pub fn get_cursor_position(&self) -> Position {
|
||||||
let layer = self.get_layer_last();
|
let layer = self.get_layer_last();
|
||||||
(layer.cursor.row(), layer.cursor.column())
|
layer.cursor.position()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_window(&self) -> (usize, usize) {
|
/// Get the current position of the cursor in the window being shown
|
||||||
|
pub fn get_cursor_position_in_window(&self) -> Position {
|
||||||
let layer = self.get_layer_last();
|
let layer = self.get_layer_last();
|
||||||
(layer.cursor.row_window(), layer.cursor.column_window())
|
layer.cursor.window_relative_position()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_offset(&self) -> (usize, usize) {
|
/// Get the origin of the window being shown. (0,0), top left corner.
|
||||||
|
pub fn get_window_origin(&self) -> Position {
|
||||||
let layer = self.get_layer_last();
|
let layer = self.get_layer_last();
|
||||||
(
|
layer.cursor.window_origin()
|
||||||
layer.cursor.row_starts_at(),
|
|
||||||
layer.cursor.column_starts_at(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cursor_mode(&mut self) {
|
pub fn set_cursor_mode(&mut self) {
|
||||||
|
@ -160,7 +160,7 @@ impl<'a> RecordView<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_value(&self) -> Value {
|
pub fn get_current_value(&self) -> Value {
|
||||||
let (row, column) = self.get_current_position();
|
let Position { row, column } = self.get_cursor_position();
|
||||||
let layer = self.get_layer_last();
|
let layer = self.get_layer_last();
|
||||||
|
|
||||||
let (row, column) = match layer.orientation {
|
let (row, column) = match layer.orientation {
|
||||||
|
@ -175,15 +175,17 @@ impl<'a> RecordView<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_tablew(&'a self, cfg: ViewConfig<'a>) -> TableWidget<'a> {
|
/// Create a table widget.
|
||||||
|
/// WARNING: this is currently really slow on large data sets.
|
||||||
|
/// It creates a string representation of every cell in the table and looks at every row for lscolorize.
|
||||||
|
fn create_table_widget(&'a self, cfg: ViewConfig<'a>) -> TableWidget<'a> {
|
||||||
let layer = self.get_layer_last();
|
let layer = self.get_layer_last();
|
||||||
let mut data = convert_records_to_string(&layer.records, cfg.nu_config, cfg.style_computer);
|
let mut data = convert_records_to_string(&layer.records, cfg.nu_config, cfg.style_computer);
|
||||||
|
|
||||||
lscolorize(&layer.columns, &mut data, cfg.lscolors);
|
lscolorize(&layer.columns, &mut data, cfg.lscolors);
|
||||||
|
|
||||||
let headers = layer.columns.as_ref();
|
let headers = layer.columns.as_ref();
|
||||||
let style_computer = cfg.style_computer;
|
let style_computer = cfg.style_computer;
|
||||||
let (row, column) = self.get_current_offset();
|
let Position { row, column } = self.get_window_origin();
|
||||||
|
|
||||||
TableWidget::new(
|
TableWidget::new(
|
||||||
headers,
|
headers,
|
||||||
|
@ -199,11 +201,17 @@ impl<'a> RecordView<'a> {
|
||||||
fn update_cursors(&mut self, rows: usize, columns: usize) {
|
fn update_cursors(&mut self, rows: usize, columns: usize) {
|
||||||
match self.get_layer_last().orientation {
|
match self.get_layer_last().orientation {
|
||||||
Orientation::Top => {
|
Orientation::Top => {
|
||||||
self.get_layer_last_mut().cursor.set_window(rows, columns);
|
let _ = self
|
||||||
|
.get_layer_last_mut()
|
||||||
|
.cursor
|
||||||
|
.set_window_size(rows, columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
Orientation::Left => {
|
Orientation::Left => {
|
||||||
self.get_layer_last_mut().cursor.set_window(rows, columns);
|
let _ = self
|
||||||
|
.get_layer_last_mut()
|
||||||
|
.cursor
|
||||||
|
.set_window_size(rows, columns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +234,10 @@ impl<'a> RecordView<'a> {
|
||||||
impl View for RecordView<'_> {
|
impl View for RecordView<'_> {
|
||||||
fn draw(&mut self, f: &mut Frame, area: Rect, cfg: ViewConfig<'_>, layout: &mut Layout) {
|
fn draw(&mut self, f: &mut Frame, area: Rect, cfg: ViewConfig<'_>, layout: &mut Layout) {
|
||||||
let mut table_layout = TableWidgetState::default();
|
let mut table_layout = TableWidgetState::default();
|
||||||
let table = self.create_tablew(cfg);
|
// TODO: creating the table widget is O(N) where N is the number of cells in the grid.
|
||||||
|
// Way too slow to do on every draw call!
|
||||||
|
// To make explore work for larger data sets, this needs to be improved.
|
||||||
|
let table = self.create_table_widget(cfg);
|
||||||
f.render_stateful_widget(table, area, &mut table_layout);
|
f.render_stateful_widget(table, area, &mut table_layout);
|
||||||
|
|
||||||
*layout = table_layout.layout;
|
*layout = table_layout.layout;
|
||||||
|
@ -234,7 +245,7 @@ impl View for RecordView<'_> {
|
||||||
self.update_cursors(table_layout.count_rows, table_layout.count_columns);
|
self.update_cursors(table_layout.count_rows, table_layout.count_columns);
|
||||||
|
|
||||||
if self.mode == UIMode::Cursor {
|
if self.mode == UIMode::Cursor {
|
||||||
let (row, column) = self.get_current_window();
|
let Position { row, column } = self.get_cursor_position_in_window();
|
||||||
let info = get_element_info(
|
let info = get_element_info(
|
||||||
layout,
|
layout,
|
||||||
row,
|
row,
|
||||||
|
@ -308,7 +319,9 @@ impl View for RecordView<'_> {
|
||||||
|
|
||||||
for (column, _) in cells.iter().enumerate() {
|
for (column, _) in cells.iter().enumerate() {
|
||||||
if i == pos {
|
if i == pos {
|
||||||
self.get_layer_last_mut().cursor.set_position(row, column);
|
self.get_layer_last_mut()
|
||||||
|
.cursor
|
||||||
|
.set_window_start_position(row, column);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +387,7 @@ pub struct RecordLayer<'a> {
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
was_transposed: bool,
|
was_transposed: bool,
|
||||||
cursor: XYCursor,
|
cursor: WindowCursor2D,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RecordLayer<'a> {
|
impl<'a> RecordLayer<'a> {
|
||||||
|
@ -384,7 +397,10 @@ impl<'a> RecordLayer<'a> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let columns = columns.into();
|
let columns = columns.into();
|
||||||
let records = records.into();
|
let records = records.into();
|
||||||
let cursor = XYCursor::new(records.len(), columns.len());
|
|
||||||
|
// TODO: refactor so this is fallible and returns a Result instead of panicking
|
||||||
|
let cursor =
|
||||||
|
WindowCursor2D::new(records.len(), columns.len()).expect("Failed to create cursor");
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
columns,
|
columns,
|
||||||
|
@ -420,7 +436,9 @@ impl<'a> RecordLayer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_cursor(&mut self) {
|
fn reset_cursor(&mut self) {
|
||||||
self.cursor = XYCursor::new(self.count_rows(), self.count_columns());
|
// TODO: refactor so this is fallible and returns a Result instead of panicking
|
||||||
|
self.cursor = WindowCursor2D::new(self.count_rows(), self.count_columns())
|
||||||
|
.expect("Failed to create cursor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +652,9 @@ fn tail_data(state: &mut RecordView<'_>, page_size: usize) {
|
||||||
let layer = state.get_layer_last_mut();
|
let layer = state.get_layer_last_mut();
|
||||||
let count_rows = layer.records.len();
|
let count_rows = layer.records.len();
|
||||||
if count_rows > page_size {
|
if count_rows > page_size {
|
||||||
layer.cursor.set_position(count_rows - page_size, 0);
|
layer
|
||||||
|
.cursor
|
||||||
|
.set_window_start_position(count_rows - page_size, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,20 +751,18 @@ fn build_table_as_record(v: &RecordView) -> Value {
|
||||||
Value::record(record, NuSpan::unknown())
|
Value::record(record, NuSpan::unknown())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_cursor_position(mode: UIMode, cursor: XYCursor) -> String {
|
fn report_cursor_position(mode: UIMode, cursor: WindowCursor2D) -> String {
|
||||||
if mode == UIMode::Cursor {
|
if mode == UIMode::Cursor {
|
||||||
let row = cursor.row();
|
let Position { row, column } = cursor.position();
|
||||||
let column = cursor.column();
|
|
||||||
format!("{row},{column}")
|
format!("{row},{column}")
|
||||||
} else {
|
} else {
|
||||||
let rows_seen = cursor.row_starts_at();
|
let Position { row, column } = cursor.window_origin();
|
||||||
let columns_seen = cursor.column_starts_at();
|
format!("{row},{column}")
|
||||||
format!("{rows_seen},{columns_seen}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_row_position(cursor: XYCursor) -> String {
|
fn report_row_position(cursor: WindowCursor2D) -> String {
|
||||||
if cursor.row_starts_at() == 0 {
|
if cursor.window_origin().row == 0 {
|
||||||
String::from("Top")
|
String::from("Top")
|
||||||
} else {
|
} else {
|
||||||
let percent_rows = get_percentage(cursor.row(), cursor.row_limit());
|
let percent_rows = get_percentage(cursor.row(), cursor.row_limit());
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nu-glob"
|
name = "nu-glob"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
authors = ["The Nushell Project Developers", "The Rust Project Developers"]
|
authors = ["The Nushell Project Developers", "The Rust Project Developers"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = """
|
description = """
|
||||||
|
@ -14,4 +14,4 @@ categories = ["filesystem"]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
doc-comment = "0.3"
|
doc-comment = "0.3"
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-json"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-json"
|
name = "nu-json"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -23,5 +23,5 @@ serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# nu-path = { path="../nu-path", version = "0.94.1" }
|
# nu-path = { path="../nu-path", version = "0.94.3" }
|
||||||
# serde_json = "1.0"
|
# serde_json = "1.0"
|
||||||
|
|
|
@ -3,14 +3,14 @@ authors = ["The Nushell Project Developers"]
|
||||||
description = "Nushell's integrated LSP server"
|
description = "Nushell's integrated LSP server"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-lsp"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-lsp"
|
||||||
name = "nu-lsp"
|
name = "nu-lsp"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cli = { path = "../nu-cli", version = "0.94.1" }
|
nu-cli = { path = "../nu-cli", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
|
|
||||||
reedline = { workspace = true }
|
reedline = { workspace = true }
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-command = { path = "../nu-command", version = "0.94.1" }
|
nu-command = { path = "../nu-command", version = "0.94.3" }
|
||||||
nu-test-support = { path = "../nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
|
||||||
|
|
||||||
assert-json-diff = "2.0"
|
assert-json-diff = "2.0"
|
||||||
|
|
|
@ -5,17 +5,17 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-parser"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-parser"
|
name = "nu-parser"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
exclude = ["/fuzz"]
|
exclude = ["/fuzz"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-plugin-engine = { path = "../nu-plugin-engine", optional = true, version = "0.94.1" }
|
nu-plugin-engine = { path = "../nu-plugin-engine", optional = true, version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
|
|
||||||
bytesize = { workspace = true }
|
bytesize = { workspace = true }
|
||||||
chrono = { default-features = false, features = ['std'], workspace = true }
|
chrono = { default-features = false, features = ['std'], workspace = true }
|
||||||
|
@ -27,4 +27,4 @@ serde_json = { workspace = true }
|
||||||
rstest = { workspace = true, default-features = false }
|
rstest = { workspace = true, default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
plugin = ["nu-plugin-engine"]
|
plugin = ["nu-plugin-engine"]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Argument, Expr, Expression},
|
ast::{Argument, Expr, Expression},
|
||||||
engine::CommandType,
|
engine::{CommandType, UNKNOWN_SPAN_ID},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -56,43 +56,49 @@ impl Command for KnownExternal {
|
||||||
};
|
};
|
||||||
|
|
||||||
let extern_name: Vec<_> = extern_name.split(' ').collect();
|
let extern_name: Vec<_> = extern_name.split(' ').collect();
|
||||||
|
let call_head_id = engine_state
|
||||||
|
.find_span_id(call.head)
|
||||||
|
.unwrap_or(UNKNOWN_SPAN_ID);
|
||||||
|
|
||||||
let arg_extern_name = Expression {
|
let arg_extern_name = Expression::new_existing(
|
||||||
expr: Expr::String(extern_name[0].to_string()),
|
Expr::String(extern_name[0].to_string()),
|
||||||
span: call.head,
|
call.head,
|
||||||
ty: Type::String,
|
call_head_id,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
};
|
);
|
||||||
|
|
||||||
extern_call.add_positional(arg_extern_name);
|
extern_call.add_positional(arg_extern_name);
|
||||||
|
|
||||||
for subcommand in extern_name.into_iter().skip(1) {
|
for subcommand in extern_name.into_iter().skip(1) {
|
||||||
extern_call.add_positional(Expression {
|
extern_call.add_positional(Expression::new_existing(
|
||||||
expr: Expr::String(subcommand.to_string()),
|
Expr::String(subcommand.to_string()),
|
||||||
span: call.head,
|
call.head,
|
||||||
ty: Type::String,
|
call_head_id,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
});
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg in &call.arguments {
|
for arg in &call.arguments {
|
||||||
match arg {
|
match arg {
|
||||||
Argument::Positional(positional) => extern_call.add_positional(positional.clone()),
|
Argument::Positional(positional) => extern_call.add_positional(positional.clone()),
|
||||||
Argument::Named(named) => {
|
Argument::Named(named) => {
|
||||||
|
let named_span_id = engine_state
|
||||||
|
.find_span_id(named.0.span)
|
||||||
|
.unwrap_or(UNKNOWN_SPAN_ID);
|
||||||
if let Some(short) = &named.1 {
|
if let Some(short) = &named.1 {
|
||||||
extern_call.add_positional(Expression {
|
extern_call.add_positional(Expression::new_existing(
|
||||||
expr: Expr::String(format!("-{}", short.item)),
|
Expr::String(format!("-{}", short.item)),
|
||||||
span: named.0.span,
|
named.0.span,
|
||||||
ty: Type::String,
|
named_span_id,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
});
|
));
|
||||||
} else {
|
} else {
|
||||||
extern_call.add_positional(Expression {
|
extern_call.add_positional(Expression::new_existing(
|
||||||
expr: Expr::String(format!("--{}", named.0.item)),
|
Expr::String(format!("--{}", named.0.item)),
|
||||||
span: named.0.span,
|
named.0.span,
|
||||||
ty: Type::String,
|
named_span_id,
|
||||||
custom_completion: None,
|
Type::String,
|
||||||
});
|
));
|
||||||
}
|
}
|
||||||
if let Some(arg) = &named.2 {
|
if let Some(arg) = &named.2 {
|
||||||
extern_call.add_positional(arg.clone());
|
extern_call.add_positional(arg.clone());
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -68,7 +68,7 @@ pub fn type_compatible(lhs: &Type, rhs: &Type) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn math_result_type(
|
pub fn math_result_type(
|
||||||
_working_set: &StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
lhs: &mut Expression,
|
lhs: &mut Expression,
|
||||||
op: &mut Expression,
|
op: &mut Expression,
|
||||||
rhs: &mut Expression,
|
rhs: &mut Expression,
|
||||||
|
@ -104,7 +104,7 @@ pub fn math_result_type(
|
||||||
| Type::Filesize,
|
| Type::Filesize,
|
||||||
_,
|
_,
|
||||||
) => {
|
) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -118,7 +118,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -130,7 +130,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Operator::Math(Math::Append) => check_append(lhs, rhs, op),
|
Operator::Math(Math::Append) => check_append(working_set, lhs, rhs, op),
|
||||||
Operator::Math(Math::Minus) => match (&lhs.ty, &rhs.ty) {
|
Operator::Math(Math::Minus) => match (&lhs.ty, &rhs.ty) {
|
||||||
(Type::Int, Type::Int) => (Type::Int, None),
|
(Type::Int, Type::Int) => (Type::Int, None),
|
||||||
(Type::Float, Type::Int) => (Type::Float, None),
|
(Type::Float, Type::Int) => (Type::Float, None),
|
||||||
|
@ -152,7 +152,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Any, None),
|
(Type::Any, _) => (Type::Any, None),
|
||||||
(_, Type::Any) => (Type::Any, None),
|
(_, Type::Any) => (Type::Any, None),
|
||||||
(Type::Int | Type::Float | Type::Date | Type::Duration | Type::Filesize, _) => {
|
(Type::Int | Type::Float | Type::Date | Type::Duration | Type::Filesize, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -166,7 +166,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -209,7 +209,7 @@ pub fn math_result_type(
|
||||||
| (Type::Duration, _)
|
| (Type::Duration, _)
|
||||||
| (Type::Filesize, _)
|
| (Type::Filesize, _)
|
||||||
| (Type::List(_), _) => {
|
| (Type::List(_), _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -223,7 +223,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -252,7 +252,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Any, None),
|
(Type::Any, _) => (Type::Any, None),
|
||||||
(_, Type::Any) => (Type::Any, None),
|
(_, Type::Any) => (Type::Any, None),
|
||||||
(Type::Int | Type::Float, _) => {
|
(Type::Int | Type::Float, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -266,7 +266,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -302,7 +302,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Any, None),
|
(Type::Any, _) => (Type::Any, None),
|
||||||
(_, Type::Any) => (Type::Any, None),
|
(_, Type::Any) => (Type::Any, None),
|
||||||
(Type::Int | Type::Float | Type::Filesize | Type::Duration, _) => {
|
(Type::Int | Type::Float | Type::Filesize | Type::Duration, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -316,7 +316,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -348,7 +348,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Any, None),
|
(Type::Any, _) => (Type::Any, None),
|
||||||
(_, Type::Any) => (Type::Any, None),
|
(_, Type::Any) => (Type::Any, None),
|
||||||
(Type::Int | Type::Float | Type::Filesize | Type::Duration, _) => {
|
(Type::Int | Type::Float | Type::Filesize | Type::Duration, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -362,7 +362,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -390,7 +390,7 @@ pub fn math_result_type(
|
||||||
// definitions. As soon as that syntax is added this should be removed
|
// definitions. As soon as that syntax is added this should be removed
|
||||||
(a, b) if a == b => (Type::Bool, None),
|
(a, b) if a == b => (Type::Bool, None),
|
||||||
(Type::Bool, _) => {
|
(Type::Bool, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -404,7 +404,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -441,7 +441,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Bool, None),
|
(Type::Any, _) => (Type::Bool, None),
|
||||||
(_, Type::Any) => (Type::Bool, None),
|
(_, Type::Any) => (Type::Bool, None),
|
||||||
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -455,7 +455,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -491,7 +491,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Bool, None),
|
(Type::Any, _) => (Type::Bool, None),
|
||||||
(_, Type::Any) => (Type::Bool, None),
|
(_, Type::Any) => (Type::Bool, None),
|
||||||
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -505,7 +505,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -541,7 +541,7 @@ pub fn math_result_type(
|
||||||
(Type::Nothing, _) => (Type::Nothing, None),
|
(Type::Nothing, _) => (Type::Nothing, None),
|
||||||
(_, Type::Nothing) => (Type::Nothing, None),
|
(_, Type::Nothing) => (Type::Nothing, None),
|
||||||
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -555,7 +555,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -591,7 +591,7 @@ pub fn math_result_type(
|
||||||
(Type::Nothing, _) => (Type::Nothing, None),
|
(Type::Nothing, _) => (Type::Nothing, None),
|
||||||
(_, Type::Nothing) => (Type::Nothing, None),
|
(_, Type::Nothing) => (Type::Nothing, None),
|
||||||
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
(Type::Int | Type::Float | Type::Duration | Type::Filesize, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -605,7 +605,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -638,7 +638,7 @@ pub fn math_result_type(
|
||||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||||
|
|
||||||
(Type::String, _) => {
|
(Type::String, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -652,7 +652,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -673,7 +673,7 @@ pub fn math_result_type(
|
||||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||||
|
|
||||||
(Type::String, _) => {
|
(Type::String, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -687,7 +687,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -708,7 +708,7 @@ pub fn math_result_type(
|
||||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||||
|
|
||||||
(Type::String, _) => {
|
(Type::String, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -722,7 +722,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -743,7 +743,7 @@ pub fn math_result_type(
|
||||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||||
|
|
||||||
(Type::String, _) => {
|
(Type::String, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -757,7 +757,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -781,7 +781,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Bool, None),
|
(Type::Any, _) => (Type::Bool, None),
|
||||||
(_, Type::Any) => (Type::Bool, None),
|
(_, Type::Any) => (Type::Bool, None),
|
||||||
(Type::Int | Type::Float | Type::String, _) => {
|
(Type::Int | Type::Float | Type::String, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -795,7 +795,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -819,7 +819,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Bool, None),
|
(Type::Any, _) => (Type::Bool, None),
|
||||||
(_, Type::Any) => (Type::Bool, None),
|
(_, Type::Any) => (Type::Bool, None),
|
||||||
(Type::Int | Type::Float | Type::String, _) => {
|
(Type::Int | Type::Float | Type::String, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -833,7 +833,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -855,7 +855,7 @@ pub fn math_result_type(
|
||||||
(Type::Any, _) => (Type::Any, None),
|
(Type::Any, _) => (Type::Any, None),
|
||||||
(_, Type::Any) => (Type::Any, None),
|
(_, Type::Any) => (Type::Any, None),
|
||||||
(Type::Int, _) => {
|
(Type::Int, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -869,7 +869,7 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
@ -881,7 +881,9 @@ pub fn math_result_type(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Operator::Assignment(Assignment::AppendAssign) => check_append(lhs, rhs, op),
|
Operator::Assignment(Assignment::AppendAssign) => {
|
||||||
|
check_append(working_set, lhs, rhs, op)
|
||||||
|
}
|
||||||
Operator::Assignment(_) => match (&lhs.ty, &rhs.ty) {
|
Operator::Assignment(_) => match (&lhs.ty, &rhs.ty) {
|
||||||
(x, y) if x == y => (Type::Nothing, None),
|
(x, y) if x == y => (Type::Nothing, None),
|
||||||
(Type::Any, _) => (Type::Nothing, None),
|
(Type::Any, _) => (Type::Nothing, None),
|
||||||
|
@ -894,7 +896,7 @@ pub fn math_result_type(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
|
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
|
@ -1026,6 +1028,7 @@ pub fn check_block_input_output(working_set: &StateWorkingSet, block: &Block) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_append(
|
fn check_append(
|
||||||
|
working_set: &mut StateWorkingSet,
|
||||||
lhs: &Expression,
|
lhs: &Expression,
|
||||||
rhs: &Expression,
|
rhs: &Expression,
|
||||||
op: &mut Expression,
|
op: &mut Expression,
|
||||||
|
@ -1050,7 +1053,7 @@ fn check_append(
|
||||||
(Type::Binary, Type::Binary) => (Type::Binary, None),
|
(Type::Binary, Type::Binary) => (Type::Binary, None),
|
||||||
(Type::Any, _) | (_, Type::Any) => (Type::Any, None),
|
(Type::Any, _) | (_, Type::Any) => (Type::Any, None),
|
||||||
(Type::Table(_) | Type::String | Type::Binary, _) => {
|
(Type::Table(_) | Type::String | Type::Binary, _) => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationRHS(
|
Some(ParseError::UnsupportedOperationRHS(
|
||||||
|
@ -1064,7 +1067,7 @@ fn check_append(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(working_set, op.span);
|
||||||
(
|
(
|
||||||
Type::Any,
|
Type::Any,
|
||||||
Some(ParseError::UnsupportedOperationLHS(
|
Some(ParseError::UnsupportedOperationLHS(
|
||||||
|
|
|
@ -694,6 +694,221 @@ pub fn parse_call_missing_req_flag() {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case("foo-external-call", "foo-external-call", "bare word")]
|
||||||
|
#[case("^foo-external-call", "foo-external-call", "bare word with caret")]
|
||||||
|
#[case(
|
||||||
|
"foo/external-call",
|
||||||
|
"foo/external-call",
|
||||||
|
"bare word with forward slash"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
"^foo/external-call",
|
||||||
|
"foo/external-call",
|
||||||
|
"bare word with forward slash and caret"
|
||||||
|
)]
|
||||||
|
#[case(r"foo\external-call", r"foo\external-call", "bare word with backslash")]
|
||||||
|
#[case(
|
||||||
|
r"^foo\external-call",
|
||||||
|
r"foo\external-call",
|
||||||
|
"bare word with backslash and caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
"^'foo external call'",
|
||||||
|
"'foo external call'",
|
||||||
|
"single quote with caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
"^'foo/external call'",
|
||||||
|
"'foo/external call'",
|
||||||
|
"single quote with forward slash and caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
r"^'foo\external call'",
|
||||||
|
r"'foo\external call'",
|
||||||
|
"single quote with backslash and caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
r#"^"foo external call""#,
|
||||||
|
r#""foo external call""#,
|
||||||
|
"double quote with caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
r#"^"foo/external call""#,
|
||||||
|
r#""foo/external call""#,
|
||||||
|
"double quote with forward slash and caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
r#"^"foo\\external call""#,
|
||||||
|
r#""foo\external call""#,
|
||||||
|
"double quote with backslash and caret"
|
||||||
|
)]
|
||||||
|
#[case("`foo external call`", "`foo external call`", "backtick quote")]
|
||||||
|
#[case(
|
||||||
|
"^`foo external call`",
|
||||||
|
"`foo external call`",
|
||||||
|
"backtick quote with caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
"`foo/external call`",
|
||||||
|
"`foo/external call`",
|
||||||
|
"backtick quote with forward slash"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
"^`foo/external call`",
|
||||||
|
"`foo/external call`",
|
||||||
|
"backtick quote with forward slash and caret"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
r"^`foo\external call`",
|
||||||
|
r"`foo\external call`",
|
||||||
|
"backtick quote with backslash"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
r"^`foo\external call`",
|
||||||
|
r"`foo\external call`",
|
||||||
|
"backtick quote with backslash and caret"
|
||||||
|
)]
|
||||||
|
fn test_external_call_name(#[case] input: &str, #[case] expected: &str, #[case] tag: &str) {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
let block = parse(&mut working_set, None, input.as_bytes(), true);
|
||||||
|
assert!(
|
||||||
|
working_set.parse_errors.is_empty(),
|
||||||
|
"{tag}: errors: {:?}",
|
||||||
|
working_set.parse_errors
|
||||||
|
);
|
||||||
|
|
||||||
|
let pipeline = &block.pipelines[0];
|
||||||
|
assert_eq!(1, pipeline.len());
|
||||||
|
let element = &pipeline.elements[0];
|
||||||
|
match &element.expr.expr {
|
||||||
|
Expr::ExternalCall(name, args) => {
|
||||||
|
match &name.expr {
|
||||||
|
Expr::String(string) => {
|
||||||
|
assert_eq!(expected, string);
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("{tag}: Unexpected expression in command name position: {other:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(0, args.len());
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("{tag}: Unexpected expression in pipeline: {other:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case("^foo bar-baz", "bar-baz", "bare word")]
|
||||||
|
#[case("^foo bar/baz", "bar/baz", "bare word with forward slash")]
|
||||||
|
#[case(r"^foo bar\baz", r"bar\baz", "bare word with backslash")]
|
||||||
|
#[case("^foo 'bar baz'", "'bar baz'", "single quote")]
|
||||||
|
#[case("foo 'bar/baz'", "'bar/baz'", "single quote with forward slash")]
|
||||||
|
#[case(r"foo 'bar\baz'", r"'bar\baz'", "single quote with backslash")]
|
||||||
|
#[case(r#"^foo "bar baz""#, r#""bar baz""#, "double quote")]
|
||||||
|
#[case(r#"^foo "bar/baz""#, r#""bar/baz""#, "double quote with forward slash")]
|
||||||
|
#[case(r#"^foo "bar\\baz""#, r#""bar\baz""#, "double quote with backslash")]
|
||||||
|
#[case("^foo `bar baz`", "`bar baz`", "backtick quote")]
|
||||||
|
#[case("^foo `bar/baz`", "`bar/baz`", "backtick quote with forward slash")]
|
||||||
|
#[case(r"^foo `bar\baz`", r"`bar\baz`", "backtick quote with backslash")]
|
||||||
|
fn test_external_call_argument_regular(
|
||||||
|
#[case] input: &str,
|
||||||
|
#[case] expected: &str,
|
||||||
|
#[case] tag: &str,
|
||||||
|
) {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
let block = parse(&mut working_set, None, input.as_bytes(), true);
|
||||||
|
assert!(
|
||||||
|
working_set.parse_errors.is_empty(),
|
||||||
|
"{tag}: errors: {:?}",
|
||||||
|
working_set.parse_errors
|
||||||
|
);
|
||||||
|
|
||||||
|
let pipeline = &block.pipelines[0];
|
||||||
|
assert_eq!(1, pipeline.len());
|
||||||
|
let element = &pipeline.elements[0];
|
||||||
|
match &element.expr.expr {
|
||||||
|
Expr::ExternalCall(name, args) => {
|
||||||
|
match &name.expr {
|
||||||
|
Expr::String(string) => {
|
||||||
|
assert_eq!("foo", string, "{tag}: incorrect name");
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("{tag}: Unexpected expression in command name position: {other:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(1, args.len());
|
||||||
|
match &args[0] {
|
||||||
|
ExternalArgument::Regular(expr) => match &expr.expr {
|
||||||
|
Expr::String(string) => {
|
||||||
|
assert_eq!(expected, string, "{tag}: incorrect arg");
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("Unexpected expression in command arg position: {other:?}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
other @ ExternalArgument::Spread(..) => {
|
||||||
|
panic!("Unexpected external spread argument in command arg position: {other:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("{tag}: Unexpected expression in pipeline: {other:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_external_call_argument_spread() {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
let block = parse(&mut working_set, None, b"^foo ...[a b c]", true);
|
||||||
|
assert!(
|
||||||
|
working_set.parse_errors.is_empty(),
|
||||||
|
"errors: {:?}",
|
||||||
|
working_set.parse_errors
|
||||||
|
);
|
||||||
|
|
||||||
|
let pipeline = &block.pipelines[0];
|
||||||
|
assert_eq!(1, pipeline.len());
|
||||||
|
let element = &pipeline.elements[0];
|
||||||
|
match &element.expr.expr {
|
||||||
|
Expr::ExternalCall(name, args) => {
|
||||||
|
match &name.expr {
|
||||||
|
Expr::String(string) => {
|
||||||
|
assert_eq!("foo", string, "incorrect name");
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("Unexpected expression in command name position: {other:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(1, args.len());
|
||||||
|
match &args[0] {
|
||||||
|
ExternalArgument::Spread(expr) => match &expr.expr {
|
||||||
|
Expr::List(items) => {
|
||||||
|
assert_eq!(3, items.len());
|
||||||
|
// that's good enough, don't really need to go so deep into it...
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("Unexpected expression in command arg position: {other:?}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
other @ ExternalArgument::Regular(..) => {
|
||||||
|
panic!(
|
||||||
|
"Unexpected external regular argument in command arg position: {other:?}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
panic!("Unexpected expression in pipeline: {other:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nothing_comparison_eq() {
|
fn test_nothing_comparison_eq() {
|
||||||
let engine_state = EngineState::new();
|
let engine_state = EngineState::new();
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-path"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-path"
|
name = "nu-path"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
exclude = ["/fuzz"]
|
exclude = ["/fuzz"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -18,4 +18,4 @@ dirs-next = { workspace = true }
|
||||||
omnipath = { workspace = true }
|
omnipath = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))'.dependencies]
|
||||||
pwd = { workspace = true }
|
pwd = { workspace = true }
|
||||||
|
|
|
@ -5,14 +5,14 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin-core
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-plugin-core"
|
name = "nu-plugin-core"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.1", default-features = false }
|
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3", default-features = false }
|
||||||
|
|
||||||
rmp-serde = { workspace = true }
|
rmp-serde = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
@ -25,4 +25,4 @@ default = ["local-socket"]
|
||||||
local-socket = ["interprocess", "nu-plugin-protocol/local-socket"]
|
local-socket = ["interprocess", "nu-plugin-protocol/local-socket"]
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
windows = { workspace = true }
|
windows = { workspace = true }
|
||||||
|
|
|
@ -5,17 +5,17 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin-engi
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-plugin-engine"
|
name = "nu-plugin-engine"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-system = { path = "../nu-system", version = "0.94.1" }
|
nu-system = { path = "../nu-system", version = "0.94.3" }
|
||||||
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.1" }
|
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3" }
|
||||||
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.1", default-features = false }
|
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.3", default-features = false }
|
||||||
|
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
@ -31,4 +31,4 @@ local-socket = ["nu-plugin-core/local-socket"]
|
||||||
windows = { workspace = true, features = [
|
windows = { workspace = true, features = [
|
||||||
# For setting process creation flags
|
# For setting process creation flags
|
||||||
"Win32_System_Threading",
|
"Win32_System_Threading",
|
||||||
] }
|
] }
|
||||||
|
|
|
@ -5,14 +5,14 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin-prot
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-plugin-protocol"
|
name = "nu-plugin-protocol"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
@ -21,4 +21,4 @@ typetag = "0.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["local-socket"]
|
default = ["local-socket"]
|
||||||
local-socket = []
|
local-socket = []
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nu-plugin-test-support"
|
name = "nu-plugin-test-support"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "Testing support for Nushell plugins"
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1", features = ["plugin"] }
|
nu-engine = { path = "../nu-engine", version = "0.94.3", features = ["plugin"] }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1", features = ["plugin"] }
|
nu-parser = { path = "../nu-parser", version = "0.94.3", features = ["plugin"] }
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.1" }
|
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.3" }
|
||||||
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.1" }
|
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.94.3" }
|
||||||
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.1" }
|
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3" }
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
similar = "2.5"
|
similar = "2.5"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
typetag = "0.2"
|
typetag = "0.2"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
|
|
|
@ -5,16 +5,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-plugin"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-plugin"
|
name = "nu-plugin"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.1" }
|
nu-plugin-protocol = { path = "../nu-plugin-protocol", version = "0.94.3" }
|
||||||
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.1", default-features = false }
|
nu-plugin-core = { path = "../nu-plugin-core", version = "0.94.3", default-features = false }
|
||||||
|
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
@ -29,4 +29,4 @@ local-socket = ["nu-plugin-core/local-socket"]
|
||||||
|
|
||||||
[target.'cfg(target_family = "unix")'.dependencies]
|
[target.'cfg(target_family = "unix")'.dependencies]
|
||||||
# For setting the process group ID (EnterForeground / LeaveForeground)
|
# For setting the process group ID (EnterForeground / LeaveForeground)
|
||||||
nix = { workspace = true, default-features = false, features = ["process"] }
|
nix = { workspace = true, default-features = false, features = ["process"] }
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-pretty-hex"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-pretty-hex"
|
name = "nu-pretty-hex"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
|
@ -18,4 +18,4 @@ nu-ansi-term = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
heapless = { version = "0.8", default-features = false }
|
heapless = { version = "0.8", default-features = false }
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-protocol"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-protocol"
|
name = "nu-protocol"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ version = "0.94.1"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-system = { path = "../nu-system", version = "0.94.1" }
|
nu-system = { path = "../nu-system", version = "0.94.3" }
|
||||||
|
|
||||||
brotli = { workspace = true, optional = true }
|
brotli = { workspace = true, optional = true }
|
||||||
byte-unit = { version = "5.1", features = [ "serde" ] }
|
byte-unit = { version = "5.1", features = [ "serde" ] }
|
||||||
|
@ -45,11 +45,11 @@ plugin = [
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
strum = "0.26"
|
strum = "0.26"
|
||||||
strum_macros = "0.26"
|
strum_macros = "0.26"
|
||||||
nu-test-support = { path = "../nu-test-support", version = "0.94.1" }
|
nu-test-support = { path = "../nu-test-support", version = "0.94.3" }
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
rstest = { workspace = true }
|
rstest = { workspace = true }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
os_pipe = { workspace = true }
|
os_pipe = { workspace = true }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|
|
@ -338,9 +338,13 @@ impl Call {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::engine::EngineState;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn argument_span_named() {
|
fn argument_span_named() {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
let named = Spanned {
|
let named = Spanned {
|
||||||
item: "named".to_string(),
|
item: "named".to_string(),
|
||||||
span: Span::new(2, 3),
|
span: Span::new(2, 3),
|
||||||
|
@ -349,7 +353,7 @@ mod test {
|
||||||
item: "short".to_string(),
|
item: "short".to_string(),
|
||||||
span: Span::new(5, 7),
|
span: Span::new(5, 7),
|
||||||
};
|
};
|
||||||
let expr = Expression::garbage(Span::new(11, 13));
|
let expr = Expression::garbage(&mut working_set, Span::new(11, 13));
|
||||||
|
|
||||||
let arg = Argument::Named((named.clone(), None, None));
|
let arg = Argument::Named((named.clone(), None, None));
|
||||||
|
|
||||||
|
@ -370,8 +374,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn argument_span_positional() {
|
fn argument_span_positional() {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
let span = Span::new(2, 3);
|
let span = Span::new(2, 3);
|
||||||
let expr = Expression::garbage(span);
|
let expr = Expression::garbage(&mut working_set, span);
|
||||||
let arg = Argument::Positional(expr);
|
let arg = Argument::Positional(expr);
|
||||||
|
|
||||||
assert_eq!(span, arg.span());
|
assert_eq!(span, arg.span());
|
||||||
|
@ -379,8 +386,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn argument_span_unknown() {
|
fn argument_span_unknown() {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
let span = Span::new(2, 3);
|
let span = Span::new(2, 3);
|
||||||
let expr = Expression::garbage(span);
|
let expr = Expression::garbage(&mut working_set, span);
|
||||||
let arg = Argument::Unknown(expr);
|
let arg = Argument::Unknown(expr);
|
||||||
|
|
||||||
assert_eq!(span, arg.span());
|
assert_eq!(span, arg.span());
|
||||||
|
@ -388,9 +398,12 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_arguments_span() {
|
fn call_arguments_span() {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
let mut call = Call::new(Span::new(0, 1));
|
let mut call = Call::new(Span::new(0, 1));
|
||||||
call.add_positional(Expression::garbage(Span::new(2, 3)));
|
call.add_positional(Expression::garbage(&mut working_set, Span::new(2, 3)));
|
||||||
call.add_positional(Expression::garbage(Span::new(5, 7)));
|
call.add_positional(Expression::garbage(&mut working_set, Span::new(5, 7)));
|
||||||
|
|
||||||
assert_eq!(Span::new(2, 7), call.arguments_span());
|
assert_eq!(Span::new(2, 7), call.arguments_span());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Argument, Block, Expr, ExternalArgument, ImportPattern, MatchPattern, RecordItem},
|
ast::{Argument, Block, Expr, ExternalArgument, ImportPattern, MatchPattern, RecordItem},
|
||||||
engine::StateWorkingSet,
|
engine::{EngineState, StateWorkingSet},
|
||||||
BlockId, DeclId, Signature, Span, Type, VarId, IN_VARIABLE_ID,
|
BlockId, DeclId, Signature, Span, SpanId, Type, VarId, IN_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -10,15 +10,18 @@ use std::sync::Arc;
|
||||||
pub struct Expression {
|
pub struct Expression {
|
||||||
pub expr: Expr,
|
pub expr: Expr,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub span_id: SpanId,
|
||||||
pub ty: Type,
|
pub ty: Type,
|
||||||
pub custom_completion: Option<DeclId>,
|
pub custom_completion: Option<DeclId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn garbage(span: Span) -> Expression {
|
pub fn garbage(working_set: &mut StateWorkingSet, span: Span) -> Expression {
|
||||||
|
let span_id = working_set.add_span(span);
|
||||||
Expression {
|
Expression {
|
||||||
expr: Expr::Garbage,
|
expr: Expr::Garbage,
|
||||||
span,
|
span,
|
||||||
|
span_id,
|
||||||
ty: Type::Any,
|
ty: Type::Any,
|
||||||
custom_completion: None,
|
custom_completion: None,
|
||||||
}
|
}
|
||||||
|
@ -471,4 +474,49 @@ impl Expression {
|
||||||
Expr::VarDecl(_) => {}
|
Expr::VarDecl(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new(working_set: &mut StateWorkingSet, expr: Expr, span: Span, ty: Type) -> Expression {
|
||||||
|
let span_id = working_set.add_span(span);
|
||||||
|
Expression {
|
||||||
|
expr,
|
||||||
|
span,
|
||||||
|
span_id,
|
||||||
|
ty,
|
||||||
|
custom_completion: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_existing(expr: Expr, span: Span, span_id: SpanId, ty: Type) -> Expression {
|
||||||
|
Expression {
|
||||||
|
expr,
|
||||||
|
span,
|
||||||
|
span_id,
|
||||||
|
ty,
|
||||||
|
custom_completion: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_unknown(expr: Expr, span: Span, ty: Type) -> Expression {
|
||||||
|
Expression {
|
||||||
|
expr,
|
||||||
|
span,
|
||||||
|
span_id: SpanId(0),
|
||||||
|
ty,
|
||||||
|
custom_completion: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_span_id(self, span_id: SpanId) -> Expression {
|
||||||
|
Expression {
|
||||||
|
expr: self.expr,
|
||||||
|
span: self.span,
|
||||||
|
span_id,
|
||||||
|
ty: self.ty,
|
||||||
|
custom_completion: self.custom_completion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn span(&self, engine_state: &EngineState) -> Span {
|
||||||
|
engine_state.get_span(self.span_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
eval_const::create_nu_constant,
|
eval_const::create_nu_constant,
|
||||||
BlockId, Category, Config, DeclId, FileId, HistoryConfig, Module, ModuleId, OverlayId,
|
BlockId, Category, Config, DeclId, FileId, HistoryConfig, Module, ModuleId, OverlayId,
|
||||||
ShellError, Signature, Span, Type, Value, VarId, VirtualPathId,
|
ShellError, Signature, Span, SpanId, Type, Value, VarId, VirtualPathId,
|
||||||
};
|
};
|
||||||
use fancy_regex::Regex;
|
use fancy_regex::Regex;
|
||||||
use lru::LruCache;
|
use lru::LruCache;
|
||||||
|
@ -81,6 +81,7 @@ pub struct EngineState {
|
||||||
// especially long, so it helps
|
// especially long, so it helps
|
||||||
pub(super) blocks: Arc<Vec<Arc<Block>>>,
|
pub(super) blocks: Arc<Vec<Arc<Block>>>,
|
||||||
pub(super) modules: Arc<Vec<Arc<Module>>>,
|
pub(super) modules: Arc<Vec<Arc<Module>>>,
|
||||||
|
pub spans: Vec<Span>,
|
||||||
usage: Usage,
|
usage: Usage,
|
||||||
pub scope: ScopeFrame,
|
pub scope: ScopeFrame,
|
||||||
pub ctrlc: Option<Arc<AtomicBool>>,
|
pub ctrlc: Option<Arc<AtomicBool>>,
|
||||||
|
@ -115,6 +116,9 @@ pub const IN_VARIABLE_ID: usize = 1;
|
||||||
pub const ENV_VARIABLE_ID: usize = 2;
|
pub const ENV_VARIABLE_ID: usize = 2;
|
||||||
// NOTE: If you add more to this list, make sure to update the > checks based on the last in the list
|
// NOTE: If you add more to this list, make sure to update the > checks based on the last in the list
|
||||||
|
|
||||||
|
// The first span is unknown span
|
||||||
|
pub const UNKNOWN_SPAN_ID: SpanId = SpanId(0);
|
||||||
|
|
||||||
impl EngineState {
|
impl EngineState {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -132,6 +136,7 @@ impl EngineState {
|
||||||
modules: Arc::new(vec![Arc::new(Module::new(
|
modules: Arc::new(vec![Arc::new(Module::new(
|
||||||
DEFAULT_OVERLAY_NAME.as_bytes().to_vec(),
|
DEFAULT_OVERLAY_NAME.as_bytes().to_vec(),
|
||||||
))]),
|
))]),
|
||||||
|
spans: vec![Span::unknown()],
|
||||||
usage: Usage::new(),
|
usage: Usage::new(),
|
||||||
// make sure we have some default overlay:
|
// make sure we have some default overlay:
|
||||||
scope: ScopeFrame::with_empty_overlay(
|
scope: ScopeFrame::with_empty_overlay(
|
||||||
|
@ -184,6 +189,7 @@ impl EngineState {
|
||||||
self.files.extend(delta.files);
|
self.files.extend(delta.files);
|
||||||
self.virtual_paths.extend(delta.virtual_paths);
|
self.virtual_paths.extend(delta.virtual_paths);
|
||||||
self.vars.extend(delta.vars);
|
self.vars.extend(delta.vars);
|
||||||
|
self.spans.extend(delta.spans);
|
||||||
self.usage.merge_with(delta.usage);
|
self.usage.merge_with(delta.usage);
|
||||||
|
|
||||||
// Avoid potentially cloning the Arcs if we aren't adding anything
|
// Avoid potentially cloning the Arcs if we aren't adding anything
|
||||||
|
@ -565,6 +571,9 @@ impl EngineState {
|
||||||
self.modules.len()
|
self.modules.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn num_spans(&self) -> usize {
|
||||||
|
self.spans.len()
|
||||||
|
}
|
||||||
pub fn print_vars(&self) {
|
pub fn print_vars(&self) {
|
||||||
for var in self.vars.iter().enumerate() {
|
for var in self.vars.iter().enumerate() {
|
||||||
println!("var{}: {:?}", var.0, var.1);
|
println!("var{}: {:?}", var.0, var.1);
|
||||||
|
@ -1019,6 +1028,25 @@ impl EngineState {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add new span and return its ID
|
||||||
|
pub fn add_span(&mut self, span: Span) -> SpanId {
|
||||||
|
self.spans.push(span);
|
||||||
|
SpanId(self.num_spans() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get existing span
|
||||||
|
pub fn get_span(&self, span_id: SpanId) -> Span {
|
||||||
|
*self
|
||||||
|
.spans
|
||||||
|
.get(span_id.0)
|
||||||
|
.expect("internal error: missing span")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find ID of a span (should be avoided if possible)
|
||||||
|
pub fn find_span_id(&self, span: Span) -> Option<SpanId> {
|
||||||
|
self.spans.iter().position(|sp| sp == &span).map(SpanId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EngineState {
|
impl Default for EngineState {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
usage::Usage, CachedFile, Command, EngineState, OverlayFrame, ScopeFrame, Variable,
|
usage::Usage, CachedFile, Command, EngineState, OverlayFrame, ScopeFrame, Variable,
|
||||||
VirtualPath,
|
VirtualPath,
|
||||||
},
|
},
|
||||||
Module,
|
Module, Span,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ pub struct StateDelta {
|
||||||
pub(super) decls: Vec<Box<dyn Command>>, // indexed by DeclId
|
pub(super) decls: Vec<Box<dyn Command>>, // indexed by DeclId
|
||||||
pub blocks: Vec<Arc<Block>>, // indexed by BlockId
|
pub blocks: Vec<Arc<Block>>, // indexed by BlockId
|
||||||
pub(super) modules: Vec<Arc<Module>>, // indexed by ModuleId
|
pub(super) modules: Vec<Arc<Module>>, // indexed by ModuleId
|
||||||
|
pub spans: Vec<Span>, // indexed by SpanId
|
||||||
pub(super) usage: Usage,
|
pub(super) usage: Usage,
|
||||||
pub scope: Vec<ScopeFrame>,
|
pub scope: Vec<ScopeFrame>,
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
|
@ -45,6 +46,7 @@ impl StateDelta {
|
||||||
decls: vec![],
|
decls: vec![],
|
||||||
blocks: vec![],
|
blocks: vec![],
|
||||||
modules: vec![],
|
modules: vec![],
|
||||||
|
spans: vec![],
|
||||||
scope: vec![scope_frame],
|
scope: vec![scope_frame],
|
||||||
usage: Usage::new(),
|
usage: Usage::new(),
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
StateDelta, Variable, VirtualPath, Visibility,
|
StateDelta, Variable, VirtualPath, Visibility,
|
||||||
},
|
},
|
||||||
BlockId, Category, Config, DeclId, FileId, Module, ModuleId, ParseError, ParseWarning, Span,
|
BlockId, Category, Config, DeclId, FileId, Module, ModuleId, ParseError, ParseWarning, Span,
|
||||||
Type, Value, VarId, VirtualPathId,
|
SpanId, Type, Value, VarId, VirtualPathId,
|
||||||
};
|
};
|
||||||
use core::panic;
|
use core::panic;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -1013,6 +1013,25 @@ impl<'a> StateWorkingSet<'a> {
|
||||||
.expect("internal error: missing virtual path")
|
.expect("internal error: missing virtual path")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_span(&mut self, span: Span) -> SpanId {
|
||||||
|
let num_permanent_spans = self.permanent_state.spans.len();
|
||||||
|
self.delta.spans.push(span);
|
||||||
|
SpanId(num_permanent_spans + self.delta.spans.len() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_span(&self, span_id: SpanId) -> Span {
|
||||||
|
let num_permanent_spans = self.permanent_state.num_spans();
|
||||||
|
if span_id.0 < num_permanent_spans {
|
||||||
|
self.permanent_state.get_span(span_id)
|
||||||
|
} else {
|
||||||
|
*self
|
||||||
|
.delta
|
||||||
|
.spans
|
||||||
|
.get(span_id.0 - num_permanent_spans)
|
||||||
|
.expect("internal error: missing span")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> miette::SourceCode for &StateWorkingSet<'a> {
|
impl<'a> miette::SourceCode for &StateWorkingSet<'a> {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub type VarId = usize;
|
pub type VarId = usize;
|
||||||
pub type DeclId = usize;
|
pub type DeclId = usize;
|
||||||
pub type BlockId = usize;
|
pub type BlockId = usize;
|
||||||
|
@ -5,3 +7,5 @@ pub type ModuleId = usize;
|
||||||
pub type OverlayId = usize;
|
pub type OverlayId = usize;
|
||||||
pub type FileId = usize;
|
pub type FileId = usize;
|
||||||
pub type VirtualPathId = usize;
|
pub type VirtualPathId = usize;
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct SpanId(pub usize); // more robust ID style used in the new parser
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{PluginIdentity, PluginSignature, ShellError, Span};
|
||||||
const BUFFER_SIZE: usize = 65536;
|
const BUFFER_SIZE: usize = 65536;
|
||||||
|
|
||||||
// Chose settings at the low end, because we're just trying to get the maximum speed
|
// Chose settings at the low end, because we're just trying to get the maximum speed
|
||||||
const COMPRESSION_QUALITY: u32 = 1;
|
const COMPRESSION_QUALITY: u32 = 3; // 1 can be very bad
|
||||||
const WIN_SIZE: u32 = 20; // recommended 20-22
|
const WIN_SIZE: u32 = 20; // recommended 20-22
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
|
|
@ -5,12 +5,12 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-std"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-std"
|
name = "nu-std"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-parser = { version = "0.94.1", path = "../nu-parser" }
|
nu-parser = { version = "0.94.3", path = "../nu-parser" }
|
||||||
nu-protocol = { version = "0.94.1", path = "../nu-protocol" }
|
nu-protocol = { version = "0.94.3", path = "../nu-protocol" }
|
||||||
nu-engine = { version = "0.94.1", path = "../nu-engine" }
|
nu-engine = { version = "0.94.3", path = "../nu-engine" }
|
||||||
miette = { workspace = true, features = ["fancy-no-backtrace"] }
|
miette = { workspace = true, features = ["fancy-no-backtrace"] }
|
||||||
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
export def main [
|
export def main [
|
||||||
condition: bool, # Condition, which should be true
|
condition: bool, # Condition, which should be true
|
||||||
message?: string, # Optional error message
|
message?: string, # Optional error message
|
||||||
--error-label: record # Label for `error make` if you want to create a custom assert
|
--error-label: record<text: string, span: record<start: int, end: int>> # Label for `error make` if you want to create a custom assert
|
||||||
] {
|
] {
|
||||||
if $condition { return }
|
if $condition { return }
|
||||||
error make {
|
error make {
|
||||||
|
@ -81,7 +81,7 @@ export def main [
|
||||||
export def not [
|
export def not [
|
||||||
condition: bool, # Condition, which should be false
|
condition: bool, # Condition, which should be false
|
||||||
message?: string, # Optional error message
|
message?: string, # Optional error message
|
||||||
--error-label: record # Label for `error make` if you want to create a custom assert
|
--error-label: record<text: string, span: record<start: int, end: int>> # Label for `error make` if you want to create a custom assert
|
||||||
] {
|
] {
|
||||||
if $condition {
|
if $condition {
|
||||||
let span = (metadata $condition).span
|
let span = (metadata $condition).span
|
||||||
|
|
|
@ -3,7 +3,7 @@ authors = ["The Nushell Project Developers", "procs creators"]
|
||||||
description = "Nushell system querying"
|
description = "Nushell system querying"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-system"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-system"
|
||||||
name = "nu-system"
|
name = "nu-system"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
@ -45,4 +45,4 @@ windows = { workspace = true, features = [
|
||||||
"Win32_System_SystemInformation",
|
"Win32_System_SystemInformation",
|
||||||
"Win32_System_Threading",
|
"Win32_System_Threading",
|
||||||
"Win32_UI_Shell",
|
"Win32_UI_Shell",
|
||||||
]}
|
]}
|
||||||
|
|
|
@ -5,20 +5,20 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-table"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-table"
|
name = "nu-table"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-color-config = { path = "../nu-color-config", version = "0.94.1" }
|
nu-color-config = { path = "../nu-color-config", version = "0.94.3" }
|
||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
fancy-regex = { workspace = true }
|
fancy-regex = { workspace = true }
|
||||||
tabled = { workspace = true, features = ["color"], default-features = false }
|
tabled = { workspace = true, features = ["color"], default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# nu-test-support = { path="../nu-test-support", version = "0.94.1" }
|
# nu-test-support = { path="../nu-test-support", version = "0.94.3" }
|
||||||
|
|
|
@ -5,12 +5,12 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-term-grid"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-term-grid"
|
name = "nu-term-grid"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
unicode-width = { workspace = true }
|
unicode-width = { workspace = true }
|
||||||
|
|
|
@ -5,17 +5,17 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-test-suppor
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-test-support"
|
name = "nu-test-support"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
nu-glob = { path = "../nu-glob", version = "0.94.1" }
|
nu-glob = { path = "../nu-glob", version = "0.94.3" }
|
||||||
nu-utils = { path = "../nu-utils", version = "0.94.1" }
|
nu-utils = { path = "../nu-utils", version = "0.94.3" }
|
||||||
|
|
||||||
num-format = { workspace = true }
|
num-format = { workspace = true }
|
||||||
which = { workspace = true }
|
which = { workspace = true }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu-utils"
|
name = "nu-utils"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-utils"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-utils"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
@ -29,4 +29,4 @@ unicase = "2.7.0"
|
||||||
crossterm_winapi = "0.9"
|
crossterm_winapi = "0.9"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
nix = { workspace = true, default-features = false, features = ["user", "fs"] }
|
nix = { workspace = true, default-features = false, features = ["user", "fs"] }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Nushell Config File
|
# Nushell Config File
|
||||||
#
|
#
|
||||||
# version = "0.94.1"
|
# version = "0.94.3"
|
||||||
|
|
||||||
# For more information on defining custom themes, see
|
# For more information on defining custom themes, see
|
||||||
# https://www.nushell.sh/book/coloring_and_theming.html
|
# https://www.nushell.sh/book/coloring_and_theming.html
|
||||||
|
@ -892,4 +892,4 @@ $env.config = {
|
||||||
event: { edit: selectall }
|
event: { edit: selectall }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Nushell Environment Config File
|
# Nushell Environment Config File
|
||||||
#
|
#
|
||||||
# version = "0.94.1"
|
# version = "0.94.3"
|
||||||
|
|
||||||
def create_left_prompt [] {
|
def create_left_prompt [] {
|
||||||
let dir = match (do --ignore-shell-errors { $env.PWD | path relative-to $nu.home-path }) {
|
let dir = match (do --ignore-shell-errors { $env.PWD | path relative-to $nu.home-path }) {
|
||||||
|
@ -97,4 +97,4 @@ $env.NU_PLUGIN_DIRS = [
|
||||||
# $env.PATH = ($env.PATH | uniq)
|
# $env.PATH = ($env.PATH | uniq)
|
||||||
|
|
||||||
# To load from a custom file you can use:
|
# 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')
|
||||||
|
|
|
@ -10,10 +10,10 @@ name = "nu_plugin_custom_values"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
serde = { workspace = true, default-features = false }
|
serde = { workspace = true, default-features = false }
|
||||||
typetag = "0.2"
|
typetag = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.1" }
|
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_exam
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_example"
|
name = "nu_plugin_example"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "nu_plugin_example"
|
name = "nu_plugin_example"
|
||||||
|
@ -15,9 +15,9 @@ bench = false
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.1" }
|
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
|
|
|
@ -5,12 +5,12 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_form
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_formats"
|
name = "nu_plugin_formats"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
# 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-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
|
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
eml-parser = "0.1"
|
eml-parser = "0.1"
|
||||||
|
@ -18,4 +18,4 @@ ical = "0.11"
|
||||||
rust-ini = "0.21.0"
|
rust-ini = "0.21.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.1" }
|
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_gsta
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_gstat"
|
name = "nu_plugin_gstat"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
|
@ -16,7 +16,7 @@ name = "nu_plugin_gstat"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
|
|
||||||
git2 = "0.18"
|
git2 = "0.18"
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_inc"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_inc"
|
name = "nu_plugin_inc"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
|
@ -16,7 +16,7 @@ name = "nu_plugin_inc"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1", features = ["plugin"] }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3", features = ["plugin"] }
|
||||||
|
|
||||||
semver = "1.0"
|
semver = "1.0"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# it also allows us to test the plugin interface with something manually implemented in a scripting
|
# 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.
|
# language without adding any extra dependencies to our tests.
|
||||||
|
|
||||||
const NUSHELL_VERSION = "0.94.1"
|
const NUSHELL_VERSION = "0.94.3"
|
||||||
|
|
||||||
def main [--stdio] {
|
def main [--stdio] {
|
||||||
if ($stdio) {
|
if ($stdio) {
|
||||||
|
@ -257,4 +257,4 @@ def start_plugin [] {
|
||||||
}) |
|
}) |
|
||||||
each { from json | handle_input } |
|
each { from json | handle_input } |
|
||||||
ignore
|
ignore
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_polars"
|
name = "nu_plugin_polars"
|
||||||
repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_polars"
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_polars"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ bench = false
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-path = { path = "../nu-path", version = "0.94.1" }
|
nu-path = { path = "../nu-path", version = "0.94.3" }
|
||||||
|
|
||||||
# Potential dependencies for extras
|
# Potential dependencies for extras
|
||||||
chrono = { workspace = true, features = ["std", "unstable-locales"], default-features = false }
|
chrono = { workspace = true, features = ["std", "unstable-locales"], default-features = false }
|
||||||
|
@ -73,9 +73,9 @@ optional = false
|
||||||
version = "0.39"
|
version = "0.39"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.1" }
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
nu-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-command = { path = "../nu-command", version = "0.94.1" }
|
nu-command = { path = "../nu-command", version = "0.94.3" }
|
||||||
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.1" }
|
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.94.3" }
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
|
|
|
@ -465,7 +465,7 @@ fn from_csv(
|
||||||
let df: NuLazyFrame = csv_reader
|
let df: NuLazyFrame = csv_reader
|
||||||
.finish()
|
.finish()
|
||||||
.map_err(|e| ShellError::GenericError {
|
.map_err(|e| ShellError::GenericError {
|
||||||
error: "Parquet reader error".into(),
|
error: "CSV reader error".into(),
|
||||||
msg: format!("{e:?}"),
|
msg: format!("{e:?}"),
|
||||||
span: Some(call.head),
|
span: Some(call.head),
|
||||||
help: None,
|
help: None,
|
||||||
|
@ -531,7 +531,7 @@ fn from_csv(
|
||||||
let df: NuDataFrame = csv_reader
|
let df: NuDataFrame = csv_reader
|
||||||
.finish()
|
.finish()
|
||||||
.map_err(|e| ShellError::GenericError {
|
.map_err(|e| ShellError::GenericError {
|
||||||
error: "Parquet reader error".into(),
|
error: "CSV reader error".into(),
|
||||||
msg: format!("{e:?}"),
|
msg: format!("{e:?}"),
|
||||||
span: Some(call.head),
|
span: Some(call.head),
|
||||||
help: None,
|
help: None,
|
||||||
|
|
|
@ -269,13 +269,36 @@ fn typed_column_to_series(name: &str, column: TypedColumn) -> Result<Series, She
|
||||||
let series_values: Result<Vec<_>, _> = column
|
let series_values: Result<Vec<_>, _> = column
|
||||||
.values
|
.values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| v.as_f64().map(|v| v as f32))
|
.map(|v| match v {
|
||||||
|
Value::Float { val, .. } => Ok(*val as f32),
|
||||||
|
Value::Int { val, .. } => Ok(*val as f32),
|
||||||
|
x => Err(ShellError::GenericError {
|
||||||
|
error: "Error converting to f32".into(),
|
||||||
|
msg: "".into(),
|
||||||
|
span: None,
|
||||||
|
help: Some(format!("Unexpected type: {x:?}")),
|
||||||
|
inner: vec![],
|
||||||
|
}),
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Ok(Series::new(name, series_values?))
|
Ok(Series::new(name, series_values?))
|
||||||
}
|
}
|
||||||
DataType::Float64 => {
|
DataType::Float64 => {
|
||||||
let series_values: Result<Vec<_>, _> =
|
let series_values: Result<Vec<_>, _> = column
|
||||||
column.values.iter().map(|v| v.as_f64()).collect();
|
.values
|
||||||
|
.iter()
|
||||||
|
.map(|v| match v {
|
||||||
|
Value::Float { val, .. } => Ok(*val),
|
||||||
|
Value::Int { val, .. } => Ok(*val as f64),
|
||||||
|
x => Err(ShellError::GenericError {
|
||||||
|
error: "Error converting to f64".into(),
|
||||||
|
msg: "".into(),
|
||||||
|
span: None,
|
||||||
|
help: Some(format!("Unexpected type: {x:?}")),
|
||||||
|
inner: vec![],
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
Ok(Series::new(name, series_values?))
|
Ok(Series::new(name, series_values?))
|
||||||
}
|
}
|
||||||
DataType::UInt8 => {
|
DataType::UInt8 => {
|
||||||
|
|
|
@ -27,7 +27,7 @@ import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
NUSHELL_VERSION = "0.94.1"
|
NUSHELL_VERSION = "0.94.3"
|
||||||
|
|
||||||
|
|
||||||
def signatures():
|
def signatures():
|
||||||
|
@ -124,7 +124,7 @@ def process_call(id, plugin_call):
|
||||||
span = plugin_call["call"]["head"]
|
span = plugin_call["call"]["head"]
|
||||||
|
|
||||||
# Creates a Value of type List that will be encoded and sent to Nushell
|
# Creates a Value of type List that will be encoded and sent to Nushell
|
||||||
f = lambda x, y: {
|
def f(x, y): return {
|
||||||
"Int": {
|
"Int": {
|
||||||
"val": x * y,
|
"val": x * y,
|
||||||
"span": span
|
"span": span
|
||||||
|
@ -169,7 +169,7 @@ def tell_nushell_hello():
|
||||||
"""
|
"""
|
||||||
hello = {
|
hello = {
|
||||||
"Hello": {
|
"Hello": {
|
||||||
"protocol": "nu-plugin", # always this value
|
"protocol": "nu-plugin", # always this value
|
||||||
"version": NUSHELL_VERSION,
|
"version": NUSHELL_VERSION,
|
||||||
"features": []
|
"features": []
|
||||||
}
|
}
|
||||||
|
@ -246,8 +246,9 @@ def plugin():
|
||||||
input = json.loads(line)
|
input = json.loads(line)
|
||||||
handle_input(input)
|
handle_input(input)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) == 2 and sys.argv[1] == "--stdio":
|
if len(sys.argv) == 2 and sys.argv[1] == "--stdio":
|
||||||
plugin()
|
plugin()
|
||||||
else:
|
else:
|
||||||
print("Run me from inside nushell!")
|
print("Run me from inside nushell!")
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_quer
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_query"
|
name = "nu_plugin_query"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
|
@ -16,10 +16,10 @@ name = "nu_plugin_query"
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = { path = "../nu-plugin", version = "0.94.1" }
|
nu-plugin = { path = "../nu-plugin", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
|
|
||||||
gjson = "0.8"
|
gjson = "0.8"
|
||||||
scraper = { default-features = false, version = "0.19" }
|
scraper = { default-features = false, version = "0.19" }
|
||||||
sxd-document = "0.3"
|
sxd-document = "0.3"
|
||||||
sxd-xpath = "0.4"
|
sxd-xpath = "0.4"
|
||||||
|
|
|
@ -88,7 +88,7 @@ pub fn execute_xpath_query(
|
||||||
|
|
||||||
match r {
|
match r {
|
||||||
sxd_xpath::Value::Nodeset(ns) => {
|
sxd_xpath::Value::Nodeset(ns) => {
|
||||||
for n in ns.into_iter() {
|
for n in ns.document_order() {
|
||||||
record.push(key.clone(), Value::string(n.string_value(), call.head));
|
record.push(key.clone(), Value::string(n.string_value(), call.head));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_stre
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nu_plugin_stress_internals"
|
name = "nu_plugin_stress_internals"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "nu_plugin_stress_internals"
|
name = "nu_plugin_stress_internals"
|
||||||
|
@ -16,4 +16,4 @@ bench = false
|
||||||
# assumptions about the serialized format
|
# assumptions about the serialized format
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
interprocess = { workspace = true }
|
interprocess = { workspace = true }
|
||||||
|
|
|
@ -5,16 +5,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nuon"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "nuon"
|
name = "nuon"
|
||||||
version = "0.94.1"
|
version = "0.94.3"
|
||||||
|
|
||||||
# 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-parser = { path = "../nu-parser", version = "0.94.1" }
|
nu-parser = { path = "../nu-parser", version = "0.94.3" }
|
||||||
nu-protocol = { path = "../nu-protocol", version = "0.94.1" }
|
nu-protocol = { path = "../nu-protocol", version = "0.94.3" }
|
||||||
nu-engine = { path = "../nu-engine", version = "0.94.1" }
|
nu-engine = { path = "../nu-engine", version = "0.94.3" }
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
fancy-regex = { workspace = true }
|
fancy-regex = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
|
|
|
@ -56,12 +56,12 @@ pub fn from_nuon(input: &str, span: Option<Span>) -> Result<Value, ShellError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let expr = if block.pipelines.is_empty() {
|
let expr = if block.pipelines.is_empty() {
|
||||||
Expression {
|
Expression::new(
|
||||||
expr: Expr::Nothing,
|
&mut working_set,
|
||||||
span: span.unwrap_or(Span::unknown()),
|
Expr::Nothing,
|
||||||
custom_completion: None,
|
span.unwrap_or(Span::unknown()),
|
||||||
ty: Type::Nothing,
|
Type::Nothing,
|
||||||
}
|
)
|
||||||
} else {
|
} else {
|
||||||
let mut pipeline = Arc::make_mut(&mut block).pipelines.remove(0);
|
let mut pipeline = Arc::make_mut(&mut block).pipelines.remove(0);
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ pub fn from_nuon(input: &str, span: Option<Span>) -> Result<Value, ShellError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if pipeline.elements.is_empty() {
|
if pipeline.elements.is_empty() {
|
||||||
Expression {
|
Expression::new(
|
||||||
expr: Expr::Nothing,
|
&mut working_set,
|
||||||
span: span.unwrap_or(Span::unknown()),
|
Expr::Nothing,
|
||||||
custom_completion: None,
|
span.unwrap_or(Span::unknown()),
|
||||||
ty: Type::Nothing,
|
Type::Nothing,
|
||||||
}
|
)
|
||||||
} else {
|
} else {
|
||||||
pipeline.elements.remove(0).expr
|
pipeline.elements.remove(0).expr
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,6 +539,15 @@ fn dynamic_closure_optional_arg() {
|
||||||
fn dynamic_closure_rest_args() {
|
fn dynamic_closure_rest_args() {
|
||||||
let actual = nu!(r#"let closure = {|...args| $args | str join ""}; do $closure 1 2 3"#);
|
let actual = nu!(r#"let closure = {|...args| $args | str join ""}; do $closure 1 2 3"#);
|
||||||
assert_eq!(actual.out, "123");
|
assert_eq!(actual.out, "123");
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
r#"let closure = {|required, ...args| $"($required), ($args | str join "")"}; do $closure 1 2 3"#
|
||||||
|
);
|
||||||
|
assert_eq!(actual.out, "1, 23");
|
||||||
|
let actual = nu!(
|
||||||
|
r#"let closure = {|required, optional?, ...args| $"($required), ($optional), ($args | str join "")"}; do $closure 1 2 3"#
|
||||||
|
);
|
||||||
|
assert_eq!(actual.out, "1, 2, 3");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "which-support")]
|
#[cfg(feature = "which-support")]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user