Nushell 0.100.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.100.0 of Nu. In addition to being a major milestone, this release adds two new operators for working with strings, fixes division and modulo quirks, improves plugin management, and includes a very large number of other minor improvements and fixes.
Where to get it
Nu 0.100.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
- Nushell 0.100.0
- Where to get it
- Table of contents
- Highlights and themes of this release [toc]
- Changes [toc]
- Additions [toc]
history import
[toc]catch
error record [toc]url split-query
[toc]help commands
andscope commands
[toc]ps -l
[toc]url join
andurl build-query
[toc]touch --no-deref
[toc]length
stor
[toc]to text --no-newline
[toc]open --raw
[toc]help
[toc]$env.config.table.footer_inheritance
[toc]- Function key keybindings [toc]
- Breaking changes [toc]
- Deprecations [toc]
- Removals [toc]
- Bug fixes and other changes [toc]
return
,break
, andcontinue
[toc]- External command bareword arguments [toc]
to text
[toc]to nuon
[toc]use
[toc]transpose
[toc]- Constants with type signatures [toc]
- Short flag type checking [toc]
- Cell path pretty printing [toc]
in $range
[toc]into datetime
[toc]ansi -l
[toc]join
[toc]- Table literals as arguments [toc]
clear
[toc]- Prefer
$env.VISUAL
over$env.EDITOR
[toc] - Fix handling of exported external aliases [toc]
- Panic fixes [toc]
- Additions [toc]
- Hall of fame [toc]
- All breaking changes [toc]
- Full changelog [toc]
Highlights and themes of this release [toc]
Cheers to a century! [toc]
We wish to express our heartfelt gratitude and congratulations to all of our contributors and users on releasing version 0.100.0! Thanks for sticking with us and making Nushell great. Here's to a hundred more! 🎉
After this release, we will be switching to a 6-week release schedule instead of our current 4-week one. This will allow us to focus more on making and merging changes, and giving major changes room to breathe.
like
and not-like
operators [toc]
With #14072, this release adds two "new" operators: like
and not-like
. These operators are alternative forms of the preexisting =~
and !~
operators, respectively. The only reason to use one form over the other is preference. For example, people familiar with SQL may prefer using like
and not-like
. In the future, there is a chance that the shorter forms may be removed, but there are no plans to do so yet, if at all.
Division, floor division, and mod
[toc]
Breaking change
See a full overview of the breaking changes
In #14157, several changes were made to the division related operators to make them more consistent.
Division
First, division between two integers used to be able to return either an int or a float value even though the type signature claimed the result would always be a float.
(1 / 2 | describe) == float
(2 / 2 | describe) == int
This release changes division between any two types to always return a float except if the left hand side is a filesize or duration and the right hand side is an int or float.
(1 / 2 | describe) == float
(2 / 2 | describe) == float
(1KB / 1KB | describe) == float
(2sec / 2sec | describe) == float
# There is no floating point representation for filesizes and durations,
# so truncating division is used in this case.
(5B / 2) == 2B
(2sec / 2.0) == 1sec
Floor division
Second, floor division now does automatic float promotion. That is, if one of the operands is a float, and the other is an int or float, then the result will be a float. This matches the behavior of other operators like addition and multiplication which do float promotion as well. It also avoids potential overflows when trying to convert a large magnitude float into an int.
# Before
(1 // 1 | describe) == int
(1 // 1.0 | describe) == int
(1.0 // 1.0 | describe) == int
# After
(1 // 1 | describe) == int
(1 // 1.0 | describe) == float
(1.0 // 1.0 | describe) == float
Additionally, the previous implementation of floor division performed unnecessary clamping which has been fixed with this release. So, results should now be more accurate.
mod
In previous releases, the implementation of mod
was based off of truncating division even though Nushell does not have a truncating division operator. This release changes mod
to be based off of floor division so that mod
and floor division in combination can satisfy the division rule:
let quotient = $n // $d
let remainder = $n mod $d
$n == $quotient * $d + $remainder
If the signs of the divisor and dividend are the same, then the result of mod
will be the same as before. However, if the signs are not the same, then the result of mod
will be different compared to before to satisfy the division rule.
# Before
let q = 8 // -3 # -3
let r = 8 mod -3 # 2
8 == $q * -3 + $r # false
# After
let q = 8 // -3 # -3
let r = 8 mod -3 # -1
8 == $q * -3 + $r # true
This matches the behavior of Python's //
and %
operators which were the original inspiration.
Otherwise, the implementation of all the division related operators has been improved to account for overflow. Rather than silently clamping or overflowing, the operators will now create an error in these cases.
plugin list
improvements [toc]
Breaking change
See a full overview of the breaking changes
The plugin list
command has been changed in #14085 to consider both the plugins currently present in the engine state as well as the plugins stored in the registry file. Changes made by plugin add
and plugin rm
should now be more obvious.
As part of this change, the is_running
column has been replaced by a status
column, which now displays many possible states a plugin can be in:
added
: The plugin is present in the plugin registry file, but not in the engine.loaded
: The plugin is present both in the plugin registry file and in the engine, but is not running.running
: The plugin is currently running, and thepid
column should contain its process ID.modified
: The plugin state present in the plugin registry file is different from the state in the engine.removed
: The plugin is still loaded in the engine, but is not present in the plugin registry file.invalid
: The data in the plugin registry file couldn't be deserialized, and the plugin most likely needs to be added again.
running
always has high priority as a state, so other statuses won't be visible if a plugin is currently running. This means that
# 0.99.0
plugin list | where is_running
can now always be replaced by:
# 0.100.0
plugin list | where status == running
In case you want to avoid loading the plugin registry file (e.g. for performance reasons), you can now use the --engine
flag to do so. Similarly, the --registry
flag will only display the contents of the registry, without comparing them against the state of the engine (but all plugins will appear as added
). The --plugin-config
flag is now supported to allow use of a separate plugin registry file, identically to the other plugin
commands.
Changes [toc]
Additions [toc]
history import
[toc]
Thanks to @qfel in #13450, this release adds the history import
command. Running this command takes the history from the alternate history file format and imports it into the currently configured history file format. For example, to migrate from plain text to sqlite:
# Current format is plain text
# $env.config.history.file_format == plaintext
# Change the file format. Make sure to set this in your config if you want to persist this change.
$env.config.history.file_format = 'sqlite'
# Import the old history to the new format. It will create a backup if necessary.
history import
You can also pipe new history entries into history import
, and they will be added to your history file. See help history import
for some examples.
catch
error record [toc]
In #14082, two additional columns were added to the error record passed to catch blocks/closures:
json
: a string containing the error data as JSON.rendered
: a string containing the pretty formatted error message, roughly the same as you would see in your terminal.
url split-query
[toc]
This release adds a new url split-query
command in #14211 thanks to @Bahex. It is the counterpart to url build-query
and splits a url query string into its different parameters. It returns a table with two columns: key
and value
.
help commands
and scope commands
[toc]
The help commands
and scope commands
now output an is_const
column indicating whether a command can be used in a parse-time constant context (#14125).
ps -l
[toc]
On macOS, ps -l
now lists the start_time
of the processes. Windows and Linux already listed a start_time
column (#14127).
url join
and url build-query
[toc]
Thanks to @adaschma in #14073, url build-query
now allows list values in the parameter record. For example:
{ a: [1 2], b: 3 } | url build-query
# a=1&a=2&b=3
Also, thanks to @Bahex in #14239, url join
and url build-query
now support table values for params
:
{
"scheme": "http",
"username": "usr",
"password": "pwd",
"host": "localhost",
"params": [
["key", "value"];
["par_1", "aaa"],
["par_2", "bbb"],
["par_1", "ccc"],
["par_2", "ddd"],
],
"port": "1234",
} | url join
http://usr:pwd@localhost:1234?par_1=aaa&par_2=bbb&par_1=ccc&par_2=ddd
touch --no-deref
[toc]
Thanks to @Dorumin in #14214, a new --no-deref
flag was added to touch
. Providing this flag will make touch
not follow symlinks.
length
Thanks to @sgvictorino in #14224, the length
command now supports binary values as input and returns the number of bytes.
stor
[toc]
stor
now supports list and table inputs thanks to @friaes in #14175.
to text --no-newline
[toc]
In #14158, the --no-newline
/-n
flag was added to to text
. Providing this flag disables the trailing new line added to the output.
[a] | to text # "a\n"
[a] | to text -n # "a"
[a b] | to text # "a\nb\n"
[a b] | to text -n # "a\nb"
open --raw
[toc]
After #14141, open --raw
now sets the appropriate content-type
in the pipeline metadata for nu
, nuon
, and json
files.
help
[toc]
The help
output for commands now shows the command type in parenthesis after the command name (i.e., plugin
, alias
, or custom
). Currently, the command type is not displayed for built-in
, keyword
, or known external
commands (#14165).
$env.config.table.footer_inheritance
[toc]
A new option has been introduced for table rendering by @zhiburt in #14070. With $env.config.table.footer_inheritance = true
, if one of the inner rendered tables trips the footer mode setting to show a footer at the bottom of the table, all of the outer tables will also have footers rendered.
Function key keybindings [toc]
Thanks to @hacker-DOM in #14201, the function keys from F21 to F35 are now allowed in key bindings. Note that for the keys to work, support for the kitty keyboard protocol needs to be enabled in your config ($env.config.use_kitty_protocol
) and your terminal also needs to support the protocol.
Breaking changes [toc]
Lone, leading pipe in closures [toc]
Breaking change
See a full overview of the breaking changes
Currently, a leading pipe character is allowed for pipelines in Nushell:
| ls
The closure syntax also uses pipe characters, so the parser previously allowed some cursed code:
{ |a $a }
{ |a, b $a $b }
Thanks to @sgvictorino in #14095, unmatched leading pipe characters in closures are no longer allowed to prevent this potential ambiguity.
{ |a| $a } # ok
{ |a $a } # now errors
url parse
[toc]
Thanks to @Bahex in #14211, the params
field output for url parse
is now a table with a key
and value
column instead of a record to match the new url split-query
command (see above).
http
--max-time
[toc]
With #14237, the --max-time
flag for the http
family of commands now takes a duration value instead of a integer number of seconds. Thanks to @alex-kattathra-johnson for making this change!
Empty rest matches [toc]
If a list rest pattern match ended up being empty, the match variable would previously be null
. In #14246 thanks to @CharlesTaylor7, the match variable will instead be an empty list if no matches are found.
# Before
match [] {
[..$rest] => ($rest == null) # true
}
# After
match [] {
[..$rest] => ($rest == []) # true
}
Case insensitive sorting [toc]
The method used for case insensitive comparisons and sorting has been updated/improved this release in #14255 thanks to @132ikl. This will affect the output of sort -i
, uniq -i
, get -s
, find -i
, str contains -i
, str starts-with -i
, str ends-with -i
, tab completions, and probably a few other commands (this list is not exhaustive).
ansi clear_entire_screen_plus_buffer
[toc]
In #14184, ansi clear_entire_screen_plus_buffer
now returns an ansi code that clears both the screen and scrollback buffer. Previously, it would only clear the scrollback buffer. In addition, a new clear_scrollback_buffer
entry has been added to the ansi
command. This will clear only the scrollback buffer.
Deprecations [toc]
AST evaluation engine [toc]
The NU_DISABLE_IR
environment variable as well as the AST evaluation engine itself is planned to be removed in the next release, and is now deprecated. We consider the IR evaluator to now be mature enough that it's time to stop maintaining the old evaluator.
Removals [toc]
std/dirs
[toc]
The std/dirs
module is no longer loaded by default on startup after #14242. See the previous release notes for more information.
Bug fixes and other changes [toc]
return
, break
, and continue
[toc]
In #14120, a bug was fixed were return
, break
, and continue
would set the last exit code to 1.
External command bareword arguments [toc]
There was a bug where "expressions" inside barewords created using backticks would be evaluated if provided as arguments to external commands. This has been fixed with #14210.
to text
[toc]
to text
previously had different behavior for list values and streaming list input. This has been fixed with #14158, and the behavior for list streams is now used for list values.
to nuon
[toc]
to nuon
previously did not escape column names containing quotes. This has been fixed by @aionescu in #14180.
use
[toc]
When importing a module that defines no constants, an empty record variable is no longer created (#14051).
transpose
[toc]
With #14096, transpose
now bubbles up any top-level errors it encounters in its input thanks to @PhotonBursted.
Constants with type signatures [toc]
Thanks to @sgvictorino in #14118, a compiler bug preventing imports of constants with type signatures has been fixed.
Short flag type checking [toc]
Short flags for commands were previously not being typed checked. This has been fixed in #14074 thanks to @sgvictorino.
Cell path pretty printing [toc]
The pretty printing for optional cell paths has been fixed by @aionescu in #14042 to show a ?
after each optional path component. This is particularly helpful for the view ir
command. Thanks!
The formatting has also been changed in #14197 to start with $
, reflecting the literal syntax. This means that the cell path literal $.foo.bar
will now be printed as $.foo.bar
instead of foo.bar
.
in $range
[toc]
The step value for ranges was previously not taken into account when checking if a value was in
a range. Thanks to @JoaquinTrinanes, this has been fixed with #14011.
into datetime
[toc]
After #14266, times are kept intact when performing conversion to the local time zone for parsed human date strings.
ansi -l
[toc]
The preview column from ansi -l
now also shows bold, dimmed, blink, and other effects thanks to @NotTheDr01ds in #14196.
join
[toc]
An issue where table literal arguments to join
were not parsed correctly has been fixed in
Table literals as arguments [toc]
An issue where table literals were incorrectly parsed when used as arguments to commands has been fixed in #14190 and #14226 thanks to @sgvictorino.
clear
[toc]
On some terminals, clear
would behave weirdly if used in a series of commands. Thanks to @NotTheDr01ds, this has been fixed in #14181.
Prefer $env.VISUAL
over $env.EDITOR
[toc]
@weirdan fixed our preference of environment variable to find an editor to be more like other Unix commands in #14275. We now prefer to use VISUAL
first, if it's set.
Fix handling of exported external aliases [toc]
In #14231, @sgvictorino fixed the way aliases to external commands are handled when exported from modules. Previously, they would mistakenly be passed arguments corresponding to the module path.
> module foo { export alias bar = ^echo }
> use foo
> foo bar baz
# 0.99.0:
bar baz
# 0.100.0:
baz
Panic fixes [toc]
A parser panic regarding redirections was fixed in #14035 thanks to @Kither12.
Hall of fame [toc]
Thanks to all the contributors below for helping us solve issues and improve documentation 🙏
author | title | PR |
---|---|---|
@atahabaki | upgrade bracoxide to v0.1.4 (fixes #14290) | #14296 |
@fdncred | allow != for polars | #14263 |
@sgvictorino | don't include import path in args to aliased external commands | #14231 |
@sgvictorino | correctly parse table literals as lists | #14226 |
@WindSoilder | fix $env.FILE_PWD and $env.CURRENT_FILE inside use | #14101 |
@fdncred | make adding newlines with to text more consistent and opt-out-able | #14158 |
@PhotonBursted | Defensive handling of errors when transposing | #14096 |
@sgvictorino | error when closure param lists aren't terminated by | | #14095 |
@sgvictorino | fix error when exporting constants with type signatures in modules | #14118 |
@fdncred | try and fix osc633 escaping yet again | #14140 |
@IanManske | Fix return setting last exit code | #14120 |
@WindSoilder | use command: Don't create a variable with empty record if it doesn't define any constants | #14051 |
@sgvictorino | run ensure_flag_arg_type for short flag values | #14074 |
All breaking changes [toc]
- #14275 Fix the order of preference for
VISUAL
andEDITOR
- #14211 Url split query
- #14242 No longer autoload deprecated-dirs
- #14255 Switch to unicase's to_folded_case
- #14157 Div, mod, and floor div overhaul
- #14246 Empty rest args match should be an empty list
- #14237 Change --max-time arg for http commands to use
Duration
type - #14085 Make
plugin list
read state from plugin registry file as well
Full changelog [toc]
- hustcer created
- sholderbach created
- NotTheDr01ds created
- fdncred created
- ignore without_timezone test for now
- update reedline to the latest commit
- allow != for polars
- update human-date-parser conversion to use local timezone
- allow oem code pages to be used to decode text
- add command_type to help
- Add metadata on
open --raw
with bytestreams - make adding newlines with
to text
more consistent and opt-out-able - add
name
to$env.config.keybindings
- update to reedline commit 9cb1128
- try and fix osc633 escaping yet again
- add
start_time
tops -l
on macos - add is_const to
help commands
andscope commands
- add rendered and json error messages in try/catch
- allow
group-by
andsplit-by
to work with other values - add
like
andnot-like
operators as synonyms for the regex operators=~
and!~
- atahabaki created
- aionescu created
- WindSoilder created
- weirdan created
- Bahex created
- sgvictorino created
- don't include import path in args to aliased external commands
- correctly parse table literals as lists
- support binary input in
length
- support table literal syntax in
join
right-table argument - error when closure param lists aren't terminated by
|
- fix error when exporting constants with type signatures in modules
- run ensure_flag_arg_type for short flag values
- app/dependabot created
- Bump crate-ci/typos from 1.26.8 to 1.27.0
- Bump notify-debouncer-full from 0.3.1 to 0.3.2
- Bump scraper from 0.20.0 to 0.21.0
- Bump softprops/action-gh-release from 2.0.8 to 2.0.9
- Bump chrono-tz from 0.8.6 to 0.10.0
- Bump trash from 5.1.1 to 5.2.0
- Bump fancy-regex from 0.13.0 to 0.14.0
- Bump unicase from 2.7.0 to 2.8.0
- Bump crate-ci/typos from 1.26.0 to 1.26.8
- Bump uuid from 1.10.0 to 1.11.0
- Bump bytes from 1.7.1 to 1.8.0
- 132ikl created
- IanManske created
- CharlesTaylor7 created
- alex-kattathra-johnson created
- Dorumin created
- Kissaki created
- vyadh created
- hacker-DOM created
- blindFS created
- qfel created
- friaes created
- ofek created
- zhiburt created
- ayax79 created
- PhotonBursted created
- adaschma created
- Kither12 created
- JoaquinTrinanes created
- YizhePKU created
- devyn created