<!--
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 replaces `ropey` with `lsp-textdocument` for easier utf16
position handling.
As a side effect, if fixes the following crashing bug:
1. create a `foo.nu` file with errors in it
2. in `bar.nu`, add code `use foo.nu *`
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
* <s>Diagnostics are now triggered only with document open/save, that's
my personal preference. Changing back to previous behavior is easy if
you guys have other concerns.</s>
* UTF-8 position encoding is not supported by lsp-textdocument, but
that's not an issue, since the previous utf-8 ropey implementation is
buggy when used in real scenarios in a text editor.
# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->
No new tests added, removed some utf-8 related ones.
# 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.
-->
# Description
A follow-on to #14727:
* Instead of using `is-interactive` as the trigger for incrementing
`SHLVL`, this change puts the increment logic just before `run_repl()`
is called.
* Tests are changed to use `-e`
* Moves the `confirm_stdin_is_terminal()` call immediately **after** the
`prerun_cmd` (which executes `--execute (-e) <commandstring>`. The fact
that it was **before** that call seems to be a bug, since the error
message says *"or provide arguments to invoke a script"* even if
`--execute` was used. This change enables REPL testing using `--execute
(-e)`.
* Added a test to ensure `-c` does *not* increment SHLVL.
# User-Facing Changes
`$env.SHLVL` runs before the REPL is started, rather than when
`is-interactive`
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
N/A
# Description
I just spent way too long trying to get `nu --testbin nu_repl
<commands>` working. That's one argument that must be called as `nu
--testbin=nu_repl <commands>` due to its implementation. This PR simply
adds a comment in `main()` noting that, hoping it will save someone else
some time in the future ;-)
# User-Facing Changes
None
# Tests + Formatting
N/A
# After Submitting
N/A
# Description
Adds a user-level (non-vendor) autoload directory:
```
($nu.default-config-dir)/autoload
```
Currently this is the only directory. We can consider adding others if
needed.
Related: As a separate PR, I'm going to try to restore the ability to
set `$env.NU_AUTOLOAD_DIRS` during startup.
# User-Facing Changes
Files in `$nu.default-config-dir/autoload` will be autoload at startup.
These files will be loaded after any vendor autoloads, so that a user
can override the vendor settings.
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
TODO; add a `$nu.user-autoload-dirs` constant.
Doc updates
# Description
Takes advantage of #14591 to remove the now-necessary calls to
`convert_env_values()` that I added in #14249. The function is now just
called once to convert `PATH`.
Also removed the Windows-build-time checks for `ensure_path`, since
previous case-insensitivity fixes make this unnecessary as well.
# User-Facing Changes
None - #14591 now handles conversion 'on-demand'.
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
N/A
<!--
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.
-->
In this PR I continued the idea of #11494, it added an `auto` option to
the ansi coloring config option, I did this too but in a more simple
approach.
So I added a new enum `UseAnsiColoring` with the three values `True`,
`False` and `Auto`. When that value is set to `auto`, the default value,
it will use `std::io::stdout().is_terminal()` to decided whether to use
ansi coloring. This allows to dynamically decide whether to print ansi
color codes or not, [cargo does it the same
way](652623b779/src/bin/cargo/main.rs (L72)).
`True` and `False` act as overrides to the `is_terminal` check. So with
that PR it is possible to force ansi colors on the `table` command or
automatically remove them from the miette errors if no terminal is used.
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
Terminal users shouldn't be affected by this change as the default value
was `true` and `is_terminal` returns for terminals `true` (duh).
Non-terminal users, that use `nu` in some embedded way or the engine
implemented in some other way (like my jupyter kernel) will now have by
default no ansi coloring and need to enable it manually if their
environment allows it.
# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->
The test for fancy errors expected ansi codes, since tests aren't run
"in terminal", the ansi codes got stripped away.
I added a line that forced ansi colors above it. I'm not sure if that
should be the case or if we should test against no ansi colors.
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# 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 should resolve#11464 and partially #11847. This also closes
#11494.
# Description
With `NU_LIB_DIRS`, `NU_PLUGIN_DIRS`, and `ENV_CONVERSIONS` now moved
out of `default_env.nu`, we're down to just a few left. This moves all
non-closure `PROMPT` variables out as well (and into Rust `main()`. It
also:
* Implements #14565 and sets the default
`TRANSIENT_PROMPT_COMMAND_RIGHT` and `TRANSIENT_MULTILINE_INDICATOR` to
an empty string so that they are removed for easier copying from the
terminal.
* Reverses portions of #14249 where I was overzealous in some of the
variables that were imported
* Fixes#12096
* Will be the final fix in place, I believe, to close#13670
# User-Facing Changes
Transient prompt will now remove the right-prompt and
multiline-indicator once a commandline has been entered.
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
-
# After Submitting
Release notes addition
<!--
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.
-->
fixes#14567
Now NuShell's `exec` command will decrement `SHLVL` env value before
passing it to target executable.
It only works in interactive session, the same as `SHLVL`
initialization.
In addition, this PR also make a simple change to `SHLVL` initialization
(only remove an unnecessary type conversion).
# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->
Formatted.
With interactively tested with several shells (bash, zsh, fish) and
cross-exec-ing them, it works well this time.
# 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.
-->
# Description
With Windows Path case-insensitivity in place, we no longer need an
`ENV_CONVERSIONS` for `PATH`, as the
`nu_engine::env::convert_env_values()` handles it automatically.
This PR:
* Removes the default `ENV_CONVERSIONS` for path from `default_env.nu`
* Sets `ENV_CONVERSIONS` to an empty record (so it can be `merge`'d) in
`main()` instead
# User-Facing Changes
No behavioral changes - Users will now have an empty `ENV_CONVERSIONS`
at startup by default, but the behavior should not change.
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
# Description
Fix#14544 and is also the reciprocal of #14549.
Before: If both a const and env `NU_PLUGIN_DIRS` were defined at the
same time, the env paths would not be used.
After: The directories from `const NU_PLUGIN_DIRS` are searched for a
matching filename, and if not found, `$env.NU_PLUGIN_DIRS` directories
will be searched.
Before: `$env.NU_PLUGIN_DIRS` was unnecessary set both in main() and in
default_env.nu
After: `$env.NU_PLUGIN_DIRS` is only set in main()
Before: `$env.NU_PLUGIN_DIRS` was set to `plugins` in the config
directory
After: `$env.NU_PLUGIN_DIRS` is set to an empty list and `const
NU_PLUGIN_DIRS` is set to the directory above.
Also updates `sample_env.nu` to use the `const`
# User-Facing Changes
Most scenarios should work just fine as there continues to be an
`$env.NU_PLUGIN_DIRS` to append to or override.
However, there is a small chance of a breaking change if someone was
*querying* the old default `$env.NU_PLUGIN_DIRS`.
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
Also updated the `env` tests and added one for the `const`.
# After Submitting
Config doc updates
# Description
A slower, gentler alternative to #14531, in that we're just moving one
setting *out* of `default_env.nu` in this PR ;-).
All this does is transition from using `$env.NU_LIB_DIRS` in the startup
config to `const $NU_LIB_DIRS`. Also updates the `sample_env.nu` to
reflect the changes.
Details:
Before: `$env.NU_LIB_DIRS` was unnecessary set both in `main()` and in
`default_env.nu`
After: `$env.NU_LIB_DIRS` is only set in `main()`
Before: `$env.NU_LIB_DIRS` was set to `config-dir/scripts` and
`data-dir/completions`
After: `$env.NU_LIB_DIRS` is set to an empty list, and `const
NU_LIB_DIRS` is set to the directories above
Before: Using `--include-path (-I)` would set the `$env.NU_LIB_DIRS`
After: Using `--include-path (-I)` sets the constant `$NU_LIB_DIRS`
# User-Facing Changes
There shouldn't be any breaking changes here. The `$env.NU_LIBS_DIRS`
still works for most cases. There are a few areas we need to clean-up to
make sure that the const is usable (`nu-check`, et. al.) but they will
still work in the meantime with the older `$env` version.
# Tests + Formatting
* Changed the Type-check on the `$env` version.
* Added a type check for the const version.
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
Doc updates
# Description
fixes
[this](https://github.com/nushell/nushell/pull/14303#issuecomment-2525100480)
where lsp and ide integration would produce the following error
---
```sh
nu --ide-check 100 "/path/to/env.nu"
```
with
```nu
const const_env = path self
```
would lead to
```
Error: nu:🐚:file_not_found
× File not found
╭─[/path/to/env.nu:1:19]
1 │ const const_env = path self
· ────┬────
· ╰── Couldn't find current file
╰────
```
# Tests + Formatting
- 🟢 `cargo fmt --all`
- 🟢 `cargo clippy --workspace`
This PR implements PWD-per-drive as described in discussion #14355
# Description
On Windows, CMD or PowerShell assigns each drive its own current
directory. For example, if you are in 'C:\Windows', switch to 'D:', and
navigate to 'D:\Game', you can return to 'C:\Windows' by simply typing
'C:'.
This PR enables Nushell on Windows to have the same capability, allowing
each drive to maintain its own PWD (Present Working Directory).
# User-Facing Changes
Currently, 'cd' or 'ls' only accept absolute paths if the path starts
with 'C:' or another drive letter. With PWD-per-drive, users can use
'cd' (or auto cd) and 'ls' in the same way as 'cd' and 'dir' in
PowerShell, or similarly to 'cd' and 'dir' in CMD (noting that cd in CMD
has slightly different behavior, 'cd' for another drive only changes
current directory of that drive, but does not switch there).
Interaction example on switching between drives:
```Nushell
~>D:
D:\>cd Test
D:\Test\>C:
~>D:
D:\Test\>C:
~>cd D:..
D:\>C:x/../y/../z/..
~>cd D:Test\Test
D:\Test\Test>C:
~>D:...
D:\>
```
Interaction example on auto-completion at cmd line:
```Nushell
~>cd D:\test[Enter]
D:\test>~[Enter]
~>D:[TAB]
~>D:\test[Enter]
D:\test>c:.c[TAB]
c:\users\nushell\.cargo\ c:\users\nushell\.config\
```
Interaction example on pass PWD-per-drive to child process: (Note CMD
will use it, but PowerShell will ignore it though it still prepares such
info for child process)
```Nushell
~>cd D:\Test
D:\Test>cd E:\Test
E:\Test\>~
~>CMD
Microsoft Windows [Version 10.0.22631.4460]
(c) Microsoft Corporation. All rights reserved.
C:\Users\Nushell>d:
D:\Test>e:
E:\Test>
```
# Brief Change Description
1.Added 'crates/nu-path/src/pwd_per_drive.rs' to implement a 26-slot
array mapping drive letters to PWDs. Test cases are included in the same
file, along with a doctest for the usage of PWD-per-drive.
2. Modified 'crates/nu-path/src/lib.rs' to declare module of
pwd_per_drive and export struct for PWD-per-drive.
3. Modified 'crates/nu-protocol/src/engine/stack.rs' to sync PWD when
set_cwd() is called. Add PWD-per-drive map as member. Clone between
parent and child. Stub/proxy for nu_path::expand_path_with() to
facilitate filesystem commands using PWD-per-drive.
4. Modified 'crates/nu-cli/src/repl.rs' auto_cd uses PWD-per-drive to
expand path.
5. Modified 'crates/nu-cli/src/completions/completion_common.rs' to
expand relative path when press [TAB] at command line.
6. Modified 'crates/nu-engine/src/env.rs' to collect PWD-per-drive info
as env vars for child process as CMD or PowerShell do, this can let
child process inherit PWD-per-drive info.
7. Modified 'crates/nu-engine/src/eval.rs', caller clone callee's
PWD-per-drive info, supporting 'def --env'
8. Modified 'crates/nu-engine/src/eval_ir.rs', 'def --env' support.
Remove duplicated fn redirect_env()
9. Modified 'src/run.rs', to init PWD-per-drive when startup.
filesystem commands that modified:
1. Modified 'crates/nu-command/src/filesystem/cd.rs', 1 line change to
use stackscoped PWD-per-drive.
Other commands, commit pending....
Local test def --env OK:
```nushell
E:\study\nushell> def --env env_cd_demo [] {
::: cd ~
::: cd D:\Project
::: cd E:Crates
::: }
E:\study\nushell>
E:\study\nushell> def cd_no_demo [] {
::: cd ~
::: cd D:\Project
::: cd E:Crates
::: }
E:\study\nushell> cd_no_demo
E:\study\nushell> C:
C:\>D:
D:\>E:
E:\study\nushell>env_cd_demo
E:\study\nushell\crates> C:
~>D:
D:\Project>E:
E:\study\nushell\crates>
```
# Tests + Formatting
- `cargo fmt --all -- --check` passed.
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
passed.
- `cargo test --workspace` passed on Windows developer mode and Ubuntu.
- `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` passed.
- nushell:
```
> use toolkit.nu # or use an `env_change` hook to activate it automatically
> toolkit check pr
> ```
passed
---------
Co-authored-by: pegasus.cadence@gmail.com <pegasus.cadence@gmail.com>
# Description
Follow up to #14341. Changes the fields of `Hooks` to `Vec` or `Hashmap`
to match the new config defaults.
# User-Facing Changes
Mostly the same as #14341. `pre_prompt` and `pre_execution` must now be
a list, and `env_change` must be a record.
# Description
As a bit of a follow-on to #13802 and #14249, this (pretty much a
"one-line" change) really does *always* populate the `$env.config`
record with the `nu-protocol::config` defaults during startup. This
means that an `$env.config` record is value (with defaults) even during:
* `nu -n` to suppress loading of config files
* `nu -c <commandstring>`
* `nu <script>`
# User-Facing Changes
There should be no case in which there isn't a valid `$env.config`.
* Before:
```nushell
nu -c "$env.config"
# -> Error
```
* After:
```nushell
nu -c "$env.config"
# -> Default $env.config record
```
Startup time impact is negligible (17.072µs from `perf!` on my system) -
Seems well worth it.
# Tests + Formatting
Added tests for several `-n -c` cases.
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
Config chapter update still in progress.
<!--
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.
-->
Make NuShell correctly inherit and update `SHLVL` from other shells
(obviously including itself) in Unix environment.
See issue #14384
# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->
New code formatted.
New feature works well in interactive usage.
# 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.
-->
# Release-Notes Short Description
* Nushell now always loads its internal `default_env.nu` before the user
`env.nu` is loaded, then loads the internal `default_config.nu` before
the user's `config.nu` is loaded. This allows for a simpler
user-configuration experience. The Configuration Chapter of the Book
will be updated soon with the new behavior.
# Description
Implements the main ideas in #13671 and a few more:
* Users can now specify only the environment and config options they
want to override in *their* `env.nu` and `config.nu`and yet still have
access to all of the defaults:
* `default_env.nu` (internally defined) will be loaded whenever (and
before) the user's `env.nu` is loaded.
* `default_config.nu` (internally defined) will be loaded whenever (and
before) the user's `config.nu` is loaded.
* No more 900+ line config out-of-the-box.
* Faster startup (again): ~40-45% improvement in launch time with a
default configuration.
* New keys that are added to the defaults in the future will
automatically be available to all users after updating Nushell. No need
to regenerate config to get the new defaults.
* It is now possible to have different internal defaults (which will be
used with `-c` and scripts) vs. REPL defaults. This would have solved
many of the user complaints about the [`display_errors`
implementation](https://www.nushell.sh/blog/2024-09-17-nushell_0_98_0.html#non-zero-exit-codes-are-now-errors-toc).
* A basic "scaffold" `config.nu` and `env.nu` are created on first
launch (if the config directory isn't present).
* Improved "out-of-the-box" experience (OOBE) - No longer asks to create
the files; the minimal scaffolding will be automatically created. If
deleted, they will not be regenerated. This provides a better
"out-of-the-box" experience for the user as they no longer have to make
this decision (without much info on the pros or cons) when first
launching.
* <s>(New: 2024-11-07) Runs the env_conversions process after the
`default_env.nu` is loaded so that users can treat `Path`/`PATH` as
lists in their own config.</s>
* (New: 2024-11-08) Given the changes in #13802, `default_config.nu`
will be a minimal file to minimize load-times. This shaves another (on
my system) ~3ms off the base launch time.
* Related: Keybindings, menus, and hooks that are already internal
defaults are no longer duplicated in `$env.config`. The documentation
will be updated to cover these scenarios.
* (New: 2024-11-08) Move existing "full" `default_config.nu` to
`sample_config.nu` for short-term "documentation" purposes.
* (New: 2024-11-18) Move the `dark-theme` and `light-theme` to Standard
Library and demonstrate their use - Also improves startup times, but
we're reaching the limit of optimization.
* (New: 2024-11-18) Extensively documented/commented `sample_env.nu` and
`sample_config.nu`. These can be displayed in-shell using (for example)
`config nu --sample | nu-highlight | less -R`. Note: Much of this will
eventually be moved to or (some) duplicated in the Doc. But for now,
this some nice in-shell doc that replaces the older
"commented/documented default".
* (New: 2024-11-20) Runs the `ENV_CONVERSIONS` process (1) after the
`default_env.nu` (allows `PATH` to be used as a list in user's `env.nu`)
and (2) before `default_config.nu` is loaded (allows user's
`ENV_CONVERSIONS` from their `env.nu` to be used in their `config.nu`).
* <s>(New: 2024-11-20) The default `ENV_CONVERSIONS` is now an empty
record. The internal Rust code handles `PATH` (and variants) conversions
regardless of the `ENV_CONVERSIONS` variable. This shaves a *very* small
amount of time off the startup.</s> Reset - Looks like there might be a
bug in `nu-enginer::env::ensure_path()` on Windows that would need to be
fixed in order for this to work.
# User-Facing Changes
By default, you shouldn't see much, if any, change when running this
with your existing configuration.
To see the greatest benefit from these changes, you'll probably want to
start with a "fresh" config. This can be easily tested using something
like:
```nushell
let temp_home = (mktemp -d)
$env.XDG_CONFIG_HOME = $temp_home
$env.XDG_DATA_HOME = $temp_home
./target/release/nu
```
You should see a message where the (mostly empty) `env.nu` and
`config.nu` are created on first start. Defaults should be the same (or
similar to) those before the PR. Please let me know if you notice any
differences.
---
Users should now specify configuration in terms of overrides of each
setting. For instance, rather than modifying `history` settings in the
monolithic `config.nu`, the following is recommended in an updated
`config.nu`:
```nu
$env.config.history = {
file_format: sqlite,
sync_on_enter: true
isolation: true
max_size: 1_000_000
}
```
or even just:
```nu
$env.config.history.file_format = sqlite
$env.config.history.isolation: true
$env.config.history.max_size = 1_000_000
```
Note: It seems many users are already appending a `source my_config.nu`
(or similar pattern) to the end of the existing `config.nu` to make
updates easier. In this case, they will likely want to remove all of the
previous defaults and just move their `my_config.nu` to `config.nu`.
Note: It should be unlikely that there are any breaking changes here,
but there's a slim chance that some code, somewhere, *expects* an
absence of certain config values. Otherwise, all config values are
available before and after this change.
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
Configuration Chapter (and related) of the doc is currently WIP and will
be finished in time for 0.101 release.
# Description
Removes the `NU_DISABLE_IR` option and some code related to evaluating
blocks with the AST
evaluator.
Does not entirely remove the AST evaluator yet. We still have some
dependencies on expression
evaluation in a few minor places which will take a little bit of effort
to fix.
Also changes `debug profile` to always include instructions, because the
output is a little
confusing otherwise, and removes the different options for
instructions/exprs.
# User-Facing Changes
- `NU_DISABLE_IR` no longer has any effect, and is removed. There is no
way to use the AST
evaluator.
- `debug profile` no longer has `--exprs`, `--instructions` options.
- `debug profile` lists `pc` and `instruction` columns by default now.
# Tests + Formatting
Eval tests fixed to only use IR.
# After Submitting
- [ ] release notes
- [ ] finish removing AST evaluator, come up with solutions for the
expression evaluation.
# Description
Turns out there are duplicate conversion functions: `as_i64` and
`as_f64`. In most cases, these can be replaced with `as_int` and
`as_float`, respectively.
<!--
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 fixes the quoting and escaping of column names in `to nuon`.
Before the PR, column names with quotes inside them would get quoted,
but not escaped:
```nushell
> { 'a"b': 2 } | to nuon
{ "a"b": 2 }
> { 'a"b': 2 } | to nuon | from nuon
Error: × error when loading nuon text
╭─[entry #1:1:27]
1 │ { "a\"b": 2 } | to nuon | from nuon
· ────┬────
· ╰── could not load nuon text
╰────
Error: × error when parsing nuon text
╭─[entry #1:1:27]
1 │ { "a\"b": 2 } | to nuon | from nuon
· ────┬────
· ╰── could not parse nuon text
╰────
Error: × error when parsing
╭────
1 │ {"a"b": 2}
· ┬
· ╰── Unexpected end of code.
╰────
> [['a"b']; [2] [3]] | to nuon
[["a"b"]; [2], [3]]
> [['a"b']; [2] [3]] | to nuon | from nuon
Error: × error when loading nuon text
╭─[entry #1:1:32]
1 │ [['a"b']; [2] [3]] | to nuon | from nuon
· ────┬────
· ╰── could not load nuon text
╰────
Error: × error when parsing nuon text
╭─[entry #1:1:32]
1 │ [['a"b']; [2] [3]] | to nuon | from nuon
· ────┬────
· ╰── could not parse nuon text
╰────
Error: × error when parsing
╭────
1 │ [["a"b"]; [2], [3]]
· ┬
· ╰── Unexpected end of code.
╰────
```
After this PR, the quote is escaped properly:
```nushell
> { 'a"b': 2 } | to nuon
{ "a\"b": 2 }
> { 'a"b': 2 } | to nuon | from nuon
╭─────┬───╮
│ a"b │ 2 │
╰─────┴───╯
> [['a"b']; [2] [3]] | to nuon
[["a\"b"]; [2], [3]]
> [['a"b']; [2] [3]] | to nuon | from nuon
╭─────╮
│ a"b │
├─────┤
│ 2 │
│ 3 │
╰─────╯
```
The cause of the issue was that `to nuon` simply wrapped column names in
`'"'` instead of calling `escape_quote_string`.
As part of this change, I also moved the functions related to quoting
(`needs_quoting` and `escape_quote_string`) into `nu-utils`, since
previously they were defined in very ad-hoc places (and, in the case of
`escape_quote_string`, it was defined multiple times with the same
body!).
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
`to nuon` now properly escapes quotes in column names.
# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->
All tests pass, including workspace and stdlib tests.
# 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.
-->
# Description
This PR standardizes updates to the config through a new
`UpdateFromValue` trait. For now, this trait is private in case we need
to make changes to it.
Note that this PR adds some additional `ShellError` cases to create
standard error messages for config errors. A follow-up PR will move
usages of the old error cases to these new ones. This PR also uses
`Type::custom` in lots of places (e.g., for string enums). Not sure if
this is something we want to encourage.
# User-Facing Changes
Should be none.
# Description
Currently there is a bit of chaos regarding construction of history file
paths. Various pieces of code across a number of crates reimplement the
same/similar logic:
- There is `get_history_path`, but it requires a directory parameter (it
really just joins it with a file name).
- Some places use a const for the directory parameter, others use a
string literal - in all cases the value seems to be `"nushell"`.
- Some places assume the `"nushell"` value, other plumb it down from
close to the top of the call stack.
- Some places use a constant for history file names while others assume
it.
This PR tries to make it so that the history/config path format is
defined in a single places and so dependencies on it are easier to
follow:
- It removes `get_history_path` and adds a `file_path` method to
`HistoryConfig` instead (an extra motivation being, this is a convenient
place that can be used from all creates that need a history file path)
- Adds a `nu_config_dir` function that returns the nushell configuration
directory.
- Updates existing code to rely on the above, effectively removing
duplicate uses of `"nushell"` and `NUSHELL_FOLDER` and assumptions about
file names associated with different history formats
# User-Facing Changes
None
# Description
Title says it all, changes `EngineState::get_env_var` to return a
`Option<&'a Value>` instead of an owned `Option<Value>`. This avoids
some unnecessary clones.
I also made a similar change to the `PluginExecutionContext` trait.
# Description
Implements #13669
When nu is started for the first time, the directory represented by
`$nu.default-config-dir` typically will not exist. In this case, Nushell
will create the directory. It will then detect that either or both
`config.nu`/`env.nu` don't exist and offer to create them.
(Existing behavior) If the user declines, the directory will still be
created (since the history file lives there as well). The
`default_config.nu` and `default_env.nu` will be loaded.
On subsequent launches, as long as the config directory continues to
exist, the user will not be prompted to recreate the config files.
Nushell will behave as if the user answered "N" to the prompt in that
`default_config.nu` and `default_env.nu` will be used.
The user can still create a `config.nu` or `env.nu` at any point, and
that will be used. In that case, `default_config.nu` and/or
`default_env.nu` will no longer be loaded (unless and until #13671 is
implemented).
# User-Facing Changes
User will no longer be prompted to create config files if they are
missing so long as the config directory exists.
## Before this change:
1. Nushell starts for the first time
2. The directory where config files are stored does not exist
3. The config files do not exist
* User is asked whether they want to create `env.nu`
- User says, "Y", `default_env.nu` is copied to the directory as
`env.nu` (and directory is created if needed)
- User says, "n", `default_env.nu` is loaded, but no file on the
filesystem is created.
* User is asked whether they want to create `config.nu`
- User says, "Y", `default_config.nu` is copied to the directory as
`config.nu` (and directory is created if needed)
- User says, "n", `default_config.nu` is loaded, but no file on the
filesystem is created.
4. The next time `nu` is run, if either file is missing, the user will
be prompted again for that file.
## After this change:
Steps 1 - 3 remains the same.
4. The next time `nu` is run, we check if the directory exists. If so:
5. Do not prompt user to create any missing files **(New Behavior)**
6. `$nu.default-config-dir/env.nu` exists?
* Yes? Use it. (Normal behavior)
* No? Evaluate `default_env.nu`. (Normal behavior)
* No file is created on the filesystem
7. `$nu.default-config-dir/config.nu` exists?
* Yes? Use it. (Normal behavior)
* No? Evaluate `default_config.nu` (Normal behavior)
* No file is created on the filesystem
# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
# After Submitting
This behavior isn't currently mentioned in the configuration doc. I'll
probably hold off on changing anything in the doc until #13671 is
implemented. Regardless, given the timing, this won't make it into a
release for at least 4 weeks.
This PR sets the current working directory to the location of the
Nushell executable at startup, using `std::env::set_current_dir()`. This
is desirable because after PR
https://github.com/nushell/nushell/pull/12922, we no longer change our
current working directory even after `cd` is executed, and some OS might
lock the directory where Nushell started.
The location of the Nushell executable is chosen because it cannot be
removed while Nushell is running anyways, so we don't have to worry
about OS locking it.
This PR has the side effect that it breaks buggy command even harder.
I'll keep this PR as a draft until these commands are fixed, but it
might be helpful to pull this PR if you're working on fixing one of
those bugs.
---------
Co-authored-by: Devyn Cairns <devyn.cairns@gmail.com>
Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
# Description
Partialy addresses #13868. `try` does not catch non-zero exit code
errors from the last command in a pipeline if the result is assigned to
a variable using `let` (or `mut`).
This was fixed by adding a new `OutDest::Value` case. This is used when
the pipeline is in a "value" position. I.e., it will be collected into a
value. This ended up replacing most of the usages of `OutDest::Capture`.
So, this PR also renames `OutDest::Capture` to `OutDest::PipeSeparate`
to better fit the few remaining use cases for it.
# User-Facing Changes
Bug fix.
# Tests + Formatting
Added two tests.
# Description
Makes IR the default evaluator, in preparation to remove the non-IR
evaluator in a future release.
# User-Facing Changes
* Remove `NU_USE_IR` option
* Add `NU_DISABLE_IR` option
* IR is enabled unless `NU_DISABLE_IR` is set
# After Submitting
- [ ] release notes
# Description
This fixes a couple of remaining differences between the IR evaluator's
handling of env vars and the AST evaluator's handling of env vars.
Blocker for #13718 (this is why those tests failed)
# User-Facing Changes
1. Handles checking overlays for hidden env vars properly, when getting
an env var from IR instruction
2. Updates config properly when doing `redirect_env()` (these probably
shouldn't be separate functions anyway, though, they're basically the
same. I did this because I intended to remove one, but now it's just
like that)
# Tests + Formatting
The `nu_repl` testbin now handles `NU_USE_IR` properly, so these tests
now work as expected.
# After Submitting
- [ ] check in on #13718 again
# Description
This PR makes it so that non-zero exit codes and termination by signal
are treated as a normal `ShellError`. Currently, these are silent
errors. That is, if an external command fails, then it's code block is
aborted, but the parent block can sometimes continue execution. E.g.,
see #8569 and this example:
```nushell
[1 2] | each { ^false }
```
Before this would give:
```
╭───┬──╮
│ 0 │ │
│ 1 │ │
╰───┴──╯
```
Now, this shows an error:
```
Error: nu:🐚:eval_block_with_input
× Eval block failed with pipeline input
╭─[entry #1:1:2]
1 │ [1 2] | each { ^false }
· ┬
· ╰── source value
╰────
Error: nu:🐚:non_zero_exit_code
× External command had a non-zero exit code
╭─[entry #1:1:17]
1 │ [1 2] | each { ^false }
· ──┬──
· ╰── exited with code 1
╰────
```
This PR fixes#12874, fixes#5960, fixes#10856, and fixes#5347. This
PR also partially addresses #10633 and #10624 (only the last command of
a pipeline is currently checked). It looks like #8569 is already fixed,
but this PR will make sure it is definitely fixed (fixes#8569).
# User-Facing Changes
- Non-zero exit codes and termination by signal now cause an error to be
thrown.
- The error record value passed to a `catch` block may now have an
`exit_code` column containing the integer exit code if the error was due
to an external command.
- Adds new config values, `display_errors.exit_code` and
`display_errors.termination_signal`, which determine whether an error
message should be printed in the respective error cases. For
non-interactive sessions, these are set to `true`, and for interactive
sessions `display_errors.exit_code` is false (via the default config).
# Tests
Added a few tests.
# After Submitting
- Update docs and book.
- Future work:
- Error if other external commands besides the last in a pipeline exit
with a non-zero exit code. Then, deprecate `do -c` since this will be
the default behavior everywhere.
- Add a better mechanism for exit codes and deprecate
`$env.LAST_EXIT_CODE` (it's buggy).
# Description
This PR fixes#13732. However, I don't think it's a proper fix.
1. It doesn't really show what the problem is.
2. It kind of side-steps the error entirely.
I do think the change in span.rs may be valid because I don't think
span.end should ever be 0. In the example in 13732 the span end was
always 0 and so that made contains_span() return true, which seems like
a false positive.
The `checked_sub()` in ide.rs kind of just stops it from failing
outloud.
I'll leave it to smarter folks than me to land this if they think it's
worthy.
# Description
The meaning of the word usage is specific to describing how a command
function is *used* and not a synonym for general description. Usage can
be used to describe the SYNOPSIS or EXAMPLES sections of a man page
where the permitted argument combinations are shown or example *uses*
are given.
Let's not confuse people and call it what it is a description.
Our `help` command already creates its own *Usage* section based on the
available arguments and doesn't refer to the description with usage.
# User-Facing Changes
`help commands` and `scope commands` will now use `description` or
`extra_description`
`usage`-> `description`
`extra_usage` -> `extra_description`
Breaking change in the plugin protocol:
In the signature record communicated with the engine.
`usage`-> `description`
`extra_usage` -> `extra_description`
The same rename also takes place for the methods on
`SimplePluginCommand` and `PluginCommand`
# Tests + Formatting
- Updated plugin protocol specific changes
# After Submitting
- [ ] update plugin protocol doc
# Description
Fixes#13587
# User-Facing Changes
Files without ending or non-`*.nu` files will not be loaded as
vendor/configuration files.
# Tests + Formatting
So far we don't have any tests for that..
This PR will close#13501
# Description
This PR expands on [the relay of signals to running plugin
processes](https://github.com/nushell/nushell/pull/13181). The Ctrlc
relay has been generalized to SignalAction::Interrupt and when
reset_signal is called on the main EngineState, a SignalAction::Reset is
now relayed to running plugins.
# User-Facing Changes
The signal handler closure now takes a `signals::SignalAction`, while
previously it took no arguments. The handler will now be called on both
interrupt and reset. The method to register a handler on the plugin side
is now called `register_signal_handler` instead of
`register_ctrlc_handler`
[example](https://github.com/nushell/nushell/pull/13510/files#diff-3e04dff88fd0780a49778a3d1eede092ec729a1264b4ef07ca0d2baa859dad05L38).
This will only affect plugin authors who have started making use of
https://github.com/nushell/nushell/pull/13181, which isn't currently
part of an official release.
The change will also require all of user's plugins to be recompiled in
order that they don't error when a signal is received on the
PluginInterface.
# Testing
```
: example ctrlc
interrupt status: false
waiting for interrupt signal...
^Cinterrupt status: true
peace.
Error: × Operation interrupted
╭─[display_output hook:1:1]
1 │ if (term size).columns >= 100 { table -e } else { table }
· ─┬
· ╰── This operation was interrupted
╰────
: example ctrlc
interrupt status: false <-- NOTE status is false
waiting for interrupt signal...
^Cinterrupt status: true
peace.
Error: × Operation interrupted
╭─[display_output hook:1:1]
1 │ if (term size).columns >= 100 { table -e } else { table }
· ─┬
· ╰── This operation was interrupted
╰────
```
# Description
Part 3 of replacing `std::path` types with `nu_path` types added in
#13115. This PR targets the paths listed in `$nu`. That is, the home,
config, data, and cache directories.
# Description
This PR adds a new method to `EngineInterface`: `register_ctrlc_handler`
which takes a closure to run when the plugin's driving engine receives a
ctrlc-signal. It also adds a mirror of the `signals` attribute from the
main shell `EngineState`.
This is an example of how a plugin which makes a long poll http request
can end the request on ctrlc:
https://github.com/cablehead/nu_plugin_http/blob/main/src/commands/request.rs#L68-L77
To facilitate the feature, a new attribute has been added to
`EngineState`: `ctrlc_handlers`. This is a Vec of closures that will be
run when the engine's process receives a ctrlc signal.
When plugins are added to an `engine_state` during a `merge_delta`, the
engine passes the ctrlc_handlers to the plugin's
`.configure_ctrlc_handler` method, which gives the plugin a chance to
register a handler that sends a ctrlc packet through the
`PluginInterface`, if an instance of the plugin is currently running.
On the plugin side: `EngineInterface` also has a ctrlc_handlers Vec of
closures. Plugin calls can use `register_ctrlc_handler` to register a
closure that will be called in the plugin process when the
PluginInput::Ctrlc command is received.
For future reference these are some alternate places that were
investigated for tying the ctrlc trigger to transmitting a Ctrlc packet
through the `PluginInterface`:
- Directly from `src/signals.rs`: the handler there would need a
reference to the Vec<Arc<RegisteredPlugins>>, which would require us to
wrap the plugins in a Mutex, which we don't want to do.
- have `PersistentPlugin.get_plugin` pass down the engine's
CtrlcHandlers to .get and then to .spawn (if the plugin isn't already
running). Once we have CtrlcHandlers in spawn, we can register a handler
to write directly to PluginInterface. We don't want to double down on
passing engine_state to spawn this way though, as it's unpredictable
because it would depend on whether the plugin has already been spawned
or not.
- pass `ctrlc_handlers` to PersistentPlugin::new so it can store it on
itself so it's available to spawn.
- in `PersistentPlugin.spawn`, create a handler that sends to a clone of
the GC event loop's tx. this has the same issues with regards to how to
get CtrlcHandlers to the spawn method, and is more complicated than a
handler that writes directly to PluginInterface
# User-Facing Changes
No breaking changes
---------
Co-authored-by: Ian Manske <ian.manske@pm.me>
fixes https://github.com/nushell/nushell/issues/13378
# Description
This PR tries to improve usage of system APIs to determine the location
of vendored autoload files.
# User-Facing Changes
The paths listed in #13180 and #13217 are changing. This has not been
part of a release yet, so arguably the user facing changes are only to
unreleased features anyway.
# Tests + Formatting
Haven't done, but if someone wants to help me here, I'm open to doing
it. I just don't know how to properly test this.
# After Submitting
<!--
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.
-->
Replaces the `dirs_next` family of crates with `dirs`. `dirs_next` was
born when the `dirs` crates were abandoned three years ago, but they're
being maintained again and most projects depend on `dirs` nowadays.
`dirs_next` has been abandoned since.
This came up while working on
https://github.com/nushell/nushell/pull/13382.
# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->
Tests and formatter have been run.
# 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.
-->
# Description
This PR adds an internal representation language to Nushell, offering an
alternative evaluator based on simple instructions, stream-containing
registers, and indexed control flow. The number of registers required is
determined statically at compile-time, and the fixed size required is
allocated upon entering the block.
Each instruction is associated with a span, which makes going backwards
from IR instructions to source code very easy.
Motivations for IR:
1. **Performance.** By simplifying the evaluation path and making it
more cache-friendly and branch predictor-friendly, code that does a lot
of computation in Nushell itself can be sped up a decent bit. Because
the IR is fairly easy to reason about, we can also implement
optimization passes in the future to eliminate and simplify code.
2. **Correctness.** The instructions mostly have very simple and
easily-specified behavior, so hopefully engine changes are a little bit
easier to reason about, and they can be specified in a more formal way
at some point. I have made an effort to document each of the
instructions in the docs for the enum itself in a reasonably specific
way. Some of the errors that would have happened during evaluation
before are now moved to the compilation step instead, because they don't
make sense to check during evaluation.
3. **As an intermediate target.** This is a good step for us to bring
the [`new-nu-parser`](https://github.com/nushell/new-nu-parser) in at
some point, as code generated from new AST can be directly compared to
code generated from old AST. If the IR code is functionally equivalent,
it will behave the exact same way.
4. **Debugging.** With a little bit more work, we can probably give
control over advancing the virtual machine that `IrBlock`s run on to
some sort of external driver, making things like breakpoints and single
stepping possible. Tools like `view ir` and [`explore
ir`](https://github.com/devyn/nu_plugin_explore_ir) make it easier than
before to see what exactly is going on with your Nushell code.
The goal is to eventually replace the AST evaluator entirely, once we're
sure it's working just as well. You can help dogfood this by running
Nushell with `$env.NU_USE_IR` set to some value. The environment
variable is checked when Nushell starts, so config runs with IR, or it
can also be set on a line at the REPL to change it dynamically. It is
also checked when running `do` in case within a script you want to just
run a specific piece of code with or without IR.
# Example
```nushell
view ir { |data|
mut sum = 0
for n in $data {
$sum += $n
}
$sum
}
```
```gas
# 3 registers, 19 instructions, 0 bytes of data
0: load-literal %0, int(0)
1: store-variable var 904, %0 # let
2: drain %0
3: drop %0
4: load-variable %1, var 903
5: iterate %0, %1, end 15 # for, label(1), from(14:)
6: store-variable var 905, %0
7: load-variable %0, var 904
8: load-variable %2, var 905
9: binary-op %0, Math(Plus), %2
10: span %0
11: store-variable var 904, %0
12: load-literal %0, nothing
13: drain %0
14: jump 5
15: drop %0 # label(0), from(5:)
16: drain %0
17: load-variable %0, var 904
18: return %0
```
# Benchmarks
All benchmarks run on a base model Mac Mini M1.
## Iterative Fibonacci sequence
This is about as best case as possible, making use of the much faster
control flow. Most code will not experience a speed improvement nearly
this large.
```nushell
def fib [n: int] {
mut a = 0
mut b = 1
for _ in 2..=$n {
let c = $a + $b
$a = $b
$b = $c
}
$b
}
use std bench
bench { 0..50 | each { |n| fib $n } }
```
IR disabled:
```
╭───────┬─────────────────╮
│ mean │ 1ms 924µs 665ns │
│ min │ 1ms 700µs 83ns │
│ max │ 3ms 450µs 125ns │
│ std │ 395µs 759ns │
│ times │ [list 50 items] │
╰───────┴─────────────────╯
```
IR enabled:
```
╭───────┬─────────────────╮
│ mean │ 452µs 820ns │
│ min │ 427µs 417ns │
│ max │ 540µs 167ns │
│ std │ 17µs 158ns │
│ times │ [list 50 items] │
╰───────┴─────────────────╯
```
![explore ir
view](https://github.com/nushell/nushell/assets/10729/d7bccc03-5222-461c-9200-0dce71b83b83)
##
[gradient_benchmark_no_check.nu](https://github.com/nushell/nu_scripts/blob/main/benchmarks/gradient_benchmark_no_check.nu)
IR disabled:
```
╭───┬──────────────────╮
│ 0 │ 27ms 929µs 958ns │
│ 1 │ 21ms 153µs 459ns │
│ 2 │ 18ms 639µs 666ns │
│ 3 │ 19ms 554µs 583ns │
│ 4 │ 13ms 383µs 375ns │
│ 5 │ 11ms 328µs 208ns │
│ 6 │ 5ms 659µs 542ns │
╰───┴──────────────────╯
```
IR enabled:
```
╭───┬──────────────────╮
│ 0 │ 22ms 662µs │
│ 1 │ 17ms 221µs 792ns │
│ 2 │ 14ms 786µs 708ns │
│ 3 │ 13ms 876µs 834ns │
│ 4 │ 13ms 52µs 875ns │
│ 5 │ 11ms 269µs 666ns │
│ 6 │ 6ms 942µs 500ns │
╰───┴──────────────────╯
```
##
[random-bytes.nu](https://github.com/nushell/nu_scripts/blob/main/benchmarks/random-bytes.nu)
I got pretty random results out of this benchmark so I decided not to
include it. Not clear why.
# User-Facing Changes
- IR compilation errors may appear even if the user isn't evaluating
with IR.
- IR evaluation can be enabled by setting the `NU_USE_IR` environment
variable to any value.
- New command `view ir` pretty-prints the IR for a block, and `view ir
--json` can be piped into an external tool like [`explore
ir`](https://github.com/devyn/nu_plugin_explore_ir).
# Tests + Formatting
All tests are passing with `NU_USE_IR=1`, and I've added some more eval
tests to compare the results for some very core operations. I will
probably want to add some more so we don't have to always check
`NU_USE_IR=1 toolkit test --workspace` on a regular basis.
# After Submitting
- [ ] release notes
- [ ] further documentation of instructions?
- [ ] post-release: publish `nu_plugin_explore_ir`
# Description
This PR introduces a new `Signals` struct to replace our adhoc passing
around of `ctrlc: Option<Arc<AtomicBool>>`. Doing so has a few benefits:
- We can better enforce when/where resetting or triggering an interrupt
is allowed.
- Consolidates `nu_utils::ctrl_c::was_pressed` and other ad-hoc
re-implementations into a single place: `Signals::check`.
- This allows us to add other types of signals later if we want. E.g.,
exiting or suspension.
- Similarly, we can more easily change the underlying implementation if
we need to in the future.
- Places that used to have a `ctrlc` of `None` now use
`Signals::empty()`, so we can double check these usages for correctness
in the future.
In this pull request, I converted the `perf` function within `nu_utils`
to a macro. This change facilitates easier usage within plugins by
allowing the use of `env_logger` and setting `RUST_LOG=nu_plugin_polars`
(or another plugin). Without this conversion, the `RUST_LOG` variable
would need to be set to `RUST_LOG=nu_utils::utils`, which is less
intuitive and impossible to narrow the perf results to one plugin.
# Description
This PR implements script or module autoloading. It does this by finding
the `$nu.vendor-autoload-dir`, lists the contents and sorts them by file
name. These files are evaluated in that order.
To see what's going on, you can use `--log-level warn`
```
❯ cargo r -- --log-level warn
Finished dev [unoptimized + debuginfo] target(s) in 0.58s
Running `target\debug\nu.exe --log-level warn`
2024-06-24 09:23:20.494 PM [WARN ] nu::config_files: set_config_path() cwd: "C:\\Users\\fdncred\\source\\repos\\nushell", default_config: config.nu, key: config-path, config_file_specified: None
2024-06-24 09:23:20.495 PM [WARN ] nu::config_files: set_config_path() cwd: "C:\\Users\\fdncred\\source\\repos\\nushell", default_config: env.nu, key: env-path, config_file_specified: None
2024-06-24 09:23:20.629 PM [WARN ] nu::config_files: setup_config() config_file_specified: None, env_file_specified: None, login: false
2024-06-24 09:23:20.660 PM [WARN ] nu::config_files: read_config_file() config_file_specified: None, is_env_config: true
Hello, from env.nu
2024-06-24 09:23:20.679 PM [WARN ] nu::config_files: read_config_file() config_file_specified: None, is_env_config: false
Hello, from config.nu
Hello, from defs.nu
Activating Microsoft Visual Studio environment.
2024-06-24 09:23:21.398 PM [WARN ] nu::config_files: read_vendor_autoload_files() src\config_files.rs:234:9
2024-06-24 09:23:21.399 PM [WARN ] nu::config_files: read_vendor_autoload_files: C:\ProgramData\nushell\vendor\autoload
2024-06-24 09:23:21.399 PM [WARN ] nu::config_files: AutoLoading: "C:\\ProgramData\\nushell\\vendor\\autoload\\01_get-weather.nu"
2024-06-24 09:23:21.675 PM [WARN ] nu::config_files: AutoLoading: "C:\\ProgramData\\nushell\\vendor\\autoload\\02_temp.nu"
2024-06-24 09:23:21.817 PM [WARN ] nu_cli::repl: Terminal doesn't support use_kitty_protocol config
```
# 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 toolkit.nu; toolkit test stdlib"` 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.
-->
# Description
This allows plugins to report their version (and potentially other
metadata in the future). The version is shown in `plugin list` and in
`version`.
The metadata is stored in the registry file, and reflects whatever was
retrieved on `plugin add`, not necessarily the running binary. This can
help you to diagnose if there's some kind of mismatch with what you
expect. We could potentially use this functionality to show a warning or
error if a plugin being run does not have the same version as what was
in the cache file, suggesting `plugin add` be run again, but I haven't
done that at this point.
It is optional, and it requires the plugin author to make some code
changes if they want to provide it, since I can't automatically
determine the version of the calling crate or anything tricky like that
to do it.
Example:
```
> plugin list | select name version is_running pid
╭───┬────────────────┬─────────┬────────────┬─────╮
│ # │ name │ version │ is_running │ pid │
├───┼────────────────┼─────────┼────────────┼─────┤
│ 0 │ example │ 0.93.1 │ false │ │
│ 1 │ gstat │ 0.93.1 │ false │ │
│ 2 │ inc │ 0.93.1 │ false │ │
│ 3 │ python_example │ 0.1.0 │ false │ │
╰───┴────────────────┴─────────┴────────────┴─────╯
```
cc @maxim-uvarov (he asked for it)
# User-Facing Changes
- `plugin list` gets a `version` column
- `version` shows plugin versions when available
- plugin authors *should* add `fn metadata()` to their `impl Plugin`,
but don't have to
# Tests + Formatting
Tested the low level stuff and also the `plugin list` column.
# After Submitting
- [ ] update plugin guide docs
- [ ] update plugin protocol docs (`Metadata` call & response)
- [ ] update plugin template (`fn metadata()` should be easy)
- [ ] release notes
# Description
This fixes issues with trying to run the tests with a terminal that is
small enough to cause errors to wrap around, or in cases where the test
environment might produce strings that are reasonably expected to wrap
around anyway. "Fancy" errors are too fancy for tests to work
predictably 😉
cc @abusch
# User-Facing Changes
- Added `--error-style` option for use with `--commands` (like
`--table-mode`)
# Tests + Formatting
Surprisingly, all of the tests pass, including in small windows! I only
had to make one change to a test for `error make` which was looking for
the box drawing characters miette uses to determine whether the span
label was showing up - but the plain error style output is even better
and easier to match on, so this test is actually more specific now.
# Description
This PR is an attempt to add a standard location for people to put
completions in. I saw this topic come up again recently and IIRC we
decided to create a standard location. I used the dirs-next crate to
dictate where these locations are. I know some people won't like that
but at least this gets the ball rolling in a direction that has a
standard directory.
This is what the default NU_LIB_DIRS looks like now in the
default_env.nu. It should also be like this when starting nushell with
`nu -n`
```nushell
$env.NU_LIB_DIRS = [
($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts
($nu.data-dir | path join 'completions') # default home for nushell completions
]
```
I also added these default folders to the `$nu` variable so now there is
`$nu.data-path` and `$nu.cache-path`.
## Data Dir Default
![image](https://github.com/nushell/nushell/assets/343840/aeeb7cd6-17b4-43e8-bb6f-986a0c7fce23)
While I was in there, I also decided to add a cache dir
## Cache Dir Default
![image](https://github.com/nushell/nushell/assets/343840/87dead66-4911-4f67-bfb2-acb16f386674)
### This is what the default looks like in Ubuntu.
![image](https://github.com/nushell/nushell/assets/343840/bca8eae8-8c18-47e8-b64f-3efe34f0004f)
### This is what it looks like with XDG_CACHE_HOME and XDG_DATA_HOME
overridden
```nushell
XDG_DATA_HOME=/tmp/data_home XDG_CACHE_HOME=/tmp/cache_home cargo r
```
![image](https://github.com/nushell/nushell/assets/343840/fae86d50-9821-41f1-868e-3814eca3730b)
### This is what the defaults look like in Windows (username scrubbed to
protect the innocent)
![image](https://github.com/nushell/nushell/assets/343840/3ebdb5cd-0150-448c-aff5-c57053e4788a)
How my NU_LIB_DIRS is set in the images above
```nushell
$env.NU_LIB_DIRS = [
($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts
'/Users/fdncred/src/nu_scripts'
($nu.config-path | path dirname)
($nu.data-dir | path join 'completions') # default home for nushell completions
]
```
Let the debate begin.
# 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 toolkit.nu; toolkit test stdlib"` 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.
-->
# Description
Add `--log-include` and `--log-exclude` options to filter the log output
from `nu` to specific module prefixes. For example,
```nushell
nu --log-level trace --log-exclude '[nu_parser]'
```
This avoids having to scan through parser spam when trying to debug
something else at `TRACE` level, and should make it feel much more
reasonable to add logging, particularly at `TRACE` level, to various
places in the codebase. It can also be used to debug non-Nushell crates
that support the Rust logging infrastructure, as many do.
You can also include a specific module instead of excluding the parser
log output:
```nushell
nu --log-level trace --log-include '[nu_plugin]'
```
Pinging #13041 for reference, but hesitant to outright say that this
closes that. I think it address that concern though. I've also struggled
with debugging plugin stuff with all of the other output, so this will
really help me there.
# User-Facing Changes
- New `nu` option: `--log-include`
- New `nu` option: `--log-exclude`