Allow different names for ...rest (#3954)

* Allow different names for ...rest

* Resolves #3945

* This change requires an explicit name for the rest argument in `WholeStreamCommand`,
  which is why there are so many changed files.

* Remove redundant clone

* Add tests
This commit is contained in:
Hristo Filaretov 2021-08-26 19:58:53 +02:00 committed by GitHub
parent 88817a8f10
commit b8e2bdd6b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
97 changed files with 270 additions and 87 deletions

View file

@ -22,6 +22,7 @@ impl WholeStreamCommand for Histogram {
None, None,
) )
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"column name to give the histogram's frequency column", "column name to give the histogram's frequency column",
) )

View file

@ -13,6 +13,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("into binary").rest( Signature::build("into binary").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"column paths to convert to binary (for table input)", "column paths to convert to binary (for table input)",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("into path").rest( Signature::build("into path").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"column paths to convert to filepath (for table input)", "column paths to convert to filepath (for table input)",
) )

View file

@ -13,6 +13,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("into int").rest( Signature::build("into int").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"column paths to convert to int (for table input)", "column paths to convert to int (for table input)",
) )

View file

@ -20,6 +20,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("into string") Signature::build("into string")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"column paths to convert to string (for table input)", "column paths to convert to string (for table input)",
) )

View file

@ -15,7 +15,7 @@ impl WholeStreamCommand for Alias {
Signature::build("alias") Signature::build("alias")
.required("name", SyntaxShape::String, "the name of the alias") .required("name", SyntaxShape::String, "the name of the alias")
.required("equals", SyntaxShape::String, "the equals sign") .required("equals", SyntaxShape::String, "the equals sign")
.rest(SyntaxShape::Any, "the expansion for the alias") .rest("rest", SyntaxShape::Any, "the expansion for the alias")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -27,7 +27,7 @@ impl WholeStreamCommand for Do {
"ignore errors as the block runs", "ignore errors as the block runs",
Some('i'), Some('i'),
) )
.rest(SyntaxShape::Any, "the parameter(s) for the block") .rest("rest", SyntaxShape::Any, "the parameter(s) for the block")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -12,7 +12,7 @@ impl WholeStreamCommand for Echo {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("echo").rest(SyntaxShape::Any, "the values to echo") Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -18,7 +18,11 @@ impl WholeStreamCommand for Help {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("help") Signature::build("help")
.rest(SyntaxShape::String, "the name of command to get help on") .rest(
"rest",
SyntaxShape::String,
"the name of command to get help on",
)
.named( .named(
"find", "find",
SyntaxShape::String, SyntaxShape::String,

View file

@ -41,7 +41,7 @@ impl WholeStreamCommand for Command {
"custom configuration source file", "custom configuration source file",
None, None,
) )
.rest(SyntaxShape::String, "source file(s) to run") .rest("rest", SyntaxShape::String, "source file(s) to run")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -20,7 +20,11 @@ impl WholeStreamCommand for DataFrame {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("dataframe drop").rest(SyntaxShape::Any, "column names to be dropped") Signature::build("dataframe drop").rest(
"rest",
SyntaxShape::Any,
"column names to be dropped",
)
} }
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> { fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -19,7 +19,11 @@ impl WholeStreamCommand for DataFrame {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("dataframe get").rest(SyntaxShape::Any, "column names to sort dataframe") Signature::build("dataframe get").rest(
"rest",
SyntaxShape::Any,
"column names to sort dataframe",
)
} }
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> { fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -20,7 +20,7 @@ impl WholeStreamCommand for DataFrame {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("dataframe group-by").rest(SyntaxShape::Any, "groupby columns") Signature::build("dataframe group-by").rest("rest", SyntaxShape::Any, "groupby columns")
} }
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> { fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -20,7 +20,7 @@ impl WholeStreamCommand for DataFrame {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("dataframe select").rest(SyntaxShape::Any, "selected column names") Signature::build("dataframe select").rest("rest", SyntaxShape::Any, "selected column names")
} }
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> { fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -21,7 +21,7 @@ impl WholeStreamCommand for DataFrame {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("dataframe sort") Signature::build("dataframe sort")
.switch("reverse", "invert sort", Some('r')) .switch("reverse", "invert sort", Some('r'))
.rest(SyntaxShape::Any, "column names to sort dataframe") .rest("rest", SyntaxShape::Any, "column names to sort dataframe")
} }
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> { fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -12,6 +12,7 @@ impl WholeStreamCommand for Mkdir {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("mkdir") Signature::build("mkdir")
.rest( .rest(
"rest",
SyntaxShape::FilePath, SyntaxShape::FilePath,
"the name(s) of the path(s) to create", "the name(s) of the path(s) to create",
) )

View file

@ -26,7 +26,11 @@ impl WholeStreamCommand for Remove {
) )
.switch("recursive", "delete subdirectories recursively", Some('r')) .switch("recursive", "delete subdirectories recursively", Some('r'))
.switch("force", "suppress error when no file", Some('f')) .switch("force", "suppress error when no file", Some('f'))
.rest(SyntaxShape::GlobPattern, "the file path(s) to remove") .rest(
"rest",
SyntaxShape::GlobPattern,
"the file path(s) to remove",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -19,7 +19,7 @@ impl WholeStreamCommand for Touch {
SyntaxShape::FilePath, SyntaxShape::FilePath,
"the path of the file you want to create", "the path of the file you want to create",
) )
.rest(SyntaxShape::FilePath, "additional files to create") .rest("rest", SyntaxShape::FilePath, "additional files to create")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
"Creates one or more files." "Creates one or more files."

View file

@ -17,7 +17,11 @@ impl WholeStreamCommand for Compact {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("compact").rest(SyntaxShape::Any, "the columns to compact from the table") Signature::build("compact").rest(
"rest",
SyntaxShape::Any,
"the columns to compact from the table",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -18,7 +18,7 @@ impl WholeStreamCommand for SubCommand {
SyntaxShape::Int, SyntaxShape::Int,
"the number of the row to drop", "the number of the row to drop",
) )
.rest(SyntaxShape::Any, "Optionally drop more rows") .rest("rest", SyntaxShape::Any, "Optionally drop more rows")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("empty?") Signature::build("empty?")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"the names of the columns to check emptiness", "the names of the columns to check emptiness",
) )

View file

@ -14,7 +14,11 @@ impl WholeStreamCommand for Command {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("flatten").rest(SyntaxShape::String, "optionally flatten data by column") Signature::build("flatten").rest(
"rest",
SyntaxShape::String,
"optionally flatten data by column",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("get").rest( Signature::build("get").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally return additional data by path", "optionally return additional data by path",
) )

View file

@ -14,7 +14,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("move") Signature::build("move")
.rest(SyntaxShape::ColumnPath, "the columns to move") .rest("rest", SyntaxShape::ColumnPath, "the columns to move")
.named( .named(
"after", "after",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,

View file

@ -18,7 +18,7 @@ impl WholeStreamCommand for Nth {
SyntaxShape::Int, SyntaxShape::Int,
"the number of the row to return", "the number of the row to return",
) )
.rest(SyntaxShape::Any, "Optionally return more rows") .rest("rest", SyntaxShape::Any, "Optionally return more rows")
.switch("skip", "Skip the rows instead of selecting them", Some('s')) .switch("skip", "Skip the rows instead of selecting them", Some('s'))
} }

View file

@ -36,6 +36,7 @@ impl WholeStreamCommand for Pivot {
Some('i'), Some('i'),
) )
.rest( .rest(
"rest",
SyntaxShape::String, SyntaxShape::String,
"the names to give columns once pivoted", "the names to give columns once pivoted",
) )

View file

@ -13,7 +13,11 @@ impl WholeStreamCommand for Reject {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("reject").rest(SyntaxShape::String, "the names of columns to remove") Signature::build("reject").rest(
"rest",
SyntaxShape::String,
"the names of columns to remove",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -19,7 +19,11 @@ impl WholeStreamCommand for Rename {
SyntaxShape::String, SyntaxShape::String,
"the new name for the first column", "the new name for the first column",
) )
.rest(SyntaxShape::String, "the new name for additional columns") .rest(
"rest",
SyntaxShape::String,
"the new name for additional columns",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -17,6 +17,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("rotate").rest( Signature::build("rotate").rest(
"rest",
SyntaxShape::String, SyntaxShape::String,
"the names to give columns once rotated", "the names to give columns once rotated",
) )

View file

@ -17,6 +17,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("rotate counter-clockwise").rest( Signature::build("rotate counter-clockwise").rest(
"rest",
SyntaxShape::String, SyntaxShape::String,
"the names to give columns once rotated", "the names to give columns once rotated",
) )

View file

@ -16,6 +16,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("select").rest( Signature::build("select").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"the columns to select from the table", "the columns to select from the table",
) )

View file

@ -21,7 +21,7 @@ impl WholeStreamCommand for SortBy {
Some('i'), Some('i'),
) )
.switch("reverse", "Sort in reverse order", Some('r')) .switch("reverse", "Sort in reverse order", Some('r'))
.rest(SyntaxShape::String, "the column(s) to sort by") .rest("rest", SyntaxShape::String, "the column(s) to sort by")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -45,6 +45,7 @@ impl WholeStreamCommand for SubCommand {
"decode the input from base64", "decode the input from base64",
Some('d')) Some('d'))
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally base64 encode / decode data by column paths", "optionally base64 encode / decode data by column paths",
) )

View file

@ -12,6 +12,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("hash").rest( Signature::build("hash").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert by column paths", "optionally convert by column paths",
) )

View file

@ -38,6 +38,7 @@ where
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()).rest( Signature::build(self.name()).rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
format!("optionally {} encode data by column paths", D::name()), format!("optionally {} encode data by column paths", D::name()),
) )

View file

@ -15,7 +15,7 @@ impl WholeStreamCommand for Seq {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("seq") Signature::build("seq")
.rest(SyntaxShape::Number, "sequence values") .rest("rest", SyntaxShape::Number, "sequence values")
.named( .named(
"separator", "separator",
SyntaxShape::String, SyntaxShape::String,

View file

@ -14,8 +14,11 @@ impl WholeStreamCommand for UrlHost {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("url host") Signature::build("url host").rest(
.rest(SyntaxShape::ColumnPath, "optionally operate by column path") "rest",
SyntaxShape::ColumnPath,
"optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -14,8 +14,11 @@ impl WholeStreamCommand for UrlPath {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("url path") Signature::build("url path").rest(
.rest(SyntaxShape::ColumnPath, "optionally operate by column path") "rest",
SyntaxShape::ColumnPath,
"optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -14,8 +14,11 @@ impl WholeStreamCommand for UrlQuery {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("url query") Signature::build("url query").rest(
.rest(SyntaxShape::ColumnPath, "optionally operate by column path") "rest",
SyntaxShape::ColumnPath,
"optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -14,7 +14,11 @@ impl WholeStreamCommand for UrlScheme {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("url scheme").rest(SyntaxShape::ColumnPath, "optionally operate by path") Signature::build("url scheme").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally operate by path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -26,7 +26,11 @@ impl WholeStreamCommand for PathBasename {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path basename") Signature::build("path basename")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") .rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named( .named(
"replace", "replace",
SyntaxShape::String, SyntaxShape::String,

View file

@ -27,7 +27,11 @@ impl WholeStreamCommand for PathDirname {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path dirname") Signature::build("path dirname")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") .rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named( .named(
"replace", "replace",
SyntaxShape::String, SyntaxShape::String,

View file

@ -23,8 +23,11 @@ impl WholeStreamCommand for PathExists {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path exists") Signature::build("path exists").rest(
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") "rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -32,7 +32,11 @@ impl WholeStreamCommand for PathExpand {
"Throw an error if the path could not be expanded", "Throw an error if the path could not be expanded",
Some('s'), Some('s'),
) )
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") .rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -26,7 +26,11 @@ impl WholeStreamCommand for PathJoin {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path join") Signature::build("path join")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") .rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named( .named(
"append", "append",
SyntaxShape::FilePath, SyntaxShape::FilePath,

View file

@ -28,7 +28,11 @@ impl WholeStreamCommand for PathParse {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path parse") Signature::build("path parse")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") .rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named( .named(
"extension", "extension",
SyntaxShape::String, SyntaxShape::String,

View file

@ -31,7 +31,11 @@ impl WholeStreamCommand for PathRelativeTo {
SyntaxShape::FilePath, SyntaxShape::FilePath,
"Parent shared with the input path", "Parent shared with the input path",
) )
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") .rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -23,8 +23,11 @@ impl WholeStreamCommand for PathSplit {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path split") Signature::build("path split").rest(
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") "rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -24,8 +24,11 @@ impl WholeStreamCommand for PathType {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("path type") Signature::build("path type").rest(
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path") "rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -40,6 +40,7 @@ impl WholeStreamCommand for SubCommand {
Some('d'), Some('d'),
) )
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally, draw gradients using text from column paths", "optionally, draw gradients using text from column paths",
) )

View file

@ -15,6 +15,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("ansi strip").rest( Signature::build("ansi strip").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally, remove ansi sequences by column paths", "optionally, remove ansi sequences by column paths",
) )

View file

@ -25,6 +25,7 @@ impl WholeStreamCommand for Exec {
Signature::build("exec") Signature::build("exec")
.required("command", SyntaxShape::FilePath, "the command to execute") .required("command", SyntaxShape::FilePath, "the command to execute")
.rest( .rest(
"rest",
SyntaxShape::GlobPattern, SyntaxShape::GlobPattern,
"any additional arguments for the command", "any additional arguments for the command",
) )

View file

@ -19,7 +19,7 @@ impl WholeStreamCommand for Kill {
SyntaxShape::Int, SyntaxShape::Int,
"process id of process that is to be killed", "process id of process that is to be killed",
) )
.rest(SyntaxShape::Int, "rest of processes to kill") .rest("rest", SyntaxShape::Int, "rest of processes to kill")
.switch("force", "forcefully kill the process", Some('f')) .switch("force", "forcefully kill the process", Some('f'))
.switch("quiet", "won't print anything to the console", Some('q')); .switch("quiet", "won't print anything to the console", Some('q'));

View file

@ -43,7 +43,7 @@ impl WholeStreamCommand for RunExternalCommand {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build(self.name()).rest(SyntaxShape::Any, "external command arguments") Signature::build(self.name()).rest("rest", SyntaxShape::Any, "external command arguments")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -21,7 +21,7 @@ impl WholeStreamCommand for Sleep {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("sleep") Signature::build("sleep")
.required("duration", SyntaxShape::Duration, "time to sleep") .required("duration", SyntaxShape::Duration, "time to sleep")
.rest(SyntaxShape::Duration, "additional time") .rest("rest", SyntaxShape::Duration, "additional time")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -16,7 +16,7 @@ impl WholeStreamCommand for Which {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("which") Signature::build("which")
.required("application", SyntaxShape::String, "application") .required("application", SyntaxShape::String, "application")
.rest(SyntaxShape::String, "additional applications") .rest("rest", SyntaxShape::String, "additional applications")
.switch("all", "list all executables", Some('a')) .switch("all", "list all executables", Some('a'))
} }

View file

@ -13,8 +13,11 @@ impl WholeStreamCommand for BuildString {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("build-string") Signature::build("build-string").rest(
.rest(SyntaxShape::Any, "all values to form into the string") "rest",
SyntaxShape::Any,
"all values to form into the string",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -135,7 +135,7 @@ impl WholeStreamCommand for Char {
SyntaxShape::Any, SyntaxShape::Any,
"the name of the character to output", "the name of the character to output",
) )
.rest(SyntaxShape::String, "multiple Unicode bytes") .rest("rest", SyntaxShape::String, "multiple Unicode bytes")
.switch("list", "List all supported character names", Some('l')) .switch("list", "List all supported character names", Some('l'))
.switch("unicode", "Unicode string i.e. 1f378", Some('u')) .switch("unicode", "Unicode string i.e. 1f378", Some('u'))
} }

View file

@ -22,7 +22,11 @@ impl WholeStreamCommand for SubCommand {
"the character that denotes what separates columns", "the character that denotes what separates columns",
) )
.switch("collapse-empty", "remove empty columns", Some('c')) .switch("collapse-empty", "remove empty columns", Some('c'))
.rest(SyntaxShape::String, "column names to give the new columns") .rest(
"rest",
SyntaxShape::String,
"column names to give the new columns",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str capitalize").rest( Signature::build("str capitalize").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally capitalize text by column paths", "optionally capitalize text by column paths",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str camel-case").rest( Signature::build("str camel-case").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text to camelCase by column paths", "optionally convert text to camelCase by column paths",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str kebab-case").rest( Signature::build("str kebab-case").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text to kebab-case by column paths", "optionally convert text to kebab-case by column paths",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str pascal-case").rest( Signature::build("str pascal-case").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text to PascalCase by column paths", "optionally convert text to PascalCase by column paths",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str screaming-snake-case").rest( Signature::build("str screaming-snake-case").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text to SCREAMING_SNAKE_CASE by column paths", "optionally convert text to SCREAMING_SNAKE_CASE by column paths",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str snake-case").rest( Signature::build("str snake-case").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text to snake_case by column paths", "optionally convert text to snake_case by column paths",
) )

View file

@ -12,6 +12,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str").rest( Signature::build("str").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert by column paths", "optionally convert by column paths",
) )

View file

@ -25,6 +25,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str contains") Signature::build("str contains")
.required("pattern", SyntaxShape::String, "the pattern to find") .required("pattern", SyntaxShape::String, "the pattern to find")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally check if string contains pattern by column paths", "optionally check if string contains pattern by column paths",
) )

View file

@ -21,6 +21,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str downcase").rest( Signature::build("str downcase").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally downcase text by column paths", "optionally downcase text by column paths",
) )

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str ends-with") Signature::build("str ends-with")
.required("pattern", SyntaxShape::String, "the pattern to match") .required("pattern", SyntaxShape::String, "the pattern to match")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally matches suffix of text by column paths", "optionally matches suffix of text by column paths",
) )

View file

@ -28,6 +28,7 @@ impl WholeStreamCommand for SubCommand {
.required("find", SyntaxShape::String, "the pattern to find") .required("find", SyntaxShape::String, "the pattern to find")
.required("replace", SyntaxShape::String, "the replacement pattern") .required("replace", SyntaxShape::String, "the replacement pattern")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally find and replace text by column paths", "optionally find and replace text by column paths",
) )

View file

@ -33,6 +33,7 @@ impl WholeStreamCommand for SubCommand {
"the pattern to find index of", "the pattern to find index of",
) )
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally returns index of pattern in string by column paths", "optionally returns index of pattern in string by column paths",
) )

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str length").rest( Signature::build("str length").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally find length of text by column paths", "optionally find length of text by column paths",
) )

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for SubCommand {
Some('c'), Some('c'),
) )
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally check if string contains pattern by column paths", "optionally check if string contains pattern by column paths",
) )

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str reverse").rest( Signature::build("str reverse").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally reverse text by column paths", "optionally reverse text by column paths",
) )

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for SubCommand {
Some('c'), Some('c'),
) )
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally check if string contains pattern by column paths", "optionally check if string contains pattern by column paths",
) )

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str starts-with") Signature::build("str starts-with")
.required("pattern", SyntaxShape::String, "the pattern to match") .required("pattern", SyntaxShape::String, "the pattern to match")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally matches prefix of text by column paths", "optionally matches prefix of text by column paths",
) )

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for SubCommand {
"the indexes to substring [start end]", "the indexes to substring [start end]",
) )
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally substring text by column paths", "optionally substring text by column paths",
) )

View file

@ -77,6 +77,7 @@ impl WholeStreamCommand for SubCommand {
Some('f'), Some('f'),
) )
.rest( .rest(
"rest",
SyntaxShape::Any, SyntaxShape::Any,
"optionally convert text into datetime by column paths", "optionally convert text into datetime by column paths",
) )

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str to-decimal").rest( Signature::build("str to-decimal").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text into decimal by column paths", "optionally convert text into decimal by column paths",
) )

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str to-int") Signature::build("str to-int")
.named("radix", SyntaxShape::Number, "radix of integer", Some('r')) .named("radix", SyntaxShape::Number, "radix of integer", Some('r'))
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally convert text into integer by column paths", "optionally convert text into integer by column paths",
) )

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str trim") Signature::build("str trim")
.rest( .rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally trim text by column paths", "optionally trim text by column paths",
) )

View file

@ -21,6 +21,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("str upcase").rest( Signature::build("str upcase").rest(
"rest",
SyntaxShape::ColumnPath, SyntaxShape::ColumnPath,
"optionally upcase text by column paths", "optionally upcase text by column paths",
) )

View file

@ -20,7 +20,7 @@ impl WholeStreamCommand for Command {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("echo").rest(SyntaxShape::Any, "the values to echo") Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View file

@ -356,7 +356,8 @@ mod tests {
#[test] #[test]
fn completes_internal_command_names() { fn completes_internal_command_names() {
let registry: VecRegistry = let registry: VecRegistry =
vec![Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")].into(); vec![Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")]
.into();
let line = "echo 1 | echo 2"; let line = "echo 1 | echo 2";
assert_eq!( assert_eq!(
@ -402,7 +403,7 @@ mod tests {
fn completes_flags() { fn completes_flags() {
let registry: VecRegistry = vec![Signature::build("du") let registry: VecRegistry = vec![Signature::build("du")
.switch("recursive", "the values to echo", None) .switch("recursive", "the values to echo", None)
.rest(SyntaxShape::Any, "blah")] .rest("rest", SyntaxShape::Any, "blah")]
.into(); .into();
let line = "du --recurs"; let line = "du --recurs";
@ -442,7 +443,7 @@ mod tests {
fn completes_flags_with_just_a_single_hyphen() { fn completes_flags_with_just_a_single_hyphen() {
let registry: VecRegistry = vec![Signature::build("du") let registry: VecRegistry = vec![Signature::build("du")
.switch("recursive", "the values to echo", None) .switch("recursive", "the values to echo", None)
.rest(SyntaxShape::Any, "blah")] .rest("rest", SyntaxShape::Any, "blah")]
.into(); .into();
let line = "du -"; let line = "du -";
@ -459,7 +460,8 @@ mod tests {
#[test] #[test]
fn completes_arguments() { fn completes_arguments() {
let registry: VecRegistry = let registry: VecRegistry =
vec![Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")].into(); vec![Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")]
.into();
let line = "echo 1 | echo 2"; let line = "echo 1 | echo 2";
assert_eq!( assert_eq!(

View file

@ -205,7 +205,7 @@ pub fn get_documentation(
} }
if let Some(rest_positional) = &signature.rest_positional { if let Some(rest_positional) = &signature.rest_positional {
long_desc.push_str(&format!(" ...args: {}\n", rest_positional.1)); long_desc.push_str(&format!(" ...args: {}\n", rest_positional.2));
} }
} }
if !signature.named.is_empty() { if !signature.named.is_empty() {

View file

@ -125,7 +125,7 @@ fn get_signature(sig: &mut Signature, tag: Tag) -> Vec<Value> {
} }
match r { match r {
Some((shape, desc)) => { Some((rest_name, shape, desc)) => {
let mut indexmap = IndexMap::new(); let mut indexmap = IndexMap::new();
// let output = format!("Rest|{}|{}|{}\n", name, shape.syntax_shape_name(), desc); // let output = format!("Rest|{}|{}|{}\n", name, shape.syntax_shape_name(), desc);
// eprintln!("{}", output); // eprintln!("{}", output);
@ -136,7 +136,7 @@ fn get_signature(sig: &mut Signature, tag: Tag) -> Vec<Value> {
); );
indexmap.insert( indexmap.insert(
"parameter_name".to_string(), "parameter_name".to_string(),
UntaggedValue::string("".to_string()).into_value(&tag), UntaggedValue::string(rest_name.to_string()).into_value(&tag),
); );
indexmap.insert( indexmap.insert(
"parameter_type".to_string(), "parameter_type".to_string(),

View file

@ -468,7 +468,10 @@ impl VarSyntaxShapeDeductor {
if let Expression::Variable(var_name, _) = &positional.expr { if let Expression::Variable(var_name, _) = &positional.expr {
let deduced_shape = { let deduced_shape = {
if pos_idx >= signature.positional.len() { if pos_idx >= signature.positional.len() {
signature.rest_positional.as_ref().map(|(shape, _)| shape) signature
.rest_positional
.as_ref()
.map(|(_, shape, _)| shape)
} else { } else {
match &signature.positional[pos_idx].0 { match &signature.positional[pos_idx].0 {
PositionalType::Mandatory(_, shape) PositionalType::Mandatory(_, shape)

View file

@ -139,7 +139,7 @@ impl WholeStreamCommand for Arc<Block> {
_ => break, _ => break,
} }
} }
if block.params.rest_positional.is_some() { if let Some(rest_pos) = &block.params.rest_positional {
let elements: Vec<_> = args_iter.collect(); let elements: Vec<_> = args_iter.collect();
let start = if let Some(first) = elements.first() { let start = if let Some(first) = elements.first() {
first.tag.span.start() first.tag.span.start()
@ -153,15 +153,15 @@ impl WholeStreamCommand for Arc<Block> {
}; };
ctx.scope.add_var( ctx.scope.add_var(
"$rest", format!("${}", rest_pos.0),
UntaggedValue::Table(elements).into_value(Span::new(start, end)), UntaggedValue::Table(elements).into_value(Span::new(start, end)),
); );
} }
} else if block.params.rest_positional.is_some() { } else if let Some(rest_pos) = &block.params.rest_positional {
//If there is a rest arg, but no args were provided, //If there is a rest arg, but no args were provided,
//we have to set $rest to an empty table //we have to set $rest to an empty table
ctx.scope.add_var( ctx.scope.add_var(
"$rest", format!("${}", rest_pos.0),
UntaggedValue::Table(Vec::new()).into_value(Span::new(0, 0)), UntaggedValue::Table(Vec::new()).into_value(Span::new(0, 0)),
); );
} }

View file

@ -88,7 +88,7 @@ mod tests {
Signature::build("bundle add") Signature::build("bundle add")
.switch("skip-install", "Adds the gem to the Gemfile but does not install it.", None) .switch("skip-install", "Adds the gem to the Gemfile but does not install it.", None)
.named("group", SyntaxShape::String, "Specify the group(s) for the added gem. Multiple groups should be separated by commas.", Some('g')) .named("group", SyntaxShape::String, "Specify the group(s) for the added gem. Multiple groups should be separated by commas.", Some('g'))
.rest(SyntaxShape::Any, "options") .rest("rest", SyntaxShape::Any, "options")
} }
#[test] #[test]

View file

@ -1601,7 +1601,7 @@ fn parse_internal_command(
positional.push(arg); positional.push(arg);
current_positional += 1; current_positional += 1;
} else if let Some((rest_type, _)) = &signature.rest_positional { } else if let Some((_, rest_type, _)) = &signature.rest_positional {
let (arg, err) = parse_arg(*rest_type, scope, &lite_cmd.parts[idx]); let (arg, err) = parse_arg(*rest_type, scope, &lite_cmd.parts[idx]);
if error.is_none() { if error.is_none() {
error = err; error = err;

View file

@ -185,20 +185,20 @@ pub fn parse_type_token(type_: &Token) -> (SyntaxShape, Option<ParseError>) {
} }
} }
pub(crate) fn parse_rest_name(name_token: &Token) -> Option<ParseError> { pub(crate) fn parse_rest_name(name_token: &Token) -> (Spanned<String>, Option<ParseError>) {
return if let TokenContents::Baseline(name) = &name_token.contents { return if let TokenContents::Baseline(name) = &name_token.contents {
if !name.starts_with("...") { match name.strip_prefix("...") {
Some(parse_rest_name_err(name_token)) Some(var_name) => (var_name.to_string().spanned(name_token.span), None),
} else if !name.starts_with("...rest") { None => (
Some(ParseError::mismatch( "InternalError".to_string().spanned(name_token.span),
"rest argument name to be 'rest'", Some(parse_rest_name_err(name_token)),
token_to_spanned_string(name_token), ),
))
} else {
None
} }
} else { } else {
Some(parse_rest_name_err(name_token)) (
"InternalError".to_string().spanned(name_token.span),
Some(parse_rest_name_err(name_token)),
)
}; };
fn parse_rest_name_err(token: &Token) -> ParseError { fn parse_rest_name_err(token: &Token) -> ParseError {

View file

@ -231,7 +231,7 @@ fn parse_rest(
tokens: &[Token], tokens: &[Token],
tokens_as_str: &Spanned<String>, tokens_as_str: &Spanned<String>,
) -> ( ) -> (
Option<(SyntaxShape, Description)>, Option<(String, SyntaxShape, Description)>,
usize, usize,
Option<ParseError>, Option<ParseError>,
) { ) {
@ -251,7 +251,7 @@ fn parse_rest(
let mut type_ = SyntaxShape::Any; let mut type_ = SyntaxShape::Any;
let mut comment = "".to_string(); let mut comment = "".to_string();
let error = parse_rest_name(&tokens[i]); let (name, error) = parse_rest_name(&tokens[i]);
err = err.or(error); err = err.or(error);
i += 1; i += 1;
@ -268,7 +268,7 @@ fn parse_rest(
comment = parsed_comment.unwrap_or_else(|| "".to_string()); comment = parsed_comment.unwrap_or_else(|| "".to_string());
} }
(Some((type_, comment)), i, err) (Some((name.item, type_, comment)), i, err)
} }
fn parse_optional_type(tokens: &[Token]) -> (Option<SyntaxShape>, usize, Option<ParseError>) { fn parse_optional_type(tokens: &[Token]) -> (Option<SyntaxShape>, usize, Option<ParseError>) {
@ -352,7 +352,7 @@ fn to_signature(
name: &str, name: &str,
params: Vec<Parameter>, params: Vec<Parameter>,
flags: Vec<Flag>, flags: Vec<Flag>,
rest: Option<(SyntaxShape, Description)>, rest: Option<(String, SyntaxShape, Description)>,
) -> Signature { ) -> Signature {
let mut sign = Signature::new(name); let mut sign = Signature::new(name);

View file

@ -332,7 +332,23 @@ fn simple_def_with_rest_arg() {
assert!(err.is_none()); assert!(err.is_none());
assert_eq!( assert_eq!(
sign.rest_positional, sign.rest_positional,
Some((SyntaxShape::Any, "".to_string())) Some(("rest".to_string(), SyntaxShape::Any, "".to_string()))
);
}
#[test]
fn simple_def_with_rest_arg_other_name() {
let name = "my_func";
let sign = "[ ...paths:path # A pathological test]";
let (sign, err) = parse_signature(name, &sign.to_string().spanned_unknown());
assert!(err.is_none());
assert_eq!(
sign.rest_positional,
Some((
"paths".to_string(),
SyntaxShape::FilePath,
"A pathological test".to_string()
))
); );
} }
@ -344,7 +360,11 @@ fn simple_def_with_rest_arg_with_type_and_comment() {
assert!(err.is_none()); assert!(err.is_none());
assert_eq!( assert_eq!(
sign.rest_positional, sign.rest_positional,
Some((SyntaxShape::FilePath, "My super cool rest arg".to_string())) Some((
"rest".to_string(),
SyntaxShape::FilePath,
"My super cool rest arg".to_string()
))
); );
} }
@ -380,6 +400,10 @@ fn simple_def_with_param_flag_and_rest() {
); );
assert_eq!( assert_eq!(
sign.rest_positional, sign.rest_positional,
Some((SyntaxShape::Table, "Another rest".to_string())) Some((
"rest".to_string(),
SyntaxShape::Table,
"Another rest".to_string()
))
); );
} }

View file

@ -147,7 +147,7 @@ pub struct Signature {
/// The list of positional arguments, both required and optional, and their corresponding types and help text /// The list of positional arguments, both required and optional, and their corresponding types and help text
pub positional: Vec<(PositionalType, Description)>, pub positional: Vec<(PositionalType, Description)>,
/// After the positional arguments, a catch-all for the rest of the arguments that might follow, their type, and help text /// After the positional arguments, a catch-all for the rest of the arguments that might follow, their type, and help text
pub rest_positional: Option<(SyntaxShape, Description)>, pub rest_positional: Option<(String, SyntaxShape, Description)>,
/// The named flags with corresponding type and help text /// The named flags with corresponding type and help text
pub named: IndexMap<String, (NamedType, Description)>, pub named: IndexMap<String, (NamedType, Description)>,
/// The type of values being sent out from the command into the pipeline, if any /// The type of values being sent out from the command into the pipeline, if any
@ -194,7 +194,7 @@ impl Signature {
allowed.insert(shape.display()); allowed.insert(shape.display());
} }
if let Some((shape, _)) = &self.rest_positional { if let Some((_, shape, _)) = &self.rest_positional {
allowed.insert(shape.display()); allowed.insert(shape.display());
} }
@ -348,8 +348,13 @@ impl Signature {
/// Set the type for the "rest" of the positional arguments /// Set the type for the "rest" of the positional arguments
/// Note: Not naming the field in your struct holding the rest values "rest", can /// Note: Not naming the field in your struct holding the rest values "rest", can
/// cause errors when deserializing /// cause errors when deserializing
pub fn rest(mut self, ty: SyntaxShape, desc: impl Into<String>) -> Signature { pub fn rest(
self.rest_positional = Some((ty, desc.into())); mut self,
name: impl Into<String>,
ty: SyntaxShape,
desc: impl Into<String>,
) -> Signature {
self.rest_positional = Some((name.into(), ty, desc.into()));
self self
} }

View file

@ -31,7 +31,7 @@ impl Plugin for Inc {
"increment the patch version (eg 1.2.1 -> 1.2.2)", "increment the patch version (eg 1.2.1 -> 1.2.2)",
Some('p'), Some('p'),
) )
.rest(SyntaxShape::ColumnPath, "the column(s) to update") .rest("rest", SyntaxShape::ColumnPath, "the column(s) to update")
.filter()) .filter())
} }

View file

@ -8,7 +8,11 @@ impl Plugin for Start {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("start") Ok(Signature::build("start")
.desc("Opens each file/directory/URL using the default application") .desc("Opens each file/directory/URL using the default application")
.rest(SyntaxShape::String, "files/urls/directories to open") .rest(
"rest",
SyntaxShape::String,
"files/urls/directories to open",
)
.named( .named(
"application", "application",
SyntaxShape::String, SyntaxShape::String,

View file

@ -373,6 +373,25 @@ fn run_custom_command_with_empty_rest() {
assert_eq!(actual.err, r#""#); assert_eq!(actual.err, r#""#);
} }
#[test]
fn run_custom_command_with_rest_other_name() {
let actual = nu!(
cwd: ".",
r#"
def say-hello [
greeting:string,
...names:string # All of the names
] {
echo $"($greeting), ($names | sort-by | str collect ' ')"
}
say-hello Salutations E D C A B
"#
);
assert_eq!(actual.out, r#"Salutations, A B C D E"#);
assert_eq!(actual.err, r#""#);
}
#[test] #[test]
fn alias_a_load_env() { fn alias_a_load_env() {
let actual = nu!( let actual = nu!(