Pipeline operators: && and || (#7448)

# Description

We got some feedback from folks used to other shells that `try/catch`
isn't quite as convenient as things like `||`. This PR adds `&&` as a
synonym for `;` and `||` as equivalent to what `try/catch` would do.

# User-Facing Changes

Adds `&&` and `||` pipeline operators.

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
JT
2022-12-13 09:53:46 +13:00
committed by GitHub
parent 7917cf9f00
commit 35bea5e044
12 changed files with 320 additions and 179 deletions

View File

@ -14,7 +14,6 @@ pub enum Redirection {
pub enum PipelineElement {
Expression(Option<Span>, Expression),
Redirection(Span, Redirection, Expression),
And(Span, Expression),
Or(Span, Expression),
}
@ -23,9 +22,8 @@ impl PipelineElement {
match self {
PipelineElement::Expression(None, expression) => expression.span,
PipelineElement::Expression(Some(span), expression)
| PipelineElement::Redirection(span, _, expression)
| PipelineElement::And(span, expression)
| PipelineElement::Or(span, expression) => Span {
| PipelineElement::Or(span, expression)
| PipelineElement::Redirection(span, _, expression) => Span {
start: span.start,
end: expression.span.end,
},
@ -35,7 +33,6 @@ impl PipelineElement {
match self {
PipelineElement::Expression(_, expression)
| PipelineElement::Redirection(_, _, expression)
| PipelineElement::And(_, expression)
| PipelineElement::Or(_, expression) => expression.has_in_variable(working_set),
}
}
@ -43,9 +40,8 @@ impl PipelineElement {
pub fn replace_in_variable(&mut self, working_set: &mut StateWorkingSet, new_var_id: VarId) {
match self {
PipelineElement::Expression(_, expression)
| PipelineElement::Redirection(_, _, expression)
| PipelineElement::And(_, expression)
| PipelineElement::Or(_, expression) => {
| PipelineElement::Or(_, expression)
| PipelineElement::Redirection(_, _, expression) => {
expression.replace_in_variable(working_set, new_var_id)
}
}
@ -59,9 +55,8 @@ impl PipelineElement {
) {
match self {
PipelineElement::Expression(_, expression)
| PipelineElement::Redirection(_, _, expression)
| PipelineElement::And(_, expression)
| PipelineElement::Or(_, expression) => {
| PipelineElement::Or(_, expression)
| PipelineElement::Redirection(_, _, expression) => {
expression.replace_span(working_set, replaced, new_span)
}
}

View File

@ -113,6 +113,13 @@ impl Stack {
.ok_or_else(|| ShellError::NushellFailed("No active overlay".into()))
}
pub fn last_exit_code(&self, engine_state: &EngineState) -> Option<i64> {
match self.get_env_var(engine_state, "LAST_EXIT_CODE") {
Some(Value::Int { val, .. }) => Some(val),
_ => None,
}
}
pub fn captures_to_stack(&self, captures: &HashMap<VarId, Value>) -> Stack {
// FIXME: this is probably slow
let mut env_vars = self.env_vars.clone();