mirror of
https://github.com/nushell/nushell.git
synced 2025-04-08 20:08:20 +02:00
Relax the closure syntax, highlight differently (#8846)
# Description This relaxes the closure syntax so that `||` is no longer required. This allows for `ls | each { $in.name }` for example. I've gone ahead and changed the syntax highlighting so that blocks and closures are distinct for now. # User-Facing Changes Removes `||` requirement for closures. # 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 - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` # 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:
parent
46dba8853a
commit
8ee52b6ee1
@ -111,6 +111,9 @@ impl Highlighter for NuHighlighter {
|
|||||||
FlatShape::Block => {
|
FlatShape::Block => {
|
||||||
add_colored_token_with_bracket_highlight!(shape.1, shape.0, next_token)
|
add_colored_token_with_bracket_highlight!(shape.1, shape.0, next_token)
|
||||||
}
|
}
|
||||||
|
FlatShape::Closure => {
|
||||||
|
add_colored_token_with_bracket_highlight!(shape.1, shape.0, next_token)
|
||||||
|
}
|
||||||
|
|
||||||
FlatShape::Filepath => add_colored_token(&shape.1, next_token),
|
FlatShape::Filepath => add_colored_token(&shape.1, next_token),
|
||||||
FlatShape::Directory => add_colored_token(&shape.1, next_token),
|
FlatShape::Directory => add_colored_token(&shape.1, next_token),
|
||||||
|
@ -9,6 +9,7 @@ pub fn default_shape_color(shape: String) -> Style {
|
|||||||
"shape_binary" => Style::new().fg(Color::Purple).bold(),
|
"shape_binary" => Style::new().fg(Color::Purple).bold(),
|
||||||
"shape_block" => Style::new().fg(Color::Blue).bold(),
|
"shape_block" => Style::new().fg(Color::Blue).bold(),
|
||||||
"shape_bool" => Style::new().fg(Color::LightCyan),
|
"shape_bool" => Style::new().fg(Color::LightCyan),
|
||||||
|
"shape_closure" => Style::new().fg(Color::Green).bold(),
|
||||||
"shape_custom" => Style::new().fg(Color::Green),
|
"shape_custom" => Style::new().fg(Color::Green),
|
||||||
"shape_datetime" => Style::new().fg(Color::Cyan).bold(),
|
"shape_datetime" => Style::new().fg(Color::Cyan).bold(),
|
||||||
"shape_directory" => Style::new().fg(Color::Cyan),
|
"shape_directory" => Style::new().fg(Color::Cyan),
|
||||||
|
@ -12,6 +12,7 @@ pub enum FlatShape {
|
|||||||
Binary,
|
Binary,
|
||||||
Block,
|
Block,
|
||||||
Bool,
|
Bool,
|
||||||
|
Closure,
|
||||||
Custom(DeclId),
|
Custom(DeclId),
|
||||||
DateTime,
|
DateTime,
|
||||||
Directory,
|
Directory,
|
||||||
@ -50,6 +51,7 @@ impl Display for FlatShape {
|
|||||||
FlatShape::Binary => write!(f, "shape_binary"),
|
FlatShape::Binary => write!(f, "shape_binary"),
|
||||||
FlatShape::Block => write!(f, "shape_block"),
|
FlatShape::Block => write!(f, "shape_block"),
|
||||||
FlatShape::Bool => write!(f, "shape_bool"),
|
FlatShape::Bool => write!(f, "shape_bool"),
|
||||||
|
FlatShape::Closure => write!(f, "shape_closure"),
|
||||||
FlatShape::Custom(_) => write!(f, "shape_custom"),
|
FlatShape::Custom(_) => write!(f, "shape_custom"),
|
||||||
FlatShape::DateTime => write!(f, "shape_datetime"),
|
FlatShape::DateTime => write!(f, "shape_datetime"),
|
||||||
FlatShape::Directory => write!(f, "shape_directory"),
|
FlatShape::Directory => write!(f, "shape_directory"),
|
||||||
@ -85,6 +87,7 @@ impl Display for FlatShape {
|
|||||||
|
|
||||||
pub fn flatten_block(working_set: &StateWorkingSet, block: &Block) -> Vec<(Span, FlatShape)> {
|
pub fn flatten_block(working_set: &StateWorkingSet, block: &Block) -> Vec<(Span, FlatShape)> {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
for pipeline in &block.pipelines {
|
for pipeline in &block.pipelines {
|
||||||
output.extend(flatten_pipeline(working_set, pipeline));
|
output.extend(flatten_pipeline(working_set, pipeline));
|
||||||
}
|
}
|
||||||
@ -115,10 +118,41 @@ pub fn flatten_expression(
|
|||||||
output.extend(flatten_expression(working_set, inner_expr));
|
output.extend(flatten_expression(working_set, inner_expr));
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
Expr::Block(block_id)
|
Expr::Closure(block_id) => {
|
||||||
| Expr::Closure(block_id)
|
let outer_span = expr.span;
|
||||||
| Expr::RowCondition(block_id)
|
|
||||||
| Expr::Subexpression(block_id) => {
|
let mut output = vec![];
|
||||||
|
|
||||||
|
let block = working_set.get_block(*block_id);
|
||||||
|
let flattened = flatten_block(working_set, block);
|
||||||
|
|
||||||
|
if let Some(first) = flattened.first() {
|
||||||
|
if first.0.start > outer_span.start {
|
||||||
|
output.push((
|
||||||
|
Span::new(outer_span.start, first.0.start),
|
||||||
|
FlatShape::Closure,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let last = if let Some(last) = flattened.last() {
|
||||||
|
if last.0.end < outer_span.end {
|
||||||
|
Some((Span::new(last.0.end, outer_span.end), FlatShape::Closure))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
output.extend(flattened);
|
||||||
|
if let Some(last) = last {
|
||||||
|
output.push(last)
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
Expr::Block(block_id) | Expr::RowCondition(block_id) | Expr::Subexpression(block_id) => {
|
||||||
let outer_span = expr.span;
|
let outer_span = expr.span;
|
||||||
|
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
@ -149,14 +183,23 @@ pub fn flatten_expression(
|
|||||||
output
|
output
|
||||||
}
|
}
|
||||||
Expr::Call(call) => {
|
Expr::Call(call) => {
|
||||||
let mut output = vec![(call.head, FlatShape::InternalCall(call.decl_id))];
|
let mut output = vec![];
|
||||||
|
|
||||||
|
if call.head.end != 0 {
|
||||||
|
// Make sure we don't push synthetic calls
|
||||||
|
output.push((call.head, FlatShape::InternalCall(call.decl_id)));
|
||||||
|
}
|
||||||
|
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
for positional in call.positional_iter() {
|
for positional in call.positional_iter() {
|
||||||
args.extend(flatten_expression(working_set, positional));
|
let flattened = flatten_expression(working_set, positional);
|
||||||
|
args.extend(flattened);
|
||||||
}
|
}
|
||||||
for named in call.named_iter() {
|
for named in call.named_iter() {
|
||||||
|
if named.0.span.end != 0 {
|
||||||
|
// Ignore synthetic flags
|
||||||
args.push((named.0.span, FlatShape::Flag));
|
args.push((named.0.span, FlatShape::Flag));
|
||||||
|
}
|
||||||
if let Some(expr) = &named.2 {
|
if let Some(expr) = &named.2 {
|
||||||
args.extend(flatten_expression(working_set, expr));
|
args.extend(flatten_expression(working_set, expr));
|
||||||
}
|
}
|
||||||
|
@ -1589,10 +1589,8 @@ pub fn parse_brace_expr(
|
|||||||
|
|
||||||
if matches!(second_token, None) {
|
if matches!(second_token, None) {
|
||||||
// If we're empty, that means an empty record or closure
|
// If we're empty, that means an empty record or closure
|
||||||
if matches!(shape, SyntaxShape::Closure(None)) {
|
if matches!(shape, SyntaxShape::Closure(_)) {
|
||||||
parse_closure_expression(working_set, shape, span, false)
|
parse_closure_expression(working_set, shape, span)
|
||||||
} else if matches!(shape, SyntaxShape::Closure(Some(_))) {
|
|
||||||
parse_closure_expression(working_set, shape, span, true)
|
|
||||||
} else if matches!(shape, SyntaxShape::Block) {
|
} else if matches!(shape, SyntaxShape::Block) {
|
||||||
parse_block_expression(working_set, span)
|
parse_block_expression(working_set, span)
|
||||||
} else if matches!(shape, SyntaxShape::MatchBlock) {
|
} else if matches!(shape, SyntaxShape::MatchBlock) {
|
||||||
@ -1603,13 +1601,11 @@ pub fn parse_brace_expr(
|
|||||||
} else if matches!(second_token_contents, Some(TokenContents::Pipe))
|
} else if matches!(second_token_contents, Some(TokenContents::Pipe))
|
||||||
|| matches!(second_token_contents, Some(TokenContents::PipePipe))
|
|| matches!(second_token_contents, Some(TokenContents::PipePipe))
|
||||||
{
|
{
|
||||||
parse_closure_expression(working_set, shape, span, true)
|
parse_closure_expression(working_set, shape, span)
|
||||||
} else if matches!(third_token, Some(b":")) {
|
} else if matches!(third_token, Some(b":")) {
|
||||||
parse_full_cell_path(working_set, None, span)
|
parse_full_cell_path(working_set, None, span)
|
||||||
} else if matches!(shape, SyntaxShape::Closure(None)) {
|
} else if matches!(shape, SyntaxShape::Closure(_)) || matches!(shape, SyntaxShape::Any) {
|
||||||
parse_closure_expression(working_set, shape, span, false)
|
parse_closure_expression(working_set, shape, span)
|
||||||
} else if matches!(shape, SyntaxShape::Closure(Some(_))) || matches!(shape, SyntaxShape::Any) {
|
|
||||||
parse_closure_expression(working_set, shape, span, true)
|
|
||||||
} else if matches!(shape, SyntaxShape::Block) {
|
} else if matches!(shape, SyntaxShape::Block) {
|
||||||
parse_block_expression(working_set, span)
|
parse_block_expression(working_set, span)
|
||||||
} else if matches!(shape, SyntaxShape::MatchBlock) {
|
} else if matches!(shape, SyntaxShape::MatchBlock) {
|
||||||
@ -4201,7 +4197,6 @@ pub fn parse_closure_expression(
|
|||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
shape: &SyntaxShape,
|
shape: &SyntaxShape,
|
||||||
span: Span,
|
span: Span,
|
||||||
require_pipe: bool,
|
|
||||||
) -> Expression {
|
) -> Expression {
|
||||||
trace!("parsing: closure expression");
|
trace!("parsing: closure expression");
|
||||||
|
|
||||||
@ -4275,15 +4270,7 @@ pub fn parse_closure_expression(
|
|||||||
Some((Box::new(Signature::new("closure".to_string())), *span)),
|
Some((Box::new(Signature::new("closure".to_string())), *span)),
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
_ => {
|
_ => (None, 0),
|
||||||
if require_pipe {
|
|
||||||
working_set.error(ParseError::ClosureMissingPipe(span));
|
|
||||||
working_set.exit_scope();
|
|
||||||
return garbage(span);
|
|
||||||
} else {
|
|
||||||
(None, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Finish this
|
// TODO: Finish this
|
||||||
|
@ -38,13 +38,6 @@ pub enum ParseError {
|
|||||||
#[diagnostic(code(nu::parser::parse_mismatch))]
|
#[diagnostic(code(nu::parser::parse_mismatch))]
|
||||||
Expected(String, #[label("expected {0}")] Span),
|
Expected(String, #[label("expected {0}")] Span),
|
||||||
|
|
||||||
#[error("Missing || inside closure")]
|
|
||||||
#[diagnostic(
|
|
||||||
code(nu::parser::closure_missing_pipe),
|
|
||||||
help("Try add || to the beginning of closure")
|
|
||||||
)]
|
|
||||||
ClosureMissingPipe(#[label("Parsing as a closure, but || is missing")] Span),
|
|
||||||
|
|
||||||
#[error("Type mismatch during operation.")]
|
#[error("Type mismatch during operation.")]
|
||||||
#[diagnostic(code(nu::parser::type_mismatch))]
|
#[diagnostic(code(nu::parser::type_mismatch))]
|
||||||
Mismatch(String, String, #[label("expected {0}, found {1}")] Span), // expected, found, span
|
Mismatch(String, String, #[label("expected {0}, found {1}")] Span), // expected, found, span
|
||||||
@ -510,7 +503,6 @@ impl ParseError {
|
|||||||
ParseError::UnknownOperator(_, _, s) => *s,
|
ParseError::UnknownOperator(_, _, s) => *s,
|
||||||
ParseError::InvalidLiteral(_, _, s) => *s,
|
ParseError::InvalidLiteral(_, _, s) => *s,
|
||||||
ParseError::NotAConstant(s) => *s,
|
ParseError::NotAConstant(s) => *s,
|
||||||
ParseError::ClosureMissingPipe(s) => *s,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ let dark_theme = {
|
|||||||
shape_binary: purple_bold
|
shape_binary: purple_bold
|
||||||
shape_block: blue_bold
|
shape_block: blue_bold
|
||||||
shape_bool: light_cyan
|
shape_bool: light_cyan
|
||||||
|
shape_closure: green_bold
|
||||||
shape_custom: green
|
shape_custom: green
|
||||||
shape_datetime: cyan_bold
|
shape_datetime: cyan_bold
|
||||||
shape_directory: cyan
|
shape_directory: cyan
|
||||||
@ -140,6 +141,7 @@ let light_theme = {
|
|||||||
shape_binary: purple_bold
|
shape_binary: purple_bold
|
||||||
shape_block: blue_bold
|
shape_block: blue_bold
|
||||||
shape_bool: light_cyan
|
shape_bool: light_cyan
|
||||||
|
shape_closure: green_bold
|
||||||
shape_custom: green
|
shape_custom: green
|
||||||
shape_datetime: cyan_bold
|
shape_datetime: cyan_bold
|
||||||
shape_directory: cyan
|
shape_directory: cyan
|
||||||
|
Loading…
Reference in New Issue
Block a user