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

Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your commandline. 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 commandline pipelines.

Today, we're releasing version 0.68 of Nu. This is release a rework of modules, a new source-env command, overlay changes, and more.

Where to get it

Nu 0.68 is available as pre-built binaries or from crates.io. If you have Rust installed you can install it using cargo install nu.

If you want all the built-in goodies, you can install cargo install nu --features=extra.

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

Themes of this release

(Major changes!) Rework of modules and environment

Some of the changes here have far-reaching consequences and it might take a while to get the book up to speed.

This release includes a bundle of changes to environment handling and modules. For now, we kept also the old functionality, but in the 0.69, it will be removed. It is therefore recommended to port your scripts and modules to the new style to avoid breakages in the next release. You can read a more complete write-up on the motivation and overall design in this document.

source becomes source-env (Sophia, kubouch)

Note: Since the release we found out that source-env with a dynamic path is not viable and had to make it require a constant string or path, just like source. The command still works as described below but as of 0.68.1, source-env requires a static path as an argument. This is not where our design was supposed to land and we'll be searching for alternatives. We might also postpone the deprecation of the existing module commands beyond 0.69. Thanks for understanding.

One of the most common pitfalls of Nushell was trying to source a dynamic path, such as source ($env.PWD | path join foo.nu). Since Nushell is a "compiled" language where commands and aliases are analyzed while parsing ("compiling") the code, sourcing dynamic paths is not possible for the same reason you cannot dynamically set #include file names in C or use modules in Rust. You can read a bit more about this in our Thinking in Nu book chapter.

To address this pitfall, we decided to change source to source-env which can be used to bring in the environment, but not custom commands, aliases and variables anymore. A benefit of doing so is that it is now possible to pass dynamic paths: source-env ($env.PWD | path join foo.nu) would bring in the environment from the foo.nu file.

How do you bring in commands and aliases without source? You need to use a module and the use keyword. See our book chapter about modules, it's quite simple. Alternatively, you can use overlays.

How do you bring in variables without source? This is not possible anymore. A workaround is to define a command in your module that will return the value you want.

source still continues to work in this release but will be removed in 0.69. In 0.69, we will also change all config files to be modules, not plain scripts.

Module environment changes (kubouch, kubouch)

The way to define environment variables from modules used to be

> module spam {
    export env FOO { 'bar' }
}

> use spam

This example shows one problem: it is easy to end up with namespaced environment variables, which in this case would be $env.'spam FOO'. Another problem with the current design is that use is a parser keyword (like the removed source) but contains both parser ("compiled") and runtime (evaluated) functionality. Since 0.67, it is possible to use modules within other modules but because environment is 100% handled in runtime, and use never evaluates the module itself, it was impossible to bring in environment variables from other modules inside a module.

Long story short, use (and hide) now handle only custom commands and aliases, not environment variables anymore. If you want to bring both environment and commands/aliases, you need to use the source-env and use commands separately (or use overlays).

Also, we simplified defining the environment in modules. Instead of defining environment variables with export env individually, there is a single export-env { } block for the whole module (see the example in the next section).

If you call source-env on that module, the export-env command will get evaluated and its environment kept in the current scope.

# spam.nu

export-env {
    let-env FOO = 'foo'
    let-env BAR = 'bar'
}
> source-env spam.nu

> $env.FOO
foo

> $env.BAR
bar

This release makes export env deprecated and it will be removed in 0.69.

Syntax unification (kubouch)

Previously, modules had some reserved syntax that was not valid in scripts: the export keywords. In this release, we allowed export keywords to be used in scripts (they do nothing: export def acts as def etc.) and thus script syntax is a superset of module syntax.

Modules can now be evaluated. This is the reason the above example with source-env works: Thanks to the unified syntax, source-env will evaluate the module which evaluates the export-env command inside the module.

Another nice thing about the unified syntax is that commands like nu-highlight now do not break or do not need to rely on heuristics if they are asked to parse a module code. Any module code is a valid script code.

Overlay changes (kubouch, WindSoilder)

overlay add and overlay remove are now renamed to overlay use and overlay hide (see the breaking changes later).

The functionality of these commands remains largely the same with one change being that overlay use will now evaluate the export-env { } block. Consider this module:

# spam.nu

export-env {
    load-env {
        FOO: 'foo'
        BAR: 'bar'
    }
}

export def foo [] { 'foo' }
export alias bar = 'bar'

instead of:

> source-env spam.nu

> use spam.nu *

you can do just:

> overlay use spam.nu

You can think of overlay use as calling source-env and use in one command and putting the result into a new overlay.

Summary

Here is a table that summarizes the changes:

commandprevious release (0.67)this release (0.68)next release (0.69)
sourceimports everything into the current scopesame (deprecated)removed
source-envN/Aimports environment variablessame
useimports environment variables, commands and aliasessameimports only commands and aliases
hidehides environment variables, commands and aliasessamehides only commands and aliases
hide-envhides environment variablessamesame
export envdefines a single environment variable in a modulesameremoved
export-envN/A(in a module) defines the environment for the whole modulesame
export-envN/A(in a script) when evaluated, preserves the environment from the blocksame
export ...only allowed in a moduleallowed in a script as wellsame
config.nuplain scriptplain scriptmodule
env.nuplain scriptplain scriptmodule
login.nuplain scriptplain scriptmodule

Allow parentheses around command signatures (Sophia)

To bring more familiarity with other languages, we added the option to define command signatures with parentheses () instead of only braces []:

def foo (x: int) { $x + 100 }

The square braces [] continue to work as well. This change is intended to test it with a larger audience to decide which one we prefer the most.

We added a new command str distance which implements the Levenshtein algorithm fdncred

This example shows that the edit distance is one edit step difference using the Levenshtein algorithm.

> 'nushell' | str distance 'nutshell'
╭──────────┬───╮
│ distance │ 1 │
╰──────────┴───╯

We'd eventually like to add more similarity comparison functionality to nushell.

We added string duration conversion to named durations fdncred

The new parameter on into duration --convert allows you to convert from string durations into named durations.

> '7min' | into duration --convert sec
420 sec

External Completions (experimental) (herlon214, rsteube)

In this release, we're trying out integrating Nushell with external completers, instead of relying solely on Nushell ones. It is possible to set the external_completer field in a config to be a block which will be evaluated if no Nushell completions were found. You can configure the block to run an external completer, such as carapace.

This example should enable carapace external completions:

# config.nu
let carapace_completer = {|spans|
    carapace $spans.0 nushell $spans | from json
}

# The default config record. This is where much of your global configuration is setup.
let-env config = {
    # ... your config
    external_completer: $carapace_completer
}

Note that this functionality is not perfectly polished yet and in some cases the external completer is not triggered correctly (see this issue).

It is also possible to extend the parameters passed to the completer block that are required for other tools than carapace, such as cursor position etc. In theory, this feature could allow you to utilize any existing completions library from any shell, such as bash, as long as you can somehow get a list of completions from them.

Breaking changes

Renaming of all? to all, any? to any, and empty? to is-empty (adamijak)

The ? suffix on the three commands all?, any?, empty? did not indicate a specific meaning across other commands. Other commands returning a boolean value, like str contains for example, don't carry the suffix. To remove a potential source of confusion and to free up the ? for potential use in a more meaningful semantic context, we decided to remove the suffix and rename empty? to is-empty to clarify its role.

Please update your scripts accordingly:

old namenew name
all?all
any?any
empty?is-empty

Renaming overlay commands (WindSoilder)

old namenew name
overlay addoverlay use
overlay removeoverlay hide

The main reason is that the overlay remove does not really remove the overlay. It deactivates it and it can be resumed again from where you left off. Therefore, we felt like hide is a better word to match this functionality and aligns with our existing use and hide keywords.

path split behaviour for Windows paths (merelymyself)

path split no longer returns drive letters and the root directory as separate elements for absolute Windows paths.

Previously, `C:\temp` | path split returned C:, \, and temp. Now it returns C:\ and temp.

Next Steps

We've been progressing with our design towards 0.80 as outlined in this Notion page.

Some time was spent trying out possible new syntax directions but we were not confident to release them yet. In the next release we'll see a removal of features deprecated in this release and we'll continue to push ahead for the 0.80.

Full changelog

Nushell

  • sophiajt created bump to 0.68, and Reverted "Make $ on variable names optional" (just in case), and Allow parens around signatures, and Make $ on variable names optional, and Move from source to source-env
  • sholderbach created Pin reedline to 0.11.0 release, and Terminate REPL if not connected to tty input, and Fix search terms for str distance, and [Experiment] Reenable CI build cache for tests, and Test command names and search terms for redundancy
  • merelymyself created let path split keeps 'C:' together, and Allow for rejecting nested record cells, and add tests, deal with pipes, newlines, tabs for to nuon, and preserve space by letting to nuon only add quotes when necessary, and let to nuon convert column names with spaces, and default to file completion after first command, add command option for completions
  • unrelentingtech created Avoid update_last_command_context "No command run" error, and Fix build on *BSD, illumos, etc.
  • WindSoilder created Restrict plugin name starts with nu_plugin_, and remove capnp relative file, and shows wrong item when some commands runs to failed., and shows wrong item when each command runs to failed., and keep raw for variable inputted argument, and remove capnp protocol for plugin..., and Try to make argument with quotes for external command better, and Plugin: Add benchmark for different encoding protocol, and Rename overlay commands, and Try again: in unix like system, set foreground process while running external command
  • kubouch created Disable cyclical module imports, and Fix overlays not preserving hidden env vars, and Fix scoped overlay use not finding a module, and Bring in module's environment when activating overlay, and Allow "export-env" parsing in modules, and Allow parsing modules as scripts, and Add export-env command
  • adamijak created Rename all?, any? and empty?
  • dependabot[bot] created Bump lz4-sys from 1.9.3 to 1.9.4, and Bump iana-time-zone from 0.1.44 to 0.1.47
  • obaudys created Fix ps command CPU usage on Apple Silicon M1 macs. #4142
  • fdncred created Revert "Add support for optional list stream output formatting", and add more color highlighting to help, and add the ast command to peek at the internals of nushell, and convert string duration to named duration, and add a plugin registration script, and add another split words example, and add edit distance/levenshtein command, and add MessagePack as a plugin protocol, and fix the way lists are rendered in markdown, and add a split words command, and create clickable links in ls output if configured
  • rgwood created Upgrade which dependency to fix case on Windows, and Disable clickable links in SSH sessions, and Always report errors in cp, and Make cp errors more specific+accurate, and Add pause and cls to cmd.exe exceptions
  • dscottboggs created better error handling for nu_command::env::config::utils::get_editor
  • nibon7 created Make run_external parameter required, and Fix the span of "invalid time zone", and register-plugin.nu: refactor register plugin, and register-plugin.nu: remove .exe extension match to simplify code, and Add test cases for $nu.config-path change, and Get $nu.config-path and $nu.env-path from EngineState, and Use string interpolation to construct log file path, and Return error when kill didn't terminate successfully
  • herlon214 created nu-command/filters: drop column check positive value, and nu-cli: merge completions tests into one file, and feat: external completions for commands/flags
  • hustcer created Update nu version for release workflow, and Bump dev version
  • volucris1 created Fix #6330
  • panicbit created Add support for optional list stream output formatting
  • dbuch created Fix slice indexing
  • CohenAriel created Add --execute option

Documentation

  • rgwood created Add Homebrew PATH documentation
  • sholderbach created Update former question mark commands in docs
  • chrjen created Update types_of_data.md with missing values
  • hustcer created Upgrade vuepress and all related plugins to improve build performance, and Upgrade all vuepress plugins and fix doc search navigation by pressing enter key, and Upgrade all vuepress plugins and fix doc search navigation by pressing enter key, and Try to fix deploy of docs by downgrade some plugins, and lock vuepress and plugins version to fix ci
  • fdncred created update to ubuntu-latest, and change from deprecated version of ubuntu
  • pedromfedricci created Update accepted types for signatures
  • Yethal created Add wrap-around merge
  • merelymyself created Remove ambiguity about command quotes
  • CAD97 created Note status of calling CMD builtins from Nushell, and Note Windows caveat in Escaping to the System, and Mention coming_from_cmd in coming_to_nu, and Update coming_from_cmd.md for nu 0.77, and Create coming_from_cmd.md
  • 1submarine created correct escapes in coming_from_bash.md, and deduplicate `**' in operators.md
  • amtoine created FIX: overlay remove flags

Nu Scripts

  • dandavison created Async git prompt
  • sholderbach created Update old question mark commands any?/all?/empty? to any/all/is-empty
  • skelly37 created Added German diacritics
  • Yethal created Add function to remove diacritics from string
  • fdncred created remove engine-q references
  • e2dk4r created custom completions: scoop: add some missing command completions, and custom completions: scoop: add some missing command completions
  • mk00pl created added webscrapping script for twitter
  • azzamsa created fix: zoxide support Nushell out of the box

reedline

  • sholderbach created Prepare 0.11.0 release
  • unrelentingtech created Add Reedline::has_last_command_context to allow checking if update_last_command_context will fail
  • nibon7 created Fix panic when using sqlite as history backend
  • morzel85 created README.md outline cleanup
Edit this page on GitHub
Contributors: fdncred, Justin Ma, sholderbach, Christer Jensen, Reilly Wood, kubouch, jntrnr, Jakub Žádník, Ian Manske, sophiajt