forked from extern/nushell
Add descriptions to arguments
This commit is contained in:
parent
7d383421c6
commit
fbd980f8b0
@ -10,7 +10,11 @@ impl WholeStreamCommand for CD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("cd").optional("directory", SyntaxShape::Path)
|
Signature::build("cd").optional(
|
||||||
|
"directory",
|
||||||
|
SyntaxShape::Path,
|
||||||
|
"the directory to change to",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -26,12 +26,16 @@ impl WholeStreamCommand for Config {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("config")
|
Signature::build("config")
|
||||||
.named("load", SyntaxShape::Path)
|
.named(
|
||||||
.named("set", SyntaxShape::Any)
|
"load",
|
||||||
.named("get", SyntaxShape::Any)
|
SyntaxShape::Path,
|
||||||
.named("remove", SyntaxShape::Any)
|
"load the config from the path give",
|
||||||
.switch("clear")
|
)
|
||||||
.switch("path")
|
.named("set", SyntaxShape::Any, "set a value in the config")
|
||||||
|
.named("get", SyntaxShape::Any, "get a value from the config")
|
||||||
|
.named("remove", SyntaxShape::Any, "remove a value from the config")
|
||||||
|
.switch("clear", "clear the config")
|
||||||
|
.switch("path", "return the path to the config file")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -21,10 +21,9 @@ impl PerItemCommand for Cpy {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("cp")
|
Signature::build("cp")
|
||||||
.required("src", SyntaxShape::Pattern)
|
.required("src", SyntaxShape::Pattern, "the place to copy from")
|
||||||
.required("dst", SyntaxShape::Path)
|
.required("dst", SyntaxShape::Path, "the place to copy to")
|
||||||
.named("file", SyntaxShape::Any)
|
.switch("recursive", "copy recursively through subdirectories")
|
||||||
.switch("recursive")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -17,7 +17,9 @@ impl WholeStreamCommand for Date {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("date").switch("utc").switch("local")
|
Signature::build("date")
|
||||||
|
.switch("utc", "use universal time (UTC)")
|
||||||
|
.switch("local", "use the local time")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -12,7 +12,7 @@ impl PerItemCommand for Echo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("echo").rest(SyntaxShape::Any)
|
Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -14,7 +14,11 @@ impl PerItemCommand for Enter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> registry::Signature {
|
fn signature(&self) -> registry::Signature {
|
||||||
Signature::build("enter").required("location", SyntaxShape::Path)
|
Signature::build("enter").required(
|
||||||
|
"location",
|
||||||
|
SyntaxShape::Path,
|
||||||
|
"the location to create a new shell from",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -11,7 +11,7 @@ impl WholeStreamCommand for Exit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("exit").switch("now")
|
Signature::build("exit").switch("now", "exit out of the shell immediately")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -19,8 +19,12 @@ impl PerItemCommand for Fetch {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build(self.name())
|
Signature::build(self.name())
|
||||||
.required("path", SyntaxShape::Path)
|
.required(
|
||||||
.switch("raw")
|
"path",
|
||||||
|
SyntaxShape::Path,
|
||||||
|
"the URL to fetch the contents from",
|
||||||
|
)
|
||||||
|
.switch("raw", "fetch contents as text rather than a table")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,11 @@ impl WholeStreamCommand for First {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("first").optional("rows", SyntaxShape::Int)
|
Signature::build("first").optional(
|
||||||
|
"rows",
|
||||||
|
SyntaxShape::Int,
|
||||||
|
"starting from the front, the number of rows to return",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,8 @@ impl WholeStreamCommand for FromCSV {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("from-csv").switch("headerless")
|
Signature::build("from-csv")
|
||||||
|
.switch("headerless", "don't treat the first row as column names")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -15,7 +15,7 @@ impl WholeStreamCommand for FromJSON {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("from-json").switch("objects")
|
Signature::build("from-json").switch("objects", "treat each line as a separate value")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -21,8 +21,12 @@ impl WholeStreamCommand for FromSSV {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build(STRING_REPRESENTATION)
|
Signature::build(STRING_REPRESENTATION)
|
||||||
.switch("headerless")
|
.switch("headerless", "don't treat the first row as column names")
|
||||||
.named("minimum-spaces", SyntaxShape::Int)
|
.named(
|
||||||
|
"minimum-spaces",
|
||||||
|
SyntaxShape::Int,
|
||||||
|
"the mininum spaces to separate columns",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,8 @@ impl WholeStreamCommand for FromTSV {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("from-tsv").switch("headerless")
|
Signature::build("from-tsv")
|
||||||
|
.switch("headerless", "don't treat the first row as column names")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -20,8 +20,15 @@ impl WholeStreamCommand for Get {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("get")
|
Signature::build("get")
|
||||||
.required("member", SyntaxShape::ColumnPath)
|
.required(
|
||||||
.rest(SyntaxShape::ColumnPath)
|
"member",
|
||||||
|
SyntaxShape::ColumnPath,
|
||||||
|
"the path to the data to get",
|
||||||
|
)
|
||||||
|
.rest(
|
||||||
|
SyntaxShape::ColumnPath,
|
||||||
|
"optionally return additional data by path",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,11 @@ impl WholeStreamCommand for GroupBy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("group-by").required("column_name", SyntaxShape::String)
|
Signature::build("group-by").required(
|
||||||
|
"column_name",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"the name of the column to group by",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -12,7 +12,7 @@ impl PerItemCommand for Help {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> registry::Signature {
|
fn signature(&self) -> registry::Signature {
|
||||||
Signature::build("help").rest(SyntaxShape::Any)
|
Signature::build("help").rest(SyntaxShape::Any, "the name of command(s) to get help on")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
@ -65,8 +65,8 @@ impl PerItemCommand for Help {
|
|||||||
one_liner.push_str("{flags} ");
|
one_liner.push_str("{flags} ");
|
||||||
}
|
}
|
||||||
|
|
||||||
for positional in signature.positional {
|
for positional in &signature.positional {
|
||||||
match positional {
|
match &positional.0 {
|
||||||
PositionalType::Mandatory(name, _m) => {
|
PositionalType::Mandatory(name, _m) => {
|
||||||
one_liner.push_str(&format!("<{}> ", name));
|
one_liner.push_str(&format!("<{}> ", name));
|
||||||
}
|
}
|
||||||
@ -77,25 +77,66 @@ impl PerItemCommand for Help {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if signature.rest_positional.is_some() {
|
if signature.rest_positional.is_some() {
|
||||||
one_liner.push_str(" ...args");
|
one_liner.push_str(&format!(" ...args",));
|
||||||
}
|
}
|
||||||
|
|
||||||
long_desc.push_str(&format!("\nUsage:\n > {}\n", one_liner));
|
long_desc.push_str(&format!("\nUsage:\n > {}\n", one_liner));
|
||||||
|
|
||||||
|
if signature.positional.len() > 0 || signature.rest_positional.is_some() {
|
||||||
|
long_desc.push_str("\nparameters:\n");
|
||||||
|
for positional in signature.positional {
|
||||||
|
match positional.0 {
|
||||||
|
PositionalType::Mandatory(name, _m) => {
|
||||||
|
long_desc
|
||||||
|
.push_str(&format!(" <{}> {}\n", name, positional.1));
|
||||||
|
}
|
||||||
|
PositionalType::Optional(name, _o) => {
|
||||||
|
long_desc
|
||||||
|
.push_str(&format!(" ({}) {}\n", name, positional.1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if signature.rest_positional.is_some() {
|
||||||
|
long_desc.push_str(&format!(
|
||||||
|
" ...args{} {}\n",
|
||||||
|
if signature.rest_positional.is_some() {
|
||||||
|
":"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
signature.rest_positional.unwrap().1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
if signature.named.len() > 0 {
|
if signature.named.len() > 0 {
|
||||||
long_desc.push_str("\nflags:\n");
|
long_desc.push_str("\nflags:\n");
|
||||||
for (flag, ty) in signature.named {
|
for (flag, ty) in signature.named {
|
||||||
match ty {
|
match ty.0 {
|
||||||
NamedType::Switch => {
|
NamedType::Switch => {
|
||||||
long_desc.push_str(&format!(" --{}\n", flag));
|
long_desc.push_str(&format!(
|
||||||
|
" --{}{} {}\n",
|
||||||
|
flag,
|
||||||
|
if ty.1.len() > 0 { ":" } else { "" },
|
||||||
|
ty.1
|
||||||
|
));
|
||||||
}
|
}
|
||||||
NamedType::Mandatory(m) => {
|
NamedType::Mandatory(m) => {
|
||||||
long_desc.push_str(&format!(
|
long_desc.push_str(&format!(
|
||||||
" --{} <{}> (required parameter)\n",
|
" --{} <{}> (required parameter){} {}\n",
|
||||||
flag, m
|
flag,
|
||||||
|
m,
|
||||||
|
if ty.1.len() > 0 { ":" } else { "" },
|
||||||
|
ty.1
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
NamedType::Optional(o) => {
|
NamedType::Optional(o) => {
|
||||||
long_desc.push_str(&format!(" --{} <{}>\n", flag, o));
|
long_desc.push_str(&format!(
|
||||||
|
" --{} <{}>{} {}\n",
|
||||||
|
flag,
|
||||||
|
o,
|
||||||
|
if ty.1.len() > 0 { ":" } else { "" },
|
||||||
|
ty.1
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,11 @@ impl WholeStreamCommand for Last {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("last").optional("rows", SyntaxShape::Number)
|
Signature::build("last").optional(
|
||||||
|
"rows",
|
||||||
|
SyntaxShape::Number,
|
||||||
|
"starting from the back, the number of rows to return",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,11 @@ impl WholeStreamCommand for LS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("ls").optional("path", SyntaxShape::Pattern)
|
Signature::build("ls").optional(
|
||||||
|
"path",
|
||||||
|
SyntaxShape::Pattern,
|
||||||
|
"a path to get the directory contents from",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -17,7 +17,7 @@ impl PerItemCommand for Mkdir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("mkdir").rest(SyntaxShape::Path)
|
Signature::build("mkdir").rest(SyntaxShape::Path, "the name(s) of the path(s) to create")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -20,9 +20,16 @@ impl PerItemCommand for Move {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("mv")
|
Signature::build("mv")
|
||||||
.required("source", SyntaxShape::Pattern)
|
.required(
|
||||||
.required("destination", SyntaxShape::Path)
|
"source",
|
||||||
.named("file", SyntaxShape::Any)
|
SyntaxShape::Pattern,
|
||||||
|
"the location to move files/directories from",
|
||||||
|
)
|
||||||
|
.required(
|
||||||
|
"destination",
|
||||||
|
SyntaxShape::Path,
|
||||||
|
"the location to move files/directories to",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,11 @@ impl WholeStreamCommand for Nth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("nth").required("row number", SyntaxShape::Any)
|
Signature::build("nth").required(
|
||||||
|
"row number",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"the number of the row to return",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,8 +16,12 @@ impl PerItemCommand for Open {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build(self.name())
|
Signature::build(self.name())
|
||||||
.required("path", SyntaxShape::Path)
|
.required(
|
||||||
.switch("raw")
|
"path",
|
||||||
|
SyntaxShape::Path,
|
||||||
|
"the file path to load values from",
|
||||||
|
)
|
||||||
|
.switch("raw", "load content as a string insead of a table")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -17,7 +17,7 @@ impl WholeStreamCommand for Pick {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("pick").rest(SyntaxShape::Any)
|
Signature::build("pick").rest(SyntaxShape::Any, "the columns to select from the table")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -21,9 +21,12 @@ impl WholeStreamCommand for Pivot {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("pivot")
|
Signature::build("pivot")
|
||||||
.switch("header-row")
|
.switch("header-row", "treat the first row as column names")
|
||||||
.switch("ignore-titles")
|
.switch("ignore-titles", "don't pivot the column names into values")
|
||||||
.rest(SyntaxShape::String)
|
.rest(
|
||||||
|
SyntaxShape::String,
|
||||||
|
"the names to give columns once pivoted",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -25,13 +25,25 @@ impl PerItemCommand for Post {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build(self.name())
|
Signature::build(self.name())
|
||||||
.required("path", SyntaxShape::Any)
|
.required("path", SyntaxShape::Any, "the URL to post to")
|
||||||
.required("body", SyntaxShape::Any)
|
.required("body", SyntaxShape::Any, "the contents of the post body")
|
||||||
.named("user", SyntaxShape::Any)
|
.named("user", SyntaxShape::Any, "the username when authenticating")
|
||||||
.named("password", SyntaxShape::Any)
|
.named(
|
||||||
.named("content-type", SyntaxShape::Any)
|
"password",
|
||||||
.named("content-length", SyntaxShape::Any)
|
SyntaxShape::Any,
|
||||||
.switch("raw")
|
"the password when authenticating",
|
||||||
|
)
|
||||||
|
.named(
|
||||||
|
"content-type",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"the MIME type of content to post",
|
||||||
|
)
|
||||||
|
.named(
|
||||||
|
"content-length",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"the length of the content being posted",
|
||||||
|
)
|
||||||
|
.switch("raw", "return values as a string instead of a table")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,7 @@ impl WholeStreamCommand for Reject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("reject").rest(SyntaxShape::Member)
|
Signature::build("reject").rest(SyntaxShape::Member, "the names of columns to remove")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -21,13 +21,16 @@ impl PerItemCommand for Remove {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("rm")
|
Signature::build("rm")
|
||||||
.required("path", SyntaxShape::Pattern)
|
.required("path", SyntaxShape::Pattern, "the file path to remove")
|
||||||
.switch("trash")
|
.switch(
|
||||||
.switch("recursive")
|
"trash",
|
||||||
|
"use the platform's recycle bin instead of permanently deleting",
|
||||||
|
)
|
||||||
|
.switch("recursive", "delete subdirectories recursively")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
"Remove a file. Append '--recursive' to remove directories and '--trash' for seding it to system recycle bin"
|
"Remove a file"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
|
@ -93,8 +93,11 @@ impl WholeStreamCommand for Save {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("save")
|
Signature::build("save")
|
||||||
.optional("path", SyntaxShape::Path)
|
.optional("path", SyntaxShape::Path, "the path to save contents to")
|
||||||
.switch("raw")
|
.switch(
|
||||||
|
"raw",
|
||||||
|
"treat values as-is rather than auto-converting based on file extension",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -17,7 +17,11 @@ impl WholeStreamCommand for SkipWhile {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("skip-while")
|
Signature::build("skip-while")
|
||||||
.required("condition", SyntaxShape::Block)
|
.required(
|
||||||
|
"condition",
|
||||||
|
SyntaxShape::Block,
|
||||||
|
"the condition that must be met to continue skipping",
|
||||||
|
)
|
||||||
.filter()
|
.filter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ impl WholeStreamCommand for SortBy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("sort-by").rest(SyntaxShape::String)
|
Signature::build("sort-by").rest(SyntaxShape::String, "the column(s) to sort by")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -21,9 +21,13 @@ impl WholeStreamCommand for SplitColumn {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("split-column")
|
Signature::build("split-column")
|
||||||
.required("separator", SyntaxShape::Any)
|
.required(
|
||||||
.switch("collapse-empty")
|
"separator",
|
||||||
.rest(SyntaxShape::Member)
|
SyntaxShape::Any,
|
||||||
|
"the character that denotes what separates columns",
|
||||||
|
)
|
||||||
|
.switch("collapse-empty", "remove empty columns")
|
||||||
|
.rest(SyntaxShape::Member, "column names to give the new columns")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -17,7 +17,11 @@ impl WholeStreamCommand for SplitRow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("split-row").required("separator", SyntaxShape::Any)
|
Signature::build("split-row").required(
|
||||||
|
"separator",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"the character that denotes what separates rows",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -11,7 +11,11 @@ impl WholeStreamCommand for Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("table").named("start_number", SyntaxShape::Number)
|
Signature::build("table").named(
|
||||||
|
"start_number",
|
||||||
|
SyntaxShape::Number,
|
||||||
|
"row number to start viewing from",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,10 @@ impl WholeStreamCommand for ToCSV {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("to-csv").switch("headerless")
|
Signature::build("to-csv").switch(
|
||||||
|
"headerless",
|
||||||
|
"do not output the columns names as the first row",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -16,7 +16,10 @@ impl WholeStreamCommand for ToTSV {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("to-tsv").switch("headerless")
|
Signature::build("to-tsv").switch(
|
||||||
|
"headerless",
|
||||||
|
"do not output the column names as the first row",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -12,7 +12,11 @@ impl PerItemCommand for Where {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> registry::Signature {
|
fn signature(&self) -> registry::Signature {
|
||||||
Signature::build("where").required("condition", SyntaxShape::Block)
|
Signature::build("where").required(
|
||||||
|
"condition",
|
||||||
|
SyntaxShape::Block,
|
||||||
|
"the condition that must match",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -13,7 +13,11 @@ impl WholeStreamCommand for Which {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("which").required("name", SyntaxShape::Any)
|
Signature::build("which").required(
|
||||||
|
"name",
|
||||||
|
SyntaxShape::Any,
|
||||||
|
"the name of the command to find the path to",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -45,12 +45,12 @@ fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Tagged<Value> {
|
|||||||
let mut sig = TaggedListBuilder::new(&tag);
|
let mut sig = TaggedListBuilder::new(&tag);
|
||||||
|
|
||||||
for arg in signature.positional.iter() {
|
for arg in signature.positional.iter() {
|
||||||
let is_required = match arg {
|
let is_required = match arg.0 {
|
||||||
PositionalType::Mandatory(_, _) => true,
|
PositionalType::Mandatory(_, _) => true,
|
||||||
PositionalType::Optional(_, _) => false,
|
PositionalType::Optional(_, _) => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
sig.insert_tagged(for_spec(arg.name(), "argument", is_required, &tag));
|
sig.insert_tagged(for_spec(arg.0.name(), "argument", is_required, &tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(_) = signature.rest_positional {
|
if let Some(_) = signature.rest_positional {
|
||||||
@ -59,7 +59,7 @@ fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Tagged<Value> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (name, ty) in signature.named.iter() {
|
for (name, ty) in signature.named.iter() {
|
||||||
match ty {
|
match ty.0 {
|
||||||
NamedType::Mandatory(_) => sig.insert_tagged(for_spec(name, "flag", true, &tag)),
|
NamedType::Mandatory(_) => sig.insert_tagged(for_spec(name, "flag", true, &tag)),
|
||||||
NamedType::Optional(_) => sig.insert_tagged(for_spec(name, "flag", false, &tag)),
|
NamedType::Optional(_) => sig.insert_tagged(for_spec(name, "flag", false, &tag)),
|
||||||
NamedType::Switch => sig.insert_tagged(for_spec(name, "switch", false, &tag)),
|
NamedType::Switch => sig.insert_tagged(for_spec(name, "switch", false, &tag)),
|
||||||
|
@ -25,7 +25,7 @@ pub fn parse_command_tail(
|
|||||||
for (name, kind) in &config.named {
|
for (name, kind) in &config.named {
|
||||||
trace!(target: "nu::parse", "looking for {} : {:?}", name, kind);
|
trace!(target: "nu::parse", "looking for {} : {:?}", name, kind);
|
||||||
|
|
||||||
match kind {
|
match &kind.0 {
|
||||||
NamedType::Switch => {
|
NamedType::Switch => {
|
||||||
let flag = extract_switch(name, tail, context.source());
|
let flag = extract_switch(name, tail, context.source());
|
||||||
|
|
||||||
@ -92,12 +92,12 @@ pub fn parse_command_tail(
|
|||||||
for arg in &config.positional {
|
for arg in &config.positional {
|
||||||
trace!(target: "nu::parse", "Processing positional {:?}", arg);
|
trace!(target: "nu::parse", "Processing positional {:?}", arg);
|
||||||
|
|
||||||
match arg {
|
match &arg.0 {
|
||||||
PositionalType::Mandatory(..) => {
|
PositionalType::Mandatory(..) => {
|
||||||
if tail.at_end_possible_ws() {
|
if tail.at_end_possible_ws() {
|
||||||
return Err(ShellError::argument_error(
|
return Err(ShellError::argument_error(
|
||||||
config.name.clone(),
|
config.name.clone(),
|
||||||
ArgumentError::MissingMandatoryPositional(arg.name().to_string()),
|
ArgumentError::MissingMandatoryPositional(arg.0.name().to_string()),
|
||||||
Tag {
|
Tag {
|
||||||
span: command_span,
|
span: command_span,
|
||||||
anchor: None,
|
anchor: None,
|
||||||
@ -113,14 +113,14 @@ pub fn parse_command_tail(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = expand_expr(&spaced(arg.syntax_type()), tail, context)?;
|
let result = expand_expr(&spaced(arg.0.syntax_type()), tail, context)?;
|
||||||
|
|
||||||
positional.push(result);
|
positional.push(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_remaining("after positional", tail.clone(), context.source());
|
trace_remaining("after positional", tail.clone(), context.source());
|
||||||
|
|
||||||
if let Some(syntax_type) = config.rest_positional {
|
if let Some((syntax_type, _)) = config.rest_positional {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -207,7 +207,7 @@ impl ColorSyntax for CommandTailShape {
|
|||||||
for (name, kind) in &signature.named {
|
for (name, kind) in &signature.named {
|
||||||
trace!(target: "nu::color_syntax", "looking for {} : {:?}", name, kind);
|
trace!(target: "nu::color_syntax", "looking for {} : {:?}", name, kind);
|
||||||
|
|
||||||
match kind {
|
match &kind.0 {
|
||||||
NamedType::Switch => {
|
NamedType::Switch => {
|
||||||
match token_nodes.extract(|t| t.as_flag(name, context.source())) {
|
match token_nodes.extract(|t| t.as_flag(name, context.source())) {
|
||||||
Some((pos, flag)) => args.insert(pos, vec![flag.color()]),
|
Some((pos, flag)) => args.insert(pos, vec![flag.color()]),
|
||||||
@ -300,7 +300,7 @@ impl ColorSyntax for CommandTailShape {
|
|||||||
for arg in &signature.positional {
|
for arg in &signature.positional {
|
||||||
trace!("Processing positional {:?}", arg);
|
trace!("Processing positional {:?}", arg);
|
||||||
|
|
||||||
match arg {
|
match arg.0 {
|
||||||
PositionalType::Mandatory(..) => {
|
PositionalType::Mandatory(..) => {
|
||||||
if token_nodes.at_end() {
|
if token_nodes.at_end() {
|
||||||
break;
|
break;
|
||||||
@ -327,7 +327,7 @@ impl ColorSyntax for CommandTailShape {
|
|||||||
|
|
||||||
// If no match, we should roll back any whitespace we chomped
|
// If no match, we should roll back any whitespace we chomped
|
||||||
color_fallible_syntax(
|
color_fallible_syntax(
|
||||||
&arg.syntax_type(),
|
&arg.0.syntax_type(),
|
||||||
token_nodes,
|
token_nodes,
|
||||||
context,
|
context,
|
||||||
&mut shapes,
|
&mut shapes,
|
||||||
@ -343,7 +343,7 @@ impl ColorSyntax for CommandTailShape {
|
|||||||
|
|
||||||
trace_remaining("after positional", token_nodes.clone(), context.source());
|
trace_remaining("after positional", token_nodes.clone(), context.source());
|
||||||
|
|
||||||
if let Some(syntax_type) = signature.rest_positional {
|
if let Some((syntax_type, _)) = signature.rest_positional {
|
||||||
loop {
|
loop {
|
||||||
if token_nodes.at_end_possible_ws() {
|
if token_nodes.at_end_possible_ws() {
|
||||||
break;
|
break;
|
||||||
|
@ -58,17 +58,19 @@ impl PositionalType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Description = String;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, new)]
|
#[derive(Debug, Serialize, Deserialize, Clone, new)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub usage: String,
|
pub usage: String,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub positional: Vec<PositionalType>,
|
pub positional: Vec<(PositionalType, Description)>,
|
||||||
#[new(value = "None")]
|
#[new(value = "None")]
|
||||||
pub rest_positional: Option<SyntaxShape>,
|
pub rest_positional: Option<(SyntaxShape, Description)>,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub named: IndexMap<String, NamedType>,
|
pub named: IndexMap<String, (NamedType, Description)>,
|
||||||
#[new(value = "false")]
|
#[new(value = "false")]
|
||||||
pub is_filter: bool,
|
pub is_filter: bool,
|
||||||
}
|
}
|
||||||
@ -83,23 +85,42 @@ impl Signature {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn required(mut self, name: impl Into<String>, ty: impl Into<SyntaxShape>) -> Signature {
|
pub fn required(
|
||||||
self.positional
|
mut self,
|
||||||
.push(PositionalType::Mandatory(name.into(), ty.into()));
|
name: impl Into<String>,
|
||||||
|
ty: impl Into<SyntaxShape>,
|
||||||
|
desc: impl Into<String>,
|
||||||
|
) -> Signature {
|
||||||
|
self.positional.push((
|
||||||
|
PositionalType::Mandatory(name.into(), ty.into()),
|
||||||
|
desc.into(),
|
||||||
|
));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn optional(mut self, name: impl Into<String>, ty: impl Into<SyntaxShape>) -> Signature {
|
pub fn optional(
|
||||||
self.positional
|
mut self,
|
||||||
.push(PositionalType::Optional(name.into(), ty.into()));
|
name: impl Into<String>,
|
||||||
|
ty: impl Into<SyntaxShape>,
|
||||||
|
desc: impl Into<String>,
|
||||||
|
) -> Signature {
|
||||||
|
self.positional.push((
|
||||||
|
PositionalType::Optional(name.into(), ty.into()),
|
||||||
|
desc.into(),
|
||||||
|
));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn named(mut self, name: impl Into<String>, ty: impl Into<SyntaxShape>) -> Signature {
|
pub fn named(
|
||||||
|
mut self,
|
||||||
|
name: impl Into<String>,
|
||||||
|
ty: impl Into<SyntaxShape>,
|
||||||
|
desc: impl Into<String>,
|
||||||
|
) -> Signature {
|
||||||
self.named
|
self.named
|
||||||
.insert(name.into(), NamedType::Optional(ty.into()));
|
.insert(name.into(), (NamedType::Optional(ty.into()), desc.into()));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -108,15 +129,17 @@ impl Signature {
|
|||||||
mut self,
|
mut self,
|
||||||
name: impl Into<String>,
|
name: impl Into<String>,
|
||||||
ty: impl Into<SyntaxShape>,
|
ty: impl Into<SyntaxShape>,
|
||||||
|
desc: impl Into<String>,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
self.named
|
self.named
|
||||||
.insert(name.into(), NamedType::Mandatory(ty.into()));
|
.insert(name.into(), (NamedType::Mandatory(ty.into()), desc.into()));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn switch(mut self, name: impl Into<String>) -> Signature {
|
pub fn switch(mut self, name: impl Into<String>, desc: impl Into<String>) -> Signature {
|
||||||
self.named.insert(name.into(), NamedType::Switch);
|
self.named
|
||||||
|
.insert(name.into(), (NamedType::Switch, desc.into()));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -126,8 +149,8 @@ impl Signature {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rest(mut self, ty: SyntaxShape) -> Signature {
|
pub fn rest(mut self, ty: SyntaxShape, desc: impl Into<String>) -> Signature {
|
||||||
self.rest_positional = Some(ty);
|
self.rest_positional = Some((ty, desc.into()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,13 @@ 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.")
|
.desc("Add a new column to the table.")
|
||||||
.required("Field", SyntaxShape::ColumnPath)
|
.required("column", SyntaxShape::ColumnPath, "the column name to add")
|
||||||
.required("Value", SyntaxShape::String)
|
.required(
|
||||||
.rest(SyntaxShape::String)
|
"value",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"the value to give the cell(s)",
|
||||||
|
)
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ impl Plugin for BinaryView {
|
|||||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||||
Ok(Signature::build("binaryview")
|
Ok(Signature::build("binaryview")
|
||||||
.desc("Autoview of binary data.")
|
.desc("Autoview of binary data.")
|
||||||
.switch("lores"))
|
.switch("lores", "use low resolution output mode"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {
|
fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {
|
||||||
|
@ -48,8 +48,16 @@ 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 column to have a new value.")
|
.desc("Edit an existing column to have a new value.")
|
||||||
.required("Field", SyntaxShape::ColumnPath)
|
.required(
|
||||||
.required("Value", SyntaxShape::String)
|
"Field",
|
||||||
|
SyntaxShape::ColumnPath,
|
||||||
|
"the name of the column to edit",
|
||||||
|
)
|
||||||
|
.required(
|
||||||
|
"Value",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"the new value to give the cell(s)",
|
||||||
|
)
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ impl Plugin for Embed {
|
|||||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||||
Ok(Signature::build("embed")
|
Ok(Signature::build("embed")
|
||||||
.desc("Embeds a new field to the table.")
|
.desc("Embeds a new field to the table.")
|
||||||
.optional("field", SyntaxShape::String)
|
.optional("field", SyntaxShape::String, "the name of the new column")
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +137,10 @@ 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. Optionally use the column of a table.")
|
.desc("Increment a value or version. Optionally use the column of a table.")
|
||||||
.switch("major")
|
.switch("major", "increment the major version (eg 1.2.1 -> 2.0.0)")
|
||||||
.switch("minor")
|
.switch("minor", "increment the minor version (eg 1.2.1 -> 1.3.0)")
|
||||||
.switch("patch")
|
.switch("patch", "increment the patch version (eg 1.2.1 -> 1.2.2)")
|
||||||
.rest(SyntaxShape::ColumnPath)
|
.rest(SyntaxShape::ColumnPath, "the column(s) to update")
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ impl Plugin for Match {
|
|||||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||||
Ok(Signature::build("match")
|
Ok(Signature::build("match")
|
||||||
.desc("filter rows by regex")
|
.desc("filter rows by regex")
|
||||||
.required("member", SyntaxShape::Member)
|
.required("member", SyntaxShape::Member, "the column name to match")
|
||||||
.required("regex", SyntaxShape::String)
|
.required("regex", SyntaxShape::String, "the regex to match with")
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
|
@ -17,7 +17,7 @@ impl Plugin for Skip {
|
|||||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||||
Ok(Signature::build("skip")
|
Ok(Signature::build("skip")
|
||||||
.desc("Skip a number of rows")
|
.desc("Skip a number of rows")
|
||||||
.rest(SyntaxShape::Number)
|
.rest(SyntaxShape::Number, "the number of rows to skip")
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
|
@ -128,11 +128,11 @@ 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")
|
.desc("Apply string function. Optional use the column of a table")
|
||||||
.switch("downcase")
|
.switch("downcase", "convert string to lowercase")
|
||||||
.switch("upcase")
|
.switch("upcase", "convert string to uppercase")
|
||||||
.switch("to-int")
|
.switch("to-int", "convert string to integer")
|
||||||
.rest(SyntaxShape::ColumnPath)
|
.rest(SyntaxShape::ColumnPath, "the column(s) to convert")
|
||||||
.filter())
|
.filter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user