Merge pull request #555 from nushell/help

Help baseline.
This commit is contained in:
Andrés N. Robalino 2019-08-31 19:37:25 -05:00 committed by GitHub
commit dd3c149615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 1180 additions and 453 deletions

View File

@ -209,6 +209,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| date (--utc) | Get the current datetime | | date (--utc) | Get the current datetime |
| ps | View current processes | | ps | View current processes |
| sys | View information about the current system | | sys | View information about the current system |
| which filename | Finds a program file. |
| open {filename or url} | Load a file into a cell, convert to table if possible (avoid by appending '--raw') | | open {filename or url} | Load a file into a cell, convert to table if possible (avoid by appending '--raw') |
| post url body (--user <user>) (--password <password>) | Post content to a url and retrieve data as a table if possible | | post url body (--user <user>) (--password <password>) | Post content to a url and retrieve data as a table if possible |
| rm {file or directory} | Remove a file, (for removing directory append '--recursive') | | rm {file or directory} | Remove a file, (for removing directory append '--recursive') |
@ -217,6 +218,8 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| p | Go to previous shell | | p | Go to previous shell |
| n | Go to next shell | | n | Go to next shell |
| shells | Display the list of current shells | | shells | Display the list of current shells |
| help | Display help information about commands |
| version | Display Nu version |
## Filters on tables (structured data) ## Filters on tables (structured data)
| command | description | | command | description |
@ -230,8 +233,11 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| add field value | Add a new field to the table | | add field value | Add a new field to the table |
| sum | Sum a column of values | | sum | Sum a column of values |
| edit field value | Edit an existing field to have a new value | | edit field value | Edit an existing field to have a new value |
| reverse | Reverses the table. |
| skip amount | Skip a number of rows | | skip amount | Skip a number of rows |
| skip-while condition | Skips rows while the condition matches. |
| first amount | Show only the first number of rows | | first amount | Show only the first number of rows |
| last amount | Show only the last number of rows |
| nth row-number | Return only the selected row | | nth row-number | Return only the selected row |
| str (field) | Apply string function. Optional use the field of a table | | str (field) | Apply string function. Optional use the field of a table |
| tags | Read the tags (metadata) for values | | tags | Read the tags (metadata) for values |
@ -240,13 +246,13 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| to-json | Convert table into .json text | | to-json | Convert table into .json text |
| to-toml | Convert table into .toml text | | to-toml | Convert table into .toml text |
| to-yaml | Convert table into .yaml text | | to-yaml | Convert table into .yaml text |
| to-bson | Convert table into .bson text |
| to-csv | Convert table into .csv text | | to-csv | Convert table into .csv text |
| to-bson | Convert table into .bson binary data | | to-bson | Convert table into .bson binary data |
| to-tsv | Convert table into .tsv text | | to-tsv | Convert table into .tsv text |
| to-sqlite | Convert table to sqlite .db binary data | | to-sqlite | Convert table to sqlite .db binary data |
| reverse | Reverse the rows of a table | | reverse | Reverse the rows of a table |
## Filters on text (unstructured data) ## Filters on text (unstructured data)
| command | description | | command | description |
| ------------- | ------------- | | ------------- | ------------- |

View File

@ -212,6 +212,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
whole_stream_command(Config), whole_stream_command(Config),
whole_stream_command(SkipWhile), whole_stream_command(SkipWhile),
per_item_command(Enter), per_item_command(Enter),
per_item_command(Help),
whole_stream_command(Exit), whole_stream_command(Exit),
whole_stream_command(Autoview), whole_stream_command(Autoview),
per_item_command(Cpy), per_item_command(Cpy),

View File

@ -25,6 +25,7 @@ pub(crate) mod from_tsv;
pub(crate) mod from_xml; pub(crate) mod from_xml;
pub(crate) mod from_yaml; pub(crate) mod from_yaml;
pub(crate) mod get; pub(crate) mod get;
pub(crate) mod help;
pub(crate) mod last; pub(crate) mod last;
pub(crate) mod lines; pub(crate) mod lines;
pub(crate) mod ls; pub(crate) mod ls;
@ -91,6 +92,7 @@ pub(crate) use from_xml::FromXML;
pub(crate) use from_yaml::FromYAML; pub(crate) use from_yaml::FromYAML;
pub(crate) use from_yaml::FromYML; pub(crate) use from_yaml::FromYML;
pub(crate) use get::Get; pub(crate) use get::Get;
pub(crate) use help::Help;
pub(crate) use last::Last; pub(crate) use last::Last;
pub(crate) use lines::Lines; pub(crate) use lines::Lines;
pub(crate) use ls::LS; pub(crate) use ls::LS;

View File

@ -12,6 +12,14 @@ impl WholeStreamCommand for Autoview {
"autoview" "autoview"
} }
fn signature(&self) -> Signature {
Signature::build("autoview")
}
fn usage(&self) -> &str {
"View the contents of the pipeline as a table or list."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -19,10 +27,6 @@ impl WholeStreamCommand for Autoview {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
Ok(args.process_raw(registry, autoview)?.run()) Ok(args.process_raw(registry, autoview)?.run())
} }
fn signature(&self) -> Signature {
Signature::build("autoview")
}
} }
pub fn autoview( pub fn autoview(

View File

@ -5,6 +5,19 @@ use crate::prelude::*;
pub struct CD; pub struct CD;
impl WholeStreamCommand for CD { impl WholeStreamCommand for CD {
fn name(&self) -> &str {
"cd"
}
fn signature(&self) -> Signature {
Signature::build("cd")
.optional("directory", SyntaxType::Path)
}
fn usage(&self) -> &str {
"Change to a new path."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -12,14 +25,6 @@ impl WholeStreamCommand for CD {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
cd(args, registry) cd(args, registry)
} }
fn name(&self) -> &str {
"cd"
}
fn signature(&self) -> Signature {
Signature::build("cd").optional("directory", SyntaxType::Path)
}
} }
fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -140,6 +140,29 @@ impl InternalCommand {
context.add_span_source(uuid, span_source); context.add_span_source(uuid, span_source);
} }
CommandAction::Exit => std::process::exit(0), CommandAction::Exit => std::process::exit(0),
CommandAction::EnterHelpShell(value) => {
match value {
Tagged {
item: Value::Primitive(Primitive::String(cmd)),
..
} => {
context.shell_manager.insert_at_current(Box::new(
HelpShell::for_command(
Tagged::from_simple_spanned_item(
Value::string(cmd),
Span::unknown(),
),
&context.registry().clone(),
)?,
));
}
_ => {
context.shell_manager.insert_at_current(Box::new(
HelpShell::index(&context.registry().clone())?,
));
}
}
}
CommandAction::EnterValueShell(value) => { CommandAction::EnterValueShell(value) => {
context context
.shell_manager .shell_manager

View File

@ -18,6 +18,15 @@ pub mod clipboard {
fn name(&self) -> &str { fn name(&self) -> &str {
"clip" "clip"
} }
fn signature(&self) -> Signature {
Signature::build("clip")
}
fn usage(&self) -> &str {
"Copy the contents of the pipeline to the copy/paste buffer"
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -25,10 +34,6 @@ pub mod clipboard {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
args.process(registry, clip)?.run() args.process(registry, clip)?.run()
} }
fn signature(&self) -> Signature {
Signature::build("clip")
}
} }
pub fn clip( pub fn clip(

View File

@ -417,6 +417,7 @@ pub enum CommandAction {
Exit, Exit,
EnterShell(String), EnterShell(String),
EnterValueShell(Tagged<Value>), EnterValueShell(Tagged<Value>),
EnterHelpShell(Tagged<Value>),
PreviousShell, PreviousShell,
NextShell, NextShell,
LeaveShell, LeaveShell,
@ -434,6 +435,9 @@ impl ToDebug for CommandAction {
CommandAction::EnterValueShell(t) => { CommandAction::EnterValueShell(t) => {
write!(f, "action:enter-value-shell={:?}", t.debug()) write!(f, "action:enter-value-shell={:?}", t.debug())
} }
CommandAction::EnterHelpShell(t) => {
write!(f, "action:enter-help-shell={:?}", t.debug())
}
CommandAction::PreviousShell => write!(f, "action:previous-shell"), CommandAction::PreviousShell => write!(f, "action:previous-shell"),
CommandAction::NextShell => write!(f, "action:next-shell"), CommandAction::NextShell => write!(f, "action:next-shell"),
CommandAction::LeaveShell => write!(f, "action:leave-shell"), CommandAction::LeaveShell => write!(f, "action:leave-shell"),
@ -488,26 +492,42 @@ impl ReturnSuccess {
pub trait WholeStreamCommand: Send + Sync { pub trait WholeStreamCommand: Send + Sync {
fn name(&self) -> &str; fn name(&self) -> &str;
fn run(
&self,
args: CommandArgs,
registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError>;
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature { Signature {
name: self.name().to_string(), name: self.name().to_string(),
usage: self.usage().to_string(),
positional: vec![], positional: vec![],
rest_positional: None, rest_positional: None,
named: indexmap::IndexMap::new(), named: indexmap::IndexMap::new(),
is_filter: true, is_filter: true,
} }
} }
fn usage(&self) -> &str;
fn run(
&self,
args: CommandArgs,
registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError>;
} }
pub trait PerItemCommand: Send + Sync { pub trait PerItemCommand: Send + Sync {
fn name(&self) -> &str; fn name(&self) -> &str;
fn signature(&self) -> Signature {
Signature {
name: self.name().to_string(),
usage: self.usage().to_string(),
positional: vec![],
rest_positional: None,
named: indexmap::IndexMap::new(),
is_filter: true,
}
}
fn usage(&self) -> &str;
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,
@ -515,16 +535,6 @@ pub trait PerItemCommand: Send + Sync {
raw_args: &RawCommandArgs, raw_args: &RawCommandArgs,
input: Tagged<Value>, input: Tagged<Value>,
) -> Result<OutputStream, ShellError>; ) -> Result<OutputStream, ShellError>;
fn signature(&self) -> Signature {
Signature {
name: self.name().to_string(),
positional: vec![],
rest_positional: None,
named: indexmap::IndexMap::new(),
is_filter: true,
}
}
} }
pub enum Command { pub enum Command {
@ -547,6 +557,13 @@ impl Command {
} }
} }
pub fn usage(&self) -> &str {
match self {
Command::WholeStream(command) => command.usage(),
Command::PerItem(command) => command.usage(),
}
}
pub fn run(&self, args: CommandArgs, registry: &registry::CommandRegistry) -> OutputStream { pub fn run(&self, args: CommandArgs, registry: &registry::CommandRegistry) -> OutputStream {
match self { match self {
Command::WholeStream(command) => match command.run(args, registry) { Command::WholeStream(command) => match command.run(args, registry) {
@ -618,6 +635,10 @@ impl WholeStreamCommand for FnFilterCommand {
&self.name &self.name
} }
fn usage(&self) -> &str {
"usage"
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -32,6 +32,10 @@ impl WholeStreamCommand for Config {
.switch("path") .switch("path")
} }
fn usage(&self) -> &str {
"Configuration management."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -15,16 +15,6 @@ pub struct CopyArgs {
} }
impl PerItemCommand for Cpy { impl PerItemCommand for Cpy {
fn run(
&self,
call_info: &CallInfo,
_registry: &CommandRegistry,
raw_args: &RawCommandArgs,
_input: Tagged<Value>,
) -> Result<OutputStream, ShellError> {
call_info.process(&raw_args.shell_manager, cp)?.run()
}
fn name(&self) -> &str { fn name(&self) -> &str {
"cp" "cp"
} }
@ -36,6 +26,20 @@ impl PerItemCommand for Cpy {
.named("file", SyntaxType::Any) .named("file", SyntaxType::Any)
.switch("recursive") .switch("recursive")
} }
fn usage(&self) -> &str {
"Copy files."
}
fn run(
&self,
call_info: &CallInfo,
_registry: &CommandRegistry,
raw_args: &RawCommandArgs,
_input: Tagged<Value>,
) -> Result<OutputStream, ShellError> {
call_info.process(&raw_args.shell_manager, cp)?.run()
}
} }
fn cp(args: CopyArgs, context: &RunnablePerItemContext) -> Result<OutputStream, ShellError> { fn cp(args: CopyArgs, context: &RunnablePerItemContext) -> Result<OutputStream, ShellError> {

View File

@ -12,6 +12,20 @@ use indexmap::IndexMap;
pub struct Date; pub struct Date;
impl WholeStreamCommand for Date { impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date"
}
fn signature(&self) -> Signature {
Signature::build("date")
.switch("utc")
.switch("local")
}
fn usage(&self) -> &str {
"Get the current datetime."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -19,13 +33,6 @@ impl WholeStreamCommand for Date {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
date(args, registry) date(args, registry)
} }
fn name(&self) -> &str {
"date"
}
fn signature(&self) -> Signature {
Signature::build("date").switch("utc").switch("local")
}
} }
pub fn date_to_value<T: TimeZone>(dt: DateTime<T>, span: Span) -> Tagged<Value> pub fn date_to_value<T: TimeZone>(dt: DateTime<T>, span: Span) -> Tagged<Value>

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct Debug; pub struct Debug;
impl WholeStreamCommand for Debug { impl WholeStreamCommand for Debug {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
debug(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"debug" "debug"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for Debug {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("debug") Signature::build("debug")
} }
fn usage(&self) -> &str {
"Debug input fed."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
debug(args, registry)
}
} }
pub fn debug(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn debug(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -17,6 +17,10 @@ impl PerItemCommand for Enter {
Signature::build("enter").required("location", SyntaxType::Block) Signature::build("enter").required("location", SyntaxType::Block)
} }
fn usage(&self) -> &str {
"Create a new shell and begin at this path."
}
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,
@ -33,7 +37,13 @@ impl PerItemCommand for Enter {
} => { } => {
let location = location.to_string(); let location = location.to_string();
let location_clone = location.to_string(); let location_clone = location.to_string();
if PathBuf::from(location).is_dir() {
if registry.has(&location) {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
Value::string(location_clone).tagged(Tag::unknown()),
)))]
.into())
} else if PathBuf::from(location).is_dir() {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell( Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell(
location_clone, location_clone,
)))] )))]

View File

@ -6,6 +6,19 @@ use crate::prelude::*;
pub struct Exit; pub struct Exit;
impl WholeStreamCommand for Exit { impl WholeStreamCommand for Exit {
fn name(&self) -> &str {
"exit"
}
fn signature(&self) -> Signature {
Signature::build("exit")
.switch("now")
}
fn usage(&self) -> &str {
"Exit the current shell (or all shells)"
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -13,14 +26,6 @@ impl WholeStreamCommand for Exit {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
exit(args, registry) exit(args, registry)
} }
fn name(&self) -> &str {
"exit"
}
fn signature(&self) -> Signature {
Signature::build("exit").switch("now")
}
} }
pub fn exit(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn exit(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -6,6 +6,19 @@ use crate::prelude::*;
pub struct First; pub struct First;
impl WholeStreamCommand for First { impl WholeStreamCommand for First {
fn name(&self) -> &str {
"first"
}
fn signature(&self) -> Signature {
Signature::build("first")
.required("amount", SyntaxType::Literal)
}
fn usage(&self) -> &str {
"Show only the first number of rows."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -13,14 +26,6 @@ impl WholeStreamCommand for First {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
first(args, registry) first(args, registry)
} }
fn name(&self) -> &str {
"first"
}
fn signature(&self) -> Signature {
Signature::build("first").required("amount", SyntaxType::Literal)
}
} }
fn first(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn first(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct FromArray; pub struct FromArray;
impl WholeStreamCommand for FromArray { impl WholeStreamCommand for FromArray {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_array(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-array" "from-array"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for FromArray {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-array") Signature::build("from-array")
} }
fn usage(&self) -> &str {
"Expand an array/list into rows"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_array(args, registry)
}
} }
fn from_array(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn from_array(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -7,14 +7,6 @@ use std::str::FromStr;
pub struct FromBSON; pub struct FromBSON;
impl WholeStreamCommand for FromBSON { impl WholeStreamCommand for FromBSON {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_bson(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-bson" "from-bson"
} }
@ -22,6 +14,18 @@ impl WholeStreamCommand for FromBSON {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-bson") Signature::build("from-bson")
} }
fn usage(&self) -> &str {
"Parse text as .bson and create table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_bson(args, registry)
}
} }
fn convert_bson_value_to_nu_value(v: &Bson, tag: impl Into<Tag>) -> Tagged<Value> { fn convert_bson_value_to_nu_value(v: &Bson, tag: impl Into<Tag>) -> Tagged<Value> {

View File

@ -16,7 +16,12 @@ impl WholeStreamCommand for FromCSV {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-csv").switch("headerless") Signature::build("from-csv")
.switch("headerless")
}
fn usage(&self) -> &str {
"Parse text as .csv and create table"
} }
fn run( fn run(

View File

@ -6,14 +6,6 @@ use std::collections::HashMap;
pub struct FromINI; pub struct FromINI;
impl WholeStreamCommand for FromINI { impl WholeStreamCommand for FromINI {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_ini(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-ini" "from-ini"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for FromINI {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-ini") Signature::build("from-ini")
} }
fn usage(&self) -> &str {
"Parse text as .ini and create table"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_ini(args, registry)
}
} }
fn convert_ini_second_to_nu_value( fn convert_ini_second_to_nu_value(

View File

@ -15,7 +15,12 @@ impl WholeStreamCommand for FromJSON {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-json").switch("objects") Signature::build("from-json")
.switch("objects")
}
fn usage(&self) -> &str {
"Parse text as .json and create table."
} }
fn run( fn run(

View File

@ -9,14 +9,6 @@ use std::path::Path;
pub struct FromSQLite; pub struct FromSQLite;
impl WholeStreamCommand for FromSQLite { impl WholeStreamCommand for FromSQLite {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_sqlite(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-sqlite" "from-sqlite"
} }
@ -24,11 +16,11 @@ impl WholeStreamCommand for FromSQLite {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-sqlite") Signature::build("from-sqlite")
} }
}
pub struct FromDB; fn usage(&self) -> &str {
"Parse binary data as sqlite .db and create table."
}
impl WholeStreamCommand for FromDB {
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -36,7 +28,11 @@ impl WholeStreamCommand for FromDB {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
from_sqlite(args, registry) from_sqlite(args, registry)
} }
}
pub struct FromDB;
impl WholeStreamCommand for FromDB {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-db" "from-db"
} }
@ -44,6 +40,18 @@ impl WholeStreamCommand for FromDB {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-db") Signature::build("from-db")
} }
fn usage(&self) -> &str {
"Parse binary data as db and create table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_sqlite(args, registry)
}
} }
pub fn convert_sqlite_file_to_nu_value( pub fn convert_sqlite_file_to_nu_value(

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct FromTOML; pub struct FromTOML;
impl WholeStreamCommand for FromTOML { impl WholeStreamCommand for FromTOML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_toml(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-toml" "from-toml"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for FromTOML {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-toml") Signature::build("from-toml")
} }
fn usage(&self) -> &str {
"Parse text as .toml and create table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_toml(args, registry)
}
} }
pub fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> Tagged<Value> { pub fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> Tagged<Value> {

View File

@ -19,6 +19,10 @@ impl WholeStreamCommand for FromTSV {
Signature::build("from-tsv").switch("headerless") Signature::build("from-tsv").switch("headerless")
} }
fn usage(&self) -> &str {
"Parse text as .tsv and create table."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct FromXML; pub struct FromXML;
impl WholeStreamCommand for FromXML { impl WholeStreamCommand for FromXML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_xml(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-xml" "from-xml"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for FromXML {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-xml") Signature::build("from-xml")
} }
fn usage(&self) -> &str {
"Parse text as .xml and create table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_xml(args, registry)
}
} }
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Tagged<Value> { fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Tagged<Value> {

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct FromYAML; pub struct FromYAML;
impl WholeStreamCommand for FromYAML { impl WholeStreamCommand for FromYAML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_yaml(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"from-yaml" "from-yaml"
} }
@ -20,11 +12,11 @@ impl WholeStreamCommand for FromYAML {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-yaml") Signature::build("from-yaml")
} }
}
pub struct FromYML; fn usage(&self) -> &str {
"Parse text as .yaml/.yml and create table."
}
impl WholeStreamCommand for FromYML {
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -32,7 +24,11 @@ impl WholeStreamCommand for FromYML {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
from_yaml(args, registry) from_yaml(args, registry)
} }
}
pub struct FromYML;
impl WholeStreamCommand for FromYML {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-yml" "from-yml"
} }
@ -40,6 +36,18 @@ impl WholeStreamCommand for FromYML {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-yml") Signature::build("from-yml")
} }
fn usage(&self) -> &str {
"Parse text as .yaml/.yml and create table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_yaml(args, registry)
}
} }
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into<Tag>) -> Tagged<Value> { fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into<Tag>) -> Tagged<Value> {

View File

@ -15,6 +15,14 @@ impl WholeStreamCommand for Get {
"get" "get"
} }
fn signature(&self) -> Signature {
Signature::build("get").rest(SyntaxType::Member)
}
fn usage(&self) -> &str {
"Open given cells as text."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -22,10 +30,6 @@ impl WholeStreamCommand for Get {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
args.process(registry, get)?.run() args.process(registry, get)?.run()
} }
fn signature(&self) -> Signature {
Signature::build("get").rest(SyntaxType::Member)
}
} }
fn get_member(path: &Tagged<String>, obj: &Tagged<Value>) -> Result<Tagged<Value>, ShellError> { fn get_member(path: &Tagged<String>, obj: &Tagged<Value>) -> Result<Tagged<Value>, ShellError> {

55
src/commands/help.rs Normal file
View File

@ -0,0 +1,55 @@
use crate::commands::command::CommandAction;
use crate::commands::PerItemCommand;
use crate::errors::ShellError;
use crate::parser::registry;
use crate::prelude::*;
pub struct Help;
impl PerItemCommand for Help {
fn name(&self) -> &str {
"help"
}
fn signature(&self) -> registry::Signature {
Signature::build("help").rest(SyntaxType::Any)
}
fn usage(&self) -> &str {
"Display help information about commands."
}
fn run(
&self,
call_info: &CallInfo,
_registry: &CommandRegistry,
_raw_args: &RawCommandArgs,
_input: Tagged<Value>,
) -> Result<OutputStream, ShellError> {
let span = call_info.name_span;
if call_info.args.len() == 0 {
return Ok(
vec![
Ok(ReturnSuccess::Action(
CommandAction::EnterHelpShell(
Tagged::from_simple_spanned_item(Value::nothing(), span)
)))].into()
)
}
match call_info.args.expect_nth(0)? {
Tagged {
item: Value::Primitive(Primitive::String(document)),
..
} => Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
Tagged::from_simple_spanned_item(Value::string(document), span)
)))]
.into()),
x => Ok(
vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(x.clone())))]
.into(),
),
}
}
}

View File

@ -6,6 +6,19 @@ use crate::prelude::*;
pub struct Last; pub struct Last;
impl WholeStreamCommand for Last { impl WholeStreamCommand for Last {
fn name(&self) -> &str {
"last"
}
fn signature(&self) -> Signature {
Signature::build("last")
.required("amount", SyntaxType::Number)
}
fn usage(&self) -> &str {
"Show only the last number of rows."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -13,14 +26,6 @@ impl WholeStreamCommand for Last {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
last(args, registry) last(args, registry)
} }
fn name(&self) -> &str {
"last"
}
fn signature(&self) -> Signature {
Signature::build("last").required("amount", SyntaxType::Literal)
}
} }
fn last(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn last(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -7,14 +7,6 @@ use log::trace;
pub struct Lines; pub struct Lines;
impl WholeStreamCommand for Lines { impl WholeStreamCommand for Lines {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
lines(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"lines" "lines"
} }
@ -22,6 +14,18 @@ impl WholeStreamCommand for Lines {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("lines") Signature::build("lines")
} }
fn usage(&self) -> &str {
"Split single string into rows, one per line."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
lines(args, registry)
}
} }
// TODO: "Amount remaining" wrapper // TODO: "Amount remaining" wrapper

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct LS; pub struct LS;
impl WholeStreamCommand for LS { impl WholeStreamCommand for LS {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
ls(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"ls" "ls"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for LS {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("ls").optional("path", SyntaxType::Path) Signature::build("ls").optional("path", SyntaxType::Path)
} }
fn usage(&self) -> &str {
"View the contents of the current or given path."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
ls(args, registry)
}
} }
fn ls(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn ls(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -12,6 +12,18 @@ pub struct MkdirArgs {
} }
impl PerItemCommand for Mkdir { impl PerItemCommand for Mkdir {
fn name(&self) -> &str {
"mkdir"
}
fn signature(&self) -> Signature {
Signature::build("mkdir").rest(SyntaxType::Path)
}
fn usage(&self) -> &str {
"Make directories, creates intermediary directories as required."
}
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,
@ -21,14 +33,6 @@ impl PerItemCommand for Mkdir {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
call_info.process(&raw_args.shell_manager, mkdir)?.run() call_info.process(&raw_args.shell_manager, mkdir)?.run()
} }
fn name(&self) -> &str {
"mkdir"
}
fn signature(&self) -> Signature {
Signature::build("mkdir").rest(SyntaxType::Path)
}
} }
fn mkdir(args: MkdirArgs, context: &RunnablePerItemContext) -> Result<OutputStream, ShellError> { fn mkdir(args: MkdirArgs, context: &RunnablePerItemContext) -> Result<OutputStream, ShellError> {

View File

@ -25,6 +25,10 @@ impl PerItemCommand for Move {
.named("file", SyntaxType::Any) .named("file", SyntaxType::Any)
} }
fn usage(&self) -> &str {
"Move files or directories."
}
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct Next; pub struct Next;
impl WholeStreamCommand for Next { impl WholeStreamCommand for Next {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
next(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"n" "n"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for Next {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("n") Signature::build("n")
} }
fn usage(&self) -> &str {
"Go to next shell."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
next(args, registry)
}
} }
fn next(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn next(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -11,14 +11,6 @@ struct NthArgs {
pub struct Nth; pub struct Nth;
impl WholeStreamCommand for Nth { impl WholeStreamCommand for Nth {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, nth)?.run()
}
fn name(&self) -> &str { fn name(&self) -> &str {
"nth" "nth"
} }
@ -26,6 +18,18 @@ impl WholeStreamCommand for Nth {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("nth").required("amount", SyntaxType::Any) Signature::build("nth").required("amount", SyntaxType::Any)
} }
fn usage(&self) -> &str {
"Return only the selected row"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, nth)?.run()
}
} }
fn nth( fn nth(

View File

@ -23,6 +23,10 @@ impl PerItemCommand for Open {
.switch("raw") .switch("raw")
} }
fn usage(&self) -> &str {
"Load a file into a cell, convert to table if possible (avoid by appending '--raw')"
}
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,

View File

@ -20,6 +20,10 @@ impl WholeStreamCommand for Pick {
Signature::build("pick").rest(SyntaxType::Any) Signature::build("pick").rest(SyntaxType::Any)
} }
fn usage(&self) -> &str {
"Down-select table to only these columns."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -51,6 +51,10 @@ impl WholeStreamCommand for PluginCommand {
self.config.clone() self.config.clone()
} }
fn usage(&self) -> &str {
&self.config.usage
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -270,6 +274,10 @@ impl WholeStreamCommand for PluginSink {
self.config.clone() self.config.clone()
} }
fn usage(&self) -> &str {
&self.config.usage
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -27,6 +27,10 @@ impl PerItemCommand for Post {
.switch("raw") .switch("raw")
} }
fn usage(&self) -> &str {
"Post content to a url and retrieve data as a table if possible."
}
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,

View File

@ -7,14 +7,6 @@ use crate::commands::WholeStreamCommand;
pub struct Previous; pub struct Previous;
impl WholeStreamCommand for Previous { impl WholeStreamCommand for Previous {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
previous(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"p" "p"
} }
@ -22,6 +14,18 @@ impl WholeStreamCommand for Previous {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("p") Signature::build("p")
} }
fn usage(&self) -> &str {
"Go to previous shell."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
previous(args, registry)
}
} }
fn previous(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn previous(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -12,14 +12,6 @@ use heim::units::{ratio, Ratio};
pub struct PS; pub struct PS;
impl WholeStreamCommand for PS { impl WholeStreamCommand for PS {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
ps(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"ps" "ps"
} }
@ -27,6 +19,18 @@ impl WholeStreamCommand for PS {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("ps") Signature::build("ps")
} }
fn usage(&self) -> &str {
"View current processes."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
ps(args, registry)
}
} }
async fn usage(process: Process) -> ProcessResult<(process::Process, Ratio)> { async fn usage(process: Process) -> ProcessResult<(process::Process, Ratio)> {

View File

@ -11,14 +11,6 @@ pub struct RejectArgs {
pub struct Reject; pub struct Reject;
impl WholeStreamCommand for Reject { impl WholeStreamCommand for Reject {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, reject)?.run()
}
fn name(&self) -> &str { fn name(&self) -> &str {
"reject" "reject"
} }
@ -26,6 +18,18 @@ impl WholeStreamCommand for Reject {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("reject").rest(SyntaxType::Member) Signature::build("reject").rest(SyntaxType::Member)
} }
fn usage(&self) -> &str {
"Remove the given columns from the table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, reject)?.run()
}
} }
fn reject( fn reject(

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct Reverse; pub struct Reverse;
impl WholeStreamCommand for Reverse { impl WholeStreamCommand for Reverse {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
reverse(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"reverse" "reverse"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for Reverse {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("reverse") Signature::build("reverse")
} }
fn usage(&self) -> &str {
"Reverses the table."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
reverse(args, registry)
}
} }
fn reverse(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn reverse(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -24,6 +24,10 @@ impl PerItemCommand for Remove {
.switch("recursive") .switch("recursive")
} }
fn usage(&self) -> &str {
"Remove a file, (for removing directory append '--recursive')"
}
fn run( fn run(
&self, &self,
call_info: &CallInfo, call_info: &CallInfo,

View File

@ -23,6 +23,10 @@ impl WholeStreamCommand for Save {
.switch("raw") .switch("raw")
} }
fn usage(&self) -> &str {
"Save the contents of the pipeline to a file."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct Shells; pub struct Shells;
impl WholeStreamCommand for Shells { impl WholeStreamCommand for Shells {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
shells(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"shells" "shells"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for Shells {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("shells") Signature::build("shells")
} }
fn usage(&self) -> &str {
"Display the list of current shells."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
shells(args, registry)
}
} }
fn shells(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn shells(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct Size; pub struct Size;
impl WholeStreamCommand for Size { impl WholeStreamCommand for Size {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
size(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"size" "size"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for Size {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("size") Signature::build("size")
} }
fn usage(&self) -> &str {
"Gather word count statistics on the text."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
size(args, registry)
}
} }
fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -20,6 +20,10 @@ impl WholeStreamCommand for SkipWhile {
.filter() .filter()
} }
fn usage(&self) -> &str {
"Skips rows while the condition matches."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,

View File

@ -10,14 +10,6 @@ pub struct SortByArgs {
} }
impl WholeStreamCommand for SortBy { impl WholeStreamCommand for SortBy {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, sort_by)?.run()
}
fn name(&self) -> &str { fn name(&self) -> &str {
"sort-by" "sort-by"
} }
@ -25,6 +17,18 @@ impl WholeStreamCommand for SortBy {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("sort-by").rest(SyntaxType::String) Signature::build("sort-by").rest(SyntaxType::String)
} }
fn usage(&self) -> &str {
"Sort by the given columns."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, sort_by)?.run()
}
} }
fn sort_by( fn sort_by(

View File

@ -15,14 +15,6 @@ struct SplitColumnArgs {
pub struct SplitColumn; pub struct SplitColumn;
impl WholeStreamCommand for SplitColumn { impl WholeStreamCommand for SplitColumn {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, split_column)?.run()
}
fn name(&self) -> &str { fn name(&self) -> &str {
"split-column" "split-column"
} }
@ -33,6 +25,18 @@ impl WholeStreamCommand for SplitColumn {
.switch("collapse-empty") .switch("collapse-empty")
.rest(SyntaxType::Member) .rest(SyntaxType::Member)
} }
fn usage(&self) -> &str {
"Split row contents across multiple columns via the separator."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, split_column)?.run()
}
} }
fn split_column( fn split_column(

View File

@ -12,6 +12,19 @@ struct SplitRowArgs {
pub struct SplitRow; pub struct SplitRow;
impl WholeStreamCommand for SplitRow { impl WholeStreamCommand for SplitRow {
fn name(&self) -> &str {
"split-row"
}
fn signature(&self) -> Signature {
Signature::build("split-row")
.required("separator", SyntaxType::Any)
}
fn usage(&self) -> &str {
"Split row contents over multiple rows via the separator."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -19,14 +32,6 @@ impl WholeStreamCommand for SplitRow {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
args.process(registry, split_row)?.run() args.process(registry, split_row)?.run()
} }
fn name(&self) -> &str {
"split-row"
}
fn signature(&self) -> Signature {
Signature::build("split-row").required("separator", SyntaxType::Any)
}
} }
fn split_row( fn split_row(

View File

@ -13,6 +13,15 @@ impl WholeStreamCommand for Table {
fn name(&self) -> &str { fn name(&self) -> &str {
"table" "table"
} }
fn signature(&self) -> Signature {
Signature::build("table")
}
fn usage(&self) -> &str {
"View the contents of the pipeline as a table."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -20,9 +29,6 @@ impl WholeStreamCommand for Table {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
args.process(registry, table)?.run() args.process(registry, table)?.run()
} }
fn signature(&self) -> Signature {
Signature::build("table")
}
} }
pub fn table(_args: TableArgs, context: RunnableContext) -> Result<OutputStream, ShellError> { pub fn table(_args: TableArgs, context: RunnableContext) -> Result<OutputStream, ShellError> {

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct Tags; pub struct Tags;
impl WholeStreamCommand for Tags { impl WholeStreamCommand for Tags {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
tags(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"tags" "tags"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for Tags {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("tags") Signature::build("tags")
} }
fn usage(&self) -> &str {
"Read the tags (metadata) for values."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
tags(args, registry)
}
} }
fn tags(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn tags(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct ToArray; pub struct ToArray;
impl WholeStreamCommand for ToArray { impl WholeStreamCommand for ToArray {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_array(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"to-array" "to-array"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for ToArray {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-array") Signature::build("to-array")
} }
fn usage(&self) -> &str {
"Collapse rows into a single list."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_array(args, registry)
}
} }
fn to_array(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn to_array(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -7,14 +7,6 @@ use std::convert::TryInto;
pub struct ToBSON; pub struct ToBSON;
impl WholeStreamCommand for ToBSON { impl WholeStreamCommand for ToBSON {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_bson(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"to-bson" "to-bson"
} }
@ -22,6 +14,18 @@ impl WholeStreamCommand for ToBSON {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-bson") Signature::build("to-bson")
} }
fn usage(&self) -> &str {
"Convert table into .bson text."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_bson(args, registry)
}
} }
pub fn value_to_bson_value(v: &Value) -> Bson { pub fn value_to_bson_value(v: &Value) -> Bson {

View File

@ -16,7 +16,12 @@ impl WholeStreamCommand for ToCSV {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-csv").switch("headerless") Signature::build("to-csv")
.switch("headerless")
}
fn usage(&self) -> &str {
"Convert table into .csv text "
} }
fn run( fn run(

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct ToJSON; pub struct ToJSON;
impl WholeStreamCommand for ToJSON { impl WholeStreamCommand for ToJSON {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_json(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"to-json" "to-json"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for ToJSON {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-json") Signature::build("to-json")
} }
fn usage(&self) -> &str {
"Convert table into .json text"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_json(args, registry)
}
} }
pub fn value_to_json_value(v: &Value) -> serde_json::Value { pub fn value_to_json_value(v: &Value) -> serde_json::Value {

View File

@ -8,14 +8,6 @@ use std::io::Read;
pub struct ToSQLite; pub struct ToSQLite;
impl WholeStreamCommand for ToSQLite { impl WholeStreamCommand for ToSQLite {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_sqlite(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"to-sqlite" "to-sqlite"
} }
@ -23,11 +15,11 @@ impl WholeStreamCommand for ToSQLite {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-sqlite") Signature::build("to-sqlite")
} }
}
pub struct ToDB; fn usage(&self) -> &str {
"Convert table to sqlite .db binary data"
}
impl WholeStreamCommand for ToDB {
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -35,7 +27,11 @@ impl WholeStreamCommand for ToDB {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
to_sqlite(args, registry) to_sqlite(args, registry)
} }
}
pub struct ToDB;
impl WholeStreamCommand for ToDB {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-db" "to-db"
} }
@ -43,6 +39,18 @@ impl WholeStreamCommand for ToDB {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-db") Signature::build("to-db")
} }
fn usage(&self) -> &str {
"Convert table to db data"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_sqlite(args, registry)
}
} }
fn comma_concat(acc: String, current: String) -> String { fn comma_concat(acc: String, current: String) -> String {

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct ToTOML; pub struct ToTOML;
impl WholeStreamCommand for ToTOML { impl WholeStreamCommand for ToTOML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_toml(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"to-toml" "to-toml"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for ToTOML {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-toml") Signature::build("to-toml")
} }
fn usage(&self) -> &str {
"Convert table into .toml text"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_toml(args, registry)
}
} }
pub fn value_to_toml_value(v: &Value) -> Result<toml::Value, ShellError> { pub fn value_to_toml_value(v: &Value) -> Result<toml::Value, ShellError> {

View File

@ -16,7 +16,12 @@ impl WholeStreamCommand for ToTSV {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-tsv").switch("headerless") Signature::build("to-tsv")
.switch("headerless")
}
fn usage(&self) -> &str {
"Convert table into .tsv text"
} }
fn run( fn run(

View File

@ -5,14 +5,6 @@ use crate::prelude::*;
pub struct ToYAML; pub struct ToYAML;
impl WholeStreamCommand for ToYAML { impl WholeStreamCommand for ToYAML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_yaml(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"to-yaml" "to-yaml"
} }
@ -20,6 +12,18 @@ impl WholeStreamCommand for ToYAML {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-yaml") Signature::build("to-yaml")
} }
fn usage(&self) -> &str {
"Convert table into .yaml/.yml text"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_yaml(args, registry)
}
} }
pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value { pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {

View File

@ -6,14 +6,6 @@ use crate::prelude::*;
pub struct Trim; pub struct Trim;
impl WholeStreamCommand for Trim { impl WholeStreamCommand for Trim {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
trim(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"trim" "trim"
} }
@ -21,6 +13,18 @@ impl WholeStreamCommand for Trim {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("trim") Signature::build("trim")
} }
fn usage(&self) -> &str {
"Trim leading and following whitespace from text data."
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
trim(args, registry)
}
} }
fn trim(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn trim(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -8,14 +8,6 @@ use indexmap::IndexMap;
pub struct Version; pub struct Version;
impl WholeStreamCommand for Version { impl WholeStreamCommand for Version {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
date(args, registry)
}
fn name(&self) -> &str { fn name(&self) -> &str {
"version" "version"
} }
@ -23,6 +15,18 @@ impl WholeStreamCommand for Version {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("version") Signature::build("version")
} }
fn usage(&self) -> &str {
"Display Nu version"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
date(args, registry)
}
} }
pub fn date(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn date(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -12,6 +12,15 @@ impl WholeStreamCommand for VTable {
fn name(&self) -> &str { fn name(&self) -> &str {
"vtable" "vtable"
} }
fn signature(&self) -> Signature {
Signature::build("vtable")
}
fn usage(&self) -> &str {
"View the contents of the pipeline as a vertical (rotated) table."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -19,9 +28,6 @@ impl WholeStreamCommand for VTable {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
args.process(registry, vtable)?.run() args.process(registry, vtable)?.run()
} }
fn signature(&self) -> Signature {
Signature::build("vtable")
}
} }
pub fn vtable(_args: VTableArgs, context: RunnableContext) -> Result<OutputStream, ShellError> { pub fn vtable(_args: VTableArgs, context: RunnableContext) -> Result<OutputStream, ShellError> {

View File

@ -12,7 +12,12 @@ impl PerItemCommand for Where {
} }
fn signature(&self) -> registry::Signature { fn signature(&self) -> registry::Signature {
Signature::build("where").required("condition", SyntaxType::Block) Signature::build("where")
.required("condition", SyntaxType::Block)
}
fn usage(&self) -> &str {
"Filter table to match the condition."
} }
fn run( fn run(

View File

@ -8,6 +8,19 @@ use crate::parser::registry::Signature;
pub struct Which; pub struct Which;
impl WholeStreamCommand for Which { impl WholeStreamCommand for Which {
fn name(&self) -> &str {
"which"
}
fn signature(&self) -> Signature {
Signature::build("which")
.required("name", SyntaxType::Any)
}
fn usage(&self) -> &str {
"Finds a program file."
}
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -15,13 +28,6 @@ impl WholeStreamCommand for Which {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
which(args, registry) which(args, registry)
} }
fn name(&self) -> &str {
"which"
}
fn signature(&self) -> Signature {
Signature::build("which").required("name", SyntaxType::Any)
}
} }
pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {

View File

@ -53,7 +53,7 @@ impl CommandRegistry {
registry.get(name).map(|c| c.clone()) registry.get(name).map(|c| c.clone())
} }
fn has(&self, name: &str) -> bool { pub(crate) fn has(&self, name: &str) -> bool {
let registry = self.registry.lock().unwrap(); let registry = self.registry.lock().unwrap();
registry.contains_key(name) registry.contains_key(name)

View File

@ -1,4 +1,5 @@
pub(crate) mod base; pub(crate) mod base;
pub(crate) mod command;
pub(crate) mod config; pub(crate) mod config;
pub(crate) mod dict; pub(crate) mod dict;
pub(crate) mod files; pub(crate) mod files;
@ -8,5 +9,6 @@ pub(crate) mod types;
#[allow(unused)] #[allow(unused)]
pub(crate) use base::{Block, Primitive, Switch, Value}; pub(crate) use base::{Block, Primitive, Switch, Value};
pub(crate) use dict::{Dictionary, TaggedDictBuilder}; pub(crate) use dict::{Dictionary, TaggedListBuilder, TaggedDictBuilder};
pub(crate) use files::dir_entry_dict; pub(crate) use files::dir_entry_dict;
pub(crate) use command::command_dict;

67
src/object/command.rs Normal file
View File

@ -0,0 +1,67 @@
use crate::commands::command::Command;
use crate::object::{TaggedDictBuilder, TaggedListBuilder, Value};
use crate::parser::registry::{NamedType, PositionalType, Signature};
use crate::prelude::*;
use std::ops::Deref;
pub(crate) fn command_dict(command: Arc<Command>, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into();
let mut cmd_dict = TaggedDictBuilder::new(tag);
cmd_dict.insert("name", Value::string(command.name()));
cmd_dict.insert(
"type",
Value::string(match command.deref() {
Command::WholeStream(_) => "Command",
Command::PerItem(_) => "Filter",
}),
);
cmd_dict.insert_tagged("signature", signature_dict(command.signature(), tag));
cmd_dict.insert("usage", Value::string(command.usage()));
cmd_dict.into_tagged_value()
}
fn for_spec(name: &str, ty: &str, required: bool, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into();
let mut spec = TaggedDictBuilder::new(tag);
spec.insert("name", Value::string(name));
spec.insert("type", Value::string(ty));
spec.insert("required", Value::string(if required { "yes" } else { "no" }));
spec.into_tagged_value()
}
fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into();
let mut sig = TaggedListBuilder::new(tag);
for arg in signature.positional.iter() {
let is_required = match arg {
PositionalType::Mandatory(_,_) => true,
PositionalType::Optional(_,_) => false,
};
sig.insert_tagged(for_spec(arg.name(), "argument", is_required, tag));
}
if let Some(_) = signature.rest_positional {
let is_required = false;
sig.insert_tagged(for_spec("rest", "argument", is_required, tag));
}
for (name, ty) in signature.named.iter() {
match ty {
NamedType::Mandatory(_) => sig.insert_tagged(for_spec(name, "flag", true, tag)),
NamedType::Optional(_) => sig.insert_tagged(for_spec(name, "flag", false, tag)),
NamedType::Switch => sig.insert_tagged(for_spec(name, "switch", false, tag)),
}
}
sig.into_tagged_value()
}

View File

@ -1,5 +1,4 @@
use crate::prelude::*; use crate::prelude::*;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use derive_new::new; use derive_new::new;
use indexmap::IndexMap; use indexmap::IndexMap;

View File

@ -49,6 +49,24 @@ pub enum SyntaxType {
Boolean, Boolean,
} }
impl std::fmt::Display for SyntaxType {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
SyntaxType::Any => write!(f, "Any"),
SyntaxType::List => write!(f, "List"),
SyntaxType::Literal => write!(f, "Literal"),
SyntaxType::String => write!(f, "String"),
SyntaxType::Member => write!(f, "Member"),
SyntaxType::Variable => write!(f, "Variable"),
SyntaxType::Number => write!(f, "Number"),
SyntaxType::Path => write!(f, "Path"),
SyntaxType::Binary => write!(f, "Binary"),
SyntaxType::Block => write!(f, "Block"),
SyntaxType::Boolean => write!(f, "Boolean")
}
}
}
pub fn baseline_parse_next_expr( pub fn baseline_parse_next_expr(
tokens: &mut TokensIterator, tokens: &mut TokensIterator,
context: &Context, context: &Context,

View File

@ -73,6 +73,8 @@ impl PositionalType {
pub struct Signature { pub struct Signature {
pub name: String, pub name: String,
#[new(default)] #[new(default)]
pub usage: String,
#[new(default)]
pub positional: Vec<PositionalType>, pub positional: Vec<PositionalType>,
#[new(value = "None")] #[new(value = "None")]
pub rest_positional: Option<SyntaxType>, pub rest_positional: Option<SyntaxType>,
@ -87,6 +89,11 @@ impl Signature {
Signature::new(name.into()) Signature::new(name.into())
} }
pub fn desc(mut self, usage: impl Into<String>) -> Signature {
self.usage = usage.into();
self
}
pub fn required(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> Signature { pub fn required(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> Signature {
self.positional self.positional
.push(PositionalType::Mandatory(name.into(), ty.into())); .push(PositionalType::Mandatory(name.into(), ty.into()));

View File

@ -43,6 +43,7 @@ impl Add {
impl Plugin for Add { impl Plugin for Add {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("add") Ok(Signature::build("add")
.desc("Add a new field to the table.")
.required("Field", SyntaxType::String) .required("Field", SyntaxType::String)
.required("Value", SyntaxType::String) .required("Value", SyntaxType::String)
.rest(SyntaxType::String).filter()) .rest(SyntaxType::String).filter())

View File

@ -12,7 +12,9 @@ impl BinaryView {
impl Plugin for BinaryView { impl Plugin for BinaryView {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("binaryview").switch("lores")) Ok(Signature::build("binaryview")
.desc("Autoview of binary data.")
.switch("lores"))
} }
fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) { fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {

View File

@ -42,6 +42,7 @@ impl Edit {
impl Plugin for Edit { impl Plugin for Edit {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("edit") Ok(Signature::build("edit")
.desc("Edit an existing field to have a new value.")
.required("Field", SyntaxType::String) .required("Field", SyntaxType::String)
.required("Value", SyntaxType::String) .required("Value", SyntaxType::String)
.filter()) .filter())

View File

@ -70,7 +70,7 @@ impl Inc {
self.error = Some(message.to_string()); self.error = Some(message.to_string());
} }
fn usage(&self) -> &'static str { pub fn usage() -> &'static str {
"Usage: inc field [--major|--minor|--patch]" "Usage: inc field [--major|--minor|--patch]"
} }
@ -116,6 +116,7 @@ impl Inc {
impl Plugin for Inc { impl Plugin for Inc {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("inc") Ok(Signature::build("inc")
.desc("Increment a value or version. Optional use the field of a table.")
.switch("major") .switch("major")
.switch("minor") .switch("minor")
.switch("patch") .switch("patch")
@ -159,7 +160,7 @@ impl Plugin for Inc {
match &self.error { match &self.error {
Some(reason) => { Some(reason) => {
return Err(ShellError::string(format!("{}: {}", reason, self.usage()))) return Err(ShellError::string(format!("{}: {}", reason, Inc::usage())))
} }
None => Ok(vec![]), None => Ok(vec![]),
} }

View File

@ -1,4 +1,3 @@
use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SyntaxType, Tagged, Value, SyntaxType, Tagged, Value,
@ -15,13 +14,10 @@ impl Skip {
impl Plugin for Skip { impl Plugin for Skip {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature { Ok(Signature::build("skip")
name: "skip".to_string(), .desc("Skip a number of rows")
positional: vec![], .rest(SyntaxType::Number)
is_filter: true, .filter())
named: IndexMap::new(),
rest_positional: Some(SyntaxType::Number),
})
} }
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional { if let Some(args) = call_info.args.positional {

View File

@ -124,7 +124,7 @@ impl Str {
} }
} }
fn usage(&self) -> &'static str { pub fn usage() -> &'static str {
"Usage: str field [--downcase|--upcase|--to-int|--replace|--find-replace]" "Usage: str field [--downcase|--upcase|--to-int|--replace|--find-replace]"
} }
} }
@ -154,7 +154,7 @@ impl Str {
None => Err(ShellError::string(format!( None => Err(ShellError::string(format!(
"{}: {}", "{}: {}",
"str needs a field when applying it to a value in an object", "str needs a field when applying it to a value in an object",
self.usage() Str::usage()
))), ))),
}, },
x => Err(ShellError::string(format!( x => Err(ShellError::string(format!(
@ -168,6 +168,7 @@ impl Str {
impl Plugin for Str { impl Plugin for Str {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("str") Ok(Signature::build("str")
.desc("Apply string function. Optional use the field of a table")
.switch("downcase") .switch("downcase")
.switch("upcase") .switch("upcase")
.switch("to-int") .switch("to-int")
@ -240,7 +241,7 @@ impl Plugin for Str {
match &self.error { match &self.error {
Some(reason) => { Some(reason) => {
return Err(ShellError::string(format!("{}: {}", reason, self.usage()))) return Err(ShellError::string(format!("{}: {}", reason, Str::usage())))
} }
None => Ok(vec![]), None => Ok(vec![]),
} }

View File

@ -64,7 +64,9 @@ impl Sum {
impl Plugin for Sum { impl Plugin for Sum {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("sum").filter()) Ok(Signature::build("sum")
.desc("Sum a column of values.")
.filter())
} }
fn begin_filter(&mut self, _: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, _: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {

View File

@ -309,7 +309,9 @@ async fn sysinfo(tag: Tag) -> Vec<Tagged<Value>> {
impl Plugin for Sys { impl Plugin for Sys {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("sys").filter()) Ok(Signature::build("sys")
.desc("View information about the current system.")
.filter())
} }
fn begin_filter(&mut self, callinfo: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, callinfo: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {

View File

@ -26,7 +26,8 @@ impl TextView {
impl Plugin for TextView { impl Plugin for TextView {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("textview")) Ok(Signature::build("textview")
.desc("Autoview of text data."))
} }
fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) { fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {

View File

@ -80,7 +80,8 @@ struct TreeViewer;
impl Plugin for TreeViewer { impl Plugin for TreeViewer {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("tree")) Ok(Signature::build("tree")
.desc("View the contents of the pipeline as a tree."))
} }
fn sink(&mut self, _call_info: CallInfo, input: Vec<Tagged<Value>>) { fn sink(&mut self, _call_info: CallInfo, input: Vec<Tagged<Value>>) {

View File

@ -68,6 +68,7 @@ pub(crate) use crate::parser::registry::Signature;
pub(crate) use crate::shell::filesystem_shell::FilesystemShell; pub(crate) use crate::shell::filesystem_shell::FilesystemShell;
pub(crate) use crate::shell::shell_manager::ShellManager; pub(crate) use crate::shell::shell_manager::ShellManager;
pub(crate) use crate::shell::value_shell::ValueShell; pub(crate) use crate::shell::value_shell::ValueShell;
pub(crate) use crate::shell::help_shell::HelpShell;
pub(crate) use crate::stream::{InputStream, OutputStream}; pub(crate) use crate::stream::{InputStream, OutputStream};
pub(crate) use crate::traits::{HasSpan, ToDebug}; pub(crate) use crate::traits::{HasSpan, ToDebug};
pub(crate) use crate::Span; pub(crate) use crate::Span;

View File

@ -4,5 +4,6 @@ pub(crate) mod helper;
pub(crate) mod shell; pub(crate) mod shell;
pub(crate) mod shell_manager; pub(crate) mod shell_manager;
pub(crate) mod value_shell; pub(crate) mod value_shell;
pub(crate) mod help_shell;
pub(crate) use helper::Helper; pub(crate) use helper::Helper;

234
src/shell/help_shell.rs Normal file
View File

@ -0,0 +1,234 @@
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
use crate::commands::cp::CopyArgs;
use crate::commands::mkdir::MkdirArgs;
use crate::commands::mv::MoveArgs;
use crate::commands::rm::RemoveArgs;
use crate::context::SourceMap;
use crate::object::{TaggedDictBuilder, command_dict};
use crate::prelude::*;
use crate::shell::shell::Shell;
use std::ffi::OsStr;
use std::path::PathBuf;
#[derive(Clone, Debug)]
pub struct HelpShell {
pub(crate) path: String,
pub(crate) value: Tagged<Value>,
}
impl HelpShell {
pub fn index(registry: &CommandRegistry) -> Result<HelpShell, std::io::Error> {
let mut cmds = TaggedDictBuilder::new(Tag::unknown());
let mut specs = Vec::new();
for cmd in registry.names() {
let mut spec = TaggedDictBuilder::new(Tag::unknown());
let value = command_dict(registry.get_command(&cmd).unwrap(), Tag::unknown());
spec.insert("name", cmd);
spec.insert("description", value.get_data_by_key("usage").unwrap().as_string().unwrap());
spec.insert_tagged("details", value);
specs.push(spec.into_tagged_value());
}
cmds.insert("help", Value::List(specs));
Ok(HelpShell {
path: "/help".to_string(),
value: cmds.into_tagged_value(),
})
}
pub fn for_command(
cmd: Tagged<Value>,
registry: &CommandRegistry,
) -> Result<HelpShell, std::io::Error> {
let mut sh = HelpShell::index(&registry)?;
if let Tagged {
item: Value::Primitive(Primitive::String(name)), ..
} = cmd {
sh.set_path(format!("/help/{:}/details", name));
}
Ok(sh)
}
fn commands(&self) -> VecDeque<Tagged<Value>> {
let mut cmds = VecDeque::new();
let full_path = PathBuf::from(&self.path);
let mut viewed = self.value.clone();
let sep_string = std::path::MAIN_SEPARATOR.to_string();
let sep = OsStr::new(&sep_string);
for p in full_path.iter() {
match p {
x if x == sep => {}
step => match viewed.get_data_by_key(step.to_str().unwrap()) {
Some(v) => {
viewed = v.clone();
}
_ => {}
},
}
}
match viewed {
Tagged {
item: Value::List(l),
..
} => {
for item in l {
cmds.push_back(item.clone());
}
}
x => {
cmds.push_back(x.clone());
}
}
cmds
}
}
impl Shell for HelpShell {
fn name(&self, source_map: &SourceMap) -> String {
let origin_name = self.value.origin_name(source_map);
format!(
"{}",
match origin_name {
Some(x) => format!("{{{}}}", x),
None => format!("<{}>", self.value.item.type_name(),),
}
)
}
fn homedir(&self) -> Option<PathBuf> {
dirs::home_dir()
}
fn path(&self) -> String {
self.path.clone()
}
fn set_path(&mut self, path: String) {
let _ = std::env::set_current_dir(&path);
self.path = path.clone();
}
fn ls(&self, _args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
Ok(self
.commands()
.map(|x| ReturnSuccess::value(x))
.to_output_stream())
}
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
let path = match args.nth(0) {
None => "/".to_string(),
Some(v) => {
let target = v.as_path()?;
let mut cwd = PathBuf::from(&self.path);
if target == PathBuf::from("..") {
cwd.pop();
} else {
match target.to_str() {
Some(target) => match target.chars().nth(0) {
Some(x) if x == '/' => cwd = PathBuf::from(target),
_ => cwd.push(target),
},
None => cwd.push(target),
}
}
cwd.to_string_lossy().to_string()
}
};
let mut stream = VecDeque::new();
stream.push_back(ReturnSuccess::change_cwd(path));
Ok(stream.into())
}
fn cp(&self, _args: CopyArgs, _name: Span, _path: &str) -> Result<OutputStream, ShellError> {
Ok(OutputStream::empty())
}
fn mv(&self, _args: MoveArgs, _name: Span, _path: &str) -> Result<OutputStream, ShellError> {
Ok(OutputStream::empty())
}
fn mkdir(
&self,
_args: MkdirArgs,
_name: Span,
_path: &str,
) -> Result<OutputStream, ShellError> {
Ok(OutputStream::empty())
}
fn rm(&self, _args: RemoveArgs, _name: Span, _path: &str) -> Result<OutputStream, ShellError> {
Ok(OutputStream::empty())
}
fn complete(
&self,
line: &str,
pos: usize,
_ctx: &rustyline::Context<'_>,
) -> Result<(usize, Vec<rustyline::completion::Pair>), rustyline::error::ReadlineError> {
let mut completions = vec![];
let mut possible_completion = vec![];
let commands = self.commands();
for cmd in commands {
match cmd {
Tagged { item, .. } => {
for desc in item.data_descriptors() {
possible_completion.push(desc);
}
}
}
}
let line_chars: Vec<_> = line.chars().collect();
let mut replace_pos = pos;
while replace_pos > 0 {
if line_chars[replace_pos - 1] == ' ' {
break;
}
replace_pos -= 1;
}
for command in possible_completion.iter() {
let mut pos = replace_pos;
let mut matched = true;
if pos < line_chars.len() {
for chr in command.chars() {
if line_chars[pos] != chr {
matched = false;
break;
}
pos += 1;
if pos == line_chars.len() {
break;
}
}
}
if matched {
completions.push(rustyline::completion::Pair {
display: command.to_string(),
replacement: command.to_string(),
});
}
}
Ok((replace_pos, completions))
}
fn hint(&self, _line: &str, _pos: usize, _ctx: &rustyline::Context<'_>) -> Option<String> {
None
}
}

View File

@ -12,6 +12,7 @@ use std::path::PathBuf;
pub trait Shell: std::fmt::Debug { pub trait Shell: std::fmt::Debug {
fn name(&self, source_map: &SourceMap) -> String; fn name(&self, source_map: &SourceMap) -> String;
fn homedir(&self) -> Option<PathBuf>; fn homedir(&self) -> Option<PathBuf>;
fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>; fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>;
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>; fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>;
fn cp(&self, args: CopyArgs, name: Span, path: &str) -> Result<OutputStream, ShellError>; fn cp(&self, args: CopyArgs, name: Span, path: &str) -> Result<OutputStream, ShellError>;

View File

@ -75,7 +75,7 @@ fn converts_structured_table_to_csv_text_skipping_headers_after_conversion() {
fn converts_from_csv_text_to_structured_table() { fn converts_from_csv_text_to_structured_table() {
Playground::setup("filter_from_csv_test_1", |dirs, sandbox| { Playground::setup("filter_from_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed( sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt", "los_tres_caballeros.txt",
r#" r#"
first_name,last_name,rusty_luck first_name,last_name,rusty_luck
Andrés,Robalino,1 Andrés,Robalino,1
@ -87,7 +87,7 @@ fn converts_from_csv_text_to_structured_table() {
let actual = nu!( let actual = nu!(
cwd: dirs.test(), h::pipeline( cwd: dirs.test(), h::pipeline(
r#" r#"
open los_tres_amigos.txt open los_tres_caballeros.txt
| from-csv | from-csv
| get rusty_luck | get rusty_luck
| str --to-int | str --to-int
@ -366,7 +366,8 @@ fn can_convert_table_to_bson_and_back_into_table() {
| get root | get root
| nth 1 | nth 1
| get b | get b
| echo $it"# | echo $it
"#
)); ));
assert_eq!(actual, "whel"); assert_eq!(actual, "whel");
@ -383,7 +384,8 @@ fn can_convert_table_to_sqlite_and_back_into_table() {
| get table_values | get table_values
| nth 2 | nth 2
| get x | get x
| echo $it"# | echo $it
"#
)); ));
assert_eq!(actual, "hello"); assert_eq!(actual, "hello");
@ -398,7 +400,8 @@ fn can_convert_table_to_toml_text_and_from_toml_text_back_into_table() {
| to-toml | to-toml
| from-toml | from-toml
| get package.name | get package.name
| echo $it"# | echo $it
"#
)); ));
assert_eq!(actual, "nu"); assert_eq!(actual, "nu");