diff --git a/blog/2026-05-23-nushell_v0_113_0.md b/blog/2026-05-23-nushell_v0_113_0.md new file mode 100644 index 00000000000..a5539f3032d --- /dev/null +++ b/blog/2026-05-23-nushell_v0_113_0.md @@ -0,0 +1,1075 @@ +--- +title: Nushell 0.113.0 +author: The Nu Authors +author_site: https://www.nushell.sh/blog +author_image: https://www.nushell.sh/blog/images/nu_logo.png +excerpt: Today, we're releasing version 0.113.0 of Nu. This release adds... +--- + + + + + +# Nushell 0.113.0 + + + +Today, we're releasing version 0.113.0 of Nu. This release adds... + +# Where to get it + +Nu 0.113.0 is available as [pre-built binaries](https://github.com/nushell/nushell/releases/tag/0.113.0) or from [crates.io](https://crates.io/crates/nu). If you have Rust installed you can install it using `cargo install nu`. + +As part of this release, we also publish a set of optional [plugins](https://www.nushell.sh/book/plugins.html) you can install and use with Nushell. + +# Table of contents + + + +# Highlights and themes of this release + + + + +# Changes + +## Breaking changes + +### Updated `kill` signal shorthand handling +Allow `kill -0` to show an error instead of killing nushell. Disallow commands like `kill -9 pid` because syntax should be `kill -s 9 pid`. +```nushell +❯ kill -0 +Error: nu::shell::incorrect_value + + × Incorrect value. + ╭─[repl_entry #2:1:1] + 1 │ kill -0 + · ──┬─ ─┬ + · │ ╰── negative pid shorthand is not supported; use `kill -s 0 ` + · ╰── encountered here + ╰──── +``` + +### Removed implicit line splitting of byte streams in `parse` + +`parse` command, when receiving byte or string stream input (i.e. from an external process or file), used to implicitly split the input into lines. With this release it will collect such streams before processing them. + +While the line-by-line behavior is closer to how tools like `sed`, `grep` and `awk` operate, it was confusing as `parse` worked differently between working with a string _stream_ input and working with a string _value_ input. + + + + + + +
Input + + + + +
file.txt
+ +``` +1. one +2. two and + a half +3. three +4. four and + some more +``` + +
+ +
Code + +```nushell +open file.txt +| parse -r r#'(?ms)^(?\d+)\. (?.*?)(?=$\s^\d|\Z)'# +``` + +
Output + + + + + + + +
BeforeAfter
+ +``` +╭───┬───┬──────────╮ +│ # │ n │ text │ +├───┼───┼──────────┤ +│ 0 │ 1 │ one │ +│ 1 │ 2 │ two and │ +│ 2 │ 3 │ three │ +│ 3 │ 4 │ four and │ +╰───┴───┴──────────╯ +``` + + + +``` +╭───┬───┬──────────────╮ +│ # │ n │ text │ +├───┼───┼──────────────┤ +│ 0 │ 1 │ one │ +│ 1 │ 2 │ two and │ +│ │ │ a half │ +│ 2 │ 3 │ three │ +│ 3 │ 4 │ four and │ +│ │ │ some more │ +╰───┴───┴──────────────╯ +``` + +
+ +
+ + +To process the input line-by-line all you need to do is run the stream through `lines`: + +```nushell +.. | lines | parse -r '...' +``` + +### (Breaking change!)`mkdir -v` now returns a table +Previously mkdir -v returns a string, now it returns a table +#### Before +``` +> let x = mkdir -v foo bar +nu: created directory '/tmp/foo' +nu: created directory '/tmp/bar' +> $x +foo bar +``` + +#### After +``` +> let x = mkdir -v dir_1 dir_2 dir_3 +> $x +╭───┬────────────┬─────────┬───────╮ +│ # │ path │ created │ error │ +├───┼────────────┼─────────┼───────┤ +│ 0 │ /tmp/dir_1 │ true │ │ +│ 1 │ /tmp/dir_2 │ true │ │ +│ 2 │ /tmp/dir_3 │ true │ │ +╰───┴────────────┴─────────┴───────╯ +``` +### `mv -v` returns a table too +``` +> touch before.txt +> mv -v before.txt after.txt +╭───┬─────────────────┬────────────────┬────────────────────╮ +│ # │ source │ destination │ message │ +├───┼─────────────────┼────────────────┼────────────────────┤ +│ 0 │ /tmp/before.txt │ /tmp/after.txt │ mv-verbose-renamed │ +╰───┴─────────────────┴────────────────┴────────────────────╯ +``` + +### Other breaking changes + +* `from xlsx` now supports `--header-row` for specifying the 0-indexed index of the row from which to read column names. Default is the first non-empty row, which is a breaking change. Specify `--header-row null` for legacy behavior (i.e., no header). ([#18189](https://github.com/nushell/nushell/pull/18189)) + +## Additions + +### Preserve TOML comments when saving files +TOML files now preserve comments, formatting, and inline tables when modified and saved. +Example: +``` +open Cargo.toml | update version "1.1.0" | save Cargo.toml +``` +should keep all comments intact. + +### Enhance `ansi gradient` command with named gradients and improved options + +You can now use named gradients with `ansi gradient`. +```nushell +'Nushell Gradient!' | ansi gradient --fgnamed rainbow +``` +image + +More fun +image + +### New commands for vi normal mode +Added two new commands to the vi normal modes: +- `o`: inserts a newline below the cursor and enters insert mode +- `O`: inserts a newline above the cursor and enters insert mode + +Their respective edit commands are `InsertNewlineBelow` and `InsertNewlineAbove` + +### Terminal emulator progress bars via `std-rfc/pb` +Added a new module to std-rfc `use std-rfc/pb` that wraps the `OSC 9;4` escape sequences for setting progress bars in the terminal (some terminals don't support any/some of the commands). + +Example: +```nushell +use std-rfc/pb + +try { + 0..<10 | each {|x| sleep 200ms ; pb set-idx $x 10 } +} catch { + pb error +} finally { + pb clear +} +``` + +### New `peek` command for inspecting streams without collecting + +Added `peek` command, which can be used to access properties of the pipeline input and get the first `$n` items of a list stream *without* collecting it. + +It works by exposing this information as pipeline metadata so it can be retrieved with `metadata access`. + +```nushell +.. | peek | metadata access {|md| + if not $md.peek.stream { + $env.LAST_RESULT = $in + $in + } else { + # do not collect, pass the stream through as it is + } +} +``` + +```nushell +.. | peek 1 | metadata access {|md| + if ( + $md.peek.value?.0? != null + and ($md.peek.value.0 | columns | $in has "type" and $in has "name") + ) { + sort-by type name + } else { + # pass the stream through as it is + } +} +``` + +### Add addtional polars selectors: ends-with, alpha, and alphanumeric + +Introduces new `polars selector` sub commands +- `polars selector alpha` for selecting columns alphabetic characters +- `polars selector alphanumeric` for selecting columns with alphanumeric characters +- `polars selector ends-with` for selecting columns with a suffix + +### Even more polars selectors + +Added 20 additional polars selectors: + +- `polars selector array` - Select all array columns. Optionally filter by fixed width. +- `polars selector binary` - Select all binary columns. +- `polars selector boolean` - Select all boolean columns. +- `polars selector by-index` - Select columns by their index position. Supports negative indices (e.g., `-1` for the last column). +- `polars selector categorical` - Select all categorical columns. +- `polars selector contains` - Select columns whose names contain the given literal substring(s). +- `polars selector date` - Select all date columns. +- `polars selector datetime` - Select all datetime columns. Optionally filter by time unit (`ns`, `us`, `ms`) and/or timezone. +- `polars selector decimal` - Select all decimal columns. +- `polars selector digit` - Select columns whose names consist entirely of digit characters. By default uses Unicode decimal digits; use `--ascii-only` to restrict to ASCII `0-9`. +- `polars selector duration` - Select all duration columns. Optionally filter by time unit (`ns`, `us`, `ms`). +- `polars selector empty` - Create an empty selector that matches no columns. Useful as a base for selector composition. +- `polars selector ends-with` - Select columns that end with the given substring(s). +- `polars selector enum` - Select all enum columns. +- `polars selector exclude` - Select all columns except those with the given name(s). This is the inverse of `polars selector by-name`. +- `polars selector list` - Select all list columns. +- `polars selector nested` - Select all nested columns (`list`, `array`, or `struct`). +- `polars selector object` - Select all object columns. +- `polars selector starts-with` - Select columns that start with the given substring(s). +- `polars selector string` - Select all string columns. Use `--include-categorical` to also select categorical columns. +- `polars selector struct` - Select all struct columns. +- `polars selector temporal` - Select all temporal columns (`date`, `datetime`, `duration`, and `time`). + +### Add `idx` family of commands for in-memory indexing + +Add the `idx` command family for in-memory filesystem indexing and search. + +### Commands + +#### `idx init [--wait]` + +Initializes the global idx runtime by scanning ``. If the runtime is already initialized it is dropped and re-scanned. `--wait` blocks until the initial scan completes; omitting it returns immediately with a `scanning = true` status. + +```nushell +idx init . +idx init ~/projects --wait +``` + +#### `idx status` + +Returns a record describing the current runtime: `initialized`, `base_path`, `watch`, `scanning`, `scan_duration_ms`, `files`, `dirs`, and arena memory usage fields. + +```nushell +idx status +``` + +#### `idx dirs` + +Returns all indexed directories as records with `relative_path` and `full_path` columns. + +```nushell +idx dirs +idx dirs | where full_path =~ src +``` + +#### `idx files []` + +Returns all indexed files as records with `relative_path`, `full_path`, `file_name`, `directory`, `size`, and `modified` columns. If an optional `` is provided it performs a direct lookup by relative or absolute path. + +```nushell +idx files +idx files src/main.rs +idx files /absolute/path/to/file.rs +``` + +#### `idx find [--files] [--dirs] [--verbose] [--limit ]` + +Fuzzy-searches the index using [`fff-search` scoring](https://docs.rs/fff-search/latest/fff_search/). By default searches both files and directories. `--files` or `--dirs` narrows the search. `--verbose` adds a `score_details` column. `--limit` caps the result count (default 100). + +```nushell +idx find main +idx find config --files --verbose +idx find src --dirs --limit 10 +``` + +#### `idx search ... [--regex] [--fuzzy] [--limit ]` + +Searches the **contents** of indexed files. Plain text is the default. `--regex` enables regex matching. `--fuzzy` enables approximate line matching. Multiple patterns are searched with `multi_grep`. `--limit` caps matches (default 50). + +```nushell +idx search hello +idx search --regex 'fn \w+' +idx search TODO FIXME HACK +``` + +#### `idx export ` + +Persists the current runtime to a **SQLite** database at ``. Returns a record with `stored`, `path`, `file_count`, `dir_count`, `base_path`, and `format`. + +```nushell +idx export ~/my-index.db +``` + +#### `idx import ` + +Imports a SQLite snapshot created by `idx export`. Performs true offline restoration by hydrating the index from stored file and directory rows in the database with no filesystem rescanning. Returns a record with `restored`, `source_path`, `base_path`, `watch`, `rehydration_mode`, `status`, `restored_files`, `restored_dirs`, and `format`. The `rehydration_mode` is `offline_from_snapshot_rows`, and the status fields (`scanning`, `scan_duration_ms`). + +```nushell +idx import ~/my-index.db +``` + +#### `idx drop` + +Drops the current runtime from memory. Returns `{dropped: bool, status: record}` where `status` is always the default (zeroed) status after the drop. + +```nushell +idx drop +``` + +### Allow filtering custom completions by description + +Custom completers can now opt into matching the user's prefix against suggestion descriptions in addition to values, by setting `match_description: true` in the returned `options` record. The inserted completion is still the suggestion's `value`. + +```nu +def "nu-complete users" [] { + { + options: { match_description: true, completion_algorithm: "substring" } + completions: [ + { value: "lk446763@example.com", description: "Lennart Kiil" } + { value: "ab123456@example.com", description: "Alice Bob" } + ] + } +} +``` + +### New `std-rfc/iter prod` comand to produce cartesian products + +A new command for producing cartesian products of an arbitrary number of lists, accessible as `std-rfc/iter prod`. + +It takes a record with list values and returns a table where each column has items from the corresponding list: +```nushell +prod { + size: [little, big] + color: [red, blue] + shape: [circle, box] +} +# returns +[ + [size, color, shape]; + [little, red, circle], + [little, red, box], + [little, blue, circle], + [little, blue, box], + [big, red, circle], + [big, red, box], + [big, blue, circle], + [big, blue, box] +] +``` + +It can also take an input stream, items of which will be in the `"in"` column: +```nushell +[1, 2] | prod { rhs: [a, b] } +# returns +[ + [in, rhs]; + [1, a] + [1, b] + [2, a] + [2, b] +] +``` + +`prod` generates its output lazily, so it doesn't collect its input. + +### Added `--no-commas` flag to `to nuon` to exclude optional commas +When you use the new `--no-commas` flag on `to nuon` you won't have to see commas. Since nuon doesn't require commas, this will make the output more succinct. Some may argue that it's harder to read, which may be true, but nuon doesn't care about that. + +```nushell +❯ ls | to nuon --indent 2 --list-of-records | str length +3312 +❯ ls | to nuon --indent 2 --list-of-records --no-commas | str length +3169 +❯ ls | to nuon | str length +2260 +❯ ls | to nuon --no-commas | str length +2114 +``` +Sometimes, every little bit helps. + +### The `pre_prompt` and `env_change` hooks may now modify the commandline +The `pre_prompt` and `env_change` hooks can now modify the commandline using the `commandline edit` command. + +Example: +```nushell +$env.config.hooks.pre_prompt ++= [{ commandline edit "test" }] +``` + +### `rm -v` returns structured data +``` +> rm -v z a c +╭───┬────────┬─────────┬───────────╮ +│ # │ path │ deleted │ error │ +├───┼────────┼─────────┼───────────┤ +│ 0 │ /tmp/z │ false │ Not found │ +│ 1 │ /tmp/c │ false │ Not found │ +│ 2 │ /tmp/a │ true │ │ +╰───┴────────┴─────────┴───────────╯ +``` +### `rm` removes other files even if there is an error in the middle +``` +> touch a +> rm z c a +Error: nu::shell::io::not_found + + × Not found + ╭─[repl_entry #7:1:6] + 1 │ rm z c a + · ┬ + · ╰── Not found + ╰──── + help: '/tmp/c' does not exist + +Error: nu::shell::io::not_found + + × Not found + ╭─[repl_entry #7:1:4] + 1 │ rm z c a + · ┬ + · ╰── Not found + ╰──── + help: '/tmp/z' does not exist +> 'a' | path exists +false +``` + +### ps -l have more columns +``` +> ps -l | select pid name mem virtual working paged +╭────┬───────┬─────────────────┬──────────┬──────────┬──────────┬──────────╮ +│ # │ pid │ name │ mem │ virtual │ working │ paged │ +├────┼───────┼─────────────────┼──────────┼──────────┼──────────┼──────────┤ +│ 0 │ 1 │ init(openSUSE-T │ 2.2 MB │ 3.1 MB │ 2.2 MB │ 0 B │ +│ 1 │ 7 │ init │ 2.6 MB │ 3.2 MB │ 2.6 MB │ 0 B │ +│ 2 │ 10 │ SessionLeader │ 917.5 kB │ 3.1 MB │ 917.5 kB │ 0 B │ +│ 3 │ 11 │ Relay(12) │ 1.1 MB │ 3.1 MB │ 1.1 MB │ 0 B │ +│ 4 │ 12 │ nu │ 28.4 MB │ 688.3 MB │ 28.4 MB │ 6.4 MB │ +│ 5 │ 53 │ zellij │ 70.3 MB │ 25.3 GB │ 70.3 MB │ 31.7 MB │ +├────┼───────┼─────────────────┼──────────┼──────────┼──────────┼──────────┤ +│ # │ pid │ name │ mem │ virtual │ working │ paged │ +╰────┴───────┴─────────────────┴──────────┴──────────┴──────────┴──────────╯ +``` + +### Added fish-style abbreviations +Added support for fish-style abbreviations that are expanded on `enter` or `space`. Abbreviations are syntax-aware in that expansion doesn't occur within strings or when appearing as arguments to an external program. + +Abbreviations can be added to the config like so: + +```nushell +$env.config.abbreviations = { + ll: "ls -l" + gs: "git status" +} +``` + +Also added `abbr` and `abbr list` commands to help make this functionality more discoverable. + +### Locked history related config values during REPL + +The following `$env.config.history` fields are now read-only after the REPL starts, since reedline only reads them once at startup and silently ignored later changes: + +- `$env.config.history.path` +- `$env.config.history.max_size` +- `$env.config.history.file_format` +- `$env.config.history.isolation` + +`sync_on_enter` and `ignore_space_prefixed` remain mutable from the REPL since they are re-read on each prompt. + +Attempting to change one of the locked fields from the REPL now produces a clear error instead of being silently ignored: + +```bash +> $env.config.history.path = "/tmp/elsewhere.txt" +Error: nu::shell::config_option_locked_after_startup + + × $env.config.history.path cannot be changed after Nushell has started + ╭─[repl_entry #1:1:28] + 1 │ $env.config.history.path = "/tmp/elsewhere.txt" + · ─────────┬────────── + · ╰── cannot be changed at runtime + ╰──── + help: set $env.config.history.path in your config.nu (or via --config / the relevant env var) and restart Nushell +``` + +### Other additions + +* `metadata access`'s closure can now modify the caller's environment, as if run with `do --env` ([#18085](https://github.com/nushell/nushell/pull/18085)) +* introduces `std-rfc`/`str lcp` calculating longest common prefix for a list of strings ([#17907](https://github.com/nushell/nushell/pull/17907)) +* `std-rfc/iter recurse` now supports multiple cell-path arguments. ([#18172](https://github.com/nushell/nushell/pull/18172)) +* Added the `std-rfc/url` module to modify urls more concisely. ([#18239](https://github.com/nushell/nushell/pull/18239)) + +## Deprecations + +### Deprecated `watch` command's optional closure argument + +`watch` command's optional closure argument is deprecated and will be removed in a future release. Update your scripts to use a for-loop or `each` instead: + +```nushell +for event in (watch . --glob=**/*.rs) { + cargo test +} +# or +watch . --glob=**/*.rs | each { cargo test } +``` + +As a reminder, using this streaming approach allows you to combine `watch` with other commands as well: +```nushell +watch . +| where operation == Write and path like "*.md" +| each { md-lint $in.path } +``` + +### Deprecated implicit `name` column for `grid` command +The `grid` command now accepts an optional column name to display the contents of that column in a grid. One should no longer rely on the old behavior which automatically displays the `name` column as it is deprecated. Moreover, passing in a record as the input is also deprecated. + +```nushell +# before +ls | grid +{ name: test } | grid + +# after +ls | grid name +[{ name: test }] | grid name +``` + + +## Removals + +### Removed deprecated flag `--datasource-ls` of `metadata set` +The deprecated flag of metadata `--datasource-ls` has been removed. Use `metadata set --path-columns [name]` instead. +The `ls` command will no longer set the `source` metadata to `ls`. + + +## Other changes + +### `to csv` and `to tsv` stream now to `save` +Saving streaming table data to `.csv` and `.tsv` now writes rows to disk as they arrive instead of buffering the full output first. + +Streaming CSV/TSV export now fails with a clear schema-drift error if later rows introduce new columns after output has started. If your input has varying columns, use `to csv --columns [...]` / `to tsv --columns [...]` or `collect` first. + +### `to yaml` now correctly quotes string values + +Before: +```nu +'{"value": "off", "listen": "0.0.0.0:8444"}' | from json | to yaml +value: off +listen: 0.0.0.0:8444 +``` + +After: +```nu +'{"value": "off", "listen": "0.0.0.0:8444"}' | from json | to yaml +value: 'off' +listen: '0.0.0.0:8444' +``` + +### Raise default promote-after to 2m and add `timeout_secs` param + +- `nu-mcp`: default auto-promote-to-background threshold raised from 10s to 120s. +- `nu-mcp`: the `evaluate` tool accepts a new optional `timeout_secs` parameter to override the promotion threshold per call. + +### `from md` now produces a more concise output by default +The `from md` command now defaults to a more human friendly reduced mode. The original ast mode is now behind the `--verbose` switch. + +Here are a couple screenshots of reduced mode. +image + +image + +### Improved argument handling for untyped rest parameters + +Fixed wrapped command argument handling in `def --wrapped [...rest]` for untyped rest params: + +- Nushell now parses `--key="value"` and `--key='value'` in wrapped rest args like external args, removing quote wrappers around the value. +- Nushell now expands `~` in untyped wrapped rest args even when args are read directly (for example via `$args | to nuon`), not only when forwarding to an external command. +- Explicitly typed string rest params `[...rest: string]` keep prior literal behavior. + +### Added dynamic dispatch for `%` sigil commands + +Nushell now supports dynamic percent builtin dispatch with forms like %($cmd) and %$cmd. + +This preserves percent safety semantics while allowing runtime command selection: + +- only builtins are eligible targets +- non-builtin/custom/alias targets are rejected +- arguments are forwarded as parsed values (not string-evaluated like shell eval) + +This should work very similarly to dynamic dispatch of externals. The same model was followed to implement it. + +Here's a couple examples that are also tests. +### Built-ins resolve +```nushell +❯ let cmd = 'echo'; %$cmd 'hello' +hello +❯ %('echo') 'world' +world +❯ let cmd = 'echo'; %($cmd) 'hello' +hello +``` +### Missing commands fail +```nushell +❯ let cmd = 'my_nonexistent_cmd'; %($cmd) +Error: nu::shell::command_not_found + + × Command not found + ╭─[repl_entry #7:1:33] + 1 │ let cmd = 'my_nonexistent_cmd'; %($cmd) + · ───┬─── + · ╰── command not found + ╰──── +``` +### Custom commands aren't built-in commands so they fail too +```nushell +❯ def custom_cmd [] { 'nope' }; let cmd = 'custom_cmd'; %($cmd) +Error: nu::shell::command_not_found + + × Command not found + ╭─[repl_entry #8:1:55] + 1 │ def custom_cmd [] { 'nope' }; let cmd = 'custom_cmd'; %($cmd) + · ───┬─── + · ╰── command not found + ╰──── +``` + +### Improved escape handling +Nushell handles escaping better with the back slash `\` when use with double quotes or string interpolation with double quotes where escapes are interpreted. + +Nushell now supports and validates more backslash escape forms consistently in string parsing, and reports clearer errors for invalid unicode/hex escapes (including better wording around missing `}` and unicode code point limits). + +Parse and process escape sequences in a byte string. + +Now, the following escape sequences are handled: + - Simple: `\n`, `\r`, `\t`, `\\`, `\"`, `\'` + - Control: `\0`, `\a`, `\b`, `\e`, `\f` + - Hex: `\xHH` (exactly 2 hex digits) + - Unicode: `\u{XXXXXX}` (1-6 hex digits, max 0x10FFFF) + - Special: `\/`, `\(`, `\)`, `\{`, `\}`, `\$`, `\^`, `\#`, `\|`, `\~` + +### Make env_hook case insensitive + +Before +``` +$env.config.hooks.env_change.pwd = [{|| print "dir changed" }] +cd .. +# => No result +``` + +After +``` +$env.config.hooks.env_change.pwd = [{|| print "dir changed" }] +cd .. +# => nushell prints out `dir changed`. +``` + +### Additional changes + +* Added conditional compilation to fix never used warning when compiling without the mcp feature. ([#18056](https://github.com/nushell/nushell/pull/18056)) +* Fixes `input list` backtab functionality by undoing previous selection before navigation. ([#18068](https://github.com/nushell/nushell/pull/18068)) +* The \`evaluate\` MCP tool no longer accepts a \`timeout_secs\` parameter. To override the promote-after timeout, set \`\$env.NU_MCP_PROMOTE_AFTER\` (e.g. \`\$env.NU_MCP_PROMOTE_AFTER = 10min\`) — the setting is REPL-sticky and applies to subsequent calls until changed. ([#18070](https://github.com/nushell/nushell/pull/18070)) +* - Improved language for the "Cannot find column ..." shell error to be more precise about missing data and suggest user actions to fix. ([#18108](https://github.com/nushell/nushell/pull/18108)) +* Refactor `--on-cols` in `polars pivot` from required to optional parameter; supply default values based on unique values of `--on` columns ([#18140](https://github.com/nushell/nushell/pull/18140)) +* `which` and `history` command now also have `path_columns` metadata in their output. So the paths will render like it does for `ls` command. ([#18020](https://github.com/nushell/nushell/pull/18020)) +* Fixed an issue where `cp` could not copy symbolic links as links. Nushell now supports `cp -P` and `cp --no-dereference`, including for symlinks that point to directories. ([#18162](https://github.com/nushell/nushell/pull/18162)) +* Make auto-cd accept paths with leading/trailing whitespace. ([#18123](https://github.com/nushell/nushell/pull/18123)) +* The `each` command now preserves the metadata of the output of the closure if the input is a scalar value. ([#18201](https://github.com/nushell/nushell/pull/18201)) + +## Bug fixes + +### Fixed internal sigil recursion error +Fixed an issue where if you used the built-in sigil you might get a recursion error like this. This no longer happens. +```nushell +/> def ls [] { %ls | move name --last } +/> ls +Error: nu::shell::recursion_limit_reached + + × Recursion limit (50) reached + ╭─[repl_entry #16:1:11] + 1 │ def ls [] { %ls | move name --last } + · ─────────────┬──────────── + · ╰── This called itself too many times + ╰──── + +/> +``` + +### `http` commands now respect the `$env.NO_PROXY` variable +`http` command now reads the environment variable `NO_PROXY` and supports the following patterns. +| Pattern | Behavior | + +### Finally no longer suppresses error messages +For example: + +```nushell +> try { 1 / 0 } finally { print 'this finally' } +``` +It prints 'this finally' and throws out the error. + +### The return value of finally is the return value of `try` or `catch` +```nushell +> let x = try { 13 } finally { print 'this finally'; 1 } +this finally +> $x == 3 +true +> let x = try { 1 / 0 } catch { "xx" } finally { print 'this finally' } +this finally +> $x == "xx" +true +``` + +### Ignore Shebangs When Parsing Module Comments +- Shebangs are now ignored when extracting the `description` for a module. This affects the output in commands like `help ` and `scope modules`. + +### Fixed `Rename` events in `watch` + +Order of the paths reported for `Rename` events are now correct, whereas previously they were reported as if `$new_path` was renamed to `$path`. + +Additionally if one of these paths happened to be outside of the watched directory, previously the event was not reported at all, now they are reported with the path outside of the watched directory as `null`. + +### Fixed issue causing `try` to execute code twice +Now the following code won't run print statement twice. + +Before: +``` +> do -i {try {}; print "Look, I ran twice!"; not_a } +Look, I ran twice! +Look, I ran twice! +``` +After: +``` +> do -i {try {}; print "Look!"; not_a } +Look! +``` + +### `try` blocks may now be interrupted with ctrl-c +Finally block will run if try block is interruped with ctrl-c, for example: +``` +# cc.nu +#!/usr/bin/env nu +"test content" | save -f cleanup-test.txt +print $"before try: cleanup-test.txt exists = ('cleanup-test.txt' | path exists)" +try { + ^ping -n 30 127.0.0.1 # or `^ping -c 30 127.0.0.1` on Linux/macOS +} finally { + print "finally ran" + rm -f cleanup-test.txt +} +print $"after try: cleanup-test.txt exists = ('cleanup-test.txt' | path exists)" +``` +And run it with: +``` +> nu cc.nu +``` +press ctrl-c during printing, it'll output `finally ran` + +### Annotated default values typed as `glob` are now properly handled +Default values in commands will now be correctly parsed as `glob` type instead of `string` when annotated. +- Before +```nushell +def foo [--x: glob = *.x] { + $x | describe +} +→ foo +# string +``` +- After +```nushell +def foo [--x: glob = *.x] { + $x | describe +} +→ foo +# glob +``` + +### mkdir will try to create all directories, even if errors happened in the middle +``` +# Assume you are inside `/tmp` directory +> mkdir a +> chmod 400 a +> mkdir b a/c +Error: nu::shell::error + + × Permission denied + ╭─[repl_entry #24:1:9] + 1 │ mkdir b a/c + · ─┬─ + · ╰── Permission denied + ╰──── +> "b" | path exists +true +``` +Also noted that the errors are pointed to correct span. Previously it points to `crates/nu-command/src/filesystem/umkdir.rs:95:48`, which is not user friendly. + +### Empty blocks' output types are the same as their input types + +Previously empty blocks (a command's body, if-else branch, match arm etc.) were inferred to return `nothing` regardless of their input type. This caused code like the following to fail type checking despite being correct: +```nushell +def pass-through []: int -> int { } +``` +The type checker now correctly recognizes that empty blocks pass their inputs as they are. + +### Fixed hash-quoting +Fix the raw string prefix and suffix in certain situations. +#### Before +```nushell + open -r foo.toml | to nuon --raw-strings +r#'# example.toml +name = "my-app" +version = "1.0.0" +'# +``` +#### After +```nushell + open -r foo.toml | to nuon --raw-strings +r##'# example.toml +name = "my-app" +version = "1.0.0" +'## +``` + +### Other fixes + +* Fixed a bug of command-wide completer where explicit `return` expressions in the completer commands disrupt the functionality. ([#18009](https://github.com/nushell/nushell/pull/18009)) +* Fixed a bug of lossy parsing of incomplete pipelines end with `|`, which is noticeable via REPL highlighting. ([#17977](https://github.com/nushell/nushell/pull/17977)) +* `random choice` from `std-rfc` now properly reports `list -> list` and `list -> any` for its type signature. ([#18093](https://github.com/nushell/nushell/pull/18093)) +* Fixes the issue where `$env.AAAA = "aaaa"; $env.AAAA = ""; hide-env AAAA` failed to hide `AAAA`. After the empty-string assignment. ([#18170](https://github.com/nushell/nushell/pull/18170)) +* Improve repl error handling when redirected like `nu > /dev/full` or `nu 2>/dev/full`. ([#18210](https://github.com/nushell/nushell/pull/18210)) + + +# Notes for plugin developers + +# Hall of fame + +Thanks to all the contributors below for helping us solve issues, improve documentation, refactor code, and more! :pray: + +| author | change | link | +| --- | --- | --- | +| [@Juhan280](https://github.com/Juhan280) | Clean up `grid` command implementation | [#18021](https://github.com/nushell/nushell/pull/18021) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `--include-ignored` flag to custom test harness | [#18034](https://github.com/nushell/nushell/pull/18034) | +| [@Juhan280](https://github.com/Juhan280) | Add tests for `grid` command | [#18022](https://github.com/nushell/nushell/pull/18022) | +| [@Juhan280](https://github.com/Juhan280) | Fix failing test for `grid` command | [#18065](https://github.com/nushell/nushell/pull/18065) | +| [@andrewgazelka](https://github.com/andrewgazelka) | Overhaul nu-mcp instructions sent to MCP clients | [#18057](https://github.com/nushell/nushell/pull/18057) | +| [@OneProgGit](https://github.com/OneProgGit) | Fixed a typo in `nu-std` crate. | [#18066](https://github.com/nushell/nushell/pull/18066) | +| [@andrewgazelka](https://github.com/andrewgazelka) | n/a (docs-only change to MCP server instructions) | [#18071](https://github.com/nushell/nushell/pull/18071) | +| [@orbisai0security](https://github.com/orbisai0security) | Fix medium severity security issue in `.github/workflows/release-msi.yml`. | [#18074](https://github.com/nushell/nushell/pull/18074) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `Command: Any` and `CustomValue: Any` | [#18076](https://github.com/nushell/nushell/pull/18076) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Implement `Debug` for `EngineState` and derive more `Debug` impls | [#18091](https://github.com/nushell/nushell/pull/18091) | +| [@Bahex](https://github.com/Bahex) | Replace FindMapResult with ControlFlow | [#18094](https://github.com/nushell/nushell/pull/18094) | +| [@Bahex](https://github.com/Bahex) | Prefer borrowed strings | [#18097](https://github.com/nushell/nushell/pull/18097) | +| [@Bahex](https://github.com/Bahex) | Refactor/update some old tests to the newer in process style | [#18096](https://github.com/nushell/nushell/pull/18096) | +| [@nome](https://github.com/nome) | Consolidate and fix closure parameter handling | [#16844](https://github.com/nushell/nushell/pull/16844) | +| [@Bahex](https://github.com/Bahex) | Add `test_table!` macro for writing tests and examples easier | [#18098](https://github.com/nushell/nushell/pull/18098) | +| [@Bahex](https://github.com/Bahex) | Parameter type and string interpolation | [#18095](https://github.com/nushell/nushell/pull/18095) | +| [@Bahex](https://github.com/Bahex) | Refactor tests to avoid format! | [#18127](https://github.com/nushell/nushell/pull/18127) | +| [@Bahex](https://github.com/Bahex) | Assortment of small refactors | [#18154](https://github.com/nushell/nushell/pull/18154) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Allow configuring `version` field in `version` command | [#18144](https://github.com/nushell/nushell/pull/18144) | +| [@Bahex](https://github.com/Bahex) | Add docs for `get_vendor_autoload_dirs` | [#18163](https://github.com/nushell/nushell/pull/18163) | +| [@WindSoilder](https://github.com/WindSoilder) | Fix clippy | [#18174](https://github.com/nushell/nushell/pull/18174) | +| [@132ikl](https://github.com/132ikl) | Gate idx import and export commands behind sqlite feature | [#18181](https://github.com/nushell/nushell/pull/18181) | +| [@Metbcy](https://github.com/Metbcy) | Add table rendering benchmarks for nu-table (#7727) | [#18179](https://github.com/nushell/nushell/pull/18179) | +| [@Bahex](https://github.com/Bahex) | Add `nu-heavy-utils` crate and consolidate endian flag handling | [#18184](https://github.com/nushell/nushell/pull/18184) | +| [@vip892766gma](https://github.com/vip892766gma) | Fix duplicated words in comments | [#18196](https://github.com/nushell/nushell/pull/18196) | +| [@Bahex](https://github.com/Bahex) | Some more cleaning | [#18186](https://github.com/nushell/nushell/pull/18186) | +| [@quyentonndbs](https://github.com/quyentonndbs) | Fix duplicated "that" in nu-parser comment | [#18200](https://github.com/nushell/nushell/pull/18200) | +| [@colinmparker](https://github.com/colinmparker) | - N/A | [#18088](https://github.com/nushell/nushell/pull/18088) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix CI not executing all tests on Windows | [#18211](https://github.com/nushell/nushell/pull/18211) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix running tests for only `nu-cli` | [#18216](https://github.com/nushell/nushell/pull/18216) | +| [@Bahex](https://github.com/Bahex) | Mark `watch` tests serial and increase timeout | [#18233](https://github.com/nushell/nushell/pull/18233) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Move `merge` implementation to `nu-heavy-utils` | [#18231](https://github.com/nushell/nushell/pull/18231) | +| [@Juhan280](https://github.com/Juhan280) | Make `commandline` command family work again in ExecuteHostCommand | [#18204](https://github.com/nushell/nushell/pull/18204) | +| [@blindFS](https://github.com/blindFS) | PathLikeKind enum for parse_path_like | [#18237](https://github.com/nushell/nushell/pull/18237) | +| [@fdncred](https://github.com/fdncred) | Add benchmarks for parser performance and throughput analysis | [#18245](https://github.com/nushell/nushell/pull/18245) | +| [@Bahex](https://github.com/Bahex) | Small refactors utilizing pattern matching for conciseness | [#18242](https://github.com/nushell/nushell/pull/18242) | +| [@Bahex](https://github.com/Bahex) | Stderr/stdout full tests should not read user config | [#18253](https://github.com/nushell/nushell/pull/18253) | +| [@Matthieu-LAURENT39](https://github.com/Matthieu-LAURENT39) | Fix query web --as-table example | [#18262](https://github.com/nushell/nushell/pull/18262) | +| [@Bahex](https://github.com/Bahex) | `peek` returns the actual type of values | [#18268](https://github.com/nushell/nushell/pull/18268) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fixed some build issues | [#18270](https://github.com/nushell/nushell/pull/18270) | + +# Full changelog + +| author | title | link | +| --- | --- | --- | +| [@132ikl](https://github.com/132ikl) | Gate idx import and export commands behind sqlite feature | [#18181](https://github.com/nushell/nushell/pull/18181) | +| [@Bahex](https://github.com/Bahex) | New `peek` command for inspecting streams without collecting | [#17796](https://github.com/nushell/nushell/pull/17796) | +| [@Bahex](https://github.com/Bahex) | `metadata access` can modify `$env` | [#18085](https://github.com/nushell/nushell/pull/18085) | +| [@Bahex](https://github.com/Bahex) | refactor: replace FindMapResult with ControlFlow | [#18094](https://github.com/nushell/nushell/pull/18094) | +| [@Bahex](https://github.com/Bahex) | refactor(parser): parameter type and string interpolation | [#18095](https://github.com/nushell/nushell/pull/18095) | +| [@Bahex](https://github.com/Bahex) | Refactor/update some old tests to the newer in process style | [#18096](https://github.com/nushell/nushell/pull/18096) | +| [@Bahex](https://github.com/Bahex) | refactor: Prefer borrowed strings | [#18097](https://github.com/nushell/nushell/pull/18097) | +| [@Bahex](https://github.com/Bahex) | Add `test_table!` macro for writing tests and examples easier | [#18098](https://github.com/nushell/nushell/pull/18098) | +| [@Bahex](https://github.com/Bahex) | Fixed `Rename` events in `watch` | [#18115](https://github.com/nushell/nushell/pull/18115) | +| [@Bahex](https://github.com/Bahex) | refactor tests to avoid format! | [#18127](https://github.com/nushell/nushell/pull/18127) | +| [@Bahex](https://github.com/Bahex) | Removed implicit line splitting of byte streams in `parse` | [#18141](https://github.com/nushell/nushell/pull/18141) | +| [@Bahex](https://github.com/Bahex) | Deprecated `watch` command's optional closure argument | [#18143](https://github.com/nushell/nushell/pull/18143) | +| [@Bahex](https://github.com/Bahex) | assortment of small refactors | [#18154](https://github.com/nushell/nushell/pull/18154) | +| [@Bahex](https://github.com/Bahex) | Add docs for `get_vendor_autoload_dirs` | [#18163](https://github.com/nushell/nushell/pull/18163) | +| [@Bahex](https://github.com/Bahex) | feat(`std-rfc/iter recurse`): support multiple cell-paths | [#18172](https://github.com/nushell/nushell/pull/18172) | +| [@Bahex](https://github.com/Bahex) | feat(std-rfc/iter): new `prod` command for cartesian products | [#18177](https://github.com/nushell/nushell/pull/18177) | +| [@Bahex](https://github.com/Bahex) | add `nu-heavy-utils` crate and consolidate endian flag handling | [#18184](https://github.com/nushell/nushell/pull/18184) | +| [@Bahex](https://github.com/Bahex) | Some more cleaning | [#18186](https://github.com/nushell/nushell/pull/18186) | +| [@Bahex](https://github.com/Bahex) | Empty blocks' output types are the same as their input types | [#18213](https://github.com/nushell/nushell/pull/18213) | +| [@Bahex](https://github.com/Bahex) | test(watch): mark `watch` tests serial and increase timeout | [#18233](https://github.com/nushell/nushell/pull/18233) | +| [@Bahex](https://github.com/Bahex) | Small refactors utilizing pattern matching for conciseness | [#18242](https://github.com/nushell/nushell/pull/18242) | +| [@Bahex](https://github.com/Bahex) | test: stderr/stdout full tests should not read user config | [#18253](https://github.com/nushell/nushell/pull/18253) | +| [@Bahex](https://github.com/Bahex) | `peek` returns the actual type of values | [#18268](https://github.com/nushell/nushell/pull/18268) | +| [@Juhan280](https://github.com/Juhan280) | refactor!: remove deprecated `DataSource::Ls` | [#18019](https://github.com/nushell/nushell/pull/18019) | +| [@Juhan280](https://github.com/Juhan280) | Add `path_columns` metadata to `which` and history command | [#18020](https://github.com/nushell/nushell/pull/18020) | +| [@Juhan280](https://github.com/Juhan280) | refactor: clean up `grid` command implementation | [#18021](https://github.com/nushell/nushell/pull/18021) | +| [@Juhan280](https://github.com/Juhan280) | add tests for `grid` command | [#18022](https://github.com/nushell/nushell/pull/18022) | +| [@Juhan280](https://github.com/Juhan280) | Fix failing test for `grid` command | [#18065](https://github.com/nushell/nushell/pull/18065) | +| [@Juhan280](https://github.com/Juhan280) | fix: allow pre_prompt and env_change hooks to modify the commandline | [#18119](https://github.com/nushell/nushell/pull/18119) | +| [@Juhan280](https://github.com/Juhan280) | feat: accept optional column argument for `grid` command | [#18187](https://github.com/nushell/nushell/pull/18187) | +| [@Juhan280](https://github.com/Juhan280) | fix: make `each` maintain the metadata of closure result if input is scalar | [#18201](https://github.com/nushell/nushell/pull/18201) | +| [@Juhan280](https://github.com/Juhan280) | fix: make `commandline` command family work again in ExecuteHostCommand | [#18204](https://github.com/nushell/nushell/pull/18204) | +| [@Matthieu-LAURENT39](https://github.com/Matthieu-LAURENT39) | Fix query web --as-table example | [#18262](https://github.com/nushell/nushell/pull/18262) | +| [@Metbcy](https://github.com/Metbcy) | Add table rendering benchmarks for nu-table (#7727) | [#18179](https://github.com/nushell/nushell/pull/18179) | +| [@Mrfiregem](https://github.com/Mrfiregem) | feat(std-rfc): add `std-rfc/url` module | [#18239](https://github.com/nushell/nushell/pull/18239) | +| [@OneProgGit](https://github.com/OneProgGit) | Fix typo | [#18066](https://github.com/nushell/nushell/pull/18066) | +| [@SunayKulkarni](https://github.com/SunayKulkarni) | fix: remove executable bit from AGENTS.md | [#18243](https://github.com/nushell/nushell/pull/18243) | +| [@Tyarel8](https://github.com/Tyarel8) | fix warning when not compiling with mcp | [#18056](https://github.com/nushell/nushell/pull/18056) | +| [@Tyarel8](https://github.com/Tyarel8) | feat(`std-rfc`): add progressbar osc 9;4 wrapper | [#18073](https://github.com/nushell/nushell/pull/18073) | +| [@Tyarel8](https://github.com/Tyarel8) | fix(`parser`): parse default values of type glob correcly | [#18111](https://github.com/nushell/nushell/pull/18111) | +| [@WindSoilder](https://github.com/WindSoilder) | `finally` should not affect return value | [#18075](https://github.com/nushell/nushell/pull/18075) | +| [@WindSoilder](https://github.com/WindSoilder) | make ctrl-c works with try..finally while running script | [#18155](https://github.com/nushell/nushell/pull/18155) | +| [@WindSoilder](https://github.com/WindSoilder) | make mv -v and mkdir -v returns structured data | [#18171](https://github.com/nushell/nushell/pull/18171) | +| [@WindSoilder](https://github.com/WindSoilder) | fix try may causes other code run twice | [#18173](https://github.com/nushell/nushell/pull/18173) | +| [@WindSoilder](https://github.com/WindSoilder) | fix clippy | [#18174](https://github.com/nushell/nushell/pull/18174) | +| [@WindSoilder](https://github.com/WindSoilder) | mkdir: don't interrupt when error happened | [#18195](https://github.com/nushell/nushell/pull/18195) | +| [@WindSoilder](https://github.com/WindSoilder) | rm: returns structure data when -v is used, and don't interrupt when error happened | [#18202](https://github.com/nushell/nushell/pull/18202) | +| [@WindSoilder](https://github.com/WindSoilder) | make env_hook case insensitive | [#18234](https://github.com/nushell/nushell/pull/18234) | +| [@WindSoilder](https://github.com/WindSoilder) | ps -l: introduce working_size, paged_size on windows and linux system | [#18255](https://github.com/nushell/nushell/pull/18255) | +| [@andrewgazelka](https://github.com/andrewgazelka) | Overhaul nu-mcp instructions sent to MCP clients | [#18057](https://github.com/nushell/nushell/pull/18057) | +| [@andrewgazelka](https://github.com/andrewgazelka) | nu-mcp: raise default promote-after to 2m and add `timeout_secs` param | [#18059](https://github.com/nushell/nushell/pull/18059) | +| [@andrewgazelka](https://github.com/andrewgazelka) | nu-mcp: remove timeout_secs param, rely on NU_MCP_PROMOTE_AFTER | [#18070](https://github.com/nushell/nushell/pull/18070) | +| [@andrewgazelka](https://github.com/andrewgazelka) | docs(nu-mcp): prefer `\| complete` over `o+e>\| complete` | [#18071](https://github.com/nushell/nushell/pull/18071) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump rand from 0.10.0 to 0.10.1 | [#18035](https://github.com/nushell/nushell/pull/18035) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.45.0 to 1.45.1 | [#18041](https://github.com/nushell/nushell/pull/18041) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump lean_string from 0.5.1 to 0.6.0 | [#18042](https://github.com/nushell/nushell/pull/18042) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump hashbrown from 0.16.1 to 0.17.0 | [#18043](https://github.com/nushell/nushell/pull/18043) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.45.1 to 1.45.2 | [#18133](https://github.com/nushell/nushell/pull/18133) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump shadow-rs from 1.7.1 to 2.0.0 | [#18134](https://github.com/nushell/nushell/pull/18134) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump data-encoding from 2.10.0 to 2.11.0 | [#18135](https://github.com/nushell/nushell/pull/18135) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump lru from 0.17.0 to 0.18.0 | [#18136](https://github.com/nushell/nushell/pull/18136) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump fancy-regex from 0.17.0 to 0.18.0 | [#18138](https://github.com/nushell/nushell/pull/18138) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.45.2 to 1.46.0 | [#18164](https://github.com/nushell/nushell/pull/18164) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump rmcp from 1.5.0 to 1.6.0 | [#18166](https://github.com/nushell/nushell/pull/18166) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump openssl from 0.10.78 to 0.10.79 | [#18167](https://github.com/nushell/nushell/pull/18167) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.46.0 to 1.46.1 | [#18191](https://github.com/nushell/nushell/pull/18191) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump calamine from 0.34.0 to 0.35.0 | [#18193](https://github.com/nushell/nushell/pull/18193) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump scraper from 0.26.0 to 0.27.0 | [#18194](https://github.com/nushell/nushell/pull/18194) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.46.1 to 1.46.2 | [#18246](https://github.com/nushell/nushell/pull/18246) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump rmcp from 1.6.0 to 1.7.0 | [#18249](https://github.com/nushell/nushell/pull/18249) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump quick-xml from 0.39.2 to 0.40.1 | [#18250](https://github.com/nushell/nushell/pull/18250) | +| [@ayax79](https://github.com/ayax79) | Add addtional polars selectors: ends-with, alpha, and alphanumeric | [#18114](https://github.com/nushell/nushell/pull/18114) | +| [@ayax79](https://github.com/ayax79) | Even more polars selectors | [#18120](https://github.com/nushell/nushell/pull/18120) | +| [@ayax79](https://github.com/ayax79) | Removed claude settings ang ignore them | [#18145](https://github.com/nushell/nushell/pull/18145) | +| [@blindFS](https://github.com/blindFS) | refactor(parser): move the pipe tokens in AST 1 element ahead | [#17977](https://github.com/nushell/nushell/pull/17977) | +| [@blindFS](https://github.com/blindFS) | fix(completion): allow explicit return in command-wide completer | [#18009](https://github.com/nushell/nushell/pull/18009) | +| [@blindFS](https://github.com/blindFS) | refactor(parser): PathLikeKind enum for parse_path_like | [#18237](https://github.com/nushell/nushell/pull/18237) | +| [@casedami](https://github.com/casedami) | feat: fish-style abbreviations | [#18197](https://github.com/nushell/nushell/pull/18197) | +| [@colinmparker](https://github.com/colinmparker) | Consolidate internal Value mutation logic | [#18088](https://github.com/nushell/nushell/pull/18088) | +| [@colinmparker](https://github.com/colinmparker) | (#17448) Update label and help text on CantFindCol error | [#18108](https://github.com/nushell/nushell/pull/18108) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Update PR template | [#18026](https://github.com/nushell/nushell/pull/18026) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `--include-ignored` flag to custom test harness | [#18034](https://github.com/nushell/nushell/pull/18034) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump to 0.112.3 | [#18055](https://github.com/nushell/nushell/pull/18055) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `Command: Any` and `CustomValue: Any` | [#18076](https://github.com/nushell/nushell/pull/18076) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Implement `Debug` for `EngineState` and derive more `Debug` impls | [#18091](https://github.com/nushell/nushell/pull/18091) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Update `random choice` type signature | [#18093](https://github.com/nushell/nushell/pull/18093) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Allow configuring `version` field in `version` command | [#18144](https://github.com/nushell/nushell/pull/18144) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix CI not executing all tests on Windows | [#18211](https://github.com/nushell/nushell/pull/18211) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix running tests for only `nu-cli` | [#18216](https://github.com/nushell/nushell/pull/18216) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Move `merge` implementation to `nu-heavy-utils` | [#18231](https://github.com/nushell/nushell/pull/18231) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fixed some build issues | [#18270](https://github.com/nushell/nushell/pull/18270) | +| [@develop7](https://github.com/develop7) | Introduce `str lcp` for `std-rfc` | [#17907](https://github.com/nushell/nushell/pull/17907) | +| [@fdncred](https://github.com/fdncred) | Enhance `ansi gradient` command with named gradients and improved options | [#18058](https://github.com/nushell/nushell/pull/18058) | +| [@fdncred](https://github.com/fdncred) | update nushell to latest reedline commit 4ffb1d3 | [#18067](https://github.com/nushell/nushell/pull/18067) | +| [@fdncred](https://github.com/fdncred) | update Rust toolchain to 1.93.1 + some deps | [#18077](https://github.com/nushell/nushell/pull/18077) | +| [@fdncred](https://github.com/fdncred) | handle `kill -0` as signal shorthand and update PID handling | [#18081](https://github.com/nushell/nushell/pull/18081) | +| [@fdncred](https://github.com/fdncred) | fix issue with sigil recursion | [#18084](https://github.com/nushell/nushell/pull/18084) | +| [@fdncred](https://github.com/fdncred) | bump reedline to latest commit | [#18099](https://github.com/nushell/nushell/pull/18099) | +| [@fdncred](https://github.com/fdncred) | refactor `from md` with `--verbose` for full ast and defaulting to a reduced mode | [#18107](https://github.com/nushell/nushell/pull/18107) | +| [@fdncred](https://github.com/fdncred) | Improved argument handling for untyped rest parameters | [#18131](https://github.com/nushell/nushell/pull/18131) | +| [@fdncred](https://github.com/fdncred) | Add `idx` family of commands for in-memory indexing | [#18142](https://github.com/nushell/nushell/pull/18142) | +| [@fdncred](https://github.com/fdncred) | Added dynamic dispatch for `%` sigil commands | [#18158](https://github.com/nushell/nushell/pull/18158) | +| [@fdncred](https://github.com/fdncred) | fix hide-env, refactor: rename remove_env_var to hide_env_var for clarity and update related logic | [#18170](https://github.com/nushell/nushell/pull/18170) | +| [@fdncred](https://github.com/fdncred) | add `--no-commas` flag to `to nuon` for compact output without comma separators | [#18185](https://github.com/nushell/nushell/pull/18185) | +| [@fdncred](https://github.com/fdncred) | fix(repl): improve error handling and cleanup on unexpected errors | [#18210](https://github.com/nushell/nushell/pull/18210) | +| [@fdncred](https://github.com/fdncred) | improve escape handling | [#18217](https://github.com/nushell/nushell/pull/18217) | +| [@fdncred](https://github.com/fdncred) | update deps for `idx` commands | [#18224](https://github.com/nushell/nushell/pull/18224) | +| [@fdncred](https://github.com/fdncred) | feat(parser): add benchmarks for parser performance and throughput analysis | [#18245](https://github.com/nushell/nushell/pull/18245) | +| [@fdncred](https://github.com/fdncred) | fix hash quoting and add tests | [#18258](https://github.com/nushell/nushell/pull/18258) | +| [@freepicheep](https://github.com/freepicheep) | Fix module description parsing with leading shebang | [#18106](https://github.com/nushell/nushell/pull/18106) | +| [@galuszkak](https://github.com/galuszkak) | feat(streaming): stream CSV/TSV output through 'save' and fail fast on schema drift implements #14338 | [#18005](https://github.com/nushell/nushell/pull/18005) | +| [@galuszkak](https://github.com/galuszkak) | fix(toml): Preserve TOML comments when saving files #4296 | [#18008](https://github.com/nushell/nushell/pull/18008) | +| [@galuszkak](https://github.com/galuszkak) | fix: losing string quoting for YAML values (Fixes #16072) | [#18010](https://github.com/nushell/nushell/pull/18010) | +| [@kaathewisegit](https://github.com/kaathewisegit) | Fix backtabbing in `--multi` mode in `input list` | [#18068](https://github.com/nushell/nushell/pull/18068) | +| [@kiil](https://github.com/kiil) | Allow filtering custom completions by description | [#18156](https://github.com/nushell/nushell/pull/18156) | +| [@kx0101](https://github.com/kx0101) | feat: lock $env.config.history.path after REPL startup | [#18190](https://github.com/nushell/nushell/pull/18190) | +| [@m4siri](https://github.com/m4siri) | Respecting $env.NO_PROXY | [#16730](https://github.com/nushell/nushell/pull/16730) | +| [@nome](https://github.com/nome) | Consolidate and fix closure parameter handling | [#16844](https://github.com/nushell/nushell/pull/16844) | +| [@orbisai0security](https://github.com/orbisai0security) | fix: using variable interpolation `${{ in release-msi.yml... | [#18074](https://github.com/nushell/nushell/pull/18074) | +| [@orbisai0security](https://github.com/orbisai0security) | fix: Limit explore search query length to keep TUI responsive | [#18251](https://github.com/nushell/nushell/pull/18251) | +| [@pyz4](https://github.com/pyz4) | feat(polars): pivot: provide default --on-cols value if not specified | [#18140](https://github.com/nushell/nushell/pull/18140) | +| [@pyz4](https://github.com/pyz4) | feat(from xlsx): add support for header row | [#18189](https://github.com/nushell/nushell/pull/18189) | +| [@quyentonndbs](https://github.com/quyentonndbs) | chore(parser): fix duplicated "that" in nu-parser comment | [#18200](https://github.com/nushell/nushell/pull/18200) | +| [@vip892766gma](https://github.com/vip892766gma) | docs: fix duplicated words in comments | [#18196](https://github.com/nushell/nushell/pull/18196) | +| [@vvvu](https://github.com/vvvu) | Fix cp --no-dereference for symlinks | [#18162](https://github.com/nushell/nushell/pull/18162) | +| [@ymcx](https://github.com/ymcx) | Trim whitespace from REPL input, byproduct is auto-cd with leading/trailing spaces works better | [#18123](https://github.com/nushell/nushell/pull/18123) |