2019-08-30 00:52:32 +02:00
|
|
|
use crate::commands::PerItemCommand;
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
use crate::data::base::property_get::get_data_by_key;
|
2019-12-04 20:52:31 +01:00
|
|
|
use crate::data::command_dict;
|
2019-08-30 00:52:32 +02:00
|
|
|
use crate::prelude::*;
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
use nu_errors::ShellError;
|
|
|
|
use nu_protocol::{
|
|
|
|
CallInfo, NamedType, PositionalType, Primitive, ReturnSuccess, Signature, SyntaxShape,
|
2019-12-04 20:52:31 +01:00
|
|
|
TaggedDictBuilder, UntaggedValue, Value,
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
};
|
2019-11-21 15:33:14 +01:00
|
|
|
use nu_source::SpannedItem;
|
2019-08-30 00:52:32 +02:00
|
|
|
|
|
|
|
pub struct Help;
|
|
|
|
|
|
|
|
impl PerItemCommand for Help {
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
"help"
|
|
|
|
}
|
|
|
|
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
fn signature(&self) -> Signature {
|
2019-10-28 06:15:35 +01:00
|
|
|
Signature::build("help").rest(SyntaxShape::Any, "the name of command(s) to get help on")
|
2019-08-30 00:52:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn usage(&self) -> &str {
|
|
|
|
"Display help information about commands."
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(
|
|
|
|
&self,
|
|
|
|
call_info: &CallInfo,
|
2019-09-03 11:36:23 +02:00
|
|
|
registry: &CommandRegistry,
|
2019-08-30 00:52:32 +02:00
|
|
|
_raw_args: &RawCommandArgs,
|
2019-11-21 15:33:14 +01:00
|
|
|
_input: Value,
|
2019-08-30 00:52:32 +02:00
|
|
|
) -> Result<OutputStream, ShellError> {
|
2019-10-13 06:12:43 +02:00
|
|
|
let tag = &call_info.name_tag;
|
2019-08-30 00:52:32 +02:00
|
|
|
|
2019-09-24 09:56:03 +02:00
|
|
|
match call_info.args.nth(0) {
|
2019-11-21 15:33:14 +01:00
|
|
|
Some(Value {
|
|
|
|
value: UntaggedValue::Primitive(Primitive::String(document)),
|
2019-09-03 11:36:23 +02:00
|
|
|
tag,
|
2019-09-24 09:56:03 +02:00
|
|
|
}) => {
|
2019-09-12 20:29:16 +02:00
|
|
|
let mut help = VecDeque::new();
|
2019-09-03 11:36:23 +02:00
|
|
|
if document == "commands" {
|
2019-09-12 20:29:16 +02:00
|
|
|
let mut sorted_names = registry.names();
|
|
|
|
sorted_names.sort();
|
|
|
|
for cmd in sorted_names {
|
|
|
|
let mut short_desc = TaggedDictBuilder::new(tag.clone());
|
2019-09-03 11:36:23 +02:00
|
|
|
let value = command_dict(registry.get_command(&cmd).unwrap(), tag.clone());
|
|
|
|
|
2019-11-21 15:33:14 +01:00
|
|
|
short_desc.insert_untagged("name", cmd);
|
|
|
|
short_desc.insert_untagged(
|
2019-09-03 11:36:23 +02:00
|
|
|
"description",
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
get_data_by_key(&value, "usage".spanned_unknown())
|
2019-11-04 16:47:03 +01:00
|
|
|
.unwrap()
|
|
|
|
.as_string()
|
|
|
|
.unwrap(),
|
2019-09-03 11:36:23 +02:00
|
|
|
);
|
|
|
|
|
2019-11-21 15:33:14 +01:00
|
|
|
help.push_back(ReturnSuccess::value(short_desc.into_value()));
|
2019-09-03 11:36:23 +02:00
|
|
|
}
|
2019-09-12 20:29:16 +02:00
|
|
|
} else {
|
|
|
|
if let Some(command) = registry.get_command(document) {
|
|
|
|
let mut long_desc = String::new();
|
|
|
|
|
|
|
|
long_desc.push_str(&command.usage());
|
|
|
|
long_desc.push_str("\n");
|
|
|
|
|
|
|
|
let signature = command.signature();
|
|
|
|
|
|
|
|
let mut one_liner = String::new();
|
|
|
|
one_liner.push_str(&signature.name);
|
|
|
|
one_liner.push_str(" ");
|
|
|
|
|
2019-10-28 06:15:35 +01:00
|
|
|
for positional in &signature.positional {
|
|
|
|
match &positional.0 {
|
2019-09-12 20:29:16 +02:00
|
|
|
PositionalType::Mandatory(name, _m) => {
|
|
|
|
one_liner.push_str(&format!("<{}> ", name));
|
|
|
|
}
|
|
|
|
PositionalType::Optional(name, _o) => {
|
|
|
|
one_liner.push_str(&format!("({}) ", name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-03 11:36:23 +02:00
|
|
|
|
2019-09-12 20:29:16 +02:00
|
|
|
if signature.rest_positional.is_some() {
|
2019-10-28 06:15:35 +01:00
|
|
|
one_liner.push_str(&format!(" ...args",));
|
2019-09-12 20:29:16 +02:00
|
|
|
}
|
2019-10-28 06:15:35 +01:00
|
|
|
|
2019-11-06 03:28:26 +01:00
|
|
|
if signature.named.len() > 0 {
|
|
|
|
one_liner.push_str("{flags} ");
|
|
|
|
}
|
|
|
|
|
2019-09-12 20:29:16 +02:00
|
|
|
long_desc.push_str(&format!("\nUsage:\n > {}\n", one_liner));
|
|
|
|
|
2019-10-28 06:15:35 +01:00
|
|
|
if signature.positional.len() > 0 || signature.rest_positional.is_some() {
|
|
|
|
long_desc.push_str("\nparameters:\n");
|
|
|
|
for positional in signature.positional {
|
|
|
|
match positional.0 {
|
|
|
|
PositionalType::Mandatory(name, _m) => {
|
|
|
|
long_desc
|
|
|
|
.push_str(&format!(" <{}> {}\n", name, positional.1));
|
|
|
|
}
|
|
|
|
PositionalType::Optional(name, _o) => {
|
|
|
|
long_desc
|
|
|
|
.push_str(&format!(" ({}) {}\n", name, positional.1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if signature.rest_positional.is_some() {
|
|
|
|
long_desc.push_str(&format!(
|
|
|
|
" ...args{} {}\n",
|
|
|
|
if signature.rest_positional.is_some() {
|
|
|
|
":"
|
|
|
|
} else {
|
|
|
|
""
|
|
|
|
},
|
|
|
|
signature.rest_positional.unwrap().1
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
2019-09-12 20:29:16 +02:00
|
|
|
if signature.named.len() > 0 {
|
|
|
|
long_desc.push_str("\nflags:\n");
|
|
|
|
for (flag, ty) in signature.named {
|
2019-10-28 06:15:35 +01:00
|
|
|
match ty.0 {
|
2019-09-12 20:29:16 +02:00
|
|
|
NamedType::Switch => {
|
2019-10-28 06:15:35 +01:00
|
|
|
long_desc.push_str(&format!(
|
|
|
|
" --{}{} {}\n",
|
|
|
|
flag,
|
|
|
|
if ty.1.len() > 0 { ":" } else { "" },
|
|
|
|
ty.1
|
|
|
|
));
|
2019-09-12 20:29:16 +02:00
|
|
|
}
|
|
|
|
NamedType::Mandatory(m) => {
|
|
|
|
long_desc.push_str(&format!(
|
2019-10-28 06:15:35 +01:00
|
|
|
" --{} <{}> (required parameter){} {}\n",
|
|
|
|
flag,
|
2019-11-25 19:07:20 +01:00
|
|
|
m.display(),
|
2019-10-28 06:15:35 +01:00
|
|
|
if ty.1.len() > 0 { ":" } else { "" },
|
|
|
|
ty.1
|
2019-09-12 20:29:16 +02:00
|
|
|
));
|
|
|
|
}
|
|
|
|
NamedType::Optional(o) => {
|
2019-10-28 06:15:35 +01:00
|
|
|
long_desc.push_str(&format!(
|
|
|
|
" --{} <{}>{} {}\n",
|
|
|
|
flag,
|
2019-11-25 19:07:20 +01:00
|
|
|
o.display(),
|
2019-10-28 06:15:35 +01:00
|
|
|
if ty.1.len() > 0 { ":" } else { "" },
|
|
|
|
ty.1
|
|
|
|
));
|
2019-09-12 20:29:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
help.push_back(ReturnSuccess::value(
|
2019-12-04 20:52:31 +01:00
|
|
|
UntaggedValue::string(long_desc).into_value(tag.clone()),
|
2019-09-12 20:29:16 +02:00
|
|
|
));
|
|
|
|
}
|
2019-09-03 11:36:23 +02:00
|
|
|
}
|
|
|
|
|
2019-09-12 20:29:16 +02:00
|
|
|
Ok(help.to_output_stream())
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
let msg = r#"Welcome to Nushell.
|
2019-09-12 20:33:52 +02:00
|
|
|
|
2019-09-12 20:29:16 +02:00
|
|
|
Here are some tips to help you get started.
|
2019-09-12 20:33:52 +02:00
|
|
|
* help commands - list all available commands
|
|
|
|
* help <command name> - display help about a particular command
|
|
|
|
|
2019-09-29 21:03:51 +02:00
|
|
|
You can also learn more at https://book.nushell.sh"#;
|
2019-09-12 20:29:16 +02:00
|
|
|
|
|
|
|
let mut output_stream = VecDeque::new();
|
|
|
|
|
2019-12-04 20:52:31 +01:00
|
|
|
output_stream.push_back(ReturnSuccess::value(
|
|
|
|
UntaggedValue::string(msg).into_value(tag),
|
|
|
|
));
|
2019-09-12 20:29:16 +02:00
|
|
|
|
|
|
|
Ok(output_stream.to_output_stream())
|
2019-09-03 11:36:23 +02:00
|
|
|
}
|
2019-08-30 00:52:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|