Merge branch 'main' into ecow-record

This commit is contained in:
Ian Manske 2024-05-01 23:02:47 -04:00
commit 4fa58435bd
417 changed files with 8877 additions and 6519 deletions

View File

@ -19,7 +19,7 @@ jobs:
# Prevent sudden announcement of a new advisory from failing ci: # Prevent sudden announcement of a new advisory from failing ci:
continue-on-error: true continue-on-error: true
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- uses: rustsec/audit-check@v1.4.1 - uses: rustsec/audit-check@v1.4.1
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -44,7 +44,7 @@ jobs:
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache - name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0 uses: actions-rust-lang/setup-rust-toolchain@v1.8.0
@ -89,7 +89,7 @@ jobs:
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache - name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0 uses: actions-rust-lang/setup-rust-toolchain@v1.8.0
@ -121,7 +121,7 @@ jobs:
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache - name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0 uses: actions-rust-lang/setup-rust-toolchain@v1.8.0
@ -174,7 +174,7 @@ jobs:
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache - name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0 uses: actions-rust-lang/setup-rust-toolchain@v1.8.0

View File

@ -27,7 +27,7 @@ jobs:
# if: github.repository == 'nushell/nightly' # if: github.repository == 'nushell/nightly'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.1.2 uses: actions/checkout@v4.1.4
if: github.repository == 'nushell/nightly' if: github.repository == 'nushell/nightly'
with: with:
ref: main ref: main
@ -36,7 +36,7 @@ jobs:
token: ${{ secrets.WORKFLOW_TOKEN }} token: ${{ secrets.WORKFLOW_TOKEN }}
- name: Setup Nushell - name: Setup Nushell
uses: hustcer/setup-nu@v3.9 uses: hustcer/setup-nu@v3.10
if: github.repository == 'nushell/nightly' if: github.repository == 'nushell/nightly'
with: with:
version: 0.91.0 version: 0.91.0
@ -123,7 +123,7 @@ jobs:
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
with: with:
ref: main ref: main
fetch-depth: 0 fetch-depth: 0
@ -139,7 +139,7 @@ jobs:
rustflags: '' rustflags: ''
- name: Setup Nushell - name: Setup Nushell
uses: hustcer/setup-nu@v3.9 uses: hustcer/setup-nu@v3.10
with: with:
version: 0.91.0 version: 0.91.0
@ -235,7 +235,7 @@ jobs:
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
with: with:
ref: main ref: main
fetch-depth: 0 fetch-depth: 0
@ -251,7 +251,7 @@ jobs:
rustflags: '' rustflags: ''
- name: Setup Nushell - name: Setup Nushell
uses: hustcer/setup-nu@v3.9 uses: hustcer/setup-nu@v3.10
with: with:
version: 0.91.0 version: 0.91.0
@ -310,12 +310,12 @@ jobs:
- name: Waiting for Release - name: Waiting for Release
run: sleep 1800 run: sleep 1800
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
with: with:
ref: main ref: main
- name: Setup Nushell - name: Setup Nushell
uses: hustcer/setup-nu@v3.9 uses: hustcer/setup-nu@v3.10
with: with:
version: 0.91.0 version: 0.91.0

View File

@ -134,9 +134,15 @@ print $'(char nl)All executable files:'; hr-line
print (ls -f ($executable | into glob)); sleep 1sec print (ls -f ($executable | into glob)); sleep 1sec
print $'(char nl)Copying release files...'; hr-line print $'(char nl)Copying release files...'; hr-line
"To use Nu plugins, use the register command to tell Nu where to find the plugin. For example: "To use the included Nushell plugins, register the binaries with the `plugin add` command to tell Nu where to find the plugin.
Then you can use `plugin use` to load the plugin into your session.
For example:
> register ./nu_plugin_query" | save $'($dist)/README.txt' -f > plugin add ./nu_plugin_query
> plugin use query
For more information, refer to https://www.nushell.sh/book/plugins.html
" | save $'($dist)/README.txt' -f
[LICENSE ...(glob $executable)] | each {|it| cp -rv $it $dist } | flatten [LICENSE ...(glob $executable)] | each {|it| cp -rv $it $dist } | flatten
print $'(char nl)Check binary release version detail:'; hr-line print $'(char nl)Check binary release version detail:'; hr-line
@ -186,7 +192,7 @@ if $os in ['macos-latest'] or $USE_UBUNTU {
# Wix need the binaries be stored in target/release/ # Wix need the binaries be stored in target/release/
cp -r ($'($dist)/*' | into glob) target/release/ cp -r ($'($dist)/*' | into glob) target/release/
ls target/release/* | print ls target/release/* | print
cargo install cargo-wix --version 0.3.4 cargo install cargo-wix --version 0.3.8
cargo wix --no-build --nocapture --package nu --output $wixRelease cargo wix --no-build --nocapture --package nu --output $wixRelease
# Workaround for https://github.com/softprops/action-gh-release/issues/280 # Workaround for https://github.com/softprops/action-gh-release/issues/280
let archive = ($wixRelease | str replace --all '\' '/') let archive = ($wixRelease | str replace --all '\' '/')

View File

@ -73,7 +73,7 @@ jobs:
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- name: Update Rust Toolchain Target - name: Update Rust Toolchain Target
run: | run: |
@ -87,7 +87,7 @@ jobs:
rustflags: '' rustflags: ''
- name: Setup Nushell - name: Setup Nushell
uses: hustcer/setup-nu@v3.9 uses: hustcer/setup-nu@v3.10
with: with:
version: 0.91.0 version: 0.91.0
@ -163,7 +163,7 @@ jobs:
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
steps: steps:
- uses: actions/checkout@v4.1.2 - uses: actions/checkout@v4.1.4
- name: Update Rust Toolchain Target - name: Update Rust Toolchain Target
run: | run: |
@ -177,7 +177,7 @@ jobs:
rustflags: '' rustflags: ''
- name: Setup Nushell - name: Setup Nushell
uses: hustcer/setup-nu@v3.9 uses: hustcer/setup-nu@v3.10
with: with:
version: 0.91.0 version: 0.91.0

View File

@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Actions Repository - name: Checkout Actions Repository
uses: actions/checkout@v4.1.2 uses: actions/checkout@v4.1.4
- name: Check spelling - name: Check spelling
uses: crate-ci/typos@v1.20.9 uses: crate-ci/typos@v1.21.0

205
Cargo.lock generated
View File

@ -165,6 +165,12 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "anyhow"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
[[package]] [[package]]
name = "arboard" name = "arboard"
version = "3.3.2" version = "3.3.2"
@ -1155,19 +1161,6 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown 0.14.3",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]] [[package]]
name = "deranged" name = "deranged"
version = "0.3.11" version = "0.3.11"
@ -2875,7 +2868,7 @@ dependencies = [
[[package]] [[package]]
name = "nu" name = "nu"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd",
"crossterm", "crossterm",
@ -2898,7 +2891,9 @@ dependencies = [
"nu-lsp", "nu-lsp",
"nu-parser", "nu-parser",
"nu-path", "nu-path",
"nu-plugin", "nu-plugin-core",
"nu-plugin-engine",
"nu-plugin-protocol",
"nu-protocol", "nu-protocol",
"nu-std", "nu-std",
"nu-system", "nu-system",
@ -2927,7 +2922,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-cli" name = "nu-cli"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"crossterm", "crossterm",
@ -2945,7 +2940,7 @@ dependencies = [
"nu-engine", "nu-engine",
"nu-parser", "nu-parser",
"nu-path", "nu-path",
"nu-plugin", "nu-plugin-engine",
"nu-protocol", "nu-protocol",
"nu-test-support", "nu-test-support",
"nu-utils", "nu-utils",
@ -2962,7 +2957,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-cmd-base" name = "nu-cmd-base"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"miette", "miette",
@ -2974,7 +2969,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-cmd-dataframe" name = "nu-cmd-dataframe"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"chrono-tz 0.8.6", "chrono-tz 0.8.6",
@ -2997,7 +2992,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-cmd-extra" name = "nu-cmd-extra"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"fancy-regex", "fancy-regex",
"heck 0.5.0", "heck 0.5.0",
@ -3022,7 +3017,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-cmd-lang" name = "nu-cmd-lang"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"itertools 0.12.1", "itertools 0.12.1",
"nu-engine", "nu-engine",
@ -3034,18 +3029,18 @@ dependencies = [
[[package]] [[package]]
name = "nu-cmd-plugin" name = "nu-cmd-plugin"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"itertools 0.12.1", "itertools 0.12.1",
"nu-engine", "nu-engine",
"nu-path", "nu-path",
"nu-plugin", "nu-plugin-engine",
"nu-protocol", "nu-protocol",
] ]
[[package]] [[package]]
name = "nu-color-config" name = "nu-color-config"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-ansi-term", "nu-ansi-term",
"nu-engine", "nu-engine",
@ -3057,11 +3052,12 @@ dependencies = [
[[package]] [[package]]
name = "nu-command" name = "nu-command"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"alphanumeric-sort", "alphanumeric-sort",
"base64 0.22.0", "base64 0.22.0",
"bracoxide", "bracoxide",
"brotli 5.0.0",
"byteorder", "byteorder",
"bytesize", "bytesize",
"calamine", "calamine",
@ -3117,6 +3113,7 @@ dependencies = [
"os_pipe", "os_pipe",
"pathdiff", "pathdiff",
"percent-encoding", "percent-encoding",
"pretty_assertions",
"print-positions", "print-positions",
"procfs", "procfs",
"quick-xml", "quick-xml",
@ -3125,6 +3122,7 @@ dependencies = [
"rand", "rand",
"rayon", "rayon",
"regex", "regex",
"rmp",
"roxmltree", "roxmltree",
"rstest", "rstest",
"rusqlite", "rusqlite",
@ -3162,7 +3160,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-engine" name = "nu-engine"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-glob", "nu-glob",
"nu-path", "nu-path",
@ -3172,10 +3170,12 @@ dependencies = [
[[package]] [[package]]
name = "nu-explore" name = "nu-explore"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"ansi-str", "ansi-str",
"anyhow",
"crossterm", "crossterm",
"log",
"lscolors", "lscolors",
"nu-ansi-term", "nu-ansi-term",
"nu-color-config", "nu-color-config",
@ -3186,6 +3186,7 @@ dependencies = [
"nu-protocol", "nu-protocol",
"nu-table", "nu-table",
"nu-utils", "nu-utils",
"once_cell",
"ratatui", "ratatui",
"strip-ansi-escapes", "strip-ansi-escapes",
"terminal_size", "terminal_size",
@ -3194,14 +3195,14 @@ dependencies = [
[[package]] [[package]]
name = "nu-glob" name = "nu-glob"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"doc-comment", "doc-comment",
] ]
[[package]] [[package]]
name = "nu-json" name = "nu-json"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"linked-hash-map", "linked-hash-map",
"num-traits", "num-traits",
@ -3211,7 +3212,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-lsp" name = "nu-lsp"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"assert-json-diff", "assert-json-diff",
"crossbeam-channel", "crossbeam-channel",
@ -3232,7 +3233,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-parser" name = "nu-parser"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"bytesize", "bytesize",
"chrono", "chrono",
@ -3240,7 +3241,7 @@ dependencies = [
"log", "log",
"nu-engine", "nu-engine",
"nu-path", "nu-path",
"nu-plugin", "nu-plugin-engine",
"nu-protocol", "nu-protocol",
"rstest", "rstest",
"serde_json", "serde_json",
@ -3248,7 +3249,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-path" name = "nu-path"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"dirs-next", "dirs-next",
"omnipath", "omnipath",
@ -3257,35 +3258,72 @@ dependencies = [
[[package]] [[package]]
name = "nu-plugin" name = "nu-plugin"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"bincode",
"interprocess",
"log", "log",
"miette",
"nix", "nix",
"nu-engine", "nu-engine",
"nu-plugin-core",
"nu-plugin-protocol",
"nu-protocol",
"serde",
"thiserror",
"typetag",
]
[[package]]
name = "nu-plugin-core"
version = "0.93.1"
dependencies = [
"interprocess",
"log",
"nu-plugin-protocol",
"nu-protocol", "nu-protocol",
"nu-system",
"nu-utils",
"rmp-serde", "rmp-serde",
"semver",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "windows 0.54.0",
]
[[package]]
name = "nu-plugin-engine"
version = "0.93.1"
dependencies = [
"log",
"nu-engine",
"nu-plugin-core",
"nu-plugin-protocol",
"nu-protocol",
"nu-system",
"serde",
"typetag", "typetag",
"windows 0.54.0", "windows 0.54.0",
] ]
[[package]]
name = "nu-plugin-protocol"
version = "0.93.1"
dependencies = [
"bincode",
"nu-protocol",
"nu-utils",
"semver",
"serde",
"typetag",
]
[[package]] [[package]]
name = "nu-plugin-test-support" name = "nu-plugin-test-support"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-ansi-term", "nu-ansi-term",
"nu-cmd-lang", "nu-cmd-lang",
"nu-engine", "nu-engine",
"nu-parser", "nu-parser",
"nu-plugin", "nu-plugin",
"nu-plugin-core",
"nu-plugin-engine",
"nu-plugin-protocol",
"nu-protocol", "nu-protocol",
"serde", "serde",
"similar", "similar",
@ -3294,7 +3332,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-pretty-hex" name = "nu-pretty-hex"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"heapless", "heapless",
"nu-ansi-term", "nu-ansi-term",
@ -3303,7 +3341,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-protocol" name = "nu-protocol"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"brotli 5.0.0", "brotli 5.0.0",
"byte-unit", "byte-unit",
@ -3332,7 +3370,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-std" name = "nu-std"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"log", "log",
"miette", "miette",
@ -3343,7 +3381,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-system" name = "nu-system"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"libc", "libc",
@ -3360,7 +3398,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-table" name = "nu-table"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"fancy-regex", "fancy-regex",
"nu-ansi-term", "nu-ansi-term",
@ -3374,7 +3412,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-term-grid" name = "nu-term-grid"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-utils", "nu-utils",
"unicode-width", "unicode-width",
@ -3382,7 +3420,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-test-support" name = "nu-test-support"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-glob", "nu-glob",
"nu-path", "nu-path",
@ -3394,7 +3432,7 @@ dependencies = [
[[package]] [[package]]
name = "nu-utils" name = "nu-utils"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"crossterm_winapi", "crossterm_winapi",
"log", "log",
@ -3420,7 +3458,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_example" name = "nu_plugin_example"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-cmd-lang", "nu-cmd-lang",
"nu-plugin", "nu-plugin",
@ -3430,7 +3468,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_formats" name = "nu_plugin_formats"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"eml-parser", "eml-parser",
"ical", "ical",
@ -3443,7 +3481,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_gstat" name = "nu_plugin_gstat"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"git2", "git2",
"nu-plugin", "nu-plugin",
@ -3452,7 +3490,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_inc" name = "nu_plugin_inc"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"nu-plugin", "nu-plugin",
"nu-protocol", "nu-protocol",
@ -3461,7 +3499,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_polars" name = "nu_plugin_polars"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"chrono-tz 0.9.0", "chrono-tz 0.9.0",
@ -3491,7 +3529,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_query" name = "nu_plugin_query"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"gjson", "gjson",
"nu-plugin", "nu-plugin",
@ -3503,7 +3541,7 @@ dependencies = [
[[package]] [[package]]
name = "nu_plugin_stress_internals" name = "nu_plugin_stress_internals"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"interprocess", "interprocess",
"serde", "serde",
@ -3629,7 +3667,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]] [[package]]
name = "nuon" name = "nuon"
version = "0.92.3" version = "0.93.1"
dependencies = [ dependencies = [
"chrono", "chrono",
"fancy-regex", "fancy-regex",
@ -4859,8 +4897,9 @@ dependencies = [
[[package]] [[package]]
name = "reedline" name = "reedline"
version = "0.31.0" version = "0.32.0"
source = "git+https://github.com/nushell/reedline?branch=main#cc9a957184800065bbc9741ef483a2dee19c2106" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf59e4c97b5049ba96b052cdb652368305a2eddcbce9bf1c16f9d003139eeea"
dependencies = [ dependencies = [
"arboard", "arboard",
"chrono", "chrono",
@ -5000,9 +5039,9 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
[[package]] [[package]]
name = "rmp" name = "rmp"
version = "0.8.13" version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddb316f4b9cae1a3e89c02f1926d557d1142d0d2e684b038c11c1b77705229a" checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"num-traits", "num-traits",
@ -5011,9 +5050,9 @@ dependencies = [
[[package]] [[package]]
name = "rmp-serde" name = "rmp-serde"
version = "1.2.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "938a142ab806f18b88a97b0dea523d39e0fd730a064b035726adcfc58a8a5188" checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"rmp", "rmp",
@ -5114,12 +5153,13 @@ dependencies = [
[[package]] [[package]]
name = "rust-ini" name = "rust-ini"
version = "0.20.0" version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" checksum = "0d625ed57d8f49af6cfa514c42e1a71fadcff60eb0b1c517ff82fe41aa025b41"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"ordered-multimap", "ordered-multimap",
"trim-in-place",
] ]
[[package]] [[package]]
@ -5193,6 +5233,15 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "scc"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96560eea317a9cc4e0bb1f6a2c93c09a19b8c4fc5cb3fcc0ec1c094cd783e2"
dependencies = [
"sdd",
]
[[package]] [[package]]
name = "schannel" name = "schannel"
version = "0.1.23" version = "0.1.23"
@ -5229,6 +5278,12 @@ dependencies = [
"tendril", "tendril",
] ]
[[package]]
name = "sdd"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84345e4c9bd703274a082fb80caaa99b7612be48dfaa1dd9266577ec412309d"
[[package]] [[package]]
name = "seahash" name = "seahash"
version = "4.1.0" version = "4.1.0"
@ -5368,23 +5423,23 @@ dependencies = [
[[package]] [[package]]
name = "serial_test" name = "serial_test"
version = "3.0.0" version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ad9342b3aaca7cb43c45c097dd008d4907070394bd0751a0aa8817e5a018d" checksum = "adb86f9315df5df6a70eae0cc22395a44e544a0d8897586820770a35ede74449"
dependencies = [ dependencies = [
"dashmap",
"futures", "futures",
"lazy_static",
"log", "log",
"once_cell",
"parking_lot", "parking_lot",
"scc",
"serial_test_derive", "serial_test_derive",
] ]
[[package]] [[package]]
name = "serial_test_derive" name = "serial_test_derive"
version = "3.0.0" version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b93fb4adc70021ac1b47f7d45e8cc4169baaa7ea58483bc5b721d19a26202212" checksum = "a9bb72430492e9549b0c4596725c0f82729bff861c45aa8099c0a8e67fc3b721"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -6168,6 +6223,12 @@ dependencies = [
"petgraph", "petgraph",
] ]
[[package]]
name = "trim-in-place"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
[[package]] [[package]]
name = "try-lock" name = "try-lock"
version = "0.2.5" version = "0.2.5"

View File

@ -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.92.3" version = "0.93.1"
# 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
@ -41,6 +41,9 @@ members = [
"crates/nu-pretty-hex", "crates/nu-pretty-hex",
"crates/nu-protocol", "crates/nu-protocol",
"crates/nu-plugin", "crates/nu-plugin",
"crates/nu-plugin-core",
"crates/nu-plugin-engine",
"crates/nu-plugin-protocol",
"crates/nu-plugin-test-support", "crates/nu-plugin-test-support",
"crates/nu_plugin_inc", "crates/nu_plugin_inc",
"crates/nu_plugin_gstat", "crates/nu_plugin_gstat",
@ -61,6 +64,7 @@ members = [
[workspace.dependencies] [workspace.dependencies]
alphanumeric-sort = "1.5" alphanumeric-sort = "1.5"
ansi-str = "0.8" ansi-str = "0.8"
anyhow = "1.0.82"
base64 = "0.22" base64 = "0.22"
bracoxide = "0.1.2" bracoxide = "0.1.2"
brotli = "5.0" brotli = "5.0"
@ -90,6 +94,7 @@ heck = "0.5.0"
human-date-parser = "0.1.1" human-date-parser = "0.1.1"
indexmap = "2.2" indexmap = "2.2"
indicatif = "0.17" indicatif = "0.17"
interprocess = "1.2.1"
is_executable = "1.0" is_executable = "1.0"
itertools = "0.12" itertools = "0.12"
libc = "0.2" libc = "0.2"
@ -117,6 +122,7 @@ open = "5.1"
os_pipe = "1.1" os_pipe = "1.1"
pathdiff = "0.2" pathdiff = "0.2"
percent-encoding = "2" percent-encoding = "2"
pretty_assertions = "1.4"
print-positions = "0.6" print-positions = "0.6"
procfs = "0.16.0" procfs = "0.16.0"
pwd = "1.3" pwd = "1.3"
@ -126,9 +132,10 @@ quickcheck_macros = "1.0"
rand = "0.8" rand = "0.8"
ratatui = "0.26" ratatui = "0.26"
rayon = "1.10" rayon = "1.10"
reedline = "0.31.0" reedline = "0.32.0"
regex = "1.9.5" regex = "1.9.5"
rmp-serde = "1.2" rmp = "0.8"
rmp-serde = "1.3"
ropey = "1.6.1" ropey = "1.6.1"
roxmltree = "0.19" roxmltree = "0.19"
rstest = { version = "0.18", default-features = false } rstest = { version = "0.18", default-features = false }
@ -168,25 +175,25 @@ windows = "0.54"
winreg = "0.52" winreg = "0.52"
[dependencies] [dependencies]
nu-cli = { path = "./crates/nu-cli", version = "0.92.3" } nu-cli = { path = "./crates/nu-cli", version = "0.93.1" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.92.3" } nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.93.1" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.92.3" } nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.93.1" }
nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.92.3", optional = true } nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.93.1", optional = true }
nu-cmd-dataframe = { path = "./crates/nu-cmd-dataframe", version = "0.92.3", features = [ nu-cmd-dataframe = { path = "./crates/nu-cmd-dataframe", version = "0.93.1", features = [
"dataframe", "dataframe",
], optional = true } ], optional = true }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.92.3" } nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.93.1" }
nu-command = { path = "./crates/nu-command", version = "0.92.3" } nu-command = { path = "./crates/nu-command", version = "0.93.1" }
nu-engine = { path = "./crates/nu-engine", version = "0.92.3" } nu-engine = { path = "./crates/nu-engine", version = "0.93.1" }
nu-explore = { path = "./crates/nu-explore", version = "0.92.3" } nu-explore = { path = "./crates/nu-explore", version = "0.93.1" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.92.3" } nu-lsp = { path = "./crates/nu-lsp/", version = "0.93.1" }
nu-parser = { path = "./crates/nu-parser", version = "0.92.3" } nu-parser = { path = "./crates/nu-parser", version = "0.93.1" }
nu-path = { path = "./crates/nu-path", version = "0.92.3" } nu-path = { path = "./crates/nu-path", version = "0.93.1" }
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.92.3" } nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.93.1" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.92.3" } nu-protocol = { path = "./crates/nu-protocol", version = "0.93.1" }
nu-std = { path = "./crates/nu-std", version = "0.92.3" } nu-std = { path = "./crates/nu-std", version = "0.93.1" }
nu-system = { path = "./crates/nu-system", version = "0.92.3" } nu-system = { path = "./crates/nu-system", version = "0.93.1" }
nu-utils = { path = "./crates/nu-utils", version = "0.92.3" } nu-utils = { path = "./crates/nu-utils", version = "0.93.1" }
reedline = { workspace = true, features = ["bashisms", "sqlite"] } reedline = { workspace = true, features = ["bashisms", "sqlite"] }
@ -215,18 +222,20 @@ nix = { workspace = true, default-features = false, features = [
] } ] }
[dev-dependencies] [dev-dependencies]
nu-test-support = { path = "./crates/nu-test-support", version = "0.92.3" } nu-test-support = { path = "./crates/nu-test-support", version = "0.93.1" }
nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.93.1" }
nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.93.1" }
assert_cmd = "2.0" assert_cmd = "2.0"
dirs-next = { workspace = true } dirs-next = { workspace = true }
divan = "0.1.14" divan = "0.1.14"
pretty_assertions = "1.4" pretty_assertions = { workspace = true }
rstest = { workspace = true, default-features = false } rstest = { workspace = true, default-features = false }
serial_test = "3.0" serial_test = "3.1"
tempfile = { workspace = true } tempfile = { workspace = true }
[features] [features]
plugin = [ plugin = [
"nu-plugin", "nu-plugin-engine",
"nu-cmd-plugin", "nu-cmd-plugin",
"nu-cli/plugin", "nu-cli/plugin",
"nu-parser/plugin", "nu-parser/plugin",
@ -296,7 +305,7 @@ bench = false
# To use a development version of a dependency please use a global override here # To use a development version of a dependency please use a global override here
# changing versions in each sub-crate of the workspace is tedious # changing versions in each sub-crate of the workspace is tedious
[patch.crates-io] [patch.crates-io]
reedline = { git = "https://github.com/nushell/reedline", branch = "main" } # reedline = { git = "https://github.com/nushell/reedline", branch = "main" }
# nu-ansi-term = {git = "https://github.com/nushell/nu-ansi-term.git", branch = "main"} # nu-ansi-term = {git = "https://github.com/nushell/nu-ansi-term.git", branch = "main"}
# Run all benchmarks with `cargo bench` # Run all benchmarks with `cargo bench`

View File

@ -1,6 +1,7 @@
use nu_cli::{eval_source, evaluate_commands}; use nu_cli::{eval_source, evaluate_commands};
use nu_parser::parse; use nu_parser::parse;
use nu_plugin::{Encoder, EncodingType, PluginCallResponse, PluginOutput}; use nu_plugin_core::{Encoder, EncodingType};
use nu_plugin_protocol::{PluginCallResponse, PluginOutput};
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, Stack}, engine::{EngineState, Stack},
eval_const::create_nu_constant, eval_const::create_nu_constant,

View File

@ -5,26 +5,26 @@ 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.92.3" version = "0.93.1"
[lib] [lib]
bench = false bench = false
[dev-dependencies] [dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" } nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }
nu-command = { path = "../nu-command", version = "0.92.3" } nu-command = { path = "../nu-command", version = "0.93.1" }
nu-test-support = { path = "../nu-test-support", version = "0.92.3" } nu-test-support = { path = "../nu-test-support", version = "0.93.1" }
rstest = { workspace = true, default-features = false } rstest = { workspace = true, default-features = false }
[dependencies] [dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.92.3" } nu-cmd-base = { path = "../nu-cmd-base", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.92.3" } nu-path = { path = "../nu-path", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.92.3" } nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-plugin = { path = "../nu-plugin", version = "0.92.3", optional = true } nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.93.1", optional = true }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.92.3" } nu-utils = { path = "../nu-utils", version = "0.93.1" }
nu-color-config = { path = "../nu-color-config", version = "0.92.3" } nu-color-config = { path = "../nu-color-config", version = "0.93.1" }
nu-ansi-term = { workspace = true } nu-ansi-term = { workspace = true }
reedline = { workspace = true, features = ["bashisms", "sqlite"] } reedline = { workspace = true, features = ["bashisms", "sqlite"] }
@ -45,5 +45,5 @@ uuid = { workspace = true, features = ["v4"] }
which = { workspace = true } which = { workspace = true }
[features] [features]
plugin = ["nu-plugin"] plugin = ["nu-plugin-engine"]
system-clipboard = ["reedline/system_clipboard"] system-clipboard = ["reedline/system_clipboard"]

View File

@ -1,5 +1,4 @@
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use unicode_segmentation::UnicodeSegmentation;
#[derive(Clone)] #[derive(Clone)]
pub struct Commandline; pub struct Commandline;
@ -11,45 +10,12 @@ impl Command for Commandline {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("commandline") Signature::build("commandline")
.input_output_types(vec![ .input_output_types(vec![(Type::Nothing, Type::String)])
(Type::Nothing, Type::Nothing),
(Type::String, Type::String),
])
.switch(
"cursor",
"Set or get the current cursor position",
Some('c'),
)
.switch(
"cursor-end",
"Set the current cursor position to the end of the buffer",
Some('e'),
)
.switch(
"append",
"appends the string to the end of the buffer",
Some('a'),
)
.switch(
"insert",
"inserts the string into the buffer at the cursor position",
Some('i'),
)
.switch(
"replace",
"replaces the current contents of the buffer (default)",
Some('r'),
)
.optional(
"cmd",
SyntaxShape::String,
"the string to perform the operation with",
)
.category(Category::Core) .category(Category::Core)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
"View or modify the current command line input buffer." "View the current command line input buffer."
} }
fn search_terms(&self) -> Vec<&str> { fn search_terms(&self) -> Vec<&str> {
@ -59,126 +25,11 @@ impl Command for Commandline {
fn run( fn run(
&self, &self,
engine_state: &EngineState, engine_state: &EngineState,
stack: &mut Stack, _stack: &mut Stack,
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
if let Some(cmd) = call.opt::<Value>(engine_state, stack, 0)? { let repl = engine_state.repl_state.lock().expect("repl state mutex");
let span = cmd.span(); Ok(Value::string(repl.buffer.clone(), call.head).into_pipeline_data())
let cmd = cmd.coerce_into_string()?;
let mut repl = engine_state.repl_state.lock().expect("repl state mutex");
if call.has_flag(engine_state, stack, "cursor")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--cursor (-c)` is deprecated".into(),
msg: "Setting the current cursor position by `--cursor (-c)` is deprecated"
.into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline set-cursor`".into()),
inner: vec![],
},
);
match cmd.parse::<i64>() {
Ok(n) => {
repl.cursor_pos = if n <= 0 {
0usize
} else {
repl.buffer
.grapheme_indices(true)
.map(|(i, _c)| i)
.nth(n as usize)
.unwrap_or(repl.buffer.len())
}
}
Err(_) => {
return Err(ShellError::CantConvert {
to_type: "int".to_string(),
from_type: "string".to_string(),
span,
help: Some(format!(r#"string "{cmd}" does not represent a valid int"#)),
})
}
}
} else if call.has_flag(engine_state, stack, "append")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--append (-a)` is deprecated".into(),
msg: "Appending the string to the end of the buffer by `--append (-a)` is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline edit --append (-a)`".into()),
inner: vec![],
},
);
repl.buffer.push_str(&cmd);
} else if call.has_flag(engine_state, stack, "insert")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--insert (-i)` is deprecated".into(),
msg: "Inserts the string into the buffer at the cursor position by `--insert (-i)` is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline edit --insert (-i)`".into()),
inner: vec![],
},
);
let cursor_pos = repl.cursor_pos;
repl.buffer.insert_str(cursor_pos, &cmd);
repl.cursor_pos += cmd.len();
} else {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--replace (-r)` is deprecated".into(),
msg: "Replacing the current contents of the buffer by `--replace (-p)` or positional argument is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline edit --replace (-r)`".into()),
inner: vec![],
},
);
repl.buffer = cmd;
repl.cursor_pos = repl.buffer.len();
}
Ok(Value::nothing(call.head).into_pipeline_data())
} else {
let mut repl = engine_state.repl_state.lock().expect("repl state mutex");
if call.has_flag(engine_state, stack, "cursor-end")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--cursor-end (-e)` is deprecated".into(),
msg: "Setting the current cursor position to the end of the buffer by `--cursor-end (-e)` is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline set-cursor --end (-e)`".into()),
inner: vec![],
},
);
repl.cursor_pos = repl.buffer.len();
Ok(Value::nothing(call.head).into_pipeline_data())
} else if call.has_flag(engine_state, stack, "cursor")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--cursor (-c)` is deprecated".into(),
msg: "Getting the current cursor position by `--cursor (-c)` is deprecated"
.into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline get-cursor`".into()),
inner: vec![],
},
);
let char_pos = repl
.buffer
.grapheme_indices(true)
.chain(std::iter::once((repl.buffer.len(), "")))
.position(|(i, _c)| i == repl.cursor_pos)
.expect("Cursor position isn't on a grapheme boundary");
Ok(Value::string(char_pos.to_string(), call.head).into_pipeline_data())
} else {
Ok(Value::string(repl.buffer.to_string(), call.head).into_pipeline_data())
}
}
} }
} }

View File

@ -12,7 +12,7 @@ impl Command for KeybindingsDefault {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()) Signature::build(self.name())
.category(Category::Platform) .category(Category::Platform)
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::table())])
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -14,7 +14,7 @@ impl Command for KeybindingsList {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()) Signature::build(self.name())
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::table())])
.switch("modifiers", "list of modifiers", Some('m')) .switch("modifiers", "list of modifiers", Some('m'))
.switch("keycodes", "list of keycodes", Some('k')) .switch("keycodes", "list of keycodes", Some('k'))
.switch("modes", "list of edit modes", Some('o')) .switch("modes", "list of edit modes", Some('o'))

View File

@ -6,7 +6,7 @@ use nu_protocol::{
report_error, HistoryFileFormat, PipelineData, report_error, HistoryFileFormat, PipelineData,
}; };
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
use nu_protocol::{ParseError, PluginCacheFile, Spanned}; use nu_protocol::{ParseError, PluginRegistryFile, Spanned};
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
use nu_utils::utils::perf; use nu_utils::utils::perf;
use std::path::PathBuf; use std::path::PathBuf;
@ -51,7 +51,7 @@ pub fn read_plugin_file(
} }
let mut start_time = std::time::Instant::now(); let mut start_time = std::time::Instant::now();
// Reading signatures from plugin cache file // Reading signatures from plugin registry file
// The plugin.msgpackz file stores the parsed signature collected from each registered plugin // The plugin.msgpackz file stores the parsed signature collected from each registered plugin
add_plugin_file(engine_state, plugin_file.clone(), storage_path); add_plugin_file(engine_state, plugin_file.clone(), storage_path);
perf( perf(
@ -89,7 +89,7 @@ pub fn read_plugin_file(
engine_state, engine_state,
&ShellError::GenericError { &ShellError::GenericError {
error: format!( error: format!(
"Error while opening plugin cache file: {}", "Error while opening plugin registry file: {}",
plugin_path.display() plugin_path.display()
), ),
msg: "plugin path defined here".into(), msg: "plugin path defined here".into(),
@ -113,15 +113,15 @@ pub fn read_plugin_file(
} }
// Read the contents of the plugin file // Read the contents of the plugin file
let contents = match PluginCacheFile::read_from(&mut file, span) { let contents = match PluginRegistryFile::read_from(&mut file, span) {
Ok(contents) => contents, Ok(contents) => contents,
Err(err) => { Err(err) => {
log::warn!("Failed to read plugin cache file: {err:?}"); log::warn!("Failed to read plugin registry file: {err:?}");
report_error_new( report_error_new(
engine_state, engine_state,
&ShellError::GenericError { &ShellError::GenericError {
error: format!( error: format!(
"Error while reading plugin cache file: {}", "Error while reading plugin registry file: {}",
plugin_path.display() plugin_path.display()
), ),
msg: "plugin path defined here".into(), msg: "plugin path defined here".into(),
@ -150,7 +150,7 @@ pub fn read_plugin_file(
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
nu_plugin::load_plugin_file(&mut working_set, &contents, span); nu_plugin_engine::load_plugin_file(&mut working_set, &contents, span);
if let Err(err) = engine_state.merge_delta(working_set.render()) { if let Err(err) = engine_state.merge_delta(working_set.render()) {
report_error_new(engine_state, &err); report_error_new(engine_state, &err);
@ -265,8 +265,8 @@ pub(crate) fn get_history_path(storage_path: &str, mode: HistoryFileFormat) -> O
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -> bool { pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -> bool {
use nu_protocol::{ use nu_protocol::{
report_error_new, PluginCacheItem, PluginCacheItemData, PluginExample, PluginIdentity, report_error_new, PluginExample, PluginIdentity, PluginRegistryItem,
PluginSignature, ShellError, PluginRegistryItemData, PluginSignature, ShellError,
}; };
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -318,7 +318,7 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -
} }
// Now that the plugin commands are loaded, we just have to generate the file // Now that the plugin commands are loaded, we just have to generate the file
let mut contents = PluginCacheFile::new(); let mut contents = PluginRegistryFile::new();
let mut groups = BTreeMap::<PluginIdentity, Vec<PluginSignature>>::new(); let mut groups = BTreeMap::<PluginIdentity, Vec<PluginSignature>>::new();
@ -339,11 +339,11 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -
} }
for (identity, commands) in groups { for (identity, commands) in groups {
contents.upsert_plugin(PluginCacheItem { contents.upsert_plugin(PluginRegistryItem {
name: identity.name().to_owned(), name: identity.name().to_owned(),
filename: identity.filename().to_owned(), filename: identity.filename().to_owned(),
shell: identity.shell().map(|p| p.to_owned()), shell: identity.shell().map(|p| p.to_owned()),
data: PluginCacheItemData::Valid { commands }, data: PluginRegistryItemData::Valid { commands },
}); });
} }

View File

@ -5,13 +5,11 @@ use nu_engine::{convert_env_values, current_dir, eval_block};
use nu_parser::parse; use nu_parser::parse;
use nu_path::canonicalize_with; use nu_path::canonicalize_with;
use nu_protocol::{ use nu_protocol::{
ast::Call,
debugger::WithoutDebug, debugger::WithoutDebug,
engine::{EngineState, Stack, StateWorkingSet}, engine::{EngineState, Stack, StateWorkingSet},
report_error, Config, PipelineData, ShellError, Span, Value, report_error, Config, PipelineData, ShellError, Span, Value,
}; };
use nu_utils::stdout_write_all_and_flush; use std::{io::Write, sync::Arc};
use std::sync::Arc;
/// Entry point for evaluating a file. /// Entry point for evaluating a file.
/// ///
@ -210,29 +208,8 @@ pub(crate) fn print_table_or_error(
std::process::exit(1); std::process::exit(1);
} }
if let Some(decl_id) = engine_state.find_decl("table".as_bytes(), &[]) { // We don't need to do anything special to print a table because print() handles it
let command = engine_state.get_decl(decl_id); print_or_exit(pipeline_data, engine_state, stack, no_newline);
if command.get_block_id().is_some() {
print_or_exit(pipeline_data, engine_state, config, no_newline);
} else {
// The final call on table command, it's ok to set redirect_output to false.
let call = Call::new(Span::new(0, 0));
let table = command.run(engine_state, stack, &call, pipeline_data);
match table {
Ok(table) => {
print_or_exit(table, engine_state, config, no_newline);
}
Err(error) => {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &error);
std::process::exit(1);
}
}
}
} else {
print_or_exit(pipeline_data, engine_state, config, no_newline);
}
// Make sure everything has finished // Make sure everything has finished
if let Some(exit_code) = exit_code { if let Some(exit_code) = exit_code {
@ -250,23 +227,19 @@ pub(crate) fn print_table_or_error(
fn print_or_exit( fn print_or_exit(
pipeline_data: PipelineData, pipeline_data: PipelineData,
engine_state: &mut EngineState, engine_state: &EngineState,
config: &Config, stack: &mut Stack,
no_newline: bool, no_newline: bool,
) { ) {
for item in pipeline_data { let result = pipeline_data.print(engine_state, stack, no_newline, false);
if let Value::Error { error, .. } = item {
let _ = std::io::stdout().flush();
let _ = std::io::stderr().flush();
if let Err(error) = result {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &error);
report_error(&working_set, &*error); let _ = std::io::stderr().flush();
std::process::exit(1); std::process::exit(1);
} }
let mut out = item.to_expanded_string("\n", config);
if !no_newline {
out.push('\n');
}
let _ = stdout_write_all_and_flush(out).map_err(|err| eprintln!("{err}"));
}
} }

View File

@ -361,7 +361,7 @@ fn find_matching_block_end_in_expr(
Expr::Nothing => None, Expr::Nothing => None,
Expr::Garbage => None, Expr::Garbage => None,
Expr::Table(hdr, rows) => { Expr::Table(table) => {
if expr_last == global_cursor_offset { if expr_last == global_cursor_offset {
// cursor is at table end // cursor is at table end
Some(expr_first) Some(expr_first)
@ -370,11 +370,11 @@ fn find_matching_block_end_in_expr(
Some(expr_last) Some(expr_last)
} else { } else {
// cursor is inside table // cursor is inside table
for inner_expr in hdr { for inner_expr in table.columns.as_ref() {
find_in_expr_or_continue!(inner_expr); find_in_expr_or_continue!(inner_expr);
} }
for row in rows { for row in table.rows.as_ref() {
for inner_expr in row { for inner_expr in row.as_ref() {
find_in_expr_or_continue!(inner_expr); find_in_expr_or_continue!(inner_expr);
} }
} }

View File

@ -5,15 +5,15 @@ 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.92.3" version = "0.93.1"
# 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.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.92.3" } nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.92.3" } nu-path = { path = "../nu-path", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
indexmap = { workspace = true } indexmap = { workspace = true }
miette = { workspace = true } miette = { workspace = true }

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT" license = "MIT"
name = "nu-cmd-dataframe" name = "nu-cmd-dataframe"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-dataframe" repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-dataframe"
version = "0.92.3" version = "0.93.1"
# 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.92.3"
bench = false bench = false
[dependencies] [dependencies]
nu-engine = { path = "../nu-engine", version = "0.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.92.3" } nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
# 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 }
@ -72,4 +72,4 @@ dataframe = ["num", "polars", "polars-io", "polars-arrow", "polars-ops", "polars
default = [] default = []
[dev-dependencies] [dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" } nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }

View File

@ -24,7 +24,7 @@ impl Command for ToNu {
.switch("tail", "shows tail rows", Some('t')) .switch("tail", "shows tail rows", Some('t'))
.input_output_types(vec![ .input_output_types(vec![
(Type::Custom("expression".into()), Type::Any), (Type::Custom("expression".into()), Type::Any),
(Type::Custom("dataframe".into()), Type::Table(vec![])), (Type::Custom("dataframe".into()), Type::table()),
]) ])
//.input_output_type(Type::Any, Type::Any) //.input_output_type(Type::Any, Type::Any)
.category(Category::Custom("dataframe".into())) .category(Category::Custom("dataframe".into()))

View File

@ -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.92.3" version = "0.93.1"
# 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.92.3"
bench = false bench = false
[dependencies] [dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.92.3" } nu-cmd-base = { path = "../nu-cmd-base", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-json = { version = "0.92.3", path = "../nu-json" } nu-json = { version = "0.93.1", path = "../nu-json" }
nu-parser = { path = "../nu-parser", version = "0.92.3" } nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-pretty-hex = { version = "0.92.3", path = "../nu-pretty-hex" } nu-pretty-hex = { version = "0.93.1", path = "../nu-pretty-hex" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.92.3" } nu-utils = { path = "../nu-utils", version = "0.93.1" }
# 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.92.3" } nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }
nu-command = { path = "../nu-command", version = "0.92.3" } nu-command = { path = "../nu-command", version = "0.93.1" }
nu-test-support = { path = "../nu-test-support", version = "0.92.3" } nu-test-support = { path = "../nu-test-support", version = "0.93.1" }

View File

@ -30,8 +30,8 @@ impl Command for BitsInto {
(Type::Duration, Type::String), (Type::Duration, Type::String),
(Type::String, Type::String), (Type::String, Type::String),
(Type::Bool, Type::String), (Type::Bool, Type::String),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) // TODO: supply exhaustive examples .allow_variants_without_examples(true) // TODO: supply exhaustive examples
.rest( .rest(
@ -64,7 +64,7 @@ impl Command for BitsInto {
vec![ vec![
Example { Example {
description: "convert a binary value into a string, padded to 8 places with 0s", description: "convert a binary value into a string, padded to 8 places with 0s",
example: "01b | into bits", example: "0x[1] | into bits",
result: Some(Value::string("00000001", result: Some(Value::string("00000001",
Span::test_data(), Span::test_data(),
)), )),

View File

@ -15,7 +15,7 @@ impl Command for Fmt {
fn signature(&self) -> nu_protocol::Signature { fn signature(&self) -> nu_protocol::Signature {
Signature::build("fmt") Signature::build("fmt")
.input_output_types(vec![(Type::Number, Type::Record(vec![]))]) .input_output_types(vec![(Type::Number, Type::record())])
.category(Category::Conversions) .category(Category::Conversions)
} }

View File

@ -16,7 +16,7 @@ impl Command for RollDown {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()) Signature::build(self.name())
// TODO: It also operates on List // TODO: It also operates on List
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))]) .input_output_types(vec![(Type::table(), Type::table())])
.named("by", SyntaxShape::Int, "Number of rows to roll", Some('b')) .named("by", SyntaxShape::Int, "Number of rows to roll", Some('b'))
.category(Category::Filters) .category(Category::Filters)
} }

View File

@ -16,8 +16,8 @@ impl Command for RollLeft {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()) Signature::build(self.name())
.input_output_types(vec![ .input_output_types(vec![
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
]) ])
.named( .named(
"by", "by",

View File

@ -16,8 +16,8 @@ impl Command for RollRight {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()) Signature::build(self.name())
.input_output_types(vec![ .input_output_types(vec![
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
]) ])
.named( .named(
"by", "by",

View File

@ -16,7 +16,7 @@ impl Command for RollUp {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()) Signature::build(self.name())
// TODO: It also operates on List // TODO: It also operates on List
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))]) .input_output_types(vec![(Type::table(), Type::table())])
.named("by", SyntaxShape::Int, "Number of rows to roll", Some('b')) .named("by", SyntaxShape::Int, "Number of rows to roll", Some('b'))
.category(Category::Filters) .category(Category::Filters)
} }

View File

@ -11,8 +11,8 @@ impl Command for Rotate {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("rotate") Signature::build("rotate")
.input_output_types(vec![ .input_output_types(vec![
(Type::Record(vec![]), Type::Table(vec![])), (Type::record(), Type::table()),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
]) ])
.switch("ccw", "rotate counter clockwise", None) .switch("ccw", "rotate counter clockwise", None)
.rest( .rest(

View File

@ -12,7 +12,7 @@ impl Command for UpdateCells {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("update cells") Signature::build("update cells")
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))]) .input_output_types(vec![(Type::table(), Type::table())])
.required( .required(
"closure", "closure",
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),

View File

@ -10,7 +10,7 @@ impl Command for FromUrl {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from url") Signature::build("from url")
.input_output_types(vec![(Type::String, Type::Record(vec![]))]) .input_output_types(vec![(Type::String, Type::record())])
.category(Category::Formats) .category(Category::Formats)
} }

View File

@ -46,8 +46,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.category(Category::Platform) .category(Category::Platform)

View File

@ -17,8 +17,8 @@ impl Command for DecodeHex {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -17,8 +17,8 @@ impl Command for EncodeHex {
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -13,8 +13,8 @@ impl Command for FormatPattern {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("format pattern") Signature::build("format pattern")
.input_output_types(vec![ .input_output_types(vec![
(Type::Table(vec![]), Type::List(Box::new(Type::String))), (Type::table(), Type::List(Box::new(Type::String))),
(Type::Record(vec![]), Type::Any), (Type::record(), Type::Any),
]) ])
.required( .required(
"pattern", "pattern",

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -14,8 +14,8 @@ impl Command for SubCommand {
Signature::build("str kebab-case") Signature::build("str kebab-case")
.input_output_types(vec![ .input_output_types(vec![
(Type::String, Type::String), (Type::String, Type::String),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
( (
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),

View File

@ -14,8 +14,8 @@ impl Command for SubCommand {
Signature::build("str pascal-case") Signature::build("str pascal-case")
.input_output_types(vec![ .input_output_types(vec![
(Type::String, Type::String), (Type::String, Type::String),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
( (
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -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.92.3" version = "0.93.1"
[lib] [lib]
bench = false bench = false
[dependencies] [dependencies]
nu-engine = { path = "../nu-engine", version = "0.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.92.3" } nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.92.3" } nu-utils = { path = "../nu-utils", version = "0.93.1" }
itertools = { workspace = true } itertools = { workspace = true }
shadow-rs = { version = "0.27", default-features = false } shadow-rs = { version = "0.27", default-features = false }

View File

@ -38,12 +38,12 @@ impl Command for Collect {
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let closure: Closure = call.req(engine_state, stack, 0)?; let closure: Closure = call.req(engine_state, stack, 0)?;
let block = engine_state.get_block(closure.block_id).clone(); let block = engine_state.get_block(closure.block_id);
let mut stack_captures = let mut stack_captures =
stack.captures_to_stack_preserve_out_dest(closure.captures.clone()); stack.captures_to_stack_preserve_out_dest(closure.captures.clone());
let metadata = input.metadata(); let metadata = input.metadata();
let input: Value = input.into_value(call.head); let input = input.into_value(call.head);
let mut saved_positional = None; let mut saved_positional = None;
if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
@ -58,7 +58,7 @@ impl Command for Collect {
let result = eval_block( let result = eval_block(
engine_state, engine_state,
&mut stack_captures, &mut stack_captures,
&block, block,
input.into_pipeline_data(), input.into_pipeline_data(),
) )
.map(|x| x.set_metadata(metadata)); .map(|x| x.set_metadata(metadata));

View File

@ -46,6 +46,19 @@ impl Command for Describe {
detailed: call.has_flag(engine_state, stack, "detailed")?, detailed: call.has_flag(engine_state, stack, "detailed")?,
collect_lazyrecords: call.has_flag(engine_state, stack, "collect-lazyrecords")?, collect_lazyrecords: call.has_flag(engine_state, stack, "collect-lazyrecords")?,
}; };
if options.collect_lazyrecords {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "Deprecated flag".into(),
msg: "the `--collect-lazyrecords` flag is deprecated, since lazy records will be removed in 0.94.0"
.into(),
span: Some(call.head),
help: None,
inner: vec![],
},
);
}
run(Some(engine_state), call, input, options) run(Some(engine_state), call, input, options)
} }

View File

@ -117,7 +117,7 @@ impl Command for Do {
None, None,
) )
}) })
.map_err(|e| e.into_spanned(call.head)) .err_span(call.head)
}) })
.transpose()?; .transpose()?;

View File

@ -41,11 +41,7 @@ impl Command for HideEnv {
for name in env_var_names { for name in env_var_names {
if !stack.remove_env_var(engine_state, &name.item) && !ignore_errors { if !stack.remove_env_var(engine_state, &name.item) && !ignore_errors {
let all_names: Vec<String> = stack let all_names = stack.get_env_var_names(engine_state);
.get_env_var_names(engine_state)
.iter()
.cloned()
.collect();
if let Some(closest_match) = did_you_mean(&all_names, &name.item) { if let Some(closest_match) = did_you_mean(&all_names, &name.item) {
return Err(ShellError::DidYouMeanCustom { return Err(ShellError::DidYouMeanCustom {
msg: format!("Environment variable '{}' not found", name.item), msg: format!("Environment variable '{}' not found", name.item),

View File

@ -59,17 +59,9 @@ impl Command for If {
.expect("internal error: missing block"); .expect("internal error: missing block");
let else_case = call.positional_nth(2); let else_case = call.positional_nth(2);
let result = eval_constant(working_set, cond)?; if eval_constant(working_set, cond)?.as_bool()? {
match &result {
Value::Bool { val, .. } => {
if *val {
let block = working_set.get_block(then_block); let block = working_set.get_block(then_block);
eval_const_subexpression( eval_const_subexpression(working_set, block, input, block.span.unwrap_or(call.head))
working_set,
block,
input,
block.span.unwrap_or(call.head),
)
} else if let Some(else_case) = else_case { } else if let Some(else_case) = else_case {
if let Some(else_expr) = else_case.as_keyword() { if let Some(else_expr) = else_case.as_keyword() {
if let Some(block_id) = else_expr.as_block() { if let Some(block_id) = else_expr.as_block() {
@ -90,14 +82,6 @@ impl Command for If {
Ok(PipelineData::empty()) Ok(PipelineData::empty())
} }
} }
x => Err(ShellError::CantConvert {
to_type: "bool".into(),
from_type: x.get_type().to_string(),
span: result.span(),
help: None,
}),
}
}
fn run( fn run(
&self, &self,
@ -118,10 +102,7 @@ impl Command for If {
let eval_expression_with_input = get_eval_expression_with_input(engine_state); let eval_expression_with_input = get_eval_expression_with_input(engine_state);
let eval_block = get_eval_block(engine_state); let eval_block = get_eval_block(engine_state);
let result = eval_expression(engine_state, stack, cond)?; if eval_expression(engine_state, stack, cond)?.as_bool()? {
match &result {
Value::Bool { val, .. } => {
if *val {
let block = engine_state.get_block(then_block); let block = engine_state.get_block(then_block);
eval_block(engine_state, stack, block, input) eval_block(engine_state, stack, block, input)
} else if let Some(else_case) = else_case { } else if let Some(else_case) = else_case {
@ -134,21 +115,12 @@ impl Command for If {
.map(|res| res.0) .map(|res| res.0)
} }
} else { } else {
eval_expression_with_input(engine_state, stack, else_case, input) eval_expression_with_input(engine_state, stack, else_case, input).map(|res| res.0)
.map(|res| res.0)
} }
} else { } else {
Ok(PipelineData::empty()) Ok(PipelineData::empty())
} }
} }
x => Err(ShellError::CantConvert {
to_type: "bool".into(),
from_type: x.get_type().to_string(),
span: result.span(),
help: None,
}),
}
}
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![ vec![

View File

@ -15,7 +15,7 @@ impl Command for LazyMake {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("lazy make") Signature::build("lazy make")
.input_output_types(vec![(Type::Nothing, Type::Record(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::record())])
.required_named( .required_named(
"columns", "columns",
SyntaxShape::List(Box::new(SyntaxShape::String)), SyntaxShape::List(Box::new(SyntaxShape::String)),
@ -54,6 +54,18 @@ impl Command for LazyMake {
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "Deprecated command".into(),
msg: "warning: lazy records and the `lazy make` command will be removed in 0.94.0"
.into(),
span: Some(call.head),
help: None,
inner: vec![],
},
);
let span = call.head; let span = call.head;
let columns: Vec<Spanned<String>> = call let columns: Vec<Spanned<String>> = call
.get_flag(engine_state, stack, "columns")? .get_flag(engine_state, stack, "columns")?

View File

@ -61,7 +61,7 @@ impl Command for Let {
let eval_block = get_eval_block(engine_state); let eval_block = get_eval_block(engine_state);
let stack = &mut stack.start_capture(); let stack = &mut stack.start_capture();
let pipeline_data = eval_block(engine_state, stack, block, input)?; let pipeline_data = eval_block(engine_state, stack, block, input)?;
let mut value = pipeline_data.into_value(call.head); let value = pipeline_data.into_value(call.head);
// if given variable type is Glob, and our result is string // if given variable type is Glob, and our result is string
// then nushell need to convert from Value::String to Value::Glob // then nushell need to convert from Value::String to Value::Glob
@ -69,12 +69,12 @@ impl Command for Let {
// if we pass it to other commands. // if we pass it to other commands.
let var_type = &engine_state.get_var(var_id).ty; let var_type = &engine_state.get_var(var_id).ty;
let val_span = value.span(); let val_span = value.span();
match value { let value = match value {
Value::String { val, .. } if var_type == &Type::Glob => { Value::String { val, .. } if var_type == &Type::Glob => {
value = Value::glob(val, false, val_span); Value::glob(val, false, val_span)
}
_ => {}
} }
value => value,
};
stack.add_var(var_id, value); stack.add_var(var_id, value);
Ok(PipelineData::empty()) Ok(PipelineData::empty())

View File

@ -1,10 +1,7 @@
use nu_engine::{ use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input, command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
}; };
use nu_protocol::{ use nu_protocol::engine::Matcher;
ast::{Expr, Expression},
engine::Matcher,
};
#[derive(Clone)] #[derive(Clone)]
pub struct Match; pub struct Match;
@ -38,25 +35,25 @@ impl Command for Match {
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let value: Value = call.req(engine_state, stack, 0)?; let value: Value = call.req(engine_state, stack, 0)?;
let block = call.positional_nth(1); let matches = call
.positional_nth(1)
.expect("checked through parser")
.as_match_block()
.expect("missing match block");
let eval_expression = get_eval_expression(engine_state); let eval_expression = get_eval_expression(engine_state);
let eval_expression_with_input = get_eval_expression_with_input(engine_state); let eval_expression_with_input = get_eval_expression_with_input(engine_state);
let eval_block = get_eval_block(engine_state); let eval_block = get_eval_block(engine_state);
if let Some(Expression {
expr: Expr::MatchBlock(matches),
..
}) = block
{
for match_ in matches {
let mut match_variables = vec![]; let mut match_variables = vec![];
if match_.0.match_value(&value, &mut match_variables) { for (pattern, expr) in matches {
if pattern.match_value(&value, &mut match_variables) {
// This case does match, go ahead and return the evaluated expression // This case does match, go ahead and return the evaluated expression
for match_variable in match_variables { for (id, value) in match_variables.drain(..) {
stack.add_var(match_variable.0, match_variable.1); stack.add_var(id, value);
} }
let guard_matches = if let Some(guard) = &match_.0.guard { let guard_matches = if let Some(guard) = &pattern.guard {
let Value::Bool { val, .. } = eval_expression(engine_state, stack, guard)? let Value::Bool { val, .. } = eval_expression(engine_state, stack, guard)?
else { else {
return Err(ShellError::MatchGuardNotBool { span: guard.span }); return Err(ShellError::MatchGuardNotBool { span: guard.span });
@ -68,15 +65,15 @@ impl Command for Match {
}; };
if guard_matches { if guard_matches {
return if let Some(block_id) = match_.1.as_block() { return if let Some(block_id) = expr.as_block() {
let block = engine_state.get_block(block_id); let block = engine_state.get_block(block_id);
eval_block(engine_state, stack, block, input) eval_block(engine_state, stack, block, input)
} else { } else {
eval_expression_with_input(engine_state, stack, &match_.1, input) eval_expression_with_input(engine_state, stack, expr, input).map(|x| x.0)
.map(|x| x.0)
}; };
} }
} } else {
match_variables.clear();
} }
} }

View File

@ -61,7 +61,7 @@ impl Command for Mut {
let eval_block = get_eval_block(engine_state); let eval_block = get_eval_block(engine_state);
let stack = &mut stack.start_capture(); let stack = &mut stack.start_capture();
let pipeline_data = eval_block(engine_state, stack, block, input)?; let pipeline_data = eval_block(engine_state, stack, block, input)?;
let mut value = pipeline_data.into_value(call.head); let value = pipeline_data.into_value(call.head);
// if given variable type is Glob, and our result is string // if given variable type is Glob, and our result is string
// then nushell need to convert from Value::String to Value::Glob // then nushell need to convert from Value::String to Value::Glob
@ -69,12 +69,12 @@ impl Command for Mut {
// if we pass it to other commands. // if we pass it to other commands.
let var_type = &engine_state.get_var(var_id).ty; let var_type = &engine_state.get_var(var_id).ty;
let val_span = value.span(); let val_span = value.span();
match value { let value = match value {
Value::String { val, .. } if var_type == &Type::Glob => { Value::String { val, .. } if var_type == &Type::Glob => {
value = Value::glob(val, false, val_span); Value::glob(val, false, val_span)
}
_ => {}
} }
value => value,
};
stack.add_var(var_id, value); stack.add_var(var_id, value);
Ok(PipelineData::empty()) Ok(PipelineData::empty())

View File

@ -40,17 +40,11 @@ impl Command for Return {
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let return_value: Option<Value> = call.opt(engine_state, stack, 0)?; let return_value: Option<Value> = call.opt(engine_state, stack, 0)?;
if let Some(value) = return_value { let value = return_value.unwrap_or(Value::nothing(call.head));
Err(ShellError::Return { Err(ShellError::Return {
span: call.head, span: call.head,
value: Box::new(value), value: Box::new(value),
}) })
} else {
Err(ShellError::Return {
span: call.head,
value: Box::new(Value::nothing(call.head)),
})
}
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -49,9 +49,7 @@ impl Command for Try {
let try_block = engine_state.get_block(try_block); let try_block = engine_state.get_block(try_block);
let eval_block = get_eval_block(engine_state); let eval_block = get_eval_block(engine_state);
let result = eval_block(engine_state, stack, try_block, input); match eval_block(engine_state, stack, try_block, input) {
match result {
Err(error) => { Err(error) => {
let error = intercept_block_control(error)?; let error = intercept_block_control(error)?;
let err_record = err_to_record(error, call.head); let err_record = err_to_record(error, call.head);
@ -66,9 +64,8 @@ impl Command for Try {
Ok(pipeline) => { Ok(pipeline) => {
let (pipeline, external_failed) = pipeline.check_external_failed(); let (pipeline, external_failed) = pipeline.check_external_failed();
if external_failed { if external_failed {
// Because external command errors aren't "real" errors, let exit_code = pipeline.drain_with_exit_code()?;
// (unless do -c is in effect) stack.add_env_var("LAST_EXIT_CODE".into(), Value::int(exit_code, call.head));
// they can't be passed in as Nushell values.
let err_value = Value::nothing(call.head); let err_value = Value::nothing(call.head);
handle_catch(err_value, catch_block, engine_state, stack, eval_block) handle_catch(err_value, catch_block, engine_state, stack, eval_block)
} else { } else {

View File

@ -16,7 +16,7 @@ impl Command for Version {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("version") Signature::build("version")
.input_output_types(vec![(Type::Nothing, Type::Record(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::record())])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.category(Category::Core) .category(Category::Core)
} }
@ -36,7 +36,7 @@ impl Command for Version {
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
version(engine_state, call) version(engine_state, call.head)
} }
fn run_const( fn run_const(
@ -45,7 +45,7 @@ impl Command for Version {
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
version(working_set.permanent(), call) version(working_set.permanent(), call.head)
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
@ -57,7 +57,13 @@ impl Command for Version {
} }
} }
pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData, ShellError> { fn push_non_empty(record: &mut Record, name: &str, value: &str, span: Span) {
if !value.is_empty() {
record.push(name, Value::string(value, span))
}
}
pub fn version(engine_state: &EngineState, span: Span) -> Result<PipelineData, ShellError> {
// Pre-allocate the arrays in the worst case (17 items): // Pre-allocate the arrays in the worst case (17 items):
// - version // - version
// - major // - major
@ -69,6 +75,7 @@ pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData,
// - build_os // - build_os
// - build_target // - build_target
// - rust_version // - rust_version
// - rust_channel
// - cargo_version // - cargo_version
// - build_time // - build_time
// - build_rust_channel // - build_rust_channel
@ -77,68 +84,36 @@ pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData,
// - installed_plugins // - installed_plugins
let mut record = Record::with_capacity(17); let mut record = Record::with_capacity(17);
record.push( record.push("version", Value::string(env!("CARGO_PKG_VERSION"), span));
"version",
Value::string(env!("CARGO_PKG_VERSION"), call.head),
);
push_version_numbers(&mut record, call.head); push_version_numbers(&mut record, span);
let version_pre = Some(build::PKG_VERSION_PRE).filter(|x| !x.is_empty()); push_non_empty(&mut record, "pre", build::PKG_VERSION_PRE, span);
if let Some(version_pre) = version_pre {
record.push("pre", Value::string(version_pre, call.head)); record.push("branch", Value::string(build::BRANCH, span));
if let Some(commit_hash) = option_env!("NU_COMMIT_HASH") {
record.push("commit_hash", Value::string(commit_hash, span));
} }
record.push("branch", Value::string(build::BRANCH, call.head)); push_non_empty(&mut record, "build_os", build::BUILD_OS, span);
push_non_empty(&mut record, "build_target", build::BUILD_TARGET, span);
let commit_hash = option_env!("NU_COMMIT_HASH"); push_non_empty(&mut record, "rust_version", build::RUST_VERSION, span);
if let Some(commit_hash) = commit_hash { push_non_empty(&mut record, "rust_channel", build::RUST_CHANNEL, span);
record.push("commit_hash", Value::string(commit_hash, call.head)); push_non_empty(&mut record, "cargo_version", build::CARGO_VERSION, span);
} push_non_empty(&mut record, "build_time", build::BUILD_TIME, span);
push_non_empty(
let build_os = Some(build::BUILD_OS).filter(|x| !x.is_empty()); &mut record,
if let Some(build_os) = build_os {
record.push("build_os", Value::string(build_os, call.head));
}
let build_target = Some(build::BUILD_TARGET).filter(|x| !x.is_empty());
if let Some(build_target) = build_target {
record.push("build_target", Value::string(build_target, call.head));
}
let rust_version = Some(build::RUST_VERSION).filter(|x| !x.is_empty());
if let Some(rust_version) = rust_version {
record.push("rust_version", Value::string(rust_version, call.head));
}
let rust_channel = Some(build::RUST_CHANNEL).filter(|x| !x.is_empty());
if let Some(rust_channel) = rust_channel {
record.push("rust_channel", Value::string(rust_channel, call.head));
}
let cargo_version = Some(build::CARGO_VERSION).filter(|x| !x.is_empty());
if let Some(cargo_version) = cargo_version {
record.push("cargo_version", Value::string(cargo_version, call.head));
}
let build_time = Some(build::BUILD_TIME).filter(|x| !x.is_empty());
if let Some(build_time) = build_time {
record.push("build_time", Value::string(build_time, call.head));
}
let build_rust_channel = Some(build::BUILD_RUST_CHANNEL).filter(|x| !x.is_empty());
if let Some(build_rust_channel) = build_rust_channel {
record.push(
"build_rust_channel", "build_rust_channel",
Value::string(build_rust_channel, call.head), build::BUILD_RUST_CHANNEL,
span,
); );
}
record.push("allocator", Value::string(global_allocator(), call.head)); record.push("allocator", Value::string(global_allocator(), span));
record.push( record.push(
"features", "features",
Value::string(features_enabled().join(", "), call.head), Value::string(features_enabled().join(", "), span),
); );
// Get a list of plugin names // Get a list of plugin names
@ -150,10 +125,10 @@ pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData,
record.push( record.push(
"installed_plugins", "installed_plugins",
Value::string(installed_plugins.join(", "), call.head), Value::string(installed_plugins.join(", "), span),
); );
Ok(Value::record(record, call.head).into_pipeline_data()) Ok(Value::record(record, span).into_pipeline_data())
} }
/// Add version numbers as integers to the given record /// Add version numbers as integers to the given record
@ -167,9 +142,9 @@ fn push_version_numbers(record: &mut Record, head: Span) {
build::PKG_VERSION_PATCH.parse().expect("Always set"), build::PKG_VERSION_PATCH.parse().expect("Always set"),
) )
}); });
record.push("major", Value::int(major as _, head)); record.push("major", Value::int(major.into(), head));
record.push("minor", Value::int(minor as _, head)); record.push("minor", Value::int(minor.into(), head));
record.push("patch", Value::int(patch as _, head)); record.push("patch", Value::int(patch.into(), head));
} }
fn global_allocator() -> &'static str { fn global_allocator() -> &'static str {

View File

@ -5,15 +5,15 @@ 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.92.3" version = "0.93.1"
# 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.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.92.3" } nu-path = { path = "../nu-path", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3", features = ["plugin"] } nu-protocol = { path = "../nu-protocol", version = "0.93.1", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.92.3" } nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.93.1" }
itertools = { workspace = true } itertools = { workspace = true }

View File

@ -1,10 +1,10 @@
use std::sync::Arc; use std::sync::Arc;
use nu_engine::{command_prelude::*, current_dir}; use nu_engine::{command_prelude::*, current_dir};
use nu_plugin::{GetPlugin, PersistentPlugin}; use nu_plugin_engine::{GetPlugin, PersistentPlugin};
use nu_protocol::{PluginCacheItem, PluginGcConfig, PluginIdentity, RegisteredPlugin}; use nu_protocol::{PluginGcConfig, PluginIdentity, PluginRegistryItem, RegisteredPlugin};
use crate::util::modify_plugin_file; use crate::util::{get_plugin_dirs, modify_plugin_file};
#[derive(Clone)] #[derive(Clone)]
pub struct PluginAdd; pub struct PluginAdd;
@ -21,7 +21,7 @@ impl Command for PluginAdd {
.named( .named(
"plugin-config", "plugin-config",
SyntaxShape::Filepath, SyntaxShape::Filepath,
"Use a plugin cache file other than the one set in `$nu.plugin-path`", "Use a plugin registry file other than the one set in `$nu.plugin-path`",
None, None,
) )
.named( .named(
@ -39,7 +39,7 @@ impl Command for PluginAdd {
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
"Add a plugin to the plugin cache file." "Add a plugin to the plugin registry file."
} }
fn extra_usage(&self) -> &str { fn extra_usage(&self) -> &str {
@ -47,14 +47,14 @@ impl Command for PluginAdd {
This does not load the plugin commands into the scope - see `register` for that. This does not load the plugin commands into the scope - see `register` for that.
Instead, it runs the plugin to get its command signatures, and then edits the Instead, it runs the plugin to get its command signatures, and then edits the
plugin cache file (by default, `$nu.plugin-path`). The changes will be plugin registry file (by default, `$nu.plugin-path`). The changes will be
apparent the next time `nu` is next launched with that plugin cache file. apparent the next time `nu` is next launched with that plugin registry file.
"# "#
.trim() .trim()
} }
fn search_terms(&self) -> Vec<&str> { fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "add", "register", "load", "signature"] vec!["load", "register", "signature"]
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
@ -66,7 +66,7 @@ apparent the next time `nu` is next launched with that plugin cache file.
}, },
Example { Example {
example: "plugin add --plugin-config polars.msgpackz nu_plugin_polars", example: "plugin add --plugin-config polars.msgpackz nu_plugin_polars",
description: "Run the `nu_plugin_polars` plugin from the current directory or $env.NU_PLUGIN_DIRS, and install its signatures to the \"polars.msgpackz\" plugin cache file.", description: "Run the `nu_plugin_polars` plugin from the current directory or $env.NU_PLUGIN_DIRS, and install its signatures to the \"polars.msgpackz\" plugin registry file.",
result: None, result: None,
}, },
] ]
@ -85,30 +85,14 @@ apparent the next time `nu` is next launched with that plugin cache file.
let cwd = current_dir(engine_state, stack)?; let cwd = current_dir(engine_state, stack)?;
// Check the current directory, or fall back to NU_PLUGIN_DIRS // Check the current directory, or fall back to NU_PLUGIN_DIRS
let filename_expanded = match nu_path::canonicalize_with(&filename.item, &cwd) { let filename_expanded = nu_path::locate_in_dirs(&filename.item, &cwd, || {
Ok(path) => path, get_plugin_dirs(engine_state, stack)
Err(err) => { })
// Try to find it in NU_PLUGIN_DIRS first, before giving up .err_span(filename.span)?;
let mut found = None;
if let Some(nu_plugin_dirs) = stack.get_env_var(engine_state, "NU_PLUGIN_DIRS") {
for dir in nu_plugin_dirs.into_list().unwrap_or(vec![]) {
if let Ok(path) = nu_path::canonicalize_with(dir.as_str()?, &cwd)
.and_then(|dir| nu_path::canonicalize_with(&filename.item, dir))
{
found = Some(path);
break;
}
}
}
found.ok_or(err.into_spanned(filename.span))?
}
};
let shell_expanded = shell let shell_expanded = shell
.as_ref() .as_ref()
.map(|s| { .map(|s| nu_path::canonicalize_with(&s.item, &cwd).err_span(s.span))
nu_path::canonicalize_with(&s.item, &cwd).map_err(|err| err.into_spanned(s.span))
})
.transpose()?; .transpose()?;
// Parse the plugin filename so it can be used to spawn the plugin // Parse the plugin filename so it can be used to spawn the plugin
@ -138,7 +122,7 @@ apparent the next time `nu` is next launched with that plugin cache file.
modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| { modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| {
// Update the file with the received signatures // Update the file with the received signatures
let item = PluginCacheItem::new(plugin.identity(), commands); let item = PluginRegistryItem::new(plugin.identity(), commands);
contents.upsert_plugin(item); contents.upsert_plugin(item);
Ok(()) Ok(())
})?; })?;

View File

@ -13,14 +13,17 @@ impl Command for PluginList {
Signature::build("plugin list") Signature::build("plugin list")
.input_output_type( .input_output_type(
Type::Nothing, Type::Nothing,
Type::Table(vec![ Type::Table(
[
("name".into(), Type::String), ("name".into(), Type::String),
("is_running".into(), Type::Bool), ("is_running".into(), Type::Bool),
("pid".into(), Type::Int), ("pid".into(), Type::Int),
("filename".into(), Type::String), ("filename".into(), Type::String),
("shell".into(), Type::String), ("shell".into(), Type::String),
("commands".into(), Type::List(Type::String.into())), ("commands".into(), Type::List(Type::String.into())),
]), ]
.into(),
),
) )
.category(Category::Plugin) .category(Category::Plugin)
} }
@ -29,6 +32,10 @@ impl Command for PluginList {
"List installed plugins." "List installed plugins."
} }
fn search_terms(&self) -> Vec<&str> {
vec!["scope"]
}
fn examples(&self) -> Vec<nu_protocol::Example> { fn examples(&self) -> Vec<nu_protocol::Example> {
vec![ vec![
Example { Example {

View File

@ -4,11 +4,13 @@ mod add;
mod list; mod list;
mod rm; mod rm;
mod stop; mod stop;
mod use_;
pub use add::PluginAdd; pub use add::PluginAdd;
pub use list::PluginList; pub use list::PluginList;
pub use rm::PluginRm; pub use rm::PluginRm;
pub use stop::PluginStop; pub use stop::PluginStop;
pub use use_::PluginUse;
#[derive(Clone)] #[derive(Clone)]
pub struct PluginCommand; pub struct PluginCommand;
@ -28,10 +30,6 @@ impl Command for PluginCommand {
"Commands for managing plugins." "Commands for managing plugins."
} }
fn extra_usage(&self) -> &str {
"To load a plugin, see `register`."
}
fn run( fn run(
&self, &self,
engine_state: &EngineState, engine_state: &EngineState,
@ -54,6 +52,21 @@ impl Command for PluginCommand {
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![ vec![
Example {
example: "plugin add nu_plugin_inc",
description: "Run the `nu_plugin_inc` plugin from the current directory and install its signatures.",
result: None,
},
Example {
example: "plugin use inc",
description: "
Load (or reload) the `inc` plugin from the plugin registry file and put its
commands in scope. The plugin must already be in the registry file at parse
time.
"
.trim(),
result: None,
},
Example { Example {
example: "plugin list", example: "plugin list",
description: "List installed plugins", description: "List installed plugins",
@ -64,11 +77,6 @@ impl Command for PluginCommand {
description: "Stop the plugin named `inc`.", description: "Stop the plugin named `inc`.",
result: None, result: None,
}, },
Example {
example: "plugin add nu_plugin_inc",
description: "Run the `nu_plugin_inc` plugin from the current directory and install its signatures.",
result: None,
},
Example { Example {
example: "plugin rm inc", example: "plugin rm inc",
description: "Remove the installed signatures for the `inc` plugin.", description: "Remove the installed signatures for the `inc` plugin.",

View File

@ -1,6 +1,6 @@
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use crate::util::modify_plugin_file; use crate::util::{canonicalize_possible_filename_arg, modify_plugin_file};
#[derive(Clone)] #[derive(Clone)]
pub struct PluginRm; pub struct PluginRm;
@ -17,7 +17,7 @@ impl Command for PluginRm {
.named( .named(
"plugin-config", "plugin-config",
SyntaxShape::Filepath, SyntaxShape::Filepath,
"Use a plugin cache file other than the one set in `$nu.plugin-path`", "Use a plugin registry file other than the one set in `$nu.plugin-path`",
None, None,
) )
.switch( .switch(
@ -28,21 +28,21 @@ impl Command for PluginRm {
.required( .required(
"name", "name",
SyntaxShape::String, SyntaxShape::String,
"The name of the plugin to remove (not the filename)", "The name, or filename, of the plugin to remove",
) )
.category(Category::Plugin) .category(Category::Plugin)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
"Remove a plugin from the plugin cache file." "Remove a plugin from the plugin registry file."
} }
fn extra_usage(&self) -> &str { fn extra_usage(&self) -> &str {
r#" r#"
This does not remove the plugin commands from the current scope or from `plugin This does not remove the plugin commands from the current scope or from `plugin
list` in the current shell. It instead removes the plugin from the plugin list` in the current shell. It instead removes the plugin from the plugin
cache file (by default, `$nu.plugin-path`). The changes will be apparent the registry file (by default, `$nu.plugin-path`). The changes will be apparent the
next time `nu` is launched with that plugin cache file. next time `nu` is launched with that plugin registry file.
This can be useful for removing an invalid plugin signature, if it can't be This can be useful for removing an invalid plugin signature, if it can't be
fixed with `plugin add`. fixed with `plugin add`.
@ -51,7 +51,7 @@ fixed with `plugin add`.
} }
fn search_terms(&self) -> Vec<&str> { fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "rm", "remove", "delete", "signature"] vec!["remove", "delete", "signature"]
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
@ -61,9 +61,14 @@ fixed with `plugin add`.
description: "Remove the installed signatures for the `inc` plugin.", description: "Remove the installed signatures for the `inc` plugin.",
result: None, result: None,
}, },
Example {
example: "plugin rm ~/.cargo/bin/nu_plugin_inc",
description: "Remove the installed signatures for the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
result: None,
},
Example { Example {
example: "plugin rm --plugin-config polars.msgpackz polars", example: "plugin rm --plugin-config polars.msgpackz polars",
description: "Remove the installed signatures for the `polars` plugin from the \"polars.msgpackz\" plugin cache file.", description: "Remove the installed signatures for the `polars` plugin from the \"polars.msgpackz\" plugin registry file.",
result: None, result: None,
}, },
] ]
@ -80,18 +85,26 @@ fixed with `plugin add`.
let custom_path = call.get_flag(engine_state, stack, "plugin-config")?; let custom_path = call.get_flag(engine_state, stack, "plugin-config")?;
let force = call.has_flag(engine_state, stack, "force")?; let force = call.has_flag(engine_state, stack, "force")?;
let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| { modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| {
if !force && !contents.plugins.iter().any(|p| p.name == name.item) { if let Some(index) = contents
.plugins
.iter()
.position(|p| p.name == name.item || p.filename == filename)
{
contents.plugins.remove(index);
Ok(())
} else if force {
Ok(())
} else {
Err(ShellError::GenericError { Err(ShellError::GenericError {
error: format!("Failed to remove the `{}` plugin", name.item), error: format!("Failed to remove the `{}` plugin", name.item),
msg: "couldn't find a plugin with this name in the cache file".into(), msg: "couldn't find a plugin with this name in the registry file".into(),
span: Some(name.span), span: Some(name.span),
help: None, help: None,
inner: vec![], inner: vec![],
}) })
} else {
contents.remove_plugin(&name.item);
Ok(())
} }
})?; })?;

View File

@ -1,5 +1,7 @@
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use crate::util::canonicalize_possible_filename_arg;
#[derive(Clone)] #[derive(Clone)]
pub struct PluginStop; pub struct PluginStop;
@ -14,7 +16,7 @@ impl Command for PluginStop {
.required( .required(
"name", "name",
SyntaxShape::String, SyntaxShape::String,
"The name of the plugin to stop.", "The name, or filename, of the plugin to stop",
) )
.category(Category::Plugin) .category(Category::Plugin)
} }
@ -30,6 +32,11 @@ impl Command for PluginStop {
description: "Stop the plugin named `inc`.", description: "Stop the plugin named `inc`.",
result: None, result: None,
}, },
Example {
example: "plugin stop ~/.cargo/bin/nu_plugin_inc",
description: "Stop the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
result: None,
},
Example { Example {
example: "plugin list | each { |p| plugin stop $p.name }", example: "plugin list | each { |p| plugin stop $p.name }",
description: "Stop all plugins.", description: "Stop all plugins.",
@ -47,9 +54,12 @@ impl Command for PluginStop {
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let name: Spanned<String> = call.req(engine_state, stack, 0)?; let name: Spanned<String> = call.req(engine_state, stack, 0)?;
let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
let mut found = false; let mut found = false;
for plugin in engine_state.plugins() { for plugin in engine_state.plugins() {
if plugin.identity().name() == name.item { let id = &plugin.identity();
if id.name() == name.item || id.filename() == filename {
plugin.stop()?; plugin.stop()?;
found = true; found = true;
} }

View File

@ -0,0 +1,89 @@
use nu_engine::command_prelude::*;
#[derive(Clone)]
pub struct PluginUse;
impl Command for PluginUse {
fn name(&self) -> &str {
"plugin use"
}
fn usage(&self) -> &str {
"Load a plugin from the plugin registry file into scope."
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build(self.name())
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.named(
"plugin-config",
SyntaxShape::Filepath,
"Use a plugin registry file other than the one set in `$nu.plugin-path`",
None,
)
.required(
"name",
SyntaxShape::String,
"The name, or filename, of the plugin to load",
)
.category(Category::Plugin)
}
fn extra_usage(&self) -> &str {
r#"
This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html
The plugin definition must be available in the plugin registry file at parse
time. Run `plugin add` first in the REPL to do this, or from a script consider
preparing a plugin registry file and passing `--plugin-config`, or using the
`--plugin` option to `nu` instead.
If the plugin was already loaded, this will reload the latest definition from
the registry file into scope.
Note that even if the plugin filename is specified, it will only be loaded if
it was already previously registered with `plugin add`.
"#
.trim()
}
fn search_terms(&self) -> Vec<&str> {
vec!["add", "register", "scope"]
}
fn is_parser_keyword(&self) -> bool {
true
}
fn run(
&self,
_engine_state: &EngineState,
_stack: &mut Stack,
_call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(PipelineData::empty())
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Load the commands for the `query` plugin from $nu.plugin-path",
example: r#"plugin use query"#,
result: None,
},
Example {
description: "Load the commands for the plugin with the filename `~/.cargo/bin/nu_plugin_query` from $nu.plugin-path",
example: r#"plugin use ~/.cargo/bin/nu_plugin_query"#,
result: None,
},
Example {
description:
"Load the commands for the `query` plugin from a custom plugin registry file",
example: r#"plugin use --plugin-config local-plugins.msgpackz query"#,
result: None,
},
]
}
}

View File

@ -35,12 +35,17 @@ impl Command for Register {
} }
fn extra_usage(&self) -> &str { fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check: r#"
https://www.nushell.sh/book/thinking_in_nu.html"# Deprecated in favor of `plugin add` and `plugin use`.
This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html
"#
.trim()
} }
fn search_terms(&self) -> Vec<&str> { fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "add", "register"] vec!["add"]
} }
fn is_parser_keyword(&self) -> bool { fn is_parser_keyword(&self) -> bool {

View File

@ -12,11 +12,12 @@ pub fn add_plugin_command_context(mut engine_state: EngineState) -> EngineState
} }
bind_command!( bind_command!(
PluginCommand,
PluginAdd, PluginAdd,
PluginCommand,
PluginList, PluginList,
PluginRm, PluginRm,
PluginStop, PluginStop,
PluginUse,
Register, Register,
); );

View File

@ -1,25 +1,28 @@
use std::fs::{self, File}; use std::{
fs::{self, File},
path::PathBuf,
};
use nu_engine::{command_prelude::*, current_dir}; use nu_engine::{command_prelude::*, current_dir};
use nu_protocol::PluginCacheFile; use nu_protocol::{engine::StateWorkingSet, PluginRegistryFile};
pub(crate) fn modify_plugin_file( pub(crate) fn modify_plugin_file(
engine_state: &EngineState, engine_state: &EngineState,
stack: &mut Stack, stack: &mut Stack,
span: Span, span: Span,
custom_path: Option<Spanned<String>>, custom_path: Option<Spanned<String>>,
operate: impl FnOnce(&mut PluginCacheFile) -> Result<(), ShellError>, operate: impl FnOnce(&mut PluginRegistryFile) -> Result<(), ShellError>,
) -> Result<(), ShellError> { ) -> Result<(), ShellError> {
let cwd = current_dir(engine_state, stack)?; let cwd = current_dir(engine_state, stack)?;
let plugin_cache_file_path = if let Some(ref custom_path) = custom_path { let plugin_registry_file_path = if let Some(ref custom_path) = custom_path {
nu_path::expand_path_with(&custom_path.item, cwd, true) nu_path::expand_path_with(&custom_path.item, cwd, true)
} else { } else {
engine_state engine_state
.plugin_path .plugin_path
.clone() .clone()
.ok_or_else(|| ShellError::GenericError { .ok_or_else(|| ShellError::GenericError {
error: "Plugin cache file not set".into(), error: "Plugin registry file not set".into(),
msg: "pass --plugin-config explicitly here".into(), msg: "pass --plugin-config explicitly here".into(),
span: Some(span), span: Some(span),
help: Some("you may be running `nu` with --no-config-file".into()), help: Some("you may be running `nu` with --no-config-file".into()),
@ -28,13 +31,13 @@ pub(crate) fn modify_plugin_file(
}; };
// Try to read the plugin file if it exists // Try to read the plugin file if it exists
let mut contents = if fs::metadata(&plugin_cache_file_path).is_ok_and(|m| m.len() > 0) { let mut contents = if fs::metadata(&plugin_registry_file_path).is_ok_and(|m| m.len() > 0) {
PluginCacheFile::read_from( PluginRegistryFile::read_from(
File::open(&plugin_cache_file_path).map_err(|err| err.into_spanned(span))?, File::open(&plugin_registry_file_path).err_span(span)?,
Some(span), Some(span),
)? )?
} else { } else {
PluginCacheFile::default() PluginRegistryFile::default()
}; };
// Do the operation // Do the operation
@ -42,9 +45,45 @@ pub(crate) fn modify_plugin_file(
// Save the modified file on success // Save the modified file on success
contents.write_to( contents.write_to(
File::create(&plugin_cache_file_path).map_err(|err| err.into_spanned(span))?, File::create(&plugin_registry_file_path).err_span(span)?,
Some(span), Some(span),
)?; )?;
Ok(()) Ok(())
} }
pub(crate) fn canonicalize_possible_filename_arg(
engine_state: &EngineState,
stack: &Stack,
arg: &str,
) -> PathBuf {
// This results in the best possible chance of a match with the plugin item
if let Ok(cwd) = nu_engine::current_dir(engine_state, stack) {
let path = nu_path::expand_path_with(arg, &cwd, true);
// Try to canonicalize
nu_path::locate_in_dirs(&path, &cwd, || get_plugin_dirs(engine_state, stack))
// If we couldn't locate it, return the expanded path alone
.unwrap_or(path)
} else {
arg.into()
}
}
pub(crate) fn get_plugin_dirs(
engine_state: &EngineState,
stack: &Stack,
) -> impl Iterator<Item = String> {
// Get the NU_PLUGIN_DIRS constant or env var
let working_set = StateWorkingSet::new(engine_state);
let value = working_set
.find_variable(b"$NU_PLUGIN_DIRS")
.and_then(|var_id| working_set.get_constant(var_id).ok().cloned())
.or_else(|| stack.get_env_var(engine_state, "NU_PLUGIN_DIRS"));
// Get all of the strings in the list, if possible
value
.into_iter()
.flat_map(|value| value.into_list().ok())
.flatten()
.flat_map(|list_item| list_item.coerce_into_string().ok())
}

View File

@ -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.92.3" version = "0.93.1"
[lib] [lib]
bench = false bench = false
[dependencies] [dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-json = { path = "../nu-json", version = "0.92.3" } nu-json = { path = "../nu-json", version = "0.93.1" }
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.92.3" } nu-test-support = { path = "../nu-test-support", version = "0.93.1" }

View File

@ -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.92.3" version = "0.93.1"
# 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,25 +13,26 @@ version = "0.92.3"
bench = false bench = false
[dependencies] [dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.92.3" } nu-cmd-base = { path = "../nu-cmd-base", version = "0.93.1" }
nu-color-config = { path = "../nu-color-config", version = "0.92.3" } nu-color-config = { path = "../nu-color-config", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.92.3" } nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-glob = { path = "../nu-glob", version = "0.92.3" } nu-glob = { path = "../nu-glob", version = "0.93.1" }
nu-json = { path = "../nu-json", version = "0.92.3" } nu-json = { path = "../nu-json", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.92.3" } nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.92.3" } nu-path = { path = "../nu-path", version = "0.93.1" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.92.3" } nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" } nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-system = { path = "../nu-system", version = "0.92.3" } nu-system = { path = "../nu-system", version = "0.93.1" }
nu-table = { path = "../nu-table", version = "0.92.3" } nu-table = { path = "../nu-table", version = "0.93.1" }
nu-term-grid = { path = "../nu-term-grid", version = "0.92.3" } nu-term-grid = { path = "../nu-term-grid", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.92.3" } nu-utils = { path = "../nu-utils", version = "0.93.1" }
nu-ansi-term = { workspace = true } nu-ansi-term = { workspace = true }
nuon = { path = "../nuon", version = "0.92.3" } nuon = { path = "../nuon", version = "0.93.1" }
alphanumeric-sort = { workspace = true } alphanumeric-sort = { workspace = true }
base64 = { workspace = true } base64 = { workspace = true }
bracoxide = { workspace = true } bracoxide = { workspace = true }
brotli = { workspace = true }
byteorder = { workspace = true } byteorder = { workspace = true }
bytesize = { workspace = true } bytesize = { workspace = true }
calamine = { workspace = true, features = ["dates"] } calamine = { workspace = true, features = ["dates"] }
@ -74,6 +75,7 @@ rayon = { workspace = true }
regex = { workspace = true } regex = { workspace = true }
roxmltree = { workspace = true } roxmltree = { workspace = true }
rusqlite = { workspace = true, features = ["bundled", "backup", "chrono"], optional = true } rusqlite = { workspace = true, features = ["bundled", "backup", "chrono"], optional = true }
rmp = { workspace = true }
same-file = { workspace = true } same-file = { workspace = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = ["preserve_order"] } serde_json = { workspace = true, features = ["preserve_order"] }
@ -135,11 +137,12 @@ trash-support = ["trash"]
which-support = ["which"] which-support = ["which"]
[dev-dependencies] [dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" } nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }
nu-test-support = { path = "../nu-test-support", version = "0.92.3" } nu-test-support = { path = "../nu-test-support", version = "0.93.1" }
dirs-next = { workspace = true } dirs-next = { workspace = true }
mockito = { workspace = true, default-features = false } mockito = { workspace = true, default-features = false }
quickcheck = { workspace = true } 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 }

View File

@ -31,8 +31,8 @@ impl Command for BytesAdd {
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.required("data", SyntaxShape::Binary, "The binary to add.") .required("data", SyntaxShape::Binary, "The binary to add.")

View File

@ -41,8 +41,8 @@ impl Command for BytesAt {
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.required("range", SyntaxShape::Range, "The range to get bytes.") .required("range", SyntaxShape::Range, "The range to get bytes.")
.rest( .rest(

View File

@ -24,14 +24,21 @@ impl Command for BytesBuild {
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { vec![
Example {
example: "bytes build 0x[01 02] 0x[03] 0x[04]", example: "bytes build 0x[01 02] 0x[03] 0x[04]",
description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]", description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]",
result: Some(Value::binary( result: Some(Value::binary(
vec![0x01, 0x02, 0x03, 0x04], vec![0x01, 0x02, 0x03, 0x04],
Span::test_data(), Span::test_data(),
)), )),
}] },
Example {
example: "bytes build 255 254 253 252",
description: "Builds binary data from byte numbers",
result: Some(Value::test_binary(vec![0xff, 0xfe, 0xfd, 0xfc])),
},
]
} }
fn run( fn run(
@ -46,8 +53,17 @@ impl Command for BytesBuild {
let eval_expression = get_eval_expression(engine_state); let eval_expression = get_eval_expression(engine_state);
eval_expression(engine_state, stack, expr) eval_expression(engine_state, stack, expr)
})? { })? {
let val_span = val.span();
match val { match val {
Value::Binary { mut val, .. } => output.append(&mut val), Value::Binary { mut val, .. } => output.append(&mut val),
Value::Int { val, .. } => {
let byte: u8 = val.try_into().map_err(|_| ShellError::IncorrectValue {
msg: format!("{val} is out of range for byte"),
val_span,
call_span: call.head,
})?;
output.push(byte);
}
// Explicitly propagate errors instead of dropping them. // Explicitly propagate errors instead of dropping them.
Value::Error { error, .. } => return Err(*error), Value::Error { error, .. } => return Err(*error),
other => { other => {

View File

@ -24,8 +24,8 @@ impl Command for BytesEndsWith {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("bytes ends-with") Signature::build("bytes ends-with")
.input_output_types(vec![(Type::Binary, Type::Bool), .input_output_types(vec![(Type::Binary, Type::Bool),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.required("pattern", SyntaxShape::Binary, "The pattern to match.") .required("pattern", SyntaxShape::Binary, "The pattern to match.")

View File

@ -28,8 +28,8 @@ impl Command for BytesIndexOf {
(Type::Binary, Type::Any), (Type::Binary, Type::Any),
// FIXME: this shouldn't be needed, cell paths should work with the two // FIXME: this shouldn't be needed, cell paths should work with the two
// above // above
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.required( .required(

View File

@ -17,8 +17,8 @@ impl Command for BytesLen {
Type::List(Box::new(Type::Binary)), Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::Int)), Type::List(Box::new(Type::Int)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -26,8 +26,8 @@ impl Command for BytesRemove {
Signature::build("bytes remove") Signature::build("bytes remove")
.input_output_types(vec![ .input_output_types(vec![
(Type::Binary, Type::Binary), (Type::Binary, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.required("pattern", SyntaxShape::Binary, "The pattern to find.") .required("pattern", SyntaxShape::Binary, "The pattern to find.")
.rest( .rest(

View File

@ -26,8 +26,8 @@ impl Command for BytesReplace {
Signature::build("bytes replace") Signature::build("bytes replace")
.input_output_types(vec![ .input_output_types(vec![
(Type::Binary, Type::Binary), (Type::Binary, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.required("find", SyntaxShape::Binary, "The pattern to find.") .required("find", SyntaxShape::Binary, "The pattern to find.")

View File

@ -13,8 +13,8 @@ impl Command for BytesReverse {
Signature::build("bytes reverse") Signature::build("bytes reverse")
.input_output_types(vec![ .input_output_types(vec![
(Type::Binary, Type::Binary), (Type::Binary, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -25,8 +25,8 @@ impl Command for BytesStartsWith {
Signature::build("bytes starts-with") Signature::build("bytes starts-with")
.input_output_types(vec![ .input_output_types(vec![
(Type::Binary, Type::Bool), (Type::Binary, Type::Bool),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.required("pattern", SyntaxShape::Binary, "The pattern to match.") .required("pattern", SyntaxShape::Binary, "The pattern to match.")

View File

@ -19,7 +19,7 @@ impl Command for Histogram {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("histogram") Signature::build("histogram")
.input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Table(vec![])),]) .input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::table()),])
.optional("column-name", SyntaxShape::String, "Column name to calc frequency, no need to provide if input is a list.") .optional("column-name", SyntaxShape::String, "Column name to calc frequency, no need to provide if input is a list.")
.optional("frequency-column-name", SyntaxShape::String, "Histogram's frequency column, default to be frequency column output.") .optional("frequency-column-name", SyntaxShape::String, "Histogram's frequency column, default to be frequency column output.")
.named("percentage-type", SyntaxShape::String, "percentage calculate method, can be 'normalize' or 'relative', in 'normalize', defaults to be 'normalize'", Some('t')) .named("percentage-type", SyntaxShape::String, "percentage calculate method, can be 'normalize' or 'relative', in 'normalize', defaults to be 'normalize'", Some('t'))

View File

@ -30,8 +30,8 @@ impl Command for SubCommand {
(Type::Bool, Type::Binary), (Type::Bool, Type::Binary),
(Type::Filesize, Type::Binary), (Type::Filesize, Type::Binary),
(Type::Date, Type::Binary), (Type::Date, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) // TODO: supply exhaustive examples .allow_variants_without_examples(true) // TODO: supply exhaustive examples
.switch("compact", "output without padding zeros", Some('c')) .switch("compact", "output without padding zeros", Some('c'))

View File

@ -16,9 +16,9 @@ impl Command for SubCommand {
(Type::Number, Type::Bool), (Type::Number, Type::Bool),
(Type::String, Type::Bool), (Type::String, Type::Bool),
(Type::Bool, Type::Bool), (Type::Bool, Type::Bool),
(Type::List(Box::new(Type::Any)), Type::Table(vec![])), (Type::List(Box::new(Type::Any)), Type::table()),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(

View File

@ -15,10 +15,9 @@ impl Command for IntoCellPath {
(Type::Int, Type::CellPath), (Type::Int, Type::CellPath),
(Type::List(Box::new(Type::Any)), Type::CellPath), (Type::List(Box::new(Type::Any)), Type::CellPath),
( (
Type::List(Box::new(Type::Record(vec![ Type::List(Box::new(Type::Record(
("value".into(), Type::Any), [("value".into(), Type::Any), ("optional".into(), Type::Bool)].into(),
("optional".into(), Type::Bool), ))),
]))),
Type::CellPath, Type::CellPath,
), ),
]) ])

View File

@ -62,8 +62,8 @@ impl Command for SubCommand {
(Type::Int, Type::Date), (Type::Int, Type::Date),
(Type::String, Type::Date), (Type::String, Type::Date),
(Type::List(Box::new(Type::String)), Type::List(Box::new(Type::Date))), (Type::List(Box::new(Type::String)), Type::List(Box::new(Type::Date))),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.named( .named(

View File

@ -17,9 +17,9 @@ impl Command for SubCommand {
(Type::Int, Type::Duration), (Type::Int, Type::Duration),
(Type::String, Type::Duration), (Type::String, Type::Duration),
(Type::Duration, Type::Duration), (Type::Duration, Type::Duration),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
//todo: record<hour,minute,sign> | into duration -> Duration //todo: record<hour,minute,sign> | into duration -> Duration
//(Type::Record(vec![]), Type::Record(vec![])), //(Type::record(), Type::record()),
]) ])
//.allow_variants_without_examples(true) //.allow_variants_without_examples(true)
.named( .named(
@ -203,9 +203,9 @@ fn string_to_duration(s: &str, span: Span) -> Result<i64, ShellError> {
Type::Duration, Type::Duration,
|x| x, |x| x,
) { ) {
if let Expr::ValueWithUnit(value, unit) = expression.expr { if let Expr::ValueWithUnit(value) = expression.expr {
if let Expr::Int(x) = value.expr { if let Expr::Int(x) = value.expr.expr {
match unit.item { match value.unit.item {
Unit::Nanosecond => return Ok(x), Unit::Nanosecond => return Ok(x),
Unit::Microsecond => return Ok(x * 1000), Unit::Microsecond => return Ok(x * 1000),
Unit::Millisecond => return Ok(x * 1000 * 1000), Unit::Millisecond => return Ok(x * 1000 * 1000),

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
(Type::Number, Type::Filesize), (Type::Number, Type::Filesize),
(Type::String, Type::Filesize), (Type::String, Type::Filesize),
(Type::Filesize, Type::Filesize), (Type::Filesize, Type::Filesize),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
( (
Type::List(Box::new(Type::Int)), Type::List(Box::new(Type::Int)),
Type::List(Box::new(Type::Filesize)), Type::List(Box::new(Type::Filesize)),

View File

@ -16,8 +16,8 @@ impl Command for SubCommand {
(Type::String, Type::Float), (Type::String, Type::Float),
(Type::Bool, Type::Float), (Type::Bool, Type::Float),
(Type::Float, Type::Float), (Type::Float, Type::Float),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
( (
Type::List(Box::new(Type::Any)), Type::List(Box::new(Type::Any)),
Type::List(Box::new(Type::Float)), Type::List(Box::new(Type::Float)),

View File

@ -27,8 +27,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::Glob)), Type::List(Box::new(Type::Glob)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032 .allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.rest( .rest(

View File

@ -36,8 +36,8 @@ impl Command for SubCommand {
(Type::Duration, Type::Int), (Type::Duration, Type::Int),
(Type::Filesize, Type::Int), (Type::Filesize, Type::Int),
(Type::Binary, Type::Int), (Type::Binary, Type::Int),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
( (
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::Int)), Type::List(Box::new(Type::Int)),

View File

@ -13,11 +13,11 @@ impl Command for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("into record") Signature::build("into record")
.input_output_types(vec![ .input_output_types(vec![
(Type::Date, Type::Record(vec![])), (Type::Date, Type::record()),
(Type::Duration, Type::Record(vec![])), (Type::Duration, Type::record()),
(Type::List(Box::new(Type::Any)), Type::Record(vec![])), (Type::List(Box::new(Type::Any)), Type::record()),
(Type::Range, Type::Record(vec![])), (Type::Range, Type::record()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.category(Category::Conversions) .category(Category::Conversions)
} }

View File

@ -40,8 +40,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::Any)), Type::List(Box::new(Type::Any)),
Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)),
), ),
(Type::Table(vec![]), Type::Table(vec![])), (Type::table(), Type::table()),
(Type::Record(vec![]), Type::Record(vec![])), (Type::record(), Type::record()),
]) ])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032 .allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.rest( .rest(

View File

@ -15,7 +15,7 @@ impl Command for IntoValue {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("into value") Signature::build("into value")
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))]) .input_output_types(vec![(Type::table(), Type::table())])
.named( .named(
"columns", "columns",
SyntaxShape::Table(vec![]), SyntaxShape::Table(vec![]),

View File

@ -24,8 +24,8 @@ impl Command for IntoSqliteDb {
Signature::build("into sqlite") Signature::build("into sqlite")
.category(Category::Conversions) .category(Category::Conversions)
.input_output_types(vec![ .input_output_types(vec![
(Type::Table(vec![]), Type::Nothing), (Type::table(), Type::Nothing),
(Type::Record(vec![]), Type::Nothing), (Type::record(), Type::Nothing),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.required( .required(

View File

@ -11,7 +11,7 @@ impl Command for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("date list-timezone") Signature::build("date list-timezone")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::table())])
.category(Category::Date) .category(Category::Date)
} }

View File

@ -13,8 +13,8 @@ impl Command for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("date to-record") Signature::build("date to-record")
.input_output_types(vec![ .input_output_types(vec![
(Type::Date, Type::Record(vec![])), (Type::Date, Type::record()),
(Type::String, Type::Record(vec![])), (Type::String, Type::record()),
]) ])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032 .allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.category(Category::Date) .category(Category::Date)

View File

@ -13,8 +13,8 @@ impl Command for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("date to-table") Signature::build("date to-table")
.input_output_types(vec![ .input_output_types(vec![
(Type::Date, Type::Table(vec![])), (Type::Date, Type::table()),
(Type::String, Type::Table(vec![])), (Type::String, Type::table()),
]) ])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032 .allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.category(Category::Date) .category(Category::Date)

View File

@ -16,7 +16,7 @@ impl Command for Ast {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("ast") Signature::build("ast")
.input_output_types(vec![(Type::String, Type::Record(vec![]))]) .input_output_types(vec![(Type::String, Type::record())])
.required( .required(
"pipeline", "pipeline",
SyntaxShape::String, SyntaxShape::String,

View File

@ -31,7 +31,7 @@ impl Command for DebugInfo {
fn signature(&self) -> nu_protocol::Signature { fn signature(&self) -> nu_protocol::Signature {
Signature::build("debug info") Signature::build("debug info")
.input_output_types(vec![(Type::Nothing, Type::Record(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::record())])
.category(Category::Debug) .category(Category::Debug)
} }

View File

@ -18,7 +18,7 @@ impl Command for Metadata {
fn signature(&self) -> nu_protocol::Signature { fn signature(&self) -> nu_protocol::Signature {
Signature::build("metadata") Signature::build("metadata")
.input_output_types(vec![(Type::Any, Type::Record(vec![]))]) .input_output_types(vec![(Type::Any, Type::record())])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.optional( .optional(
"expression", "expression",

View File

@ -34,7 +34,7 @@ impl Command for DebugProfile {
"How many blocks/closures deep to step into (default 2)", "How many blocks/closures deep to step into (default 2)",
Some('m'), Some('m'),
) )
.input_output_types(vec![(Type::Any, Type::Table(vec![]))]) .input_output_types(vec![(Type::Any, Type::table())])
.category(Category::Debug) .category(Category::Debug)
} }

View File

@ -20,12 +20,15 @@ impl Command for ViewFiles {
Signature::build("view files") Signature::build("view files")
.input_output_types(vec![( .input_output_types(vec![(
Type::Nothing, Type::Nothing,
Type::Table(vec![ Type::Table(
[
("filename".into(), Type::String), ("filename".into(), Type::String),
("start".into(), Type::Int), ("start".into(), Type::Int),
("end".into(), Type::Int), ("end".into(), Type::Int),
("size".into(), Type::Int), ("size".into(), Type::Int),
]), ]
.into(),
),
)]) )])
.category(Category::Debug) .category(Category::Debug)
} }

View File

@ -260,6 +260,8 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
From, From,
FromCsv, FromCsv,
FromJson, FromJson,
FromMsgpack,
FromMsgpackz,
FromNuon, FromNuon,
FromOds, FromOds,
FromSsv, FromSsv,
@ -273,6 +275,8 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
ToCsv, ToCsv,
ToJson, ToJson,
ToMd, ToMd,
ToMsgpack,
ToMsgpackz,
ToNuon, ToNuon,
ToText, ToText,
ToToml, ToToml,

View File

@ -15,7 +15,7 @@ impl Command for LoadEnv {
fn signature(&self) -> nu_protocol::Signature { fn signature(&self) -> nu_protocol::Signature {
Signature::build("load-env") Signature::build("load-env")
.input_output_types(vec![ .input_output_types(vec![
(Type::Record(vec![]), Type::Nothing), (Type::record(), Type::Nothing),
(Type::Nothing, Type::Nothing), (Type::Nothing, Type::Nothing),
]) ])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)

View File

@ -33,7 +33,7 @@ impl Command for Du {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("du") Signature::build("du")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::table())])
.allow_variants_without_examples(true) .allow_variants_without_examples(true)
.rest( .rest(
"path", "path",

View File

@ -45,7 +45,7 @@ impl Command for Ls {
fn signature(&self) -> nu_protocol::Signature { fn signature(&self) -> nu_protocol::Signature {
Signature::build("ls") Signature::build("ls")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))]) .input_output_types(vec![(Type::Nothing, Type::table())])
// LsGlobPattern is similar to string, it won't auto-expand // LsGlobPattern is similar to string, it won't auto-expand
// and we use it to track if the user input is quoted. // and we use it to track if the user input is quoted.
.rest("pattern", SyntaxShape::OneOf(vec![SyntaxShape::GlobPattern, SyntaxShape::String]), "The glob pattern to use.") .rest("pattern", SyntaxShape::OneOf(vec![SyntaxShape::GlobPattern, SyntaxShape::String]), "The glob pattern to use.")

Some files were not shown because too many files have changed in this diff Show More