Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions .vuepress/configs/sidebar/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const sidebarEn: SidebarConfig = {
'/book/overlays.md',
'/book/sorting.md',
'/book/testing.md',
'/book/debugging.md',
'/book/style_guide.md',
],
},
Expand Down Expand Up @@ -119,6 +120,7 @@ export const sidebarEn: SidebarConfig = {
'/book/plugins.md',
'/book/explore.md',
'/book/tui.md',
'/book/mcp.md',
],
},
],
Expand Down
5 changes: 4 additions & 1 deletion book/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ next:
text: Standard Library
link: /book/standard_library.md
---

# (Not so) Advanced

While the "Advanced" title might sound daunting and you might be tempted to skip this chapter, in fact, some of the most interesting and powerful features can be found here.
Expand All @@ -24,5 +25,7 @@ Thanks to Nushell's strict scoping rules, it is very easy to [iterate over colle

You can [interactively explore data](explore.md) with the [`explore`](/commands/docs/explore.md) command, and you can [build your own terminal user interfaces](tui.md), such as pickers, dialogs, and dashboards, with the `tui` family of commands.

Finally, you can extend Nushell's functionality with [plugins](plugins.md).
You can extend Nushell's functionality with [plugins](plugins.md).
Almost anything can be a plugin as long as it communicates with Nushell in a protocol that Nushell understands.

Finally, Nushell can run as an [MCP server](mcp.md), so AI agents and other Model Context Protocol clients can look up its commands and run Nushell code.
39 changes: 38 additions & 1 deletion book/aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Running `help` on an alias shows what it expands to, followed by the help for th
def greet [name: string] { $"Hello, ($name)!" }
alias hi = greet
help hi
# => Alias for greet
# => Alias for `greet`
# =>
# => Alias: hi
# =>
Expand Down Expand Up @@ -74,6 +74,43 @@ help hi
# => ╰───┴───────┴────────╯
```

When an alias runs a subcommand, `help` on the parent command lists the alias under its own name, right after the subcommand it runs:

```nu
# Manage notes
def notes [] {}
# Add a note
def "notes add" [text: string] {}
# List notes
def "notes list" [] {}
alias nl = notes list
help notes
# => Manage notes
# =>
# => Usage:
# => > notes
# =>
# => Subcommands:
# => notes add (custom) - Add a note
# => notes list (custom) - List notes
# => nl (alias) - Alias for `notes list`
# =>
# => Flags:
# => -h, --help: Display the help message for this command
# =>
# => Command Type:
# => > custom
# =>
# => Input/output types:
# => ╭───┬───────┬────────╮
# => │ # │ input │ output │
# => ├───┼───────┼────────┤
# => │ 0 │ any │ any │
# => ╰───┴───────┴────────╯
```

The same works for built-in commands: after `alias st = str trim`, `help str` lists `st (alias)` right after `str trim`. Hidden commands and aliases are left out.

## Persisting

To make your aliases persistent they must be added to your _config.nu_ file by running `config nu` to open an editor and inserting them, and then restarting nushell.
Expand Down
10 changes: 10 additions & 0 deletions book/background_jobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ next:
text: Coming to Nu
link: /book/coming_to_nu.md
---

# Background Jobs

Nushell currently has experimental support for thread-based background jobs.
Expand Down Expand Up @@ -175,3 +176,12 @@ for spawning independent background processes (see [#15201](https://github.com/n
Additionally, if the user is running an interactive Nushell session and runs
[`exit`](/commands/docs/exit.md) while there are background jobs running,
the shell will warn about them before prompting the user to confirm `exit`.

Pressing <kbd>Ctrl</kbd>+<kbd>C</kbd> at the REPL interrupts only the command running in the foreground.
Background jobs and frozen jobs keep running.

When Nushell runs a script or a command given with `nu -c`, it stops any jobs that are still running,
along with their child processes, before it exits. This also happens when the script was interrupted
with <kbd>Ctrl</kbd>+<kbd>C</kbd> and the interruption was caught.

Calling `exit` inside a job's closure ends that job, not the shell.
5 changes: 5 additions & 0 deletions book/coming_from_bash.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ $env.Path = ($env.Path | prepend 'C:\Program Files\Git\usr\bin')
| `sed` | `str replace` | Find and replace a pattern in a string |
| `grep <pattern>` | `where $it =~ <substring>` or `find <substring>` | Filter strings that contain the substring |
| `grep -i <pattern>` | `find -i <substring>` | Filter strings that contain the substring, ignoring case |
| `grep -o <regex>` | `find -o -r <regex>` | Output only the matched text, one value per match |
| `man <command>` | `help <command>` | Get the help for a given command |
| | `help commands` | List all available commands |
| | `help --find <string>` | Search for match in all available commands |
Expand Down Expand Up @@ -87,6 +88,10 @@ $env.Path = ($env.Path | prepend 'C:\Program Files\Git\usr\bin')
| `read var` | `let var = input` | Get input from the user |
| `read -s secret` | `let secret = input -s` | Get a secret value from the user without printing keystrokes |

::: tip
In Nushell, `type` is the keyword that declares a [type alias](./custom_commands.md#type-aliases), so `type FOO` is a parse error rather than a command lookup. Use `which FOO` instead. If your system has an external `type` program (macOS has `/usr/bin/type`), run it as `^type FOO`.
:::

## History Substitutions and Default Keybindings:

| Bash | Nu | Task |
Expand Down
4 changes: 3 additions & 1 deletion book/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ $env.PROMPT_COMMAND_RIGHT = {

`commandline set-prompt` sets the left prompt by default. Use `--right`, `--indicator`, `--vi-insert`, `--vi-normal`, or `--multiline` to set the other prompt components. The new text lasts until the next prompt is drawn.

A job started from a prompt closure, or from a `pre_prompt` or `env_change` [hook](./hooks.md), can finish before the prompt is drawn, for example when `git` answers quickly. Its `commandline set-prompt` still shows on that prompt. The same is true when a hook or prompt closure calls `commandline set-prompt` directly: the pushed text replaces what the prompt variable gives that segment.

### ENV_CONVERSIONS

Certain variables, such as those containing multiple paths, are often stored as a
Expand Down Expand Up @@ -665,6 +667,7 @@ The following stages and their steps _may_ occur during startup, based on the fl
- ❌ Does not enter the REPL
- ❌ Does not source the files in `vendor-autoload-dirs`
- ❌ Does not source the files in `user-autoload-dirs`

- `nu -l -c "ls"`:

- ✅ Makes the Standard Library available
Expand Down Expand Up @@ -751,4 +754,3 @@ The following stages and their steps _may_ occur during startup, based on the fl
- ❌ Does not enter the REPL
- ❌ Does not source the files in `vendor-autoload-dirs`
- ❌ Does not source the files in `user-autoload-dirs`

31 changes: 17 additions & 14 deletions book/control_flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ match $foo {

The `_` in the second branch means it matches any record with field `name` and `count`, not just ones where `name` is `'bar'`.

Lists unpack the same way. In a list pattern, `..` stands for any number of items, and it can go at the start, in the middle, or at the end. `..$name` also binds those items to a variable:

```nu
let steps = [build test done]
match $steps {
[] => 'nothing to do',
[.., 'done'] => 'finished',
[$current, ..] => $"running ($current)"
}
# => finished
```

#### Guards

You can also add an additional condition to each branch called a "guard" to determine if the branch should be matched. To do so, after the matched pattern put `if` and then the condition before the `=>`.
Expand Down Expand Up @@ -218,30 +230,21 @@ $result
# => ╰───┴───╯
```

When creating custom errors, loops have an advantage over pipelines because they don't fail evaluation.

Creating an error in a pipeline yields a pipeline evaluation error *and* the custom error:
Errors, on the other hand, are not a reason to pick one over the other. When the closure given to `each` fails, Nushell reports the closure's own error, with an extra `source value` label on the input item that was being processed:

```nu
[0] | each { error make { msg: "Custom error" } | default '' }
# => Error: nu::shell::eval_block_with_input
# => Error: nu::shell::error
# =>
# => × Eval block failed with pipeline input
# => × Custom error
# => ╭─[repl_entry #1:1:2]
# => 1 │ [0] | each { error make { msg: "Custom error" } | default '' }
# => · ┬
# => · ┬ ───────────────────────
# => · ╰── source value
# => ╰────
# =>
# => Error:
# => × Custom error
# => ╭─[repl_entry #1:1:25]
# => 1 │ [0] | each { error make { msg: "Custom error" } | default '' }
# => · ───────────────────────
# => ╰────
```

When using a loop, a `for` loop in this example, evaluation succeeds and only the created error occurs:
A `for` loop reports the same error, without the `source value` label:

```nu
for x in [0] { error make { msg: "Custom error" } }
Expand Down
50 changes: 47 additions & 3 deletions book/custom_commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,11 @@ Strings which might be confused with other parser patterns should be avoided. Fo

- `1`, `"1"`, or `"1.5"`: Nushell will not allow numbers to be used as command names
- `4MiB` or `"4MiB"`: Nushell will not allow filesizes to be used as command names
- `"number#four"` or `"number^four"`: Carets and hash symbols are not allowed in command names
- `"number#four"`, `"number^four"`, or `"number%four"`: Carets, hash symbols, and percent signs are not allowed in command names
- `"foo bar"`, `" foo"`, or `"foo "`: The words of a command name must be separated by single spaces, with no leading or trailing whitespace. Such a name could never be called, so `def`, `extern`, and `alias` reject it.
- `-a`, `"{foo}"`, `"(bar)"`: Will not be callable, as Nushell will interpret them as flags, closures, or expressions.

Parser keywords such as `if`, `for`, `let`, `def`, `use` or `where` can't be used as command names at all, because shadowing them would break the language constructs they implement:
Parser keywords such as `if`, `for`, `let`, `def`, `type`, `use` or `where` can't be used as command names at all, because shadowing them would break the language constructs they implement:

```nu
def if [] { "my if" }
Expand Down Expand Up @@ -553,7 +554,7 @@ Most types can be used as type-annotations. In addition, there are a few "shapes
- `path`: A string that is treated as a filesystem path. A leading `~` is expanded to the home directory, and "n-dot" shorthands such as `...` are expanded to `../..`. Relative paths stay relative: `.` stays `.`, and `foo/../bar` becomes `bar`. See [Path](/lang-guide/chapters/types/other_types/path.html) in the Language Reference Guide for example usage.
- `directory`: A subset of `path` (above). Only directories will be offered when using tab-completion for the parameter. Expansions take place just as with `path`.
- `external_arg`: Parses the argument the way an [external command](./running_externals.md) would. A bare word is kept exactly as typed, so `0001` or `true` is not turned into an `int` or `bool`, while quoted strings, variables and subexpressions keep their own value. This is mainly useful for the `main` command of a [script](./scripts.md) that receives arguments from another shell.
- `oneof<...>`: Accepts any one of the listed types, for example `oneof<int, string>`.
- `oneof<...>`: Accepts any one of the listed types, for example `oneof<int, string>`. A literal argument gets the first listed type that it matches, with the text-like types (`string`, `path`, `directory`, `glob`, `cell-path`, `external_arg`, and `any`) tried last whatever their position. So with `oneof<string, list<string>>`, `[foo bar]` is a list, and with `oneof<string, int>`, `5` (and `007`) is an `int`. Quote the argument if you need the text.
- `error`: Available, but currently no known valid usage. See [Error](/lang-guide/chapters/types/other_types/error.html) in the Language Reference Guide for more information.

For example, compare an untyped parameter with an `external_arg` parameter:
Expand Down Expand Up @@ -590,6 +591,49 @@ The following [types](./types_of_data.html) can be used for parameter annotation

:::

### Type Aliases

When several commands take or return the same structured data, writing out a type like `record<x: float, y: float>` each time gets long and easy to get wrong. The [`type`](/commands/docs/type.md) keyword gives a type a name:

```nu
type Point = record<x: float, y: float>
type Polygon = list<Point>

def first-x [poly: Polygon]: nothing -> float { $poly.0.x }

first-x [{x: 1.0, y: 2.0} {x: 3.0, y: 4.0}]
# => 1.0
```

A type alias is only a shorter way to write its type. The parser replaces the name with the full type wherever the name is used, so `help`, [`describe`](/commands/docs/describe.md), and error messages show the full type:

```nu
type Point = record<x: float, y: float>
def length-of [p: Point]: nothing -> float { ($p.x ** 2 + $p.y ** 2) | math sqrt }

length-of {x: 1, y: 2}
# => Error: nu::parser::type_mismatch
# =>
# => × Type mismatch.
# => ╭─[repl_entry #3:1:11]
# => 1 │ length-of {x: 1, y: 2}
# => · ──────┬─────
# => · ╰── expected record<x: float, y: float>, found record<x: int, y: int>
# => ╰────
```

You can use a type alias anywhere a type annotation goes: positional parameters, flags, rest parameters, closure parameters, input/output types, the annotations of `let`, `mut`, and `const`, inside other types (such as `list<Point>`), and on the right-hand side of another `type`.

A few rules apply:

- Like [`alias`](./aliases.md) and `const`, a type alias is visible from its definition to the end of the enclosing block. It must be defined above its first use, and it can't refer to itself.
- A custom completer belongs to the parameter, not the type. Write it on the parameter, as in `def paint [color: Color@[red green blue]] { ... }`. `type Color = string@[red green blue]` is an error.
- In a module, a type alias is private unless it is defined with `export type`. See [Modules](./modules/creating_modules.md#exports) for how to export one and [Using Modules](./modules/using_modules.md#importing-type-aliases) for how to import it.

::: warning
`type` is a parser keyword, so a custom command, alias, or extern can't be named `type`. To run an external command named `type`, call it as `^type`, or use Nushell's [`which`](/commands/docs/which.md) to see what a command name refers to.
:::

### Flags

In addition to positional parameters, you can also define named flags.
Expand Down
16 changes: 15 additions & 1 deletion book/custom_completions.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,20 @@ def --wrapped jc [...args] {
}
```

A `def --wrapped` command passes flags it doesn't declare on to its rest parameter. So a completer on that rest parameter is also called for arguments that start with `-`, and its suggestions are listed together with the command's own flags:

```nu
def "nu-complete what" [] { [--verbose --color=always plain] }
def --wrapped what [--local, ...args: string@"nu-complete what"] { $args }

'what --' | commandline complete
# => ╭───┬────────────────╮
# => │ 0 │ --local │
# => │ 1 │ --color=always │
# => │ 2 │ --verbose │
# => ╰───┴────────────────╯
```

## Custom Descriptions and Styles

As an alternative to returning a list of strings, a completion function can also return a list of records with a `value` field and any of these optional fields:
Expand Down Expand Up @@ -370,7 +384,7 @@ def open-file [path: string@pick-file] {
}
```

Typing `open-file ` and pressing <kbd>Tab</kbd> opens `fzf`, and the file you pick is inserted into the command line.
Typing `open-file ` and pressing <kbd>Tab</kbd> opens `fzf`, and the file you pick is inserted into the command line. If you cancel the picker instead (for example with <kbd>Esc</kbd>), nothing is inserted and no menu stays open; pressing <kbd>Tab</kbd> again opens the picker again.

## Testing Completers

Expand Down
Loading
Loading