Compare commits

...

90 Commits
0.88.0 ... main

Author SHA1 Message Date
c74cff213e remove std clip (#11131)
follow up to
- https://github.com/nushell/nushell/pull/11097

related to
- https://github.com/nushell/nu_scripts/pull/674

> **Important**
> wait for in between Nushell 0.88.0 and 0.89.0

# Description
this PR removes the `std clip` command after it's been deprecated in
https://github.com/nushell/nushell/pull/11097 😋

# User-Facing Changes
`std clip` will no longer be available.

# Tests + Formatting

# After Submitting
2024-01-08 21:46:10 +02:00
2ea5819b02 Bump crate-ci/typos from 1.16.26 to 1.17.0
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.16.26 to 1.17.0.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.16.26...v1.17.0)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 01:17:04 +00:00
1115190a49 Bump shadow-rs from 0.25.0 to 0.26.0
Bumps [shadow-rs](https://github.com/baoyachi/shadow-rs) from 0.25.0 to 0.26.0.
- [Release notes](https://github.com/baoyachi/shadow-rs/releases)
- [Changelog](https://github.com/baoyachi/shadow-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/baoyachi/shadow-rs/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: shadow-rs
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 01:06:59 +00:00
7132c5ad02 add wheres 2024-01-07 19:04:04 -06:00
1920ece759 fix: closure captures can also be constants (#11493)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->
When evaluating a closure (in
`EvalRuntime::eval_row_condition_or_closure()`), we try to resolve the
closure's block's captures, but we only check if they're variables on
the stack. We need to also check if they are constants (see the logic in
`Stack::gather_captures()`).

fixes #10701
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-01-07 12:51:39 +02:00
6f59abaf43 update reedline version to latest main (#11490)
# Description
Update reedline version to fix
https://github.com/nushell/nushell/issues/11399
2024-01-05 17:19:43 -06:00
5f7425a7b4 Xml errors fix (#11487)
# Description
Fixes #11264
This PR adds checks in `to xml` to output error for malformed xml
entries:
* With columns that are not one of `tag`, `attributes` or `content`
* With no `tag` when entry is not a string
* With `tag` that is not a string
This PR also replaces `attrs` with `attributes` in example and
extra_usage of `to xml` (column was originally named attrs and renamed
to attributes, but this was missed in docs)

# User-Facing Changes
`to xml` will produce error for conditions described above instead of
silently returning nothing

# Tests + Formatting
Added tests for `to xml` to check handling of malformed xml entries
2024-01-05 15:56:13 -06:00
1ab9ec3ebc Bump terminal_size to 0.3 (#11486)
# Description
Simplify the dependencies. There are two different versions of
`terminal_size` that nushell directly depends on.

Related: #8060
2024-01-05 10:19:46 -06:00
f2095ed0cc Fix cross building for target x86_64-pc-windows-gnu on linux (#11485)
# Description

Cross build for target `x86_64-pc-windows-gnu` fails on linux.

```console
nushell on  main [?] is 📦 v0.88.2 via 🦀 v1.77.0-nightly
❯ cargo build --target x86_64-pc-windows-gnu -p nu-system
   Compiling nu-system v0.88.2 (/data/source/nushell/crates/nu-system)
error[E0432]: unresolved import `chrono::Local`
   --> crates/nu-system/src/windows.rs:5:14
    |
5   | use chrono::{Local, NaiveDate};
    |              ^^^^^ no `Local` in the root
    |
note: found an item that was configured out
   --> /path/to/home/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/chrono-0.4.31/src/lib.rs:537:17
    |
537 | pub use offset::Local;
    |                 ^^^^^
    = note: the item is gated behind the `clock` feature

error[E0412]: cannot find type `Local` in crate `chrono`
   --> crates/nu-system/src/windows.rs:68:46
    |
68  |     pub start_time: chrono::DateTime<chrono::Local>,
    |                                              ^^^^^ not found in `chrono`
    |
note: found an item that was configured out
   --> /path/to/home/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/chrono-0.4.31/src/lib.rs:537:17
    |
537 | pub use offset::Local;
    |                 ^^^^^
    = note: the item is gated behind the `clock` feature

Some errors have detailed explanations: E0412, E0432.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `nu-system` (lib) due to 2 previous errors
```
2024-01-05 07:31:38 -06:00
7e26b4fcc2 Bump sysinfo from 0.29 to 0.30 (#11484)
# Description
Bumps `sysinfo` to 0.30.

* Changelog
 https://github.com/GuillaumeGomez/sysinfo/blob/master/CHANGELOG.md#0304

# User-Facing Changes
N/A
2024-01-05 05:31:29 -06:00
ad95e4cc27 Refactor tests (using cococo instead of ^echo) (#11479)
- related PR: #11478 

# Description

Now we can use `nu --testbin cococo` instead of `^echo` to echo messages
to stdout in tests.

But `nu` treats parameters as its own flags when parameter starts with
`-`. So `^echo --foo='bar'` still use `^echo`.

# User-Facing Changes

(none)

# Tests + Formatting

- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library


# After Submitting

(none)
2024-01-05 11:40:56 +08:00
ee5a18167c Replace winapi with windows (#11481)
# Description
`winapi` is not actively maintained, use the Microsoft blessed `windows`
crate instead.

# User-Facing Changes
N/A
2024-01-04 11:17:19 -06:00
75c9e3e5df Try to fix riscv64 building by using unbuntu-latest (#11476)
Try to fix `riscv64gc-unknown-linux-gnu` building by using
`unbuntu-latest`
This PR should close https://github.com/nushell/nushell/issues/11452
The action should run without errors:
https://github.com/nushell/nightly/actions/runs/7394915358
2024-01-04 07:55:10 +08:00
77f10eb270 Fix the test which fails on windows (#11478)
- related PR: #11463

# Description

Currently, `commands::complete::basic` fails on Windows without git
bash.
This pr fixes it.

# User-Facing Changes

(none)

# Tests + Formatting

- [x] (on Windows) `cargo fmt --all -- --check` to check standard code
formatting (`cargo fmt --all` applies these changes)
- [x] (on Windows) `cargo clippy --workspace -- -D warnings -D
clippy::unwrap_used` to check that you're using the standard code style
- [x] (on Windows without git bash, Windows with git bash and Ubuntu)
`cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- on my Windows with Japanese lang pack: 1 test still fails. (see
#11463)
- [x] (on Windows and Ubuntu) `cargo run -- -c "use std testing; testing
run-tests --path crates/nu-std"` to run the tests for the standard
library

# After Submitting

(none)
2024-01-03 07:22:43 -06:00
42bb42a2e1 Fix rm for symlinks pointing to directory on windows (issue #11461) (#11463)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

- this PR closes #11461

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

Using `std::fs::remove_dir` instead of `std::fs::remove_file` when try
remove symlinks pointing to a directory on Windows.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

none

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- I got 2 test fails on my Windows devenv; these fails in main branch
too
- `commands::complete::basic` : passed on Ubuntu, failed on Windows (a
bug?)
- `commands::cp::copy_file_with_read_permission`: failed on Windows with
Japanese environment (This test refers error message, so that fails on
environments using a language except for english.)
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->

This fix has no changes to user-facing interface.
2024-01-02 21:27:03 +08:00
f597380112 Bump lsp-types from 0.94.1 to 0.95.0 (#11457)
Bumps [lsp-types](https://github.com/gluon-lang/lsp-types) from 0.94.1
to 0.95.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/gluon-lang/lsp-types/blob/master/CHANGELOG.md">lsp-types's
changelog</a>.</em></p>
<blockquote>
<h2>v0.95.0 (2023-12-12)</h2>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<h3>v0.94.2 (2023-12-12)</h3>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ccf64e2fb6"><code>ccf64e2</code></a>
chore: Release lsp-types version 0.95.0</li>
<li><a
href="bccf50c1c6"><code>bccf50c</code></a>
Update changelog</li>
<li><a
href="75cea03884"><code>75cea03</code></a>
chore: Release lsp-types version 0.94.2</li>
<li><a
href="4084a00cd1"><code>4084a00</code></a>
Update changelog</li>
<li><a
href="b588e166be"><code>b588e16</code></a>
Merge pull request <a
href="https://redirect.github.com/gluon-lang/lsp-types/issues/274">#274</a>
from lapce/inline-completion</li>
<li><a
href="3031a76c44"><code>3031a76</code></a>
Add support for textDocument/inlineCompletion</li>
<li><a
href="038577b0b5"><code>038577b</code></a>
doc: Update readme to request links to the spec for PRs</li>
<li><a
href="f106ccb584"><code>f106ccb</code></a>
Merge pull request <a
href="https://redirect.github.com/gluon-lang/lsp-types/issues/257">#257</a>
from ahlinc/init-work-done-token</li>
<li><a
href="730924021a"><code>7309240</code></a>
Merge pull request <a
href="https://redirect.github.com/gluon-lang/lsp-types/issues/259">#259</a>
from ebkalderon/fix-telemetry-event-params</li>
<li><a
href="a15daede51"><code>a15daed</code></a>
Merge pull request <a
href="https://redirect.github.com/gluon-lang/lsp-types/issues/264">#264</a>
from tage64/master</li>
<li>Additional commits viewable in <a
href="https://github.com/gluon-lang/lsp-types/compare/v0.94.1...v0.95.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=lsp-types&package-manager=cargo&previous-version=0.94.1&new-version=0.95.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-02 07:22:38 +08:00
b92b4120dc Bump crate-ci/typos from 1.16.25 to 1.16.26 (#11458)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.16.25
to 1.16.26.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.16.26</h2>
<h2>[1.16.26] - 2023-12-27</h2>
<h3>Fixes</h3>
<ul>
<li>Apply <code>extend-ignore-re</code> to file names in addition to
file content</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h2>[1.16.26] - 2023-12-27</h2>
<h3>Fixes</h3>
<ul>
<li>Apply <code>extend-ignore-re</code> to file names in addition to
file content</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="45a880d9f8"><code>45a880d</code></a>
chore: Release</li>
<li><a
href="1e55ede61c"><code>1e55ede</code></a>
docs: Update changelog</li>
<li><a
href="e32ec882ea"><code>e32ec88</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/886">#886</a>
from epage/olt</li>
<li><a
href="bf66cbd0b6"><code>bf66cbd</code></a>
fix(config): Apply extend-ignore-re to file names</li>
<li><a
href="a9afeef275"><code>a9afeef</code></a>
test(cli): Show extend-ignore on file names</li>
<li>See full diff in <a
href="https://github.com/crate-ci/typos/compare/v1.16.25...v1.16.26">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.16.25&new-version=1.16.26)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-02 07:22:19 +08:00
de5ad5de19 Revert "Return external file completions if not empty (#10898)" (#11446)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

This reverts #10898 which breaks external completion.
Not having file completion fallback on empty result is **intentional**
as this indicates that there is nothing to complete at this position.
To have nushell fallback to file completion the external completer can
simply return *nothing*.


`NO RECORDS FOUND`:
```nushell
let external_completer = {|spans|
    []
}
```

Fallback to file completion:
```nushell
let external_completer = {|spans|
}
```

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-31 08:45:05 -06:00
64695cd67c bump rust toolchain to 1.73.0 (#11445)
This PR bumps the nushell rust toolchain from 1.72.1 to 1.73.0 since
1.75.0 was released recently.

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-30 10:41:27 -06:00
21b3eeed99 Allow spreading arguments to commands (#11289)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

Finishes implementing https://github.com/nushell/nushell/issues/10598,
which asks for a spread operator in lists, in records, and when calling
commands.

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

This PR will allow spreading arguments to commands (both internal and
external). It will also deprecate spreading arguments automatically when
passing to external commands.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

- Users will be able to use `...` to spread arguments to custom/builtin
commands that have rest parameters or allow unknown arguments, or to any
external command
- If a custom command doesn't have a rest parameter and it doesn't allow
unknown arguments either, the spread operator will not be allowed
- Passing lists to external commands without `...` will work for now but
will cause a deprecation warning saying that it'll stop working in 0.91
(is 2 versions enough time?)

Here's a function to help with demonstrating some behavior:
```nushell
> def foo [ a, b, c?, d?, ...rest ] { [$a $b $c $d $rest] | to nuon }
```

You can pass a list of arguments to fill in the `rest` parameter using
`...`:
```nushell
> foo 1 2 3 4 ...[5 6]
[1, 2, 3, 4, [5, 6]]
```

If you don't use `...`, the list `[5 6]` will be treated as a single
argument:

```nushell
> foo 1 2 3 4 [5 6] # Note the double [[]]
[1, 2, 3, 4, [[5, 6]]]
```

You can omit optional parameters before the spread arguments:
```nushell
> foo 1 2 3 ...[4 5] # d is omitted here
[1, 2, 3, null, [4, 5]]
```

If you have multiple lists, you can spread them all:
```nushell
> foo 1 2 3 ...[4 5] 6 7 ...[8] ...[]
[1, 2, 3, null, [4, 5, 6, 7, 8]]
```

Here's the kind of error you get when you try to spread arguments to a
command with no rest parameter:

![image](https://github.com/nushell/nushell/assets/45539777/93faceae-00eb-4e59-ac3f-17f98436e6e4)

And this is the warning you get when you pass a list to an external now
(without `...`):


![image](https://github.com/nushell/nushell/assets/45539777/d368f590-201e-49fb-8b20-68476ced415e)


# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

Added tests to cover the following cases:
- Spreading arguments to a command that doesn't have a rest parameter
(unexpected spread argument error)
- Spreading arguments to a command that doesn't have a rest parameter
*but* there's also a missing positional argument (missing positional
error)
- Spreading arguments to a command that doesn't have a rest parameter
but does allow unknown arguments, such as `exec` (allowed)
- Spreading a list literal containing arguments of the wrong type (parse
error)
- Spreading a non-list value, both to internal and external commands
- Having named arguments in the middle of rest arguments
- `explain`ing a command call that spreads its arguments

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->

# Examples

Suppose you have multiple tables:
```nushell
let people = [[id name age]; [0 alice 100] [1 bob 200] [2 eve 300]]
let evil_twins = [[id name age]; [0 ecila 100] [-1 bob 200] [-2 eve 300]]
```

Maybe you often find yourself needing to merge multiple tables and want
a utility to do that. You could write a function like this:
```nushell
def merge_all [ ...tables ] { $tables | reduce { |it, acc| $acc | merge $it } }
```

Then you can use it like this:
```nushell
> merge_all ...([$people $evil_twins] | each { |$it| $it | select name age })
╭───┬───────┬─────╮
│ # │ name  │ age │
├───┼───────┼─────┤
│ 0 │ ecila │ 100 │
│ 1 │ bob   │ 200 │
│ 2 │ eve   │ 300 │
╰───┴───────┴─────╯
```

Except they had duplicate columns, so now you first want to suffix every
column with a number to tell you which table the column came from. You
can make a command for that:
```nushell
def select_and_merge [ --cols: list<string>, ...tables ] {
  let renamed_tables = $tables
    | enumerate
    | each { |it|
      $it.item | select $cols | rename ...($cols | each { |col| $col + ($it.index | into string) })
    };
  merge_all ...$renamed_tables
}
```
And call it like this:
```nushell
> select_and_merge --cols [name age] $people $evil_twins
╭───┬───────┬──────┬───────┬──────╮
│ # │ name0 │ age0 │ name1 │ age1 │
├───┼───────┼──────┼───────┼──────┤
│ 0 │ alice │  100 │ ecila │  100 │
│ 1 │ bob   │  200 │ bob   │  200 │
│ 2 │ eve   │  300 │ eve   │  300 │
╰───┴───────┴──────┴───────┴──────╯
```

---

Suppose someone's made a command to search for APT packages:

```nushell
# The main command
def search-pkgs [
    --install                   # Whether to install any packages it finds
    log_level: int              # Pretend it's a good idea to make this a required positional parameter
    exclude?: list<string>      # Packages to exclude
    repositories?: list<string> # Which repositories to look in (searches in all if not given)
    ...pkgs                     # Package names to search for
] {
  { install: $install, log_level: $log_level, exclude: ($exclude | to nuon), repositories: ($repositories | to nuon), pkgs: ($pkgs | to nuon) }
}
```

It has a lot of parameters to configure it, so you might make your own
helper commands to wrap around it for specific cases. Here's one
example:
```nushell
# Only look for packages locally
def search-pkgs-local [
    --install              # Whether to install any packages it finds
    log_level: int
    exclude?: list<string> # Packages to exclude
    ...pkgs                # Package names to search for
] {
  # All required and optional positional parameters are given
  search-pkgs --install=$install $log_level [] ["<local URI or something>"] ...$pkgs
}
```
And you can run it like this:
```nushell
> search-pkgs-local --install=false 5 ...["python2.7" "vim"]
╭──────────────┬──────────────────────────────╮
│ install      │ false                        │
│ log_level    │ 5                            │
│ exclude      │ []                           │
│ repositories │ ["<local URI or something>"] │
│ pkgs         │ ["python2.7", vim]           │
╰──────────────┴──────────────────────────────╯
```

One thing I realized when writing this was that if we decide to not
allow passing optional arguments using the spread operator, then you can
(mis?)use the spread operator to skip optional parameters. Here, I
didn't want to give `exclude` explicitly, so I used a spread operator to
pass the packages to install. Without it, I would've needed to do
`search-pkgs-local --install=false 5 [] "python2.7" "vim"` (explicitly
pass `[]` (or `null`, in the general case) to `exclude`). There are
probably more idiomatic ways to do this, but I just thought it was
something interesting.

If you're a virologist of the [xkcd](https://xkcd.com/350/) kind,
another helper command you might make is this:
```nushell
# Install any packages it finds
def live-dangerously [ ...pkgs ] {
  # One optional argument was given (exclude), while another was not (repositories)
  search-pkgs 0 [] ...$pkgs --install # Flags can go after spread arguments
}
```

Running it:
```nushell
> live-dangerously "git" "*vi*" # *vi* because I don't feel like typing out vim and neovim
╭──────────────┬─────────────╮
│ install      │ true        │
│ log_level    │ 0           │
│ exclude      │ []          │
│ repositories │ null        │
│ pkgs         │ [git, *vi*] │
╰──────────────┴─────────────╯
```

Here's an example that uses the spread operator more than once within
the same command call:
```nushell
let extras = [ chrome firefox python java git ]

def search-pkgs-curated [ ...pkgs ] {
  (search-pkgs
      1
      [emacs]
      ["example.com", "foo.com"]
      vim # A must for everyone!
      ...($pkgs | filter { |p| not ($p | str contains "*") }) # Remove packages with globs
      python # Good tool to have
      ...$extras
      --install=false
      python3) # I forget, did I already put Python in extras?
}
```

Running it:
```nushell
> search-pkgs-curated "git" "*vi*"
╭──────────────┬───────────────────────────────────────────────────────────────────╮
│ install      │ false                                                             │
│ log_level    │ 1                                                                 │
│ exclude      │ [emacs]                                                           │
│ repositories │ [example.com, foo.com]                                            │
│ pkgs         │ [vim, git, python, chrome, firefox, python, java, git, "python3"] │
╰──────────────┴───────────────────────────────────────────────────────────────────╯
```
2023-12-28 15:43:20 +08:00
a86a7e6c29 Allow http commands' automatic redirect-following to be disabled (#11329)
Intends to close #8920 

This PR suggests a new flag for the `http` commands, `--redirect-mode`,
which enables users to choose between different redirect handling modes.
The current behaviour of letting ureq silently follow redirects remains
the default, but two new options are introduced here, following the lead
of [JavaScript's `fetch`
API](https://developer.mozilla.org/en-US/docs/Web/API/fetch#redirect):
"manual", where any 3xx response to a request is simply returned as the
command's result, and "error", where any 3xx response causes a network
error like those caused by 4xx and 5xx responses.

This PR is a draft. Tests have not been added or run, the flag is
currently only implemented for the `http get` command, and design tweaks
are likely to be appropriate.

Most notably, it's not obvious to me whether a single flag which can
take one of three values is the nicest solution here.
We might instead consider two binary flags (like
`--no-following-redirects` and `--disallow-redirects`, although I'm bad
at naming things so I need help with that anyway), or completely drop
the "error" option if it's not deemed useful enough. (I personally think
it has some merit, especially since 4xx and 5xx responses are already
treated as errors by default; So this would allow users to treat only
immediate 2xx responses as success)

# User-facing changes
New options for the `http [method]` commands. Behaviour remains
unchanged when the command line flag introduced here is not used.


![image](https://github.com/nushell/nushell/assets/12228688/1eb89f14-7d48-4f41-8a3e-cc0f1bd0a4f8)
2023-12-28 15:26:34 +08:00
15421dc45e Fix the bug for "bytes remove --end" . (#11428)
This PR should close #11426 .

# Description
> ### Describe the bug
> When using the `--end` option of bytes remove, nushell panics if the
provided bytes don't exist. This doesn't seem to affect `bytes remove`
w/o flag or `bytes remove --all`.

# User-Facing Changes
Nushell doesn`t panic anymore.

# Tests + Formatting
Behavior before fixing the bug:
![nu-before
changes](https://github.com/UPB-CS-OpenSourceUpstream/nushell/assets/119429832/f9c26d88-8962-4f38-a373-ba436a26ca7c)
Behavior after fixing the bug:
![nu- after
changes](https://github.com/UPB-CS-OpenSourceUpstream/nushell/assets/119429832/0dd2b487-1696-45a6-9ea2-928cbd3a33a8)
2023-12-28 07:01:55 +08:00
9522052063 More specific errors for missing values in records (#11423)
# Description
Currently, when writing a record, if you don't give the value for a
field, the syntax error highlights the entire record instead of
pinpointing the issue. Here's some examples:

```nushell
> { a: 2, 3 } # Missing colon (and value)
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #2:1:1]
 1 │  { a: 2, 3 }
   ·  ─────┬─────
   ·       ╰── expected record
   ╰────

> { a: 2, 3: } # Missing value
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #3:1:1]
 1 │  { a: 2, 3: }
   ·  ──────┬─────
   ·        ╰── expected record
   ╰────

> { a: 2, 3 4 } # Missing colon
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #4:1:1]
 1 │  { a: 2, 3 4 }
   ·  ──────┬──────
   ·        ╰── expected record
   ╰────
```

In all of them, the entire record is highlighted red because an
`Expr::Garbage` is returned covering that whole span:


![image](https://github.com/nushell/nushell/assets/45539777/36660b50-23be-4353-b180-3f84eff3c220)

This PR is for highlighting only the part inside the record that could
not be parsed. If the record literal is big, an error message pointing
to the start of where the parser thinks things went wrong should help
people fix their code.

# User-Facing Changes
Below are screenshots of the new errors:

If there's a stray record key right before the record ends, it
highlights only that key and tells the user it expected a colon after
it:


![image](https://github.com/nushell/nushell/assets/45539777/94503256-8ea2-47dd-b69a-4b520c66f7b6)

If the record ends before the value for the last field was given, it
highlights the key and colon of that field and tells the user it
expected a value after the colon:


![image](https://github.com/nushell/nushell/assets/45539777/2f3837ec-3b35-4b81-8c57-706f8056ac04)

If there are two consecutive expressions without a colon between them,
it highlights everything from the second expression to the end of the
record and tells the user it expected a colon. I was tempted to add a
help message suggesting adding a colon in between, but that may not
always be the right thing to do.


![image](https://github.com/nushell/nushell/assets/45539777/1abaaaa8-1896-4909-bbb7-9a38cece5250)

# Tests + Formatting

# After Submitting
2023-12-27 10:15:12 +01:00
ba880277bf Remove unnecessary replace_in_variable (#11424)
# Description
`Expression::replace_in_variable` is only called in one place, and it is
called with `new_var_id` = `IN_VARIABLE_ID`. So, it ends up doing
nothing. E.g., adding `debug_assert_eq!(new_var_id, IN_VARIABLE_ID)` in
`replace_in_variable` does not trigger any panic.

# User-Facing Changes
Breaking change for `nu_protocol`.
2023-12-26 18:46:49 +01:00
40241e9be6 Revert "Bump reedline development version" (#11425)
Reverts nushell/nushell#11406

This PR https://github.com/nushell/reedline/pull/688 is causing clear
screens to happen at strange times. Documented here
https://github.com/nushell/nushell/pull/11406#issuecomment-1869591405
2023-12-26 09:08:32 -06:00
34f3da7150 Don't panic when http_client fails (#11422)
# Description

This PR makes `http_client` return `Result<ureq::Agent, ShellError>`, so
errors can be propagated to the caller.
2023-12-25 23:09:37 +08:00
534287ed65 Don't create a thread if stderr_stream is None (#11421)
# Description

There is no need to create a thread if `stderr_stream` is `None`.
2023-12-25 08:10:15 -06:00
913c2b8d1c Bump ical from 0.8.0 to 0.9.0 (#11419)
Bumps [ical](https://github.com/Peltoche/ical-rs) from 0.8.0 to 0.9.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Peltoche/ical-rs/releases">ical's
releases</a>.</em></p>
<blockquote>
<h2>v0.9.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add the github actions by <a
href="https://github.com/Peltoche"><code>@​Peltoche</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/35">Peltoche/ical-rs#35</a></li>
<li>Use thiserror instead of failure by <a
href="https://github.com/Peltoche"><code>@​Peltoche</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/36">Peltoche/ical-rs#36</a></li>
<li>Accept lowercase vCards by <a
href="https://github.com/link2xt"><code>@​link2xt</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/37">Peltoche/ical-rs#37</a></li>
<li>Parse multiline attributes with tabs correctly by <a
href="https://github.com/FliegendeWurst"><code>@​FliegendeWurst</code></a>
in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/41">Peltoche/ical-rs#41</a></li>
<li>Ical serde by <a
href="https://github.com/daladim"><code>@​daladim</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/44">Peltoche/ical-rs#44</a></li>
<li>Set the license to Apache 2 by <a
href="https://github.com/Peltoche"><code>@​Peltoche</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/47">Peltoche/ical-rs#47</a></li>
<li>Update README.md by <a
href="https://github.com/Zearin"><code>@​Zearin</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/51">Peltoche/ical-rs#51</a></li>
<li>Adding ical-output support by <a
href="https://github.com/migmedia"><code>@​migmedia</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/49">Peltoche/ical-rs#49</a></li>
<li>Improve documentation of builders. by <a
href="https://github.com/migmedia"><code>@​migmedia</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/52">Peltoche/ical-rs#52</a></li>
<li>Add access functions for properties by <a
href="https://github.com/reedts"><code>@​reedts</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/53">Peltoche/ical-rs#53</a></li>
<li>Fix README by <a
href="https://github.com/westy92"><code>@​westy92</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/55">Peltoche/ical-rs#55</a></li>
<li>Handle the case were a line contains non-utf8 characters by <a
href="https://github.com/Peltoche"><code>@​Peltoche</code></a> in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/57">Peltoche/ical-rs#57</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/link2xt"><code>@​link2xt</code></a> made
their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/37">Peltoche/ical-rs#37</a></li>
<li><a
href="https://github.com/FliegendeWurst"><code>@​FliegendeWurst</code></a>
made their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/41">Peltoche/ical-rs#41</a></li>
<li><a href="https://github.com/daladim"><code>@​daladim</code></a> made
their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/44">Peltoche/ical-rs#44</a></li>
<li><a href="https://github.com/Zearin"><code>@​Zearin</code></a> made
their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/51">Peltoche/ical-rs#51</a></li>
<li><a href="https://github.com/migmedia"><code>@​migmedia</code></a>
made their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/49">Peltoche/ical-rs#49</a></li>
<li><a href="https://github.com/reedts"><code>@​reedts</code></a> made
their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/53">Peltoche/ical-rs#53</a></li>
<li><a href="https://github.com/westy92"><code>@​westy92</code></a> made
their first contribution in <a
href="https://redirect.github.com/Peltoche/ical-rs/pull/55">Peltoche/ical-rs#55</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/Peltoche/ical-rs/compare/0.6.0...v0.9.0">https://github.com/Peltoche/ical-rs/compare/0.6.0...v0.9.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/Peltoche/ical-rs/commits/v0.9.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ical&package-manager=cargo&previous-version=0.8.0&new-version=0.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-25 09:23:27 +08:00
aeffa188f0 Fix an infinite loop if the input stream and output stream are the same (#11384)
# Description

Fixes #11382 

# User-Facing Changes
* before

```console
nushell/test (109f629) [✘?]
❯ open hello.md
hello
nushell/test (109f629) [✘?]
❯ ls hello.md | get size
╭───┬─────╮
│ 0 │ 6 B │
╰───┴─────╯
nushell/test (109f629) [✘?]
❯ open --raw hello.md | prepend "world" | save --raw --force hello.md
^C
nushell/test (109f629) [✘?]
❯ ls hello.md | get size
╭───┬─────────╮
│ 0 │ 2.8 GiB │
╰───┴─────────╯
```

* after

```console
nushell/test on  fix_save [✘!?⇡]
❯ open hello.md | prepend "hello" | save --force hello.md
nushell/test on  fix_save [✘!?⇡]
❯ open --raw hello.md | prepend "hello" | save --raw --force ../test/hello.md
Error:   × pipeline input and output are same file
   ╭─[entry #4:1:1]
 1 │ open --raw hello.md | prepend "hello" | save --raw --force ../test/hello.md
   ·                                                           ────────┬───────
   ·                                                                   ╰── can't save output to '/data/source/nushell/test/hello.md' while it's being reading
   ╰────
  help: you should change output path


nushell/test on  fix_save [✘!?⇡]
❯ open hello | prepend "hello" | save --force hello
Error:   × pipeline input and output are same file
   ╭─[entry #5:1:1]
 1 │ open hello | prepend "hello" | save --force hello
   ·                                            ──┬──
   ·                                              ╰── can't save output to '/data/source/nushell/test/hello' while it's being reading
   ╰────
  help: you should change output path
```

# Tests + Formatting
Make sure you've run and fixed any issues with these commands:
- [x] add `commands::save::save_same_file_with_extension`
- [x] add `commands::save::save_same_file_without_extension`
- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

# After Submitting
2023-12-24 23:29:23 +08:00
543a25599c Simplify the feature gates for stor commands (#11416)
All of them depend on feature `sqlite` so just conditionally `use` the
parent module.
2023-12-24 13:31:46 +01:00
7ad0e5541e Make polars deps optional for cargo test --all (#11415)
As `--workspace/--all` pulls in all crates in the workspace for `cargo
test --workspace` let's make sure that the `polars` family of
dependencies are also feature gated so they only build for `--features
dataframe`. The test modules themselves also depend on the feature.

Should speed up a bare `cargo test --workspace`
2023-12-24 13:12:31 +01:00
c1cc1c82cc Lock out new direct construction of Record (#11414)
# Description
With #11386 we don't have any nushell-internal code directly accessing
the `vals` field of `Record`, so let's make it private so everyone in
the future uses the checked ways guaranteeing matching cols/vals.

The `cols` feel has to remain pub for now as `rename` still directly
mutates this field. See #11020 for challenges for this refactor.

# Plugin-Author-Facing Changes
This is a breaking change for outside plugins that relied on the `pub`
fields.
2023-12-24 13:12:16 +01:00
b0b4c3dffd Check for clean repo after tests (#11409)
Goal: detect problems like adressed by #11407 or missing `Cargo.lock`
update early

Try to fail when there is a non clear `git status` message
2023-12-23 20:28:07 +01:00
f3de373c59 Bump reedline development version (#11406)
Fix for #11399
Provided by nushell/reedline#688
2023-12-23 20:08:37 +01:00
df1fecd2cb Fix sandboxing of redirection tests (#11407)
When running `cargo test --workspace` a file `crates/nu-command/a.txt`
remained which we also saw as an accidential additions in some commits.

Searching for `a.txt` narrowed it down that
`redirection_keep_exit_codes` was not sandboxed in a temporary directory
and created this file.

Went through redirection tests and placed them in a `Playground` to get
sandboxing `dirs` for `nu!(cwd:`.
For those tests where redirection fails and no file should be created
now I added a check that no file is created on accident.


- Sandbox `redirection_keep_exit_codes` test
- Sandbox `no_duplicate_redirection` test
- Check that no redirect file is created on error
- Sandbox `redirection_should_have_a_target` test
2023-12-23 20:01:20 +01:00
9620e27e4f fix: prevent greedy matching of directory names (#11403)
Fixes #11396

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

If a directory name is an exact match, the completer stops greedily
matching directories with the same prefix.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

Completions should work as described in #11396.

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-23 00:06:00 -06:00
072ecec8ca Bump unsafe-libyaml from 0.2.9 to 0.2.10 (#11391) 2023-12-21 18:49:12 +00:00
748d82cec1 Bump windows from 0.48.0 to 0.52.0 (#11325)
# Description
Bump `windows` to 0.52.0 and fix `is_admin`

https://github.com/microsoft/windows-rs/pull/2476

# User-Facing Changes
N/A

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-21 18:49:15 +01:00
5e5d1ea81b Bump fancy-regex to single 0.12.0 version (#11389)
Supersedes #11039 that was broken due to dependabot not correctly taking
the workspace into account (this bug has been worked around in #11387)
2023-12-21 17:10:33 +01:00
bb570e42be Bump lscolors from 0.15.0 to 0.16.0 (#11359) 2023-12-21 16:08:19 +00:00
3a050864df Simplify SIGQUIT handling (#11381)
# Description
Simplifies `SIGQUIT` protection to a single `signal` ignore system call.

# User-Facing Changes
`SIGQUIT` is no longer blocked if nushell is in non-interactive mode
(signals should not be blocked in non-interactive mode).
Also a breaking API change for `nu_protocol`.

# Tests + Formatting
Should come after #11178 for testing.
2023-12-21 17:00:38 +01:00
8cfa96b4c0 Construct Records only through checked helpers (#11386)
# Description

Constructing the internals of `Record` without checking the lengths is
bad. (also incompatible with changes to how we store records)

- Use `Record::from_raw_cols_vals` in dataframe code
- Use `record!` macro in dataframe test
- Use `record!` in `nu-color-config` tests
- Stop direct record construction in `nu-command`
- Refactor table construction in `from nuon`

# User-Facing Changes
None

# Tests + Formatting
No new tests, updated tests in equal fashion
2023-12-21 16:48:15 +01:00
6f384da57e Make Call::get_flag_expr return Expression by ref (#11388)
# Description
A small refactor that eliminates some `Expression` cloning.

# User-Facing Changes
Breaking change for `nu_protocol`.
2023-12-21 16:42:07 +01:00
f8e63328d8 Expand the workspace members in Cargo.toml (#11387)
While the `cargo` tools will include crates we depend on in the
directory into the workspace, I observed dependabot not taking all of
our crates into account in its version bump attempts leading to
duplication of outside dependencies.

e.g.
- https://github.com/nushell/nushell/pull/11039
2023-12-21 16:41:31 +01:00
5d98a727ca Deprecate --flag: bool in custom command (#11365)
# Description
While #11057 is merged, it's hard to tell the difference between
`--flag: bool` and `--flag`, and it makes user hard to read custom
commands' signature, and hard to use them correctly.

After discussion, I think we can deprecate `--flag: bool` usage, and
encourage using `--flag` instead.

# User-Facing Changes
The following code will raise warning message, but don't stop from
running.
```nushell
❯ def florb [--dry-run: bool, --another-flag] { "aaa" };  florb
Error:   × Deprecated: --flag: bool
   ╭─[entry #7:1:1]
 1 │ def florb [--dry-run: bool, --another-flag] { "aaa" };  florb
   ·                       ──┬─
   ·                         ╰── `--flag: bool` is deprecated. Please use `--flag` instead, more info: https://www.nushell.sh/book/custom_commands.html
   ╰────

aaa
```

cc @kubouch 

# Tests + Formatting
Done

# After Submitting
- [ ] Add more information under
https://www.nushell.sh/book/custom_commands.html to indicate `--dry-run:
bool` is not allowed,
- [ ] remove `: bool` from custom commands between 0.89 and 0.90

---------

Co-authored-by: Antoine Stevan <44101798+amtoine@users.noreply.github.com>
2023-12-21 10:07:08 +01:00
109f629cb6 📝 Update str trim CLI help doc (#11383)
# Description
Hi! I updated the samples of `str trim` because there were repeated and
clarified the explanations

# User-Facing Changes
Yes! I send the details here:


![image](https://github.com/nushell/nushell/assets/30557287/e30a5612-4214-4365-8b83-7aefbc0ee825)

(`old` is version `88.1` not the latest main)

# Tests + Formatting
~~I ran `toolkit check pr` successfully~~

There was a tiny problem, a test I never touched now it's failing

```nu
(^echo a | complete) == {stdout: "a\n", exit_code: 0}
```
should output `true` but outputs `false`, both in my running `nu`
version and in my PR version
This make the test `nu-command::main commands::complete::basic` fail
located in `crates\nu-command\tests\commands\complete.rs`

# After Submitting
I'm not sure if I need to update nushell.github.io, some of the help is
auto-generated, but maybe not all?
I can file a PR if needed
2023-12-20 14:23:41 -06:00
ff6a67d293 Remove Expr::MatchPattern (#11367)
# Description
Following from #11356, it looks like `Expr::MatchPattern` is no longer
used in any way. This PR removes `Expr::MatchPattern` alongside
`Type::MatchPattern` and `SyntaxShape::MatchPattern`.

# User-Facing Changes
Breaking API change for `nu_protocol`.
2023-12-20 18:52:28 +01:00
03ae01f11e Bump itertools from 0.11.0 to 0.12.0 (#11360)
Bumps [itertools](https://github.com/rust-itertools/itertools) from
0.11.0 to 0.12.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md">itertools's
changelog</a>.</em></p>
<blockquote>
<h2>0.12.0</h2>
<h3>Breaking</h3>
<ul>
<li>Made <code>take_while_inclusive</code> consume iterator by value (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/709">#709</a>)</li>
<li>Added <code>Clone</code> bound to <code>Unique</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/777">#777</a>)</li>
</ul>
<h3>Added</h3>
<ul>
<li>Added <code>Itertools::try_len</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/723">#723</a>)</li>
<li>Added free function <code>sort_unstable</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/796">#796</a>)</li>
<li>Added <code>GroupMap::fold_with</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/778">#778</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/785">#785</a>)</li>
<li>Added <code>PeekNth::{peek_mut, peek_nth_mut}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/716">#716</a>)</li>
<li>Added <code>PeekNth::{next_if, next_if_eq}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/734">#734</a>)</li>
<li>Added conversion into <code>(Option&lt;A&gt;,Option&lt;B&gt;)</code>
to <code>EitherOrBoth</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/713">#713</a>)</li>
<li>Added conversion from <code>Either&lt;A, B&gt;</code> to
<code>EitherOrBoth&lt;A, B&gt;</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/715">#715</a>)</li>
<li>Implemented <code>ExactSizeIterator</code> for <code>Tuples</code>
(<a
href="https://redirect.github.com/rust-itertools/itertools/issues/761">#761</a>)</li>
<li>Implemented <code>ExactSizeIterator</code> for
<code>(Circular)TupleWindows</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/752">#752</a>)</li>
<li>Made <code>EitherOrBoth&lt;T&gt;</code> a shorthand for
<code>EitherOrBoth&lt;T, T&gt;</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/719">#719</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Added missing <code>#[must_use]</code> annotations on iterator
adaptors (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/794">#794</a>)</li>
<li>Made <code>Combinations</code> lazy (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/795">#795</a>)</li>
<li>Made <code>Intersperse(With)</code> lazy (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/797">#797</a>)</li>
<li>Made <code>Permutations</code> lazy (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/793">#793</a>)</li>
<li>Made <code>Product</code> lazy (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/800">#800</a>)</li>
<li>Made <code>TupleWindows</code> lazy (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/602">#602</a>)</li>
<li>Specialized <code>Combinations::{count, size_hint}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/729">#729</a>)</li>
<li>Specialized <code>CombinationsWithReplacement::{count,
size_hint}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/737">#737</a>)</li>
<li>Specialized <code>Powerset::fold</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/765">#765</a>)</li>
<li>Specialized <code>Powerset::count</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/735">#735</a>)</li>
<li>Specialized <code>TupleCombinations::{count, size_hint}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/763">#763</a>)</li>
<li>Specialized <code>TupleCombinations::fold</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/775">#775</a>)</li>
<li>Specialized <code>WhileSome::fold</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/780">#780</a>)</li>
<li>Specialized <code>WithPosition::fold</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/772">#772</a>)</li>
<li>Specialized <code>ZipLongest::fold</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/774">#774</a>)</li>
<li>Changed <code>{min, max}_set*</code> operations require
<code>alloc</code> feature, instead of <code>std</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/760">#760</a>)</li>
<li>Improved documentation of <code>tree_fold1</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/787">#787</a>)</li>
<li>Improved documentation of <code>permutations</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/724">#724</a>)</li>
<li>Fixed typo in documentation of <code>multiunzip</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/770">#770</a>)</li>
</ul>
<h3>Notable Internal Changes</h3>
<ul>
<li>Improved specialization tests (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/799">#799</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/786">#786</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/782">#782</a>)</li>
<li>Simplified implementation of <code>Permutations</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/739">#739</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/748">#748</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/790">#790</a>)</li>
<li>Combined
<code>Merge</code>/<code>MergeBy</code>/<code>MergeJoinBy</code>
implementations (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/736">#736</a>)</li>
<li>Simplified <code>Permutations::size_hint</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/739">#739</a>)</li>
<li>Fix wrapping arithmetic in benchmarks (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/770">#770</a>)</li>
<li>Enforced <code>rustfmt</code> in CI (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/751">#751</a>)</li>
<li>Disallowed compile warnings in CI (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/720">#720</a>)</li>
<li>Used <code>cargo hack</code> to check MSRV (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/754">#754</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="98ecabb47d"><code>98ecabb</code></a>
chore: Release itertools version 0.12.0</li>
<li><a
href="22fc427ac5"><code>22fc427</code></a>
prepare v0.12.0 release</li>
<li><a
href="6d291786a9"><code>6d29178</code></a>
Document the field <code>a_cur</code> of <code>Product</code></li>
<li><a
href="bf2b0129d1"><code>bf2b012</code></a>
Better <code>Product::size_hint</code></li>
<li><a
href="8d07f6b856"><code>8d07f6b</code></a>
Make <code>Product</code> lazy</li>
<li><a
href="d7e6bab9fd"><code>d7e6bab</code></a>
Document the field <code>peek</code> of
<code>IntersperseWith</code></li>
<li><a
href="9b01a11891"><code>9b01a11</code></a>
Make <code>IntersperseWith</code> lazy</li>
<li><a
href="4f22173b93"><code>4f22173</code></a>
Refactor <code>IntersperseWith::next</code></li>
<li><a
href="b76172b412"><code>b76172b</code></a>
chore: adjust docs to reflect discussion in the PR</li>
<li><a
href="955927f6c4"><code>955927f</code></a>
chore: fixup docs of tree_fold1</li>
<li>Additional commits viewable in <a
href="https://github.com/rust-itertools/itertools/compare/v0.11.0...v0.12.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=itertools&package-manager=cargo&previous-version=0.11.0&new-version=0.12.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 22:58:07 +08:00
697f3c03f1 enable flag value type checking (#11311)
# Description
Fixes: #11310

# User-Facing Changes
After the change, the following code will go to error:
```nushell
> def a [--x: int = 3] { "aa" }
> let y = "aa"
> a --x=$y
Error: nu::parser::type_mismatch

  × Type mismatch.
   ╭─[entry #32:2:1]
 2 │ let y = "aa"
 3 │ a --x=$y
   ·       ─┬
   ·        ╰── expected int, found string
   ╰────
```
2023-12-20 11:07:19 +01:00
1cecb37628 Bump shadow-rs from 0.24.1 to 0.25.0 (#11282)
Bumps [shadow-rs](https://github.com/baoyachi/shadow-rs) from 0.24.1 to
0.25.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f08828be45"><code>f08828b</code></a>
Update Cargo.toml</li>
<li><a
href="a3cc1a118f"><code>a3cc1a1</code></a>
Update README.md</li>
<li><a
href="96fdafc738"><code>96fdafc</code></a>
Merge pull request <a
href="https://redirect.github.com/baoyachi/shadow-rs/issues/144">#144</a>
from baoyachi/wasm_example</li>
<li><a
href="24d3bd82c0"><code>24d3bd8</code></a>
fix</li>
<li><a
href="aab9bf2d4d"><code>aab9bf2</code></a>
Update check.yml</li>
<li><a
href="1d4e455730"><code>1d4e455</code></a>
add wasm example</li>
<li>See full diff in <a
href="https://github.com/baoyachi/shadow-rs/compare/v0.24.1...v0.25.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=shadow-rs&package-manager=cargo&previous-version=0.24.1&new-version=0.25.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 17:49:03 +08:00
89436e978b add special emoji handling for debug --raw (#11368)
# Description

This PR add special handling in `debug -r` for emoji's so that it prints
the code points.

### Before
```nushell
❯ emoji --list | where name =~ farmer | reject utf8_bytes | get 0.emoji | debug -r
String {
    val: "🧑\u{200d}🌾",
    internal_span: Span {
        start: 0,
        end: 0,
    },
}
```

### After
```nushell
❯ emoji --list | where name =~ farmer | reject utf8_bytes | get 0.emoji | debug -r
String {
    val: "\\u{1f9d1}\\u{200d}\\u{1f33e}",
    internal_span: Span {
        start: 0,
        end: 0,
    },
}
```

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-19 13:09:31 -06:00
cd0a52cf00 Fix build for BSDs (#11372)
# Description
This PR fixes build for BSD variants (including FreeBSD and NetBSD). 

Currently, `procfs` only support linux, android and l4re, and
0cba269d80 only adds support for NetBSD,
this PR should work on all BSD variants.


b153b782a5/procfs/build.rs (L4-L8)

Fixes #11373 

# User-Facing Changes
* before

```console
nibon7@fbsd /d/s/nushell ((70f7db14))> cargo build
   Compiling tempfile v3.8.1
   Compiling procfs v0.16.0
   Compiling toml_edit v0.21.0
   Compiling native-tls v0.2.11
error: failed to run custom build command for `procfs v0.16.0`

Caused by:
  process didn't exit successfully: `/data/source/nushell/target/debug/build/procfs-d59599f40f32f0d5/build-script-build` (exit status: 1)
  --- stderr
  Building procfs on an for a unsupported platform. Currently only linux and android are supported
  (Your current target_os is freebsd)
warning: build failed, waiting for other jobs to finish...
```

* after

```console
nushell on  bsd [✘!?] is 📦 v0.88.2 via 🦀 v1.74.1
❯ version
╭────────────────────┬───────────────────────────────────────────╮
│ version            │ 0.88.2                                    │
│ branch             │ bsd                                       │
│ commit_hash        │ 151edef186  │
│ build_os           │ freebsd-x86_64                            │
│ build_target       │ x86_64-unknown-freebsd                    │
│ rust_version       │ rustc 1.74.1 (a28077b28 2023-12-04)       │
│ rust_channel       │ stable-x86_64-unknown-freebsd             │
│ cargo_version      │ cargo 1.74.1 (ecb9851af 2023-10-18)       │
│ build_time         │ 2023-12-19 10:12:15 +00:00                │
│ build_rust_channel │ debug                                     │
│ allocator          │ mimalloc                                  │
│ features           │ default, extra, sqlite, trash, which, zip │
│ installed_plugins  │                                           │
╰────────────────────┴───────────────────────────────────────────╯
nushell on  bsd [✘!?] is 📦 v0.88.2 via 🦀 v1.74.1
❯ cargo test --workspace commands::ulimit e>> /dev/null | rg ulimit
test commands::ulimit::limit_set_filesize2 ... ok
test commands::ulimit::limit_set_filesize1 ... ok
test commands::ulimit::limit_set_hard1 ... ok
test commands::ulimit::limit_set_hard2 ... ok
test commands::ulimit::limit_set_invalid1 ... ok
test commands::ulimit::limit_set_invalid3 ... ok
test commands::ulimit::limit_set_invalid4 ... ok
test commands::ulimit::limit_set_invalid5 ... ok
test commands::ulimit::limit_set_soft2 ... ok
test commands::ulimit::limit_set_soft1 ... ok
nushell on  bsd [✘!?] is 📦 v0.88.2 via 🦀 v1.74.1
```


# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-19 08:58:45 -06:00
c6043eb500 improve completions of use and overlay use (#11330)
# Description
this PR is two-fold
- make `use` and `overlay use` use the same completion algorithm in
48f29b633
- list directory modules in completions of both with 402acde5c

# User-Facing Changes
i currently have the following in my `NU_LIB_DIRS`
<details>
<summary>click to see the script</summary>

```nushell
for dir in $env.NU_LIB_DIRS {
    print $dir
    print (ls $dir --short-names | select name type)
}
```
</details>

```
/home/amtoine/.local/share/nupm/modules
#┬────────name────────┬type
0│nu-git-manager      │dir
1│nu-git-manager-sugar│dir
2│nu-hooks            │dir
3│nu-scripts          │dir
4│nu-themes           │dir
5│nupm                │dir
─┴────────────────────┴────

/home/amtoine/.config/nushell/overlays
#┬──name──┬type
0│ocaml.nu│file
─┴────────┴────
```

> **Note**
> all the samples below are run from the Nushell repo, i.e. a directory
with a `toolkit.nu` module

## before the changes
- `use` would give me `["ocaml.nu", "toolkit.nu"]` 
- `overlay use` would give me `[]` 

## after the changes
both commands give me
```nushell
[
    "nupm/",
    "ocaml.nu",
    "toolkit.nu",
    "nu-scripts/",
    "nu-git-manager/",
    "nu-git-manager-sugar/",
]
```

# Tests + Formatting
- adds a new `directory_completion/mod.nu` to the completion fixtures
- make sure `source-env`, `use` and `overlay-use` are all tested in the
_dotnu_ test
- fix all the other tests that use completions in the fixtures directory
for completions

# After Submitting
2023-12-19 17:14:34 +08:00
729373aba0 fix(cd): on android/termux fails to cd into /sdcard (#10329)
fix on android/termux fails to cd into /sdcard or any directory that
user has access via group

fixes #8095

I am not aware how this works on other platform so feel free to modify
this pr or even close it if it is not correct

# Description
on android or on linux to check if the user belongs to given directory
group, use `libc::getgroups` function

# User-Facing Changes
NA
2023-12-19 16:48:20 +08:00
f59a6990dc Refactor group-by with closure grouper (#11370)
# Description
Refactors `group_closure` in `group_by.rs` as suggested by the TODO
comment.
2023-12-19 15:48:37 +08:00
0f9094ead2 Bump crate-ci/typos from 1.16.24 to 1.16.25 (#11358)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.16.24
to 1.16.25.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.16.25</h2>
<h2>[1.16.25] - 2023-12-13</h2>
<h3>Fixes</h3>
<ul>
<li>Have correction in <code>extend-words</code> match the original
word's case</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h2>[1.16.25] - 2023-12-13</h2>
<h3>Fixes</h3>
<ul>
<li>Have correction in <code>extend-words</code> match the original
word's case</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5bd389de71"><code>5bd389d</code></a>
chore: Release</li>
<li><a
href="8dbecf3e45"><code>8dbecf3</code></a>
docs: Update changelog</li>
<li><a
href="f8f8c6edf1"><code>f8f8c6e</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/884">#884</a>
from epage/custom</li>
<li><a
href="55d802d0ef"><code>55d802d</code></a>
fix(dict): Mirror original case for custom dict</li>
<li><a
href="86c4c9fb4a"><code>86c4c9f</code></a>
test(cli): Add reproduction case</li>
<li>See full diff in <a
href="https://github.com/crate-ci/typos/compare/v1.16.24...v1.16.25">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.16.24&new-version=1.16.25)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-19 15:17:10 +08:00
70f7db14d4 Only run $env.PROMPT_COMMAND once per prompt (copy of #10986) (#11366)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

This PR is basically a copy of #10986 by @CAD97, which made
`$env.PROMPT_COMMAND` only run once per prompt, but @fdncred found an
issue where hitting Enter would make the transient prompt appear and be
immediately overwritten by the regular prompt, so it was
[reverted](https://github.com/nushell/nushell/pull/11340).
https://github.com/nushell/nushell/pull/10788 was also made to do the
same thing as #10986 but that ended up having the same issue. For some
reason, this branch doesn't have that problem, although I haven't
figured out why yet.

@CAD97, if you have any inputs or want to make your own PR, let me know.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

When hitting enter, the prompt shouldn't blink in place anymore.

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-18 09:33:04 -06:00
pin
0cba269d80 Fix build on NetBSD (#11364)
- this PR should close #11354

# Description
Allow building on NetBSD.

# User-Facing Changes
NA
2023-12-18 06:41:27 -06:00
ec2593efb8 nu-cli repl get_command_finished_marker() does not need to be pub (#11362)
```rust
fn get_command_finished_marker
```
does not need to be public so just doing a little code cleanup
2023-12-17 20:20:31 -08:00
c2283596ac Rename extra's format to format pattern (#11355)
This removes the naming conflict, introduced by `fd77114` (#11334), when
the `extra` feature is enabled.
2023-12-17 17:32:34 -06:00
c9399f5142 Downgrade openssl-src to fix riscv64 build target, close #11345 (#11353) 2023-12-18 05:57:20 +08:00
c9c93f5b4d Remove Value::MatchPattern (#11356)
# Description
`Value::MatchPattern` implies that `MatchPattern`s are first-class
values. This PR removes this case, and commands must now instead use
`Expr::MatchPattern` to extract `MatchPattern`s just like how the
`match` command does using `Expr::MatchBlock`.

# User-Facing Changes
Breaking API change for `nu_protocol` crate.
2023-12-18 07:25:34 +13:00
2264682443 fix shell integration markers (#11352)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->
Fixes #11260 

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->
Note: my issue description was a bit wrong. Issue one can't be
reproduced without a config (`shell_integration` isn't on by default,
so..), however the issue itself is still valid

For issue 1, the default prompt needs to know about the
`shell_integration` config, and the markers are added around the default
prompt when that's on.

For issue 2, this is actually related to transient prompts. When
rendering, the markers weren't added like for normal prompts.

After the fix the output do now contain the proper markers:

Reproducing the minimum config here for convenience:

```nu
$env.config = {
    show_banner: false
    shell_integration: true
}
# $env.PROMPT_COMMAND = {|| "> " }
```

For issue 1, the output looks like: 
```
[2.3490236,"o","\u001b[?25l\u001b[21;1H\u001b[21;1H\u001b[J\u001b[38;5;10m\u001b]133;A\u001b\\/home/steven\u001b]133;B\u001b\\\u001b[38;5;14m\u001b[38;5;5m\u001b7\u001b[21;84H12/16/2023 03:31:58 PM\u001b8\u001b[0m\u001b[0m\u001b[1;36mecho\u001b[0m\u001b7\u001b8\u001b[?25h"]
[2.5676293,"o","\u001b[6n"]
[2.571353,"o","\u001b[?25l\u001b[21;1H\u001b[21;1H\u001b[J\u001b[38;5;10m\u001b]133;A\u001b\\\u001b]133;A\u001b\\/home/steven\u001b]133;B\u001b\\\u001b]133;B\u001b\\\u001b[38;5;14m\u001b[38;5;5m\u001b7\u001b[21;84H12/16/2023 03:31:59 PM\u001b8\u001b[0m\u001b[0m\u001b[1;36mecho\u001b[0m\u001b7\u001b8\u001b[?25h\u001b[21;1H\r\n\u001b[21;1H"]
[2.571436,"o","\u001b[?2004l"]
[2.5714657,"o","\u001b]133;C\u001b\\"]
```
in line 3, where enter is pressed, `133 A` and `B` are present.

Same for issue 2 (uncomment the `PROMPT_COMMAND` line in the config):
```
[1.9585224,"o","\u001b[?25l\u001b[21;1H\u001b[21;1H\u001b[J\u001b[38;5;10m\u001b]133;A\u001b\\> \u001b]133;B\u001b\\\u001b[38;5;14m\u001b[38;5;5m\u001b7\u001b[21;84H12/16/2023 03:32:15 PM\u001b8\u001b[0m\u001b[0m\u001b[1;36mecho\u001b[0m\u001b7\u001b8\u001b[?25h"]
[2.453972,"o","\u001b[6n"]
[2.4585786,"o","\u001b[?25l\u001b[21;1H\u001b[21;1H\u001b[J\u001b[38;5;10m\u001b]133;A\u001b\\\u001b]133;A\u001b\\> \u001b]133;B\u001b\\\u001b]133;B\u001b\\\u001b[38;5;14m\u001b[38;5;5m\u001b7\u001b[21;84H12/16/2023 03:32:15 PM\u001b8\u001b[0m\u001b[0m\u001b[1;36mecho\u001b[0m\u001b7\u001b8\u001b[?25h\u001b[21;1H\r\n\u001b[21;1H\u001b[?2004l\u001b]133;C\u001b\\\r\n\u001b]133;D;0\u001b\\\u001b]7;file://Aostro-5468/home/steven\u001b\\\u001b]2;~\u0007\u001b[?1l"]
[2.4669976,"o","\u001b[?2004h\u001b[6n"]
[2.4703515,"o","\u001b[6n"]
[2.4736586,"o","\u001b[?25l\u001b[21;1H\u001b[21;1H\u001b[J\u001b[38;5;10m\u001b]133;A\u001b\\> \u001b]133;B\u001b\\\u001b[38;5;14m\u001b[38;5;5m\u001b7\u001b[21;84H12/16/2023 03:32:15 PM\u001b8\u001b[0m\u001b[0m\u001b7\u001b8\u001b[?25h"]
```

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

None user facing changes other than that prompt markers are working

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-16 20:12:34 -06:00
247c33b6d6 Satisfy clippy lint in benchmark (#11350)
Fixes the two `clippy::let_and_return` lints in `benchmark.rs`.
2023-12-16 21:06:42 +01:00
a6da8ce769 Allow filesize type as a valid limit value (#11349)
# Description
This pr allow us to use `filesize` type as a valid limit value, which is
benefit for some file size based limits.

# User-Facing Changes
```console
/data/source/nushell> ulimit -f                                                                                                   
╭───┬─────────────────────────────────────────────────────┬───────────┬───────────╮
│ # │                     description                     │   soft    │   hard    │
├───┼─────────────────────────────────────────────────────┼───────────┼───────────┤
│ 0 │ Maximum size of files created by the shell (kB, -f) │ unlimited │ unlimited │
╰───┴─────────────────────────────────────────────────────┴───────────┴───────────╯
/data/source/nushell> ulimit -f 10Mib                                                                                           
/data/source/nushell> ulimit -f                                                                                                    
╭───┬─────────────────────────────────────────────────────┬───────┬───────╮
│ # │                     description                     │ soft  │ hard  │
├───┼─────────────────────────────────────────────────────┼───────┼───────┤
│ 0 │ Maximum size of files created by the shell (kB, -f) │ 10240 │ 10240 │
╰───┴─────────────────────────────────────────────────────┴───────┴───────╯
/data/source/nushell> ulimit -n                                                                                                 
╭───┬──────────────────────────────────────────────┬──────┬────────╮
│ # │                 description                  │ soft │  hard  │
├───┼──────────────────────────────────────────────┼──────┼────────┤
│ 0 │ Maximum number of open file descriptors (-n) │ 1024 │ 524288 │
╰───┴──────────────────────────────────────────────┴──────┴────────╯
/data/source/nushell> ulimit -n 10Mib                                                                                            
Error: nu:🐚:type_mismatch

  × Type mismatch.
   ╭─[entry #5:1:1]
 1 │ ulimit -n 10Mib
   ·             ─┬─
   ·              ╰── filesize is not compatible with resource RLIMIT_NOFILE
   ╰────
```

# Tests + Formatting
Make sure you've run and fixed any issues with these commands:

- [x] add `commands::ulimit::limit_set_filesize1`
- [x] add `commands::ulimit::limit_set_filesize2`
- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library
2023-12-16 09:56:03 -06:00
020e121391 Bubble up errors passed to complete (#11313)
Errors passed in `PipelineData::Value` get thrown in `complete` now.

Also added two simple tests for the command.

Fix #11187
Fix #10204
2023-12-16 09:07:08 -06:00
7d5bd0d6be Allow int type as a valid limit value (#11346)
# Description
This PR allows `int` type as a valid limit value for `ulimit`, so there
is no need to use `into string` to convert limit values in the tests.

# User-Facing Changes
N/A

# Tests + Formatting
Make sure you've run and fixed any issues with these commands:
- [x] add `commands::ulimit::limit_set_invalid3`
- [x] add `commands::ulimit::limit_set_invalid4`
- [x] add `commands::ulimit::limit_set_invalid5`
- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library
2023-12-16 08:55:44 -06:00
87717b9ddd Don't redraw prompt when transient prompt disabled (#10788)
# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

moonlander pointed out in Discord that the transient prompt feature
added in release 0.86 (implemented in #10391) is causing the normal
prompt to be redrawn when the transient prompt variables are unset or
set to null. This PR is for fixing that, although it's more of a bandaid
fix. Maybe the transient prompt feature should be taken out entirely for
now so more thought can be given to its implementation.

Previously, I'd thought that when reedline redraws the prompt after a
command is entered, it's a whole new prompt, but apparently it's
actually the same prompt as the current line (?). So now, `nu_prompt` in
`repl.rs` is an `Arc<RwLock<NushellPrompt>>` (rather than just a
`NushellPrompt`), and this `Arc` is shared with the `TransientPrompt`
object so that if it can't find one of the `TRANSIENT_PROMPT_*`
variables, it uses a segment from `NushellPrompt` rather than
re-evaluate `PROMPT_COMMAND`, `PROMPT_COMMAND_RIGHT`, etc. Using an
`RwLock` means that there's a bunch of `.expect()`s all over the place,
which is not nice. It could perhaps be avoided with some changes on the
reedline side.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

`$env.PROMPT_COMMAND` (and other such variables) should no longer be
executed twice if the corresponding `$env.TRANSIENT_PROMPT_*` variable
is not set.

<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# Steps to reproduce

Described by moonlander in Discord
[here](https://discord.com/channels/601130461678272522/614593951969574961/1164928022126792844).

Adding this to `env.nu` will result in `11` being added to
`/tmp/run_count` every time any command is run. The expected behavior is
a single `1` being added to `/tmp/run_count` instead of two. The prompt
command should not be executed again when the prompt is redrawn after a
command is executed.

```nu
$env.PROMPT_COMMAND = {||
  touch /tmp/run_count
  '1' | save /tmp/run_count --append
  '>'
}

# $env.TRANSIENT_PROMPT_COMMAND not set
```

If the following is added to `env.nu`, then `12` will be added to
`/tmp/run_count` every time any command is run, which is expected
behavior because the normal prompt command must be displayed the first
time the prompt is shown, then the transient prompt command is run when
the prompt is redrawn.
```nu
$env.TRANSIENT_PROMPT_COMMAND = {||
  touch /tmp/run_count
  '2' | save /tmp/run_count --append
  '>'
}
```

Here's a screenshot of what adding that first snippet looks like (`cargo
run` in the `main` branch):

![image](https://github.com/nushell/nushell/assets/45539777/b27a5c07-55b4-43c7-8a2c-0deba2d9d53a)


Here's a screenshot of what it looks like with this PR (only one `1` is
added to `/tmp/run_count` each time):

![image](https://github.com/nushell/nushell/assets/45539777/2b5c0a3a-8566-4428-9fda-1ffcc1dd6ae3)
2023-12-15 13:41:44 -06:00
3c6fac059e Properly update to the reedline repo patch (#11342)
Follow up to #11339
2023-12-15 20:16:36 +01:00
9092fc1b12 Revert "Only run $env.PROMPT_COMMAND once per prompt" (#11340)
Reverts nushell/nushell#10986

@CAD97 This isn't working right. I have a 2 line prompt with a transient
prompt. on enter, you see the transient prompt drawn and then the normal
prompt overwrites it.
2023-12-15 11:58:32 -06:00
5b557a888e update reedline to latest + include PR 675 for testing (#11339)
# Description

This PR updates to the latest reedline main branch which includes
reedline 27.1 and reedline PR
https://github.com/nushell/reedline/pull/675 for better resize behavior.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-15 11:48:54 -06:00
398b756aee Make hover equal to help command (#11320)
# Description
Hi! A few days ago I changed the hover from `--ide-lsp` to match `help`
#11284, now this PR is doing the same but for the new `--lsp` server

I also did some tiny fixes to syntax, with some clippy `pedantic` lints

# User-Facing Changes

![image](https://github.com/nushell/nushell/assets/30557287/0e167dc8-777a-4961-8746-aa29f18eccfa)


# Tests + Formatting
 ran `toolkit check pr`
2023-12-15 11:39:19 -06:00
533c1a89af Only run $env.PROMPT_COMMAND once per prompt (#10986)
# Description

If `$env.TRANSIENT_PROMPT_COMMAND` is not set, use the prompt created by
`$env.PROMPT_COMMAND` instead of running the command a second time. As a
side effect, `$env.TRANSIENT_PROMPT_COMMAND` now runs after the hooks
`pre_prompt` and `env_change`, instead of before.

# User-Facing Changes

- `$env.PROMPT_COMMAND` gets run only once per prompt instead of twice
- `$env.TRANSIENT_PROMPT_COMMAND` now sees any environment set in a
`pre_prompt` or `env_change` hook, like `$env.PROMPT_COMMAND` does
2023-12-15 07:56:29 -06:00
84742275a1 Add ulimit command (#11324)
# Description
Add `ulimit` command to Nushell.

Closes #9563
Closes #3976

Related pr #11246

Reference:
https://github.com/fish-shell/fish-shell/blob/master/fish-rust/src/builtins/ulimit.rs
https://github.com/mirror/busybox/blob/master/shell/shell_common.c#L529

# User-Facing Changes
```
nushell on  ulimit is 📦 v0.88.2 via 🦀 v1.72.1                                                                                                [3/246]
❯ ulimit -a
╭────┬──────────────────────────────────────────────────────────────────────────┬───────────┬───────────╮
│  # │                               description                                │   soft    │   hard    │
├────┼──────────────────────────────────────────────────────────────────────────┼───────────┼───────────┤
│  0 │ Maximum size of core files created                              (kB, -c) │ unlimited │ unlimited │
│  1 │ Maximum size of a process's data segment                        (kB, -d) │ unlimited │ unlimited │
│  2 │ Controls of maximum nice priority                                   (-e) │         0 │         0 │
│  3 │ Maximum size of files created by the shell                      (kB, -f) │ unlimited │ unlimited │
│  4 │ Maximum number of pending signals                                   (-i) │     55273 │     55273 │
│  5 │ Maximum size that may be locked into memory                     (kB, -l) │      8192 │      8192 │
│  6 │ Maximum resident set size                                       (kB, -m) │ unlimited │ unlimited │
│  7 │ Maximum number of open file descriptors                             (-n) │      1024 │    524288 │
│  8 │ Maximum bytes in POSIX message queues                           (kB, -q) │       800 │       800 │
│  9 │ Maximum realtime scheduling priority                                (-r) │         0 │         0 │
│ 10 │ Maximum stack size                                              (kB, -s) │      8192 │ unlimited │
│ 11 │ Maximum amount of CPU time in seconds                      (seconds, -t) │ unlimited │ unlimited │
│ 12 │ Maximum number of processes available to the current user           (-u) │     55273 │     55273 │
│ 13 │ Maximum amount of virtual memory available to each process      (kB, -v) │ unlimited │ unlimited │
│ 14 │ Maximum number of file locks                                        (-x) │ unlimited │ unlimited │
│ 15 │ Maximum contiguous realtime CPU time                                (-y) │ unlimited │ unlimited │
╰────┴──────────────────────────────────────────────────────────────────────────┴───────────┴───────────╯
nushell on  ulimit is 📦 v0.88.2 via 🦀 v1.72.1
❯ ulimit -s
╭───┬─────────────────────────────┬──────┬───────────╮
│ # │         description         │ soft │   hard    │
├───┼─────────────────────────────┼──────┼───────────┤
│ 0 │ Maximum stack size (kB, -s) │ 8192 │ unlimited │
╰───┴─────────────────────────────┴──────┴───────────╯
nushell on  ulimit is 📦 v0.88.2 via 🦀 v1.72.1
❯ ulimit -s 100
nushell on  ulimit is 📦 v0.88.2 via 🦀 v1.72.1
❯ ulimit -s
╭───┬─────────────────────────────┬──────┬──────╮
│ # │         description         │ soft │ hard │
├───┼─────────────────────────────┼──────┼──────┤
│ 0 │ Maximum stack size (kB, -s) │  100 │  100 │
╰───┴─────────────────────────────┴──────┴──────╯
nushell on  ulimit is 📦 v0.88.2 via 🦀 v1.72.1
```

# Tests + Formatting
- [x] add commands::ulimit::limit_set_soft1
- [x] add commands::ulimit::limit_set_soft2
- [x] add commands::ulimit::limit_set_hard1
- [x] add commands::ulimit::limit_set_hard2
- [x] add commands::ulimit::limit_set_invalid1
- [x] add commands::ulimit::limit_set_invalid2
- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library
2023-12-15 07:11:17 -06:00
92d968b8c8 ♻️ Match --ide-hover with help command (#11284)
# Description
Hi! @fdncred pointed that the `help` command doesn't give the same
result as hovering a command in the VS Code extension. I digged out that
this trace back from `src/ide.rs`, so I decided to change this: (look at
the window of VS Code when hovering help)

![image](https://github.com/nushell/nushell/assets/30557287/32e24090-9238-423e-88ba-7dd6eb53d885)

into this:

![image](https://github.com/nushell/nushell/assets/30557287/51457cf7-4baf-4220-b901-66a78f7ee817)


# User-Facing Changes
The `--ide-hover` change a lot, by matching the `help` command of the
terminal nushell

The only missing part is the `subcommands` part

# Tests + Formatting
All good!

# After Submitting
2023-12-15 07:00:08 -06:00
50102bf69b Move history into their own module (#11308)
# Description

Since there are plans to add more history commands, it seems sensible to
put them into their own module and category

https://github.com/nushell/nushell/pull/10440#issuecomment-1731408785

# User-Facing Changes

The history commands are in the category "History" rather than "Misc"
2023-12-15 13:17:12 +01:00
156232fe08 disable directory submodule auto export (#11157)
should
- close https://github.com/nushell/nushell/issues/11133

# Description
to allow more freedom when writing complex modules, we are disabling the
auto-export of director modules.

the change was as simple as removing the crawling of files and modules
next to any `mod.nu` and update the standard library.

# User-Facing Changes
users will have to explicitely use `export module <mod>` to define
submodules and `export use <mod> <cmd>` to re-export definitions, e.g.
```nushell
# my-module/mod.nu
export module foo.nu     # export a submodule
export use bar.nu bar-1  # re-export an internal command

export def top [] {
    print "`top` from `mod.nu`"
}
```
```nushell
# my-module/foo.nu
export def "foo-1" [] {
    print "`foo-1` from `lib/foo.nu`"
}

export def "foo-2" [] {
    print "`foo-2` from `lib/foo.nu`"
}
```
```nushell
# my-module/bar.nu
export def "bar-1" [] {
    print "`bar-1` from `lib/bar.nu`"
}
```

# Tests + Formatting
i had to add `export module` calls in the `tests/modules/samples/spam`
directory module and allow the `not_allowed` module to not give an
error, it is just empty, which is fine.

# After Submitting
- mention in the release note
- update the following repos
```
#┬─────name─────┬version┬─type─┬─────────repo─────────
0│nu-git-manager│0.4.0  │module│amtoine/nu-git-manager
1│nu-scripts    │0.1.0  │module│amtoine/scripts       
2│nu-zellij     │0.1.0  │module│amtoine/zellij-layouts
3│nu-scripts    │0.1.0  │module│nushell/nu_scripts    
4│nupm          │0.1.0  │module│nushell/nupm          
─┴──────────────┴───────┴──────┴──────────────────────
```
2023-12-15 12:37:55 +01:00
0a3761a594 Bump zerocopy from 0.7.29 to 0.7.31 (#11336) 2023-12-15 10:40:56 +00:00
44dc890124 Polars Struct support without unsafe blocks (#11229)
Second attempt at polars Struct support. This version avoid using unsafe
checks by cloning the StructArray and utilizing the into_static to
convert to a StructOwned.

---------

Co-authored-by: Jack Wright <jack.wright@disqo.com>
2023-12-15 11:21:30 +01:00
6ead98effb Bump actions/setup-python from 4 to 5 (#11279)
Bumps [actions/setup-python](https://github.com/actions/setup-python)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-python/releases">actions/setup-python's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<p>In scope of this release, we update node version runtime from node16
to node20 (<a
href="https://redirect.github.com/actions/setup-python/pull/772">actions/setup-python#772</a>).
Besides, we update dependencies to the latest versions.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v4.8.0...v5.0.0">https://github.com/actions/setup-python/compare/v4.8.0...v5.0.0</a></p>
<h2>v4.8.0</h2>
<h2>What's Changed</h2>
<p>In scope of this release we added support for GraalPy (<a
href="https://redirect.github.com/actions/setup-python/pull/694">actions/setup-python#694</a>).
You can use this snippet to set up GraalPy:</p>
<pre lang="yaml"><code>steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4 
  with:
    python-version: 'graalpy-22.3' 
- run: python my_script.py
</code></pre>
<p>Besides, the release contains such changes as:</p>
<ul>
<li>Trim python version when reading from file by <a
href="https://github.com/FerranPares"><code>@​FerranPares</code></a> in
<a
href="https://redirect.github.com/actions/setup-python/pull/628">actions/setup-python#628</a></li>
<li>Use non-deprecated versions in examples by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/724">actions/setup-python#724</a></li>
<li>Change deprecation comment to past tense by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/723">actions/setup-python#723</a></li>
<li>Bump <code>@​babel/traverse</code> from 7.9.0 to 7.23.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/743">actions/setup-python#743</a></li>
<li>advanced-usage.md: Encourage the use actions/checkout@v4 by <a
href="https://github.com/cclauss"><code>@​cclauss</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/729">actions/setup-python#729</a></li>
<li>Examples now use checkout@v4 by <a
href="https://github.com/simonw"><code>@​simonw</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/738">actions/setup-python#738</a></li>
<li>Update actions/checkout to v4 by <a
href="https://github.com/dmitry-shibanov"><code>@​dmitry-shibanov</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/761">actions/setup-python#761</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/FerranPares"><code>@​FerranPares</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-python/pull/628">actions/setup-python#628</a></li>
<li><a href="https://github.com/timfel"><code>@​timfel</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-python/pull/694">actions/setup-python#694</a></li>
<li><a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-python/pull/724">actions/setup-python#724</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v4...v4.8.0">https://github.com/actions/setup-python/compare/v4...v4.8.0</a></p>
<h2>v4.7.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump word-wrap from 1.2.3 to 1.2.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/702">actions/setup-python#702</a></li>
<li>Add range validation for toml files by <a
href="https://github.com/dmitry-shibanov"><code>@​dmitry-shibanov</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/726">actions/setup-python#726</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v4...v4.7.1">https://github.com/actions/setup-python/compare/v4...v4.7.1</a></p>
<h2>v4.7.0</h2>
<p>In scope of this release, the support for reading python version from
pyproject.toml was added (<a
href="https://redirect.github.com/actions/setup-python/pull/669">actions/setup-python#669</a>).</p>
<pre lang="yaml"><code>      - name: Setup Python
        uses: actions/setup-python@v4
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0a5c615913"><code>0a5c615</code></a>
Update action to node20 (<a
href="https://redirect.github.com/actions/setup-python/issues/772">#772</a>)</li>
<li><a
href="0ae58361cd"><code>0ae5836</code></a>
Add example of GraalPy to docs (<a
href="https://redirect.github.com/actions/setup-python/issues/773">#773</a>)</li>
<li><a
href="b64ffcaf5b"><code>b64ffca</code></a>
update actions/checkout to v4 (<a
href="https://redirect.github.com/actions/setup-python/issues/761">#761</a>)</li>
<li><a
href="8d2896179a"><code>8d28961</code></a>
Examples now use checkout@v4 (<a
href="https://redirect.github.com/actions/setup-python/issues/738">#738</a>)</li>
<li><a
href="7bc6abb01e"><code>7bc6abb</code></a>
advanced-usage.md: Encourage the use actions/checkout@v4 (<a
href="https://redirect.github.com/actions/setup-python/issues/729">#729</a>)</li>
<li><a
href="e8111cec9d"><code>e8111ce</code></a>
Bump <code>@​babel/traverse</code> from 7.9.0 to 7.23.2 (<a
href="https://redirect.github.com/actions/setup-python/issues/743">#743</a>)</li>
<li><a
href="a00ea43da6"><code>a00ea43</code></a>
add fix for graalpy ci (<a
href="https://redirect.github.com/actions/setup-python/issues/741">#741</a>)</li>
<li><a
href="8635b1ccc5"><code>8635b1c</code></a>
Change deprecation comment to past tense (<a
href="https://redirect.github.com/actions/setup-python/issues/723">#723</a>)</li>
<li><a
href="f6cc428f53"><code>f6cc428</code></a>
Use non-deprecated versions in examples (<a
href="https://redirect.github.com/actions/setup-python/issues/724">#724</a>)</li>
<li><a
href="5f2af211d6"><code>5f2af21</code></a>
Add GraalPy support (<a
href="https://redirect.github.com/actions/setup-python/issues/694">#694</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/setup-python/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-python&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-15 15:31:18 +08:00
d5f76c02f0 Bump crate-ci/typos from 1.16.23 to 1.16.24 (#11280)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.16.23
to 1.16.24.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.16.24</h2>
<h2>[1.16.24] - 2023-12-08</h2>
<h3>Fixes</h3>
<ul>
<li>Don't silently ignore config when there is an error in a field</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h2>[1.16.24] - 2023-12-08</h2>
<h3>Fixes</h3>
<ul>
<li>Don't silently ignore config when there is an error in a field</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="548ac37a5d"><code>548ac37</code></a>
chore: Release</li>
<li><a
href="a838b1820f"><code>a838b18</code></a>
chore: Release</li>
<li><a
href="44e4455f33"><code>44e4455</code></a>
docs: Update changelog</li>
<li><a
href="4362a6e5e4"><code>4362a6e</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/882">#882</a>
from epage/regex</li>
<li><a
href="1b92c0182c"><code>1b92c01</code></a>
fix(config): Propagate validation errors</li>
<li><a
href="632b256901"><code>632b256</code></a>
test: Demonstrate bad config bug</li>
<li><a
href="8dec26e3c6"><code>8dec26e</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/879">#879</a>
from epage/update</li>
<li><a
href="69f4b1eaff"><code>69f4b1e</code></a>
chore: Move off deprecated</li>
<li><a
href="cb9b485bd3"><code>cb9b485</code></a>
chore: Update from '_rust/main'</li>
<li><a
href="8c836eaa9d"><code>8c836ea</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/10">#10</a> from
epage/renovate/migrate-config</li>
<li>Additional commits viewable in <a
href="https://github.com/crate-ci/typos/compare/v1.16.23...v1.16.24">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.16.23&new-version=1.16.24)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-15 15:31:04 +08:00
fd77114d82 Add format meta command (#11334) 2023-12-15 14:57:18 +08:00
78f52e8b66 Replace bash with POSIX sh in tests (#11293)
Just my small pet peeve. This allows to run tests without bash
installed.

There were only two minor tests which required a change.
2023-12-15 14:53:19 +08:00
5b01685fc3 Enforce required, optional, and rest positional arguments start with an uppercase and end with a period. (#11285)
# Description

This updates all the positional arguments (except with
`--features=dataframe` or `--features=extra`) to start with an uppercase
letter and end with a period.

Part of #5066, specifically [this
comment](/nushell/nushell/issues/5066#issuecomment-1421528910)

Some arguments had example data removed from them because it also
appears in the examples.

There are other inconsistencies in positional arguments I noticed while
making the tests pass which I will bring up in #5066.

# User-Facing Changes

Positional arguments are now consistent

# Tests + Formatting

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting

Automatic documentation updates
2023-12-15 14:32:37 +08:00
c2b684464f Bump version to 0.88.2 (#11333) 2023-12-14 13:55:48 -06:00
fd56768fdc Bump version to 0.88.1 (#11303) 2023-12-14 18:14:47 +01:00
070afa4528 Revert lock file changes due to openssl build fail (#11328)
A theoretically semver compatible version bump of dependencies in the
`Cargo.lock` was part of #11302. The particular upstream openSSL version
pulled in by that fails to build on our RISC-V build config (3.2.0)

- https://github.com/nushell/nushell/pull/11302#issuecomment-1856011363
-
https://github.com/nushell/nightly/actions/runs/7210339119/job/19643253780

So far no updated openssl release is available or it is unclear how the
runner needs to be configured to avoid the issue described in:

- https://github.com/openssl/openssl/issues/22871

Out of abundance of caution let's try to revert this version bump and
try to figure out a solution later, so we can ship our `0.88.1` patch
release.
2023-12-14 18:09:28 +01:00
23fec8eb0d Fix piping output logic (#11317)
# Description
Fixes: #11295

Sorry for introducing such issue.
The issue is caused by we wrongly set `redirect_stdout` and
`redirect_stderr` during eval, take the following as example:
```nushell
ls | bat --paging always
```
When running `bat --paging always`, `redirect_stdout` should be `false`.
But before this pr, it's set to true due to `ls` command, and then the
`true` value will go to all remaining commands.

# User-Facing Changes
NaN

# Tests + Formatting
Sorry I don't think we have a way to test it. Because it needs to be
tested on interactive command like `nvim`.

# After Submitting
NaN
2023-12-13 13:16:23 -06:00
c9841f67e9 fix-open-is-ambiguous (#11302)
# Description
Running `cargo install nu` on rustc 1.71.1 (eb26296b5 2023-08-03)
produced the following error message when reaching `nu-command v0.88.0`:
```sh
error[E0659]: `open` is ambiguous
  --> /home/antoine/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nu-command-0.88.0/src/stor/mod.rs:30:9
   |
30 | pub use open::StorOpen;
   |         ^^^^ ambiguous name
   |
   = note: ambiguous because of multiple potential import sources
   = note: `open` could refer to a crate passed with `--extern`
   = help: use `::open` to refer to this crate unambiguously
note: `open` could also refer to the module defined here
  --> /home/antoine/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nu-command-0.88.0/src/stor/mod.rs:12:1
   |
12 | mod open;
   | ^^^^^^^^^
   = help: use `self::open` to refer to this module unambiguously

   Compiling nu-cli v0.88.0
   Compiling nu-lsp v0.88.0
For more information about this error, try `rustc --explain E0659`.
error: could not compile `nu-command` (lib) due to previous error
warning: build failed, waiting for other jobs to finish...
error: failed to compile `nu v0.88.0`, intermediate artifacts can be found at `/tmp/cargo-installEUsfIr`
```

# User-Facing Changes
No user-facing changes.
2023-12-13 13:08:00 -06:00
76482cc1b2 Move stor commands to category Database (#11315)
Fixes #11309
2023-12-13 16:24:16 +01:00
363 changed files with 4281 additions and 2428 deletions

1
.github/.typos.toml vendored
View File

@ -12,3 +12,4 @@ IIF = "IIF"
numer = "numer"
ratatui = "ratatui"
doas = "doas"
wheres = "wheres"

View File

@ -92,6 +92,17 @@ jobs:
- name: Tests
run: cargo test --workspace --profile ci --exclude nu_plugin_* ${{ matrix.flags }}
- name: Check for clean repo
shell: bash
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "there are changes";
git status --porcelain
exit 1
else
echo "no changes in working directory";
fi
std-lib-and-python-virtualenv:
strategy:
fail-fast: true
@ -117,7 +128,7 @@ jobs:
run: nu -c 'use std testing; testing run-tests --path crates/nu-std'
- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.10"
@ -129,6 +140,17 @@ jobs:
run: nu scripts/test_virtualenv.nu
shell: bash
- name: Check for clean repo
shell: bash
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "there are changes";
git status --porcelain
exit 1
else
echo "no changes in working directory";
fi
plugins:
strategy:
fail-fast: true
@ -150,3 +172,14 @@ jobs:
- name: Tests
run: cargo test --profile ci --package nu_plugin_*
- name: Check for clean repo
shell: bash
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "there are changes";
git status --porcelain
exit 1
else
echo "no changes in working directory";
fi

View File

@ -119,7 +119,7 @@ jobs:
os: ubuntu-20.04
target_rustflags: ''
- target: riscv64gc-unknown-linux-gnu
os: ubuntu-20.04
os: ubuntu-latest
target_rustflags: ''
runs-on: ${{matrix.os}}

View File

@ -82,8 +82,8 @@ print $'Start building ($bin)...'; hr-line
# ----------------------------------------------------------------------------
# Build for Ubuntu and macOS
# ----------------------------------------------------------------------------
if $os in [$USE_UBUNTU, 'macos-latest'] {
if $os == $USE_UBUNTU {
if $os in [$USE_UBUNTU, 'macos-latest', 'ubuntu-latest'] {
if $os starts-with ubuntu {
sudo apt update
sudo apt-get install libxcb-composite0-dev -y
}
@ -106,7 +106,7 @@ if $os in [$USE_UBUNTU, 'macos-latest'] {
_ => {
# musl-tools to fix 'Failed to find tool. Is `musl-gcc` installed?'
# Actually just for x86_64-unknown-linux-musl target
if $os == $USE_UBUNTU { sudo apt install musl-tools -y }
if $os starts-with ubuntu { sudo apt install musl-tools -y }
cargo-build-nu $flags
}
}
@ -153,7 +153,7 @@ if ($ver | str trim | is-empty) {
# Create a release archive and send it to output for the following steps
# ----------------------------------------------------------------------------
cd $dist; print $'(char nl)Creating release archive...'; hr-line
if $os in [$USE_UBUNTU, 'macos-latest'] {
if $os in [$USE_UBUNTU, 'macos-latest', 'ubuntu-latest'] {
let files = (ls | get name)
let dest = if $env.RELEASE_TYPE == 'full' { $'($bin)-($version)-($FULL_NAME)' } else { $'($bin)-($version)-($target)' }

View File

@ -66,7 +66,7 @@ jobs:
os: ubuntu-20.04
target_rustflags: ''
- target: riscv64gc-unknown-linux-gnu
os: ubuntu-20.04
os: ubuntu-latest
target_rustflags: ''
runs-on: ${{matrix.os}}

View File

@ -10,6 +10,6 @@ jobs:
uses: actions/checkout@v4
- name: Check spelling
uses: crate-ci/typos@v1.16.23
uses: crate-ci/typos@v1.17.0
with:
config: ./.github/.typos.toml

377
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,8 @@ homepage = "https://www.nushell.sh"
license = "MIT"
name = "nu"
repository = "https://github.com/nushell/nushell"
rust-version = "1.60"
version = "0.88.0"
rust-version = "1.72.1"
version = "0.88.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -33,7 +33,11 @@ members = [
"crates/nu-cmd-lang",
"crates/nu-cmd-dataframe",
"crates/nu-command",
"crates/nu-color-config",
"crates/nu-explore",
"crates/nu-json",
"crates/nu-lsp",
"crates/nu-pretty-hex",
"crates/nu-protocol",
"crates/nu-plugin",
"crates/nu_plugin_inc",
@ -43,31 +47,34 @@ members = [
"crates/nu_plugin_custom_values",
"crates/nu_plugin_formats",
"crates/nu-std",
"crates/nu-table",
"crates/nu-term-grid",
"crates/nu-utils",
]
[dependencies]
nu-cli = { path = "./crates/nu-cli", version = "0.88.0" }
nu-color-config = { path = "./crates/nu-color-config", version = "0.88.0" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.88.0" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.88.0" }
nu-cmd-dataframe = { path = "./crates/nu-cmd-dataframe", version = "0.88.0", features = ["dataframe"], optional = true }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.88.0", optional = true }
nu-command = { path = "./crates/nu-command", version = "0.88.0" }
nu-engine = { path = "./crates/nu-engine", version = "0.88.0" }
nu-explore = { path = "./crates/nu-explore", version = "0.88.0" }
nu-json = { path = "./crates/nu-json", version = "0.88.0" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.88.0" }
nu-parser = { path = "./crates/nu-parser", version = "0.88.0" }
nu-path = { path = "./crates/nu-path", version = "0.88.0" }
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.88.0" }
nu-pretty-hex = { path = "./crates/nu-pretty-hex", version = "0.88.0" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.88.0" }
nu-system = { path = "./crates/nu-system", version = "0.88.0" }
nu-table = { path = "./crates/nu-table", version = "0.88.0" }
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.88.0" }
nu-std = { path = "./crates/nu-std", version = "0.88.0" }
nu-utils = { path = "./crates/nu-utils", version = "0.88.0" }
nu-cli = { path = "./crates/nu-cli", version = "0.88.2" }
nu-color-config = { path = "./crates/nu-color-config", version = "0.88.2" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.88.2" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.88.2" }
nu-cmd-dataframe = { path = "./crates/nu-cmd-dataframe", version = "0.88.2", features = ["dataframe"], optional = true }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.88.2", optional = true }
nu-command = { path = "./crates/nu-command", version = "0.88.2" }
nu-engine = { path = "./crates/nu-engine", version = "0.88.2" }
nu-explore = { path = "./crates/nu-explore", version = "0.88.2" }
nu-json = { path = "./crates/nu-json", version = "0.88.2" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.88.2" }
nu-parser = { path = "./crates/nu-parser", version = "0.88.2" }
nu-path = { path = "./crates/nu-path", version = "0.88.2" }
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.88.2" }
nu-pretty-hex = { path = "./crates/nu-pretty-hex", version = "0.88.2" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.88.2" }
nu-system = { path = "./crates/nu-system", version = "0.88.2" }
nu-table = { path = "./crates/nu-table", version = "0.88.2" }
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.88.2" }
nu-std = { path = "./crates/nu-std", version = "0.88.2" }
nu-utils = { path = "./crates/nu-utils", version = "0.88.2" }
nu-ansi-term = "0.49.0"
reedline = { version = "0.27.0", features = ["bashisms", "sqlite"] }
@ -97,7 +104,7 @@ nix = { version = "0.27", default-features = false, features = [
] }
[dev-dependencies]
nu-test-support = { path = "./crates/nu-test-support", version = "0.88.0" }
nu-test-support = { path = "./crates/nu-test-support", version = "0.88.2" }
assert_cmd = "2.0"
criterion = "0.5"
pretty_assertions = "1.4"
@ -166,7 +173,7 @@ bench = false
# 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
[patch.crates-io]
# reedline = { git = "https://github.com/nushell/reedline.git", branch = "main" }
reedline = { git = "https://github.com/nushell/reedline.git", branch = "main" }
# nu-ansi-term = {git = "https://github.com/nushell/nu-ansi-term.git", branch = "main"}
# uu_cp = { git = "https://github.com/uutils/coreutils.git", branch = "main" }

View File

@ -24,13 +24,9 @@ fn canonicalize_path(engine_state: &EngineState, path: &Path) -> PathBuf {
}
fn get_home_path(engine_state: &EngineState) -> PathBuf {
let home_path = if let Some(path) = nu_path::home_dir() {
let canon_home_path = canonicalize_path(engine_state, &path);
canon_home_path
} else {
std::path::PathBuf::new()
};
home_path
nu_path::home_dir()
.map(|path| canonicalize_path(engine_state, &path))
.unwrap_or_default()
}
// FIXME: All benchmarks live in this 1 file to speed up build times when benchmarking.

View File

@ -5,31 +5,31 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cli"
edition = "2021"
license = "MIT"
name = "nu-cli"
version = "0.88.0"
version = "0.88.2"
[lib]
bench = false
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.0" }
nu-command = { path = "../nu-command", version = "0.88.0" }
nu-test-support = { path = "../nu-test-support", version = "0.88.0" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.2" }
nu-command = { path = "../nu-command", version = "0.88.2" }
nu-test-support = { path = "../nu-test-support", version = "0.88.2" }
rstest = { version = "0.18.1", default-features = false }
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.88.0" }
nu-engine = { path = "../nu-engine", version = "0.88.0" }
nu-path = { path = "../nu-path", version = "0.88.0" }
nu-parser = { path = "../nu-parser", version = "0.88.0" }
nu-protocol = { path = "../nu-protocol", version = "0.88.0" }
nu-utils = { path = "../nu-utils", version = "0.88.0" }
nu-color-config = { path = "../nu-color-config", version = "0.88.0" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.88.2" }
nu-engine = { path = "../nu-engine", version = "0.88.2" }
nu-path = { path = "../nu-path", version = "0.88.2" }
nu-parser = { path = "../nu-parser", version = "0.88.2" }
nu-protocol = { path = "../nu-protocol", version = "0.88.2" }
nu-utils = { path = "../nu-utils", version = "0.88.2" }
nu-color-config = { path = "../nu-color-config", version = "0.88.2" }
nu-ansi-term = "0.49.0"
reedline = { version = "0.27.0", features = ["bashisms", "sqlite"] }
chrono = { default-features = false, features = ["std"], version = "0.4" }
crossterm = "0.27"
fancy-regex = "0.11"
fancy-regex = "0.12"
fuzzy-matcher = "0.3"
is_executable = "1.0"
log = "0.4"
@ -37,7 +37,7 @@ miette = { version = "5.10", features = ["fancy-no-backtrace"] }
once_cell = "1.18"
percent-encoding = "2"
pathdiff = "0.2"
sysinfo = "0.29"
sysinfo = "0.30"
unicode-segmentation = "1.10"
uuid = { version = "1.6.0", features = ["v4"] }
which = "5.0.0"

View File

@ -34,7 +34,7 @@ impl Command for History {
"Show long listing of entries for sqlite history",
Some('l'),
)
.category(Category::Misc)
.category(Category::History)
}
fn run(

View File

@ -18,7 +18,7 @@ impl Command for HistorySession {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("history session")
.category(Category::Misc)
.category(Category::History)
.input_output_types(vec![(Type::Nothing, Type::Int)])
}

View File

@ -0,0 +1,5 @@
mod history_;
mod history_session;
pub use history_::History;
pub use history_session::HistorySession;

View File

@ -1,15 +1,13 @@
mod commandline;
mod default_context;
mod history;
mod history_session;
mod keybindings;
mod keybindings_default;
mod keybindings_list;
mod keybindings_listen;
pub use commandline::Commandline;
pub use history::History;
pub use history_session::HistorySession;
pub use history::{History, HistorySession};
pub use keybindings::Keybindings;
pub use keybindings_default::KeybindingsDefault;
pub use keybindings_list::KeybindingsList;

View File

@ -250,7 +250,9 @@ impl NuCompleter {
working_set.get_span_contents(previous_expr.0).to_vec();
// Completion for .nu files
if prev_expr_str == b"use" || prev_expr_str == b"source-env"
if prev_expr_str == b"use"
|| prev_expr_str == b"overlay use"
|| prev_expr_str == b"source-env"
{
let mut completer =
DotNuCompletion::new(self.engine_state.clone());
@ -352,9 +354,7 @@ impl NuCompleter {
if let Some(external_result) = self.external_completion(
block_id, &spans, offset, new_span,
) {
if !external_result.is_empty() {
return external_result;
}
return external_result;
}
}

View File

@ -22,7 +22,10 @@ fn complete_rec(
Some(base) if matches(base, &entry_name, options) => {
let partial = &partial[1..];
if !partial.is_empty() || isdir {
completions.extend(complete_rec(partial, &path, options, dir, isdir))
completions.extend(complete_rec(partial, &path, options, dir, isdir));
if entry_name.eq(base) {
break;
}
} else {
completions.push(path)
}

View File

@ -5,7 +5,7 @@ use nu_protocol::{
};
use reedline::Suggestion;
use std::{
path::{is_separator, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR},
path::{is_separator, Path, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR},
sync::Arc,
};
@ -91,16 +91,21 @@ impl Completer for DotNuCompletion {
// and transform them into suggestions
let output: Vec<Suggestion> = search_dirs
.into_iter()
.flat_map(|it| {
file_path_completion(span, &partial, &it, options)
.flat_map(|search_dir| {
let completions = file_path_completion(span, &partial, &search_dir, options);
completions
.into_iter()
.filter(|it| {
.filter(move |it| {
// Different base dir, so we list the .nu files or folders
if !is_current_folder {
it.1.ends_with(".nu") || it.1.ends_with(SEP)
} else {
// Lib dirs, so we filter only the .nu files
it.1.ends_with(".nu")
// Lib dirs, so we filter only the .nu files or directory modules
if it.1.ends_with(SEP) {
Path::new(&search_dir).join(&it.1).join("mod.nu").exists()
} else {
it.1.ends_with(".nu")
}
}
})
.map(move |x| Suggestion {

View File

@ -35,6 +35,10 @@ pub fn evaluate_commands(
let mut working_set = StateWorkingSet::new(engine_state);
let output = parse(&mut working_set, None, commands.item.as_bytes(), false);
if let Some(warning) = working_set.parse_warnings.first() {
report_error(&working_set, warning);
}
if let Some(err) = working_set.parse_errors.first() {
report_error(&working_set, err);

View File

@ -1,3 +1,4 @@
use crate::prompt_update::{POST_PROMPT_MARKER, PRE_PROMPT_MARKER};
#[cfg(windows)]
use nu_utils::enable_vt_processing;
use reedline::DefaultPrompt;
@ -11,6 +12,7 @@ use {
/// Nushell prompt definition
#[derive(Clone)]
pub struct NushellPrompt {
shell_integration: bool,
left_prompt_string: Option<String>,
right_prompt_string: Option<String>,
default_prompt_indicator: Option<String>,
@ -20,15 +22,10 @@ pub struct NushellPrompt {
render_right_prompt_on_last_line: bool,
}
impl Default for NushellPrompt {
fn default() -> Self {
NushellPrompt::new()
}
}
impl NushellPrompt {
pub fn new() -> NushellPrompt {
pub fn new(shell_integration: bool) -> NushellPrompt {
NushellPrompt {
shell_integration,
left_prompt_string: None,
right_prompt_string: None,
default_prompt_indicator: None,
@ -111,7 +108,11 @@ impl Prompt for NushellPrompt {
.to_string()
.replace('\n', "\r\n");
prompt.into()
if self.shell_integration {
format!("{PRE_PROMPT_MARKER}{prompt}{POST_PROMPT_MARKER}").into()
} else {
prompt.into()
}
}
}

View File

@ -7,8 +7,6 @@ use nu_protocol::{
Config, PipelineData, Value,
};
use reedline::Prompt;
use std::borrow::Cow;
use std::sync::Arc;
// Name of environment variable where the prompt could be stored
pub(crate) const PROMPT_COMMAND: &str = "PROMPT_COMMAND";
@ -28,8 +26,8 @@ pub(crate) const TRANSIENT_PROMPT_MULTILINE_INDICATOR: &str =
"TRANSIENT_PROMPT_MULTILINE_INDICATOR";
// According to Daniel Imms @Tyriar, we need to do these this way:
// <133 A><prompt><133 B><command><133 C><command output>
const PRE_PROMPT_MARKER: &str = "\x1b]133;A\x1b\\";
const POST_PROMPT_MARKER: &str = "\x1b]133;B\x1b\\";
pub(crate) const PRE_PROMPT_MARKER: &str = "\x1b]133;A\x1b\\";
pub(crate) const POST_PROMPT_MARKER: &str = "\x1b]133;B\x1b\\";
fn get_prompt_string(
prompt: &str,
@ -98,12 +96,12 @@ fn get_prompt_string(
})
}
pub(crate) fn update_prompt<'prompt>(
pub(crate) fn update_prompt(
config: &Config,
engine_state: &EngineState,
stack: &Stack,
nu_prompt: &'prompt mut NushellPrompt,
) -> &'prompt dyn Prompt {
nu_prompt: &mut NushellPrompt,
) {
let mut stack = stack.clone();
let left_prompt_string = get_prompt_string(PROMPT_COMMAND, config, engine_state, &mut stack);
@ -146,125 +144,55 @@ pub(crate) fn update_prompt<'prompt>(
(prompt_vi_insert_string, prompt_vi_normal_string),
config.render_right_prompt_on_last_line,
);
let ret_val = nu_prompt as &dyn Prompt;
trace!("update_prompt {}:{}:{}", file!(), line!(), column!());
ret_val
}
struct TransientPrompt {
engine_state: Arc<EngineState>,
stack: Stack,
}
/// Try getting `$env.TRANSIENT_PROMPT_<X>`, and get `$env.PROMPT_<X>` if that fails
fn get_transient_prompt_string(
transient_prompt: &str,
prompt: &str,
/// Construct the transient prompt based on the normal nu_prompt
pub(crate) fn make_transient_prompt(
config: &Config,
engine_state: &EngineState,
stack: &mut Stack,
) -> Option<String> {
get_prompt_string(transient_prompt, config, engine_state, stack)
.or_else(|| get_prompt_string(prompt, config, engine_state, stack))
}
nu_prompt: &NushellPrompt,
) -> Box<dyn Prompt> {
let mut nu_prompt = nu_prompt.clone();
impl Prompt for TransientPrompt {
fn render_prompt_left(&self) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_left(get_transient_prompt_string(
TRANSIENT_PROMPT_COMMAND,
PROMPT_COMMAND,
config,
&self.engine_state,
&mut stack,
));
nu_prompt.render_prompt_left().to_string().into()
if let Some(s) = get_prompt_string(TRANSIENT_PROMPT_COMMAND, config, engine_state, stack) {
nu_prompt.update_prompt_left(Some(s))
}
fn render_prompt_right(&self) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_right(
get_transient_prompt_string(
TRANSIENT_PROMPT_COMMAND_RIGHT,
PROMPT_COMMAND_RIGHT,
config,
&self.engine_state,
&mut stack,
),
config.render_right_prompt_on_last_line,
);
nu_prompt.render_prompt_right().to_string().into()
if let Some(s) = get_prompt_string(TRANSIENT_PROMPT_COMMAND_RIGHT, config, engine_state, stack)
{
nu_prompt.update_prompt_right(Some(s), config.render_right_prompt_on_last_line)
}
fn render_prompt_indicator(&self, prompt_mode: reedline::PromptEditMode) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_indicator(get_transient_prompt_string(
TRANSIENT_PROMPT_INDICATOR,
PROMPT_INDICATOR,
config,
&self.engine_state,
&mut stack,
));
nu_prompt.update_prompt_vi_insert(get_transient_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_INSERT,
PROMPT_INDICATOR_VI_INSERT,
config,
&self.engine_state,
&mut stack,
));
nu_prompt.update_prompt_vi_normal(get_transient_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_NORMAL,
PROMPT_INDICATOR_VI_NORMAL,
config,
&self.engine_state,
&mut stack,
));
nu_prompt
.render_prompt_indicator(prompt_mode)
.to_string()
.into()
if let Some(s) = get_prompt_string(TRANSIENT_PROMPT_INDICATOR, config, engine_state, stack) {
nu_prompt.update_prompt_indicator(Some(s))
}
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_multiline(get_transient_prompt_string(
TRANSIENT_PROMPT_MULTILINE_INDICATOR,
PROMPT_MULTILINE_INDICATOR,
config,
&self.engine_state,
&mut stack,
));
nu_prompt
.render_prompt_multiline_indicator()
.to_string()
.into()
}
fn render_prompt_history_search_indicator(
&self,
history_search: reedline::PromptHistorySearch,
) -> Cow<str> {
NushellPrompt::new()
.render_prompt_history_search_indicator(history_search)
.to_string()
.into()
}
}
/// Construct the transient prompt
pub(crate) fn transient_prompt(engine_state: Arc<EngineState>, stack: &Stack) -> Box<dyn Prompt> {
Box::new(TransientPrompt {
if let Some(s) = get_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_INSERT,
config,
engine_state,
stack: stack.clone(),
})
stack,
) {
nu_prompt.update_prompt_vi_insert(Some(s))
}
if let Some(s) = get_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_NORMAL,
config,
engine_state,
stack,
) {
nu_prompt.update_prompt_vi_normal(Some(s))
}
if let Some(s) = get_prompt_string(
TRANSIENT_PROMPT_MULTILINE_INDICATOR,
config,
engine_state,
stack,
) {
nu_prompt.update_prompt_multiline(Some(s))
}
Box::new(nu_prompt)
}

View File

@ -32,7 +32,7 @@ use std::{
sync::atomic::Ordering,
time::Instant,
};
use sysinfo::SystemExt;
use sysinfo::System;
// According to Daniel Imms @Tyriar, we need to do these this way:
// <133 A><prompt><133 B><command><133 C><command output>
@ -54,7 +54,8 @@ pub fn evaluate_repl(
) -> Result<()> {
use nu_cmd_base::hook;
use reedline::Signal;
let use_color = engine_state.get_config().use_ansi_coloring;
let config = engine_state.get_config();
let use_color = config.use_ansi_coloring;
// Guard against invocation without a connected terminal.
// reedline / crossterm event polling will fail without a connected tty
@ -68,7 +69,7 @@ pub fn evaluate_repl(
let mut entry_num = 0;
let mut nu_prompt = NushellPrompt::new();
let mut nu_prompt = NushellPrompt::new(config.shell_integration);
let start_time = std::time::Instant::now();
// Translate environment variables from Strings to Values
@ -134,17 +135,6 @@ pub fn evaluate_repl(
use_color,
);
start_time = std::time::Instant::now();
let sys = sysinfo::System::new();
perf(
"get sysinfo",
start_time,
file!(),
line!(),
column!(),
use_color,
);
if let Some(s) = prerun_command {
eval_source(
engine_state,
@ -212,20 +202,6 @@ pub fn evaluate_repl(
use_color,
);
start_time = std::time::Instant::now();
// Reset the SIGQUIT handler
if let Some(sig_quit) = engine_state.get_sig_quit() {
sig_quit.store(false, Ordering::SeqCst);
}
perf(
"reset sig_quit",
start_time,
file!(),
line!(),
column!(),
use_color,
);
start_time = std::time::Instant::now();
let config = engine_state.get_config();
@ -267,11 +243,7 @@ pub fn evaluate_repl(
.with_quick_completions(config.quick_completions)
.with_partial_completions(config.partial_completions)
.with_ansi_colors(config.use_ansi_coloring)
.with_cursor_config(cursor_config)
.with_transient_prompt(prompt_update::transient_prompt(
engine_reference.clone(),
stack,
));
.with_cursor_config(cursor_config);
perf(
"reedline builder",
start_time,
@ -424,7 +396,9 @@ pub fn evaluate_repl(
start_time = std::time::Instant::now();
let config = &engine_state.get_config().clone();
let prompt = prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt);
prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt);
let transient_prompt =
prompt_update::make_transient_prompt(config, engine_state, stack, &nu_prompt);
perf(
"update_prompt",
start_time,
@ -437,12 +411,13 @@ pub fn evaluate_repl(
entry_num += 1;
start_time = std::time::Instant::now();
let input = line_editor.read_line(prompt);
line_editor = line_editor.with_transient_prompt(transient_prompt);
let input = line_editor.read_line(&nu_prompt);
let shell_integration = config.shell_integration;
match input {
Ok(Signal::Success(s)) => {
let hostname = sys.host_name();
let hostname = System::host_name();
let history_supports_meta =
matches!(config.history_file_format, HistoryFileFormat::Sqlite);
if history_supports_meta && !s.is_empty() && line_editor.has_last_command_context()
@ -764,7 +739,7 @@ fn map_nucursorshape_to_cursorshape(shape: NuCursorShape) -> Option<SetCursorSty
}
}
pub fn get_command_finished_marker(stack: &Stack, engine_state: &EngineState) -> String {
fn get_command_finished_marker(stack: &Stack, engine_state: &EngineState) -> String {
let exit_code = stack
.get_env_var(engine_state, "LAST_EXIT_CODE")
.and_then(|e| e.as_i64().ok());

View File

@ -329,7 +329,6 @@ fn find_matching_block_end_in_expr(
Expr::ImportPattern(_) => None,
Expr::Overlay(_) => None,
Expr::Signature(_) => None,
Expr::MatchPattern(_) => None,
Expr::MatchBlock(_) => None,
Expr::Nothing => None,
Expr::Garbage => None,
@ -386,6 +385,7 @@ fn find_matching_block_end_in_expr(
Argument::Named((_, _, opt_expr)) => opt_expr.as_ref(),
Argument::Positional(inner_expr) => Some(inner_expr),
Argument::Unknown(inner_expr) => Some(inner_expr),
Argument::Spread(inner_expr) => Some(inner_expr),
};
if let Some(inner_expr) = opt_expr {

View File

@ -220,6 +220,10 @@ pub fn eval_source(
source,
false,
);
if let Some(warning) = working_set.parse_warnings.first() {
report_error(&working_set, warning);
}
if let Some(err) = working_set.parse_errors.first() {
set_last_exit_code(stack, 1);
report_error(&working_set, err);

View File

@ -91,7 +91,7 @@ fn variables_dollar_sign_with_varialblecompletion() {
let target_dir = "$ ";
let suggestions = completer.complete(target_dir, target_dir.len());
assert_eq!(7, suggestions.len());
assert_eq!(8, suggestions.len());
}
#[rstest]
@ -144,15 +144,34 @@ fn dotnu_completions() {
let completion_str = "source-env ".to_string();
let suggestions = completer.complete(&completion_str, completion_str.len());
assert_eq!(1, suggestions.len());
assert_eq!(2, suggestions.len());
assert_eq!("custom_completion.nu", suggestions.first().unwrap().value);
#[cfg(windows)]
assert_eq!("directory_completion\\", suggestions.get(1).unwrap().value);
#[cfg(not(windows))]
assert_eq!("directory_completion/", suggestions.get(1).unwrap().value);
// Test use completion
let completion_str = "use ".to_string();
let suggestions = completer.complete(&completion_str, completion_str.len());
assert_eq!(1, suggestions.len());
assert_eq!(2, suggestions.len());
assert_eq!("custom_completion.nu", suggestions.first().unwrap().value);
#[cfg(windows)]
assert_eq!("directory_completion\\", suggestions.get(1).unwrap().value);
#[cfg(not(windows))]
assert_eq!("directory_completion/", suggestions.get(1).unwrap().value);
// Test overlay use completion
let completion_str = "overlay use ".to_string();
let suggestions = completer.complete(&completion_str, completion_str.len());
assert_eq!(2, suggestions.len());
assert_eq!("custom_completion.nu", suggestions.first().unwrap().value);
#[cfg(windows)]
assert_eq!("directory_completion\\", suggestions.get(1).unwrap().value);
#[cfg(not(windows))]
assert_eq!("directory_completion/", suggestions.get(1).unwrap().value);
}
#[test]
@ -208,6 +227,7 @@ fn file_completions() {
let expected_paths: Vec<String> = vec![
folder(dir.join("another")),
file(dir.join("custom_completion.nu")),
folder(dir.join("directory_completion")),
file(dir.join("nushell")),
folder(dir.join("test_a")),
folder(dir.join("test_b")),
@ -323,6 +343,7 @@ fn command_ls_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -333,6 +354,7 @@ fn command_ls_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -355,6 +377,7 @@ fn command_open_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -365,6 +388,7 @@ fn command_open_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -388,6 +412,7 @@ fn command_rm_with_globcompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -398,6 +423,7 @@ fn command_rm_with_globcompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -421,6 +447,7 @@ fn command_cp_with_globcompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -431,6 +458,7 @@ fn command_cp_with_globcompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -454,6 +482,7 @@ fn command_save_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -464,6 +493,7 @@ fn command_save_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -487,6 +517,7 @@ fn command_touch_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -497,6 +528,7 @@ fn command_touch_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -520,6 +552,7 @@ fn command_watch_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -530,6 +563,7 @@ fn command_watch_with_filecompletion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -625,6 +659,7 @@ fn folder_with_directorycompletions() {
// Create the expected values
let expected_paths: Vec<String> = vec![
folder(dir.join("another")),
folder(dir.join("directory_completion")),
folder(dir.join("test_a")),
folder(dir.join("test_b")),
folder(dir.join(".hidden_folder")),
@ -839,6 +874,7 @@ fn unknown_command_completion() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -849,6 +885,7 @@ fn unknown_command_completion() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),
@ -899,6 +936,7 @@ fn filecompletions_triggers_after_cursor() {
let expected_paths: Vec<String> = vec![
"another\\".to_string(),
"custom_completion.nu".to_string(),
"directory_completion\\".to_string(),
"nushell".to_string(),
"test_a\\".to_string(),
"test_b\\".to_string(),
@ -909,6 +947,7 @@ fn filecompletions_triggers_after_cursor() {
let expected_paths: Vec<String> = vec![
"another/".to_string(),
"custom_completion.nu".to_string(),
"directory_completion/".to_string(),
"nushell".to_string(),
"test_a/".to_string(),
"test_b/".to_string(),

View File

@ -5,21 +5,21 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-base"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-base"
version = "0.88.0"
version = "0.88.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.88.0" }
nu-glob = { path = "../nu-glob", version = "0.88.0" }
nu-parser = { path = "../nu-parser", version = "0.88.0" }
nu-path = { path = "../nu-path", version = "0.88.0" }
nu-protocol = { path = "../nu-protocol", version = "0.88.0" }
nu-utils = { path = "../nu-utils", version = "0.88.0" }
nu-engine = { path = "../nu-engine", version = "0.88.2" }
nu-glob = { path = "../nu-glob", version = "0.88.2" }
nu-parser = { path = "../nu-parser", version = "0.88.2" }
nu-path = { path = "../nu-path", version = "0.88.2" }
nu-protocol = { path = "../nu-protocol", version = "0.88.2" }
nu-utils = { path = "../nu-utils", version = "0.88.2" }
indexmap = "2.1"
miette = "5.10.0"
[dev-dependencies]
nu-test-support = { path = "../nu-test-support", version = "0.88.0" }
nu-test-support = { path = "../nu-test-support", version = "0.88.2" }
rstest = "0.18.2"

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-dataframe"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-dataframe"
version = "0.88.0"
version = "0.88.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,9 +13,9 @@ version = "0.88.0"
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.88.0" }
nu-parser = { path = "../nu-parser", version = "0.88.0" }
nu-protocol = { path = "../nu-protocol", version = "0.88.0" }
nu-engine = { path = "../nu-engine", version = "0.88.2" }
nu-parser = { path = "../nu-parser", version = "0.88.2" }
nu-protocol = { path = "../nu-protocol", version = "0.88.2" }
# Potential dependencies for extras
chrono = { version = "0.4", features = ["std", "unstable-locales"], default-features = false }
@ -26,9 +26,9 @@ num = { version = "0.4", optional = true }
serde = { version = "1.0", features = ["derive"] }
sqlparser = { version = "0.39", optional = true }
polars-io = { version = "0.35", features = ["avro"], optional = true }
polars-arrow = "0.35"
polars-ops = "0.35"
polars-plan = "0.35"
polars-arrow = { version = "0.35", optional = true }
polars-ops = { version = "0.35", optional = true }
polars-plan = { version = "0.35", optional = true }
[dependencies.polars]
features = [
@ -65,9 +65,9 @@ optional = true
version = "0.35"
[features]
dataframe = ["num", "polars", "polars-io", "sqlparser"]
dataframe = ["num", "polars", "polars-io", "polars-arrow", "polars-ops", "polars-plan", "sqlparser"]
default = []
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.0" }
nu-test-support = { path = "../nu-test-support", version = "0.88.0" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.2" }
nu-test-support = { path = "../nu-test-support", version = "0.88.2" }

View File

@ -1,11 +1,12 @@
use super::{DataFrameValue, NuDataFrame};
use std::ops::{Deref, DerefMut};
use chrono::{DateTime, FixedOffset, NaiveDateTime};
use chrono::{DateTime, Duration, FixedOffset, NaiveTime, TimeZone, Utc};
use chrono_tz::Tz;
use indexmap::map::{Entry, IndexMap};
use nu_protocol::{Record, ShellError, Span, Value};
use polars::chunked_array::builder::AnonymousOwnedListBuilder;
use polars::chunked_array::object::builder::ObjectChunkedBuilder;
use polars::chunked_array::ChunkedArray;
use polars::datatypes::AnyValue;
use polars::export::arrow::Either;
use polars::prelude::{
DataFrame, DataType, DatetimeChunked, Float64Type, Int64Type, IntoSeries,
@ -13,11 +14,14 @@ use polars::prelude::{
ListUtf8ChunkedBuilder, NamedFrom, NewChunkedArray, ObjectType, Series, TemporalMethods,
TimeUnit,
};
use std::ops::{Deref, DerefMut};
const SECS_PER_DAY: i64 = 86_400;
use nu_protocol::{Record, ShellError, Span, Value};
// The values capacity is for the size of an internal vec.
use super::{DataFrameValue, NuDataFrame};
const NANOS_PER_DAY: i64 = 86_400_000_000_000;
// The values capacity is for the size of an vec.
// Since this is impossible to determine without traversing every value
// I just picked one. Since this is for converting back and forth
// between nushell tables the values shouldn't be too extremely large for
@ -199,7 +203,7 @@ fn value_to_input_type(value: &Value) -> InputType {
Value::Filesize { .. } => InputType::Filesize,
Value::List { vals, .. } => {
// We need to determined the type inside of the list.
// Since Value::List does not have any kind of internal
// Since Value::List does not have any kind of
// type information, we need to look inside the list.
// This will cause errors if lists have inconsistent types.
// Basically, if a list column needs to be converted to dataframe,
@ -775,28 +779,21 @@ fn series_to_values(
}),
Some(ca) => {
let it = ca.into_iter();
let values: Vec<Value> =
if let (Some(size), Some(from_row)) = (maybe_size, maybe_from_row) {
Either::Left(it.skip(from_row).take(size))
if let (Some(size), Some(from_row)) = (maybe_size, maybe_from_row) {
Either::Left(it.skip(from_row).take(size))
} else {
Either::Right(it)
}
.map(|ca| {
let sublist: Vec<Value> = if let Some(ref s) = ca {
series_to_values(s, None, None, Span::unknown())?
} else {
Either::Right(it)
}
.map(|ca| {
let sublist = ca
.map(|ref s| {
match series_to_values(s, None, None, Span::unknown()) {
Ok(v) => v,
Err(e) => {
eprintln!("Error list values: {e}");
vec![]
}
}
})
.unwrap_or(vec![]);
Value::list(sublist, span)
})
.collect::<Vec<Value>>();
Ok(values)
// empty item
vec![]
};
Ok(Value::list(sublist, span))
})
.collect::<Result<Vec<Value>, ShellError>>()
}
}
}
@ -817,51 +814,16 @@ fn series_to_values(
}
.map(|v| match v {
Some(a) => {
// elapsed time in day since 1970-01-01
let seconds = a as i64 * SECS_PER_DAY;
let naive_datetime = match NaiveDateTime::from_timestamp_opt(seconds, 0) {
Some(val) => val,
None => {
return Value::error(
ShellError::UnsupportedInput {
msg: "The given local datetime representation is invalid."
.to_string(),
input: format!("timestamp is {a:?}"),
msg_span: span,
input_span: Span::unknown(),
},
span,
)
}
};
// Zero length offset
let offset = match FixedOffset::east_opt(0) {
Some(val) => val,
None => {
return Value::error(
ShellError::UnsupportedInput {
msg: "The given local datetime representation is invalid."
.to_string(),
input: format!("timestamp is {a:?}"),
msg_span: span,
input_span: Span::unknown(),
},
span,
)
}
};
let datetime =
DateTime::<FixedOffset>::from_naive_utc_and_offset(naive_datetime, offset);
Value::date(datetime, span)
let nanos = nanos_per_day(a);
let datetime = datetime_from_epoch_nanos(nanos, &None, span)?;
Ok(Value::date(datetime, span))
}
None => Value::nothing(span),
None => Ok(Value::nothing(span)),
})
.collect::<Vec<Value>>();
.collect::<Result<Vec<Value>, ShellError>>()?;
Ok(values)
}
DataType::Datetime(time_unit, _) => {
DataType::Datetime(time_unit, tz) => {
let casted = series.datetime().map_err(|e| ShellError::GenericError {
error: "Error casting column to datetime".into(),
msg: "".into(),
@ -878,55 +840,46 @@ fn series_to_values(
}
.map(|v| match v {
Some(a) => {
let unit_divisor = match time_unit {
TimeUnit::Nanoseconds => 1_000_000_000,
TimeUnit::Microseconds => 1_000_000,
TimeUnit::Milliseconds => 1_000,
};
// elapsed time in nano/micro/milliseconds since 1970-01-01
let seconds = a / unit_divisor;
let naive_datetime = match NaiveDateTime::from_timestamp_opt(seconds, 0) {
Some(val) => val,
None => {
return Value::error(
ShellError::UnsupportedInput {
msg: "The given local datetime representation is invalid."
.to_string(),
input: format!("timestamp is {a:?}"),
msg_span: span,
input_span: Span::unknown(),
},
span,
)
}
};
// Zero length offset
let offset = match FixedOffset::east_opt(0) {
Some(val) => val,
None => {
return Value::error(
ShellError::UnsupportedInput {
msg: "The given local datetime representation is invalid."
.to_string(),
input: format!("timestamp is {a:?}"),
msg_span: span,
input_span: Span::unknown(),
},
span,
)
}
};
let datetime =
DateTime::<FixedOffset>::from_naive_utc_and_offset(naive_datetime, offset);
Value::date(datetime, span)
let nanos = nanos_from_timeunit(a, *time_unit);
let datetime = datetime_from_epoch_nanos(nanos, tz, span)?;
Ok(Value::date(datetime, span))
}
None => Value::nothing(span),
None => Ok(Value::nothing(span)),
})
.collect::<Vec<Value>>();
.collect::<Result<Vec<Value>, ShellError>>()?;
Ok(values)
}
DataType::Struct(polar_fields) => {
let casted = series.struct_().map_err(|e| ShellError::GenericError {
error: "Error casting column to struct".into(),
msg: "".to_string(),
span: None,
help: Some(e.to_string()),
inner: Vec::new(),
})?;
let it = casted.into_iter();
let values: Result<Vec<Value>, ShellError> =
if let (Some(size), Some(from_row)) = (maybe_size, maybe_from_row) {
Either::Left(it.skip(from_row).take(size))
} else {
Either::Right(it)
}
.map(|any_values| {
let vals: Result<Vec<Value>, ShellError> = any_values
.iter()
.map(|v| any_value_to_value(v, span))
.collect();
let cols: Vec<String> = polar_fields
.iter()
.map(|field| field.name.to_string())
.collect();
let record = Record::from_raw_cols_vals(cols, vals?);
Ok(Value::record(record, span))
})
.collect();
values
}
DataType::Time => {
let casted =
series
@ -963,10 +916,152 @@ fn series_to_values(
}
}
fn any_value_to_value(any_value: &AnyValue, span: Span) -> Result<Value, ShellError> {
match any_value {
AnyValue::Null => Ok(Value::nothing(span)),
AnyValue::Boolean(b) => Ok(Value::bool(*b, span)),
AnyValue::Utf8(s) => Ok(Value::string(s.to_string(), span)),
AnyValue::UInt8(i) => Ok(Value::int(*i as i64, span)),
AnyValue::UInt16(i) => Ok(Value::int(*i as i64, span)),
AnyValue::UInt32(i) => Ok(Value::int(*i as i64, span)),
AnyValue::UInt64(i) => Ok(Value::int(*i as i64, span)),
AnyValue::Int8(i) => Ok(Value::int(*i as i64, span)),
AnyValue::Int16(i) => Ok(Value::int(*i as i64, span)),
AnyValue::Int32(i) => Ok(Value::int(*i as i64, span)),
AnyValue::Int64(i) => Ok(Value::int(*i, span)),
AnyValue::Float32(f) => Ok(Value::float(*f as f64, span)),
AnyValue::Float64(f) => Ok(Value::float(*f, span)),
AnyValue::Date(d) => {
let nanos = nanos_per_day(*d);
datetime_from_epoch_nanos(nanos, &None, span)
.map(|datetime| Value::date(datetime, span))
}
AnyValue::Datetime(a, time_unit, tz) => {
let nanos = nanos_from_timeunit(*a, *time_unit);
datetime_from_epoch_nanos(nanos, tz, span).map(|datetime| Value::date(datetime, span))
}
AnyValue::Duration(a, time_unit) => {
let nanos = match time_unit {
TimeUnit::Nanoseconds => *a,
TimeUnit::Microseconds => *a * 1_000,
TimeUnit::Milliseconds => *a * 1_000_000,
};
Ok(Value::duration(nanos, span))
}
// AnyValue::Time represents the current time since midnight.
// Unfortunately, there is no timezone related information.
// Given this, calculate the current date from UTC and add the time.
AnyValue::Time(nanos) => time_from_midnight(*nanos, span),
AnyValue::List(series) => {
series_to_values(series, None, None, span).map(|values| Value::list(values, span))
}
AnyValue::Struct(_idx, _struct_array, _s_fields) => {
// This should convert to a StructOwned object.
let static_value =
any_value
.clone()
.into_static()
.map_err(|e| ShellError::GenericError {
error: "Cannot convert polars struct to static value".into(),
msg: e.to_string(),
span: Some(span),
help: None,
inner: Vec::new(),
})?;
any_value_to_value(&static_value, span)
}
AnyValue::StructOwned(struct_tuple) => {
let values: Result<Vec<Value>, ShellError> = struct_tuple
.0
.iter()
.map(|s| any_value_to_value(s, span))
.collect();
let fields = struct_tuple
.1
.iter()
.map(|f| f.name().to_string())
.collect();
Ok(Value::Record {
val: Record::from_raw_cols_vals(fields, values?),
internal_span: span,
})
}
AnyValue::Utf8Owned(s) => Ok(Value::string(s.to_string(), span)),
AnyValue::Binary(bytes) => Ok(Value::binary(*bytes, span)),
AnyValue::BinaryOwned(bytes) => Ok(Value::binary(bytes.to_owned(), span)),
e => Err(ShellError::GenericError {
error: "Error creating Value".into(),
msg: "".to_string(),
span: None,
help: Some(format!("Value not supported in nushell: {e}")),
inner: Vec::new(),
}),
}
}
fn nanos_per_day(days: i32) -> i64 {
days as i64 * NANOS_PER_DAY
}
fn nanos_from_timeunit(a: i64, time_unit: TimeUnit) -> i64 {
a * match time_unit {
TimeUnit::Microseconds => 1_000, // Convert microseconds to nanoseconds
TimeUnit::Milliseconds => 1_000_000, // Convert milliseconds to nanoseconds
TimeUnit::Nanoseconds => 1, // Already in nanoseconds
}
}
fn datetime_from_epoch_nanos(
nanos: i64,
timezone: &Option<String>,
span: Span,
) -> Result<DateTime<FixedOffset>, ShellError> {
let tz: Tz = if let Some(polars_tz) = timezone {
polars_tz
.parse::<Tz>()
.map_err(|_| ShellError::GenericError {
error: format!("Could not parse polars timezone: {polars_tz}"),
msg: "".to_string(),
span: Some(span),
help: None,
inner: vec![],
})?
} else {
Tz::UTC
};
Ok(tz.timestamp_nanos(nanos).fixed_offset())
}
fn time_from_midnight(nanos: i64, span: Span) -> Result<Value, ShellError> {
let today = Utc::now().date_naive();
NaiveTime::from_hms_opt(0, 0, 0) // midnight
.map(|time| time + Duration::nanoseconds(nanos)) // current time
.map(|time| today.and_time(time)) // current date and time
.and_then(|datetime| {
FixedOffset::east_opt(0) // utc
.map(|offset| {
DateTime::<FixedOffset>::from_naive_utc_and_offset(datetime, offset)
})
})
.map(|datetime| Value::date(datetime, span)) // current date and time
.ok_or(ShellError::CantConvert {
to_type: "datetime".to_string(),
from_type: "polars time".to_string(),
span,
help: Some("Could not convert polars time of {nanos} to datetime".to_string()),
})
}
#[cfg(test)]
mod tests {
use super::*;
use indexmap::indexmap;
use nu_protocol::record;
use polars::export::arrow::array::{BooleanArray, PrimitiveArray};
use polars::prelude::Field;
use polars_io::prelude::StructArray;
use super::*;
#[test]
fn test_parsed_column_string_list() -> Result<(), Box<dyn std::error::Error>> {
@ -1001,4 +1096,181 @@ mod tests {
Ok(())
}
#[test]
fn test_any_value_to_value() -> Result<(), Box<dyn std::error::Error>> {
let span = Span::test_data();
assert_eq!(
any_value_to_value(&AnyValue::Null, span)?,
Value::nothing(span)
);
let test_bool = true;
assert_eq!(
any_value_to_value(&AnyValue::Boolean(test_bool), span)?,
Value::bool(test_bool, span)
);
let test_str = "foo";
assert_eq!(
any_value_to_value(&AnyValue::Utf8(test_str), span)?,
Value::string(test_str.to_string(), span)
);
assert_eq!(
any_value_to_value(&AnyValue::Utf8Owned(test_str.into()), span)?,
Value::string(test_str.to_owned(), span)
);
let tests_uint8 = 4;
assert_eq!(
any_value_to_value(&AnyValue::UInt8(tests_uint8), span)?,
Value::int(tests_uint8 as i64, span)
);
let tests_uint16 = 233;
assert_eq!(
any_value_to_value(&AnyValue::UInt16(tests_uint16), span)?,
Value::int(tests_uint16 as i64, span)
);
let tests_uint32 = 897688233;
assert_eq!(
any_value_to_value(&AnyValue::UInt32(tests_uint32), span)?,
Value::int(tests_uint32 as i64, span)
);
let tests_uint64 = 903225135897388233;
assert_eq!(
any_value_to_value(&AnyValue::UInt64(tests_uint64), span)?,
Value::int(tests_uint64 as i64, span)
);
let tests_float32 = 903225135897388233.3223353;
assert_eq!(
any_value_to_value(&AnyValue::Float32(tests_float32), span)?,
Value::float(tests_float32 as f64, span)
);
let tests_float64 = 9064251358973882322333.64233533232;
assert_eq!(
any_value_to_value(&AnyValue::Float64(tests_float64), span)?,
Value::float(tests_float64, span)
);
let test_days = 10_957;
let comparison_date = Utc
.with_ymd_and_hms(2000, 1, 1, 0, 0, 0)
.unwrap()
.fixed_offset();
assert_eq!(
any_value_to_value(&AnyValue::Date(test_days), span)?,
Value::date(comparison_date, span)
);
let test_millis = 946_684_800_000;
assert_eq!(
any_value_to_value(
&AnyValue::Datetime(test_millis, TimeUnit::Milliseconds, &None),
span
)?,
Value::date(comparison_date, span)
);
let test_duration_millis = 99_999;
let test_duration_micros = 99_999_000;
let test_duration_nanos = 99_999_000_000;
assert_eq!(
any_value_to_value(
&AnyValue::Duration(test_duration_nanos, TimeUnit::Nanoseconds),
span
)?,
Value::duration(test_duration_nanos, span)
);
assert_eq!(
any_value_to_value(
&AnyValue::Duration(test_duration_micros, TimeUnit::Microseconds),
span
)?,
Value::duration(test_duration_nanos, span)
);
assert_eq!(
any_value_to_value(
&AnyValue::Duration(test_duration_millis, TimeUnit::Milliseconds),
span
)?,
Value::duration(test_duration_nanos, span)
);
let test_binary = b"sdf2332f32q3f3afwaf3232f32";
assert_eq!(
any_value_to_value(&AnyValue::Binary(test_binary), span)?,
Value::binary(test_binary.to_vec(), span)
);
assert_eq!(
any_value_to_value(&AnyValue::BinaryOwned(test_binary.to_vec()), span)?,
Value::binary(test_binary.to_vec(), span)
);
let test_time_nanos = 54_000_000_000_000;
let test_time = DateTime::<FixedOffset>::from_naive_utc_and_offset(
Utc::now()
.date_naive()
.and_time(NaiveTime::from_hms_opt(15, 00, 00).unwrap()),
FixedOffset::east_opt(0).unwrap(),
);
assert_eq!(
any_value_to_value(&AnyValue::Time(test_time_nanos), span)?,
Value::date(test_time, span)
);
let test_list_series = Series::new("int series", &[1, 2, 3]);
let comparison_list_series = Value::list(
vec![
Value::int(1, span),
Value::int(2, span),
Value::int(3, span),
],
span,
);
assert_eq!(
any_value_to_value(&AnyValue::List(test_list_series), span)?,
comparison_list_series
);
let field_value_0 = AnyValue::Int32(1);
let field_value_1 = AnyValue::Boolean(true);
let values = vec![field_value_0, field_value_1];
let field_name_0 = "num_field";
let field_name_1 = "bool_field";
let fields = vec![
Field::new(field_name_0, DataType::Int32),
Field::new(field_name_1, DataType::Boolean),
];
let test_owned_struct = AnyValue::StructOwned(Box::new((values, fields.clone())));
let comparison_owned_record = Value::test_record(record!(
field_name_0 => Value::int(1, span),
field_name_1 => Value::bool(true, span),
));
assert_eq!(
any_value_to_value(&test_owned_struct, span)?,
comparison_owned_record.clone()
);
let test_int_arr = PrimitiveArray::from([Some(1_i32)]);
let test_bool_arr = BooleanArray::from([Some(true)]);
let test_struct_arr = StructArray::new(
DataType::Struct(fields.clone()).to_arrow(),
vec![Box::new(test_int_arr), Box::new(test_bool_arr)],
None,
);
assert_eq!(
any_value_to_value(
&AnyValue::Struct(0, &test_struct_arr, fields.as_slice()),
span
)?,
comparison_owned_record
);
Ok(())
}
}

View File

@ -158,7 +158,10 @@ impl NuDataFrame {
.map(|i| format!("{i}"))
.collect::<Vec<String>>();
conversion::insert_record(&mut column_values, Record { cols, vals })?
conversion::insert_record(
&mut column_values,
Record::from_raw_cols_vals(cols, vals),
)?
}
Value::Record { val: record, .. } => {
conversion::insert_record(&mut column_values, record)?

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-extra"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-extra"
version = "0.88.0"
version = "0.88.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,22 +13,22 @@ version = "0.88.0"
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.88.0" }
nu-parser = { path = "../nu-parser", version = "0.88.0" }
nu-protocol = { path = "../nu-protocol", version = "0.88.0" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.88.0" }
nu-utils = { path = "../nu-utils", version = "0.88.0" }
nu-engine = { path = "../nu-engine", version = "0.88.2" }
nu-parser = { path = "../nu-parser", version = "0.88.2" }
nu-protocol = { path = "../nu-protocol", version = "0.88.2" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.88.2" }
nu-utils = { path = "../nu-utils", version = "0.88.2" }
# Potential dependencies for extras
heck = "0.4.1"
num-traits = "0.2"
ahash = "0.8.3"
nu-ansi-term = "0.49.0"
fancy-regex = "0.11.0"
fancy-regex = "0.12.0"
rust-embed = "8.0.0"
serde = "1.0.164"
nu-pretty-hex = { version = "0.88.0", path = "../nu-pretty-hex" }
nu-json = { version = "0.88.0", path = "../nu-json" }
nu-pretty-hex = { version = "0.88.2", path = "../nu-pretty-hex" }
nu-json = { version = "0.88.2", path = "../nu-json" }
serde_urlencoded = "0.7.1"
htmlescape = "0.3.1"
@ -37,6 +37,6 @@ extra = ["default"]
default = []
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.0" }
nu-command = { path = "../nu-command", version = "0.88.0" }
nu-test-support = { path = "../nu-test-support", version = "0.88.0" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.2" }
nu-command = { path = "../nu-command", version = "0.88.2" }
nu-test-support = { path = "../nu-test-support", version = "0.88.2" }

View File

@ -65,7 +65,7 @@ pub fn add_extra_command_context(mut engine_state: EngineState) -> EngineState {
bind_command!(platform::ansi::Gradient);
bind_command!(
strings::format::Format,
strings::format::FormatPattern,
strings::encode_decode::EncodeHex,
strings::encode_decode::DecodeHex,
strings::str_::case::Str,

View File

@ -10,15 +10,15 @@ use nu_protocol::{
};
#[derive(Clone)]
pub struct Format;
pub struct FormatPattern;
impl Command for Format {
impl Command for FormatPattern {
fn name(&self) -> &str {
"format"
"format pattern"
}
fn signature(&self) -> Signature {
Signature::build("format")
Signature::build("format pattern")
.input_output_types(vec![
(Type::Table(vec![]), Type::List(Box::new(Type::String))),
(Type::Record(vec![]), Type::Any),
@ -80,12 +80,12 @@ impl Command for Format {
vec![
Example {
description: "Print filenames with their sizes",
example: "ls | format '{name}: {size}'",
example: "ls | format pattern '{name}: {size}'",
result: None,
},
Example {
description: "Print elements from some columns of a table",
example: "[[col1, col2]; [v1, v2] [v3, v4]] | format '{col2}'",
example: "[[col1, col2]; [v1, v2] [v3, v4]] | format pattern '{col2}'",
result: Some(Value::list(
vec![Value::test_string("v2"), Value::test_string("v4")],
Span::test_data(),
@ -318,8 +318,8 @@ fn format_record(
mod test {
#[test]
fn test_examples() {
use super::Format;
use super::FormatPattern;
use crate::test_examples;
test_examples(Format {})
test_examples(FormatPattern {})
}
}

View File

@ -1,3 +1,3 @@
mod command;
pub(crate) use command::Format;
pub(crate) use command::FormatPattern;

View File

@ -6,24 +6,24 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-lang"
edition = "2021"
license = "MIT"
name = "nu-cmd-lang"
version = "0.88.0"
version = "0.88.2"
[lib]
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.88.0" }
nu-parser = { path = "../nu-parser", version = "0.88.0" }
nu-protocol = { path = "../nu-protocol", version = "0.88.0" }
nu-utils = { path = "../nu-utils", version = "0.88.0" }
nu-engine = { path = "../nu-engine", version = "0.88.2" }
nu-parser = { path = "../nu-parser", version = "0.88.2" }
nu-protocol = { path = "../nu-protocol", version = "0.88.2" }
nu-utils = { path = "../nu-utils", version = "0.88.2" }
nu-ansi-term = "0.49.0"
fancy-regex = "0.11"
itertools = "0.11"
shadow-rs = { version = "0.24", default-features = false }
fancy-regex = "0.12"
itertools = "0.12"
shadow-rs = { version = "0.26", default-features = false }
[build-dependencies]
shadow-rs = { version = "0.24", default-features = false }
shadow-rs = { version = "0.26", default-features = false }
[features]
mimalloc = []

View File

@ -19,11 +19,11 @@ impl Command for Alias {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("alias")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("name", SyntaxShape::String, "name of the alias")
.required("name", SyntaxShape::String, "Name of the alias.")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
"equals sign followed by value",
"Equals sign followed by value.",
)
.category(Category::Core)
}

View File

@ -20,7 +20,7 @@ impl Command for Collect {
.required(
"closure",
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),
"the closure to run once the stream is collected",
"The closure to run once the stream is collected.",
)
.switch(
"keep-env",

View File

@ -18,11 +18,11 @@ impl Command for Const {
Signature::build("const")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("const_name", SyntaxShape::VarWithOptType, "constant name")
.required("const_name", SyntaxShape::VarWithOptType, "Constant name.")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::MathExpression)),
"equals sign followed by constant value",
"Equals sign followed by constant value.",
)
.category(Category::Core)
}

View File

@ -19,9 +19,9 @@ impl Command for Def {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("def")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("def_name", SyntaxShape::String, "command name")
.required("params", SyntaxShape::Signature, "parameters")
.required("block", SyntaxShape::Closure(None), "body of the definition")
.required("def_name", SyntaxShape::String, "Command name.")
.required("params", SyntaxShape::Signature, "Parameters.")
.required("block", SyntaxShape::Closure(None), "Body of the definition.")
.switch("env", "keep the environment defined inside the command", None)
.switch("wrapped", "treat unknown flags and arguments as strings (requires ...rest-like parameter in signature)", None)
.category(Category::Core)

View File

@ -290,7 +290,6 @@ fn describe_value(
| Value::Date { .. }
| Value::Range { .. }
| Value::String { .. }
| Value::MatchPattern { .. }
| Value::Nothing { .. } => Value::record(
record!(
"type" => Value::string(value.get_type().to_string(), head),

View File

@ -25,7 +25,7 @@ impl Command for Do {
.required(
"closure",
SyntaxShape::OneOf(vec![SyntaxShape::Closure(None), SyntaxShape::Any]),
"the closure to run",
"The closure to run.",
)
.input_output_types(vec![(Type::Any, Type::Any)])
.switch(
@ -53,7 +53,11 @@ impl Command for Do {
"keep the environment defined inside the command",
None,
)
.rest("rest", SyntaxShape::Any, "the parameter(s) for the closure")
.rest(
"rest",
SyntaxShape::Any,
"The parameter(s) for the closure.",
)
.category(Category::Core)
}

View File

@ -21,7 +21,7 @@ impl Command for Echo {
fn signature(&self) -> Signature {
Signature::build("echo")
.input_output_types(vec![(Type::Nothing, Type::Any)])
.rest("rest", SyntaxShape::Any, "the values to echo")
.rest("rest", SyntaxShape::Any, "The values to echo.")
.category(Category::Core)
}

View File

@ -19,7 +19,7 @@ impl Command for ErrorMake {
.required(
"error_struct",
SyntaxShape::Record(vec![]),
"the error to create",
"The error to create.",
)
.switch(
"unspanned",

View File

@ -19,11 +19,11 @@ impl Command for ExportAlias {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("export alias")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("name", SyntaxShape::String, "name of the alias")
.required("name", SyntaxShape::String, "Name of the alias.")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
"equals sign followed by value",
"Equals sign followed by value.",
)
.category(Category::Core)
}

View File

@ -20,11 +20,11 @@ impl Command for ExportConst {
Signature::build("export const")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("const_name", SyntaxShape::VarWithOptType, "constant name")
.required("const_name", SyntaxShape::VarWithOptType, "Constant name.")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::MathExpression)),
"equals sign followed by constant value",
"Equals sign followed by constant value.",
)
.category(Category::Core)
}

View File

@ -19,9 +19,9 @@ impl Command for ExportDef {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("export def")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("def_name", SyntaxShape::String, "command name")
.required("params", SyntaxShape::Signature, "parameters")
.required("block", SyntaxShape::Block, "body of the definition")
.required("def_name", SyntaxShape::String, "Command name.")
.required("params", SyntaxShape::Signature, "Parameters.")
.required("block", SyntaxShape::Block, "Body of the definition.")
.switch("env", "keep the environment defined inside the command", None)
.switch("wrapped", "treat unknown flags and arguments as strings (requires ...rest-like parameter in signature)", None)
.category(Category::Core)

View File

@ -17,8 +17,8 @@ impl Command for ExportExtern {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("export extern")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("def_name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required("def_name", SyntaxShape::String, "Definition name.")
.required("params", SyntaxShape::Signature, "Parameters.")
.category(Category::Core)
}

View File

@ -20,11 +20,11 @@ impl Command for ExportModule {
Signature::build("export module")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("module", SyntaxShape::String, "module name or module path")
.required("module", SyntaxShape::String, "Module name or module path.")
.optional(
"block",
SyntaxShape::Block,
"body of the module if 'module' parameter is not a path",
"Body of the module if 'module' parameter is not a path.",
)
.category(Category::Core)
}

View File

@ -19,11 +19,11 @@ impl Command for ExportUse {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("export use")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("module", SyntaxShape::String, "Module or module file")
.required("module", SyntaxShape::String, "Module or module file.")
.optional(
"members",
SyntaxShape::Any,
"Which members of the module to import",
"Which members of the module to import.",
)
.category(Category::Core)
}

View File

@ -17,8 +17,8 @@ impl Command for Extern {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("extern")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("def_name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required("def_name", SyntaxShape::String, "Definition name.")
.required("params", SyntaxShape::Signature, "Parameters.")
.category(Category::Core)
}

View File

@ -25,14 +25,14 @@ impl Command for For {
.required(
"var_name",
SyntaxShape::VarWithOptType,
"name of the looping variable",
"Name of the looping variable.",
)
.required(
"range",
SyntaxShape::Keyword(b"in".to_vec(), Box::new(SyntaxShape::Any)),
"range of the loop",
"Range of the loop.",
)
.required("block", SyntaxShape::Block, "the block to run")
.required("block", SyntaxShape::Block, "The block to run.")
.switch(
"numbered",
"return a numbered item ($it.index and $it.item)",

View File

@ -13,11 +13,11 @@ impl Command for Hide {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("hide")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.required("module", SyntaxShape::String, "Module or module file")
.required("module", SyntaxShape::String, "Module or module file.")
.optional(
"members",
SyntaxShape::Any,
"Which members of the module to import",
"Which members of the module to import.",
)
.category(Category::Core)
}

View File

@ -20,7 +20,7 @@ impl Command for HideEnv {
.rest(
"name",
SyntaxShape::String,
"environment variable names to hide",
"Environment variable names to hide.",
)
.switch(
"ignore-errors",

View File

@ -21,11 +21,11 @@ impl Command for If {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("if")
.input_output_types(vec![(Type::Any, Type::Any)])
.required("cond", SyntaxShape::MathExpression, "condition to check")
.required("cond", SyntaxShape::MathExpression, "Condition to check.")
.required(
"then_block",
SyntaxShape::Block,
"block to run if check succeeds",
"Block to run if check succeeds.",
)
.optional(
"else_expression",
@ -36,7 +36,7 @@ impl Command for If {
SyntaxShape::Expression,
])),
),
"expression or block to run if check fails",
"Expression or block to run when the condition is false.",
)
.category(Category::Core)
}

View File

@ -19,11 +19,11 @@ impl Command for Let {
Signature::build("let")
.input_output_types(vec![(Type::Any, Type::Nothing)])
.allow_variants_without_examples(true)
.required("var_name", SyntaxShape::VarWithOptType, "variable name")
.required("var_name", SyntaxShape::VarWithOptType, "Variable name.")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::MathExpression)),
"equals sign followed by value",
"Equals sign followed by value.",
)
.category(Category::Core)
}

View File

@ -21,7 +21,7 @@ impl Command for Loop {
Signature::build("loop")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("block", SyntaxShape::Block, "block to loop")
.required("block", SyntaxShape::Block, "Block to loop.")
.category(Category::Core)
}

View File

@ -20,11 +20,11 @@ impl Command for Match {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("match")
.input_output_types(vec![(Type::Any, Type::Any)])
.required("value", SyntaxShape::Any, "value to check")
.required("value", SyntaxShape::Any, "Value to check.")
.required(
"match_block",
SyntaxShape::MatchBlock,
"block to run if check succeeds",
"Block to run if check succeeds.",
)
.category(Category::Core)
}

View File

@ -20,11 +20,11 @@ impl Command for Module {
Signature::build("module")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("module", SyntaxShape::String, "module name or module path")
.required("module", SyntaxShape::String, "Module name or module path.")
.optional(
"block",
SyntaxShape::Block,
"body of the module if 'module' parameter is not a module path",
"Body of the module if 'module' parameter is not a module path.",
)
.category(Category::Core)
}

View File

@ -19,11 +19,11 @@ impl Command for Mut {
Signature::build("mut")
.input_output_types(vec![(Type::Any, Type::Nothing)])
.allow_variants_without_examples(true)
.required("var_name", SyntaxShape::VarWithOptType, "variable name")
.required("var_name", SyntaxShape::VarWithOptType, "Variable name.")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::MathExpression)),
"equals sign followed by value",
"Equals sign followed by value.",
)
.category(Category::Core)
}

View File

@ -20,10 +20,10 @@ impl Command for OverlayHide {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("overlay hide")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.optional("name", SyntaxShape::String, "Overlay to hide")
.optional("name", SyntaxShape::String, "Overlay to hide.")
.switch(
"keep-custom",
"Keep all newly added commands and aliases in the next activated overlay",
"Keep all newly added commands and aliases in the next activated overlay.",
Some('k'),
)
.named(

View File

@ -21,7 +21,7 @@ impl Command for OverlayNew {
Signature::build("overlay new")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("name", SyntaxShape::String, "Name of the overlay")
.required("name", SyntaxShape::String, "Name of the overlay.")
// TODO:
// .switch(
// "prefix",

View File

@ -27,12 +27,12 @@ impl Command for OverlayUse {
.required(
"name",
SyntaxShape::String,
"Module name to use overlay for",
"Module name to use overlay for.",
)
.optional(
"as",
SyntaxShape::Keyword(b"as".to_vec(), Box::new(SyntaxShape::String)),
"as keyword followed by a new name",
"`as` keyword followed by a new name.",
)
.switch(
"prefix",

View File

@ -20,12 +20,12 @@ impl Command for Register {
.required(
"plugin",
SyntaxShape::Filepath,
"path of executable for plugin",
"Path of executable for plugin.",
)
.optional(
"signature",
SyntaxShape::Any,
"Block with signature description as json object",
"Block with signature description as json object.",
)
.named(
"shell",

View File

@ -20,7 +20,11 @@ impl Command for Return {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("return")
.input_output_types(vec![(Type::Nothing, Type::Any)])
.optional("return_value", SyntaxShape::Any, "optional value to return")
.optional(
"return_value",
SyntaxShape::Any,
"Optional value to return.",
)
.category(Category::Core)
}

View File

@ -21,7 +21,7 @@ impl Command for Try {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("try")
.input_output_types(vec![(Type::Any, Type::Any)])
.required("try_block", SyntaxShape::Block, "block to run")
.required("try_block", SyntaxShape::Block, "Block to run.")
.optional(
"catch_block",
SyntaxShape::Keyword(
@ -31,7 +31,7 @@ impl Command for Try {
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),
])),
),
"block to run if try block fails",
"Block to run if try block fails.",
)
.category(Category::Core)
}

View File

@ -21,11 +21,11 @@ impl Command for Use {
Signature::build("use")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("module", SyntaxShape::String, "Module or module file")
.required("module", SyntaxShape::String, "Module or module file.")
.rest(
"members",
SyntaxShape::Any,
"Which members of the module to import",
"Which members of the module to import.",
)
.category(Category::Core)
}

View File

@ -21,11 +21,11 @@ impl Command for While {
Signature::build("while")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("cond", SyntaxShape::MathExpression, "condition to check")
.required("cond", SyntaxShape::MathExpression, "Condition to check.")
.required(
"block",
SyntaxShape::Block,
"block to loop if check succeeds",
"Block to loop if check succeeds.",
)
.category(Category::Core)
}

View File

@ -278,9 +278,6 @@ impl<'a> std::fmt::Debug for DebuggableValue<'a> {
let rec = val.collect().map_err(|_| std::fmt::Error)?;
write!(f, "LazyRecord({:?})", DebuggableValue(&rec))
}
Value::MatchPattern { val, .. } => {
write!(f, "MatchPattern({:?})", val)
}
}
}
}

View File

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

View File

@ -92,7 +92,7 @@ fn color_string_to_nustyle(color_string: String) -> Style {
mod tests {
use super::*;
use nu_ansi_term::{Color, Style};
use nu_protocol::{Span, Value};
use nu_protocol::{record, Span, Value};
#[test]
fn test_color_string_to_nustyle_empty_string() {
@ -120,13 +120,10 @@ mod tests {
#[test]
fn test_get_style_from_value() {
// Test case 1: all values are valid
let record = Record {
cols: vec!["bg".to_string(), "fg".to_string(), "attr".to_string()],
vals: vec![
Value::string("red", Span::unknown()),
Value::string("blue", Span::unknown()),
Value::string("bold", Span::unknown()),
],
let record = record! {
"bg" => Value::test_string("red"),
"fg" => Value::test_string("blue"),
"attr" => Value::test_string("bold"),
};
let expected_style = NuStyle {
bg: Some("red".to_string()),
@ -136,19 +133,15 @@ mod tests {
assert_eq!(get_style_from_value(&record), Some(expected_style));
// Test case 2: no values are valid
let record = Record {
cols: vec!["invalid".to_string()],
vals: vec![Value::nothing(Span::unknown())],
let record = record! {
"invalid" => Value::nothing(Span::test_data()),
};
assert_eq!(get_style_from_value(&record), None);
// Test case 3: some values are valid
let record = Record {
cols: vec!["bg".to_string(), "invalid".to_string()],
vals: vec![
Value::string("green", Span::unknown()),
Value::nothing(Span::unknown()),
],
let record = record! {
"bg" => Value::test_string("green"),
"invalid" => Value::nothing(Span::unknown()),
};
let expected_style = NuStyle {
bg: Some("green".to_string()),

View File

@ -131,8 +131,7 @@ impl<'a> StyleComputer<'a> {
Value::Closure { .. }
| Value::CustomValue { .. }
| Value::Error { .. }
| Value::LazyRecord { .. }
| Value::MatchPattern { .. } => TextStyle::basic_left(),
| Value::LazyRecord { .. } => TextStyle::basic_left(),
}
}

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-command"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-command"
version = "0.88.0"
version = "0.88.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -14,19 +14,19 @@ bench = false
[dependencies]
nu-ansi-term = "0.49.0"
nu-cmd-base = { path = "../nu-cmd-base", version = "0.88.0" }
nu-color-config = { path = "../nu-color-config", version = "0.88.0" }
nu-engine = { path = "../nu-engine", version = "0.88.0" }
nu-glob = { path = "../nu-glob", version = "0.88.0" }
nu-json = { path = "../nu-json", version = "0.88.0" }
nu-parser = { path = "../nu-parser", version = "0.88.0" }
nu-path = { path = "../nu-path", version = "0.88.0" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.88.0" }
nu-protocol = { path = "../nu-protocol", version = "0.88.0" }
nu-system = { path = "../nu-system", version = "0.88.0" }
nu-table = { path = "../nu-table", version = "0.88.0" }
nu-term-grid = { path = "../nu-term-grid", version = "0.88.0" }
nu-utils = { path = "../nu-utils", version = "0.88.0" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.88.2" }
nu-color-config = { path = "../nu-color-config", version = "0.88.2" }
nu-engine = { path = "../nu-engine", version = "0.88.2" }
nu-glob = { path = "../nu-glob", version = "0.88.2" }
nu-json = { path = "../nu-json", version = "0.88.2" }
nu-parser = { path = "../nu-parser", version = "0.88.2" }
nu-path = { path = "../nu-path", version = "0.88.2" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.88.2" }
nu-protocol = { path = "../nu-protocol", version = "0.88.2" }
nu-system = { path = "../nu-system", version = "0.88.2" }
nu-table = { path = "../nu-table", version = "0.88.2" }
nu-term-grid = { path = "../nu-term-grid", version = "0.88.2" }
nu-utils = { path = "../nu-utils", version = "0.88.2" }
alphanumeric-sort = "1.5"
base64 = "0.21"
@ -42,7 +42,7 @@ dialoguer = { default-features = false, features = ["fuzzy-select"], version = "
digest = { default-features = false, version = "0.10" }
dtparse = "2.0"
encoding_rs = "0.8"
fancy-regex = "0.11"
fancy-regex = "0.12"
filesize = "0.2"
filetime = "0.2"
fs_extra = "1.3"
@ -50,9 +50,9 @@ htmlescape = "0.3"
human-date-parser = "0.1.1"
indexmap = "2.1"
indicatif = "0.17"
itertools = "0.11"
itertools = "0.12"
log = "0.4"
lscolors = { version = "0.15", default-features = false, features = ["nu-ansi-term"] }
lscolors = { version = "0.16", default-features = false, features = ["nu-ansi-term"] }
md5 = { package = "md-5", version = "0.10" }
miette = { version = "5.10", features = ["fancy-no-backtrace"] }
mime = "0.3"
@ -80,7 +80,7 @@ serde_json = "1.0"
serde_urlencoded = "0.7"
serde_yaml = "0.9"
sha2 = "0.10"
sysinfo = "0.29"
sysinfo = "0.30"
tabled = { version = "0.14.0", features = ["color"], default-features = false }
terminal_size = "0.3"
titlecase = "2.0"
@ -104,9 +104,9 @@ winreg = "0.52"
[target.'cfg(unix)'.dependencies]
libc = "0.2"
umask = "2.1"
nix = { version = "0.27", default-features = false, features = ["user"] }
nix = { version = "0.27", default-features = false, features = ["user", "resource"] }
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "android"), not(target_os = "ios")))'.dependencies]
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
procfs = "0.16.0"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies.trash]
@ -122,7 +122,7 @@ features = [
"Win32_Security",
"Win32_System_Threading",
]
version = "0.48"
version = "0.52"
[features]
plugin = ["nu-parser/plugin"]
@ -131,8 +131,8 @@ trash-support = ["trash"]
which-support = ["which"]
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.0" }
nu-test-support = { path = "../nu-test-support", version = "0.88.0" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.88.2" }
nu-test-support = { path = "../nu-test-support", version = "0.88.2" }
dirs-next = "2.0"
mockito = { version = "1.2", default-features = false }

View File

@ -40,7 +40,7 @@ impl Command for BytesAdd {
(Type::Record(vec![]), Type::Record(vec![])),
])
.allow_variants_without_examples(true)
.required("data", SyntaxShape::Binary, "the binary to add")
.required("data", SyntaxShape::Binary, "The binary to add.")
.named(
"index",
SyntaxShape::Int,
@ -51,7 +51,7 @@ impl Command for BytesAdd {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, add bytes to the data at the given cell paths",
"For a data structure input, add bytes to the data at the given cell paths.",
)
.category(Category::Bytes)
}

View File

@ -47,11 +47,11 @@ impl Command for BytesAt {
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
])
.required("range", SyntaxShape::Range, "the range to get bytes")
.required("range", SyntaxShape::Range, "The range to get bytes.")
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, get bytes from data at the given cell paths",
"For a data structure input, get bytes from data at the given cell paths.",
)
.category(Category::Bytes)
}

View File

@ -1,4 +1,4 @@
use nu_engine::eval_expression;
use nu_engine::{eval_expression, CallExt};
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
@ -25,7 +25,7 @@ impl Command for BytesBuild {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("bytes build")
.input_output_types(vec![(Type::Nothing, Type::Binary)])
.rest("rest", SyntaxShape::Any, "list of bytes")
.rest("rest", SyntaxShape::Any, "List of bytes.")
.category(Category::Bytes)
}
@ -48,8 +48,7 @@ impl Command for BytesBuild {
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let mut output = vec![];
for expr in call.positional_iter() {
let val = eval_expression(engine_state, stack, expr)?;
for val in call.rest_iter_flattened(0, |expr| eval_expression(engine_state, stack, expr))? {
match val {
Value::Binary { mut val, .. } => output.append(&mut val),
// Explicitly propagate errors instead of dropping them.

View File

@ -20,7 +20,7 @@ impl Command for BytesCollect {
.optional(
"separator",
SyntaxShape::Binary,
"optional separator to use when creating binary",
"Optional separator to use when creating binary.",
)
.category(Category::Bytes)
}

View File

@ -33,11 +33,11 @@ impl Command for BytesEndsWith {
(Type::Record(vec![]), Type::Record(vec![])),
])
.allow_variants_without_examples(true)
.required("pattern", SyntaxShape::Binary, "the pattern to match")
.required("pattern", SyntaxShape::Binary, "The pattern to match.")
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, check if bytes at the given cell paths end with the pattern",
"For a data structure input, check if bytes at the given cell paths end with the pattern.",
)
.category(Category::Bytes)
}

View File

@ -41,12 +41,12 @@ impl Command for BytesIndexOf {
.required(
"pattern",
SyntaxShape::Binary,
"the pattern to find index of",
"The pattern to find index of.",
)
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, find the indexes at the given cell paths",
"For a data structure input, find the indexes at the given cell paths.",
)
.switch("all", "returns all matched index", Some('a'))
.switch("end", "search from the end of the binary", Some('e'))

View File

@ -29,7 +29,7 @@ impl Command for BytesLen {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, find the length of data at the given cell paths",
"For a data structure input, find the length of data at the given cell paths.",
)
.category(Category::Bytes)
}

View File

@ -35,11 +35,11 @@ impl Command for BytesRemove {
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
])
.required("pattern", SyntaxShape::Binary, "the pattern to find")
.required("pattern", SyntaxShape::Binary, "The pattern to find.")
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, remove bytes from data at the given cell paths",
"For a data structure input, remove bytes from data at the given cell paths.",
)
.switch("end", "remove from end of binary", Some('e'))
.switch("all", "remove occurrences of finding binary", Some('a'))
@ -105,6 +105,13 @@ impl Command for BytesRemove {
vec![0x10, 0xAA, 0x10, 0xBB, 0xCC, 0xAA],
)),
},
Example {
description: "Remove find binary from end not found",
example: "0x[10 AA 10 BB CC AA 10] | bytes remove --end 0x[11]",
result: Some(Value::test_binary (
vec![0x10, 0xAA, 0x10, 0xBB, 0xCC, 0xAA, 0x10],
)),
},
Example {
description: "Remove all occurrences of find binary in table",
example: "[[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes remove 0x[11] ColA ColC",
@ -159,8 +166,11 @@ fn remove_impl(input: &[u8], arg: &Arguments, span: Span) -> Value {
}
// append the remaining thing to result, this can be happening when
// we have something to remove and remove_all is False.
let mut remain = input[..left as usize].iter().copied().rev().collect();
result.append(&mut remain);
// check if the left is positive, if it is not, we don't need to append anything.
if left > 0 {
let mut remain = input[..left as usize].iter().copied().rev().collect();
result.append(&mut remain);
}
result = result.into_iter().rev().collect();
Value::binary(result, span)
} else {

View File

@ -36,12 +36,12 @@ impl Command for BytesReplace {
(Type::Record(vec![]), Type::Record(vec![])),
])
.allow_variants_without_examples(true)
.required("find", SyntaxShape::Binary, "the pattern to find")
.required("replace", SyntaxShape::Binary, "the replacement pattern")
.required("find", SyntaxShape::Binary, "The pattern to find.")
.required("replace", SyntaxShape::Binary, "The replacement pattern.")
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, replace bytes in data at the given cell paths",
"For a data structure input, replace bytes in data at the given cell paths.",
)
.switch("all", "replace all occurrences of find binary", Some('a'))
.category(Category::Bytes)

View File

@ -26,7 +26,7 @@ impl Command for BytesReverse {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, reverse data at the given cell paths",
"For a data structure input, reverse data at the given cell paths.",
)
.category(Category::Bytes)
}

View File

@ -35,11 +35,11 @@ impl Command for BytesStartsWith {
(Type::Record(vec![]), Type::Record(vec![])),
])
.allow_variants_without_examples(true)
.required("pattern", SyntaxShape::Binary, "the pattern to match")
.required("pattern", SyntaxShape::Binary, "The pattern to match.")
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, check if bytes at the given cell paths start with the pattern",
"For a data structure input, check if bytes at the given cell paths start with the pattern.",
)
.category(Category::Bytes)
}

View File

@ -25,8 +25,8 @@ impl Command for Histogram {
fn signature(&self) -> Signature {
Signature::build("histogram")
.input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Table(vec![])),])
.optional("column-name", SyntaxShape::String, "column name to calc frequency, no need to provide if input is just a list")
.optional("frequency-column-name", SyntaxShape::String, "histogram's frequency column, default to be frequency column output")
.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.")
.named("percentage-type", SyntaxShape::String, "percentage calculate method, can be 'normalize' or 'relative', in 'normalize', defaults to be 'normalize'", Some('t'))
.category(Category::Chart)
}
@ -258,16 +258,16 @@ fn histogram_impl(
result.push((
count, // attach count first for easily sorting.
Value::record(
Record {
cols: result_cols.clone(),
vals: vec![
Record::from_raw_cols_vals(
result_cols.clone(),
vec![
val.into_value(),
Value::int(count, span),
Value::float(quantile, span),
Value::string(percentage, span),
Value::string(freq, span),
],
},
),
span,
),
));

View File

@ -44,7 +44,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.category(Category::Conversions)
}

View File

@ -29,7 +29,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.category(Category::Conversions)
}

View File

@ -104,7 +104,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.category(Category::Conversions)
}

View File

@ -36,7 +36,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.category(Category::Conversions)
}

View File

@ -49,7 +49,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.category(Category::Conversions)
}

View File

@ -31,7 +31,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.allow_variants_without_examples(true)
.category(Category::Conversions)

View File

@ -81,7 +81,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.category(Category::Conversions)
}

View File

@ -52,7 +52,7 @@ impl Command for SubCommand {
.rest(
"rest",
SyntaxShape::CellPath,
"for a data structure input, convert data at the given cell paths",
"For a data structure input, convert data at the given cell paths.",
)
.named(
"decimals",

View File

@ -25,7 +25,7 @@ impl Command for IntoSqliteDb {
.required(
"file_name",
SyntaxShape::String,
"Specify the filename to save the database to",
"Specify the filename to save the database to.",
)
.named(
"table_name",
@ -260,7 +260,6 @@ fn nu_value_to_string(value: Value, separator: &str) -> String {
Value::Binary { val, .. } => format!("{val:?}"),
Value::CellPath { val, .. } => val.to_string(),
Value::CustomValue { val, .. } => val.value_string(),
Value::MatchPattern { val, .. } => format!("{:?}", val),
}
}

View File

@ -22,9 +22,9 @@ impl Command for QueryDb {
.required(
"SQL",
SyntaxShape::String,
"SQL to execute against the database",
"SQL to execute against the database.",
)
.category(Category::Custom("database".into()))
.category(Category::Database)
}
fn usage(&self) -> &str {

View File

@ -17,7 +17,7 @@ impl Command for SchemaDb {
fn signature(&self) -> Signature {
Signature::build(self.name())
.input_output_types(vec![(Type::Any, Type::Any)])
.category(Category::Custom("database".into()))
.category(Category::Database)
}
fn usage(&self) -> &str {

View File

@ -499,13 +499,7 @@ pub fn convert_sqlite_row_to_nu_value(row: &Row, span: Span, column_names: Vec<S
vals.push(val);
}
Value::record(
Record {
cols: column_names,
vals,
},
span,
)
Value::record(Record::from_raw_cols_vals(column_names, vals), span)
}
pub fn convert_sqlite_value_to_nu_value(value: ValueRef, span: Span) -> Value {

View File

@ -22,7 +22,7 @@ impl Command for SubCommand {
Signature::build("date to-timezone")
.input_output_types(vec![(Type::Date, Type::Date), (Type::String, Type::Date)])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.required("time zone", SyntaxShape::String, "time zone description")
.required("time zone", SyntaxShape::String, "Time zone description.")
.category(Category::Date)
}

View File

@ -25,7 +25,7 @@ impl Command for Ast {
.required(
"pipeline",
SyntaxShape::String,
"the pipeline to print the ast for",
"The pipeline to print the ast for.",
)
.switch("json", "serialize to json", Some('j'))
.switch("minify", "minify the nuon or json output", Some('m'))

View File

@ -23,7 +23,7 @@ impl Command for Explain {
.required(
"closure",
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),
"the closure to run",
"The closure to run.",
)
.input_output_types(vec![(Type::Any, Type::Any), (Type::Nothing, Type::Any)])
.allow_variants_without_examples(true)
@ -191,6 +191,24 @@ fn get_arguments(engine_state: &EngineState, stack: &mut Stack, call: Call) -> V
let arg_value_name_span_start = evaled_span.start as i64;
let arg_value_name_span_end = evaled_span.end as i64;
let record = record! {
"arg_type" => Value::string(arg_type, span),
"name" => Value::string(arg_value_name, inner_expr.span),
"type" => Value::string(arg_value_type, span),
"span_start" => Value::int(arg_value_name_span_start, span),
"span_end" => Value::int(arg_value_name_span_end, span),
};
arg_value.push(Value::record(record, inner_expr.span));
}
Argument::Spread(inner_expr) => {
let arg_type = "spread";
let evaluated_expression = get_expression_as_value(engine_state, stack, inner_expr);
let arg_value_name = debug_string_without_formatting(&evaluated_expression);
let arg_value_type = &evaluated_expression.get_type().to_string();
let evaled_span = evaluated_expression.span();
let arg_value_name_span_start = evaled_span.start as i64;
let arg_value_name_span_end = evaled_span.end as i64;
let record = record! {
"arg_type" => Value::string(arg_type, span),
"name" => Value::string(arg_value_name, inner_expr.span),
@ -259,6 +277,5 @@ pub fn debug_string_without_formatting(value: &Value) -> String {
Value::Binary { val, .. } => format!("{val:?}"),
Value::CellPath { val, .. } => val.to_string(),
Value::CustomValue { val, .. } => val.value_string(),
Value::MatchPattern { val, .. } => format!("{:?}", val),
}
}

View File

@ -4,7 +4,7 @@ use nu_protocol::{
record, Category, Example, IntoPipelineData, LazyRecord, PipelineData, Record, ShellError,
Signature, Span, Type, Value,
};
use sysinfo::{Pid, PidExt, ProcessExt, ProcessRefreshKind, RefreshKind, System, SystemExt};
use sysinfo::{MemoryRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
const ENV_PATH_SEPARATOR_CHAR: char = {
#[cfg(target_family = "windows")]
{
@ -98,8 +98,9 @@ impl LazySystemInfoRecord {
}
"system" => {
// only get information requested
let system_opt =
SystemOpt::from((system_option, || RefreshKind::new().with_memory()));
let system_opt = SystemOpt::from((system_option, || {
RefreshKind::new().with_memory(MemoryRefreshKind::everything())
}));
let system = system_opt.get_system();
@ -135,53 +136,66 @@ impl LazySystemInfoRecord {
"virtual_memory" => Value::filesize(p.virtual_memory() as i64, self.span),
"status" => Value::string(p.status().to_string(), self.span),
"root" => {
if let Some(filename) = p.exe().parent() {
Value::string(filename.to_string_lossy().to_string(), self.span)
if let Some(path) = p.exe().and_then(|p| p.parent()) {
Value::string(path.to_string_lossy().to_string(), self.span)
} else {
Value::nothing(self.span)
}
},
"cwd" => Value::string(p.cwd().to_string_lossy().to_string(), self.span),
"exe_path" => Value::string(p.exe().to_string_lossy().to_string(), self.span),
"cwd" => {
if let Some(path) = p.cwd() {
Value::string(path.to_string_lossy().to_string(), self.span)
}else{
Value::nothing(self.span)
}
},
"exe_path" => {
if let Some(path)= p.exe() {
Value::string(path.to_string_lossy().to_string(), self.span)
}else{
Value::nothing(self.span)
}
},
"command" => Value::string(p.cmd().join(" "), self.span),
"name" => Value::string(p.name().to_string(), self.span),
"environment" => {
let mut env_rec = Record::new();
for val in p.environ() {
if let Some((key, value)) = val.split_once('=') {
let is_env_var_a_list = {
"environment" => {
let mut env_rec = Record::new();
for val in p.environ() {
if let Some((key, value)) = val.split_once('=') {
let is_env_var_a_list = {
{
#[cfg(target_family = "windows")]
{
#[cfg(target_family = "windows")]
{
key == "Path" || key == "PATHEXT" || key == "PSMODULEPATH" || key == "PSModulePath"
}
#[cfg(not(target_family = "windows"))]
{
key == "PATH" || key == "DYLD_FALLBACK_LIBRARY_PATH"
}
key == "Path" || key == "PATHEXT" || key == "PSMODULEPATH" || key == "PSModulePath"
}
#[cfg(not(target_family = "windows"))]
{
key == "PATH" || key == "DYLD_FALLBACK_LIBRARY_PATH"
}
};
if is_env_var_a_list {
let items = value.split(ENV_PATH_SEPARATOR_CHAR).map(|r| Value::string(r.to_string(), self.span)).collect::<Vec<_>>();
env_rec.push(key.to_string(), Value::list(items, self.span));
} else if key == "LS_COLORS" { // LS_COLORS is a special case, it's a colon separated list of key=value pairs
let items = value.split(':').map(|r| Value::string(r.to_string(), self.span)).collect::<Vec<_>>();
env_rec.push(key.to_string(), Value::list(items, self.span));
} else {
env_rec.push(key.to_string(), Value::string(value.to_string(), self.span));
}
};
if is_env_var_a_list {
let items = value.split(ENV_PATH_SEPARATOR_CHAR).map(|r| Value::string(r.to_string(), self.span)).collect::<Vec<_>>();
env_rec.push(key.to_string(), Value::list(items, self.span));
} else if key == "LS_COLORS" { // LS_COLORS is a special case, it's a colon separated list of key=value pairs
let items = value.split(':').map(|r| Value::string(r.to_string(), self.span)).collect::<Vec<_>>();
env_rec.push(key.to_string(), Value::list(items, self.span));
} else {
env_rec.push(key.to_string(), Value::string(value.to_string(), self.span));
}
}
Value::record(env_rec, self.span)
},
}
Value::record(env_rec, self.span)
},
},
self.span,
))
} else {
// If we can't get the process information, just return the system information
// only get information requested
let system_opt =
SystemOpt::from((system_option, || RefreshKind::new().with_memory()));
let system_opt = SystemOpt::from((system_option, || {
RefreshKind::new().with_memory(MemoryRefreshKind::everything())
}));
let system = system_opt.get_system();
Ok(Value::record(
@ -228,7 +242,7 @@ impl<'a> LazyRecord<'a> for LazySystemInfoRecord {
.without_disk_usage()
.without_user(),
)
.with_memory();
.with_memory(MemoryRefreshKind::everything());
// only get information requested
let system = System::new_with_specifics(rk);

View File

@ -25,7 +25,7 @@ impl Command for Metadata {
.optional(
"expression",
SyntaxShape::Any,
"the expression you want metadata for",
"The expression you want metadata for.",
)
.category(Category::Debug)
}
@ -86,6 +86,12 @@ impl Command for Metadata {
PipelineMetadata {
data_source: DataSource::HtmlThemes,
} => record.push("source", Value::string("into html --list", head)),
PipelineMetadata {
data_source: DataSource::FilePath(path),
} => record.push(
"source",
Value::string(path.to_string_lossy().to_string(), head),
),
}
}
@ -133,6 +139,12 @@ fn build_metadata_record(arg: &Value, metadata: Option<&PipelineMetadata>, head:
PipelineMetadata {
data_source: DataSource::HtmlThemes,
} => record.push("source", Value::string("into html --list", head)),
PipelineMetadata {
data_source: DataSource::FilePath(path),
} => record.push(
"source",
Value::string(path.to_string_lossy().to_string(), head),
),
}
}

View File

@ -24,7 +24,7 @@ impl Command for TimeIt {
.required(
"command",
SyntaxShape::OneOf(vec![SyntaxShape::Block, SyntaxShape::Expression]),
"the command or block to run",
"The command or block to run.",
)
.input_output_types(vec![
(Type::Any, Type::Duration),

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