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