mirror of
https://github.com/nushell/nushell.git
synced 2024-12-23 15:39:06 +01:00
Add experimental support for flags in custom commands (#2808)
* Add experimental support for flags in custom commands * clippy
This commit is contained in:
parent
67acaae53c
commit
c012d648fb
@ -275,6 +275,39 @@ impl WholeStreamCommand for Block {
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(args) = evaluated.args.named {
|
||||
for named in &block.params.named {
|
||||
let name = named.0;
|
||||
if let Some(value) = args.get(name) {
|
||||
if name.starts_with('$') {
|
||||
ctx.scope.add_var(name, value.clone());
|
||||
} else {
|
||||
ctx.scope.add_var(format!("${}", name), value.clone());
|
||||
}
|
||||
} else if name.starts_with('$') {
|
||||
ctx.scope
|
||||
.add_var(name, UntaggedValue::nothing().into_untagged_value());
|
||||
} else {
|
||||
ctx.scope.add_var(
|
||||
format!("${}", name),
|
||||
UntaggedValue::nothing().into_untagged_value(),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for named in &block.params.named {
|
||||
let name = named.0;
|
||||
if name.starts_with('$') {
|
||||
ctx.scope
|
||||
.add_var(name, UntaggedValue::nothing().into_untagged_value());
|
||||
} else {
|
||||
ctx.scope.add_var(
|
||||
format!("${}", name),
|
||||
UntaggedValue::nothing().into_untagged_value(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
let result = run_block(&block, &ctx, input).await;
|
||||
ctx.scope.exit_scope();
|
||||
result.map(|x| x.to_output_stream())
|
||||
|
@ -173,6 +173,29 @@ impl LiteBlock {
|
||||
Span::new(start, 0)
|
||||
}
|
||||
}
|
||||
pub fn head(&self) -> Option<Spanned<String>> {
|
||||
if let Some(group) = self.block.get(0) {
|
||||
if let Some(pipeline) = group.pipelines.get(0) {
|
||||
if let Some(command) = pipeline.commands.get(0) {
|
||||
if let Some(head) = command.parts.get(0) {
|
||||
return Some(head.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
pub fn remove_head(&mut self) {
|
||||
if let Some(group) = self.block.get_mut(0) {
|
||||
if let Some(pipeline) = group.pipelines.get_mut(0) {
|
||||
if let Some(command) = pipeline.commands.get_mut(0) {
|
||||
if !command.parts.is_empty() {
|
||||
command.parts.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -2027,36 +2027,76 @@ fn parse_signature(
|
||||
Expression::Literal(Literal::String(st)) => {
|
||||
let parts: Vec<_> = st.split(':').collect();
|
||||
if parts.len() == 1 {
|
||||
signature.positional.push((
|
||||
PositionalType::Mandatory(parts[0].to_string(), SyntaxShape::Any),
|
||||
String::new(),
|
||||
));
|
||||
if parts[0].starts_with("--") {
|
||||
// Flag
|
||||
let flagname = parts[0][2..].to_string();
|
||||
signature
|
||||
.named
|
||||
.insert(flagname, (NamedType::Switch(None), String::new()));
|
||||
} else {
|
||||
// Positional
|
||||
signature.positional.push((
|
||||
PositionalType::Mandatory(parts[0].to_string(), SyntaxShape::Any),
|
||||
String::new(),
|
||||
));
|
||||
}
|
||||
} else if parts.len() == 2 {
|
||||
let name = parts[0].to_string();
|
||||
let shape = match parts[1] {
|
||||
"int" => SyntaxShape::Int,
|
||||
"string" => SyntaxShape::String,
|
||||
"path" => SyntaxShape::Path,
|
||||
"table" => SyntaxShape::Table,
|
||||
"unit" => SyntaxShape::Unit,
|
||||
"number" => SyntaxShape::Number,
|
||||
"pattern" => SyntaxShape::Pattern,
|
||||
"range" => SyntaxShape::Range,
|
||||
"block" => SyntaxShape::Block,
|
||||
"any" => SyntaxShape::Any,
|
||||
_ => {
|
||||
if err.is_none() {
|
||||
err = Some(ParseError::mismatch(
|
||||
"params with known types",
|
||||
s.clone(),
|
||||
));
|
||||
if parts[0].starts_with("--") {
|
||||
// Flag
|
||||
let flagname = parts[0][2..].to_string();
|
||||
let shape = match parts[1] {
|
||||
"int" => SyntaxShape::Int,
|
||||
"string" => SyntaxShape::String,
|
||||
"path" => SyntaxShape::Path,
|
||||
"table" => SyntaxShape::Table,
|
||||
"unit" => SyntaxShape::Unit,
|
||||
"number" => SyntaxShape::Number,
|
||||
"pattern" => SyntaxShape::Pattern,
|
||||
"range" => SyntaxShape::Range,
|
||||
"block" => SyntaxShape::Block,
|
||||
"any" => SyntaxShape::Any,
|
||||
_ => {
|
||||
if err.is_none() {
|
||||
err = Some(ParseError::mismatch(
|
||||
"params with known types",
|
||||
s.clone(),
|
||||
));
|
||||
}
|
||||
SyntaxShape::Any
|
||||
}
|
||||
SyntaxShape::Any
|
||||
}
|
||||
};
|
||||
signature
|
||||
.positional
|
||||
.push((PositionalType::Mandatory(name, shape), String::new()));
|
||||
};
|
||||
signature.named.insert(
|
||||
flagname,
|
||||
(NamedType::Optional(None, shape), String::new()),
|
||||
);
|
||||
} else {
|
||||
// Positional
|
||||
let name = parts[0].to_string();
|
||||
let shape = match parts[1] {
|
||||
"int" => SyntaxShape::Int,
|
||||
"string" => SyntaxShape::String,
|
||||
"path" => SyntaxShape::Path,
|
||||
"table" => SyntaxShape::Table,
|
||||
"unit" => SyntaxShape::Unit,
|
||||
"number" => SyntaxShape::Number,
|
||||
"pattern" => SyntaxShape::Pattern,
|
||||
"range" => SyntaxShape::Range,
|
||||
"block" => SyntaxShape::Block,
|
||||
"any" => SyntaxShape::Any,
|
||||
_ => {
|
||||
if err.is_none() {
|
||||
err = Some(ParseError::mismatch(
|
||||
"params with known types",
|
||||
s.clone(),
|
||||
));
|
||||
}
|
||||
SyntaxShape::Any
|
||||
}
|
||||
};
|
||||
signature
|
||||
.positional
|
||||
.push((PositionalType::Mandatory(name, shape), String::new()));
|
||||
}
|
||||
} else if err.is_none() {
|
||||
err = Some(ParseError::mismatch("param with type", s.clone()));
|
||||
}
|
||||
@ -2246,11 +2286,6 @@ pub fn classify_block(
|
||||
}
|
||||
}
|
||||
|
||||
// for def in scope.get_definitions() {
|
||||
// let name = def.params.name.clone();
|
||||
// output.definitions.insert(name, def.clone());
|
||||
// }
|
||||
|
||||
(output, error)
|
||||
}
|
||||
|
||||
|
@ -344,6 +344,30 @@ fn run_custom_command() {
|
||||
assert_eq!(actual.out, "15");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_custom_command_with_flag() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
def foo [--bar:number] { if $(echo $bar | empty?) { echo "empty" } { echo $bar } }; foo --bar 10
|
||||
"#
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "10");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_custom_command_with_flag_missing() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
def foo [--bar:number] { if $(echo $bar | empty?) { echo "empty" } { echo $bar } }; foo
|
||||
"#
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "empty");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_variable() {
|
||||
let actual = nu!(
|
||||
|
Loading…
Reference in New Issue
Block a user