add signature information when get help on one command (#7079)

* add signature information when help on one command

* tell user that one command support operated on cell paths

Also, make type output to be more friendly, like `record<>` should just be `record`

And the same to `table<>`, which should be `table`

* simplify code

* don't show signatures for parser keyword

* update comment

* output arg syntax shape as type, so it's the same as describe command

* fix string when no positional args

* update signature body

* update

* add help signature test

* fix arg output format for composed data type like list or record

* fix clippy

* add comment
This commit is contained in:
WindSoilder
2022-11-20 21:22:42 +08:00
committed by GitHub
parent a896892ac9
commit d01ccd5a54
29 changed files with 258 additions and 55 deletions

View File

@ -29,7 +29,13 @@ impl Command for Bits {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Bits.signature(), &Bits.examples(), engine_state, stack),
val: get_full_help(
&Bits.signature(),
&Bits.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -29,7 +29,13 @@ impl Command for Bytes {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Bytes.signature(), &Bytes.examples(), engine_state, stack),
val: get_full_help(
&Bytes.signature(),
&Bytes.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -29,7 +29,13 @@ impl Command for Into {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Into.signature(), &[], engine_state, stack),
val: get_full_help(
&Into.signature(),
&[],
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -45,6 +45,7 @@ impl Command for ExportCommand {
&ExportCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -1,5 +1,4 @@
use fancy_regex::Regex;
use itertools::Itertools;
use nu_ansi_term::{
Color::{Default, Red, White},
Style,
@ -105,6 +104,7 @@ fn help(
let mut vals = vec![];
let decl = engine_state.get_decl(decl_id);
let sig = decl.signature().update_from_command(decl.borrow());
let signatures = sig.to_string();
let key = sig.name;
let usage = sig.usage;
let search_terms = sig.search_terms;
@ -154,11 +154,11 @@ fn help(
cols.push("signatures".into());
vals.push(Value::String {
val: sig
.input_output_types
.iter()
.map(|(i, o)| format!("{:?} => {:?}", i.to_shape(), o.to_shape()))
.join("\n"),
val: if decl.is_parser_keyword() {
"".to_string()
} else {
signatures
},
span: head,
});
@ -219,6 +219,7 @@ fn help(
let decl = engine_state.get_decl(decl_id);
let sig = decl.signature().update_from_command(decl.borrow());
let signatures = sig.to_string();
let key = sig.name;
let usage = sig.usage;
let search_terms = sig.search_terms;
@ -249,11 +250,11 @@ fn help(
cols.push("signatures".into());
vals.push(Value::String {
val: sig
.input_output_types
.iter()
.map(|(i, o)| format!("{:?} => {:?}", i.to_shape(), o.to_shape()))
.join("\n"),
val: if decl.is_parser_keyword() {
"".to_string()
} else {
signatures
},
span: head,
});
@ -290,9 +291,9 @@ fn help(
let output = engine_state
.get_signatures_with_examples(false)
.iter()
.filter(|(signature, _, _, _)| signature.name == name)
.map(|(signature, examples, _, _)| {
get_full_help(signature, examples, engine_state, stack)
.filter(|(signature, _, _, _, _)| signature.name == name)
.map(|(signature, examples, _, _, is_parser_keyword)| {
get_full_help(signature, examples, engine_state, stack, *is_parser_keyword)
})
.collect::<Vec<String>>();

View File

@ -38,7 +38,13 @@ impl Command for Overlay {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Overlay.signature(), &[], engine_state, stack),
val: get_full_help(
&Overlay.signature(),
&[],
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -53,7 +53,13 @@ fn date(
let head = call.head;
Ok(Value::String {
val: get_full_help(&Date.signature(), &Date.examples(), engine_state, stack),
val: get_full_help(
&Date.signature(),
&Date.examples(),
engine_state,
stack,
false,
),
span: head,
}
.into_pipeline_data())

View File

@ -34,6 +34,7 @@ impl Command for ConfigMeta {
&ConfigMeta.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -31,7 +31,13 @@ impl Command for Roll {
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(Value::String {
val: get_full_help(&Roll.signature(), &Roll.examples(), engine_state, stack),
val: get_full_help(
&Roll.signature(),
&Roll.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -27,7 +27,13 @@ impl Command for From {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, ShellError> {
Ok(Value::String {
val: get_full_help(&From.signature(), &From.examples(), engine_state, stack),
val: get_full_help(
&From.signature(),
&From.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -27,7 +27,13 @@ impl Command for To {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, ShellError> {
Ok(Value::String {
val: get_full_help(&To.signature(), &To.examples(), engine_state, stack),
val: get_full_help(
&To.signature(),
&To.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -27,7 +27,13 @@ impl Command for Hash {
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(Value::String {
val: get_full_help(&Self.signature(), &Self.examples(), engine_state, stack),
val: get_full_help(
&Self.signature(),
&Self.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -34,6 +34,7 @@ impl Command for MathCommand {
&MathCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -35,7 +35,13 @@ impl Command for Url {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Url.signature(), &Url.examples(), engine_state, stack),
val: get_full_help(
&Url.signature(),
&Url.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -49,6 +49,7 @@ the path literal."#
&PathCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -38,6 +38,7 @@ impl Command for Keybindings {
&Keybindings.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -38,6 +38,7 @@ impl Command for RandomCommand {
&RandomCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -34,6 +34,7 @@ impl Command for SplitCommand {
&SplitCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}

View File

@ -29,7 +29,13 @@ impl Command for Str {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Str.signature(), &Str.examples(), engine_state, stack),
val: get_full_help(
&Str.signature(),
&Str.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
.into_pipeline_data())

View File

@ -14,3 +14,15 @@ fn help_commands_length() {
let is_positive = output_int.is_positive();
assert!(is_positive);
}
#[test]
fn help_shows_signature() {
let actual = nu!(cwd: ".", pipeline("help str distance"));
assert!(actual
.out
.contains("<string> | str distance <string> -> <int>"));
// don't show signature for parser keyword
let actual = nu!(cwd: ".", pipeline("help alias"));
assert!(!actual.out.contains("Signatures"));
}

View File

@ -92,7 +92,7 @@ fn reject_record_from_raw_eval() {
)
);
assert!(actual.out.contains("record<>"));
assert!(actual.out.contains("record"));
}
#[test]