nu_plugin_dialog/
lib.rs

1use dialoguer::theme::{ColorfulTheme, Theme};
2use nu_plugin::{LabeledError, Plugin};
3use nu_protocol::{PluginSignature, SyntaxShape};
4
5mod confirm;
6mod multiselect;
7mod password;
8mod prompt;
9mod select;
10
11pub struct DialogPlugin {
12    pub(crate) theme: Box<dyn Theme>,
13}
14
15impl DialogPlugin {
16    pub fn new() -> Self {
17        Self {
18            theme: Box::new(ColorfulTheme::default()),
19        }
20    }
21}
22
23impl Plugin for DialogPlugin {
24    fn signature(&self) -> Vec<nu_protocol::PluginSignature> {
25        vec![
26            PluginSignature::build("ask").required(
27                "subcommand",
28                SyntaxShape::String,
29                "The ask subcommand to run",
30            ),
31            PluginSignature::build("ask confirm")
32                .usage("Prompt the user with a confirmation prompt.")
33                .required(
34                    "prompt",
35                    SyntaxShape::String,
36                    "The question to ask the user.",
37                )
38                .switch("abortable", "If set users can abort the prompt.", None)
39                .named(
40                    "default",
41                    SyntaxShape::Boolean,
42                    "The default selection.",
43                    None,
44                )
45                .category(nu_protocol::Category::Misc),
46            PluginSignature::build("ask select")
47                .usage("Prompt the user with a selection prompt.")
48                .required(
49                    "items",
50                    SyntaxShape::List(Box::new(SyntaxShape::String)),
51                    "The items out of which one can be selected.",
52                )
53                .switch("fuzzy", "To add a fuzzy search to the select.", None)
54                .switch("abortable", "If set users can abort the prompt.", None)
55                .named(
56                    "prompt",
57                    SyntaxShape::String,
58                    "An optional prompt that can be shown to the user for the selection.",
59                    None,
60                )
61                .named(
62                    "default",
63                    SyntaxShape::Number,
64                    "The default selection.",
65                    None,
66                )
67                .category(nu_protocol::Category::Misc),
68            PluginSignature::build("ask multiselect")
69                .usage("Prompt the user with a selection prompt.")
70                .required(
71                    "items",
72                    SyntaxShape::List(Box::new(SyntaxShape::String)),
73                    "The items out of which one can be selected.",
74                )
75                .switch("abortable", "If set users can abort the prompt.", None)
76                .named(
77                    "prompt",
78                    SyntaxShape::String,
79                    "An optional prompt that can be shown to the user for the selection.",
80                    None,
81                )
82                .named(
83                    "default",
84                    SyntaxShape::String,
85                    "The default selections as a comma separated string of indices",
86                    None,
87                )
88                .category(nu_protocol::Category::Misc),
89            PluginSignature::build("ask password")
90                .usage("Prompt the user with a password input.")
91                .named(
92                    "prompt",
93                    SyntaxShape::String,
94                    "The prompt to this password input",
95                    None,
96                )
97                .switch(
98                    "confirm",
99                    "Prompts the user twice for matching password inputs",
100                    None,
101                )
102                .switch(
103                    "allow-empty",
104                    "Allows the user to input an empty password",
105                    None,
106                )
107                .category(nu_protocol::Category::Misc),
108        ]
109    }
110
111    fn run(
112        &mut self,
113        name: &str,
114        call: &nu_plugin::EvaluatedCall,
115        input: &nu_protocol::Value,
116    ) -> Result<nu_protocol::Value, nu_plugin::LabeledError> {
117        match name {
118            "ask confirm" => self.confirm(call, input),
119            "ask select" => self.select(call, input),
120            "ask multiselect" => self.multiselect(call, input),
121            "ask password" => self.password(call, input),
122            "ask" => 
123            Err(LabeledError {
124                label: "Missing subcommand".into(),
125                msg: "the subcommand to the ask command is missing".into(),
126                span: Some(call.head),
127            }),
128            _ =>  Err(LabeledError {
129                label: "Plugin call with wrong name signature".into(),
130                msg: "the signature used to call the plugin does not match any name in the plugin signature vector".into(),
131                span: Some(call.head),
132            })
133        }
134    }
135}