nushell/src
Andy Gayton 7b82c6b482
feat: make ctrlc available to plugins (#13181)
# Description

This PR adds a new method to `EngineInterface`: `register_ctrlc_handler`
which takes a closure to run when the plugin's driving engine receives a
ctrlc-signal. It also adds a mirror of the `signals` attribute from the
main shell `EngineState`.

This is an example of how a plugin which makes a long poll http request
can end the request on ctrlc:
https://github.com/cablehead/nu_plugin_http/blob/main/src/commands/request.rs#L68-L77

To facilitate the feature, a new attribute has been added to
`EngineState`: `ctrlc_handlers`. This is a Vec of closures that will be
run when the engine's process receives a ctrlc signal.

When plugins are added to an `engine_state` during a `merge_delta`, the
engine passes the ctrlc_handlers to the plugin's
`.configure_ctrlc_handler` method, which gives the plugin a chance to
register a handler that sends a ctrlc packet through the
`PluginInterface`, if an instance of the plugin is currently running.

On the plugin side: `EngineInterface` also has a ctrlc_handlers Vec of
closures. Plugin calls can use `register_ctrlc_handler` to register a
closure that will be called in the plugin process when the
PluginInput::Ctrlc command is received.

For future reference these are some alternate places that were
investigated for tying the ctrlc trigger to transmitting a Ctrlc packet
through the `PluginInterface`:

- Directly from `src/signals.rs`: the handler there would need a
reference to the Vec<Arc<RegisteredPlugins>>, which would require us to
wrap the plugins in a Mutex, which we don't want to do.

- have `PersistentPlugin.get_plugin` pass down the engine's
CtrlcHandlers to .get and then to .spawn (if the plugin isn't already
running). Once we have CtrlcHandlers in spawn, we can register a handler
to write directly to PluginInterface. We don't want to double down on
passing engine_state to spawn this way though, as it's unpredictable
because it would depend on whether the plugin has already been spawned
or not.

- pass `ctrlc_handlers` to PersistentPlugin::new so it can store it on
itself so it's available to spawn.

- in `PersistentPlugin.spawn`, create a handler that sends to a clone of
the GC event loop's tx. this has the same issues with regards to how to
get CtrlcHandlers to the spawn method, and is more complicated than a
handler that writes directly to PluginInterface

# User-Facing Changes

No breaking changes

---------

Co-authored-by: Ian Manske <ian.manske@pm.me>
2024-07-30 08:29:18 -05:00
..
command.rs Change the error style during tests to plain (#13061) 2024-06-18 21:37:24 -07:00
config_files.rs Use directories for autoloading (#13382) 2024-07-19 03:47:07 -07:00
ide.rs Use CommandType in more places (#12832) 2024-05-18 23:37:31 +00:00
logger.rs Add options for filtering the log output from nu (#13044) 2024-06-05 16:42:55 +08:00
main.rs Switch from dirs_next 2.0 to dirs 5.0 (#13384) 2024-07-16 07:16:26 -05:00
README.md Remove old nushell/merge engine-q 2022-02-07 14:54:06 -05:00
run.rs Internal representation (IR) compiler and evaluator (#13330) 2024-07-10 17:33:59 -07:00
signals.rs feat: make ctrlc available to plugins (#13181) 2024-07-30 08:29:18 -05:00
terminal.rs Deduplicate nix dependency versions (#12307) 2024-03-27 16:43:37 +01:00
test_bins.rs Revert "Remove std::env::set_current_dir() call from EngineState::merge_env()" (#12954) 2024-05-24 11:09:59 -05:00

Nushell REPL

This directory contains the main Nushell REPL (read eval print loop) as part of the CLI portion of Nushell, which creates the nu binary itself.

Current versions of the nu binary will use the Nu argument parsing logic to parse the commandline arguments passed to nu, leaving the logic here to be a thin layer around what the core libraries.