nu_cmd_plugin/commands/plugin/
stop.rs1use nu_engine::command_prelude::*;
2use nu_protocol::shell_error::generic::GenericError;
3
4use crate::util::canonicalize_possible_filename_arg;
5
6#[derive(Clone)]
7pub struct PluginStop;
8
9impl Command for PluginStop {
10 fn name(&self) -> &str {
11 "plugin stop"
12 }
13
14 fn signature(&self) -> Signature {
15 Signature::build("plugin stop")
16 .input_output_type(Type::Nothing, Type::Nothing)
17 .required(
18 "name",
19 SyntaxShape::String,
20 "The name, or filename, of the plugin to stop.",
21 )
22 .category(Category::Plugin)
23 }
24
25 fn description(&self) -> &str {
26 "Stop an installed plugin if it was running."
27 }
28
29 fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
30 vec![
31 Example {
32 example: "plugin stop inc",
33 description: "Stop the plugin named `inc`.",
34 result: None,
35 },
36 Example {
37 example: "plugin stop ~/.cargo/bin/nu_plugin_inc",
38 description: "Stop the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
39 result: None,
40 },
41 Example {
42 example: "plugin list | each { |p| plugin stop $p.name }",
43 description: "Stop all plugins.",
44 result: None,
45 },
46 ]
47 }
48
49 fn run(
50 &self,
51 engine_state: &EngineState,
52 stack: &mut Stack,
53 call: &Call,
54 _input: PipelineData,
55 ) -> Result<PipelineData, ShellError> {
56 let name: Spanned<String> = call.req(engine_state, stack, 0)?;
57
58 let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
59
60 let mut found = false;
61 for plugin in engine_state.plugins() {
62 let id = &plugin.identity();
63 if id.name() == name.item || id.filename() == filename {
64 plugin.stop()?;
65 found = true;
66 }
67 }
68
69 if found {
70 Ok(PipelineData::empty())
71 } else {
72 Err(ShellError::Generic(
73 GenericError::new(
74 format!("Failed to stop the `{}` plugin", name.item),
75 "couldn't find a plugin with this name",
76 name.span,
77 )
78 .with_help("you may need to `plugin add` the plugin first"),
79 ))
80 }
81 }
82}