Skip to main content

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            head,
84        );
85    }
86
87    if rest.is_empty() {
88        Ok(build_help_aliases(engine_state, stack, head))
89    } else {
90        let mut name = String::new();
91
92        for r in &rest {
93            if !name.is_empty() {
94                name.push(' ');
95            }
96            name.push_str(&r.item);
97        }
98
99        let Some(alias) = engine_state.find_decl(name.as_bytes(), &[]) else {
100            return Err(ShellError::AliasNotFound {
101                span: Span::merge_many(rest.iter().map(|s| s.span)),
102            });
103        };
104
105        let alias = engine_state.get_decl(alias);
106
107        if alias.as_alias().is_none() {
108            return Err(ShellError::AliasNotFound {
109                span: Span::merge_many(rest.iter().map(|s| s.span)),
110            });
111        };
112
113        let help = get_full_help(alias, engine_state, stack, call.head);
114
115        Ok(Value::string(help, call.head).into_pipeline_data())
116    }
117}
118
119fn build_help_aliases(engine_state: &EngineState, stack: &Stack, span: Span) -> PipelineData {
120    let mut scope_data = ScopeData::new(engine_state, stack);
121    scope_data.populate_decls();
122
123    Value::list(scope_data.collect_aliases(span), span).into_pipeline_data()
124}
125
126#[cfg(test)]
127mod test {
128    #[test]
129    fn test_examples() -> nu_test_support::Result {
130        use super::HelpAliases;
131        nu_test_support::test().examples(HelpAliases)
132    }
133}