Skip to content
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 200 additions & 10 deletions book/standard_library.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Nushell ships with a standard library of useful commands written in native Nu. By default, the standard library is loaded into memory (but not automatically imported) when Nushell starts.

[[toc]]

## Overview

The standard library currently includes:

- Assertions
Expand All @@ -14,32 +18,218 @@ The standard library currently includes:
To see a complete list of the commands available in the standard library, run the following:

```nu
use std
scope commands
| where name =~ '^std '
| select name usage extra_usage
| wrap "std-lib"
nu -c "
use std
scope commands
| where name =~ '^std '
| select name description extra_description
| wrap 'Standard Library Commands'
| table -e
"
```

::: note
The `use std` command above loads the entire standard library so that you can see all of the commands at once. This is typically not how it will be used (more info below). It is also run in a separate Nu subshell simply so that it is not loaded into scope in the shell you are using.
:::

## Importing the Standard Library

While working at the commandline, it can be convenient to load the entire standard library using:

```nu
use std *
```

However, this form should be avoided in custom commands and scripts since it has the longest load time. While the load time is only on the order of ~20-30 milliseconds on an average system, that can add up in certain scenarios.

::: important Optimal Startup when Using the Standard Library
See the [notes below](#optimal-startup) on how to ensure that your configuration isn't loading the entire Standard Library.
:::

### Importing Submodules

Each submodule of the standard library can be loaded separately. Again, for best performance, load only the submodule(s) that you need in your code.

There are several forms that can be used:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the following points go too much into how modules work, that's not necessary. We can link to https://www.nushell.sh/book/modules.html where it's explained already (although it also needs improvements).

Here you can just say that std is a “virtual” directory and the iter, help are submodules in it, defined as module directories. Linking to https://github.com/nushell/nushell/tree/main/crates/nu-std/std would be helpful to show the module directory structure.

We don't want to teach users to invoke magic incantations. std is a normal module like any other module. We shouldn't give an impression that there is anything special about it.

I think you can formulate the points as something like (very abbreviated version):

The std submodules were designed to be used in different ways

  1. Import the submodule as subcommands
    Some modules follow a subcommand structure and meant to be imported as use std/<submodule>.
    a) E.g., use std/iter ... defines iter xxxsubcommands
    b) Same, but designed to shadow existing commands, e.g., use std/help.
    ... list all modules in this style
  2. Import the contents of the module directly
    These modules were designed to make their content available in the current scope with use std/<submodule> *.
    ... list all modules in this style
  3. Import specific definitions -- IMO this point is not necessary
  4. Good

When in doubt, checked the source code of the module (linked above).

The terms “prefix” or “namespace” are not very well-defined in Nushell and can be confusing. You can use “scope”, or talk about defining subcommands.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree with you on both points. (1) We should be able to point to the Modules chapter, and yet (2) the Modules chapter needs a lot of attention. One of the things we should (i.e., I plan to do) is split out Modules into "Using Modules" and "Writing Modules". At the moment, a reader would have to wade through all of the "writing" information just to find out how to import the different forms.

I'd like to keep this section mostly intact for now, and as soon as I get a chance I'll work on the Modules rewrite. I can use std submodules for the examples in the "Using Modules" chapter (or subchapter) since:

  1. As you mention std is just a standard module/submodule design - Nothing special.
  2. It's already on the user's system with no need to come up with "fake examples"
  3. I can just move (not duplicate) some of this to that chapter where it belongs.

Does that sound like an acceptable path?


#### 1. Import the submodule

Examples:

```nu
use std/iter
[2 5 "4" 7] | iter filter-map {|it| $it ** 2}

use std/help
help ls
help commands
```

This form requires that you prefix the command using the submodule name. This can be useful in two scenarios.

1. In the `use std/iter` example, it's important to prefix the commands with the `iter` namespace. If, on the other hand, you were to `use std/iter *`, you would shadow the built-in `find` command with the `iter` module's `find` command.

2. In the `use std/help` example, `help` is both the submodule name and the name of the main command it exports. Using `use std/help` allows you to access:

```nu
help
help aliases
help modules
help commands
help operators
help externs
```

In this case, the `std/help` commands are meant to shadow (replace) the built-in versions.

Submodules that are normally imported with `use std/<submodule>`:

- `use std/assert`: `assert` and its subcommands
- `use std/bench`: The benchmarking command `bench`
- `use std/dirs`: The directory stack command `dirs` and its subcommands
- `use std/input`: The `input display` command
- `use std/help`: An alternative version of the `help` command and its subcommands which supports completion and other features
- `use std/iters`: Additional `iters`-prefixed iteration commands. Note: See-also alternative option #3 below.
- `use std/log`: The `log <subcommands>` such as `log warning <msg>`
- `use std/math`: Mathematical constants such as `$math.E`. These can also be imported without a prefix using Form #2 below.

#### 2. Import all submodule commands without a prefix

For certain submodules, you will want the commands from a submodule to be available in the current namespace, so that you _can_ simply access the command by name. For instance:

```nu
use std/formats *
ls | to jsonl
```

Submodules that are normally imported with `use std/<submodule> *`:

- `use std/dt *`: Additional commands for working with `date` values
- `use std/formats *`: Additional `to` and `from` format conversions
- `use std/math *`: The math constants without a prefix, such as `$E`. Note that the prefixed form #1 above is likely more understandable when reading and maintaining code.
- `use std/xml *`: Additional commands for working with XML data

#### 3. Importing specific subcommands

As with most modules, you can choose to import only a subset of the commands. For instance, the following would import the `zip-with` command without requiring that it be called with`iter zip-with`.

```nu
use std/iter [ zip-with ]
```

#### 4. Not Recommended - `use std <submodule>` and `use std <submodule> *`

While it is _possible_ to import Standard Library submodules using a space-separated form:

```nu
use std log
use std formats *
```

This is NOT RECOMMENDED. Using this form has the same performance impact as:

```nu
use std *
```

::: caution
The difference is subtle, but important from a performance perspective. Using `std/<submodules>` (with a slash) is far faster than `std <submodule>` (with a space):

```nu
bench -n 200 --pretty { nu -c "use std/formats *; exit" }
# => 9ms 271µs 832ns +/- 328µs 860ns
bench -n 200 --pretty { nu -c "use std formats *; exit" }
# => 26ms 921µs 59ns +/- 588µs 919ns
```

In addition, `stdlib-candidate`, found in the [nu_scripts Repository](https://github.com/nushell/nu_scripts/tree/main/stdlib-candidate/std-rfc), serves as a staging ground for new commands before they are added to the standard library.
:::

## The Standard Library Candidate Module

(Also known as `std-rfc`)

`stdlib-candidate`, found in the [nu_scripts Repository](https://github.com/nushell/nu_scripts/tree/main/stdlib-candidate/std-rfc), serves as a staging ground for new commands before they are added to the Standard Library.

If you are interested in adding to the Standard Library, please submit your code via PR to the Candidate module in that repository. We also encourage you to install this module and provide feedback on upcoming candidate commands.

::: details More details

Candidate commands for the Standard Library should, in general:

- Have broad appeal - Be useful to a large number of users or use cases
- Be well-written and clearly commented for future maintainers
- Implement help comments with example usage
- Have a description that explains why you feel the command should be a part of the standard library. Think of this as an "advertisement" of sorts to convince people to try the command and provide feedback so that it can be promoted in the future.

In order for a command to be graduated from RFC to the Standard Library, it must have:

- Positive feedback
- Few (or no) outstanding issues and, of course, no significant issues
- A PR author for the `std` submission. This does not necessarily have to be the original author of the command.
- Test cases as part of the `std` submission PR

Ultimately a member of the core team will decide when and if to merge the command into `std` based on these criteria.

Of course, if a candidate command in `std-rfc` no longer works or has too many issues, it may be removed from or disabled in `std-rfc`.

::: tip Note
Currently, parsing of the standard library impacts Nushell startup time. New commands are not being added to the library until this is resolved.
:::

## Disabling the Standard Library

To disable the standard library, you can start using:

```nu
nu --no-std-lib
```

You will not be able to import the library using `use std *`, nor use any of its commands, if it is disabled in this way.
This can be especially useful to minimize overhead when running a command in a subshell using `nu -c`. For example:

```nu
nu --no-std-lib -n -c "$nu.startup-time"
# => 1ms 125µs 10ns

nu -n -c "$nu.startup-time"
# => 4ms 889µs 576ns
```

You will not be able to import the library, any of its submodules, nor use any of its commands, when it is disabled in this way.

## Optimal Startup

If Nushell's startup time is important to your workflow, review your [startup configuration]([./configuration.md]) in `config.nu`, `env.nu`, and potentially others for inefficient use of the standard library. The following command should identify any problem areas:

```nu
view files
| enumerate | flatten
| where filename !~ '^std'
| where filename !~ '^entry'
| where {|file|
(view span $file.start $file.end) =~ 'use\W+std[^\/]'
}
```

Edit those files to use the recommended syntax below.
:::

::: note
If a Nushell library (e.g., from [the `nu_scripts` repository](https://github.com/nushell/nu_scripts)), example, or doc is using this syntax, please report it via an issue or PR. These will be updated over time after Nushell 0.99.0 is released.

If a third-party module is using this syntax, please report it to the author/maintainers to update.
:::

## Viewing Standard Library Source

::: tip Did You Know?
Because the standard library is simply composed of [custom commands](./custom_commands.html) in [modules](./modules.html) and [submodules](./modules.html#submodules-and-subcommands), you can see the source for each command with the [`view source`](/commands/docs/view_source.md) command. For example, to view the source for the `ellie` command (with syntax highlighting):

```nu
use std *
use std/util *
view source ellie | nu-highlight
:::

## Windows Path Syntax

::: important
Nushell on Windows supports both forward-slashes and back-slashes as the path separator. However, to ensure cross-platform support for scripts and modules using `std`, using only the forward-slash `/` when importing Standard Library submodules is highly recommended.
:::
```