Nushell 0.87.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.87.0 of Nu. This release focussed heavily on improving internals, fills a few gaps in our command set and completion handling, and starts work on an integrated LSP language server.

Where to get it

Nu 0.87.0 is available as pre-built binariesopen in new window or from crates.ioopen in new window. If you have Rust installed you can install it using cargo install nu.

Note

The optional dataframe functionality is available by cargo install nu --features=dataframe.

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 content

Themes of this release / New features [toc]

Hall of fame [toc]

Bug fixes [toc]

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

authordescriptionurl
@hustceropen in new windowFix winget release submission error#10757open in new window
@sophiajtopen in new windowfix the flag type on release-pkg.nu#10762open in new window
@fdncredopen in new windowupdate release-pkg.nu with updated manual instructions#10759open in new window
@amtoineopen in new windowremove the last mention to let-env#10718open in new window
@hustceropen in new windowUpdate Nushell version to v0.86 for release script#10797open in new window
@stfaccopen in new windowDo not use white text in the default light theme#10796open in new window
@sholderbachopen in new windowRevert "Bump regex from 1.9.6 to 1.10.2"#10818open in new window
@fdncredopen in new windowfix main not building due to errors later found in describe#10821open in new window
@hudclarkopen in new windowfix: Ensure consistent vals and cols when parsing with --flexible#10814open in new window
@gaetschwartzopen in new windowFix describe -d for lazy records#10836open in new window
@fdncredopen in new windowupdated NU_LIB_DIRS delimiter for command line#10837open in new window
@WindSoilderopen in new windowredirection: fix internal commands error with o+e> redirection#10816open in new window
@amtoineopen in new windowsync $env.config.filesize.metric#10277open in new window
@michel-slmopen in new window[nu-cmd-base] add missing LICENSE text#10855open in new window
@amtoineopen in new windowuse to_lowercase in str downcase#10850open in new window
@lavafrothopen in new windowfix: preserve path when completing intermediate directory#10831open in new window
@CAD97open in new windowImprove case insensitivity consistency#10884open in new window
@stfaccopen in new windowAdd "shape_keyword" to default config#10922open in new window
@KAAtheWiseGitopen in new windowFix issues with error make refactor#10950open in new window
@hustceropen in new windowFix alpine docker file#10992open in new window
@gaetschwartzopen in new windowFix tests for cargo.exe check command#11022open in new window
@FMotallebopen in new windowFix (http) get HTTP_PROXY from $env#11026open in new window
@fdncredopen in new windowallow items to properly evaluate block settings#10980open in new window
@WindSoilderopen in new windowfix custom command's default value#11043open in new window

Enhancing the documentation [toc]

Thanks to all the contributors below for helping us making the documentation of Nushell commands better 🙏

authordescriptionurl
@Hofer-Julianopen in new windowAdd long options for misc and network#10753open in new window
@Hofer-Julianopen in new windowAdd long options for generators and math#10752open in new window
@Hofer-Julianopen in new windowAdd long options for platform and random#10776open in new window
@Hofer-Julianopen in new windowAdd long options for path#10775open in new window
@Hofer-Julianopen in new windowUse long options for string#10777open in new window
@Hofer-Julianopen in new windowAdd long options for viewers#10787open in new window
@KAAtheWiseGitopen in new windowChange category of scope commands to core#10892open in new window
@dzoryaopen in new windowbetter help message for MissingPositional error#10949open in new window
@drbrainopen in new windowShow plugin extra usage and search terms#10952open in new window
@drbrainopen in new windowUpdate description and error types for split-by#10865open in new window
@fdncredopen in new windowupdate items example to send data through the pipeline#10976open in new window
@sholderbachopen in new windowSpell out our platform support policy#10778open in new window

Changes to the internals of Nushell [toc]

Thanks to all the contributors below for helping us making the source base of Nushell better and helping with the general development process of the project 🙏

authordescriptionurl
@WindSoilderopen in new windowRefactor: simplify lex_item impl#10744open in new window
@WindSoilderopen in new windowRefactor: remove duplicate code to simplify lite_parsing logic.#10735open in new window
@lavafrothopen in new windowExtract common logic for setting error in parse_short_flags#10709open in new window
@amtoineopen in new windowadd toolkit run to run a Nushell revision#10687open in new window
@CAD97open in new windowRemove registry clean_string hack#10804open in new window
@sholderbachopen in new windowConvert more examples and tests to record! macro#10840open in new window
@sholderbachopen in new windowAdd common map-like API to nu_protocol::Record#10841open in new window
@sholderbachopen in new windowAdd Record::remove/retain/retain_mut#10876open in new window
@sholderbachopen in new windowConvert "pure" macros to pure fn in config.rs#10893open in new window
@IanManskeopen in new windowReuse Closure type in Value::Closure#10894open in new window
@WindSoilderopen in new windowRefactor: introduce a gen_save_call function to reduce duplicate code#10852open in new window
@IanManskeopen in new windowMake FromValue take owned Values#10900open in new window
@sholderbachopen in new windowUse Record APIs in nu-protocol/nu-engine#10917open in new window
@IanManskeopen in new windowReduce element shifting in Record::retain_mut#10915open in new window
@fdncredopen in new windowremove unwraps in registry_query command#10936open in new window
@drbrainopen in new windowRestore test_config tests#10954open in new window
@fdncredopen in new windowupdates trash dependency to 3.1.2#10965open in new window
@fdncredopen in new windowremove unnecessary files#10966open in new window
@drbrainopen in new windowConvert ShellError::UnsupportedInput to named fields#10971open in new window
@IanManskeopen in new windowUse Vec for Closure captures#10940open in new window
@sholderbachopen in new windowRefactor find in terms of clean Record API#10929open in new window
@sholderbachopen in new windowRefactor table cmd and nu-table with Record API#10930open in new window
@drbrainopen in new windowConvert ShellError::DatetimeParseError to named fields#10991open in new window
@sholderbachopen in new windowUse Record's public API in a bunch of places#10927open in new window
@sholderbachopen in new windowRefactor and fix Config<->Value mechanism#10896open in new window
@IanManskeopen in new windowUse Record::get instead of Value functions#10925open in new window
@sholderbachopen in new windowAdd Record::drain to take out elements by range#11002open in new window
@sholderbachopen in new windowUse record API in more parts of nu-protocol#10928open in new window
@IanManskeopen in new windowRefactor env conversion to eliminate Value::follow_cell_path_not_from_user_input#10926open in new window
@sholderbachopen in new windowAdd Record::truncate for trimming based on len#11004open in new window
@IanManskeopen in new windowRefactor drop columns to fix issues#10903open in new window
@drbrainopen in new windowMatch toolkit clippy settings to CI clippy settings#10984open in new window
@IanManskeopen in new windowRefactor flatten command#11017open in new window
@IanManskeopen in new windowImplement Display for CellPath#11023open in new window
@CAD97open in new windowLimit run-external --redirect-combine sh test to not(Windows)#10905open in new window
@KAAtheWiseGitopen in new windowAdd special error case for alias#10975open in new window

LSP is coming to Nushell [toc]

IDE support has been and still is one of the big goals for Nushell 1.0: a modern language needs to have proper language support to unlock pleasant and fast development with it 😄

In #10990open in new window, @fdncredopen in new window made the shell integration with VS Code better.

WARNING

The rest of this section is in the early stages of its development. It will require time to mature and be fully featured, but we're happy to ship it with Nushell as of now.

Thanks to @schrieveslaachopen in new window and #10723open in new window, LSP is now coming to Nushell!

As Cargo comes with Rust, we want Nushell to embed its language support one way or another. The goal is to make nu fully featured and capable of handling LSP, formatting, and testing without any extra installation by default.

#10723open in new window integrates a Language Server Protocol (LSP) implementation directly inside Nushell. Running

nu --lsp

will start the language server.

When properly configured in an IDE, the server can be run and then a client can attach to it and query things like diagnostics, completions, and more in the future.

A very incomplete example, just to give you an idea, could be the following to setup nu --lsp as a language server in Neovim:

configs.nulsp = {
    default_config = {
        cmd = { "nu", "--lsp" },
        filetypes = { "nu" },
        root_dir = function(fname)
            ...
        end
    },
}

Living in the terminal: completions and hints [toc]

Thanks to @lavafrothopen in new window in #10898open in new window Nushell will now fall back to the builtin default completer when external completers are defined but return no results for the current command.

Note

The following example is fictitious, carapace-bin should be able to complete it 😉

Let's say you have Carapaceopen in new window setup as an external completeropen in new window but it is not able to autocomplete git comm<TAB>, then Nushell will try to do it.

Because most commands make sense only in the directory they were run in, @p00fopen in new window wrote #10780open in new window which will make hints aware of the current directory.

Note

Hints are the shadowed incomplete completions that appear when you start typing commands, e.g. if you were to run echo foo bar baz, pressing echo would then show foo bar baz in a dimmed font: this is a hint.

Handling exotic paths [toc]

As can be seen in #10571open in new window , #10364open in new window , #10211open in new window , #9558open in new window, #9310open in new window and probably more related issues and duplicates, handling exotic filenames and filesystem paths, e.g. containing globbing characters or looking like command options, is a non-trivial problem to solve.

As part of this new release, @lavafrothopen in new window and @bobhyopen in new window have worked in the direction of making this experience better in Nushell:

  • files that look like command options, i.e. starting with - or -- will be correctly escaped in completions with #10721open in new window
  • with #10694open in new window commands such as cp, rm, or mv will first look at files from the input paths as the literal string and then, only if the literal file does not exist, they will expand the globbing and work on the resulting found files

e.g. let's say I created a bunch of files, one of them containing an obvious globbing pattern

touch *.txt foo.txt bar.txt baz.txt
  • running rm *.txt once will only remove *.txt and leave the three {foo,bar,baz}.txt files
  • running rm *.txt a second time will remove all the other files

TIP

The first time *.txt is interpreted as a literal and the *.txt file is found and removed. The second time *.txt is not found as a literal filename. rm searches for *.txt as a glob pattern; finds foo.txt, bar.txt, and baz.txt; and removes them.

Improving the match command [toc]

Can we all agree for one moment that match is a great command?

def work-on-list []: any -> string {
    match $in {
        [$x, ..] if $x == 1 => { 'good list' },
        [..] => { 'not a very good list' },
        _ => { 'not a list at all' }
    }
}
> [1, 2, 3] | work-on-list
good list
> [2, 1, 3] | work-on-list
not a very good list
> "ehe i'm not a list" | work-on-list
not a list at all

However, it had a pretty big flaw: it was not able to work on null values 😮

> match null { null => "success", _ => "failure" }
failure

In #10829open in new window, thanks to @hudclarkopen in new window, the match command is now able to work properly on null values.

> match null { null => "success", _ => "failure" }
success

Pipeline redirections [toc]

Once again @WindSoilderopen in new window has been working on pipeline redirections. Because they need to be given a target path to properly function, i.e.

echo aaa o> | ignore

does not make sense in itself, #10835open in new window makes commands such as the one just above throw a nice error:

Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #1:1:1]
 1 echo aaa o> | ignore
   ·          ─┬
   ·           ╰── expected redirection target
   ╰────

The following will still function as expected:

echo aaa o> foo.txt | ignore

Some work on the standard library [toc]

@amtoineopen in new window made the use of std 'path add' better in #10710open in new window. Now this command that allows adding paths to the $env.PATH environment variable will (1) expand all the input paths to get only absolute paths and (2) split $env.PATH on : to make sure the command runs properly the first time it runs in the configuration.

Note

If Bash is still your login shell, the value of $env.PATH in env.nu might be a :-separated list of system paths. This change to std 'path add' should help prevent the final $env.PATH from containing this original :-separated list of paths.

A new candidate to the standard library, null-streamopen in new window, has been added by @Hullabaloo-and-Howdy-Doopen in new window in nushell/nu_scripts#649open in new window

New allowed operands to the modulo operator [toc]

When doing maths, modulo is a ubiquitous operator, e.g.

> (11 + 5) mod 7
2
> (123 * 456) mod 13
6

However, this operation was only possible on int and float values. As durations are so similar to integers and real numbers, i.e. they are just numbers with a simple unit, @gaetschwartzopen in new window implemented the mod operator of Nushell for durations in #10745open in new window.

Thanks to their work, Nushell will now allow the following command:

> (2min + 31sec) mod 20sec
11sec

Disallowing invalid table definitions and manipulations [toc]

As can be seen in #11020open in new window and #10875open in new window, Nushell will let you define or manipulate tables that have columns called the same. Starting the effort to fix these unexpected and error-prone behaviors, @sholderbachopen in new window disallowed the definition of table literals with duplicated columns in #10875open in new window.

Trying to define the following ill-defined table

[[a a]; [1 2]]

will result in an error from now onwards.

Error: nu::shell::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
   ╰────

The documentation becomes better [toc]

This section sheds some light on some of the contributions from Enhancing the documentation.

PluginSignature test 1 for plugin. Returns Value::Nothing

Extra usage for nu-example-1

Search terms: example

Usage:
  > nu-example-1 {flags} <a> <b> (opt) ...(rest)

Flags:
  -h, --help - Display the help message for this command
  -f, --flag - a flag for the signature
  -n, --named <String> - named string

Parameters:
  a <int>: required integer value
  b <string>: required string value
  opt <int>: Optional number (optional)
  ...rest <string>: rest value string

Examples:
  running example with an int value and string value
  > nu-example-1 3 bb

Some progress in the "dataframe" department [toc]

Thanks again to @ayax79open in new window who has been working on the dataframes.

Our set of commands is evolving [toc]

As usual, new release rhymes with changes to commands!

New commands [toc]

Changes to existing commands [toc]

error make {
    msg: "Message"
    label: {
        text: "Label text"
        span: (metadata $var).span
    }
}

Deprecated commands [toc]

Removed commands [toc]

Breaking changes [toc]

Full changelog [toc]

Nushell

Extension

Documentation

Nu_Scripts

Reedline