diff --git a/crates/nu-command/src/help/help_commands.rs b/crates/nu-command/src/help/help_commands.rs index f0f8df9c02..9d3ab9c924 100644 --- a/crates/nu-command/src/help/help_commands.rs +++ b/crates/nu-command/src/help/help_commands.rs @@ -87,21 +87,10 @@ pub fn help_commands( name.push_str(&r.item); } - let output = engine_state - .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() { - Ok( - Value::string(output.join("======================\n\n"), call.head) - .into_pipeline_data(), - ) + if let Some(decl) = engine_state.find_decl(name.as_bytes(), &[]) { + let cmd = engine_state.get_decl(decl); + let help_text = get_full_help(cmd, engine_state, stack); + Ok(Value::string(help_text, call.head).into_pipeline_data()) } else { Err(ShellError::CommandNotFound { span: Span::merge_many(rest.iter().map(|s| s.span)), diff --git a/crates/nu-command/src/help/help_externs.rs b/crates/nu-command/src/help/help_externs.rs index af07835af4..27775b416e 100644 --- a/crates/nu-command/src/help/help_externs.rs +++ b/crates/nu-command/src/help/help_externs.rs @@ -107,21 +107,10 @@ pub fn help_externs( name.push_str(&r.item); } - let output = engine_state - .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() { - Ok( - Value::string(output.join("======================\n\n"), call.head) - .into_pipeline_data(), - ) + if let Some(decl) = engine_state.find_decl(name.as_bytes(), &[]) { + let cmd = engine_state.get_decl(decl); + let help_text = get_full_help(cmd, engine_state, stack); + Ok(Value::string(help_text, call.head).into_pipeline_data()) } else { Err(ShellError::CommandNotFound { span: Span::merge_many(rest.iter().map(|s| s.span)), diff --git a/crates/nu-engine/src/compile/call.rs b/crates/nu-engine/src/compile/call.rs index 4112e889b1..e58a7b3efe 100644 --- a/crates/nu-engine/src/compile/call.rs +++ b/crates/nu-engine/src/compile/call.rs @@ -20,12 +20,11 @@ pub(crate) fn compile_call( // Check if this call has --help - if so, just redirect to `help` if call.named_iter().any(|(name, _, _)| name.item == "help") { - return compile_help( - working_set, - builder, - decl.name().into_spanned(call.head), - io_reg, - ); + let name = working_set + .find_decl_name(call.decl_id) // check for name in scope + .and_then(|name| std::str::from_utf8(name).ok()) + .unwrap_or(decl.name()); // fall back to decl's name + return compile_help(working_set, builder, name.into_spanned(call.head), io_reg); } // Try to figure out if this is a keyword call like `if`, and handle those specially diff --git a/crates/nu-protocol/src/engine/state_working_set.rs b/crates/nu-protocol/src/engine/state_working_set.rs index 0d59068dbf..5cbc959f63 100644 --- a/crates/nu-protocol/src/engine/state_working_set.rs +++ b/crates/nu-protocol/src/engine/state_working_set.rs @@ -459,21 +459,48 @@ impl<'a> StateWorkingSet<'a> { } // check overlay in perma - for overlay_frame in self - .permanent_state - .active_overlays(&removed_overlays) - .rev() - { - visibility.append(&overlay_frame.visibility); + self.permanent_state.find_decl(name, &removed_overlays) + } + + pub fn find_decl_name(&self, decl_id: DeclId) -> Option<&[u8]> { + let mut removed_overlays = vec![]; + + let mut visibility: Visibility = Visibility::new(); + + for scope_frame in self.delta.scope.iter().rev() { + if self.search_predecls { + for (name, id) in scope_frame.predecls.iter() { + if id == &decl_id { + return Some(name); + } + } + } + + // check overlay in delta + for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() { + visibility.append(&overlay_frame.visibility); + + if self.search_predecls { + for (name, id) in overlay_frame.predecls.iter() { + if id == &decl_id { + return Some(name); + } + } + } - if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { - return Some(decl_id); + for (name, id) in overlay_frame.decls.iter() { + if id == &decl_id { + return Some(name); + } + } } } } - None + // check overlay in perma + self.permanent_state + .find_decl_name(decl_id, &removed_overlays) } pub fn find_module(&self, name: &[u8]) -> Option {