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

Today, we're releasing version 0.115.1 of Nu. This patch release improves completions, adds Helix keybinding support, and fixes issues with semver comparisons, $ans, SQLite table updates, and keybinding merging.

Where to get it

Nu 0.115.1 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 Nushell.

Table of contents

Changes [toc]

Additions [toc]

Add HelixChangeMode keybinding support [toc]

PR #18878 by @kronberger-droid

Keybindings can now switch helix modes with { send: HelixChangeMode, mode: normal }, taking normal, insert or select. An until list covers vi and helix in one binding, since a mode event is inapplicable in the other editor's state machine:

$env.config.keybindings ++= [
  {
    name: leave_insert_mode
    modifier: control
    keycode: char_g
    mode: [vi_insert helix_insert]
    event: { until: [
      { send: ViChangeMode, mode: normal }
      { send: HelixChangeMode, mode: normal }
    ] }
  }
]

Add background-completions opt-out [toc]

PR #18764 by @kronberger-droid

Added the background-completions experimental option (enabled by default). Disabling it makes completions block the line editor again, which lets custom completers drive interactive child processes like fzf:

nu --experimental-options '[background-completions=false]'

Other changes [toc]

Interactive pickers in completions [toc]

PR #18881 by @fdncred

Tab completion can run an interactive picker from $env.config.completions.external.completer (and from custom @comp / @complete closures). Closures such as fzf or input list take the TTY while the line editor waits. Completers that only print a list should still return quickly.

After input list (or a similar picker) returns from a completion or a custom menu, the prompt keeps raw mode. Backspace and other editing keys work again.

Subprocesses spawned from a background completion thread stay detached from the terminal even when their stdin is a pipe, so they cannot steal the TTY from the line editor.

Tab waits for the external completer [toc]

PR #18881 by @fdncred

When $env.config.completions.external.completer is set, Tab on an external command waits for that closure before the line editor continues. That lets a picker such as fzf or input list take the terminal. Completers that only print a list (for example Carapace) should return quickly; a slow closure freezes the prompt until it finishes.

File and command-name completion still run in the background. Custom menu source closures were already synchronous.

To make every Tab wait, not only user completers:

nu --experimental-options '[background-completions=false]'

Results from the external completer and from @comp / @complete are not cached, so a picker runs again on the next Tab.

Bug fixes [toc]

Fixed semver (and other custom) comparisons not working in boolean expressions [toc]

PR #18854 by @fdncred

Comparing two semver values already returned a bool at runtime, but the parser treated that result as a semver. Combining it with or / and, binding it with let, or passing it to a bool parameter failed.

Those now work:

# missing or out of date
(which crush | is-empty) or ((crush --version | into semver) < ('1.0.0' | into semver))

let outdated = ('0.9.0' | into semver) < ('1.0.0' | into semver)
# $outdated is bool

true or (('1.2.3' | into semver) in ('>=1.0.0' | into semver-range))

The same applies to other custom values whose comparisons return a bool (for example matrix). Custom types that return another custom value from < / == (polars expressions) are unchanged.

A raw custom value is still not a bool: true or ('1.0.0' | into semver) remains a type error.

Fix $ans after invalid operations on $ans.last [toc]

PR #18863 by @fdncred

$ans stays usable after a type error on $ans.last

Invalid operations on $ans.last that embed type errors as values (for example $ans.last | str length on a table) no longer replace $ans.last or break later $ans display.

This mainly showed up with table --expand as the display_output hook.

$env.config.max_last_result_size = 1mb

ls
# table of files

$ans.last | str length
# Error: nu::shell::only_supports_this_input_type
# (still printed — the command is invalid)

$ans
# record with the original ls table in `.last` — no longer reprints the type error

$ans.last
# still the ls table

$ans.exit_code, $ans.duration, and $ans.command still update for the failed line. Results that mix real values and errors still replace $ans.last. Top-level table --expand on a list of errors still shows the original diagnostic.

Fix update closures on lazy SQLite tables [toc]

PR #18865 by @fdncred

update with a closure now works on a table taken from an opened SQLite database. open foo.db | get my_table is a lazy query; it already printed as a table, but update col { ... } reported a missing column instead of transforming each row.

[{ key: test, created: 1787132290545485211, expiry: 1787139010545500670, value: [7, 2, 128] }]
| into sqlite --table-name std_cache_store test.db

open test.db | get std_cache_store | update expiry { into datetime }
# table with `expiry` as datetime
open sample.db | get ints | update z { default 0 | $in + 1 }
# each `z` value is incremented

Fix $env.config.keybindings merging for shared names [toc]

PR #18870 by @kronberger-droid

Fixed an issue where two keybindings sharing a name on different keys silently dropped one of them (broke atuin's ctrl-r). Nushell now warns once when keybindings share a name, matches mode spellings like emacs and [emacs] when merging, and $env.config.keybindings = [] clears the list again.

Fix completions for cd and custom completers [toc]

PR #18868 by @philocalyst

Fixed completions for empty directory-typed arguments such as cd <tab> so they suggest directories instead of all paths.

Custom completers that error, return no result, or try to run interactive input commands now gracefully fall back to file completions instead of leaving the completion list empty or racing the line editor for terminal input.

commandline complete now includes a type: null field for completion items that do not have a more specific type.

Hall of fame [toc]

Thanks to all the contributors below for helping us solve issues, improve documentation, refactor code, and more! 🙏

authorchangelink
@cptpiepmatzFix test by removing printf calls#18883

Full changelog [toc]

authortitlelink
@app/dependabotbuild(deps): bump hustcer/setup-nu from 3.26 to 3.27#18857
@ayax79Update h2 do to RUSTSEC-2026-0258#18875
@cptpiepmatzBump patch version after release#18845
@cptpiepmatzFix test by removing printf calls#18883
@fdncredallow boolean comparison with semver#18854
@fdncredallow $ans to still work after invalid operation#18863
@fdncredfix update to work better with custom values#18865
@fdncredfix(completions): keep the REPL usable when a completer runs fzf or input list#18881
@kronberger-droidfeat(completions): add a background-completions opt-out#18764
@kronberger-droidfix(config): merge keybindings by name and key instead of name alone#18870
@kronberger-droidchore(reedline): bump reedline to e692224#18878
@philocalystCompleter Fixes#18868
Edit this page on GitHub
Contributors: Piepmatz