Skip to main content

nu_cmd_plugin/commands/plugin/
rm.rs

1use nu_engine::command_prelude::*;
2use nu_protocol::shell_error::generic::GenericError;
3
4use crate::util::{canonicalize_possible_filename_arg, modify_plugin_file};
5
6#[derive(Clone)]
7pub struct PluginRm;
8
9impl Command for PluginRm {
10    fn name(&self) -> &str {
11        "plugin rm"
12    }
13
14    fn signature(&self) -> Signature {
15        Signature::build(self.name())
16            .input_output_type(Type::Nothing, Type::Nothing)
17            // This matches the option to `nu`
18            .named(
19                "plugin-config",
20                SyntaxShape::Filepath,
21                "Use a plugin registry file other than the one set in `$nu.plugin-path`.",
22                None,
23            )
24            .switch(
25                "force",
26                "Don't cause an error if the plugin name wasn't found in the file.",
27                Some('f'),
28            )
29            .required(
30                "name",
31                SyntaxShape::String,
32                "The name, or filename, of the plugin to remove.",
33            )
34            .category(Category::Plugin)
35    }
36
37    fn description(&self) -> &str {
38        "Remove a plugin from the plugin registry file."
39    }
40
41    fn extra_description(&self) -> &str {
42        "
43This does not remove the plugin commands from the current scope or from `plugin
44list` in the current shell. It instead removes the plugin from the plugin
45registry file (by default, `$nu.plugin-path`). The changes will be apparent the
46next time `nu` is launched with that plugin registry file.
47
48This can be useful for removing an invalid plugin signature, if it can't be
49fixed with `plugin add`.
50"
51        .trim()
52    }
53
54    fn search_terms(&self) -> Vec<&str> {
55        vec!["remove", "delete", "signature"]
56    }
57
58    fn examples(&self) -> Vec<Example<'_>> {
59        vec![
60            Example {
61                example: "plugin rm inc",
62                description: "Remove the installed signatures for the `inc` plugin.",
63                result: None,
64            },
65            Example {
66                example: "plugin rm ~/.cargo/bin/nu_plugin_inc",
67                description: "Remove the installed signatures for the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
68                result: None,
69            },
70            Example {
71                example: "plugin rm --plugin-config polars.msgpackz polars",
72                description: "Remove the installed signatures for the `polars` plugin from the \"polars.msgpackz\" plugin registry file.",
73                result: None,
74            },
75        ]
76    }
77
78    fn run(
79        &self,
80        engine_state: &EngineState,
81        stack: &mut Stack,
82        call: &Call,
83        _input: PipelineData,
84    ) -> Result<PipelineData, ShellError> {
85        let name: Spanned<String> = call.req(engine_state, stack, 0)?;
86        let custom_path = call.get_flag(engine_state, stack, "plugin-config")?;
87        let force = call.has_flag(engine_state, stack, "force")?;
88
89        let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
90
91        modify_plugin_file(engine_state, stack, call.head, &custom_path, |contents| {
92            if let Some(index) = contents
93                .plugins
94                .iter()
95                .position(|p| p.name == name.item || p.filename == filename)
96            {
97                contents.plugins.remove(index);
98                Ok(())
99            } else if force {
100                Ok(())
101            } else {
102                Err(ShellError::Generic(GenericError::new(
103                    format!("Failed to remove the `{}` plugin", name.item),
104                    "couldn't find a plugin with this name in the registry file",
105                    name.span,
106                )))
107            }
108        })?;
109
110        Ok(Value::nothing(call.head).into_pipeline_data())
111    }
112}