Commit Graph

1900 Commits

Author SHA1 Message Date
Ian Manske
c747ec75c9
Add command_prelude module (#12291)
# Description
When implementing a `Command`, one must also import all the types
present in the function signatures for `Command`. This makes it so that
we often import the same set of types in each command implementation
file. E.g., something like this:
```rust
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
    record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
    ShellError, Signature, Span, Type, Value,
};
```

This PR adds the `nu_engine::command_prelude` module which contains the
necessary and commonly used types to implement a `Command`:
```rust
// command_prelude.rs
pub use crate::CallExt;
pub use nu_protocol::{
    ast::{Call, CellPath},
    engine::{Command, EngineState, Stack},
    record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, IntoSpanned,
    PipelineData, Record, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
};
```

This should reduce the boilerplate needed to implement a command and
also gives us a place to track the breadth of the `Command` API. I tried
to be conservative with what went into the prelude modules, since it
might be hard/annoying to remove items from the prelude in the future.
Let me know if something should be included or excluded.
2024-03-26 21:17:30 +00:00
Auca Coyan
b3721a24fa
🐛 remove 3 backticks messing the hover (#12273)
# Description

The hover was bugged with 3 backticks. I don't understand how it worked
before, but this apparently now works correctly on my machine. This is
really puzzling. My next step is to make a test to assert this will
break a little less. I fixed it 3 times in the past

# Tests + Formatting

Added a test to be sure this doesn't breaks again 😄 (at least from
nushell/nushell side)
2024-03-24 14:15:01 -05:00
Devyn Cairns
ff41cf91ef
Misc doc fixes (#12266)
# Description

Just a bunch of miscellaneous fixes to the Rust documentation that I
found recently while doing
a pass on some things.

# User-Facing Changes
None
2024-03-23 07:26:08 -05:00
dannou812
8237d15683
to json -r not removing whitespaces fix (#11948)
fixes #11900  

# Description
Use `serde_json` instead.

# User-Facing Changes
The problem described in the issue now no longer persists.

No whitespace in the output of `to json --raw`
Output of unicode escape changed to consistent `\uffff`

# Tests + Formatting
I corrected all Tests that were affected by this change.
2024-03-20 22:14:31 +01:00
Stefan Holderbach
ec528c0626
Refactor source cache into CachedFile struct (#12240)
# Description
Get rid of two parallel `Vec`s in `StateDelta` and `EngineState`, that
also duplicated span information. Use a struct with documenting fields.

Also use `Arc<str>` and `Arc<[u8]>` for the allocations as they are
never modified and cloned often (see #12229 for the first improvement).
This also makes the representation more compact as no capacity is
necessary.

# User-Facing Changes
API breakage on `EngineState`/`StateWorkingSet`/`StateDelta` that should
not really affect plugin authors.
2024-03-20 19:43:50 +01:00
Devyn Cairns
cf321ab510
Make EngineState clone cheaper with Arc on all of the heavy objects (#12229)
# Description
This makes many of the larger objects in `EngineState` into `Arc`, and
uses `Arc::make_mut` to do clone-on-write if the reference is not
unique. This is generally very cheap, giving us the best of both worlds
- allowing us to mutate without cloning if we have an exclusive
reference, and cloning if we don't.

This started as more of a curiosity for me after remembering that
`Arc::make_mut` exists and can make using `Arc` for mostly immutable
data that sometimes needs to be changed very convenient, and also after
hearing someone complain about memory usage on Discord - this is a
somewhat significant win for that.

The exact objects that were wrapped in `Arc`:

- `files`, `file_contents` - the strings and byte buffers
- `decls` - the whole `Vec`, but mostly to avoid lots of individual
`malloc()` calls on Clone rather than for memory usage
- `blocks` - the blocks themselves, rather than the outer Vec
- `modules` - the modules themselves, rather than the outer Vec
- `env_vars`, `previous_env_vars` - the entire maps
- `config`

The changes required were relatively minimal, but this is a breaking API
change. In particular, blocks are added as Arcs, to allow the parser
cache functionality to work.

With my normal nu config, running on Linux, this saves me about 15 MiB
of process memory usage when running interactively (65 MiB → 50 MiB).

This also makes quick command executions cheaper, particularly since
every REPL loop now involves a clone of the engine state so that we can
recover from a panic. It also reduces memory usage where engine state
needs to be cloned and sent to another thread or kept within an
iterator.

# User-Facing Changes
Shouldn't be any, since it's all internal stuff, but it does change some
public interfaces so it's a breaking change
2024-03-19 19:07:00 +01:00
Ian Manske
b6c7656194
IO and redirection overhaul (#11934)
# Description
The PR overhauls how IO redirection is handled, allowing more explicit
and fine-grain control over `stdout` and `stderr` output as well as more
efficient IO and piping.

To summarize the changes in this PR:
- Added a new `IoStream` type to indicate the intended destination for a
pipeline element's `stdout` and `stderr`.
- The `stdout` and `stderr` `IoStream`s are stored in the `Stack` and to
avoid adding 6 additional arguments to every eval function and
`Command::run`. The `stdout` and `stderr` streams can be temporarily
overwritten through functions on `Stack` and these functions will return
a guard that restores the original `stdout` and `stderr` when dropped.
- In the AST, redirections are now directly part of a `PipelineElement`
as a `Option<Redirection>` field instead of having multiple different
`PipelineElement` enum variants for each kind of redirection. This
required changes to the parser, mainly in `lite_parser.rs`.
- `Command`s can also set a `IoStream` override/redirection which will
apply to the previous command in the pipeline. This is used, for
example, in `ignore` to allow the previous external command to have its
stdout redirected to `Stdio::null()` at spawn time. In contrast, the
current implementation has to create an os pipe and manually consume the
output on nushell's side. File and pipe redirections (`o>`, `e>`, `e>|`,
etc.) have precedence over overrides from commands.

This PR improves piping and IO speed, partially addressing #10763. Using
the `throughput` command from that issue, this PR gives the following
speedup on my setup for the commands below:
| Command | Before (MB/s) | After (MB/s) | Bash (MB/s) |
| --------------------------- | -------------:| ------------:|
-----------:|
| `throughput o> /dev/null` | 1169 | 52938 | 54305 |
| `throughput \| ignore` | 840 | 55438 | N/A |
| `throughput \| null` | Error | 53617 | N/A |
| `throughput \| rg 'x'` | 1165 | 3049 | 3736 |
| `(throughput) \| rg 'x'` | 810 | 3085 | 3815 |

(Numbers above are the median samples for throughput)

This PR also paves the way to refactor our `ExternalStream` handling in
the various commands. For example, this PR already fixes the following
code:
```nushell
^sh -c 'echo -n "hello "; sleep 0; echo "world"' | find "hello world"
```
This returns an empty list on 0.90.1 and returns a highlighted "hello
world" on this PR.

Since the `stdout` and `stderr` `IoStream`s are available to commands
when they are run, then this unlocks the potential for more convenient
behavior. E.g., the `find` command can disable its ansi highlighting if
it detects that the output `IoStream` is not the terminal. Knowing the
output streams will also allow background job output to be redirected
more easily and efficiently.

# User-Facing Changes
- External commands returned from closures will be collected (in most
cases):
  ```nushell
  1..2 | each {|_| nu -c "print a" }
  ```
This gives `["a", "a"]` on this PR, whereas this used to print "a\na\n"
and then return an empty list.

  ```nushell
  1..2 | each {|_| nu -c "print -e a" }
  ```
This gives `["", ""]` and prints "a\na\n" to stderr, whereas this used
to return an empty list and print "a\na\n" to stderr.

- Trailing new lines are always trimmed for external commands when
piping into internal commands or collecting it as a value. (Failure to
decode the output as utf-8 will keep the trailing newline for the last
binary value.) In the current nushell version, the following three code
snippets differ only in parenthesis placement, but they all also have
different outputs:

  1. `1..2 | each { ^echo a }`
     ```
     a
     a
     ╭────────────╮
     │ empty list │
     ╰────────────╯
     ```
  2. `1..2 | each { (^echo a) }`
     ```
     ╭───┬───╮
     │ 0 │ a │
     │ 1 │ a │
     ╰───┴───╯
     ```
  3. `1..2 | (each { ^echo a })`
     ```
     ╭───┬───╮
     │ 0 │ a │
     │   │   │
     │ 1 │ a │
     │   │   │
     ╰───┴───╯
     ```

  But in this PR, the above snippets will all have the same output:
  ```
  ╭───┬───╮
  │ 0 │ a │
  │ 1 │ a │
  ╰───┴───╯
  ```

- All existing flags on `run-external` are now deprecated.

- File redirections now apply to all commands inside a code block:
  ```nushell
  (nu -c "print -e a"; nu -c "print -e b") e> test.out
  ```
This gives "a\nb\n" in `test.out` and prints nothing. The same result
would happen when printing to stdout and using a `o>` file redirection.

- External command output will (almost) never be ignored, and ignoring
output must be explicit now:
  ```nushell
  (^echo a; ^echo b)
  ```
This prints "a\nb\n", whereas this used to print only "b\n". This only
applies to external commands; values and internal commands not in return
position will not print anything (e.g., `(echo a; echo b)` still only
prints "b").

- `complete` now always captures stderr (`do` is not necessary).

# After Submitting
The language guide and other documentation will need to be updated.
2024-03-14 15:51:55 -05:00
Yash Thakur
0ff36dfe42
Canonicalize each component of config files (#12167)
<!--
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.
-->

Because `std::fs::canonicalize` requires the path to exist, this PR
makes it so that when canonicalizing any config file, the
`$nu.default-config-dir/nushell` part is canonicalized first, then
`$nu.default-config-dir/nushell/foo.nu` is canonicalized.

This should also fix the issue @devyn pointed out
[here](https://github.com/nushell/nushell/pull/12118#issuecomment-1989546708)
where a couple of the tests failed if one's `~/.config/nushell` folder
was actually a symlink to a different folder. The tests previously
didn't canonicalize the expected paths.

I was going to make a PR that caches the config directory on startup (as
suggested by fdncred and Ian in Discord), but I can make that part of
this PR if we want to avoid creating unnecessary PRs. I think it
probably makes more sense to separate them though.

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-03-13 06:26:06 -05:00
Yash Thakur
f6853fd636
Use XDG_CONFIG_HOME before default config directory (#12118)
<!--
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!
-->

Closes #12103

# 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.
-->

As described in #12103, this PR makes Nushell use `XDG_CONFIG_HOME` as
the config directory if it exists. Otherwise, it uses the old behavior,
which was to use `dirs_next::config_dir()`.

Edit: We discussed choosing between `XDG_CONFIG_HOME` and the default
config directory in Discord and decided against it, at least for now.

<s>@kubouch also suggested letting users choose between
`XDG_CONFIG_HOME` and the default config directory if config files
aren't found on startup and `XDG_CONFIG_HOME` is set to a value
different from the default config directory</s>

On Windows and MacOS, if the `XDG_CONFIG_HOME` variable is set but
`XDG_CONFIG_HOME` is either empty or doesn't exist *and* the old config
directory is non-empty, Nushell will issue a warning on startup saying
that it won't move files from the old config directory to the new one.
To do this, I had to add a `nu_path::config_dir_old()` function. I
assume that at some point, we will remove the warning message and the
function can be removed too. Alternatively, instead of having that
function there, `main.rs` could directly call `dirs_next::config_dir()`.

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

When `$env.XDG_CONFIG_HOME` is set to an absolute path, Nushell will use
`$"($env.XDG_CONFIG_HOME)/nushell"` as its config directory (previously,
this only worked on Linux).

To use `App Data\Roaming` (Windows) or `Library/Application Support`
(MacOS) instead (the old behavior), one can either leave
`XDG_CONFIG_HOME` unset or set it to an empty string.

If `XDG_CONFIG_HOME` is set, but to a non-absolute/invalid path, Nushell
will report an error on startup and use the default config directory
instead:


![image](https://github.com/nushell/nushell/assets/45539777/a434fe04-b7c8-4e95-b50c-80628008ad08)

On Windows and MacOS, if the `XDG_CONFIG_HOME` variable is set but
`XDG_CONFIG_HOME` is either empty or doesn't exist *and* the old config
directory is non-empty, Nushell will issue a warning on startup saying
that it won't move files from the old config directory to the new one.


![image](https://github.com/nushell/nushell/assets/45539777/1686cc17-4083-4c12-aecf-1d832460ca57)


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

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

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

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

The existing config path tests have been modified to use
`XDG_CONFIG_HOME` to change the config directory on all OSes, not just
Linux.

# 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.
-->

The documentation will have to be updated to note that Nushell uses
`XDG_CONFIG_HOME` now. As @fdncred pointed out, it's possible for people
to set `XDG_CONFIG_HOME` to, say, `~/.config/nushell` rather than
`~/.config`, so the documentation could warn about that mistake.
2024-03-11 06:15:46 -05:00
Stefan Holderbach
f695ba408a
Restructure nu-protocol in more meaningful units (#11917)
This is partially "feng-shui programming" of moving things to new
separate places.

The later commits include "`git blame` tollbooths" by moving out chunks
of code into new files, which requires an extra step to track things
with `git blame`. We can negiotiate if you want to keep particular
things in their original place.

If egregious I tried to add a bit of documentation. If I see something
that is unused/unnecessarily `pub` I will try to remove that.


- Move `nu_protocol::Exportable` to `nu-parser`
- Guess doccomment for `Exportable`
- Move `Unit` enum from `value` to `AST`
- Move engine state `Variable` def into its folder
- Move error-related files in `nu-protocol` subdir
- Move `pipeline_data` module into its own folder
- Move `stream.rs` over into the `pipeline_data` mod
- Move `PipelineMetadata` into its own file
- Doccomment `PipelineMetadata`
- Remove unused `is_leap_year` in `value/mod`
- Note about criminal `type_compatible` helper
- Move duration fmting into new `value/duration.rs`
- Move filesize fmting logic to new `value/filesize`
- Split reexports from standard imports in `value/mod`
- Doccomment trait `CustomValue`
- Polish doccomments and intradoc links
2024-03-10 18:45:45 +01:00
Stefan Holderbach
067ceedf79
Remove feat extra and include in default (#12140)
# Description
The intended effect of the `extra` feature has been undermined by
introducing the full builds on our release pages and having more
activity on some of the extra commands.

To simplify the feature matrix let's get rid of it and focus our effort
on truly either refining a command to well-specified behavior or
discarding it entirely from the `nu` binary and moving it into plugins.

## Details
- Remove `--features extra` from CI
- Don't explicitly name `extra` in full build wf
- Remove feature extra from build-help scripts
- Update README in `nu-cmd-extra`
- Remove feature `extra`
- Fix previously dead `format pattern` tests
- Relax signature of `to html`
- Fix/ignore `html::test_no_color_flag`
- Remove dead features from `version`
- Refine `to html` type signature

# User-Facing Changes
The commands that were previously only available when building with
`--features extra` will now be available to everyone. This increases the
number of dependencies slightly but has a limited impact on the overall
binary size.

# Tests + Formatting
Some tests that were left in `nu-command` during cratification were dead
because the feature was not passed to `nu-command` and only to
`nu-cmd-lang` for feature-flag mention in `version`.
Those tests have now been either fixed or ignored in one case.

# After Submitting
There may be places in the documentation where we point to `--features
extra` that will now be moot (apart from the generated command help)
2024-03-10 17:29:02 +01:00
Yash Thakur
a7b281292d
Canonicalize config dir (#12136)
It turns out that my previous PR,
https://github.com/nushell/nushell/pull/11999, didn't properly
canonicalize `$nu.default-config-dir` in a scenario where
`XDG_CONFIG_HOME` (or the equivalent on each platform) was a symlink. To
remedy that, this PR makes `nu_path::config_dir()` return a
canonicalized path. This probably shouldn't break anything (except maybe
tests relying on the old behavior), since the canonical path will be
equivalent to non-canonical paths.

# User-Facing Changes

A user may get a path with symlinks resolved and `..`s replaced where
they previously didn't. I'm not sure where this would happen, though,
and anyway, the canonical path is probably the "correct" thing to
present to the user. We're using `omnipath` to make the path presentable
to the user on Windows, so there's no danger of someone getting an path
with `\\?` there.

# Tests + Formatting

The tests for config files have been updated to run the binary using the
`Director` so that it has access to the `XDG_CONFIG_HOME`/`HOME`
environment variables to be able to change the config directory.
2024-03-10 11:07:31 +01:00
Devyn Cairns
bc19be25b1
Keep plugins persistently running in the background (#12064)
# Description
This PR uses the new plugin protocol to intelligently keep plugin
processes running in the background for further plugin calls.

Running plugins can be seen by running the new `plugin list` command,
and stopped by running the new `plugin stop` command.

This is an enhancement for the performance of plugins, as starting new
plugin processes has overhead, especially for plugins in languages that
take a significant amount of time on startup. It also enables plugins
that have persistent state between commands, making the migration of
features like dataframes and `stor` to plugins possible.

Plugins are automatically stopped by the new plugin garbage collector,
configurable with `$env.config.plugin_gc`:

```nushell
  $env.config.plugin_gc = {
      # Configuration for plugin garbage collection
      default: {
          enabled: true # true to enable stopping of inactive plugins
          stop_after: 10sec # how long to wait after a plugin is inactive to stop it
      }
      plugins: {
          # alternate configuration for specific plugins, by name, for example:
          #
          # gstat: {
          #     enabled: false
          # }
      }
  }
```

If garbage collection is enabled, plugins will be stopped after
`stop_after` passes after they were last active. Plugins are counted as
inactive if they have no running plugin calls. Reading the stream from
the response of a plugin call is still considered to be activity, but if
a plugin holds on to a stream but the call ends without an active
streaming response, it is not counted as active even if it is reading
it. Plugins can explicitly disable the GC as appropriate with
`engine.set_gc_disabled(true)`.

The `version` command now lists plugin names rather than plugin
commands. The list of plugin commands is accessible via `plugin list`.

Recommend doing this together with #12029, because it will likely force
plugin developers to do the right thing with mutability and lead to less
unexpected behavior when running plugins nested / in parallel.

# User-Facing Changes
- new command: `plugin list`
- new command: `plugin stop`
- changed command: `version` (now lists plugin names, rather than
commands)
- new config: `$env.config.plugin_gc`
- Plugins will keep running and be reused, at least for the configured
GC period
- Plugins that used mutable state in weird ways like `inc` did might
misbehave until fixed
- Plugins can disable GC if they need to
- Had to change plugin signature to accept `&EngineInterface` so that
the GC disable feature works. #12029 does this anyway, and I'm expecting
(resolvable) conflicts with that

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

Because there is some specific OS behavior required for plugins to not
respond to Ctrl-C directly, I've developed against and tested on both
Linux and Windows to ensure that works properly.

# After Submitting
I think this probably needs to be in the book somewhere
2024-03-09 17:10:22 -06:00
Raphael Gaschignard
d8f13b36b1
Allow for stacks to have parents (#11654)
This is another attempt on #11288 

This allows for a `Stack` to have a parent stack (behind an `Arc`). This
is being added to avoid constant stack copying in REPL code.

Concretely the following changes are included here:
- `Stack` can now have a `parent_stack`, pointing to another stack
- variable lookups can fallback to this parent stack (env vars and
everything else is still copied)
- REPL code has been reworked so that we use parenting rather than
cloning. A REPL-code-specific trait helps to ensure that we do not
accidentally trigger a full clone of the main stack
- A property test has been added to make sure that parenting "looks the
same" as cloning for consumers of `Stack` objects

---------

Co-authored-by: Raphael Gaschignard <rtpg@rokkenjima.local>
Co-authored-by: Ian Manske <ian.manske@pm.me>
2024-03-09 17:55:39 +01:00
Jakub Žádník
14d1c67863
Debugger experiments (#11441)
<!--
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 adds a new evaluator path with callbacks to a mutable trait
object implementing a Debugger trait. The trait object can do anything,
e.g., profiling, code coverage, step debugging. Currently,
entering/leaving a block and a pipeline element is marked with
callbacks, but more callbacks can be added as necessary. Not all
callbacks need to be used by all debuggers; unused ones are simply empty
calls. A simple profiler is implemented as a proof of concept.

The debugging support is implementing by making `eval_xxx()` functions
generic depending on whether we're debugging or not. This has zero
computational overhead, but makes the binary slightly larger (see
benchmarks below). `eval_xxx()` variants called from commands (like
`eval_block_with_early_return()` in `each`) are chosen with a dynamic
dispatch for two reasons: to not grow the binary size due to duplicating
the code of many commands, and for the fact that it isn't possible
because it would make Command trait objects object-unsafe.

In the future, I hope it will be possible to allow plugin callbacks such
that users would be able to implement their profiler plugins instead of
having to recompile Nushell.
[DAP](https://microsoft.github.io/debug-adapter-protocol/) would also be
interesting to explore.

Try `help debug profile`.

## Screenshots

Basic output:

![profiler_new](https://github.com/nushell/nushell/assets/25571562/418b9df0-b659-4dcb-b023-2d5fcef2c865)

To profile with more granularity, increase the profiler depth (you'll
see that repeated `is-windows` calls take a large chunk of total time,
making it a good candidate for optimizing):

![profiler_new_m3](https://github.com/nushell/nushell/assets/25571562/636d756d-5d56-460c-a372-14716f65f37f)

## Benchmarks

### Binary size

Binary size increase vs. main: **+40360 bytes**. _(Both built with
`--release --features=extra,dataframe`.)_

### Time

```nushell
# bench_debug.nu
use std bench

let test = {
    1..100
    | each {
        ls | each {|row| $row.name | str length }
    }
    | flatten
    | math avg
}

print 'debug:'
let res2 = bench { debug profile $test } --pretty
print $res2
```

```nushell
# bench_nodebug.nu
use std bench

let test = {
    1..100
    | each {
        ls | each {|row| $row.name | str length }
    }
    | flatten
    | math avg
}

print 'no debug:'
let res1 = bench { do $test } --pretty
print $res1
```

`cargo run --release -- bench_debug.nu` is consistently 1--2 ms slower
than `cargo run --release -- bench_nodebug.nu` due to the collection
overhead + gathering the report. This is expected. When gathering more
stuff, the overhead is obviously higher.

`cargo run --release -- bench_nodebug.nu` vs. `nu bench_nodebug.nu` I
didn't measure any difference. Both benchmarks report times between 97
and 103 ms randomly, without one being consistently higher than the
other. This suggests that at least in this particular case, when not
running any debugger, there is no runtime overhead.

## API changes

This PR adds a generic parameter to all `eval_xxx` functions that forces
you to specify whether you use the debugger. You can resolve it in two
ways:
* Use a provided helper that will figure it out for you. If you wanted
to use `eval_block(&engine_state, ...)`, call `let eval_block =
get_eval_block(&engine_state); eval_block(&engine_state, ...)`
* If you know you're in an evaluation path that doesn't need debugger
support, call `eval_block::<WithoutDebug>(&engine_state, ...)` (this is
the case of hooks, for example).

I tried to add more explanation in the docstring of `debugger_trait.rs`.

## TODO

- [x] Better profiler output to reduce spam of iterative commands like
`each`
- [x] Resolve `TODO: DEBUG` comments
- [x] Resolve unwraps
- [x] Add doc comments
- [x] Add usage and extra usage for `debug profile`, explaining all
columns

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

Hopefully none.

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

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

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

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

# 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-03-08 20:21:35 +02:00
dj-sourbrough
48fca1c151
Fix: lex now throws error on unbalanced closing parentheses (issue #11982) (#12098)
- Fixes issue #11982 

# Description
Expressions with unbalanced parenthesis [excess closing ')' parenthesis]
will throw an error instead of interpreting ')' as a string.

Solved he same way as closing braces '}' are handled.

![Screenshot 2024-03-06 at 14 53
46](https://github.com/nushell/nushell/assets/56027726/86834e47-a1e5-484d-881d-0e3b80fecef8)

![Screenshot 2024-03-06 at 14 48
27](https://github.com/nushell/nushell/assets/56027726/bb27c969-6a3b-4735-8a1e-a5881d9096d3)

# User-Facing Changes
- Trailing closing parentheses ')' which do not match the number of
opening parentheses '(' will lead to a parse error.
- From what I have found in the documentation this is the intended
behavior, thus no documentation has been updated on my part

# Tests + Formatting
- Two tests added in src/tests/test_parser.rs
- All previous tests are still passing
- cargo fmt, clippy and test have been run

Unable to get the following command run
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library
![Screenshot 2024-03-06 at 20 06
25](https://github.com/nushell/nushell/assets/56027726/91724fb9-d7d0-472b-bf14-bfa2a7618d09)

---------

Co-authored-by: Noak Jönsson <noakj@kth.se>
2024-03-07 06:05:04 -06:00
Yash Thakur
4cda183103
Canonicalize default-config-dir and plugin-path (#11999)
<!--
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 makes sure `$nu.default-config-dir` and `$nu.plugin-path` are
canonicalized.

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

`$nu.default-config-dir` (and `$nu.plugin-path`) will now give canonical
paths, with symlinks and whatnot resolved.

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

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

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

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

I've added a couple of tests to check that even if the config folder
and/or any of the config files within are symlinks, the `$nu.*`
variables are properly canonicalized. These tests unfortunately only run
on Linux and MacOS, because I couldn't figure out how to change the
config directory on Windows. Also, given that they involve creating
files, I'm not sure if they're excessive, so I could remove one or two
of them.

# 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-03-02 11:15:31 -06:00
Wind
387328fe73
Glob: don't allow implicit casting between glob and string (#11992)
# Description
As title, currently on latest main, nushell confused user if it allows
implicit casting between glob and string:
```nushell
let x = "*.txt"
def glob-test [g: glob] { open $g } 
glob-test $x
```
It always expand the glob although `$x` is defined as a string.
This pr implements a solution from @kubouch :
> We could make it really strict and disallow all autocasting between
globs and strings because that's what's causing the "magic" confusion.
Then, modify all builtins that accept globs to accept oneof(glob,
string) and the rules would be that globs always expand and strings
never expand

# User-Facing Changes
After this pr, user needs to use `into glob` to invoke `glob-test`, if
user pass a string variable:
```nushell
let x = "*.txt"
def glob-test [g: glob] { open $g } 
glob-test ($x | into glob)
```
Or else nushell will return an error.
```
 3 │ glob-test $x
   ·           ─┬
   ·            ╰── can't convert string to glob
```

# Tests + Formatting
Done

# After Submitting
Nan
2024-02-28 23:05:35 +08:00
moonlander
d3895d71db
add binary data handling to bits commands (#11854)
# Description
- enables `bits` commands to operate on binary data, where both inputs
are binary and can vary in length
- adds an `--endian` flag to `bits and`, `or`, `xor` for specifying
endianness (for binary values of different lengths)

# User-Facing Changes
- `bits` commands will no longer error for non-int inputs
- the default for `--number-bytes` is now `auto` (infer int size;
changed from 8)

# Tests + Formatting
> addendum: first PR, please inform if any changes are needed
2024-02-28 20:43:50 +08:00
Yash Thakur
c0ff0f12f0
Add ConfigDirNotFound error (#11849)
<!--
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.
-->

Currently, there's multiple places that look for a config directory, and
each of them has different error messages when it can't be found. This
PR makes a `ConfigDirNotFound` error to standardize the error message
for all of these cases.

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

Previously, the errors in `create_nu_constant()` would say which config
file Nushell was trying to get when it couldn't find the config
directory. Now it doesn't. However, I think that's fine, given that it
doesn't matter whether it couldn't find the config directory while
looking for `login.nu` or `env.nu`, it only matters that it couldn't
find it.

This is what the error looks like:


![image](https://github.com/nushell/nushell/assets/45539777/52298ed4-f9e9-4900-bb94-1154d389efa7)

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

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

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

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

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

---------

Co-authored-by: Antoine Stevan <44101798+amtoine@users.noreply.github.com>
2024-02-26 15:42:20 +08:00
Jack Wright
99ba365c4a
Handle configuration panics (#11935)
Use the default configuration on panic.

Adding a line that panics to any configuration:
```nushell
# Nushell Config File
#
# version = "0.86.0"
"2031-13-31" | into datetime
```

An error message will be displayed and the shell will continue:
<img width="1016" alt="Screenshot 2024-02-22 at 10 14 25"
src="https://github.com/nushell/nushell/assets/56345/8ccff001-300a-4caf-b131-bf7b114a06e3">

Co-authored-by: Jack Wright <jack.wright@disqo.com>
2024-02-22 16:25:55 -06:00
Jack Wright
f17f857b1f
wrapping run_repl with catch_unwind and restarting the repl on panic (#11860)
Provides the ability to cleanly recover from panics, falling back to the
last known good state of EngineState and Stack. This pull request also
utilizes miette's panic handler for better formatting of panics.

<img width="642" alt="Screenshot 2024-02-21 at 08 34 35"
src="https://github.com/nushell/nushell/assets/56345/f81efaba-aa45-4e47-991c-1a2cf99e06ff">

---------

Co-authored-by: Jack Wright <jack.wright@disqo.com>
2024-02-22 12:14:10 -06:00
Wind
1058707a29
make stderr works for failed external command (#11914)
# Description
Fixes: #11913

When running external command, nushell shouldn't consumes stderr
messages, if user want to redirect stderr.

# User-Facing Changes
NaN

# Tests + Formatting
Done

# After Submitting
NaN
2024-02-21 21:15:05 +08:00
KITAGAWA Yasutaka
752d25b004
separate commandline into subcommands (#11877)
<!--
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.
-->
Related issue and PR, #11825 #11864 
This improves the signature of `commandline`.

## Before

`commandline` returns different types depending on the flags and an
aurgument.

| command | input | output | description |

|-----------------------------|---------|---------|----------------------------------------|
| `commandline` | nothing | string | get current cursor line |
| `commandline arg` | nothing | nothing | replace the cursor line with
`arg` |
| `commandline --append arg` | nothing | nothing | append `arg` to the
end of cursor line |
| `commandline --insert arg` | nothing | nothing | insert `arg` to the
position of cursor |
| `commandline --replace arg` | nothing | nothing | replace the cursor
line with `arg` |
| `commandline --cursor` | nothing | int | get current cursor position |
| `commandline --cursor pos` | nothing | nothing | set cursor position
to pos |
| `commandline --cursor-end` | nothing | nothing | set cursor position
to end |

`help commandline` shows that `commandline` accepts string as pipeline
input, but `commandline` ignores pipeline input.

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

671bd08bcd/crates/nu-cli/src/commands/commandline.rs (L70)

This is misleading.

Due to the change #11864 , typecheck does not work well.
https://github.com/nushell/nushell/pull/11864#discussion_r1491814054

## After

Separate `commandline` into subcommands so that each subcommands returns
the same type for the same input type.

| command | input | output | description |

|----------------------------------|---------|---------|----------------------------------------|
| `commandline` | nothing | string | get current cursor line |
| `commandline edit arg` | nothing | nothing | replace the cursor line
with `arg` |
| `commandline edit --append arg` | nothing | nothing | append `arg` to
the end of cursor line |
| `commandline edit --insert arg` | nothing | nothing | insert `arg` to
the position of cursor |
| `commandline edit --replace arg` | nothing | nothing | replace the
cursor line with `arg` |
| `commandline get-cursor` | nothing | int | get current cursor position
|
| `commandline set-cursor pos` | nothing | nothing | set cursor position
to pos |
| `commandline set-cursor --end` | nothing | nothing | set cursor
position to end |

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-02-18 16:15:59 -06:00
Ian Manske
68fcd71898
Add Value::coerce_str (#11885)
# Description
Following #11851, this PR adds one final conversion function for
`Value`. `Value::coerce_str` takes a `&Value` and converts it to a
`Cow<str>`, creating an owned `String` for types that needed converting.
Otherwise, it returns a borrowed `str` for `String` and `Binary`
`Value`s which avoids a clone/allocation. Where possible, `coerce_str`
and `coerce_into_string` should be used instead of `coerce_string`,
since `coerce_string` always allocates a new `String`.
2024-02-18 17:47:10 +01:00
Ian Manske
1c49ca503a
Name the Value conversion functions more clearly (#11851)
# Description
This PR renames the conversion functions on `Value` to be more consistent.
It follows the Rust [API guidelines](https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv) for ad-hoc conversions.
The conversion functions on `Value` now come in a few forms:
- `coerce_{type}` takes a `&Value` and attempts to convert the value to
`type` (e.g., `i64` are converted to `f64`). This is the old behavior of
some of the `as_{type}` functions -- these functions have simply been
renamed to better reflect what they do.
- The new `as_{type}` functions take a `&Value` and returns an `Ok`
result only if the value is of `type` (no conversion is attempted). The
returned value will be borrowed if `type` is non-`Copy`, otherwise an
owned value is returned.
- `into_{type}` exists for non-`Copy` types, but otherwise does not
attempt conversion just like `as_type`. It takes an owned `Value` and
always returns an owned result.
- `coerce_into_{type}` has the same relationship with `coerce_{type}` as
`into_{type}` does with `as_{type}`.
- `to_{kind}_string`: conversion to different string formats (debug,
abbreviated, etc.). Only two of the old string conversion functions were
removed, the rest have been renamed only.
- `to_{type}`: other conversion functions. Currently, only `to_path`
exists. (And `to_string` through `Display`.)

This table summaries the above:
| Form | Cost | Input Ownership | Output Ownership | Converts `Value`
case/`type` |
| ---------------------------- | ----- | --------------- |
---------------- | -------- |
| `as_{type}` | Cheap | Borrowed | Borrowed/Owned | No |
| `into_{type}` | Cheap | Owned | Owned | No |
| `coerce_{type}` | Cheap | Borrowed | Borrowed/Owned | Yes |
| `coerce_into_{type}` | Cheap | Owned | Owned | Yes |
| `to_{kind}_string` | Expensive | Borrowed | Owned | Yes |
| `to_{type}` | Expensive | Borrowed | Owned | Yes |

# User-Facing Changes
Breaking API change for `Value` in `nu-protocol` which is exposed as
part of the plugin API.
2024-02-17 18:14:16 +00:00
KITAGAWA Yasutaka
a20b24a712
Fix commandline --cursor to return int (#11864)
<!--
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.
-->
Fix #11825 

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-02-15 08:17:38 -06:00
Yash Thakur
cb67de675e
Disallow spreading lists automatically when calling externals (#11857)
<!--
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.
-->

Spreading lists automatically when calling externals was deprecated in
0.89 (#11289), and this PR is to remove it in 0.91.

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

The new error message looks like this:

```
>  ^echo [1 2]
Error: nu:🐚:cannot_pass_list_to_external

  × Lists are not automatically spread when calling external commands
   ╭─[entry #13:1:8]
 1 │  ^echo [1 2]
   ·        ──┬──
   ·          ╰── Spread operator (...) is necessary to spread lists
   ╰────
  help: Either convert the list to a string or use the spread operator, like so: ...[1 2]
```

The old error message didn't say exactly where to put the `...` and
seemed to confuse a lot of people, so hopefully this helps.

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

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

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

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

There was one test to check that implicit spread was deprecated before,
updated that to check that it's disallowed now.

# 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-02-14 18:16:19 -05:00
TrMen
4b91ed57dd
Enforce call stack depth limit for all calls (#11729)
# Description
Previously, only direcly-recursive calls were checked for recursion
depth. But most recursive calls in nushell are mutually recursive since
expressions like `for`, `where`, `try` and `do` all execute a separte
block.

```nushell
def f [] {
    do { f }
}
```
Calling `f` would crash nushell with a stack overflow.

I think the only general way to prevent such a stack overflow is to
enforce a maximum call stack depth instead of only disallowing directly
recursive calls.

This commit also moves that logic into `eval_call()` instead of
`eval_block()` because the recursion limit is tracked in the `Stack`,
but not all blocks are evaluated in a new stack. Incrementing the
recursion depth of the caller's stack would permanently increment that
for all future calls.

Fixes #11667

# User-Facing Changes
Any function call can now fail with `recursion_limit_reached` instead of
just directly recursive calls. Mutually-recursive calls no longer crash
nushell.

# 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-02-08 06:42:24 +08:00
Jakub Žádník
c7a8aac883
Tighten def body parsing (#11719)
<!--
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 https://github.com/nushell/nushell/issues/11711

Previously, syntax `def a [] (echo 4)` was allowed to parse and then
failed with panic duting eval.

Current error:
```
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #1:1:1]
 1 │ def a [] (echo 4)
   ·          ────┬───
   ·              ╰── expected definition body closure { ... }
   ╰────
```

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-02-03 13:20:40 +02:00
Yash Thakur
c08f46f836
Respect SyntaxShape when parsing spread operator (#11674)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

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

This fixes an issue brought up by nihilander in
[Discord](https://discord.com/channels/601130461678272522/614593951969574961/1201594105986285649).

# 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.
-->

Nushell panics when the spread operator is used like this (the
`...$rest` shouldn't actually be parsed as a spread operator at all):

```nu
$ def foo [...rest: string] {...$rest}                      
$ foo bar baz                                               
thread 'main' panicked at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nu-protocol-0.89.0/src/signature.rs:650:9:
Internal error: can't run a predeclaration without a body
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: <nu_protocol::signature::Predeclaration as nu_protocol::engine::command::Command>::run
   3: nu_engine::eval::eval_call
   4: nu_engine::eval::eval_expression_with_input
   5: nu_engine::eval::eval_element_with_input
   6: nu_engine::eval::eval_block
   7: nu_cli::util::eval_source
   8: nu_cli::repl::evaluate_repl
   9: nu::run::run_repl
  10: nu::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

The problem was that whenever the parser saw something like `{...$`,
`{...(`, or `{...[`, it would treat that as a record with a spread
expression, ignoring the syntax shape of the block it was parsing. This
should now be fixed, and the snippet above instead gives the following
error:

```nu
Error: nu:🐚:external_command

  × External command failed
   ╭─[entry #1:1:1]
 1 │  def foo [...rest] {...$rest}
   ·                     ────┬───
   ·                         ╰── executable was not found
   ╰────
  help: No such file or directory (os error 2)
```

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

Stuff like `do { ...$rest }` will now try to run a command `...$rest`
rather than complaining that variable `$rest` doesn't exist.

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

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

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

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

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

Sorry about the issue, I am not touching the parser again for a long
time :)
2024-01-30 13:49:42 +08:00
Sophia June Turner
798ae7b251
Fix precedence of 'not' operator (#11672)
<!--
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

A bit hackish but this fixes the precedence of the `not` operator.

Before: `not false and false` => true

Now: `not false and false` => false

Fixes #11633

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

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

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

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

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

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

---------

Co-authored-by: Jakub Žádník <kubouch@gmail.com>
2024-01-29 21:42:27 +02:00
WindSoilder
56acebb826
making empty list matches list<int> types (#11596)
# Description
Fixes: #11595

The original issue is caused by #11475, we also need to make empty list
matches `list type` or `table type`

cc @amtoine 

# User-Facing Changes
Nan

# Tests + Formatting
Done
2024-01-26 22:24:17 +08:00
WindSoilder
a4809d2f08
Remove --flag: bool support (#11541)
# Description
This is a follow up to: #11365

After this pr, `--flag: bool` is no longer allowed.

I think `ParseWarning::Deprecated` is useful when we want to deprecated
something at syntax level, so I just leave it there for now.

# User-Facing Changes
## Before
```
❯ def foo [--b: bool] {}
Error:   × Deprecated: --flag: bool
   ╭─[entry #15:1:1]
 1 │ def foo [--b: bool] {}
   ·               ──┬─
   ·                 ╰── `--flag: bool` is deprecated and will be removed in 0.90. Please use `--flag` instead, more info: https://www.nushell.sh/book/custom_commands.html
   ╰────
```

## After
```
❯ def foo [--b: bool] {}
Error:   × Type annotations are not allowed for boolean switches.
   ╭─[entry #2:1:1]
 1 │ def foo [--b: bool] {}
   ·               ──┬─
   ·                 ╰── Remove the `: bool` type annotation.
   ╰────
```
# Tests + Formatting
Done
2024-01-25 14:16:49 +08:00
WindSoilder
c59d6d31bc
do not attempt to glob expand if the file path is wrapped in quotes (#11569)
# Description
Fixes: #11455

### For arguments which is annotated with `:path/:directory/:glob`
To fix the issue, we need to have a way to know if a path is originally
quoted during runtime. So the information needed to be added at several
levels:
* parse time (from user input to expression)
We need to add quoted information into `Expr::Filepath`,
`Expr::Directory`, `Expr::GlobPattern`
* eval time
When convert from `Expr::Filepath`, `Expr::Directory`,
`Expr::GlobPattern` to `Value::String` during runtime, we won't auto
expanded the path if it's quoted

### For `ls`
It's really special, because it accepts a `String` as a pattern, and it
generates `glob` expression inside the command itself.

So the idea behind the change is introducing a special SyntaxShape to
ls: `SyntaxShape::LsGlobPattern`. So we can track if the pattern is
originally quoted easier, and we don't auto expand the path either.

Then when constructing a glob pattern inside ls, we check if input
pattern is quoted, if so: we escape the input pattern, so we can run `ls
a[123]b`, because it's already escaped.
Finally, to accomplish the checking process, we also need to introduce a
new value type called `Value::QuotedString` to differ from
`Value::String`, it's used to generate an enum called `NuPath`, which is
finally used in `ls` function. `ls` learned from `NuPath` to know if
user input is quoted.

# User-Facing Changes
Actually it contains several changes
### For arguments which is annotated with `:path/:directory/:glob`
#### Before
```nushell
> def foo [p: path] { echo $p }; print (foo "~/a"); print (foo '~/a')
/home/windsoilder/a
/home/windsoilder/a
> def foo [p: directory] { echo $p }; print (foo "~/a"); print (foo '~/a')
/home/windsoilder/a
/home/windsoilder/a
> def foo [p: glob] { echo $p }; print (foo "~/a"); print (foo '~/a')
/home/windsoilder/a
/home/windsoilder/a
```
#### After
```nushell
> def foo [p: path] { echo $p }; print (foo "~/a"); print (foo '~/a')
~/a
~/a
> def foo [p: directory] { echo $p }; print (foo "~/a"); print (foo '~/a')
~/a
~/a
> def foo [p: glob] { echo $p }; print (foo "~/a"); print (foo '~/a')
~/a
~/a
```
### For ls command
`touch '[uwu]'`
#### Before
```
❯ ls -D "[uwu]"
Error:   × No matches found for [uwu]
   ╭─[entry #6:1:1]
 1 │ ls -D "[uwu]"
   ·       ───┬───
   ·          ╰── Pattern, file or folder not found
   ╰────
  help: no matches found
```

#### After
```
❯ ls -D "[uwu]"
╭───┬───────┬──────┬──────┬──────────╮
│ # │ name  │ type │ size │ modified │
├───┼───────┼──────┼──────┼──────────┤
│ 0 │ [uwu] │ file │  0 B │ now      │
╰───┴───────┴──────┴──────┴──────────╯
```

# Tests + Formatting
Done

# After Submitting
NaN
2024-01-21 23:22:25 +08:00
Ian Manske
55bf4d847f
Add CLI flag to disable history (#11550)
# Description
Adds a CLI flag for nushell that disables reading and writing to the
history file. This will be useful for future testing and possibly our
users as well. To borrow `fish` shell's terminology, this allows users
to start nushell in "private" mode.

# User-Facing Changes
Breaking API change for `nu-protocol` (changed `Config`).
2024-01-17 09:40:59 -06:00
Ian Manske
924986576d
Do not block signals for child processes (#11402)
# Description / User-Facing Changes
Signals are no longer blocked for child processes launched from both
interactive and non-interactive mode. The only exception is that
`SIGTSTP`, `SIGTTIN`, and `SIGTTOU` remain blocked for child processes
launched only from **interactive** mode. This is to help prevent nushell
from getting into an unrecoverable state, since we don't support
background jobs. Anyways, this fully fixes #9026.

# Other Notes
- Needs Rust version `>= 1.66` for a fix in
`std::process::Command::spawn`, but it looks our current Rust version is
way above this.
- Uses `sigaction` instead of `signal`, since the behavior of `signal`
can apparently differ across systems. Also, the `sigaction` man page
says:
> The sigaction() function supersedes the signal() function, and should
be used in preference.

Additionally, using both `sigaction` and `signal` is not recommended.
Since we were already using `sigaction` in some places (and possibly
some of our dependencies as well), this PR replaces all usages of
`signal`.

# Tests
Might want to wait for #11178 for testing.
2024-01-15 16:08:21 -06:00
Eric Hodel
7071617f18
Allow plugins to receive configuration from the nushell configuration (#10955)
# Description

When nushell calls a plugin it now sends a configuration `Value` from
the nushell config under `$env.config.plugins.PLUGIN_SHORT_NAME`. This
allows plugin authors to read configuration provided by plugin users.

The `PLUGIN_SHORT_NAME` must match the registered filename after
`nu_plugin_`. If you register `target/debug/nu_plugin_config` the
`PLUGIN_NAME` will be `config` and the nushell config will loook like:

        $env.config = {
          # ...
          plugins: {
            config: [
              some
              values
            ]
          }
        }

Configuration may also use a closure which allows passing values from
`$env` to a plugin:

        $env.config = {
          # ...
          plugins: {
            config: {||
              $env.some_value
            }
          }
        }

This is a breaking change for the plugin API as the `Plugin::run()`
function now accepts a new configuration argument which is an
`&Option<Value>`. If no configuration was supplied the value is `None`.

Plugins compiled after this change should work with older nushell, and
will behave as if the configuration was not set.

Initially discussed in #10867

# User-Facing Changes

* Plugins can read configuration data stored in `$env.config.plugins`
* The plugin `CallInfo` now includes a `config` entry, existing plugins
will require updates

# Tests + Formatting

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

# After Submitting

- [ ] Update [Creating a plugin (in
Rust)](https://www.nushell.sh/contributor-book/plugins.html#creating-a-plugin-in-rust)
[source](https://github.com/nushell/nushell.github.io/blob/main/contributor-book/plugins.md)
- [ ] Add "Configuration" section to [Plugins
documentation](https://www.nushell.sh/contributor-book/plugins.html)
2024-01-15 16:59:47 +08:00
nibon7
a109283118
Apply nightly clippy fixes (#11508)
# Description

Clippy fixes

# User-Facing Changes
N/A
2024-01-15 10:52:16 +08:00
Antoine Büsch
e88a531945
Fix commandline --cursor-end (#11504)
<!--
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 `commandline --cursor-end`, set `repl.cursor_pos` to the number of
bytes in the buffer, not the number of graphemes.

fixes: #11503

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2024-01-13 08:24:14 +08:00
WindSoilder
724818030d
add type check during eval time (#11475)
# Description
Fixes: #11438 

Take the following as example:
```nushell
def spam [foo: string] {
    $'foo: ($foo | describe)'
}
def outer [--foo: string] {
    spam $foo
}

outer
```
When we call `outer`, type checker only check the all for `outer`, but
doesn't check inside the body of `outer`. This pr is trying to introduce
a type checking process through `Type::is_subtype()` during eval time.

## NOTE
I'm not really sure if it's easy to make a check inside the body of
`outer`. Adding an eval time type checker seems like an easier solution.
As a result: `outer` will be caught by runtime, not parse time type
checker

cc @kubouch 

# User-Facing Changes
After this pr the following call will failed:
```nushell
> outer
Error: nu:🐚:cant_convert

  × Can't convert to string.
   ╭─[entry #27:1:1]
 1 │ def outer [--foo: any] {
 2 │     spam $foo
   ·          ──┬─
   ·            ╰── can't convert nothing to string
 3 │ }
   ╰────
```

# Tests + Formatting
Done

# After Submitting
NaN
2024-01-12 23:48:53 +08:00
Yash Thakur
0ebbc8f71c
Make only_buffer_difference: true work (#11488) 2024-01-11 11:58:14 -06:00
Artemiy
1867bb1a88
Fix incorrect handling of boolean flags for builtin commands (#11492)
# Description
Possible fix of #11456
This PR fixes a bug where builtin commands did not respect the logic of
dynamically passed boolean flags. The reason is
[has_flag](6f59abaf43/crates/nu-protocol/src/ast/call.rs (L204C5-L212C6))
method did not evaluate and take into consideration expression used with
flag.

To address this issue a solution is proposed:
1. `has_flag` method is moved to `CallExt` and new logic to evaluate
expression and check if it is a boolean value is added
2. `has_flag_const` method is added to `CallExt` which is a constant
version of `has_flag`
3. `has_named` method is added to `Call` which is basically the old
logic of `has_flag`
4. All usages of `has_flag` in code are updated, mostly to pass
`engine_state` and `stack` to new `has_flag`. In `run_const` commands it
is replaced with `has_flag_const`. And in a few select places: parser,
`to nuon` and `into string` old logic via `has_named` is used.

# User-Facing Changes
Explicit values of boolean flags are now respected in builtin commands.
Before:

![image](https://github.com/nushell/nushell/assets/17511668/f9fbabb2-3cfd-43f9-ba9e-ece76d80043c)
After:

![image](https://github.com/nushell/nushell/assets/17511668/21867596-2075-437f-9c85-45563ac70083)

Another example:
Before:

![image](https://github.com/nushell/nushell/assets/17511668/efdbc5ca-5227-45a4-ac5b-532cdc2bbf5f)
After:

![image](https://github.com/nushell/nushell/assets/17511668/2907d5c5-aa93-404d-af1c-21cdc3d44646)


# Tests + Formatting
Added test reproducing some variants of original issue.
2024-01-11 17:19:48 +02:00
Yash Thakur
21b3eeed99
Allow spreading arguments to commands (#11289)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

# Examples

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

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

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

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

---

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

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

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

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

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

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

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

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

Running it:
```nushell
> search-pkgs-curated "git" "*vi*"
╭──────────────┬───────────────────────────────────────────────────────────────────╮
│ install      │ false                                                             │
│ log_level    │ 1                                                                 │
│ exclude      │ [emacs]                                                           │
│ repositories │ [example.com, foo.com]                                            │
│ pkgs         │ [vim, git, python, chrome, firefox, python, java, git, "python3"] │
╰──────────────┴───────────────────────────────────────────────────────────────────╯
```
2023-12-28 15:43:20 +08:00
Yash Thakur
9522052063
More specific errors for missing values in records (#11423)
# Description
Currently, when writing a record, if you don't give the value for a
field, the syntax error highlights the entire record instead of
pinpointing the issue. Here's some examples:

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

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

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

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

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

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

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


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

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

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

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


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

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


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

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


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

# Tests + Formatting

# After Submitting
2023-12-27 10:15:12 +01:00
Ian Manske
3a050864df
Simplify SIGQUIT handling (#11381)
# Description
Simplifies `SIGQUIT` protection to a single `signal` ignore system call.

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

# Tests + Formatting
Should come after #11178 for testing.
2023-12-21 17:00:38 +01:00
Ian Manske
6f384da57e
Make Call::get_flag_expr return Expression by ref (#11388)
# Description
A small refactor that eliminates some `Expression` cloning.

# User-Facing Changes
Breaking change for `nu_protocol`.
2023-12-21 16:42:07 +01:00
WindSoilder
5d98a727ca
Deprecate --flag: bool in custom command (#11365)
# Description
While #11057 is merged, it's hard to tell the difference between
`--flag: bool` and `--flag`, and it makes user hard to read custom
commands' signature, and hard to use them correctly.

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

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

aaa
```

cc @kubouch 

# Tests + Formatting
Done

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

---------

Co-authored-by: Antoine Stevan <44101798+amtoine@users.noreply.github.com>
2023-12-21 10:07:08 +01:00
WindSoilder
697f3c03f1
enable flag value type checking (#11311)
# Description
Fixes: #11310

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

  × Type mismatch.
   ╭─[entry #32:2:1]
 2 │ let y = "aa"
 3 │ a --x=$y
   ·       ─┬
   ·        ╰── expected int, found string
   ╰────
```
2023-12-20 11:07:19 +01:00
Auca Coyan
92d968b8c8
♻️ Match --ide-hover with help command (#11284)
# Description
Hi! @fdncred pointed that the `help` command doesn't give the same
result as hovering a command in the VS Code extension. I digged out that
this trace back from `src/ide.rs`, so I decided to change this: (look at
the window of VS Code when hovering help)

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

into this:

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


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

The only missing part is the `subcommands` part

# Tests + Formatting
All good!

# After Submitting
2023-12-15 07:00:08 -06:00
Darren Schroeder
d717e8faeb
Add nu lib dirs default (#11248)
# Description

This PR is kind of two PRs in one because they were dependent on each
other.

PR1 -
3de58d4dc2
with update
7fcdb242d9
- This follows our mantra of having everything with defaults written in
nushell rust code. So, that if you run without a config, you get the
same behavior as with the default config/env files. This sets
NU_LIB_DIRS to $nu.config-path/scripts and sets NU_PLUGIN_DIRS to
$nu.config-path/plugins.

PR2 -
0e8ac876fd
- The benchmarks have been broke for some time and we didn't notice it.
This PR fixes that. It's dependent on PR1 because it was throwing errors
because PWD needed to be set to a valid folder and `$nu` did not exist
based on how the benchmark was setup.

I've tested the benchmarks and they run without error now and I've also
launched nushell as `nu -n --no-std-lib` and the env vars exist.

closes #11236

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-12-07 08:13:50 -06:00
Yash Thakur
0303d709e6
Spread operator in record literals (#11144)
Goes towards implementing #10598, which asks for a spread operator in
lists, in records, and when calling commands (continuation of #11006,
which only implements it in lists)

# Description
This PR is for adding a spread operator that can be used when building
records. Additional functionality can be added later.

Changes:

- Previously, the `Expr::Record` variant held `(Expression, Expression)`
pairs. It now holds instances of an enum `RecordItem` (the name isn't
amazing) that allows either a key-value mapping or a spread operator.
- `...` will be treated as the spread operator when it appears before
`$`, `{`, or `(` inside records (no whitespace allowed in between) (not
implemented yet)
- The error message for duplicate columns now includes the column name
itself, because if two spread records are involved in such an error, you
can't tell which field was duplicated from the spans alone

`...` will still be treated as a normal string outside records, and even
in records, it is not treated as a spread operator when not followed
immediately by a `$`, `{`, or `(`.

# User-Facing Changes
Users will be able to use `...` when building records.

```
> let rec = { x: 1, ...{ a: 2 } }
> $rec
╭───┬───╮
│ x │ 1 │
│ a │ 2 │
╰───┴───╯
> { foo: bar, ...$rec, baz: blah }
╭─────┬──────╮
│ foo │ bar  │
│ x   │ 1    │
│ a   │ 2    │
│ baz │ blah │
╰─────┴──────╯
```
If you want to update a field of a record, you'll have to use `merge`
instead:
```
> { ...$rec, x: 5 }
Error: nu:🐚:column_defined_twice

  × Record field or table column used twice: x
   ╭─[entry #2:1:1]
 1 │  { ...$rec, x: 5 }
   ·       ──┬─  ┬
   ·         │   ╰── field redefined here
   ·         ╰── field first defined here
   ╰────
> $rec | merge { x: 5 }
╭───┬───╮
│ x │ 5 │
│ a │ 2 │
╰───┴───╯
```

# Tests + Formatting

# After Submitting
2023-11-29 18:31:31 +01:00
Darren Schroeder
e290fa0e68
Add stor family of commands (#11170)
# Description

This PR adds the `stor` family of commands. These commands are meant to
create, open, insert, update, delete, reset data in an in-memory sqlite
database. This is really an experiment to see how creatively we can use
an in-memory database.

```
Usage:
  > stor

Subcommands:
  stor create - Create a table in the in-memory sqlite database
  stor delete - Delete a table or specified rows in the in-memory sqlite database
  stor export - Export the in-memory sqlite database to a sqlite database file
  stor import - Import a sqlite database file into the in-memory sqlite database
  stor insert - Insert information into a specified table in the in-memory sqlite database
  stor open - Opens the in-memory sqlite database
  stor reset - Reset the in-memory database by dropping all tables
  stor update - Update information in a specified table in the in-memory sqlite database

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

Input/output types:
  ╭─#─┬──input──┬─output─╮
  │ 0 │ nothing │ string │
  ╰───┴─────────┴────────╯
```

### Examples

## stor create
```nushell
❯ stor create --table-name nudb --columns {bool1: bool, int1: int, float1: float, str1: str, datetime1: datetime}
╭──────┬────────────────╮
│ nudb │ [list 0 items] │
╰──────┴────────────────╯
```
## stor insert
```nushell
❯ stor insert --table-name nudb --data-record {bool1: true, int1: 2, float1: 1.1, str1: fdncred, datetime1: 2023-04-17} 
╭──────┬───────────────╮
│ nudb │ [table 1 row] │
╰──────┴───────────────╯
```
## stor open
```nushell
❯ stor open | table -e 
╭──────┬────────────────────────────────────────────────────────────────────╮
│      │ ╭─#─┬id─┬bool1┬int1┬float1┬──str1───┬─────────datetime1──────────╮ │
│ nudb │ │ 0 │ 1 │   1 │  2 │ 1.10 │ fdncred │ 2023-04-17 00:00:00 +00:00 │ │
│      │ ╰───┴───┴─────┴────┴──────┴─────────┴────────────────────────────╯ │
╰──────┴────────────────────────────────────────────────────────────────────╯
```
## stor update
```nushell
❯ stor update --table-name nudb --update-record {str1: toby datetime1: 2021-04-17} --where-clause "bool1 = 1"
╭──────┬───────────────╮
│ nudb │ [table 1 row] │
╰──────┴───────────────╯
❯ stor open | table -e
╭──────┬─────────────────────────────────────────────────────────────────╮
│      │ ╭─#─┬id─┬bool1┬int1┬float1┬─str1─┬─────────datetime1──────────╮ │
│ nudb │ │ 0 │ 1 │   1 │  2 │ 1.10 │ toby │ 2021-04-17 00:00:00 +00:00 │ │
│      │ ╰───┴───┴─────┴────┴──────┴──────┴────────────────────────────╯ │
╰──────┴─────────────────────────────────────────────────────────────────╯
```
## insert another row
```nushell
❯ stor insert --table-name nudb --data-record {bool1: true, int1: 5, float1: 1.1, str1: fdncred, datetime1: 2023-04-17} 
╭──────┬────────────────╮
│ nudb │ [table 2 rows] │
╰──────┴────────────────╯
❯ stor open | table -e
╭──────┬────────────────────────────────────────────────────────────────────╮
│      │ ╭─#─┬id─┬bool1┬int1┬float1┬──str1───┬─────────datetime1──────────╮ │
│ nudb │ │ 0 │ 1 │   1 │  2 │ 1.10 │ toby    │ 2021-04-17 00:00:00 +00:00 │ │
│      │ │ 1 │ 2 │   1 │  5 │ 1.10 │ fdncred │ 2023-04-17 00:00:00 +00:00 │ │
│      │ ╰───┴───┴─────┴────┴──────┴─────────┴────────────────────────────╯ │
╰──────┴────────────────────────────────────────────────────────────────────╯
```
## stor delete (specific row(s))
```nushell
❯ stor delete --table-name nudb --where-clause "int1 == 5"
╭──────┬───────────────╮
│ nudb │ [table 1 row] │
╰──────┴───────────────╯
```
## insert multiple tables
```nushell
❯ stor create --table-name nudb1 --columns {bool1: bool, int1: int, float1: float, str1: str, datetime1: datetime}
╭───────┬────────────────╮
│ nudb  │ [table 1 row]  │
│ nudb1 │ [list 0 items] │
╰───────┴────────────────╯
❯ stor insert --table-name nudb1 --data-record {bool1: true, int1: 2, float1: 1.1, str1: fdncred, datetime1: 2023-04-17}
╭───────┬───────────────╮
│ nudb  │ [table 1 row] │
│ nudb1 │ [table 1 row] │
╰───────┴───────────────╯
❯ stor create --table-name nudb2 --columns {bool1: bool, int1: int, float1: float, str1: str, datetime1: datetime}
╭───────┬────────────────╮
│ nudb  │ [table 1 row]  │
│ nudb1 │ [table 1 row]  │
│ nudb2 │ [list 0 items] │
╰───────┴────────────────╯
❯ stor insert --table-name nudb2 --data-record {bool1: true, int1: 2, float1: 1.1, str1: fdncred, datetime1: 2023-04-17}
╭───────┬───────────────╮
│ nudb  │ [table 1 row] │
│ nudb1 │ [table 1 row] │
│ nudb2 │ [table 1 row] │
╰───────┴───────────────╯
```
## stor delete (specific table)
```nushell
❯ stor delete --table-name nudb1
╭───────┬───────────────╮
│ nudb  │ [table 1 row] │
│ nudb2 │ [table 1 row] │
╰───────┴───────────────╯
```
## stor reset (all tables are deleted)
```nushell
❯ stor reset
```
## stor export
```nushell
❯ stor export --file-name nudb.sqlite3
╭──────┬───────────────╮
│ nudb │ [table 1 row] │
╰──────┴───────────────╯
❯ open nudb.sqlite3 | table -e
╭──────┬────────────────────────────────────────────────────────────────────╮
│      │ ╭─#─┬id─┬bool1┬int1┬float1┬──str1───┬─────────datetime1──────────╮ │
│ nudb │ │ 0 │ 1 │   1 │  5 │ 1.10 │ fdncred │ 2023-04-17 00:00:00 +00:00 │ │
│      │ ╰───┴───┴─────┴────┴──────┴─────────┴────────────────────────────╯ │
╰──────┴────────────────────────────────────────────────────────────────────╯
❯ open nudb.sqlite3 | schema | table -e
╭────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│        │ ╭──────┬──────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ tables │ │      │ ╭───────────────┬──────────────────────────────────────────────────────────────────────────────╮ │ │
│        │ │ nudb │ │               │ ╭─#─┬─cid─┬───name────┬─────type─────┬─notnull─┬───────default────────┬─pk─╮ │ │ │
│        │ │      │ │ columns       │ │ 0 │ 0   │ id        │ INTEGER      │ 1       │                      │ 1  │ │ │ │
│        │ │      │ │               │ │ 1 │ 1   │ bool1     │ BOOLEAN      │ 0       │                      │ 0  │ │ │ │
│        │ │      │ │               │ │ 2 │ 2   │ int1      │ INTEGER      │ 0       │                      │ 0  │ │ │ │
│        │ │      │ │               │ │ 3 │ 3   │ float1    │ REAL         │ 0       │                      │ 0  │ │ │ │
│        │ │      │ │               │ │ 4 │ 4   │ str1      │ VARCHAR(255) │ 0       │                      │ 0  │ │ │ │
│        │ │      │ │               │ │ 5 │ 5   │ datetime1 │ DATETIME     │ 0       │ STRFTIME('%Y-%m-%d   │ 0  │ │ │ │
│        │ │      │ │               │ │   │     │           │              │         │ %H:%M:%f', 'NOW')    │    │ │ │ │
│        │ │      │ │               │ ╰─#─┴─cid─┴───name────┴─────type─────┴─notnull─┴───────default────────┴─pk─╯ │ │ │
│        │ │      │ │ constraints   │ [list 0 items]                                                               │ │ │
│        │ │      │ │ foreign_keys  │ [list 0 items]                                                               │ │ │
│        │ │      │ │ indexes       │ [list 0 items]                                                               │ │ │
│        │ │      │ ╰───────────────┴──────────────────────────────────────────────────────────────────────────────╯ │ │
│        │ ╰──────┴──────────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```
## Using with `query db`
```nushell
❯ stor open | query db "select * from nudb"
╭─#─┬id─┬bool1┬int1┬float1┬──str1───┬─────────datetime1──────────╮
│ 0 │ 1 │   1 │  5 │ 1.10 │ fdncred │ 2023-04-17 00:00:00 +00:00 │
╰───┴───┴─────┴────┴──────┴─────────┴────────────────────────────╯
```
## stor import
```nushell
❯ stor open
# note, nothing is returned. there is nothing in memory, atm.
❯ stor import --file-name nudb.sqlite3
╭──────┬───────────────╮
│ nudb │ [table 1 row] │
╰──────┴───────────────╯
❯ stor open | table -e 
╭──────┬────────────────────────────────────────────────────────────────────╮
│      │ ╭─#─┬id─┬bool1┬int1┬float1┬──str1───┬─────────datetime1──────────╮ │
│ nudb │ │ 0 │ 1 │   1 │  5 │ 1.10 │ fdncred │ 2023-04-17 00:00:00 +00:00 │ │
│      │ ╰───┴───┴─────┴────┴──────┴─────────┴────────────────────────────╯ │
╰──────┴────────────────────────────────────────────────────────────────────╯
```

TODO:
- [x] `stor export` - Export a fully formed sqlite db file. 
- [x] `stor import` - Imports a specified sqlite db file.
- [x] Perhaps feature-gate it with the sqlite feature
- [x] Update `query db` to work with the in-memory database
- [x] Remove `open --in-memory`

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-11-29 08:02:46 -08:00
WindSoilder
182b0ab4fb
add echo_env_mixed testbin to reduce windows only tests (#11172)
# Description
We have seen some test cases which requires to output message to both
stdout and stderr, especially in redirection scenario.

This pr is going to introduce a new echo_env_mixed testbin, so we can
have less tests which only runs on windows.

# User-Facing Changes
NaN

# Tests + Formatting
NaN

# After Submitting
NaN
2023-11-28 06:42:35 -06:00
WindSoilder
6cfe35eb7e
enable to pass switch values dynamically (#11057)
# Description
Closes: #7260 

About the change:
When we make an internalcall, and meet a `switch` (Flag.arg is None),
nushell will try to see if the switch is called like `--xyz=false` , if
that is true, `parse_long_flag` will return relative value.

# User-Facing Changes
So after the pr, the following would be possible:
```nushell
def build-imp [--push, --release] {
    echo $"Doing a build with push: ($push) and release: ($release)"
}
def build [--push, --release] {
    build-imp --push=$push --release=$release
}

build --push --release=false
build --push=false --release=true
build --push=false --release=false
build --push --release
build
```

# Tests + Formatting
Done

# After Submitting
Needs to submit a doc update, mentioned about the difference between
`def a [--x] {}` and `def a [--x: bool] {}`
2023-11-23 06:57:37 +08:00
ysthakur
823e578c46
Spread operator for list literals (#11006) 2023-11-22 23:10:08 +02:00
Eric Hodel
e36f69bf3c
Convert FileNotFoundCustom to named fields (#11123)
# Description

Part of #10700

# User-Facing Changes

None

# Tests + Formatting

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

# After Submitting

N/A
2023-11-21 17:30:21 -06:00
nibon7
f41c93b2d3
Apply nightly clippy fixes (#11083)
<!--
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.
-->
Clippy fixes for rust 1.76.0-nightly

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-11-17 09:15:55 -06:00
Darren Schroeder
e93e51d672
bump rust-toolchain to 1.72.1 (#11079)
# Description

This PR follows our process of staying 2 releases behind rust. 1.74.0
was released today so we update to 1.72.1.

Reference https://releases.rs/

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-11-16 15:14:45 -06:00
Marc Schreiber
c110ddff66
Implement LSP Text Document Synchronization (#10941) 2023-11-15 17:35:48 -06:00
WindSoilder
942ff7df4d
fix custom command's default value (#11043)
# Description
Fixes: #11033

Sorry for the issue, it's a regression which introduce by this pr:
#10456.
And this pr is going to fix it.

About the change: create a new field named `type_annotated` for
`Arg::Flag` and `Arg::Signature` instead of `arg_explicit_type`
variable.
When we meet a type in `TypeMode`, we set `type_annotated` field of the
argument to be true, then we know that if the arg have a annotated type
easily
2023-11-14 13:46:05 +01:00
Stefan Holderbach
0b25385109
Revert "add color-backtrace crate (#10942)" (#11032)
The `color-backtrace` crate does not seem to either handle the terminal
modes well or operate in a way that the unwinding has not yet succeeded
to reach the backup disablement of the terminal raw mode in
`reedline::Reedline`'s `Drop` implementation.

This reverts commit d838871063.

Fixes #11029
2023-11-11 16:03:33 -06:00
Gaëtan
588a078872
Fix tests for cargo.exe check command (#11022)
This pull request fixes the tests for the `cargo.exe check` command. The
tests were failing due `cargo check -h` sometimes reporting `cargo.exe`
as the binary and thus not containing `cargo check` in the output.

The fix involves using the `Command` module from the `std::process`
library to run the command and comparing its output to the expected
output. No changes were made to the codebase itself.
2023-11-10 21:15:11 +01:00
Christopher Durham
0f600bc3f5
Improve case insensitivity consistency (#10884)
# Description

Add an extension trait `IgnoreCaseExt` to nu_utils which adds some case
insensitivity helpers, and use them throughout nu to improve the
handling of case insensitivity. Proper case folding is done via unicase,
which is already a dependency via mime_guess from nu-command.

In actuality a lot of code still does `to_lowercase`, because unicase
only provides immediate comparison and doesn't expose a `to_folded_case`
yet. And since we do a lot of `contains`/`starts_with`/`ends_with`, it's
not sufficient to just have `eq_ignore_case`. But if we get access in
the future, this makes us ready to use it with a change in one place.

Plus, it's clearer what the purpose is at the call site to call
`to_folded_case` instead of `to_lowercase` if it's exclusively for the
purpose of case insensitive comparison, even if it just does
`to_lowercase` still.

# User-Facing Changes

- Some commands that were supposed to be case insensitive remained only
insensitive to ASCII case (a-z), and now are case insensitive w.r.t.
non-ASCII characters as well.

# Tests + Formatting

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

---------

Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
2023-11-08 23:58:54 +01:00
Darren Schroeder
d838871063
add color-backtrace crate for more intuitive backtraces (#10942)
# Description

Just throwing up this PR because color-backtrace seemed to produce more
useful backtraces. Just curious what others think.

Did this:
1. RUST_BACKTRACE=full cargo r
2. ❯ def test01 [] {
     let sorted = [storm]
     $sorted | range 1.. | zip ($sorted | range ..(-2))
  }
3. test01

I like how it shows the code snippet.


![image](https://github.com/nushell/nushell/assets/343840/1302e766-dfac-4749-a465-85bf53060532)

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-11-05 17:19:06 -06:00
Eric Hodel
51d5d0eac8
Restore test_config tests (#10954)
# Description

These tests got orphaned and they would be a good place to test behavior
I want to add for #10867

# User-Facing Changes

None

# Tests + Formatting

Tests were updated to account for removed test infrastructure

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

# After Submitting

N/A
2023-11-04 15:18:57 -05:00
Marc Schreiber
0ca8fcf58c
Integrated Language Server (#10723)
# Description

This commit integrates a language server into nushell so that IDEs don't
have to convert CLI option back and forth.

- fixes https://github.com/nushell/vscode-nushell-lang/issues/117
- fixes https://github.com/jokeyrhyme/nuls/issues/8

Tracking tasks


- [x]
[textDocument/hover](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_hover)
-> `nu --ide-hover`
- [x]
[textDocument/completion](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion)
-> `nu --ide-complete`
- [x]
[textDocument/definition](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_definition)
-> `nu --ide-goto-def`
- ~~[ ]
[textDocument/didChange](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didChange),
[textDocument/didClose](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didClose),
and
[textDocument/didOpen](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didOpen)~~
(will be done in a follow-up PR)
- ~~[ ]
[textDocument/inlayHint](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHint)
-> `nu --ide-check`~~ (will be done in a follow-up PR)
- ~~[ ]
[textDocument/publishDiagnostics](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_publishDiagnostics)
-> `nu --ide-check`~~ (will be done in a follow-up PR)
- ~~[ ]
[workspace/configuration](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration)~~
(will be done in a follow-up PR)
- ~~[ ]
[workspace/didChangeConfiguration](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeConfiguration)~~
(will be done in a follow-up PR)


# User-Facing Changes

The command line options `--lsp` will start a LSP server.

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-11-02 10:18:57 -05:00
Stefan Holderbach
0569a9c92e
Disallow duplicated columns in table literals (#10875)
# Description
Pretty much all operations/commands in Nushell assume that the column
names/keys in a record and thus also in a table (which consists of a
list of records) are unique.
Access through a string-like cell path should refer to a single column
or key/value pair and our output through `table` will only show the last
mention of a repeated column name.

```nu
[[a a]; [1 2]]
╭─#─┬─a─╮
│ 0 │ 2 │
╰───┴───╯
```

While the record parsing already either errors with the
`ShellError::ColumnDefinedTwice` or silently overwrites the first
occurence with the second occurence, the table literal syntax `[[header
columns]; [val1 val2]]` currently still allowed the creation of tables
(and internally records with more than one entry with the same name.

This is not only confusing, but also breaks some assumptions around how
we can efficiently perform operations or in the past lead to outright
bugs (e.g. #8431 fixed by #8446).

This PR proposes to make this an error.
After this change another hole which allowed the construction of records
with non-unique column names will be plugged.

## Parts
- Fix `SE::ColumnDefinedTwice` error code
- Remove previous tests permitting duplicate columns
- Deny duplicate column in table literal eval
- Deny duplicate column in const eval
- Deny duplicate column in `from nuon`

# User-Facing Changes
`[[a a]; [1 2]]` will now return an error:

```
Error: nu:🐚:column_defined_twice

  × Record field or table column used twice
   ╭─[entry #2:1:1]
 1 │ [[a a]; [1 2]]
   ·   ┬ ┬
   ·   │ ╰── field redefined here
   ·   ╰── field first defined here
   ╰────
```

this may under rare circumstances block code from evaluating.

Furthermore this makes some NUON files invalid if they previously
contained tables with repeated column names.

# Tests + Formatting
Added tests for each of the different evaluation paths that materialize
tables.
2023-11-01 21:25:35 +01:00
Darren Schroeder
38f4ab0bc9
updated NU_LIB_DIRS delimiter for command line (#10837)
# Description

This PR corrects some help text by stating what the real delimiter is
for the `--include-path` command line parameter which is `char
record_sep` aka `\x1e`. Up to this point, this has really only been used
for the vscode extension to setup the NU_LIB_DIRS env var correctly. We
tried `:` and `;` and neither would work so we had to choose something
that wouldn't be confused so easily.

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-10-25 09:38:20 -05:00
Gaëtan
27e6271402
Implement modulo for duration (#10745)
# Description
This PR adds the ability to use modulo with durations:

```nu
(2min + 31sec) mod 20sec # 11sec
```

# User-Facing Changes

Allows to use `<duration> mod <duration>`
2023-10-19 12:27:00 +02:00
Stefan Holderbach
e427c68731
Relax type-check of key-less table/record (#10629)
# Description
Relax typechecking of key-less `table`/`record`

Assume that they are acceptable for more narrowly specified
`table<...>`/`record<...>` where `...` specifies keys and potentially
types for those keys/columns.

This ensures that you can use commands that specify general return
values statically with more specific input-/args-type requirements.

Reduces the power of the type-check a bit but unlocks you to actually
use the specific annotations in more places.
Incompatibilities will only be raised if an output type declares
specific columns/keys.

Closes #9702

Supersedes #10594 as a simpler solution requiring no extra distinction.

h/t @1kinoti, @NotLebedev
# User-Facing Changes
Now legal at type-check time

```nu
def foo []: nothing -> table { [] }
def foo []: nothing -> table<> { ls }
def bar []: table<a:int,b:string> -> nothing {}

foo | bar 
```

# Tests + Formatting
- 1 explicit test with specified relaxed return type passed to concrete
expected input type
- 1 test leveraging the general output type of a built-in command
- 1 test wrapping a general built-in command and verifying the type
inference in the function body
2023-10-08 13:26:36 +02:00
Hofer-Julian
ff6c0fcb81
Add long options for filters (#10641) 2023-10-08 13:12:46 +02:00
Stefan Holderbach
4f4e8c984e
Parse custom completer annotation only in args (#10581)
# Description
To my knowledge `type@completer` annotations only make sense in
arguments at the moment.
Restrict the parsing.
Also fix a bug in parsing the completer annotation should there be more
than 1 `@`


- Add test that we disallow completer in type
- Guard against `@` inside command name
- Disallow custom completers in type specification


# User-Facing Changes
Error when annotating a variable or input-output type with a completer

# Tests + Formatting
Tests to verify the error message
2023-10-05 22:39:37 +02:00
Stefan Holderbach
7c1487e18d
Use int type name consistently (#10579)
# Description
When referring to the type use `int` consistently. Only when referring
to the concept of integer numbers use `integer`.

- Fix `random integer` to `random int` tests
  - Forgot in #10520
- Use int instead of integer in error messages
- Use int type name in bits commands
- Fix messages in `for` examples
- Use int typename in `into` commands
- Use int typename in rest of commands
- Report errors in `nu-protocol` with int typename

Work for #10332 

# User-Facing Changes
User errorrs should now use `int` so you can easily find the necessary
commands or type annotations.

# Tests + Formatting
Only two tests found that needed updating
2023-10-03 18:24:32 +02:00
Jakub Žádník
eb6870cab5
Add --env and --wrapped flags to def (#10566) 2023-10-02 21:13:31 +03:00
Antoine Stevan
6c026242d4
remove the $nothing variable (#10478)
related to 
- https://github.com/nushell/nushell/pull/9973
- https://github.com/nushell/nushell/pull/9918

thanks to @jntrnr and their super useful tips on this PR, i learned
about the parser + evaluation, so 🙏

# Description
because we already have `null` as the value of the type `nothing` and as
a followup to the two other attempts of mine, i propose to remove the
redundant `$nothing` built-in variable 😋

this PR is the first step, deprecating `$nothing`.
a followup PR will remove it altogether and wait for 0.87 👍 

⚙️ **details**: a new `NOTHING_VARIABLE_ID = 3` has been added,
parsing `$nothing` will create it, finally a `Value::Nothing` will be
produced and a warning will be reported.

this PR already fixes the `toolkit.nu` module so that it does not throw
a bunch of warnings each time 👌

# User-Facing Changes
`$nothing` is now deprecated and will be removed in 0.87
```nushell
> $nothing
Error:   × Deprecated variable
   ╭─[entry #1:1:1]
 1 │ $nothing
   · ────┬───
   ·     ╰── `$nothing` is deprecated and will be removed in 0.87.
   ╰────
  help: Use `null` instead
```

# Tests + Formatting
tests have been updated, especially
- `nothing_fails_string`
- `nothing_fails_int`
which use a variable called `nil` now to make sure `nothing` does not
support cell paths 👍

# After Submitting
classic deprecation mention 👍
2023-09-26 18:49:28 +02:00
WindSoilder
d2c87ad4b4
differentiating between --x and --x: bool (#10456)
# Description
Fixes: #10450 

This pr differentiating between `--x: bool` and `--x`

Here are examples which demostrate difference between them:
```nushell
def a [--x: bool] { $x };
a --x    # not allowed, you need to parse a value to the flag.
a        # it's allowed, and the value of `$x` is false, which behaves the same to `def a [--x] { $x }; a`
```

For boolean flag with default value, it works a little bit different to
#10450 mentioned:
```nushell
def foo [--option: bool = false] { $option }
foo                  # output false
foo --option         # not allowed, you need to parse a value to the flag.
foo --option true    # output true
```

# User-Facing Changes
After the pr, the following code is not allowed:
```nushell
def a [--x: bool] { $x }; a --x
```

Instead, you have to pass a value to flag `--x` like `a --x false`. But
bare flag works in the same way as before.

## Update: one more breaking change to help on #7260 
```
def foo [--option: bool] { $option == null }
foo
```
After the pr, if we don't use a boolean flag, the value will be `null`
instead of `true`. Because here `--option: bool` is treated as a flag
rather than a switch

---------

Co-authored-by: amtoine <stevan.antoine@gmail.com>
2023-09-23 10:20:48 +02:00
Darren Schroeder
4880721b73
evaluate $nu during --ide-check (#10470)
# Description

This PR fixes a bug found by @kubouch where `$nu` is not evaluated as a
constant when the `--ide-check` parameter is passed to nushell for the
LSP-like functionality. Not quite sure my changes are proper but it
seems to work!

### Before

![image](https://github.com/nushell/nushell/assets/343840/72ba28fe-74a1-450a-8a75-8d152c3a15b1)


### After

![image](https://github.com/nushell/nushell/assets/343840/1f70985b-4350-4e3f-8708-0aead3f5a505)


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

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

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

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

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

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

---------

Co-authored-by: Jakub Žádník <kubouch@gmail.com>
2023-09-22 10:53:25 -05:00
Stefan Holderbach
1072bd06c3
Improve assertions in src/tests.rs (#10449)
# Description
Mention the expected substring in:
- `fn run_test_contains()`
- `fn test_ide_contains()`
- `fn fail_test()`


# Developer-Facing Changes
You can read the test failure to figure out what is going on, don't
necessarily have to look up the test

New look of failure
```
failures:

---- tests::test_math::broken_math stdout ----
stdout:
stderr: Error: nu::parser::incomplete_math_expression

  × Incomplete math expression.
   ╭─[/tmp/.tmpz0V8nC:1:1]
 1 │ 3 +
   ·   ┬
   ·   ╰── incomplete math expression
   ╰────


Expected error to contain: Incomplete universe
thread 'tests::test_math::broken_math' panicked at 'assertion failed: !stderr.is_empty() && stderr.contains(expected)', src/tests.rs:181:5
```
2023-09-21 20:12:36 +02:00
Andreas Källberg
8d8b44342b
Fix exponential parser time on sequence of [[[[ (#10439)
<!--
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.
-->

Before this change, parsing `[[[[[[[[[[[[[[[[[[[[[[` would cause nushell
to consume several gigabytes of memory, now it should be linear in time.

The old code first tried parsing the head of the table as a list and
then after that it checked if it got more arguments. If it didn't, it
throws away the previous result and tries to parse the whole thing as a
list, which means we call `parse_list_expression` twice for each call to
`parse_table_expression`, resulting in the exponential growth

The fix is to simply check that we have all the arguments we need before
parsing the head of the table, so we know that we will either call
parse_list_expression only on sub-expressions or on the whole thing,
never both.

Fixes #10438


# User-Facing Changes
Should give a noticable speedup when typing a sequence of `[[[[[[` open
brackets
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting

I would like to add tests, but I'm not sure how to do that without
crashing CI with OOM on regression

- [x] Don't forget to add tests that cover your changes.
- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used`
to check that you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass (on Windows
make sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- [x] `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library
<!--
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
2023-09-21 03:53:48 +12:00
Stefan Holderbach
19d732f313
Clippy in tests (#10394)
Running `cargo clippy --workspace --tests`

We should move that to CI as well
2023-09-16 21:49:10 +02:00
Stefan Holderbach
a14e9e0a2e
Invert &Options to Option<&T> (#10315)
Elide the reference for `Copy` type (`usize`)
Use the canonical deref where possible.
* `&Box` -> `&`
* `&String` -> `&str`
* `&PathBuf` -> `&Path`

Skips the ctrl-C handler for now.
2023-09-13 07:00:58 +08:00
Stefan Holderbach
6e9b6f22c9
Deref &String arguments to &str where appropriate (#10321)
# Description
This generally makes for nicer APIs, as you are not forced to use an
existing allocation covering the full `String`.

Some exceptions remain where the underlying type requirements favor it.

# User-Facing Changes
None
2023-09-12 14:06:56 +08:00
Ian Manske
21d30d1e4d
Fix rm on macOS (#10282)
# Description

Removes the signal ignore for `SIGCHLD` added by #10021, since it
interferes with `rm` on macOS.
2023-09-08 19:03:30 -05:00
Ian Manske
872eb2c3df
Restore initial foreground process group on exit (#10021)
# Description
When launching nushell interactively from another shell, the parent
shell usually gives us own our process group and handles restoring
control to itself. However, other programs that do not support job
control expect us to give control of the terminal back to them. This PR
makes it so that we record the initial foreground process group and
restore it when nushell exits. An "exit" can be from the `exit` command,
a panic, or a `SIGTERM` signal.

The changes in `terminal.rs` mostly follow [fish's
example](0874dd6a96/fish-rust/src/common.rs (L1634)).

# User-Facing Changes
Fixes interactions between nushell and other interactive CLI commands
(e.g., VIFM #10015).
2023-09-08 18:19:01 +02:00
Darren Schroeder
a9216deaa4
allow --login to be used with nu's --commands parameter (#10253)
# Description

This PR allows the `--login`/`-l` parameter to be used with nushell's
`--commands`/`-c` parameter. When you do this, since you're invoking it
with the `-l` flag, nushell will load your env.nu, config.nu, and
login.nu, in that order. Then it will proceed to run your commands. I
think this provides a better quality of life when you want to run
scripts with your personal config files as a login shell.


### Before (these entries are from the default_env.nu)

![image](https://github.com/nushell/nushell/assets/343840/ce7adcd0-419e-485c-b7d1-f11f162e8e9e)


### After (these entries are from my personal env.nu)

![image](https://github.com/nushell/nushell/assets/343840/33bbc06b-983c-4461-8274-290e4c712506)


closes https://github.com/nushell/nushell/issues/9833

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-09-06 13:27:16 -05:00
Antoine Stevan
7486850357
rename the types with spaces in them to use - (#9929)
# Description
before this PR,
```nushell
> $.a.b | describe
cell path
```
which feels inconsistent with the `cell-path` type annotation, like in
```nushell
> def foo [x: cell-path] { $x | describe }; foo $.a.b
cell path
```

this PR changes the name of the "cell path" type from `cell path` to
`cell-path`

# User-Facing Changes
`cell path` is now `cell-path` in the output of `describe`.
this might be a breaking change in some scripts.

same goes with
- `list stream` -> `list-stream`
- `match pattern` -> `match-pattern`

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
-  `toolkit test`
-  `toolkit test stdlib`

this PR adds a new `cell_path_type` test to make sure it stays equal to
`cell-path` in the future.

# After Submitting

---------

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
2023-09-06 13:22:12 -05:00
JT
6cdfee3573
Move Value to helpers, separate span call (#10121)
# Description

As part of the refactor to split spans off of Value, this moves to using
helper functions to create values, and using `.span()` instead of
matching span out of Value directly.

Hoping to get a few more helping hands to finish this, as there are a
lot of commands to update :)

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

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

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

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

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

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

---------

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
Co-authored-by: WindSoilder <windsoilder@outlook.com>
2023-09-03 07:27:29 -07:00
Jakub Žádník
d28f728787
Add NU_VERSION environment variable on startup (#10177) 2023-09-01 09:48:13 +03:00
Jakub Žádník
f35808cb89
Make $nu constant (#10160) 2023-09-01 09:18:55 +03:00
Horasal
b943cbedff
skip comments and eols while parsing pipeline (#10149)
This pr 
- fixes https://github.com/nushell/nushell/issues/10143
- fixes https://github.com/nushell/nushell/issues/5559

# Description

Current `lite_parse` does not handle multiple line comments and eols in
pipeline.
When parsing the following tokens:


| `"abcdefg"` | ` \|` | `# foobar` | ` \n` | `split chars` |
| ------------- | ------------- |------------- |-------------
|------------- |
| [Command] | [Pipe] | [Comment] | [Eol] | [Command] |
| | | Last Token |Current Token | |

`TokenContent::Eol` handler only checks if `last_token` is `Pipe` but it
will be broken if there exist any other thing, e.g. extra `[Comment]` in
this example.

This pr make the following change:

- While parsing `[Eol]`, try to find the last non-comment token as
`last_token`
- Comment is supposed as `[Comment]+` or `([Comment] [Eol])+`
- `[Eol]+` is still parsed just like current nu (i.e. generates
`nothing`).

Notice that this pr is just a quick patch if more comment/eol related
issue occures, `lite_parser` may need a rewrite.

# User-Facing Changes

Now the following pipeline works: 

```bash
1 | # comment
each { |it| $it + 2 } | # comment
math sum
```

Comment will not end the pipeline in interactive mode:

```bash
❯ 1 | # comment   (now enter multiple line mode instead of end)
▶▶ # foo
▶▶ 2
```

# Tests + Formatting

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

# After Submitting

None

---------

Co-authored-by: Horasal <horsal@horsal.dev>
2023-08-30 13:24:13 -05:00
Michael Angerman
3f2c76df28
Move eval_hook to nu-cmd-base (#10146)
I moved hook to *nu_cmd_base* instead of *nu_cli* because it will enable
other developers to continue to use hook even if they decide to write
their on cli or NOT depend on nu-cli

Then they will still have the hook functionality because they can
include nu-cmd-base
2023-08-29 23:46:50 +02:00
Darren Schroeder
0f05475e2e
name hooks internally (#10127)
# Description

This PR names the hooks as they're executing so that you can see them
with debug statements. So, at the beginning of `eval_hook()` you could
put a dbg! or eprintln! to see what hook was executing. It also shows up
in View files.

### Before - notice item 14 and 25

![image](https://github.com/nushell/nushell/assets/343840/22c19bbe-6bac-4132-9579-863922d91f22)

### After - The hooks are now named (14 & 25)

![image](https://github.com/nushell/nushell/assets/343840/a08abd11-4f03-4f09-bbac-e4b5180df078)


Curiosity, on my mac, the display_output hook fires 3 times before
anything else. Also, curious is that the value if the display_output, is
not what I have in my config but what is in the default_config. So,
there may be a bug or some shenanigans going on somewhere with hooks.

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

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

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

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

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-08-27 06:55:20 -05:00
Jakub Žádník
5ac5b90aed
Allow parse-time evaluation of calls, pipelines and subexpressions (#9499)
Co-authored-by: Antoine Stevan <44101798+amtoine@users.noreply.github.com>
2023-08-26 16:41:29 +03:00
nibon7
ad12018199
Use built-in is_terminal instead of is_terminal::is_terminal (#9550)
# Description
This PR tries to remove ~atty~ is-terminal from the entire code base,
since ~[atty is
unmaintained](https://rustsec.org/advisories/RUSTSEC-2021-0145) and~
[`is_terminal` has been
stabilized](https://blog.rust-lang.org/2023/06/01/Rust-1.70.0.html#isterminal)
in rust 1.70.0.

cc @fdncred 

# 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 -A
clippy::needless_collect -A clippy::result_large_err` to check that
you're using the standard code style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-08-25 10:54:44 +02:00
Darren Schroeder
af82eeca72
remove --column from length command and remove record processing (#10091)
# Description

This PR removes `record` processing from the `length` command. It just
doesn't make sense to try and get the length of a record. This PR also
removes the `--column` parameter. If you want to list or count columns,
you could use `$table | columns` or `$table | columns | length`.

close #10074 

### Before

![image](https://github.com/nushell/nushell/assets/343840/83488316-3ec4-4c32-9583-00341a71f46f)

### After
Catches records two different ways now.
with the `input_output_types` checker

![image](https://github.com/nushell/nushell/assets/343840/ca67f8b6-359e-4933-ab4d-1b702f8d79cf)

and with additional logic in the command for cases like `echo`

![image](https://github.com/nushell/nushell/assets/343840/99064351-b208-4bd3-bab9-535f97cd7ad4)


# 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
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-08-23 16:03:26 -05:00
Jakub Žádník
66023f6243
Remove "let config" warning (#10068)
If you have a `config` variable defined at some point after reading
config files, Nushell would print
```
warning: use `$env.config = ...` instead of `let config = ...`
```

I think it's long enough since we've used `$env.config` that we can
remove this. Furthermore, it should be printed during `let` parsing
because you can end up with a `config` constant after importing a
`config` module (that was my case). The warning thus can be misleading.
2023-08-20 22:02:52 +02:00
Darren Schroeder
13114e972b
try to document the more obscure testbin commands (#10057)
# Description

This PR tries to document some of the more obscure testbin parameters
and what they do. I still don't grok all of them.

# 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 -A
clippy::needless_collect -A clippy::result_large_err` to check that
you're using the standard code style
- `cargo test --workspace` to check that all tests pass
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

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

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2023-08-19 08:23:11 -05:00
Jakub Žádník
cdf09abcc0
Allow exporting extern-wrapped (#10025) 2023-08-18 20:45:33 +03:00
Jakub Žádník
2e0fb7c1a6
Change str replace to match substring by default (#10038) 2023-08-18 00:18:16 +03:00