nu_command/help/
help_aliases.rs

1use crate::filters::find_internal;
2use nu_engine::{command_prelude::*, get_full_help, scope::ScopeData};
3
4#[derive(Clone)]
5pub struct HelpAliases;
6
7impl Command for HelpAliases {
8    fn name(&self) -> &str {
9        "help aliases"
10    }
11
12    fn description(&self) -> &str {
13        "Show help on nushell aliases."
14    }
15
16    fn signature(&self) -> Signature {
17        Signature::build("help aliases")
18            .category(Category::Core)
19            .rest(
20                "rest",
21                SyntaxShape::String,
22                "The name of alias to get help on.",
23            )
24            .named(
25                "find",
26                SyntaxShape::String,
27                "string to find in alias names and descriptions",
28                Some('f'),
29            )
30            .input_output_types(vec![(Type::Nothing, Type::table())])
31            .allow_variants_without_examples(true)
32    }
33
34    fn examples(&self) -> Vec<Example> {
35        vec![
36            Example {
37                description: "show all aliases",
38                example: "help aliases",
39                result: None,
40            },
41            Example {
42                description: "show help for single alias",
43                example: "help aliases my-alias",
44                result: None,
45            },
46            Example {
47                description: "search for string in alias names and descriptions",
48                example: "help aliases --find my-alias",
49                result: None,
50            },
51        ]
52    }
53
54    fn run(
55        &self,
56        engine_state: &EngineState,
57        stack: &mut Stack,
58        call: &Call,
59        _input: PipelineData,
60    ) -> Result<PipelineData, ShellError> {
61        help_aliases(engine_state, stack, call)
62    }
63}
64
65pub fn help_aliases(
66    engine_state: &EngineState,
67    stack: &mut Stack,
68    call: &Call,
69) -> Result<PipelineData, ShellError> {
70    let head = call.head;
71    let find: Option<Spanned<String>> = call.get_flag(engine_state, stack, "find")?;
72    let rest: Vec<Spanned<String>> = call.rest(engine_state, stack, 0)?;
73
74    if let Some(f) = find {
75        let all_cmds_vec = build_help_aliases(engine_state, stack, head);
76        return find_internal(
77            all_cmds_vec,
78            engine_state,
79            stack,
80            &f.item,
81            &["name", "description"],
82            true,
83        );
84    }
85
86    if rest.is_empty() {
87        Ok(build_help_aliases(engine_state, stack, head))
88    } else {
89        let mut name = String::new();
90
91        for r in &rest {
92            if !name.is_empty() {
93                name.push(' ');
94            }
95            name.push_str(&r.item);
96        }
97
98        let Some(alias) = engine_state.find_decl(name.as_bytes(), &[]) else {
99            return Err(ShellError::AliasNotFound {
100                span: Span::merge_many(rest.iter().map(|s| s.span)),
101            });
102        };
103
104        let alias = engine_state.get_decl(alias);
105
106        if alias.as_alias().is_none() {
107            return Err(ShellError::AliasNotFound {
108                span: Span::merge_many(rest.iter().map(|s| s.span)),
109            });
110        };
111
112        let help = get_full_help(alias, engine_state, stack);
113
114        Ok(Value::string(help, call.head).into_pipeline_data())
115    }
116}
117
118fn build_help_aliases(engine_state: &EngineState, stack: &Stack, span: Span) -> PipelineData {
119    let mut scope_data = ScopeData::new(engine_state, stack);
120    scope_data.populate_decls();
121
122    Value::list(scope_data.collect_aliases(span), span).into_pipeline_data()
123}
124
125#[cfg(test)]
126mod test {
127    #[test]
128    fn test_examples() {
129        use super::HelpAliases;
130        use crate::test_examples;
131        test_examples(HelpAliases {})
132    }
133}