nu_command/help/
help_externs.rs1use crate::filters::find_internal;
2use nu_engine::{command_prelude::*, get_full_help, scope::ScopeData};
3
4#[derive(Clone)]
5pub struct HelpExterns;
6
7impl Command for HelpExterns {
8 fn name(&self) -> &str {
9 "help externs"
10 }
11
12 fn description(&self) -> &str {
13 "Show help on nushell externs."
14 }
15
16 fn signature(&self) -> Signature {
17 Signature::build("help externs")
18 .category(Category::Core)
19 .rest(
20 "rest",
21 SyntaxShape::String,
22 "The name of extern to get help on.",
23 )
24 .named(
25 "find",
26 SyntaxShape::String,
27 "string to find in extern 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 externs",
38 example: "help externs",
39 result: None,
40 },
41 Example {
42 description: "show help for single extern",
43 example: "help externs smth",
44 result: None,
45 },
46 Example {
47 description: "search for string in extern names and descriptions",
48 example: "help externs --find smth",
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_externs(engine_state, stack, call)
62 }
63}
64
65pub fn help_externs(
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_externs(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_externs(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 if let Some(decl) = engine_state.find_decl(name.as_bytes(), &[]) {
99 let cmd = engine_state.get_decl(decl);
100 let help_text = get_full_help(cmd, engine_state, stack);
101 Ok(Value::string(help_text, call.head).into_pipeline_data())
102 } else {
103 Err(ShellError::CommandNotFound {
104 span: Span::merge_many(rest.iter().map(|s| s.span)),
105 })
106 }
107 }
108}
109
110fn build_help_externs(engine_state: &EngineState, stack: &Stack, span: Span) -> PipelineData {
111 let mut scope = ScopeData::new(engine_state, stack);
112 scope.populate_decls();
113 Value::list(scope.collect_externs(span), span).into_pipeline_data()
114}
115
116#[cfg(test)]
117mod test {
118 #[test]
119 fn test_examples() {
120 use super::HelpExterns;
121 use crate::test_examples;
122 test_examples(HelpExterns {})
123 }
124}