Nushell
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
GitHub
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
GitHub

Nushell 0.99.0

Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your command line. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful command line pipelines.

Today, we're releasing version 0.99.0 of Nu. This release overhauls sorting and adds increased support for the kitty keyboard protocol.

Where to get it

Nu 0.99.0 is available as pre-built binaries or from crates.io. 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 you can install and use with Nu. To install, use cargo install nu_plugin_<plugin name>.

Table of contents

  • Highlights and themes of this release
    • Sorting overhaul
    • Handling stopped TUI applications
  • Changes
    • Additions
      • ls --threads
      • Enhanced keybinding configuration
      • input listen
      • random bytes and random chars
      • str stats
      • sort-by --custom
    • Breaking changes
      • sort-by and sort
      • Standard Library
    • Deprecations
      • Standard Library std/dirs
    • Removals
      • decode new-base64 and encode new-base64
    • Bug fixes and other changes
      • Prompt to write default config files
      • Mid-pipeline exit codes
      • Last exit code
      • try
      • Parser bugs
      • hash
      • view-source
      • do -p
      • format date
      • save -p
      • Panic fixes
  • Notes for plugin developers
  • Hall of fame
  • Full changelog

Highlights and themes of this release [toc]

Sorting overhaul [toc]

This release features an overhaul to the sort-by and sort commands, courtesy of #132ikl in #13154. Notably, the sort commands are now much more consistent and several handy new features were added as well.

Starting with new features, any cell path can now be used as the sort key in sort-by 🎉

> [[name info]; [Cairo {founded: 969}] [Kyoto {founded: 794}]] | sort-by info.founded
  ╭───┬───────┬───────────────────╮
  │ # │ name  │       info        │
  ├───┼───────┼───────────────────┤
  │ 0 │ Kyoto │ ╭─────────┬─────╮ │
  │   │       │ │ founded │ 794 │ │
  │   │       │ ╰─────────┴─────╯ │
  │ 1 │ Cairo │ ╭─────────┬─────╮ │
  │   │       │ │ founded │ 969 │ │
  │   │       │ ╰─────────┴─────╯ │
  ╰───┴───────┴───────────────────╯

You can now also use closures to compute a value to sort by:

# Sorting by file extension
> ls | where type == file | sort-by { get name | path parse | get extension }
╭────┬─────────────────────┬──────┬───────────┬───────────────╮
│  # │        name         │ type │   size    │   modified    │
├────┼─────────────────────┼──────┼───────────┼───────────────┤
│  0 │ LICENSE             │ file │   1.1 KiB │ 11 months ago │
│  1 │ CITATION.cff        │ file │     812 B │ a month ago   │
│  2 │ Cargo.lock          │ file │ 175.6 KiB │ 2 days ago    │
│  3 │ CODE_OF_CONDUCT.md  │ file │   3.4 KiB │ a year ago    │
│  4 │ CONTRIBUTING.md     │ file │  11.0 KiB │ a month ago   │
│  5 │ README.md           │ file │  12.0 KiB │ a month ago   │
│  6 │ SECURITY.md         │ file │   2.6 KiB │ a month ago   │
│  7 │ toolkit.nu          │ file │  19.2 KiB │ 3 days ago    │
│  8 │ Cargo.toml          │ file │   9.0 KiB │ 2 days ago    │
│  9 │ Cross.toml          │ file │     666 B │ 5 months ago  │
│ 10 │ rust-toolchain.toml │ file │   1.1 KiB │ 2 weeks ago   │
│ 11 │ typos.toml          │ file │     513 B │ 2 weeks ago   │
╰────┴─────────────────────┴──────┴───────────┴───────────────╯

Of course, you can still sort by multiple keys/columns:

# Sort by extension, then by modified time if two files have the same extension.
# Note that the last four toml files have changed order.
> ls | where type == file | sort-by { get name | path parse | get extension } modified
╭────┬─────────────────────┬──────┬───────────┬───────────────╮
│  # │        name         │ type │   size    │   modified    │
├────┼─────────────────────┼──────┼───────────┼───────────────┤
│  0 │ LICENSE             │ file │   1.1 KiB │ 11 months ago │
│  1 │ CITATION.cff        │ file │     812 B │ a month ago   │
│  2 │ Cargo.lock          │ file │ 175.6 KiB │ 2 days ago    │
│  3 │ CODE_OF_CONDUCT.md  │ file │   3.4 KiB │ a year ago    │
│  4 │ CONTRIBUTING.md     │ file │  11.0 KiB │ a month ago   │
│  5 │ README.md           │ file │  12.0 KiB │ a month ago   │
│  6 │ SECURITY.md         │ file │   2.6 KiB │ a month ago   │
│  7 │ toolkit.nu          │ file │  19.2 KiB │ 3 days ago    │
│  8 │ Cross.toml          │ file │     666 B │ 5 months ago  │
│  9 │ rust-toolchain.toml │ file │   1.1 KiB │ 2 weeks ago   │
│ 10 │ typos.toml          │ file │     513 B │ 2 weeks ago   │
│ 11 │ Cargo.toml          │ file │   9.0 KiB │ 2 days ago    │
╰────┴─────────────────────┴──────┴───────────┴───────────────╯

One final addition is allowing custom sort orders via closures. When provided with the --custom/-c flag, all closures passed to sort-by are assumed to take two arguments and return a boolean indicating whether or not the first argument should come before the second argument in the sort order.

> ls | sort-by -c {|a, b| $a.size < $b.size }
╭───┬─────────────────────┬──────┬──────────┬────────────────╮
│ # │        name         │ type │   size   │    modified    │
├───┼─────────────────────┼──────┼──────────┼────────────────┤
│ 0 │ my-secret-plans.txt │ file │    100 B │ 10 minutes ago │
│ 1 │ shopping_list.txt   │ file │    100 B │ 2 months ago   │
│ 2 │ myscript.nu         │ file │  1.1 KiB │ 2 weeks ago    │
│ 3 │ bigfile.img         │ file │ 10.0 MiB │ 3 weeks ago    │
╰───┴─────────────────────┴──────┴──────────┴────────────────╯

If a custom sort closure needs to be used in combination with a regular closure that computes a value, then two separate sort-bys need to be used. The sort commands perform stable sorts, so chaining multiple sorts together has the same effect as one sort with multiple comparators.

ls
| sort-by { get name | path parse | get extension }
| sort-by -c {|a, b| $a.size < $b.size }

Now, on to the other (breaking) changes. As part of reworking the sort commands to be more consistent, the default sort order was changed. Most notably, null values are now sorted to be after values of all other types.

> [null 1 null str] | sort
╭───┬─────╮
│ 0 │   1 │
│ 1 │ str │
│ 2 │     │
│ 3 │     │
╰───┴─────╯

Also, values of the same type will appear next to each other in sorted order. I.e., sorted numbers come first, then sorted strings, then sorted lists, etc. There are, however, a few exceptions:

  • Integers and floats are sorted/intermixed together based on their numerical value.
  • Similarly, strings and globs will be intermixed, sorted lexicographically by their Unicode code points.
  • If the --natural/-n flag is provided, then ints and floats will be sorted as strings. For example:
    [1 "4" 3 "2"] | sort --natural
    ╭───┬───╮
    │ 0 │ 1 │
    │ 1 │ 2 │
    │ 2 │ 3 │
    │ 3 │ 4 │
    ╰───┴───╯

Otherwise, there were a few other minor changes to makes things more consistent:

  • The --insensitive/-i flag was fixed, as case insensitive sorting did not occur in some cases.
  • If a column cannot be found in a value, sort-by now errors instead of silently continuing.
  • sort now errors if provided no input (to match the existing behavior of sort-by).
  • sort -v no longer converts record values to strings. Instead, it uses the new standard sort order that sort and sort-by also do.

Handling stopped TUI applications [toc]

Thanks to @nome in #13741, Nushell will no longer hang the terminal on unix systems if an external command is suspended (e.g., via ctrl+z). Instead, Nushell will now display a message and wait for any key press before bringing the suspended process back to the terminal foreground.

Changes [toc]

Additions [toc]

ls --threads [toc]

With #13836, an experimental --threads flag was added to ls. When provided, this flag makes ls use multiple threads (the exact number is currently undefined). In some cases, this significantly reduces the running time of ls.

Enhanced keybinding configuration [toc]

Support for kitty keyboard protocol modifiers.

Thanks to @replcat in #13906, keybindings in your config can now use any combination of the modifiers shift, alt, ctrl, super, hyper, and meta. Note that this requires your terminal to support the kitty keyboard protocol and for the config option $env.config.use_kitty_protocol to be set to true.

Support for Unicode Code Points in Keycodes.

Starting from #14020, users can now specify characters in the keycode field using their Unicode code points, in the format char_uXXXX, where XXXX is the hexadecimal Unicode code point. This provides greater flexibility when configuring keybindings in Nushell.

Specifying Unicode code points can help eliminate confusion when characters from different Unicode blocks look identical but have different code points. For example, by using char_u0041 for the Latin A, char_u0391 for the Greek Α, or char_u0410 for the Cyrillic А, users can accurately define keybindings and avoid ambiguity in configurations.

Key Feature:

The current implementation does not restrict the number of leading zeroes when specifying Unicode code points. For example, the character A can be represented as char_u41, char_u0041, or even char_u000041. However, it is recommended to use four hexadecimal digits (e.g., char_u0041) to improve readability and maintain a consistent format across different configurations. This recommendation follows the standard Unicode representation and helps prevent ambiguity.

Example usage:

$env.config = {
    ...

    keybindings: [
        {
            name: <command_name>, # name of the command
            modifier: none,       # key modifier
            keycode: char_u0391,  # Unicode code for Greek 'Α'
            mode: vi_normal,      # mode in which this binding should work
            event: {
                send: <action>    # action to be performed
            }
        }
    ]

    ...
}

input listen [toc]

The input listen command now supports the kitty keyboard protocol and respects the $env.config.use_kitty_protocol config option. This was added in #13892 thanks to @weirdan.

random bytes and random chars [toc]

random bytes and random chars now support file size values as arguments for the amount/length of data to be generated.

random binary 1kb
random chars --length 1kb

str stats [toc]

After #14014, str stats now outputs an additional stat/column: unicode-width.

sort-by --custom [toc]

See the sorting overhaul section in the highlights.

Breaking changes [toc]

sort-by and sort [toc]

See the sorting overhaul section in the highlights.

Standard Library [toc]

The internal storage location for the standard library, as well as how it is handled during Nushell start-up, has changed to improve launch times. While every effort has been made to ensure backward-compatibility, there may be some corner-cases in how other scripts and modules have imported std in the past.

If you run into an issue, try the following import pattern. Replace log or formats with the module name you are using:

# If the module commands should be "prefixed", e.g., `log warning "Hello"`
use std/log

# When the module's command names should be available in the current namespace
# E.g., `ls | to jsonl`
use std/formats *

Refer to the Standard Library documentation for more information.

Deprecations [toc]

Standard Library std/dirs [toc]

Starting with the next release, Nushell will no longer automatically load the std/dirs aliases at startup (#13842). In 0.99.0, using one of these aliases (n, p, g, enter, dexit, or shells) will result in a warning message.

To disable the warning message and prepare for 0.100.0, add the following to your startup configuration (typically config.nu or env.nu, etc.):

use std/dirs shells-aliases *

See the Shells in Shells chapter of the Book for more options.

Removals [toc]

decode new-base64 and encode new-base64 [toc]

The decode new-base64 and encode new-base64 commands added in the last release have now replaced the previous decode base64 and encode base64 commands as planned with #14018.

group [toc]

With #14056, the group command deprecated back in 0.96.0 has been removed. Please use the chunks command instead.

Bug fixes and other changes [toc]

Prompt to write default config files [toc]

After #13857, Nushell will only prompt the user to write the default config files if the default config directory does not exist. After the first prompt, the default config directory is created regardless of the response so that the user is not prompted again.

Mid-pipeline exit codes [toc]

Some internal commands collect their input which could trigger the non-zero exit code error added in 0.98.0. After, #13899 this has been fixed and only the final command in a pipeline can trigger a non-zero exit code error if it is an external command.

Last exit code [toc]

Fixed $env.LAST_EXIT_CODE not being set to 1 for errors not relating to external commands in #13954.

try [toc]

In #13885, a bug where try did not catch errors when assigned to a variable using let was fixed. In addition, an issue was fixed in #13992 where try would sometimes print values when it was not the last pipeline element.

Parser bugs [toc]

Thanks to @sgvictorino in #14053, several parser bugs related to strings containing equal signs has been fixed.

hash [toc]

The hash commands supported binary input, but their command signatures did not say so. This has been fixed in #13923.

view source [toc]

view source now sets the pipeline metadata to application/x-nuscript after #13859 thanks to @Bahex.

do -p [toc]

Fixed do not waiting for external commands to complete when provided the -p flag in #13881.

format date [toc]

#14037 fixed format date not respecting the current $env.LC_TIME.

save -p [toc]

The progress bar for save -p now updates at a minimum of every 75ms. Before, the progress bar would update at every write, making it hard to read.

Panic fixes [toc]

Thanks to @sgvictorino, panics due to empty record input for inspect and explore were fixed in #13893.

Thanks to @anka-213 in #10395, a parser panic regarding custom command arguments was fixed.

Notes for plugin developers [toc]

There were no changes to the plugin API or protocol in this release. Compiling with the new version or bumping the protocol version should be sufficient to update any plugins.

Hall of fame [toc]

Thanks to all the contributors below for helping us solve issues and improve documentation 🙏

authortitleurl
@NotTheDr01dsAdd search terms to into value#13890
@NotTheDr01dsUpdate merge example#13985
@NotTheDr01dsUpdate wrap example#13986
@NotTheDr01dsRemove superfluous separator when there's no flag description/comment#13993
@Lord-LightSpeedUpdate fill.rs to fix last example given with help#13993
@sdmoralesmaFix example for hide-env#14013
@quadristan[str replace] add example for escaped regexes#14038
@NotTheDr01dsFix --header-row description#14065

Full changelog [toc]

  • ayax79 created
    • Removed CustomValue portion of CustomValue type name strings.
    • polars into-df struct fix
    • Expose flag truncate-ragged-lines in polars open
    • Added command polars len for performing count(*) like operations.
    • Added command polars profile for profiling lazy dataframes
    • Added polars concat to allow concatenation of multiple dataframes
  • WindSoilder created
    • change display_error.exit_code to false
    • Revert "fix $env.FILE_PWD and $env.CURRENT_FILE inside use (#13958)"
    • Making nushell works better with external args which surrounded by backtick quotes
    • fix $env.FILE_PWD and $env.CURRENT_FILE inside use
    • Removes more quotes on external command arguments
    • Bump version to 0.98.1
  • IanManske created
    • Fix deleted lowercase in keybinding parsing
    • Fix try printing when it is not the last pipeline element
    • Refactor config updates
    • Remove group command
    • Make get_env_var return a reference to a Value
    • Fix non-zero exit code errors in middle of pipeline
    • Fix LAST_EXIT_CODE not being set for internal errors
    • Fix try not working with let, etc.
    • Fix do -p not waiting for external commands
  • 132ikl created
    • Ratelimit save command progress bar updates
    • Rework sorting and add cell path and closure comparators to sort-by
  • fdncred created
    • Revert "Add the history import command"
    • make FooterMode::Auto work
    • hard-code selection color to be reverse
    • fix format date by getting the env vars properly
    • update to reedline 5e556bfd
    • update nushell to reedline 871075e
    • add unicode-width to str stats
    • update osc_633 string escaping
    • since windows allows slash or backslash, allow both instead of MAIN_SEPARATOR
    • allow bools to be type checked with each other
    • update human-date-parser crate
    • a potential solution that may fix vt processing
    • ensure toolkit is using external cargo command
    • fix ls_colors coloring in grid and ls
    • update folder_depth algorithm for glob command
    • update the defaults for shell_integration
    • add binary as input to hash commands
    • update reedline to the latest 660a5074
    • Add threads to the ls command in order to increase performance in some circumstances
    • fix the ability to add a plugin by name instead of path
  • qfel created
    • Add the history import command
    • Reduce nesting in the history command code
    • Reduce duplication in history path construction
  • sgvictorino created
    • support filesize arguments in random binary/chars
    • fix unknown_command when parsing certain strings with equal signs
    • fix inspect and explore panics on empty records
  • NotTheDr01ds created
    • Correct wording from previous PR
    • Fix --header-row description
    • Respect use_ansi_coloring setting in banner
    • Virtual std module subdirectories
    • Fix dirs removal warning
    • Load env when importing with use std *
    • Fix operator completion typo and increase consistency
    • Fix namespace collision in std and nupm
    • Set proc/env cwd to engine_state value
    • Remove superfluous separator when there's no flag description/comment
    • Updated warning message for old dirs/shells
    • Improves startup time when using std-lib
    • Update wrap example
    • Update merge example
    • Only ask to create config files the first time nu is started
    • Add search terms to into value
  • quadristan created
    • [umkdir][tests] get umask instead of assuming it
    • [str replace] add example for escaped regexes
  • hustcer created
    • Create Sha256sum file for each release binary
    • Replace the old encode base64 and decode base64 with new-base64 commands
    • Fix typos
    • Simplify the Dockerfile
    • Some small tweaks to release and nightly workflow
    • Add loongarch64-unknown-linux-gnu-gcc build target
  • app/dependabot created
    • Bump crate-ci/typos from 1.25.0 to 1.26.0
    • Bump indexmap from 2.5.0 to 2.6.0
    • Bump tempfile from 3.12.0 to 3.13.0
    • Bump once_cell from 1.19.0 to 1.20.1
    • Bump crate-ci/typos from 1.24.6 to 1.25.0
    • Bump actions-rust-lang/setup-rust-toolchain from 1.10.0 to 1.10.1
    • Bump actions-rust-lang/setup-rust-toolchain from 1.9.0 to 1.10.0
    • Bump rustsec/audit-check from 1.4.1 to 2.0.0
    • Bump crate-ci/typos from 1.24.5 to 1.24.6
    • Bump shadow-rs from 0.34.0 to 0.35.0
    • Bump unicode-segmentation from 1.11.0 to 1.12.0
    • Bump tango-bench from 0.5.0 to 0.6.0
  • 1256-bits created
    • Add ls colors to cjs and mjs files
  • JustForFun88 created
    • Improve keybinding parsing for Unicode support
  • Kither12 created
    • Improve completer
    • escape dollarsign in tab completion
  • sdmoralesma created
    • Fix example for hide-env
  • uek-1 created
    • Add operator completions
  • akirabaruah created
    • Consistent default key bindings for ide_completion_menu
  • zhiburt created
    • nu-table/ Fix footer truncation in case of head_on_border
    • nu-exlore/ Fix :try table view
    • Fix issue with ls | explore coloring of file names
  • Lord-LightSpeed created
    • Update fill.rs to fix last example given with help
  • cptpiepmatz created
    • Make SpanId and RegId also use new ID struct
    • Replace raw usize IDs with new types
  • anka-213 created
    • Fix panic on too few arguments for custom function
  • saurabh10041998 created
    • Fix Docker image build failure
  • fornwall created
    • Bump rustix from 0.38.34 to 0.38.37
  • YizhePKU created
    • Set current working directory at startup
  • weirdan created
    • Respect $env.config.use_kitty_protocol in input listen
  • replcat created
    • Support kitty key modifiers in keybindings
  • nome created
    • Fix handling of stopped TUI applications on unix
  • Bahex created
    • view source: add content_type metadata
  • dead10ck created
    • polars: add binary type support
  • devyn created
    • Bump version to 0.98.0
Edit this page on GitHub
Contributors: Ian Manske, NotTheDr01ds, JustForFun88, Jack Wright, Devyn Cairns