mirror of
https://github.com/nushell/nushell
synced 2024-12-26 13:03:07 +00:00
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.
This commit is contained in:
parent
474293bf1c
commit
baeba19b22
36 changed files with 82 additions and 413 deletions
|
@ -36,16 +36,6 @@ For more information on input and keybindings, check:
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Keybindings.signature(),
|
|
||||||
&Keybindings.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,50 +12,49 @@ impl NuHelpCompleter {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn completion_helper(&self, line: &str, pos: usize) -> Vec<Suggestion> {
|
fn completion_helper(&self, line: &str, pos: usize) -> Vec<Suggestion> {
|
||||||
let full_commands = self.0.get_signatures_with_examples(false);
|
|
||||||
let folded_line = line.to_folded_case();
|
let folded_line = line.to_folded_case();
|
||||||
|
|
||||||
//Vec<(Signature, Vec<Example>, bool, bool)> {
|
let mut commands = self
|
||||||
let mut commands = full_commands
|
.0
|
||||||
.iter()
|
.get_decls_sorted(false)
|
||||||
.filter(|(sig, _, _)| {
|
.into_iter()
|
||||||
sig.name.to_folded_case().contains(&folded_line)
|
.filter_map(|(_, decl_id)| {
|
||||||
|| sig.usage.to_folded_case().contains(&folded_line)
|
let decl = self.0.get_decl(decl_id);
|
||||||
|| sig
|
(decl.name().to_folded_case().contains(&folded_line)
|
||||||
.search_terms
|
|| decl.usage().to_folded_case().contains(&folded_line)
|
||||||
.iter()
|
|| decl
|
||||||
|
.search_terms()
|
||||||
|
.into_iter()
|
||||||
.any(|term| term.to_folded_case().contains(&folded_line))
|
.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::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
commands.sort_by(|(a, _, _), (b, _, _)| {
|
commands.sort_by_cached_key(|decl| levenshtein_distance(line, decl.name()));
|
||||||
let a_distance = levenshtein_distance(line, &a.name);
|
|
||||||
let b_distance = levenshtein_distance(line, &b.name);
|
|
||||||
a_distance.cmp(&b_distance)
|
|
||||||
});
|
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(sig, examples, _)| {
|
.map(|decl| {
|
||||||
let mut long_desc = String::new();
|
let mut long_desc = String::new();
|
||||||
|
|
||||||
let usage = &sig.usage;
|
let usage = decl.usage();
|
||||||
if !usage.is_empty() {
|
if !usage.is_empty() {
|
||||||
long_desc.push_str(usage);
|
long_desc.push_str(usage);
|
||||||
long_desc.push_str("\r\n\r\n");
|
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() {
|
if !extra_usage.is_empty() {
|
||||||
long_desc.push_str(extra_usage);
|
long_desc.push_str(extra_usage);
|
||||||
long_desc.push_str("\r\n\r\n");
|
long_desc.push_str("\r\n\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let sig = decl.signature();
|
||||||
let _ = write!(long_desc, "Usage:\r\n > {}\r\n", sig.call_signature());
|
let _ = write!(long_desc, "Usage:\r\n > {}\r\n", sig.call_signature());
|
||||||
|
|
||||||
if !sig.named.is_empty() {
|
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)
|
v.to_parsable_string(", ", &self.0.config)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -93,13 +92,14 @@ impl NuHelpCompleter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let extra: Vec<String> = examples
|
let extra: Vec<String> = decl
|
||||||
|
.examples()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|example| example.example.replace('\n', "\r\n"))
|
.map(|example| example.example.replace('\n', "\r\n"))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Suggestion {
|
Suggestion {
|
||||||
value: sig.name.clone(),
|
value: decl.name().into(),
|
||||||
description: Some(long_desc),
|
description: Some(long_desc),
|
||||||
style: None,
|
style: None,
|
||||||
extra: Some(extra),
|
extra: Some(extra),
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Dfr {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Dfr.signature(),
|
|
||||||
&Dfr.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Bits {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Bits.signature(),
|
|
||||||
&Bits.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,16 +33,6 @@ impl Command for Roll {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Roll.signature(),
|
|
||||||
&Roll.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Str {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Str.signature(),
|
|
||||||
&Str.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,17 +35,7 @@ impl Command for ExportCommand {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&ExportCommand.signature(),
|
|
||||||
&ExportCommand.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
|
|
@ -37,16 +37,6 @@ impl Command for Overlay {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Overlay.signature(),
|
|
||||||
&[],
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,6 @@ impl Command for Scope {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Scope.signature(),
|
|
||||||
&[],
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,17 +37,7 @@ impl Command for PluginCommand {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&PluginCommand.signature(),
|
|
||||||
&PluginCommand.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Bytes {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Bytes.signature(),
|
|
||||||
&Bytes.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Into {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Into.signature(),
|
|
||||||
&[],
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,26 +42,6 @@ impl Command for Date {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
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<PipelineData, ShellError> {
|
|
||||||
let head = call.head;
|
|
||||||
|
|
||||||
Ok(Value::string(
|
|
||||||
get_full_help(
|
|
||||||
&Date.signature(),
|
|
||||||
&Date.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for View {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&View.signature(),
|
|
||||||
&View.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
crates/nu-command/src/env/config/config_.rs
vendored
12
crates/nu-command/src/env/config/config_.rs
vendored
|
@ -29,17 +29,7 @@ impl Command for ConfigMeta {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&ConfigMeta.signature(),
|
|
||||||
&ConfigMeta.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search_terms(&self) -> Vec<&str> {
|
fn search_terms(&self) -> Vec<&str> {
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for From {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&From.signature(),
|
|
||||||
&From.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for To {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&To.signature(),
|
|
||||||
&To.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Hash {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Self.signature(),
|
|
||||||
&Self.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::help::highlight_search_in_table;
|
use crate::help::highlight_search_in_table;
|
||||||
use nu_color_config::StyleComputer;
|
use nu_color_config::StyleComputer;
|
||||||
use nu_engine::{command_prelude::*, get_full_help};
|
use nu_engine::{command_prelude::*, get_full_help};
|
||||||
use nu_protocol::engine::CommandType;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct HelpCommands;
|
pub struct HelpCommands;
|
||||||
|
@ -89,18 +88,13 @@ pub fn help_commands(
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = engine_state
|
let output = engine_state
|
||||||
.get_signatures_with_examples(false)
|
.get_decls_sorted(false)
|
||||||
.iter()
|
.into_iter()
|
||||||
.filter(|(signature, _, _)| signature.name == name)
|
.filter_map(|(_, decl_id)| {
|
||||||
.map(|(signature, examples, cmd_type)| {
|
let decl = engine_state.get_decl(decl_id);
|
||||||
get_full_help(
|
(decl.name() == name).then_some(decl)
|
||||||
signature,
|
|
||||||
examples,
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
cmd_type == &CommandType::Keyword,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
.map(|cmd| get_full_help(cmd, engine_state, stack))
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
if !output.is_empty() {
|
if !output.is_empty() {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::help::highlight_search_in_table;
|
use crate::help::highlight_search_in_table;
|
||||||
use nu_color_config::StyleComputer;
|
use nu_color_config::StyleComputer;
|
||||||
use nu_engine::{command_prelude::*, get_full_help, scope::ScopeData};
|
use nu_engine::{command_prelude::*, get_full_help, scope::ScopeData};
|
||||||
use nu_protocol::engine::CommandType;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct HelpExterns;
|
pub struct HelpExterns;
|
||||||
|
@ -109,18 +108,13 @@ pub fn help_externs(
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = engine_state
|
let output = engine_state
|
||||||
.get_signatures_with_examples(false)
|
.get_decls_sorted(false)
|
||||||
.iter()
|
.into_iter()
|
||||||
.filter(|(signature, _, _)| signature.name == name)
|
.filter_map(|(_, decl_id)| {
|
||||||
.map(|(signature, examples, cmd_type)| {
|
let decl = engine_state.get_decl(decl_id);
|
||||||
get_full_help(
|
(decl.name() == name).then_some(decl)
|
||||||
signature,
|
|
||||||
examples,
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
cmd_type == &CommandType::Keyword,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
.map(|cmd| get_full_help(cmd, engine_state, stack))
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
if !output.is_empty() {
|
if !output.is_empty() {
|
||||||
|
|
|
@ -149,6 +149,7 @@ pub fn help_modules(
|
||||||
if !module.decls.is_empty() || module.main.is_some() {
|
if !module.decls.is_empty() || module.main.is_some() {
|
||||||
let commands: Vec<(Vec<u8>, DeclId)> = engine_state
|
let commands: Vec<(Vec<u8>, DeclId)> = engine_state
|
||||||
.get_decls_sorted(false)
|
.get_decls_sorted(false)
|
||||||
|
.into_iter()
|
||||||
.filter(|(_, id)| !engine_state.get_decl(*id).is_alias())
|
.filter(|(_, id)| !engine_state.get_decl(*id).is_alias())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -186,6 +187,7 @@ pub fn help_modules(
|
||||||
if !module.decls.is_empty() {
|
if !module.decls.is_empty() {
|
||||||
let aliases: Vec<(Vec<u8>, DeclId)> = engine_state
|
let aliases: Vec<(Vec<u8>, DeclId)> = engine_state
|
||||||
.get_decls_sorted(false)
|
.get_decls_sorted(false)
|
||||||
|
.into_iter()
|
||||||
.filter(|(_, id)| engine_state.get_decl(*id).is_alias())
|
.filter(|(_, id)| engine_state.get_decl(*id).is_alias())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for MathCommand {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&MathCommand.signature(),
|
|
||||||
&MathCommand.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,6 @@ impl Command for Http {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Http.signature(),
|
|
||||||
&Http.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,16 +33,6 @@ impl Command for Url {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Url.signature(),
|
|
||||||
&Url.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,16 +42,6 @@ the path literal."#
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&PathCommand.signature(),
|
|
||||||
&PathCommand.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,16 +33,6 @@ impl Command for RandomCommand {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&RandomCommand.signature(),
|
|
||||||
&RandomCommand.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Stor {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Stor.signature(),
|
|
||||||
&Stor.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Format {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Format.signature(),
|
|
||||||
&Format.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for SplitCommand {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&SplitCommand.signature(),
|
|
||||||
&SplitCommand.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,6 @@ impl Command for Str {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(
|
|
||||||
&Str.signature(),
|
|
||||||
&Str.examples(),
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
self.is_keyword(),
|
|
||||||
),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,16 @@ use crate::eval_call;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Argument, Call, Expr, Expression, RecordItem},
|
ast::{Argument, Call, Expr, Expression, RecordItem},
|
||||||
debugger::WithoutDebug,
|
debugger::WithoutDebug,
|
||||||
engine::{EngineState, Stack},
|
engine::{Command, EngineState, Stack},
|
||||||
record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Type,
|
record, Category, Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Type,
|
||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, fmt::Write};
|
use std::{collections::HashMap, fmt::Write};
|
||||||
|
|
||||||
pub fn get_full_help(
|
pub fn get_full_help(
|
||||||
sig: &Signature,
|
command: &dyn Command,
|
||||||
examples: &[Example],
|
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
is_parser_keyword: bool,
|
|
||||||
) -> String {
|
) -> String {
|
||||||
let config = engine_state.get_config();
|
let config = engine_state.get_config();
|
||||||
let doc_config = DocumentationConfig {
|
let doc_config = DocumentationConfig {
|
||||||
|
@ -23,14 +21,15 @@ pub fn get_full_help(
|
||||||
};
|
};
|
||||||
|
|
||||||
let stack = &mut stack.start_capture();
|
let stack = &mut stack.start_capture();
|
||||||
|
let signature = command.signature().update_from_command(command);
|
||||||
|
|
||||||
get_documentation(
|
get_documentation(
|
||||||
sig,
|
&signature,
|
||||||
examples,
|
&command.examples(),
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
&doc_config,
|
&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()
|
code_string.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
|
||||||
fn get_documentation(
|
fn get_documentation(
|
||||||
sig: &Signature,
|
sig: &Signature,
|
||||||
examples: &[Example],
|
examples: &[Example],
|
||||||
|
|
|
@ -27,18 +27,8 @@ pub fn eval_call<D: DebugContext>(
|
||||||
let decl = engine_state.get_decl(call.decl_id);
|
let decl = engine_state.get_decl(call.decl_id);
|
||||||
|
|
||||||
if !decl.is_known_external() && call.named_iter().any(|(flag, _, _)| flag.item == "help") {
|
if !decl.is_known_external() && call.named_iter().any(|(flag, _, _)| flag.item == "help") {
|
||||||
let mut signature = engine_state.get_signature(decl);
|
let help = get_full_help(decl, engine_state, caller_stack);
|
||||||
signature.usage = decl.usage().to_string();
|
Ok(Value::string(help, call.head).into_pipeline_data())
|
||||||
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())
|
|
||||||
} else if let Some(block_id) = decl.block_id() {
|
} else if let Some(block_id) = decl.block_id() {
|
||||||
let block = engine_state.get_block(block_id);
|
let block = engine_state.get_block(block_id);
|
||||||
|
|
||||||
|
|
|
@ -139,14 +139,10 @@ impl<'a> PluginExecutionContext for PluginExecutionCommandContext<'a> {
|
||||||
fn get_help(&self) -> Result<Spanned<String>, ShellError> {
|
fn get_help(&self) -> Result<Spanned<String>, ShellError> {
|
||||||
let decl = self.engine_state.get_decl(self.call.decl_id);
|
let decl = self.engine_state.get_decl(self.call.decl_id);
|
||||||
|
|
||||||
Ok(get_full_help(
|
Ok(
|
||||||
&decl.signature(),
|
get_full_help(decl, &self.engine_state, &mut self.stack.clone())
|
||||||
&decl.examples(),
|
.into_spanned(self.call.head),
|
||||||
&self.engine_state,
|
|
||||||
&mut self.stack.clone(),
|
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.into_spanned(self.call.head))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_span_contents(&self, span: Span) -> Result<Spanned<Vec<u8>>, ShellError> {
|
fn get_span_contents(&self, span: Span) -> Result<Spanned<Vec<u8>>, ShellError> {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
Variable, Visibility, DEFAULT_OVERLAY_NAME,
|
Variable, Visibility, DEFAULT_OVERLAY_NAME,
|
||||||
},
|
},
|
||||||
eval_const::create_nu_constant,
|
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,
|
ShellError, Signature, Span, Type, Value, VarId, VirtualPathId,
|
||||||
};
|
};
|
||||||
use fancy_regex::Regex;
|
use fancy_regex::Regex;
|
||||||
|
@ -766,10 +766,7 @@ impl EngineState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all commands within scope, sorted by the commands' names
|
/// Get all commands within scope, sorted by the commands' names
|
||||||
pub fn get_decls_sorted(
|
pub fn get_decls_sorted(&self, include_hidden: bool) -> Vec<(Vec<u8>, DeclId)> {
|
||||||
&self,
|
|
||||||
include_hidden: bool,
|
|
||||||
) -> impl Iterator<Item = (Vec<u8>, DeclId)> {
|
|
||||||
let mut decls_map = HashMap::new();
|
let mut decls_map = HashMap::new();
|
||||||
|
|
||||||
for overlay_frame in self.active_overlays(&[]) {
|
for overlay_frame in self.active_overlays(&[]) {
|
||||||
|
@ -790,7 +787,7 @@ impl EngineState {
|
||||||
let mut decls: Vec<(Vec<u8>, DeclId)> = decls_map.into_iter().collect();
|
let mut decls: Vec<(Vec<u8>, DeclId)> = decls_map.into_iter().collect();
|
||||||
|
|
||||||
decls.sort_by(|a, b| a.0.cmp(&b.0));
|
decls.sort_by(|a, b| a.0.cmp(&b.0));
|
||||||
decls.into_iter()
|
decls
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_signature(&self, decl: &dyn Command) -> Signature {
|
pub fn get_signature(&self, decl: &dyn Command) -> Signature {
|
||||||
|
@ -804,6 +801,7 @@ impl EngineState {
|
||||||
/// Get signatures of all commands within scope.
|
/// Get signatures of all commands within scope.
|
||||||
pub fn get_signatures(&self, include_hidden: bool) -> Vec<Signature> {
|
pub fn get_signatures(&self, include_hidden: bool) -> Vec<Signature> {
|
||||||
self.get_decls_sorted(include_hidden)
|
self.get_decls_sorted(include_hidden)
|
||||||
|
.into_iter()
|
||||||
.map(|(_, id)| {
|
.map(|(_, id)| {
|
||||||
let decl = self.get_decl(id);
|
let decl = self.get_decl(id);
|
||||||
|
|
||||||
|
@ -812,22 +810,6 @@ impl EngineState {
|
||||||
.collect()
|
.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<Example>, 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<Block> {
|
pub fn get_block(&self, block_id: BlockId) -> &Arc<Block> {
|
||||||
self.blocks
|
self.blocks
|
||||||
.get(block_id)
|
.get(block_id)
|
||||||
|
|
|
@ -191,13 +191,7 @@ pub(crate) fn parse_commandline_args(
|
||||||
let help = call.has_flag(engine_state, &mut stack, "help")?;
|
let help = call.has_flag(engine_state, &mut stack, "help")?;
|
||||||
|
|
||||||
if help {
|
if help {
|
||||||
let full_help = get_full_help(
|
let full_help = get_full_help(&Nu, engine_state, &mut stack);
|
||||||
&Nu.signature(),
|
|
||||||
&Nu.examples(),
|
|
||||||
engine_state,
|
|
||||||
&mut stack,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
let _ = std::panic::catch_unwind(move || stdout_write_all_and_flush(full_help));
|
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
|
// Just give the help and exit if the above fails
|
||||||
let full_help = get_full_help(
|
let full_help = get_full_help(&Nu, engine_state, &mut stack);
|
||||||
&Nu.signature(),
|
|
||||||
&Nu.examples(),
|
|
||||||
engine_state,
|
|
||||||
&mut stack,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
print!("{full_help}");
|
print!("{full_help}");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
@ -452,11 +440,7 @@ impl Command for Nu {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
Ok(Value::string(
|
Ok(Value::string(get_full_help(self, engine_state, stack), call.head).into_pipeline_data())
|
||||||
get_full_help(&Nu.signature(), &Nu.examples(), engine_state, stack, true),
|
|
||||||
call.head,
|
|
||||||
)
|
|
||||||
.into_pipeline_data())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<nu_protocol::Example> {
|
fn examples(&self) -> Vec<nu_protocol::Example> {
|
||||||
|
|
|
@ -54,8 +54,7 @@ fn in_and_if_else() -> TestResult {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn help_works_with_missing_requirements() -> TestResult {
|
fn help_works_with_missing_requirements() -> TestResult {
|
||||||
let expected_length = "70";
|
run_test(r#"each --help | lines | length"#, "72")
|
||||||
run_test(r#"each --help | lines | length"#, expected_length)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -65,12 +64,12 @@ fn scope_variable() -> TestResult {
|
||||||
"int",
|
"int",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case("a", "<> nothing")]
|
#[case("a", "<> nothing")]
|
||||||
#[case("b", "<1.23> float")]
|
#[case("b", "<1.23> float")]
|
||||||
#[case("flag1", "<> nothing")]
|
#[case("flag1", "<> nothing")]
|
||||||
#[case("flag2", "<4.56> float")]
|
#[case("flag2", "<4.56> float")]
|
||||||
|
|
||||||
fn scope_command_defaults(#[case] var: &str, #[case] exp_result: &str) -> TestResult {
|
fn scope_command_defaults(#[case] var: &str, #[case] exp_result: &str) -> TestResult {
|
||||||
run_test(
|
run_test(
|
||||||
&format!(
|
&format!(
|
||||||
|
|
Loading…
Reference in a new issue