Nushell 0.116.1
Today, we're releasing version 0.116.1 of Nu. This patch release improves TUI widgets with live stream updates, customizable borders and titles, and more reliable pane resizing, while fixing completions and refining startup-time reporting.
Where to get it
Nu 0.116.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]
Deprecations [toc]
Deprecation: tui label --title is now tui label --titlebar [toc]
To put a label in the top bar, use tui label --titlebar "My app" instead of tui label --title "My app". The old switch still works but warns on first use and is scheduled for removal in 0.118.0.
Additions [toc]
Widgets can set their border title with --title [toc]
Use --title <text> to name the border of tui table, tui tree, tui select, tui log, tui preview, tui search, or tui textbox. The title replaces the widget's default name, while row counts and status indicators remain visible. For example:
ls | tui table --title files | tui runThe table's border now reads files (12) rather than table (12) when it has 12 rows. For tui preview, the previewed filename follows the custom title, as in files (Cargo.toml); without a file to preview, only the custom title appears. For tui search, the title also becomes the default placeholder unless --placeholder is set. An empty --title is rejected.
Choose tui border lines with --border or $env.config.tui.border_type [toc]
Bordered TUI widgets now accept --border <name> to change their outline. This includes tui table, tui tree, tui select, tui log, tui preview, tui search, tui textbox, tui box, and the dropdowns opened by tui menu. The names match table --theme options, and the flag offers completion for valid border names.
ls | tui table --border rounded | tui run
$env.config.tui.border_type = "double"
ls | tui table | tui run$env.config.tui.border_type sets the default for all TUI borders, including menu dropdowns and dialog frames. An individual widget's --border overrides it. The default is single, which preserves the previous appearance. For example, rounded draws ╭─╮, double draws ╔═╗, and heavy draws ┏━┓; styles such as basic, dots, and markdown are available too.
none and default are not valid TUI border names. Use frameless for an outline with no visible lines: it still occupies one cell, and the widget's title remains visible. When a widget has its own --border, its widgets record includes the selected border name.
Bug fixes [toc]
TUI widgets now display streamed data as it arrives [toc]
Slow and endless streams now update TUI widgets while tui run is open. A log displays each row as it arrives, and a progress bar advances as its input runs instead of starting at 100%:
1.. | each {|n| sleep 1sec; $n} | tui log | tui runThis also works for streams piped into widgets in a child list, such as tui split [(tail -f app.log | tui log) (ls | tui table)].
TUI builders now always output a tui value: piping one into a non-TUI command, such as 1.. | tui table | first, no longer returns the input rows. A TUI value saved with let reads its stream on the first run. If the stream finishes, later runs display the same rows; if it stops early, later runs display no rows. When a tui run closure, tui bind, button, or menu hook returns data, that data replaces the piped data for the rest of the run, without additional rows arriving from the stream.
Streams now keep around 100,000 of their newest rows, dropping older rows in batches of 12,500. Up to 12,499 extra rows can appear between drops, and tui log --max-lines can raise the limit further. Piping data into a child list whose widgets all specify --data now produces an error instead of silently ignoring the input.
TUI split panes now resize reliably with keyboard and mouse [toc]
After focusing a tui split with Tab, the arrow keys or h/j/k/l move its first divider in either direction. Each press moves it one cell on splits up to 100 cells wide or tall when there is room; on larger splits, a press may move it a few cells. This works for both the default side-by-side layout and --vertical, including short splits where resizing previously got stuck.
ls | tui split [(tui table) (tui preview)] | tui run
ls | tui split [(tui table) (tui preview)] --vertical | tui runDragging a divider with the mouse now places it as close to the pointer as the surrounding panes allow, including dividers between later panes in a split. Resizing preserves at least one cell for every pane, and fixed-height splits such as a row of buttons no longer respond to keyboard resizing.
Completion menus stay open when nothing matches [toc] PR #19129 by @kronberger-droid
An open completion menu no longer closes when the typed text stops matching. It shows NO RECORDS FOUND and fills again once the text matches, as it did before 0.116. Cancelling an @interactive picker with Esc now closes its menu right away, and Tab on the same line opens the picker again.
Startup time now starts inside Nushell and is available throughout startup [toc]
$nu.startup-time is now measured from the start of Nushell's main function, rather than from when the operating system created the process. It no longer includes the time spent loading the executable and its libraries, and exec nu starts a fresh measurement instead of carrying over the previous program's time. This applies across platforms.
Before startup finishes, $nu.startup-time now contains the elapsed startup time instead of -1ns. It is available in config files, -e commands, and the --mcp, --lsp, --dap, and --ide-check modes. The --ide-hover, --ide-complete, --ide-goto-def, and --ide-ast modes can now also access $nu, enabling type information for constants built from it and completion of $nu fields. Config files loaded with nu --mcp now see $nu.is-mcp as true.
With --log-level perf, the "before main" line is gone. The final REPL startup line is labeled "startup (main to first prompt)", and the --mcp and --lsp startup lines no longer include the time spent serving the rest of the session.
Other fixes [toc]
- Fixed some incorrect cell path parsing. (#19112)
- Fixed a regression since 0.115 where custom completers on a
def --wrappedrest parameter were not called for arguments starting with-, sowhat --<Tab>only offered declared flags. (#19130)
Other changes
Changed tui records [toc]
For scripts that inspect TUI values, a titled widget now has a title field in its widgets record, and a top-bar label's slot is now titlebar instead of title. When nothing is being previewed, values.<preview id>.title is now an empty string rather than preview.
Hall of fame [toc]
Thanks to all the contributors below for helping us solve issues, improve documentation, refactor code, and more! 🙏
Full changelog [toc]
| author | title | link |
|---|---|---|
| @app/dependabot | build(deps): bump taiki-e/install-action from 2.87.17 to 2.87.21 | #19117 |
| @app/dependabot | build(deps): bump crate-ci/typos from 1.50.2 to 1.50.3 | #19118 |
| @app/dependabot | build(deps): bump mq-markdown from 0.8.4 to 0.9.1 | #19119 |
| @fdncred | fix(tui): builders no longer read piped streams, so slow streams show live | #19099 |
| @fdncred | feat(tui): --border and $env.config.tui.border_type pick border lines by table --theme name | #19100 |
| @fdncred | fix(tui): arrow keys resize tui split panes in both directions | #19101 |
| @fdncred | feat(tui): --title renames a widget's border; tui label --title becomes --titlebar | #19102 |
| @fdncred | Update cell_path.rs | #19112 |
| @fdncred | fix(startup): time nushell from main like bash and zsh, fix exec | #19136 |
| @kronberger-droid | chore: bump reedline to d7bcb12 | #19123 |
| @kronberger-droid | fix(completions): keep menus open on no match, let cancelled pickers close and reopen | #19129 |
| @kronberger-droid | fix(completions): run a wrapped rest completer on flag-like tokens | #19130 |