From baeba19b22c08e7a4c6cf3f1ff4b37df0c54987a Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Sun, 19 May 2024 17:56:33 +0000 Subject: [PATCH] Make `get_full_help` take `&dyn Command` (#12903) # Description Changes `get_full_help` to take a `&dyn Command` instead of multiple arguments (`&Signature`, `&Examples` `is_parser_keyword`). All of these arguments can be gathered from a `Command`, so there is no need to pass the pieces to `get_full_help`. This PR also fixes an issue where the search terms are not shown if `--help` is used on a command. --- crates/nu-cli/src/commands/keybindings.rs | 12 +---- crates/nu-cli/src/menus/help_completions.rs | 44 +++++++++---------- crates/nu-cmd-dataframe/src/dataframe/stub.rs | 12 +---- crates/nu-cmd-extra/src/extra/bits/bits_.rs | 12 +---- .../src/extra/filters/roll/roll_.rs | 12 +---- .../src/extra/strings/str_/case/str_.rs | 12 +---- .../nu-cmd-lang/src/core_commands/export.rs | 12 +---- .../src/core_commands/overlay/command.rs | 12 +---- .../src/core_commands/scope/command.rs | 12 +---- .../nu-cmd-plugin/src/commands/plugin/mod.rs | 12 +---- crates/nu-command/src/bytes/bytes_.rs | 12 +---- .../src/conversions/into/command.rs | 12 +---- crates/nu-command/src/date/date_.rs | 22 +--------- crates/nu-command/src/debug/view.rs | 12 +---- crates/nu-command/src/env/config/config_.rs | 12 +---- crates/nu-command/src/formats/from/command.rs | 12 +---- crates/nu-command/src/formats/to/command.rs | 12 +---- crates/nu-command/src/hash/hash_.rs | 12 +---- crates/nu-command/src/help/help_commands.rs | 18 +++----- crates/nu-command/src/help/help_externs.rs | 18 +++----- crates/nu-command/src/help/help_modules.rs | 2 + crates/nu-command/src/math/math_.rs | 12 +---- crates/nu-command/src/network/http/http_.rs | 12 +---- crates/nu-command/src/network/url/url_.rs | 12 +---- crates/nu-command/src/path/path_.rs | 12 +---- crates/nu-command/src/random/random_.rs | 12 +---- crates/nu-command/src/stor/stor_.rs | 12 +---- .../nu-command/src/strings/format/format_.rs | 12 +---- .../nu-command/src/strings/split/command.rs | 12 +---- .../nu-command/src/strings/str_/case/str_.rs | 12 +---- crates/nu-engine/src/documentation.rs | 14 +++--- crates/nu-engine/src/eval.rs | 14 +----- crates/nu-plugin-engine/src/context.rs | 10 ++--- crates/nu-protocol/src/engine/engine_state.rs | 26 ++--------- src/command.rs | 22 ++-------- tests/repl/test_engine.rs | 5 +-- 36 files changed, 82 insertions(+), 413 deletions(-) diff --git a/crates/nu-cli/src/commands/keybindings.rs b/crates/nu-cli/src/commands/keybindings.rs index a8c8053a56..347ce983ea 100644 --- a/crates/nu-cli/src/commands/keybindings.rs +++ b/crates/nu-cli/src/commands/keybindings.rs @@ -36,16 +36,6 @@ For more information on input and keybindings, check: call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Keybindings.signature(), - &Keybindings.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cli/src/menus/help_completions.rs b/crates/nu-cli/src/menus/help_completions.rs index 62f40b9d8d..c9c1b7bf94 100644 --- a/crates/nu-cli/src/menus/help_completions.rs +++ b/crates/nu-cli/src/menus/help_completions.rs @@ -12,50 +12,49 @@ impl NuHelpCompleter { } fn completion_helper(&self, line: &str, pos: usize) -> Vec { - let full_commands = self.0.get_signatures_with_examples(false); let folded_line = line.to_folded_case(); - //Vec<(Signature, Vec, bool, bool)> { - let mut commands = full_commands - .iter() - .filter(|(sig, _, _)| { - sig.name.to_folded_case().contains(&folded_line) - || sig.usage.to_folded_case().contains(&folded_line) - || sig - .search_terms - .iter() + let mut commands = self + .0 + .get_decls_sorted(false) + .into_iter() + .filter_map(|(_, decl_id)| { + let decl = self.0.get_decl(decl_id); + (decl.name().to_folded_case().contains(&folded_line) + || decl.usage().to_folded_case().contains(&folded_line) + || decl + .search_terms() + .into_iter() .any(|term| term.to_folded_case().contains(&folded_line)) - || sig.extra_usage.to_folded_case().contains(&folded_line) + || decl.extra_usage().to_folded_case().contains(&folded_line)) + .then_some(decl) }) .collect::>(); - commands.sort_by(|(a, _, _), (b, _, _)| { - let a_distance = levenshtein_distance(line, &a.name); - let b_distance = levenshtein_distance(line, &b.name); - a_distance.cmp(&b_distance) - }); + commands.sort_by_cached_key(|decl| levenshtein_distance(line, decl.name())); commands .into_iter() - .map(|(sig, examples, _)| { + .map(|decl| { let mut long_desc = String::new(); - let usage = &sig.usage; + let usage = decl.usage(); if !usage.is_empty() { long_desc.push_str(usage); long_desc.push_str("\r\n\r\n"); } - let extra_usage = &sig.extra_usage; + let extra_usage = decl.extra_usage(); if !extra_usage.is_empty() { long_desc.push_str(extra_usage); long_desc.push_str("\r\n\r\n"); } + let sig = decl.signature(); let _ = write!(long_desc, "Usage:\r\n > {}\r\n", sig.call_signature()); if !sig.named.is_empty() { - long_desc.push_str(&get_flags_section(Some(&*self.0.clone()), sig, |v| { + long_desc.push_str(&get_flags_section(Some(&*self.0.clone()), &sig, |v| { v.to_parsable_string(", ", &self.0.config) })) } @@ -93,13 +92,14 @@ impl NuHelpCompleter { } } - let extra: Vec = examples + let extra: Vec = decl + .examples() .iter() .map(|example| example.example.replace('\n', "\r\n")) .collect(); Suggestion { - value: sig.name.clone(), + value: decl.name().into(), description: Some(long_desc), style: None, extra: Some(extra), diff --git a/crates/nu-cmd-dataframe/src/dataframe/stub.rs b/crates/nu-cmd-dataframe/src/dataframe/stub.rs index 58dd2996cd..dfabbe0b82 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/stub.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/stub.rs @@ -29,16 +29,6 @@ impl Command for Dfr { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Dfr.signature(), - &Dfr.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cmd-extra/src/extra/bits/bits_.rs b/crates/nu-cmd-extra/src/extra/bits/bits_.rs index d795beda4e..1190c01b4d 100644 --- a/crates/nu-cmd-extra/src/extra/bits/bits_.rs +++ b/crates/nu-cmd-extra/src/extra/bits/bits_.rs @@ -29,16 +29,6 @@ impl Command for Bits { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Bits.signature(), - &Bits.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs index a1622d71c0..867bc2706e 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs @@ -33,16 +33,6 @@ impl Command for Roll { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Roll.signature(), - &Roll.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs index 56e0d1164f..fe6cb86324 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs @@ -29,16 +29,6 @@ impl Command for Str { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Str.signature(), - &Str.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cmd-lang/src/core_commands/export.rs b/crates/nu-cmd-lang/src/core_commands/export.rs index 8634a8c06b..565e7895dc 100644 --- a/crates/nu-cmd-lang/src/core_commands/export.rs +++ b/crates/nu-cmd-lang/src/core_commands/export.rs @@ -35,17 +35,7 @@ impl Command for ExportCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &ExportCommand.signature(), - &ExportCommand.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/command.rs b/crates/nu-cmd-lang/src/core_commands/overlay/command.rs index 72cc28e77c..00ec7438ad 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/command.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/command.rs @@ -37,16 +37,6 @@ impl Command for Overlay { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Overlay.signature(), - &[], - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cmd-lang/src/core_commands/scope/command.rs b/crates/nu-cmd-lang/src/core_commands/scope/command.rs index 72a9e74932..98439226cf 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/command.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/command.rs @@ -31,16 +31,6 @@ impl Command for Scope { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Scope.signature(), - &[], - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-cmd-plugin/src/commands/plugin/mod.rs b/crates/nu-cmd-plugin/src/commands/plugin/mod.rs index cf4ee5d9a3..36590e9a8a 100644 --- a/crates/nu-cmd-plugin/src/commands/plugin/mod.rs +++ b/crates/nu-cmd-plugin/src/commands/plugin/mod.rs @@ -37,17 +37,7 @@ impl Command for PluginCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &PluginCommand.signature(), - &PluginCommand.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/bytes/bytes_.rs b/crates/nu-command/src/bytes/bytes_.rs index 451ee1e5d5..82bf7c619b 100644 --- a/crates/nu-command/src/bytes/bytes_.rs +++ b/crates/nu-command/src/bytes/bytes_.rs @@ -29,16 +29,6 @@ impl Command for Bytes { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Bytes.signature(), - &Bytes.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/conversions/into/command.rs b/crates/nu-command/src/conversions/into/command.rs index 5a8175b298..03b8e81c4a 100644 --- a/crates/nu-command/src/conversions/into/command.rs +++ b/crates/nu-command/src/conversions/into/command.rs @@ -29,16 +29,6 @@ impl Command for Into { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Into.signature(), - &[], - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/date/date_.rs b/crates/nu-command/src/date/date_.rs index 158940cc2e..fd67e9c923 100644 --- a/crates/nu-command/src/date/date_.rs +++ b/crates/nu-command/src/date/date_.rs @@ -42,26 +42,6 @@ impl Command for Date { call: &Call, _input: PipelineData, ) -> Result { - date(engine_state, stack, call) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } - -fn date( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, -) -> Result { - let head = call.head; - - Ok(Value::string( - get_full_help( - &Date.signature(), - &Date.examples(), - engine_state, - stack, - false, - ), - head, - ) - .into_pipeline_data()) -} diff --git a/crates/nu-command/src/debug/view.rs b/crates/nu-command/src/debug/view.rs index fcbc377e4b..4ef1c1c7e0 100644 --- a/crates/nu-command/src/debug/view.rs +++ b/crates/nu-command/src/debug/view.rs @@ -29,16 +29,6 @@ impl Command for View { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &View.signature(), - &View.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/env/config/config_.rs b/crates/nu-command/src/env/config/config_.rs index 948e8248b8..1cd6ef4621 100644 --- a/crates/nu-command/src/env/config/config_.rs +++ b/crates/nu-command/src/env/config/config_.rs @@ -29,17 +29,7 @@ impl Command for ConfigMeta { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &ConfigMeta.signature(), - &ConfigMeta.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } fn search_terms(&self) -> Vec<&str> { diff --git a/crates/nu-command/src/formats/from/command.rs b/crates/nu-command/src/formats/from/command.rs index 3df3d86e2e..40085b51d2 100644 --- a/crates/nu-command/src/formats/from/command.rs +++ b/crates/nu-command/src/formats/from/command.rs @@ -29,16 +29,6 @@ impl Command for From { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &From.signature(), - &From.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/formats/to/command.rs b/crates/nu-command/src/formats/to/command.rs index 1288c2d73b..2138085c87 100644 --- a/crates/nu-command/src/formats/to/command.rs +++ b/crates/nu-command/src/formats/to/command.rs @@ -29,16 +29,6 @@ impl Command for To { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &To.signature(), - &To.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/hash/hash_.rs b/crates/nu-command/src/hash/hash_.rs index fc7f58cd3b..d4eca79354 100644 --- a/crates/nu-command/src/hash/hash_.rs +++ b/crates/nu-command/src/hash/hash_.rs @@ -29,16 +29,6 @@ impl Command for Hash { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Self.signature(), - &Self.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/help/help_commands.rs b/crates/nu-command/src/help/help_commands.rs index 2633595356..f2440cc36f 100644 --- a/crates/nu-command/src/help/help_commands.rs +++ b/crates/nu-command/src/help/help_commands.rs @@ -1,7 +1,6 @@ use crate::help::highlight_search_in_table; use nu_color_config::StyleComputer; use nu_engine::{command_prelude::*, get_full_help}; -use nu_protocol::engine::CommandType; #[derive(Clone)] pub struct HelpCommands; @@ -89,18 +88,13 @@ pub fn help_commands( } let output = engine_state - .get_signatures_with_examples(false) - .iter() - .filter(|(signature, _, _)| signature.name == name) - .map(|(signature, examples, cmd_type)| { - get_full_help( - signature, - examples, - engine_state, - stack, - cmd_type == &CommandType::Keyword, - ) + .get_decls_sorted(false) + .into_iter() + .filter_map(|(_, decl_id)| { + let decl = engine_state.get_decl(decl_id); + (decl.name() == name).then_some(decl) }) + .map(|cmd| get_full_help(cmd, engine_state, stack)) .collect::>(); if !output.is_empty() { diff --git a/crates/nu-command/src/help/help_externs.rs b/crates/nu-command/src/help/help_externs.rs index 0378553463..4a5c8123a4 100644 --- a/crates/nu-command/src/help/help_externs.rs +++ b/crates/nu-command/src/help/help_externs.rs @@ -1,7 +1,6 @@ use crate::help::highlight_search_in_table; use nu_color_config::StyleComputer; use nu_engine::{command_prelude::*, get_full_help, scope::ScopeData}; -use nu_protocol::engine::CommandType; #[derive(Clone)] pub struct HelpExterns; @@ -109,18 +108,13 @@ pub fn help_externs( } let output = engine_state - .get_signatures_with_examples(false) - .iter() - .filter(|(signature, _, _)| signature.name == name) - .map(|(signature, examples, cmd_type)| { - get_full_help( - signature, - examples, - engine_state, - stack, - cmd_type == &CommandType::Keyword, - ) + .get_decls_sorted(false) + .into_iter() + .filter_map(|(_, decl_id)| { + let decl = engine_state.get_decl(decl_id); + (decl.name() == name).then_some(decl) }) + .map(|cmd| get_full_help(cmd, engine_state, stack)) .collect::>(); if !output.is_empty() { diff --git a/crates/nu-command/src/help/help_modules.rs b/crates/nu-command/src/help/help_modules.rs index 690968251b..5b39133a6d 100644 --- a/crates/nu-command/src/help/help_modules.rs +++ b/crates/nu-command/src/help/help_modules.rs @@ -149,6 +149,7 @@ pub fn help_modules( if !module.decls.is_empty() || module.main.is_some() { let commands: Vec<(Vec, DeclId)> = engine_state .get_decls_sorted(false) + .into_iter() .filter(|(_, id)| !engine_state.get_decl(*id).is_alias()) .collect(); @@ -186,6 +187,7 @@ pub fn help_modules( if !module.decls.is_empty() { let aliases: Vec<(Vec, DeclId)> = engine_state .get_decls_sorted(false) + .into_iter() .filter(|(_, id)| engine_state.get_decl(*id).is_alias()) .collect(); diff --git a/crates/nu-command/src/math/math_.rs b/crates/nu-command/src/math/math_.rs index 9f230362ea..2ac067af4e 100644 --- a/crates/nu-command/src/math/math_.rs +++ b/crates/nu-command/src/math/math_.rs @@ -29,16 +29,6 @@ impl Command for MathCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &MathCommand.signature(), - &MathCommand.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/network/http/http_.rs b/crates/nu-command/src/network/http/http_.rs index b1e8d64120..361033708e 100644 --- a/crates/nu-command/src/network/http/http_.rs +++ b/crates/nu-command/src/network/http/http_.rs @@ -35,16 +35,6 @@ impl Command for Http { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Http.signature(), - &Http.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/network/url/url_.rs b/crates/nu-command/src/network/url/url_.rs index 49d55c4c6b..9988063d46 100644 --- a/crates/nu-command/src/network/url/url_.rs +++ b/crates/nu-command/src/network/url/url_.rs @@ -33,16 +33,6 @@ impl Command for Url { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Url.signature(), - &Url.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/path/path_.rs b/crates/nu-command/src/path/path_.rs index 2d1d0730fa..667008b658 100644 --- a/crates/nu-command/src/path/path_.rs +++ b/crates/nu-command/src/path/path_.rs @@ -42,16 +42,6 @@ the path literal."# call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &PathCommand.signature(), - &PathCommand.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/random/random_.rs b/crates/nu-command/src/random/random_.rs index 16135000ea..5cf14d7748 100644 --- a/crates/nu-command/src/random/random_.rs +++ b/crates/nu-command/src/random/random_.rs @@ -33,16 +33,6 @@ impl Command for RandomCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &RandomCommand.signature(), - &RandomCommand.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/stor/stor_.rs b/crates/nu-command/src/stor/stor_.rs index 3fb6840e7d..c5bb378c2d 100644 --- a/crates/nu-command/src/stor/stor_.rs +++ b/crates/nu-command/src/stor/stor_.rs @@ -29,16 +29,6 @@ impl Command for Stor { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Stor.signature(), - &Stor.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/strings/format/format_.rs b/crates/nu-command/src/strings/format/format_.rs index c51213e4ef..21b46a8b05 100644 --- a/crates/nu-command/src/strings/format/format_.rs +++ b/crates/nu-command/src/strings/format/format_.rs @@ -29,16 +29,6 @@ impl Command for Format { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Format.signature(), - &Format.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/strings/split/command.rs b/crates/nu-command/src/strings/split/command.rs index 0333249c2b..ff9057eacc 100644 --- a/crates/nu-command/src/strings/split/command.rs +++ b/crates/nu-command/src/strings/split/command.rs @@ -29,16 +29,6 @@ impl Command for SplitCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &SplitCommand.signature(), - &SplitCommand.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/strings/str_/case/str_.rs b/crates/nu-command/src/strings/str_/case/str_.rs index 56e0d1164f..fe6cb86324 100644 --- a/crates/nu-command/src/strings/str_/case/str_.rs +++ b/crates/nu-command/src/strings/str_/case/str_.rs @@ -29,16 +29,6 @@ impl Command for Str { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help( - &Str.signature(), - &Str.examples(), - engine_state, - stack, - self.is_keyword(), - ), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } } diff --git a/crates/nu-engine/src/documentation.rs b/crates/nu-engine/src/documentation.rs index 62e68eaa6c..3cd1130060 100644 --- a/crates/nu-engine/src/documentation.rs +++ b/crates/nu-engine/src/documentation.rs @@ -2,18 +2,16 @@ use crate::eval_call; use nu_protocol::{ ast::{Argument, Call, Expr, Expression, RecordItem}, debugger::WithoutDebug, - engine::{EngineState, Stack}, + engine::{Command, EngineState, Stack}, record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Type, Value, }; use std::{collections::HashMap, fmt::Write}; pub fn get_full_help( - sig: &Signature, - examples: &[Example], + command: &dyn Command, engine_state: &EngineState, stack: &mut Stack, - is_parser_keyword: bool, ) -> String { let config = engine_state.get_config(); let doc_config = DocumentationConfig { @@ -23,14 +21,15 @@ pub fn get_full_help( }; let stack = &mut stack.start_capture(); + let signature = command.signature().update_from_command(command); get_documentation( - sig, - examples, + &signature, + &command.examples(), engine_state, stack, &doc_config, - is_parser_keyword, + command.is_keyword(), ) } @@ -61,7 +60,6 @@ fn nu_highlight_string(code_string: &str, engine_state: &EngineState, stack: &mu code_string.to_string() } -#[allow(clippy::cognitive_complexity)] fn get_documentation( sig: &Signature, examples: &[Example], diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 02feef3f38..af051a1dc7 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -27,18 +27,8 @@ pub fn eval_call( let decl = engine_state.get_decl(call.decl_id); if !decl.is_known_external() && call.named_iter().any(|(flag, _, _)| flag.item == "help") { - let mut signature = engine_state.get_signature(decl); - signature.usage = decl.usage().to_string(); - signature.extra_usage = decl.extra_usage().to_string(); - - let full_help = get_full_help( - &signature, - &decl.examples(), - engine_state, - caller_stack, - decl.is_keyword(), - ); - Ok(Value::string(full_help, call.head).into_pipeline_data()) + let help = get_full_help(decl, engine_state, caller_stack); + Ok(Value::string(help, call.head).into_pipeline_data()) } else if let Some(block_id) = decl.block_id() { let block = engine_state.get_block(block_id); diff --git a/crates/nu-plugin-engine/src/context.rs b/crates/nu-plugin-engine/src/context.rs index 0b1d56c050..d5be6ad4b6 100644 --- a/crates/nu-plugin-engine/src/context.rs +++ b/crates/nu-plugin-engine/src/context.rs @@ -139,14 +139,10 @@ impl<'a> PluginExecutionContext for PluginExecutionCommandContext<'a> { fn get_help(&self) -> Result, ShellError> { let decl = self.engine_state.get_decl(self.call.decl_id); - Ok(get_full_help( - &decl.signature(), - &decl.examples(), - &self.engine_state, - &mut self.stack.clone(), - false, + Ok( + get_full_help(decl, &self.engine_state, &mut self.stack.clone()) + .into_spanned(self.call.head), ) - .into_spanned(self.call.head)) } fn get_span_contents(&self, span: Span) -> Result>, ShellError> { diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 1948b67d43..710ca77d4c 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -7,7 +7,7 @@ use crate::{ Variable, Visibility, DEFAULT_OVERLAY_NAME, }, eval_const::create_nu_constant, - BlockId, Category, Config, DeclId, Example, FileId, HistoryConfig, Module, ModuleId, OverlayId, + BlockId, Category, Config, DeclId, FileId, HistoryConfig, Module, ModuleId, OverlayId, ShellError, Signature, Span, Type, Value, VarId, VirtualPathId, }; use fancy_regex::Regex; @@ -766,10 +766,7 @@ impl EngineState { } /// Get all commands within scope, sorted by the commands' names - pub fn get_decls_sorted( - &self, - include_hidden: bool, - ) -> impl Iterator, DeclId)> { + pub fn get_decls_sorted(&self, include_hidden: bool) -> Vec<(Vec, DeclId)> { let mut decls_map = HashMap::new(); for overlay_frame in self.active_overlays(&[]) { @@ -790,7 +787,7 @@ impl EngineState { let mut decls: Vec<(Vec, DeclId)> = decls_map.into_iter().collect(); decls.sort_by(|a, b| a.0.cmp(&b.0)); - decls.into_iter() + decls } pub fn get_signature(&self, decl: &dyn Command) -> Signature { @@ -804,6 +801,7 @@ impl EngineState { /// Get signatures of all commands within scope. pub fn get_signatures(&self, include_hidden: bool) -> Vec { self.get_decls_sorted(include_hidden) + .into_iter() .map(|(_, id)| { let decl = self.get_decl(id); @@ -812,22 +810,6 @@ impl EngineState { .collect() } - /// Get signatures of all commands within scope. - /// - /// In addition to signatures, it returns each command's examples and type. - pub fn get_signatures_with_examples( - &self, - include_hidden: bool, - ) -> Vec<(Signature, Vec, CommandType)> { - self.get_decls_sorted(include_hidden) - .map(|(_, id)| { - let decl = self.get_decl(id); - let signature = self.get_signature(decl).update_from_command(decl); - (signature, decl.examples(), decl.command_type()) - }) - .collect() - } - pub fn get_block(&self, block_id: BlockId) -> &Arc { self.blocks .get(block_id) diff --git a/src/command.rs b/src/command.rs index ab7a74884e..7fcf2da1b3 100644 --- a/src/command.rs +++ b/src/command.rs @@ -191,13 +191,7 @@ pub(crate) fn parse_commandline_args( let help = call.has_flag(engine_state, &mut stack, "help")?; if help { - let full_help = get_full_help( - &Nu.signature(), - &Nu.examples(), - engine_state, - &mut stack, - true, - ); + let full_help = get_full_help(&Nu, engine_state, &mut stack); let _ = std::panic::catch_unwind(move || stdout_write_all_and_flush(full_help)); @@ -245,13 +239,7 @@ pub(crate) fn parse_commandline_args( } // Just give the help and exit if the above fails - let full_help = get_full_help( - &Nu.signature(), - &Nu.examples(), - engine_state, - &mut stack, - true, - ); + let full_help = get_full_help(&Nu, engine_state, &mut stack); print!("{full_help}"); std::process::exit(1); } @@ -452,11 +440,7 @@ impl Command for Nu { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::string( - get_full_help(&Nu.signature(), &Nu.examples(), engine_state, stack, true), - call.head, - ) - .into_pipeline_data()) + Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/tests/repl/test_engine.rs b/tests/repl/test_engine.rs index c1eb919afa..e452295f42 100644 --- a/tests/repl/test_engine.rs +++ b/tests/repl/test_engine.rs @@ -54,8 +54,7 @@ fn in_and_if_else() -> TestResult { #[test] fn help_works_with_missing_requirements() -> TestResult { - let expected_length = "70"; - run_test(r#"each --help | lines | length"#, expected_length) + run_test(r#"each --help | lines | length"#, "72") } #[test] @@ -65,12 +64,12 @@ fn scope_variable() -> TestResult { "int", ) } + #[rstest] #[case("a", "<> nothing")] #[case("b", "<1.23> float")] #[case("flag1", "<> nothing")] #[case("flag2", "<4.56> float")] - fn scope_command_defaults(#[case] var: &str, #[case] exp_result: &str) -> TestResult { run_test( &format!(