Skip to content

Commit

Permalink
Plugin management overhaul docs - new commands and new file format (#…
Browse files Browse the repository at this point in the history
…1367)

* Documentation for the plugin.msgpackz overhaul

* find more `register` cases

* add docs related to `plugin use`

* plugin cache file ⇒ plugin registry file
  • Loading branch information
devyn committed Apr 30, 2024
1 parent 5c82772 commit 0a7a6e8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 24 deletions.
4 changes: 2 additions & 2 deletions book/cheat_sheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,8 @@
> This expression results in error.**
```nu
> const plugin = 'path/­to/­plugin'
> register $plugin
> const file = 'path/­to/­file.nu'
> source $file
```

> **a constant variable is immutable value which is fully evaluated at parse-time**
Expand Down
43 changes: 28 additions & 15 deletions book/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,44 +32,51 @@ If you chose to download the git repository instead, run this when inside the cl
> cargo install --path .
```

This will create a binary file that can be used to register the plugin.
This will create a binary file that can be used to add the plugin.

Keep in mind that when installing using crates.io, the binary can be saved in different locations depending on how your system is set up. A typical location is in the users's home directory under .cargo/bin.

## Registering a plugin
## Adding a plugin

To enable an installed plugin, call the [`register`](/commands/docs/register.md) command to tell Nu where to find it. As you do, you'll need to also tell Nushell what encoding the plugin uses.
To add a plugin to the plugin registry file, call the [`plugin add`](/commands/docs/plugin_add.md) command to tell Nu where to find it.

Please note that the plugin name needs to start with `nu_plugin_`, Nu uses the name prefix to detect plugins.

Linux+macOS:

```nu
> register ./my_plugins/nu_plugin_cool
> plugin add ./my_plugins/nu_plugin_cool
```

Windows:

```nu
> register .\my_plugins\nu_plugin_cool.exe
> plugin add .\my_plugins\nu_plugin_cool.exe
```

When [`register`](/commands/docs/register.md) is called:
When [`plugin add`](/commands/docs/plugin_add.md) is called, Nu runs the plugin binary and communicates via the [plugin protocol](plugin_protocol_reference.md) to get the signatures of all of the commands the plugin supports. It then saves information about the plugin, including the command signatures, to the plugin registry file at `$nu.plugin-path` in a custom brotli-compressed MessagePack format. This caching step saves `nu` from having to run all plugins during startup, which could be very slow.

1. Nu launches the plugin, and waits for the plugin to tell Nu which communication encoding it should use
2. Nu sends it a "Signature" message over stdin
3. The plugin responds via stdout with a message containing its signature (name, description, arguments, flags, and more)
4. Nu saves the plugin signature in the file at `$nu.plugin-path`, so registration is persisted across multiple launches

Once registered, the plugin is available as part of your set of commands:
Once added, the next time `nu` is started, the plugin's commands are available as part of your set of commands:

```nu
> help commands | where command_type == "plugin"
```

You can also immediately reload a plugin in the current session by calling `plugin use`:

```nu
> plugin use cool
```

Note that `plugin use` is a parser keyword, so when evaluating a script, it will be evaluated first. This means that while you can execute `plugin add` and then `plugin use` at the REPL on separate lines, you can't do this in a single script. If you need to run `nu` with a specific plugin or set of plugins without preparing a cache file, you can pass the `--plugins` option to `nu` with a list of plugin executable files:

```nu
> nu --plugins '[./my_plugins/nu_plugin_cool]'
```

### Updating a plugin

When updating a plugin, it is important to run `register` again just as above to load the new signatures from the plugin and allow Nu to rewrite them to the plugin file (`$nu.plugin-path`).
When updating a plugin, it is important to run `plugin add` again just as above to load the new signatures from the plugin and allow Nu to rewrite them to the plugin file (`$nu.plugin-path`). You can then `plugin use` to get the updated signatures within the current session.

## Managing plugins

Expand All @@ -96,7 +103,7 @@ To view the list of plugins you have installed:
╰───┴─────────┴────────────┴─────────┴───────────────────────┴───────┴───────────────────────────────╯
```

Plugins stay running while they are in use, and are automatically stopped by default after a period of time of inactivity. This behavior is managed by the [plugin garbage collector](#plugin-garbage-collector). To manually stop a plugin:
Plugins stay running while they are in use, and are automatically stopped by default after a period of time of inactivity. This behavior is managed by the [plugin garbage collector](#plugin-garbage-collector). To manually stop a plugin, call `plugin stop` with its name:

```nu
> plugin stop gstat
Expand Down Expand Up @@ -144,7 +151,13 @@ For more information on exactly under what circumstances a plugin is considered

## Removing a plugin

To remove a plugin, edit the `$nu.plugin-path` file and remove all of the `register` commands referencing the plugin you want to remove, including the signature argument.
To remove a plugin, call `plugin rm` with the name of the plugin you want to remove. For example, if you previously added the plugin `~/.cargo/bin/nu_plugin_gstat`, its name would be `gstat`. To remove it:

```nu
plugin rm gstat
```

You can check the name of a plugin by running `plugin list`.

## Examples

Expand Down
6 changes: 3 additions & 3 deletions book/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ To use mutable variables for such behaviour, you are encouraged to use the loops

### Constant Variables

A constant variable is an immutable variable that can be fully evaluated at parse-time. These are useful with commands that need to know the value of an argument at parse time, like [`source`](/commands/docs/source.md), [`use`](/commands/docs/use.md) and [`register`](/commands/docs/register.md). See [how nushell code gets run](how_nushell_code_gets_run.md) for a deeper explanation. They are declared using the `const` keyword
A constant variable is an immutable variable that can be fully evaluated at parse-time. These are useful with commands that need to know the value of an argument at parse time, like [`source`](/commands/docs/source.md), [`use`](/commands/docs/use.md) and [`plugin use`](/commands/docs/plugin_use.md). See [how nushell code gets run](how_nushell_code_gets_run.md) for a deeper explanation. They are declared using the `const` keyword

```nu
const plugin = 'path/to/plugin'
register $plugin
const script_file = 'path/to/script.nu'
source $script_file
```

## Variable Names
Expand Down
16 changes: 12 additions & 4 deletions contributor-book/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ For more detailed information about how exactly this communication works, especi

## Discovery

Nu keeps a registry of plugins at the file system location defined by configuration variable `$nu.plugin-path`. To register a plugin, execute `register <path_to_plugin_executable>` in a Nu shell.
Nu keeps a registry of plugins known as the ‘plugin registry file’ at the file system location defined by configuration variable `$nu.plugin-path`. To add a plugin, execute `plugin add <path_to_plugin_executable>` in a Nu shell. The plugin's signatures will be added to the plugin registry file for future launches of Nu. To make them available immediately, call `plugin use <plugin_name>`.

## Launch environment

Expand Down Expand Up @@ -241,13 +241,19 @@ Here we import everything we need -- types and functions -- to be able to create

Once we have finished our plugin, to use it all we need to do is install it.

```sh
```nu
> cargo install --path .
# nushell only (run with `nu -c` if not in nushell)
> plugin add ~/.cargo/bin/nu_plugin_len # add .exe on Windows
```

Once `nu` starts up, it will discover the plugin and register it as a command.
If you're already running `nu` during the installation process of your plugin, ensure you restart `nu` so that it can load your plugin, or call `plugin use` to load it immediately:

```nu
> plugin use len # the name of the plugin (without `nu_plugin_`)
```

If you're already running `nu` during the installation process of your plugin, ensure you restart `nu` so that it can load and register your plugin or register it manually with `register ./target/release/nu_plugin_len`.
Once `nu` starts up, it will discover the plugin and add its commands to the scope.

```
> nu
Expand All @@ -266,6 +272,8 @@ Signatures:
<string> | len -> <int>
```

Run `plugin list` to see all plugins currently registered and available to this Nu session, including whether or not they are running, and their process ID if so.

## Using streams in plugins

The `SimplePluginCommand` trait that we just implemented for our plugin does not support streaming input or output. If we want to extend our plugin to support determining the lengths of lists, it would be helpful to not have to consume an entire list that is a stream. We can do this by implementing `PluginCommand` instead.
Expand Down

0 comments on commit 0a7a6e8

Please sign in to comment.