Commit Graph

70 Commits

Author SHA1 Message Date
5aa1ccea10 fix rest parameter spans (#16176)
Closes #16071

# Description

Rest parameter variables are now fully spanned, instead of just the
first value:

```diff
def foo [...rest] {
  metadata $rest | view span $in.span.start $in.span.end
}
foo 1 2

-1
+1 2
```
2025-07-16 13:02:48 +03:00
2df00ff498 Revert "Add extern for nu command" (#16180)
Reverts nushell/nushell#16119
2025-07-15 19:18:44 +03:00
c4e8e040ce Add warning when using history isolation with non-SQLite history format (#16151)
# Description
This PR depends on #16147, use `git diff 132ikl/shell-warning
132ikl/isolation-warn` to see only changes from this PR

People seem to get tripped up by this a lot, and it's not exactly
intuitive, so I added a warning if you try to set
`$env.config.history.isolation = true` when using the plaintext file
format:

    Warning: nu:🐚:invalid_config

      ⚠ Encountered 1 warnings(s) when updating config

    Warning: nu:🐚:incompatible_options

      ⚠ Incompatible options
       ╭─[source:1:33]
     1 │ $env.config.history.isolation = true
       ·                                 ──┬─
       ·                                   ╰── history isolation only compatible with SQLite format
       ╰────
      help: disable history isolation, or set $env.config.history.file_format = "sqlite"


# User-Facing Changes
* Added a warning when using history isolation without using SQLite
history.

# Tests + Formatting
Added a test
2025-07-15 16:40:32 +03:00
316d2d6af2 Add extern for nu command (#16119)
# Description
Adds an `extern` definition (`KnownExternal`) for the `nu` command. This
way you can do `help nu` and get tab completions for flags on the `nu`
executable

# User-Facing Changes
* You can now view the flags for Nushell itself with `help nu`, and tab
completion for flags on `nu` works
2025-07-15 02:26:40 +03:00
9da0f41ebb Fix easy clippy lints from latest stable (#16053)
1.88.0 was released today, clippy now lints (machine-applicable)
against:
- format strings with empty braces that could be inlined
  - easy win
- `manual_abs_diff`
- returning of a stored result of the last expression.
  - this can be somewhat contentious but touched only a few places
2025-06-29 17:37:17 +02:00
5478ec44bb to <format>: preserve round float numbers' type (#16016)
- fixes #16011

# Description
`Display` implementation for `f64` omits the decimal part for round
numbers, and by using it we did the same.
This affected:
- conversions to delimited formats: `csv`, `tsv`
- textual formats: `html`, `md`, `text`
- pretty printed `json` (`--raw` was unaffected)
- how single float values are displayed in the REPL

> [!TIP]
> This PR fixes our existing json pretty printing implementation.
> We can likely switch to using serde_json's impl using its
PrettyFormatter which allows arbitrary indent strings.

# User-Facing Changes
- Round trips through `csv`, `tsv`, and `json` preserve the type of
round floats.
- It's always clear whether a number is an integer or a float in the
REPL
  ```nushell
  4 / 2
  # => 2  # before: is this an int or a float?

  4 / 2
  # => 2.0  # after: clearly a float
  ``` 

# Tests + Formatting
Adjusted tests for the new behavior.

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

# After Submitting
N/A

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
2025-06-26 15:15:19 -05:00
f8b0af70ff Don't make unquoted file/dir paths absolute (#15878)
# Description

Closes #15848. Currently, we expand unquoted strings to absolute paths
if they are of type `path` or `directory`. This PR makes this no longer
happen. `~`, `.`, and `..+` are still expanded, but a path like
`.../foo/bar/..` will only be turned into `../../foo`, rather than a
full absolute path.

This is mostly so that paths don't get modified before being sent to
known external commands (as in the linked issue). But also, it seems
unnecessary to make all unquoted paths absolute.

After feedback from @132ikl, this PR also makes it so that unquoted
paths are expanded at parse time, so that it matches the runtime
behavior. Previously, `path` expressions were turned into strings
verbatim, while `directory` expressions were treated as not being const.

API change: `nu_path::expansions::expand_path` is now exposed as
`nu_path::expand_path`.

# User-Facing Changes

This has the potential to silently break a lot of scripts. For example,
if someone has a command that expects an already-expanded absolute path,
changes the current working directory, and then passes the path
somewhere, they will now need to use `path expand` to expand the path
themselves before changing the current working directory.

# Tests + Formatting

Just added one test to make sure unquoted `path` arguments aren't made
absolute.

# After Submitting

This is a breaking change, so will need to be mentioned in the release
notes.
2025-06-13 07:26:01 +08:00
12465193a4 cli: Use latest specified flag value when repeated (#15919)
# Description

This PR makes the last specified CLI arguments take precedence over the
earlier ones.

Existing command line tools that align with the new behaviour include:
- `neovim`: `nvim -u a.lua -u b.lua` will use `b.lua`
- `ripgrep`: you can have `--smart-case` in your user config but
override it later with `--case-sensitive` or `--ignore-case` (not
exactly the same flag override as the one I'm talking about but I think
it's still a valid example of latter flags taking precedence over the
first ones)

I think a flag defined last can be considered an override. This allows
having a `nu` alias that includes some default config (`alias nu="nu
--config something.nu"`) but being able to override that default config
as if using `nu` normally.
 
## Example

```sh
nu --config config1.nu --config config2.nu -c '$nu.config-path'
```
The current behavior would print `config1.nu`, and the new one would
print `config2.nu`

## Implementation

Just `.rev()` the iterator to search for arguments starting from the end
of the list. To support that I had to modify the return type of
`named_iter` (I couldn't find a more generic way than
`DoubleEndedIterator`).

# User-Facing Changes

- Users passing repeated flags and relying in nushell using the first
value will experience breakage. Given that right now there's no point in
passing a flag multiple times I guess not many users will be affected

# Tests + Formatting

I added a test that checks the new behavior with `--config` and
`--env-config`. I'm happy to add more cases if needed

# After Submitting
2025-06-13 07:23:38 +08:00
c4dcfdb77b feat!: Explicit cell-path case sensitivity syntax (#15692)
Related:
- #15683
- #14551
- #849
- #12701
- #11527

# Description
Currently various commands have differing behavior regarding cell-paths

```nushell
{a: 1, A: 2} | get a A
# => ╭───┬───╮
# => │ 0 │ 2 │
# => │ 1 │ 2 │
# => ╰───┴───╯
{a: 1, A: 2} | select a A
# => ╭───┬───╮
# => │ a │ 1 │
# => │ A │ 2 │
# => ╰───┴───╯
{A: 1} | update a 2
# => Error: nu:🐚:column_not_found
# => 
# =>   × Cannot find column 'a'
# =>    ╭─[entry #62:1:1]
# =>  1 │ {A: 1} | update a 2
# =>    · ───┬──          ┬
# =>    ·    │            ╰── cannot find column 'a'
# =>    ·    ╰── value originates here
# =>    ╰────
```

Proposal: making cell-path access case-sensitive by default and adding
new syntax for case-insensitive parts, similar to optional (?) parts.

```nushell
{FOO: BAR}.foo
# => Error: nu:🐚:name_not_found
# => 
# =>   × Name not found
# =>    ╭─[entry #60:1:21]
# =>  1 │ {FOO: BAR}.foo
# =>    ·            ─┬─
# =>    ·             ╰── did you mean 'FOO'?
# =>    ╰────
{FOO: BAR}.foo!
# => BAR
```

This would solve the problem of case sensitivity for all commands
without causing an explosion of flags _and_ make it more granular

Assigning to a field using a case-insensitive path is case-preserving.
```nushell
mut val = {FOO: "I'm FOO"}; $val
# => ╭─────┬─────────╮
# => │ FOO │ I'm FOO │
# => ╰─────┴─────────╯
$val.foo! = "I'm still FOO"; $val
# => ╭─────┬───────────────╮
# => │ FOO │ I'm still FOO │
# => ╰─────┴───────────────╯
```

For `update`, case-insensitive is case-preserving.
```nushell
{FOO: 1} | update foo! { $in + 1 }
# => ╭─────┬───╮
# => │ FOO │ 2 │
# => ╰─────┴───╯
```

`insert` can insert values into nested values so accessing into existing
columns is case-insensitive, but creating new columns uses the cell-path
as it is.
So `insert foo! ...` and `insert FOO! ...` would work exactly as they do
without `!`
```nushell
{FOO: {quox: 0}}
# => ╭─────┬──────────────╮
# => │     │ ╭──────┬───╮ │
# => │ FOO │ │ quox │ 0 │ │
# => │     │ ╰──────┴───╯ │
# => ╰─────┴──────────────╯
{FOO: {quox: 0}} | insert foo.bar 1
# => ╭─────┬──────────────╮
# => │     │ ╭──────┬───╮ │
# => │ FOO │ │ quox │ 0 │ │
# => │     │ ╰──────┴───╯ │
# => │     │ ╭─────┬───╮  │
# => │ foo │ │ bar │ 1 │  │
# => │     │ ╰─────┴───╯  │
# => ╰─────┴──────────────╯
{FOO: {quox: 0}} | insert foo!.bar 1
# => ╭─────┬──────────────╮
# => │     │ ╭──────┬───╮ │
# => │ FOO │ │ quox │ 0 │ │
# => │     │ │ bar  │ 1 │ │
# => │     │ ╰──────┴───╯ │
# => ╰─────┴──────────────╯
```

`upsert` is tricky, depending on the input, the data might end up with
different column names in rows. We can either forbid case-insensitive
cell-paths for `upsert` or trust the user to keep their data in a
sensible shape.

This would be a breaking change as it would make existing cell-path
accesses case-sensitive, however the case-sensitivity is already
inconsistent and any attempt at making it consistent would be a breaking
change.

> What about `$env`?

1. Initially special case it so it keeps its current behavior.
2. Accessing environment variables with non-matching paths gives a
deprecation warning urging users to either use exact casing or use the
new explicit case-sensitivity syntax
3. Eventuall remove `$env`'s special case, making `$env` accesses
case-sensitive by default as well.

> `$env.ENV_CONVERSIONS`?

In addition to `from_string` and `to_string` add an optional field to
opt into case insensitive/preserving behavior.

# User-Facing Changes

- `get`, `where` and other previously case-insensitive commands are now
case-sensitive by default.
- `get`'s `--sensitive` flag removed, similar to `--ignore-errors` there
is now an `--ignore-case` flag that treats all parts of the cell-path as
case-insensitive.
- Users can explicitly choose the case case-sensitivity of cell-path
accesses or commands.

# Tests + Formatting

Existing tests required minimal modification. ***However, new tests are
not yet added***.

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

# After Submitting

- Update the website to include the new syntax
- Update [tree-sitter-nu](https://github.com/nushell/tree-sitter-nu)

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
2025-05-18 12:19:09 +03:00
c2ac8f730e Rust 1.85, edition=2024 (#15741) 2025-05-13 16:49:30 +02:00
a0d7c1a4fd Add SyntaxShape::OneOf syntax users can use (#15646)
# Description
Built-in commands can have parameter of `SyntaxShape::OneOf`.
This PR changes `OneOf`'s string representation and gives users the
ability to use it in definitions.

> _Syntax updated after discussion on discord._

```nushell
def foo [
    param: oneof<binary, string>
] { .. }
```
```
Usage:
  > foo <param> 

Flags:
  -h, --help: Display the help message for this command

Parameters:
  param <oneof<binary, string>>

Input/output types:
  ╭───┬───────┬────────╮
  │ # │ input │ output │
  ├───┼───────┼────────┤
  │ 0 │ any   │ any    │
  ╰───┴───────┴────────╯
```

<details><summary>Previous iterations</summary>
<p>

> ```nushell
> def foo [
>     param: (binary | string)
> ] { .. }
> ```

> ---
>
> ```nushell
> def foo [
>     param: one_of(binary, string)
> ] { .. }
> ```

</p>
</details> 


# User-Facing Changes

# Tests + Formatting
Added some test cases.

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

# After Submitting
- Update the website to include the new syntax
[here](https://github.com/nushell/nushell.github.io/blob/main/book/custom_commands.md)
- Update [tree-sitter-nu](https://github.com/nushell/tree-sitter-nu)
- Update `std` and `std-rfc` where applicable

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
2025-05-07 15:43:01 -05:00
a7547a54bc fix(parser): namespace pollution of constants by use module.nu (#15518)
A bug introduced by #14920 

When `use module.nu` is called, all exported constants defined in it are
added to the scope.

# Description

On the branch of empty arguments, the constant var_id vector should be
empty, only constant_values (for `$module.foo` access) are injected.

# User-Facing Changes

# Tests + Formatting

~todo!~

adjusted

# After Submitting
2025-05-01 09:47:16 -05:00
2f6b4c5e9b bump the rust toolchain to 1.83.0 (#15148)
# Description

This PR bumps the rust toolchain to 1.83.0 and fixes a clippy lint. We
do this because Rust 1.85.0 was released today, and we try and stay 2
versions behind.

# 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.
-->
2025-02-20 16:34:09 -06:00
62e56d3581 Rework operator type errors (#14429)
# Description

This PR adds two new `ParseError` and `ShellError` cases for type errors
relating to operators.
- `OperatorUnsupportedType` is used when a type is not supported by an
operator in any way, shape, or form. E.g., `+` does not support `bool`.
- `OperatorIncompatibleTypes` is used when a operator is used with types
it supports, but the combination of types provided cannot be used
together. E.g., `filesize + duration` is not a valid combination.

The other preexisting error cases related to operators have been removed
and replaced with the new ones above. Namely:

- `ShellError::OperatorMismatch`
- `ShellError::UnsupportedOperator`
- `ParseError::UnsupportedOperationLHS`
- `ParseError::UnsupportedOperationRHS`
- `ParseError::UnsupportedOperationTernary`

# User-Facing Changes

- `help operators` now lists the precedence of `not` as 55 instead of 0
(above the other boolean operators). Fixes #13675.
- `math median` and `math mode` now ignore NaN values so that `[NaN NaN]
| math median` and `[NaN NaN] | math mode` no longer trigger a type
error. Instead, it's now an empty input error. Fixing this in earnest
can be left for a future PR.
- Comparisons with `nan` now return false instead of causing an error.
E.g., `1 == nan` is now `false`.
- All the operator type errors have been standardized and reworked. In
particular, they can now have a help message, which is currently used
for types errors relating to `++`.

```nu
[1] ++ 2
```
```
Error: nu::parser::operator_unsupported_type

  × The '++' operator does not work on values of type 'int'.
   ╭─[entry #1:1:5]
 1 │ [1] ++ 2
   ·     ─┬ ┬
   ·      │ ╰── int
   ·      ╰── does not support 'int'
   ╰────
  help: if you meant to append a value to a list or a record to a table, use the `append` command or wrap the value in a list. For example: `$list ++ $value` should be
        `$list ++ [$value]` or `$list | append $value`.
```
2025-02-12 20:03:40 -08:00
1128fa137f Fix spread operator lexing in records (#15023)
# Description

Zyphys found that when parsing `{...{}, ...{}, a: 1}`, the `a:` would be
considered one token, leading to a parse error ([Discord
message](https://discord.com/channels/601130461678272522/614593951969574961/1336762075535511573)).
This PR fixes that.

What would happen is that while getting tokens, the following would
happen in a loop:
1. Get the next two tokens while treating `:` as a special character (so
we get the next field key and a colon token)
2. Get the next token while not treating `:` as a special character (so
we get the next value)

I didn't update this when I added the spread operator. With `{...{},
...{}, a: 1}`, the first two tokens would be `...{}` and `...{}`, and
the next token would be `a:`. This PR changes this loop to first get a
single token, check if it's spreading a record, and move on if so.

Alternatives considered:
- Treat `:` as a special character when getting the value too. This
would simplify the loop greatly, but would mean you can't use colons in
values.
- Merge the loop for getting tokens and the loop for parsing those
tokens. I tried this, but it complicates things if you run into a syntax
error and want to create a garbage span going to the end of the record.

# User-Facing Changes

Nothing new
2025-02-11 09:51:34 -05:00
93e121782c Improve and fix filesize formatting/display (#14397)
# Description

This PR cleans up the code surrounding formatting and displaying file
sizes.
- The `byte_unit` crate we use for file size units displays kilobytes as
`KB`, which is not the SI or ISO/IEC standard. Rather it should be `kB`,
so this fixes #8872. On some systems, `KB` actually means `KiB`, so this
avoids any potential confusion.
- The `byte_unit` crate, when displaying file sizes, casts integers to
floats which will lose precision for large file sizes. This PR adds a
custom `Display` implementation for `Filesize` that can give an exact
string representation of a `Filesize` for metric/SI units.
- This PR also removes the dependency on the `byte_unit` crate which
brought in several other dependencies.

Additionally, this PR makes some changes to the config for filesize
formatting (`$env.config.filesize`).
- The previous filesize config had the `metric` and `format` options. If
a metric (SI) unit was set in `format`, but `metric` was set to false,
then the `metric` option would take precedence and convert `format` to
the corresponding binary unit (or vice versa). E.g., `{ format: kB,
metric: false }` => `KiB`. Instead, this PR adds the `unit` option to
replace the `format` and `metric` options. `unit` can be set to a fixed
file size unit like `kB` or `KiB`, or it can be set to one of the
special options: `binary` or `metric`. These options tells nushell to
format file sizes using an appropriately scaled metric or binary unit
(examples below).
  ```nushell
  # precision = null

  # unit = kB
  1kB  # 1 kB
  1KiB # 1.024 kB
  
  # unit = KiB
  1kB  # 0.9765625 KiB
  1KiB # 1 KiB
  
  # unit = metric
  1000B     # 1 kB
  1024B     # 1.024 kB
  10_000MB  # 10 GB
  10_240MiB # 10.73741824 GB

  # unit = binary
  1000B     # 1000 B
  1024B     # 1 KiB
  10_000MB  # 9.313225746154785 GiB
  10_240MiB # 10 GiB
  ```
- In addition, this PR also adds the `precision` option to the filesize
config. It determines how many digits to show after the decimal point.
If set to null, then everything after the decimal point is shown.
- The default filesize config is `{ unit: metric, precision: 1 }`.

# User-Facing Changes

- Commands that use the config to format file sizes will follow the
changes described above (e.g., `table`, `into string`, `to text`, etc.).
- The file size unit/format passed to `format filesize` is now case
sensitive. An error with the valid units is shown if the case does not
match.
- `$env.config.filesize.format` and `$env.config.filesize.metric` are
deprecated and replaced by `$env.config.filesize.unit`.
- A new `$env.config.filesize.precision` option was added.

# Tests + Formatting

Mostly updated test expected outputs.

# After Submitting

This PR does not change the way NUON serializes file sizes, because that
would require changing the nu parser to be able to losslessly decode the
new, exact string representation introduced in this PR.

Similarly, this PR also does not change the file size parsing in any
way. Although the file size units provided to `format filesize` or the
filesize config are now case-sensitive, the same is not yet true for
file size literals in nushell code.
2025-01-22 22:24:51 -08:00
8759936636 Fix variable names that end in a duration suffix can't be on the right part of a range (#14848)
# Description
Fixes: #14844

The issue occurs when nushell is parsing a value with
`SyntaxShape::Any`, it checks `Duration` and `Filesize` first, then
`Range`. Nushell raises errors too early while parsing
`Duration/Filesize`.

This pr changes the order of parsing to fix the issue.

# User-Facing Changes

The following code should be able to run after this pr
```nushell
let runs = 10;
1..$runs
```

# Tests + Formatting
Added 2 tests, one for filesize, one for duration.

# After Submitting
NaN
2025-01-17 06:21:59 -06:00
4dcaf2a201 Rename/deprecate range to slice (#14825)
# Description
As the `range` command has an ambiguous name (does it construct a range
type?, does it iterate a range like `seq`) replace it with a more
descriptive verb of what it does: `slice`

Closes #14130
# User-Facing Changes
`range` is now deprecated and replaced in whole by `slice` with the same
behavior.
`range` will be removed in `0.103.0`

# Tests + Formatting
Tests have been updated to use `slice`

# After submitting

- [ ] prepare PR for `nu_scripts` (several usages of `range` to be
fixed)
- [ ] update documentation usages of `range` after release
2025-01-17 06:21:32 -06:00
6eff420e17 fix error propagation in export-env (#14847)
- fixes #14801

# Description

- Fixed the issue
- Added some comments mirroring the ones used in `export-env` handling
in `use`
- Added two tests to prevent regressions

# User-Facing Changes

# Tests + Formatting

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

# After Submitting
2025-01-16 13:59:39 -06:00
6eb14522b6 Remove deprecated commands (#14726)
# Description

Remove commands which were deprecated in 0.101:

* `split-by` (#14019)
* `date to-record` and `date to-table` (#14319)

# User-Facing Changes

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

# After Submitting

TODO: `grep` (`ag`) doc repo for any usage of these commands
2025-01-07 07:37:51 +08:00
d36514a323 Rename/deprecate into bits to format bits (#14634)
# Description
`into bits` is a bad name because it is not a traditional type cast to a
`bits` type like all the other `into` commands.

Instead it is a pretty printer generating `string` type output. Thus the
correct bucket is `format` and its subcommands.


# User-Facing Changes
`into bits` will raise a `DeprecatedWarning` suggesting the move to
`format bits`
`into bits` can be removed in `0.103.0`

# Tests + Formatting
All tests that relied on `into bits` have been updated to `format bits`
2024-12-28 22:49:25 +01:00
b1da50774a 14523 all comments should be prefixed with space tab or be beginning of token (#14616)
This PR should close
1. #10327 
1. #13667 
1. #13810 
1. #14129 

# Description
This got reverted https://github.com/nushell/nushell/pull/14606 because
the previous changes only considered space a whitespace and forgot about
tabs. I now added a check for any whitespace, even if it is only those
two that would be relevant.

The added test failed before the changes. 

For `#` to start a comment, then it either need to be the first
character of the token or prefixed with ` ` (space).

So now you can do this:
``` 
~/Projects/nushell> 1..10 | each {echo test#testing }                                                                                                                     12/05/2024 05:37:19 PM
╭───┬──────────────╮
│ 0 │ test#testing │
│ 1 │ test#testing │
│ 2 │ test#testing │
│ 3 │ test#testing │
│ 4 │ test#testing │
│ 5 │ test#testing │
│ 6 │ test#testing │
│ 7 │ test#testing │
│ 8 │ test#testing │
│ 9 │ test#testing │
╰───┴──────────────╯
```  

# User-Facing Changes
It is a breaking change if anyone expected comments to start in the
middle of a string without any prefixing ` ` (space).

# Tests + Formatting
Did all: 
- `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

# After Submitting
I cant see that I need to update anything in [the
documentation](https://github.com/nushell/nushell.github.io) but please
point me in the direction if there is anything.
2024-12-25 21:31:51 +08:00
d94b344342 Revert "For # to start a comment, then it either need to be the first chara…" (#14606)
Reverts nushell/nushell#14562 due to https://github.com/nushell/nushell/issues/14605
2024-12-17 06:26:56 -06:00
cc0616b753 return const values from scope variables (#14577)
Fixes #14542

# User-Facing Changes

Constant values are no longer missing from `scope variables` output
when the IR evaluator is enabled:

```diff
const foo = 1
scope variables | where name == "$foo" | get value.0 | to nuon
-null
+int
```
2024-12-13 16:23:17 -06:00
cbf5fa6684 For # to start a comment, then it either need to be the first chara… (#14562)
This PR should close
1. #10327 
1. #13667 
1. #13810 
1. #14129 

# Description
For `#` to start a comment, then it either need to be the first
character of the token or prefixed with ` ` (space).

So now you can do this:
``` 
~/Projects/nushell> 1..10 | each {echo test#testing }                                                                                                                     12/05/2024 05:37:19 PM
╭───┬──────────────╮
│ 0 │ test#testing │
│ 1 │ test#testing │
│ 2 │ test#testing │
│ 3 │ test#testing │
│ 4 │ test#testing │
│ 5 │ test#testing │
│ 6 │ test#testing │
│ 7 │ test#testing │
│ 8 │ test#testing │
│ 9 │ test#testing │
╰───┴──────────────╯
```  

# User-Facing Changes
It is a breaking change if anyone expected comments to start in the
middle of a string without any prefixing ` ` (space).

# Tests + Formatting
Did all: 
- `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

# After Submitting
I cant see that I need to update anything in [the
documentation](https://github.com/nushell/nushell.github.io) but please
point me in the direction if there is anything.
2024-12-13 07:02:07 -06:00
0872e9c3ae Allow both NU_PLUGIN_DIRS const and env at the same time (#14553)
# 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
2024-12-11 11:41:06 -06:00
1a573d17c0 Revert "For # to start a comment, then it either need to be the first chara…" (#14560)
Reverts nushell/nushell#14548

I'm finding may oddities
2024-12-11 07:08:15 -06:00
e4bb248142 For # to start a comment, then it either need to be the first chara… (#14548)
This PR should close
1. #10327 
1. #13667 
1. #13810 
1. #14129 

# Description
For `#` to start a comment, then it either need to be the first
character of the token or prefixed with ` ` (space).

So now you can do this:
``` 
~/Projects/nushell> 1..10 | each {echo test#testing }                                                                                                                     12/05/2024 05:37:19 PM
╭───┬──────────────╮
│ 0 │ test#testing │
│ 1 │ test#testing │
│ 2 │ test#testing │
│ 3 │ test#testing │
│ 4 │ test#testing │
│ 5 │ test#testing │
│ 6 │ test#testing │
│ 7 │ test#testing │
│ 8 │ test#testing │
│ 9 │ test#testing │
╰───┴──────────────╯
```  

# User-Facing Changes
It is a breaking change if anyone expected comments to start in the
middle of a string without any prefixing ` ` (space).

# Tests + Formatting
Did all: 
- `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

# After Submitting
I cant see that I need to update anything in [the
documentation](https://github.com/nushell/nushell.github.io) but please
point me in the direction if there is anything.

---------

Co-authored-by: Wind <WindSoilder@outlook.com>
2024-12-11 09:39:36 +08:00
cf82814606 Use const NU_LIB_DIRS in startup (#14549)
# 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
2024-12-10 06:36:05 -06:00
234484b6f8 normalize special characters in module names to allow variable access (#14353)
Fixes #14252

# User-Facing Changes

- Special characters in module names are replaced with underscores when
  importing constants, preventing "expected valid variable name":

```nushell
> module foo-bar { export const baz = 1 }
> use foo-bar
> $foo_bar.baz
```

- "expected valid variable name" errors now include a suggestion list:

```nushell
> module foo-bar { export const baz = 1 }
> use foo-bar
> $foo-bar
Error: nu::parser::parse_mismatch_with_did_you_mean

  × Parse mismatch during operation.
   ╭─[entry #1:1:1]
 1 │ $foo-bar;
   · ────┬───
   ·     ╰── expected valid variable name. Did you mean '$foo_bar'?
   ╰────
```
2024-12-05 21:35:15 +08:00
1c18e37a7c Always populate config record during startup (#14435)
# 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.
2024-11-27 13:52:47 +08:00
7c84634e3f return accurate type errors from blocks/expressions in type unions (#14420)
# User-Facing Changes

- `expected <type>` errors are now propagated from
  `Closure | Block | Expression` instead of falling back to
  "expected one of..." for the block:

Before:

```nushell
def foo [bar: bool] {}
if true {} else { foo 1 }
                ────┬────
                    ╰── expected one of a list of accepted shapes: [Block, Expression]
```

After:

```nushell
if true {} else { foo 1 }
                      ┬
                      ╰── expected bool
```
2024-11-23 13:42:00 -08:00
4ed25b63a6 Always load default env/config values (#14249)
# 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.
2024-11-20 16:15:15 -06:00
f0cb2dafbb Allow duration to be added to date (#14295)
# Description

Fixes #14294 - Turned out to be a whole lot easier than I expected, but
please double-check me on this, since it's an area I haven't been in
before.

# User-Facing Changes

Allow date to be added to a duration type.

# Tests + Formatting

Tests added:

* Duration + Date is allowed
* Duration - Date is not allowed
2024-11-14 10:07:37 +01:00
23fba6d2ea correctly parse table literals as lists (#14226)
# User-Facing Changes

Table literal arguments to list parameters are now correctly parsed:

```diff
def a [l: list<any>] { $l | to nuon }; a [[a]; [2]]
-[[a]]
+[[a]; [2]]
```
2024-11-06 07:36:56 -06:00
1c3ff179bc Improve CellPath display output (#14197)
<!--
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: #13362

This PR fixes the `Display` impl for `CellPath`, as laid out in #13362
and #14090:

```nushell
> $.0."0"
$.0."0"

> $."foo.bar".baz
$."foo.bar".baz
```

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

Cell-paths are now printed using the same `$.` notation that is used to
create them, and ambiguous column names are properly quoted.

# 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.
-->
2024-11-02 10:28:10 -05:00
3f75b6b371 error when closure param lists aren't terminated by | (#14095)
Fixes #13757, fixes #9562

# User-Facing Changes

- `unclosed |` is returned for malformed closure parameters:

```
{ |a }
```

- Parameter list closing pipes are highlighted as part of the closure
2024-10-22 10:40:45 -05:00
f738932bbd Fix range contains (#14011)
# Description

This PR changes the range contains logic to take the step into account. 

```nushell
# before
2 in 1..3.. # true

# now
2 in 1..3.. # false
```

---

I encountered another issue while adding tests. Due to floating point
precision, `2.1 in 1..1.1..3` will return `false`. The floating point
error is even bigger than `f64::EPSILON` (`0.09999999999999876` vs
`2.220446049250313e-16`). This issue disappears with bigger numbers.

I tried a different algorithm (checking if the estimated number of steps
is close enough to any integer) but the results are still pretty bad:

```rust
let n_steps = (value - self.start) / self.step; // 14.999999999999988
(n_steps - n_steps.round()).abs() < f64::EPSILON // returns false
```

Maybe it can be shipped like this, the REPL already has floating point
errors (`1.1 - 1` returns `0.10000000000000009`). Or maybe there's a way
to fix this that I didn't think of. I'm open to ideas! But in any case
performing this kind of checks on a range of floats seems more niche
than doing it on a range of ints.

# User-Facing Changes

Code that depended on this behavior to check if a number is between
`start` and `end` will potentially return a different value.

# Tests + Formatting

# After Submitting
2024-10-22 10:34:41 -05:00
4968b6b9d0 fix error when exporting consts with type signatures in modules (#14118)
Fixes #14023

# Description

- Prevents "failed to find added variable" when modules export constants
  with type signatures:

```nushell
> module foo { export const bar: int = 2 }
Error: nu::parser::unknown_state

  × Internal error.
   ╭─[entry #1:1:21]
 1 │ module foo { export const bar: int = 2 }
   ·                     ─────────┬────────
   ·                              ╰── failed to find added variable
```

- Returns `name_is_builtin_var` errors for names with type signatures:

```nushell
> let env: string = "";
Error: nu::parser::name_is_builtin_var

  × `env` used as variable name.
   ╭─[entry #1:1:5]
 1 │ let env: string = "";
   ·     ─┬─
   ·      ╰── already a builtin variable
```
2024-10-22 11:54:31 +02:00
d7014e671d use command: Don't create a variable with empty record if it doesn't define any constants (#14051)
# Description
Fixes: #13967

The key changes lays in `nu-protocol/src/module.rs`, when resolving
import pattern, nushell only needs to bring `$module` with a record
value if it defines any constants.

# User-Facing Changes
```nushell
module spam {}
use spam
```
Will no longer create a `$spam` variable with an empty record.

# Tests + Formatting
Adjusted some tests and added some tests.
2024-10-20 23:12:57 +02:00
b0427ca9ff run ensure_flag_arg_type for short flag values (#14074)
Closes #13654

# User-Facing Changes

- Short flags are now fully type-checked,
  including null and record signatures for literal arguments:

```nushell
def test [-v: record<l: int>] {};
test -v null # error
test -v {l: ""} # error

def test2 [-v: int] {};
let v = ""
test2 -v $v # error
```

- `polars unpivot` `--index`/`--on` and `into value --columns`
now accept `list` values
2024-10-20 23:12:57 +02:00
28b6db115a Revert PRs for 0.99.1 patch (#14119)
# Description

Temporarily reverts PRs merged after the 0.99.1 bump.
2024-10-18 02:51:14 +00:00
71b49c3374 use command: Don't create a variable with empty record if it doesn't define any constants (#14051)
# Description
Fixes: #13967

The key changes lays in `nu-protocol/src/module.rs`, when resolving
import pattern, nushell only needs to bring `$module` with a record
value if it defines any constants.

# User-Facing Changes
```nushell
module spam {}
use spam
```
Will no longer create a `$spam` variable with an empty record.

# Tests + Formatting
Adjusted some tests and added some tests.
2024-10-16 21:25:45 -05:00
2eef42c6b9 run ensure_flag_arg_type for short flag values (#14074)
Closes #13654

# User-Facing Changes

- Short flags are now fully type-checked,
  including null and record signatures for literal arguments:

```nushell
def test [-v: record<l: int>] {};
test -v null # error
test -v {l: ""} # error

def test2 [-v: int] {};
let v = ""
test2 -v $v # error
```

- `polars unpivot` `--index`/`--on` and `into value --columns`
now accept `list` values
2024-10-16 21:25:17 -05:00
fce6146576 Refactor config updates (#13802)
# 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.
2024-10-11 18:40:32 +02:00
df0a174802 fix unknown_command when parsing certain strings with equal signs (#14053)
# Description

Prevents errors when `=` is used before the end of:

- strings in lists/records (with a symbol adjacent to the quotes)
- raw strings

```
> ["=a"]
Error: nu::parser::unknown_command

  × Unknown command.
   ╭─[entry #9:1:1]
 1 │ ["=a"]
   · ───┬──
   ·    ╰── unknown command
   ╰────
```

```
> r#'=a'#
Error: nu::parser::unknown_command

  × Unknown command.
   ╭─[entry #5:1:1]
 1 │ r#'=a'#
   · ───┬───
   ·    ╰── unknown command
   ╰────
```

Closes #13902, closes #13901, closes #9879, closes #6401, closes #5806

# User-Facing Changes

Variable names in environment shorthand assignments must satisfy
`is_identifier`.
2024-10-11 07:53:39 -05:00
bcb7ef48b6 Reduce duplication in history path construction (#13475)
# 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
2024-10-11 07:51:50 -05:00
68377c176d Remove superfluous separator when there's no flag description/comment (#14007)
# Description

Fixes a small side-issue in #10977 - If a command flag didn't have a
comment/description, it would still show an unnecessary separator at the
end of the line.

This fixes that, plus uses the `: ` (colon) to separate the flag from
the description. This aligns with the way that named parameters are
handled.

# User-Facing Changes

Help/doc only

# Tests + Formatting

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

# After Submitting

N/A
2024-10-05 15:19:26 +02:00
00709fc5bd Improves startup time when using std-lib (#13842)
Updated summary for commit
[612e0e2](612e0e2160)
- While folks are welcome to read through the entire comments, the core
information is summarized here.

# Description

This PR drastically improves startup times of Nushell by only parsing a
single submodule of the Standard Library that provides the `banner` and
`pwd` commands. All other Standard Library commands and submodules are
parsed when imported by the user. This cuts startup times by more than
60%.

At the moment, we have stopped adding to `std-lib` because every
addition adds a small amount to the Nushell startup time.
With this change, we should once again be able to allow new
functionality to be added to the Standard Library without it impacting
`nu` startup times.

# User-Facing Changes

* Nushell now starts about 60% faster
* Breaking change: The `dirs` (Shells) aliases will return a warning
message that it will not be auto-loaded in the following release, along
with instructions on how to restore it (and disable the message)
* The `use std <submodule> *` syntax is available for convenience, but
should be avoided in scripts as it parses the entire `std` module and
all other submodules and places it in scope. The correct syntax to
*just* load a submodule is `use std/<submodule> *` (asterisk optional).
The slash is important. This will be documented.
* `use std *` can be used for convenience to load all of the library but
still incurs the full loading-time.
* `std/dirs`: Semi-breaking change. The `dirs` command replaces the
`show` command. This is more in line with the directory-stack
functionality found in other shells. Existing users will not be impacted
by this as the alias (`shells`) remains the same.

* Breaking-change: Technically a breaking change, but probably only
impacts maintainers of `std`. The virtual path for the standard library
has changed. It could previously be imported using its virtual path (and
technically, this would have been the correct way to do it):

  ```nu
  use NU_STDLIB_VIRTUAL_DIR/std
  ```

  The path is now simply `std/`:

  ```nu
  use std
  ```

  All submodules have moved accordingly.
  

# Timings

Comparisons below were made:

* In a temporary, clean config directory using `$env.XDG_CONFIG_HOME =
(mktemp -d)`.
* `nu` was run with a release build
* `nu` was run one time to generate the default `config.nu` (etc.) files
- Otherwise timings would include the user-prompt
* The shell was exited and then restarted several times to get timing
samples

(Note: Old timings based on 0.97 rather than 0.98, but in the range of
being accurate)

| Scenario | `$nu.startup-time` |
| --- | --- |
| 0.97.2
([aaaab8e](aaaab8e070))
Without this PR | 23ms - 24ms |
| This PR with deprecated commands | 9ms - <11ms |
| This PR after deprecated commands are removed in following release |
8ms - <10ms |
| Final PR (remove deprecated), using `--no-std-lib` | 6.1ms to 6.4ms |
| Final PR (remove deprecated), using `--no-config-file` | 3.1ms - 3.6ms
|
| Final PR (remove deprecated), using `--no-config-file --no-std-lib` |
1ms - 1.5ms |

*These last two timings point to the opportunity for further
optimization (see comment in thread below (will link once I write it).*

# Implementation details for future maintenance

* `use std banner` is a ridiculously deceptive call. That call parses
and imports *all* of `std` into scope. Simply replacing it with `use
std/core *` is essentially what saves ~14-15ms. This *only* imports the
submodule with the `banner` and `pwd` commands.

* From the code-comments, the reason that `NU_STDLIB_VIRTUAL_DIR` was
used as a prefix was so that there wouldn't be an issue if a user had a
`./std/mod.nu` in the current directory. This does **not** appear to be
an issue. After removing the prefix, I tested with both a relative
module as well as one in the `$env.NU_LIB_DIRS` path, and in all cases
the *internal* `std` still took precedence.

* By removing the prefix, users can now `use std` (and variants) without
requiring that it already be parsed and in scope.

* In the next release, we'll stop autoloading the `dirs` (shells)
functionality. While this only costs an additional 1-1.5ms, I think it's
better moved to the `config.nu` where the user can optionally remove it.
The main reason is its use of aliases (which have also caused issues) -
The `n`, `p`, and `g` short-commands are valuable real-estate, and users
may want to map these to something else.
  
For this release, there's an `deprecated_dirs` module that is still
autoloaded. As with the top-level commands, use of these will give a
deprecation warning with instructions on how to handle going forward.

To help with this, moved the aliases to their own submodule inside the
`dirs` module.

* Also sneaks in a small change where the top-level `dirs` command is
now the replacement for `dirs show`

* Fixed a double-import of `assert` in `dirs.nu`
* The `show_banner` step is replaced with simply `banner` rather than
re-importing it.

* A `virtual_path` may now be referenced with either a forward-slash or
a backward-slash on Windows. This allows `use std/<submodule>` to work
on all platforms.

# Performance side-notes:

* Future parsing and/or IR improvements should improve performance even
further.
* While the existing load time penalty of `std-lib` was not noticeable
on many systems, Nushell runs on a wide-variety of hardware and OS
platforms. Slower platforms will naturally see a bigger jump in
performance here. For users starting multiple Nushell sessions
frequently (e.g., `tmux`, Zellij, `screen`, et. al.) it is recommended
to keep total startup time (including user configuration) under ~250ms.

# Tests + Formatting

* All tests are green

* Updated tests:
- Removed the test that confirmed that `std` was loaded (since we
don't).
- Removed the `shells` test since it is not autoloaded. Main `dirs.nu`
functionality is tested through `stdlib-test`.
- Many tests assumed that the library was fully loaded, because it was
(even though we didn't intend for it to be). Fixed those tests.
- Tests now import only the necessary submodules (e.g., `use
std/assert`, rather than `use std assert`)
- Some tests *thought* they were loading `std/log`, but were doing so
improperly. This was masked by the now-fixed "load-everything-into-scope
bug". Local CI would pass due the `$env.NU_LOG_<...>` variables being
inherited from the calling process, but would fail in the "clean" GitHub
CI environment. These tests have also been fixed.

 * Added additional tests for the changes

# After Submitting

Will update the Standard Library doc page
2024-10-03 06:28:22 -05:00
8200831b07 Fix panic on too few arguments for custom function (#10395)
# Description
Old code was comparing remaining positional arguments with total number
of arguments, where it should've compared remaining positional with
with remaining arguments of any kind. This means that if a function was
given too few arguments, `calculate_end_span` would believe that it
actually had too many arguments, since after parsing the first few
arguments, the number of remaining arguments needed were fewer than the
*total* number of arguments, of which we had used several.

Fixes #9072
Fixes: https://github.com/nushell/nushell/issues/13930
Fixes: https://github.com/nushell/nushell/issues/12069
Fixes: https://github.com/nushell/nushell/issues/8385

Extracted from #10381

## Bonus

It also improves the error handling on missing positional arguments
before keywords (no longer crashing since #9851). Instead of just giving
the keyword to the parser for the missing positional, we give an
explicit error about a missing positional argument. I would like better
descriptions than "missing var_name" though, but I'm not sure if that's
available without

Old error
```
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #1:1:1]
 1 │ let = if foo
   ·     ┬
   ·     ╰── expected valid variable name
   ╰────
```

New error
```
Error: nu::parser::missing_positional

  × Missing required positional argument.
   ╭─[entry #18:1:1]
 1 │ let = foo
   ·    ┬
   ·    ╰── missing var_name
   ╰────
  help: Usage: let <var_name> = <initial_value>
```

# User-Facing Changes
The program `alias = = =` is no longer accepted by the parser
2024-09-27 23:39:45 +08:00