mirror of
https://github.com/nushell/nushell
synced 2025-01-16 07:04:09 +00: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
4 changed files with 148 additions and 33 deletions
crates
tests/shell/pipeline/commands
|
@ -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;
|
let result = run_block(&block, &ctx, input).await;
|
||||||
ctx.scope.exit_scope();
|
ctx.scope.exit_scope();
|
||||||
result.map(|x| x.to_output_stream())
|
result.map(|x| x.to_output_stream())
|
||||||
|
|
|
@ -173,6 +173,29 @@ impl LiteBlock {
|
||||||
Span::new(start, 0)
|
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)]
|
#[derive(Clone, Copy)]
|
||||||
|
|
|
@ -2027,11 +2027,50 @@ fn parse_signature(
|
||||||
Expression::Literal(Literal::String(st)) => {
|
Expression::Literal(Literal::String(st)) => {
|
||||||
let parts: Vec<_> = st.split(':').collect();
|
let parts: Vec<_> = st.split(':').collect();
|
||||||
if parts.len() == 1 {
|
if parts.len() == 1 {
|
||||||
|
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((
|
signature.positional.push((
|
||||||
PositionalType::Mandatory(parts[0].to_string(), SyntaxShape::Any),
|
PositionalType::Mandatory(parts[0].to_string(), SyntaxShape::Any),
|
||||||
String::new(),
|
String::new(),
|
||||||
));
|
));
|
||||||
|
}
|
||||||
} else if parts.len() == 2 {
|
} else if parts.len() == 2 {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
};
|
||||||
|
signature.named.insert(
|
||||||
|
flagname,
|
||||||
|
(NamedType::Optional(None, shape), String::new()),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Positional
|
||||||
let name = parts[0].to_string();
|
let name = parts[0].to_string();
|
||||||
let shape = match parts[1] {
|
let shape = match parts[1] {
|
||||||
"int" => SyntaxShape::Int,
|
"int" => SyntaxShape::Int,
|
||||||
|
@ -2057,6 +2096,7 @@ fn parse_signature(
|
||||||
signature
|
signature
|
||||||
.positional
|
.positional
|
||||||
.push((PositionalType::Mandatory(name, shape), String::new()));
|
.push((PositionalType::Mandatory(name, shape), String::new()));
|
||||||
|
}
|
||||||
} else if err.is_none() {
|
} else if err.is_none() {
|
||||||
err = Some(ParseError::mismatch("param with type", s.clone()));
|
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)
|
(output, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,30 @@ fn run_custom_command() {
|
||||||
assert_eq!(actual.out, "15");
|
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]
|
#[test]
|
||||||
fn set_variable() {
|
fn set_variable() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
|
|
Loading…
Reference in a new issue