Nushell 0.92.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.92.0 of Nu. This release adds exciting new plugin features (persistence, a reworked API, and more functionality), a simple profiler, support for XDG_CONFIG_HOME, scoped file redirections, and changes to external command output.
Where to get it
Nu 0.92.0 is available as pre-built binaries or from crates.io. 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
- External command output changes
- Scoped file redirections
- Tilde expansion
- Support for
XDG_CONFIG_HOME
- Incorporating the
extra
feature by default - Persistent plugins
- Plugin API overhaul
- Plugin engine calls
- Improved plugin custom values
- Plugin test support crate
- Official plugin template
- Debugging support and proof-of-concept profiler
- Support for binary data in
explore
- Performance improvements
- Hall of fame
- Our set of commands is evolving
- Breaking changes
- Full changelog
Themes of this release / New features [toc]
External command output changes [toc]
Breaking change
See a full overview of the breaking changes
With #11934, we improved the performance of pipelines with external commands. As part of this effort, Nushell now streams external command output in more places where it is possible. Namely, parentheses no longer collect external command output and are now solely for grouping and precedence. For example, take this pipeline:
(nu -c "for x in 1.. { try { print $x } catch { break } }")
| lines
| first
In previous versions, this would collect the output of nu
and would not print anything until ctrl+c
was pressed. Now, this will immediately print the first line and then immediately finish the pipeline.
So now, external command output will only be collected if it's being turned into a value (or if it's passed to an internal command that collects its input). For example, external commands will be collected if it's a command argument:
print (^external)
Or, if it's being stored in record, list, table, or variable:
{
result: (^external)
}
[(^external)]
let result = ^external
"Being turned into a value" now also includes closures in many cases. For example, each
, insert
, reduce
, and many other commands run closures to compute values. In these cases, if an external command is in "return position" (it's the last command), then its output will be collected into a value instead of writing to the terminal/stdio. For example, the code below used to print "text"
twice and then return an empty list:
1..2 | each { nu -c 'print text' }
But now, this will collect the output of nu
, giving the list ['text', 'text']
. To achieve the old behavior, you can return null
instead:
1..2 | each { nu -c "print text"; null }
# or, you could use a `for` loop
Only a few commands take a closure but do not use it to compute a value:
do
with-env
collect
tee
watch
These commands will not collect external command output from the closure and will instead forward it to the next command in the pipeline or to the terminal/stdio.
Another notable change is that external command output will no longer be implicitly ignored. For example, external commands in subexpressions that were not the last command used to have their output discarded:
(^echo first; ^echo last)
Before, this would only print last
, but now this prints both first
and last
.
One final change to note is that external command output now has trailing new lines removed by default. The exceptions are if the external command is being redirected to a file, another external command, to the terminal, or to the complete
command.
Scoped file redirections [toc]
Breaking change
See a full overview of the breaking changes
File redirections (o>
, e>
, o+e>
, etc.) now apply to all external commands inside an expression. For example, the snippet below will redirect stderr from both commands into err.log
.
(nu -c "print -e first"; nu -c "print -e last") e> err.log
# err.log will contain: "first\nlast\n"
Note that if there were any custom commands called inside the subexpression, then any external commands inside the custom command would also use the same file redirection.
def cmd [] {
^extern1
^extern2
}
(^extern3; cmd) o> out.txt
# output from `extern1`, `extern2`, `extern3` will be redirected to the file
Tilde expansion [toc]
Breaking change
See a full overview of the breaking changes
Building off of last release's work with globs, this version makes similar changes to tilde expansion in #12232. Now, tildes will be expanded to the home directory only if it's part of a glob.
ls ~/dir # expands tilde
ls "~/dir" # does not expand tilde
let f = "~/dir"
ls $f # does not expand tilde
ls ($f | path expand) # tilde explicitly expanded
ls ($f | into glob) # tilde will be expanded
let f: glob = "~/aaa"
ls $f # tilde will be expanded
Support for XDG_CONFIG_HOME
[toc]
Breaking change
See a full overview of the breaking changes
When nushell firsts starts up, if it detects that the XDG_CONFIG_HOME
environment variable is set to an absolute path, then nushell will use XDG_CONFIG_HOME/nushell
as the config directory. Otherwise, nushell will use the same config directory as it did in previous versions. Note that setting XDG_CONFIG_HOME
in env.nu
will not work! XDG_CONFIG_HOME
must be set before nushell is launched. This can be accomplished through settings in your terminal emulator, using another shell to launch nushell, by setting environment variables at the OS level, etc. The relevant PR is #12118.
Incorporating the extra
feature by default [toc]
Breaking change
See a full overview of the breaking changes
The extra
cargo feature was removed in this version, since all of its features and commands are now included by default with #12140. Packagers and users that compile nushell from source will need to check whether they enable the extra
feature and remove it from their build scripts.
This was done to simplify the distribution of Nushell to have a canonical set of commands. Commands that we deem to serve a niche role or are not fully developed yet will now most likely be removed from the core nu
binary and move into their dedicated plugins.
(Now only the dataframe
feature remains to add a major set of commands, but work is underway to allow you to add this simply as a plugin)
If your current build of nushell does not have the extra
feature enabled, then you should have access to more commands in this new release:
update cells
provides an easy way to update all cells of a table using a closure.each while
is like theeach
command, except it stops once a null value is returned by the closure.into bits
returns the stringified binary representation of a value.- The
bits
family of commands which has bit-wise operations likebits and
,bits or
,bits not
,bits shl
, and more! - More
math
commands likemath exp
,math ln
, and trigonometric functions likemath sin
,math sinh
,math arcsin
, andmath arcsinh
. format pattern
which provides a simpiler way to format columns of a table compared to, for example, using string interpolation.fmt
which formats numbers into binary, hex, octal, exponential notation, and more.encode hex
anddecode hex
allows one to encode and decode binary values as hex strings.- Commands to change the casing of strings like
str camel-case
,str kebab-case
, and more. - The
roll
family of commands to roll columns or rows of a table up, down, left, or right. - The
rotate
command to rotate a table clockwise or counter clockwise. ansi gradient
adds a color gradient to text foreground and/or background.to html
converts a table into HTML text.from url
parses a url encoded string into a record.
Future releases may choose to remove some of those commands to plugins to slim down the nu
binary or make sure that we can maintain stability guarantees after the 1.0 release of Nushell.
Persistent plugins [toc]
Warning
We recommend removing your plugin.nu
file (from the config directory) when migrating to this new version, due to the significant changes made. You will then need register
all of your plugins again after they have been updated.
A major enhancement for plugin users: plugins can now run persistently in the background and serve multiple calls before exiting! 🎉
This improves the performance of plugin commands considerably, because starting a process has a much more considerable overhead than talking to an existing one:
# 0.91.0
> 1..1000 | each { timeit { "2.3.2" | inc -m } } | math avg
2ms 498µs 493ns
# 0.92.0 (8x faster!)
> 1..1000 | each { timeit { "2.3.2" | inc -m } } | math avg
308µs 577ns
That difference is even more significant for plugins written in JIT or interpreted languages:
# 0.91.0
> 1..100 | each { timeit { nu-python 1 foo } } | math avg
40ms 704µs 902ns
# 0.92.0 (47x faster!)
> 1..1000 | each { timeit { nu-python 1 foo } } | math avg
871µs 410ns
This will open the door to plugins that would have otherwise been too slow to be useful, particularly in languages that have a reputation for being slow to cold start, like Java and other JVM languages.
By default, plugins will stay running for 10 seconds after they were last used, and quit if there is no activity. This behavior is configurable:
$env.config.plugin_gc = {
# Settings for plugins not otherwise specified:
default: {
enabled: true # set to false to never automatically stop plugins
stop_after: 10sec # how long to wait after the plugin is inactive before stopping it
}
# Settings for specific plugins, by plugin name
# (i.e. what you see in `plugin list`):
plugins: {
gstat: {
stop_after: 1min
}
inc: {
stop_after: 0sec # stop as soon as possible
}
stream_example: {
enabled: false # never stop automatically
}
}
}
Aside from performance, this also enables plugins to have much more advanced behavior. Plugins can now maintain state across plugin calls, and for example use a handle custom value to track resources that remain in the plugin's process without having to be serialized somehow, or implement caches to speed up certain operations that are repeated often.
For more details on how to manage plugins with this change, see the newly added plugin list
and plugin stop
commands.
Plugin API overhaul [toc]
Breaking change
See a full overview of the breaking changes
Warning
Plugins are no longer launched in the current working directory of the shell. Instead, they are launched in the directory of their plugin executable. See this section of the plugins guide for details.
This release brings major reorganization to the plugin API. The Plugin
trait now specifies a list of PluginCommand
trait objects, which implement both the signature and the functionality for that command. Dispatching the commands by name is now handled by serve_plugin()
automatically, so no more match
statements! This should make creating plugins that expose many commands much easier, and also makes a one-command-per-module pattern easier to follow.
StreamingPlugin
has been removed. Instead, PluginCommand
uses the streaming API, with PipelineData
input and output, and SimplePluginCommand
has value input and output just as before.
The signature()
method has been broken up into more methods to reflect the internal Command
trait. This makes core commands and plugin commands look more similar to each other, and makes it easier to move core commands to plugins if we want to. The new methods are: name()
, usage()
, extra_usage()
, examples()
, search_terms()
. PluginSignature
and PluginExample
are both no longer needed to be used by plugin developers - just use Signature
and Example
like core commands do.
The arguments passed to run()
have also changed. It now takes &self
rather than &mut self
, and all plugins and commands are required to be Sync
, so that they can be safely shared between threads. Use thread-safe state management utilities such as those found in std::sync
to create stateful plugins.
The config
parameter has been removed and replaced with an EngineInterface
reference, which supports many more functions, including get_plugin_config()
to get the config. For the other added functionality on EngineInterface
, see that section.
LabeledError
has been reworked, and now supports multiple labeled spans and some other attributes that miette provides. This helps to ensure that ShellError
can generally be passed through a LabeledError
and still appear the same to the user. A new ShellError::LabeledError
variant is provided to contain it. More complex plugins might like to implement a miette::Diagnostic
error, in which case converting to LabeledError
can be done automatically via LabeledError::from_diagnostic()
.
A complete example of the new API organization from the plugin docs:
use nu_plugin::{serve_plugin, EvaluatedCall, JsonSerializer};
use nu_plugin::{EngineInterface, Plugin, PluginCommand, SimplePluginCommand};
use nu_protocol::{LabeledError, Signature, Type, Value};
struct LenPlugin;
impl Plugin for LenPlugin {
fn commands(&self) -> Vec<Box<dyn PluginCommand<Plugin = Self>>> {
vec![Box::new(Len)]
}
}
struct Len;
impl SimplePluginCommand for Len {
type Plugin = LenPlugin;
fn name(&self) -> &str {
"len"
}
fn usage(&self) -> &str {
"calculates the length of its input"
}
fn signature(&self) -> Signature {
Signature::build(PluginCommand::name(self))
.input_output_type(Type::String, Type::Int)
}
fn run(
&self,
_plugin: &LenPlugin,
_engine: &EngineInterface,
call: &EvaluatedCall,
input: &Value,
) -> Result<Value, LabeledError> {
let span = input.span();
match input {
Value::String { val, .. } => Ok(Value::int(val.len() as i64, span)),
_ => Err(
LabeledError::new("Expected String input from pipeline").with_label(
format!("requires string input; got {}", input.get_type()),
call.head,
),
),
}
}
}
fn main() {
serve_plugin(&LenPlugin, JsonSerializer)
}
Plugin engine calls [toc]
The added EngineInterface
parameter mentioned previously enables the following new functionality for plugins:
- Get the engine
Config
:.get_config()
(part of #12029) - Evaluate closure:
.eval_closure()
,.eval_closure_with_stream()
(part of #12029) - Get environment variables and working directory:
.get_env_var()
,.get_env_vars()
,.get_current_dir()
(#12166) - Set environment variables in caller's scope:
.add_env_var()
(#12204) - Plugin garbage collection disable/enable:
.set_gc_disabled()
(part of #12064) - Get command help text, useful for subcommand collections:
.get_help()
(#12243)
See the docs for details and examples on what can be done with the EngineInterface
.
Improved plugin custom values [toc]
Custom values returned by plugins previously had very limited functionality - they could really only be sent back to the same plugin in another command. This release expands the number of supported operations:
- Cell paths (e.g.
$custom_value.0
and$custom_value.field
) - Operators (e.g.
$custom_value + $other
,$custom_value ++ "plain value"
) - Comparisons (for compatibility with
sort
) - Drop notification (useful for implementing handles)
Most of these improvements originated in #12088. Additionally, custom values are now also allowed to be used in examples for commands in plugins #12113.
For more information, see the plugins guide and CustomValue
docs.
Plugin test support crate [toc]
With plugins having much more functionality, we thought it would be nice if it were easy to write tests for your plugins, and even test your examples automatically. Now you can!
Add the nu-plugin-test-support
crate to your dev-dependencies:
[dev-dependencies]
nu-plugin-test-support = "0.92.0"
Then test your examples:
#[test]
fn test_examples() -> Result<(), nu_protocol::ShellError> {
use nu_plugin_test_support::PluginTest;
PluginTest::new("my_plugin", MyPlugin.into())?.test_command_examples(&MyCommand)
}
For more information, see the crate docs and the contributor book.
Official plugin template [toc]
With this release, we are launching an official template for plugins, to help you get started. Use cargo-generate:
> cargo generate --force --git https://github.com/nushell/nu_plugin_template
🤷 What will this plugin be named?: foo
Creating a new plugin named "foo"
Your plugin crate will be named "nu_plugin_foo".
Note that the MIT license is used by default, to reflect the majority of
Nushell projects. You can change this manually if you'd like to.
!!! IMPORTANT !!!
You must run cargo generate with --force, or it will rename your project to
something that is non-standard for Nushell plugins and this will fail.
If you see a message after this about renaming your project, please abort and
try again with --force.
🔧 Destination: /var/home/devyn/Projects/nushell/nu_plugin_foo ...
🔧 project-name: nu_plugin_foo ...
🔧 Generating template ...
🤷 What should your first command be called? (spaces are okay): foo
✔ 🤷 Do you intend to create more than one command / subcommand? · No
✔ 🤷 Would you like a simple command? Say no if you would like to use streaming. · Yes
🤷 What is your GitHub username? (Leave blank if you don't want to publish to GitHub) [default: ]:
🔧 Moving generated files into: `/var/home/devyn/Projects/nushell/nu_plugin_foo`...
🔧 Initializing a fresh Git repository
✨ Done! New project created /var/home/devyn/Projects/nushell/nu_plugin_foo
> cd nu_plugin_foo
> cargo build
> register target/debug/nu_plugin_foo
> foo Ferris
Hello, Ferris. How are you today?
Debugging support and proof-of-concept profiler [toc]
You may remember that we used to have a profile
command which then got removed due to unsound implementation. Now, it's back as debug profile
! You can give it a closure and it will profile each pipeline element in it, stepping recursively into nested blocks/closures/command calls. Make sure to check its help message to understand its output and options.
Under the hood, the profiler uses a new general debugging API that is now hooked into the evaluation engine. The profiler is a proof-of-concept implementation using this API, but we imagine it could be used for other purposes, such as step debugging, code coverage, or even allowing to create custom debugger plugins.
A short user story as an example: The following screenshot shows the profiler output of sourcing kubouch's env.nu file: You can see that most time is spent inside the load-env
calls and in the if (is-windows) { ...
. We can increase the number of blocks to step into with the --max-depth
flag which reveals more detail: You can notice that most of the expensive pipeline elements have one thing in common: The is-windows
call. It is a custom command in kubouch's env.nu which internally calls (sys).host.name
which on kubouch's machine takes around 13 ms. Changing it to use $nu.os-info.name
and other smaller fixes decreased the startup time from 130ms to 50ms.
Support for binary data in explore
[toc]
@zhiburt has added the colored hexdump view for binary data to the explore
command (#12184), making it much easier to page through the output. This should be handy for anyone who spends a lot of time looking at binary formats!
Performance improvements [toc]
A significant effort in this release went into improving Nushell's performance and resource usage. As part of this, we grew our internal benchmark suite to measure the performance impact of future changes (#12025, #12293). In addition to performance improvements from the external command and plugin changes, there have been other notable efforts to make nushell faster! In #11654, @rtpg reduced the work needed to clone stacks. This improvement will be most noticeable if you have very large global variables in the REPL, as these will no longer need to be copied in memory each time you hit enter. On top of this, @devyn made it cheaper to clone the engine state in #12229. This should make nushell more performant when evaluating closures and also should reduce memory usage (especially in the REPL). To further address memory usage @FilipAndersson245 reduced the size of our Value
primitive in #12252 and with #12326 @sholderbach changed our internal Record
to a more compact and efficient representation. During work we also identified and fixed inefficiencies like unnecessarily copying values when accessing columns in a table or record (#12325). Overall we hope to improve the experience with Nushell and welcome the community to contribute suggestions for benchmarks that reflect their workloads to avoid regressions and tune Nushell's engine.
Hall of fame [toc]
Bug fixes [toc]
Thanks to all the contributors below for helping us solve issues and bugs 🙏
author | description | url |
---|---|---|
@merelymyself | Make autocd return exit code 0 | #12337 |
@dead10ck | into sqlite: Fix insertion of null values | #12328 |
@sholderbach | Fix return in filter closure eval | #12292 |
@lavafroth | fix: use environment variables to prevent command_not_found from recursing | #11090 |
@YizhePKU | Fix: missing parse error when extra tokens are given to let bindings | #12238 |
@dannou812 | to json -r not removing whitespaces fix | #11948 |
@JoaoFidalgo1403 | Fix usage of --tabs flag while converting to json | #12251 |
@YizhePKU | Fix inaccurate sleep duration | #12235 |
@IanManske | Use rest argument in export use to match use | #12228 |
@sarubo | Adjust permissions using umask in mkdir | #12207 |
@WindSoilder | fix ls with empty string | #12086 |
@rgwood | Fix up ctrl+C handling in into sqlite | #12130 |
@NowackiPatryk | Fix unexpected sqlite insert behaviour (attempt 2) | #12128 |
@VlkrS | Fix build on OpenBSD | #12111 |
@dj-sourbrough | Fix: lex now throws error on unbalanced closing parentheses (issue #11982) | #12098 |
@NotTheDr01ds | Fix: Convert help example results to text | #12078 |
@rgwood | Remove unused/incorrect input type from start | #12107 |
@fdncred | fix du --exclude globbing bug | #12093 |
Enhancing the documentation [toc]
Thanks to all the contributors below for helping us making the documentation of Nushell commands better 🙏
author | description | url |
---|---|---|
@Jasha10 | Fix dead links in CONTRIBUTING.md | #12353 |
@AucaCoyan | ♻️ rework some help strings | #12306 |
@devyn | Fix zip signature to mention closure input type | #12216 |
@thomassimmer | Fix histogram error message | #12197 |
@nils-degroot | Improve error message for into sqlite with empty records | #12149 |
@IanManske | Fix broken doc link | #12092 |
@wellweek | remove repetitive word | #12117 |
@sholderbach | Remove outdated doccomment on EngineState | #12158 |
@devyn | Misc doc fixes | #12266 |
@fdncred | cleanup coreutils tagging | #12286 |
Our set of commands is evolving [toc]
New commands [toc]
This release adds four new commands and more flags to some existing commands.
plugin list
[toc]
As part of the plugin persistence update, this command shows you not only all of the plugins you have installed and their commands, but also whether they are running and what their process ID is if they are:
> plugin list
╭───┬─────────┬────────────┬─────────┬───────────────────────┬───────┬───────────────────────────────╮
│ # │ name │ is_running │ pid │ filename │ shell │ commands │
├───┼─────────┼────────────┼─────────┼───────────────────────┼───────┼───────────────────────────────┤
│ 0 │ gstat │ true │ 1389890 │ .../nu_plugin_gstat │ │ ╭───┬───────╮ │
│ │ │ │ │ │ │ │ 0 │ gstat │ │
│ │ │ │ │ │ │ ╰───┴───────╯ │
│ 1 │ inc │ false │ │ .../nu_plugin_inc │ │ ╭───┬─────╮ │
│ │ │ │ │ │ │ │ 0 │ inc │ │
│ │ │ │ │ │ │ ╰───┴─────╯ │
│ 2 │ example │ false │ │ .../nu_plugin_example │ │ ╭───┬───────────────────────╮ │
│ │ │ │ │ │ │ │ 0 │ nu-example-1 │ │
│ │ │ │ │ │ │ │ 1 │ nu-example-2 │ │
│ │ │ │ │ │ │ │ 2 │ nu-example-3 │ │
│ │ │ │ │ │ │ │ 3 │ nu-example-config │ │
│ │ │ │ │ │ │ │ 4 │ nu-example-disable-gc │ │
│ │ │ │ │ │ │ ╰───┴───────────────────────╯ │
╰───┴─────────┴────────────┴─────────┴───────────────────────┴───────┴───────────────────────────────╯
You can join the output of this command on pid
with ps
in order to get information about the running plugins. For example, to see the memory usage of running plugins:
> plugin list | join (ps) pid | select name pid mem
╭───┬───────┬────────┬──────────╮
│ # │ name │ pid │ mem │
├───┼───────┼────────┼──────────┤
│ 0 │ gstat │ 741572 │ 10.2 MiB │
│ 1 │ inc │ 741577 │ 3.6 MiB │
╰───┴───────┴────────┴──────────╯
plugin stop
[toc]
If you want to explicitly stop a plugin that's running in the background, you can use the plugin stop
command. This works even if the plugin signals to Nushell that it wants to stay running.
> plugin stop inc
> plugin list | where is_running and name == inc
╭────────────╮
│ empty list │
╰────────────╯
Unlike kill
, this does not send a signal to the process - it merely deregisters the plugin from Nushell's list of running plugins, which should eventually cause it to exit. If the plugin is unresponsive, you can kill
its PID:
> plugin list | where is_running and name == inc | each { kill $in.pid }
debug profile
[toc]
Profile a closure, see debugging support and proof-of-concept profiler.
uname
[toc]
Thanks to @dmatos2012, version 0.92.0 adds the uname
command. Under the hood, it uses uutils to return a record containing system information.
query db --params
[toc]
Thanks to @Dorumin, the --params
flag was added to query db
in #12249. This allows one to specify parameters in the SQL query instead of using string interpolation. This helps avoids potential SQL injection attacks.
detect columns --guess
[toc]
A new flag, --guess
, was added to detect columns
in #12277. This uses a histogram approach to detect the boundaries between fixed-width columns, and may give better results for certain command outputs.
Changes to existing commands [toc]
echo
[toc]
Breaking change
See a full overview of the breaking changes
echo
will now never directly print values. It only returns its arguments, matching the behavior described in its help
text. To print values to stdout or stderr, use the print
command instead.
table
[toc]
Breaking change
See a full overview of the breaking changes
With #12294, the table
command will always pretty print binary values. It used to not if the next command was an external command.
into bits
[toc]
Breaking change
See a full overview of the breaking changes
In #12313, into bits
was changed so that it can no longer take date values as input. The current implementation of into binary
(and until this release of into bits
) for the date
type is unstable and dependent on your system locale and timezone settings, as it creates a human-readable string instead of unique representation of the date-time point. We intend to deprecate and remove the into binary
implementation for the date
type in a future release.
nu-check
[toc]
Breaking change
See a full overview of the breaking changes
nu-check
received a significant refactor in #12317. It is now possible to check module directories, so the provided path no longer needs to end in .nu
. As part of this, the --all
flag was removed, since all modules can be parsed as a script.
mkdir
[toc]
mkdir
now uses uucore
under the hood to determine the umask to apply to the directory being created (implemented in #12207).
ls
[toc]
With #12086, ls ""
no longer behaves like ls /
. Instead, it will now report an error.
version
[toc]
The version
command has been changed to list plugin names in plugins
. These reflect the name
field of plugin list
. The previous behavior was to list all plugin commands.
filter
[toc]
The filter
command now supports early returns in closures (fixed by #12292).
insert
[toc]
With #12209, if a closure is used to insert new values, then the $in
value for the closure will now have the same value as the first parameter of the closure (instead of often being null
).
do
[toc]
Closures passed to do
may now take optional parameters and rest parameters. Additionally, type annotations on the parameters will be checked/enforced. See #12056 for the relevant PR.
complete
[toc]
complete
now captures stderr output by default, and it is no longer necessary to use do
in combination with complete
.
ignore
[toc]
In #12120, the ignore
command has been patched to drop values it receives immediately rather than storing them first. This helps reduce the memory usage of large command output passed to ignore
.
export use
[toc]
In #12228, export use
was changed to take a rest argument instead of an optional argument. This allows exporting items from nested modules at any arbitrary depth, and this now matches the existing behavior of use
(without export
).
sleep
[toc]
Fixed an issue with sleep
in #12235 where the sleep duration would be rounded up to the nearest 100ms.
into sqlite
[toc]
into sqlite
has had a few bug fixes:
- Ctrl+c handling in
into sqlite
was fixed with #12130. - Insertion of null values was fixed with #12328.
- Column ordering for INSERT was fixed in #11429.
- Improved the error message for empty records in #12149.
to json
[toc]
With #11948, to json --raw
now properly removes all whitespace. Additionally, the --tabs
and --indent
flags were fixed in #12251.
du
[toc]
A bug with du
was fixed in #12903 where the --exclude
flag would error complaining that it couldn't convert a glob to a string.
histogram
[toc]
Improved the error message for when the column-name
parameter was not provided (fixed by #12197).
into string
[toc]
Custom values are now supported if their base value resolves to a string (#12231). We will likely extend this to other conversions in the future.
Deprecated commands [toc]
run-external
flags [toc]
Breaking change
See a full overview of the breaking changes
All preexisting flags for run-external
are now deprecated.
This is because run-external
now interacts with pipe and file redirections just like if an external command had been run directly. I.e., run-external cmd
should be the same as just ^cmd
. The only difference is that run-external
may have additional flags added in the future for other functionality.
- To achieve the old
--redirect-stdout
behavior, simply use a pipe|
. - Instead of
--redirect-stderr
, use the stderr pipee>|
, or use a regular pipe|
for internal commands that use stderr directly (i.e.,save --stderr
andtee --stderr
). - Instead of
--redirect-combine
, use the stdout and stderr pipeo+e>|
.
As noted in external command output changes, external command output now has trailing new lines trimmed by default, so the --trim-end-newline
flag was deprecated as well.
Removed commands [toc]
str escape-glob
[toc]
str escape-glob
was deprecated in the previous release (0.91.0), and it has now been removed.
Breaking changes [toc]
- #11934 IO and redirection overhaul
- #12232 ls, rm, cp, open, touch, mkdir: Don't expand tilde if input path is quoted string or a variable.
- #12118 Use XDG_CONFIG_HOME before default config directory
- #12140 Remove feat
extra
and include in default - #12064 Keep plugins persistently running in the background
- #12279 Change PluginCommand API to be more like Command
- #12029 Add support for engine calls from plugins
- #12294 Always pretty print binary values in
table
- #12249 Initial --params implementation (
query db
) - #11948
to json -r
not removing whitespaces fix - #12309 Rename
Value::CustomValue
toValue::Custom
- #12313 Remove ambiguous
into bits
impl fordate
- #12328 into sqlite: Fix insertion of null values
- #12241 remove str escape-glob command
- #12137 Refactor nu-check
Full changelog [toc]
- IanManske created
mkdir
umask fix- Use safe
nix
API instead oflibc
- Fix file redirection for externals streams
- Make
Record.cols
private - Add
command_prelude
module - Cancel old CI runs on commit
- Always pretty print binary values in
table
- Use rest argument in
export use
to matchuse
- Fix wrong stdout with
e>|
- Fix
$in
value forinsert
closure - IO and redirection overhaul
- Fix ignored clippy lints
- Fix clippy lints
- Fix
chrono
deprecation warnings - Fix clippy lints
- Fix broken doc link
- Jasha10 created
- sholderbach created
- Refactor
Record
to use a single backingVec
- Remove ambiguous
into bits
impl fordate
- Reuse existing small allocations if possible
- Elide clone in
V::follow_cell_path
for record - Use nightly clippy to kill dead code/fix style
- Avoid uses of
Record
internals again - Fix #10131
- Rename
Value::CustomValue
toValue::Custom
- Deduplicate
nix
dependency versions - Benchmark table creation and access
- Fix
return
infilter
closure eval - Follow API guidelines for public types
- Remove dead
impl PluginEncoder for EncodingType
- Style: move some
Option
if/else to method chains - Refactor source cache into
CachedFile
struct - Respond to nightly clippy
- Update contributor image generation with new upper bound
- Disable
fmt
feature ofpolars(-core)
- Minor refactor in
to html
- Remove the rarely used std-lib issue template
- Bump
arboard
from3.3.0
to3.3.2
- Refactor benches for more command benchmarks
- Include benchmarks in the CI clippy run
- Bump
iana-time-zone
due to yanked locked version - Remove outdated doccomment on
EngineState
- Bump
reedline
to dev (andstrum
) - Restructure
nu-protocol
in more meaningful units - Remove feat
extra
and include in default - Reschedule dependabot PR opening to Wednesday
- Bump version to
0.91.1
- Refactor
- merelymyself created
- devyn created
- Remove serde derive for
ShellError
, replace viaLabeledError
- Fix build of nu-protocol without plugin feature enabled
- Change PluginCommand API to be more like Command
- Add example tests (nu-plugin-test-support) for plugins in repo
- Fix #12280: replace
difference
crate withsimilar
- Make some of the stream tests more robust against bad timeouts
- Support for getting help text from a plugin command
- Add test support crate for plugin developers
- Misc doc fixes
- Better generic errors for plugins (and perhaps scripts)
- Address feedback from PR #12229
- Refactor
PluginCustomValue::render_to_base_value_in
- Refactor PipelineDataHeader ⇄ PipelineData mapping
- Make EngineState clone cheaper with Arc on all of the heavy objects
- Merge stream_example into example plugin and clean up names
- Fix broken build: replace value_string() straggler
- Make custom value type handling more consistent
- Support
into string
for custom values - Support for custom values in plugin examples
- Fix zip signature to mention closure input type
- Add
Value::recurse_mut()
to save duplicated code inPluginCustomValue
- Allow plugins to set environment variables in their caller's scope
- Reorganize plugin API around commands
- MsgPack deserializer: improve handling of EOF
- More robustness improvements to plugin persistence tests
- Fix locking soundness in PersistentPlugin
- Disable plugin GC tests on macOS
- Add environment engine calls for plugins
- Sync with the plugin garbage collector when setting config
- Support for all custom value operations on plugin custom values
- Make the plugin persistence GC delay test more reliable
- Fix unused IntoSpanned warning in nu_parser::parse_keywords when 'plugin' feature not enabled
- Keep plugins persistently running in the background
- Add support for engine calls from plugins
- Improve the error message for a plugin version mismatch
- Change the ignore command to use drain() instead of collecting a value
- Remove serde derive for
- WindSoilder created
- detect columns: intruduce a --guess flag, remove --legacy
- Change default algorithm in
detect columns
- ls, rm, cp, open, touch, mkdir: Don't expand tilde if input path is quoted string or a variable.
- remove str escape-glob command
- remove test warnings
- clean cp tests
do
command: Make closure support default parameters and type checking- fix ls with empty string
- dead10ck created
- fdncred created
- AucaCoyan created
- app/dependabot created
- Bump sqlparser from 0.43.1 to 0.44.0
- Bump ical from 0.10.0 to 0.11.0
- Bump rayon from 1.9.0 to 1.10.0
- Bump base64 from 0.21.7 to 0.22.0
- Bump heck from 0.4.1 to 0.5.0
- Bump uuid from 1.7.0 to 1.8.0
- Bump rayon from 1.8.1 to 1.9.0
- Bump miette from 7.1.0 to 7.2.0
- Bump softprops/action-gh-release from 2.0.1 to 2.0.4
- Bump actions/checkout from 4.1.1 to 4.1.2
- Bump windows from 0.52.0 to 0.54.0
- Bump scraper from 0.18.1 to 0.19.0
- Bump open from 5.0.1 to 5.1.1
- Bump mockito from 1.3.0 to 1.4.0
- FilipAndersson245 created
- dmatos2012 created
- schrieveslaach created
- Dorumin created
- abusch created
- zhiburt created
- lavafroth created
- YizhePKU created
- dannou812 created
- JoaoFidalgo1403 created
- Tastaturtaste created
- sarubo created
- thomassimmer created
- ysthakur created
- nils-degroot created
- kubouch created
- rtpg created
- hustcer created
- rgwood created
- NowackiPatryk created
- wellweek created
- VlkrS created
- dj-sourbrough created
- NotTheDr01ds created