Skip to content
Merged
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
76 changes: 63 additions & 13 deletions blog/2026-09-26-nushell_v0_116_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,49 @@ def complete-from-place [place: record] {
def complete-from-buffer [buffer: string] {
$buffer | split row " "
}
def complete-from-multiple [token: record, place: record, buffer: string] {
#...
}
```

`token` describes the token at the cursor, with fields like `text`, `kind`, and `span`. `place` describes the resolved completion site and replacement range, including fields like `cursor`, `target`, `kind`, `flag`, `index`, and `shape` when applicable. `buffer` is the exact command line from the beginning of the line through the cursor, including text before pipes, inside closures, and after separators.
- `token` describes the token at the cursor, with fields like `text`, `kind`, and `span`.
- `place` describes the resolved completion site and replacement range, including fields like `cursor`, `target`, `kind`, `flag`, `index`, `command` and `shape` when applicable.
- `buffer` is the exact command line from the beginning of the line through the cursor, including text before pipes, inside closures, and after separators.

To demonstrate how they look we'll use the newly added `commandline complete --input` (explained further below) to see what a completer receives:

```nushell
'git checkout mai' | commandline complete --input
```
```nushell :no-line-numbers
{
token: {
text: mai,
kind: value,
span: {
start: 13,
end: 16
}
},
place: {
cursor: 16,
target: {
start: 13,
end: 16
},
kind: positional,
index: 1,
shape: external-argument,
command: [
git,
checkout,
mai
]
},
buffer: "git checkout mai"
}
```

Use `buffer` instead of calling `commandline` from inside a completer. `buffer` is always the line currently being completed; `commandline` can be empty in some editor states, such as after `;`.

Expand All @@ -132,12 +172,11 @@ or, if it really needs the whole line:
source: {|buffer| $buffer }
```

External completers also need to migrate from the old spans-style input to the new named inputs. For example, a whole-line external completer should declare `buffer`:
External completers also need to migrate from the old spans-style input to the new named inputs. For example, a whole-line external completer should declare `buffer` or `place`:

```nushell
$env.config.completions.external.completer = {|buffer|
let words = $buffer | split row " "
carapace ($words | first) nushell ...$words | from json
$env.config.completions.external.completer = {|place|
carapace ($place.command | first) nushell ...$place.command | from json
}
```

Expand Down Expand Up @@ -183,17 +222,28 @@ External completers are closures and cannot carry `@interactive` themselves. To

```nushell
@interactive
def carapace-fzf [buffer: string] {
let words = $buffer | split row " "
carapace ($words | first) nushell ...$words | from json | ^fzf | lines
def carapace-fzf [place: record] {
carapace ($place.command | first) nushell ...$place.command
| from json
| ^fzf
| lines
}
$env.config.completions.external.completer = {|buffer|
carapace-fzf $buffer
$env.config.completions.external.completer = {|place|
carapace-fzf $place
}
```

`commandline complete` gained tools for developing completers. `commandline complete --input` returns the `{token, place, buffer}` record a completer would receive without running the completer. `commandline complete --detailed` returns suggestions in the custom-completer output format. `commandline complete --type directory|path|glob|command|variable|env-var` runs one built-in completion source, which is useful when composing Nushell's built-in completions with custom ones. `--input` cannot be combined with `--detailed` or `--type`.
#### New completion tools

`commandline complete` gained tools for developing completers:
- `commandline complete --input` returns the `{token, place, buffer}` record a completer would receive without running the completer.
- `commandline complete --detailed` returns suggestions in the custom-completer output format.
- `commandline complete --type directory|path|glob|command|variable|env-var` runs one built-in completion source, which is useful when composing Nushell's built-in completions with custom ones.

::: note
`--input` cannot be combined with `--detailed` or `--type`.
:::

Some completion behavior changed as part of this unification:

Expand All @@ -208,8 +258,8 @@ Common migrations:
| Previous form | New form |
|:------------------------------------------|:------------------------------------------------------------------------------------------------|
| `def comp [input pos] { ... }` | `def comp [token: record] { $token.text \| ... }` |
| `def comp [spans] { ... }` | `def comp [buffer: string] { $buffer \| split row " " \| ... }` when whole-line input is needed |
| `{ \|spans\| ... }` external completer | `{ \|buffer: string\| ... }` |
| `def comp [spans] { ... }` | `def comp [place: record] { $place.command \| ... }` |
| `{ \|spans\| ... }` external completer | `{ \|place: record\| ... }` `$place.command` is equivalent to the old `spans` parameter. |
| `{ \|buffer position\| ... }` menu source | `{ \|token: record\| ... }`, `{ \|place: record\| ... }`, or `{ \|buffer: string\| ... }` |
| Global background-completion opt-out | `@interactive` on the terminal-owning completion command |

Expand Down
Loading