2020-04-13 07:59:57 +00:00
|
|
|
use nu_protocol::hir::*;
|
2020-04-06 07:16:14 +00:00
|
|
|
use nu_protocol::UnspannedPathMember;
|
|
|
|
use nu_source::{Spanned, SpannedItem};
|
|
|
|
|
|
|
|
/// Converts a SpannedExpression into a spanned shape(s) ready for color-highlighting
|
|
|
|
pub fn expression_to_flat_shape(e: &SpannedExpression) -> Vec<Spanned<FlatShape>> {
|
|
|
|
match &e.expr {
|
2020-04-13 07:59:57 +00:00
|
|
|
Expression::Block(exprs) => shapes(exprs),
|
2020-05-16 03:18:24 +00:00
|
|
|
Expression::Invocation(exprs) => shapes(exprs),
|
2020-04-06 07:16:14 +00:00
|
|
|
Expression::FilePath(_) => vec![FlatShape::Path.spanned(e.span)],
|
|
|
|
Expression::Garbage => vec![FlatShape::Garbage.spanned(e.span)],
|
|
|
|
Expression::List(exprs) => {
|
|
|
|
let mut output = vec![];
|
|
|
|
for expr in exprs.iter() {
|
|
|
|
output.append(&mut expression_to_flat_shape(expr));
|
|
|
|
}
|
|
|
|
output
|
|
|
|
}
|
2020-08-30 04:55:33 +00:00
|
|
|
Expression::Table(headers, cells) => {
|
|
|
|
let mut output = vec![];
|
|
|
|
for header in headers.iter() {
|
|
|
|
output.append(&mut expression_to_flat_shape(header));
|
|
|
|
}
|
|
|
|
for row in cells {
|
|
|
|
for cell in row {
|
|
|
|
output.append(&mut expression_to_flat_shape(&cell));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
output
|
|
|
|
}
|
2020-04-06 07:16:14 +00:00
|
|
|
Expression::Path(exprs) => {
|
|
|
|
let mut output = vec![];
|
|
|
|
output.append(&mut expression_to_flat_shape(&exprs.head));
|
|
|
|
for member in exprs.tail.iter() {
|
|
|
|
if let UnspannedPathMember::String(_) = &member.unspanned {
|
|
|
|
output.push(FlatShape::StringMember.spanned(member.span));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
output
|
|
|
|
}
|
2020-08-25 01:47:58 +00:00
|
|
|
Expression::Command => vec![FlatShape::InternalCommand.spanned(e.span)],
|
2020-04-10 07:56:48 +00:00
|
|
|
Expression::Literal(Literal::Bare(_)) => vec![FlatShape::BareMember.spanned(e.span)],
|
2020-04-06 07:16:14 +00:00
|
|
|
Expression::Literal(Literal::ColumnPath(_)) => vec![FlatShape::Path.spanned(e.span)],
|
|
|
|
Expression::Literal(Literal::GlobPattern(_)) => {
|
|
|
|
vec![FlatShape::GlobPattern.spanned(e.span)]
|
|
|
|
}
|
|
|
|
Expression::Literal(Literal::Number(_)) => vec![FlatShape::Int.spanned(e.span)],
|
2020-04-18 01:50:58 +00:00
|
|
|
Expression::Literal(Literal::Operator(_)) => vec![FlatShape::Operator.spanned(e.span)],
|
2020-04-06 07:16:14 +00:00
|
|
|
Expression::Literal(Literal::Size(number, unit)) => vec![FlatShape::Size {
|
|
|
|
number: number.span,
|
|
|
|
unit: unit.span,
|
|
|
|
}
|
|
|
|
.spanned(e.span)],
|
|
|
|
Expression::Literal(Literal::String(_)) => vec![FlatShape::String.spanned(e.span)],
|
|
|
|
Expression::ExternalWord => vec![FlatShape::ExternalWord.spanned(e.span)],
|
|
|
|
Expression::ExternalCommand(_) => vec![FlatShape::ExternalCommand.spanned(e.span)],
|
|
|
|
Expression::Synthetic(_) => vec![FlatShape::BareMember.spanned(e.span)],
|
2020-10-26 06:55:52 +00:00
|
|
|
Expression::Variable(_, _) => vec![FlatShape::Variable.spanned(e.span)],
|
2020-04-06 07:16:14 +00:00
|
|
|
Expression::Binary(binary) => {
|
|
|
|
let mut output = vec![];
|
|
|
|
output.append(&mut expression_to_flat_shape(&binary.left));
|
2020-04-18 01:50:58 +00:00
|
|
|
output.push(FlatShape::Operator.spanned(binary.op.span));
|
2020-04-06 07:16:14 +00:00
|
|
|
output.append(&mut expression_to_flat_shape(&binary.right));
|
|
|
|
output
|
|
|
|
}
|
|
|
|
Expression::Range(range) => {
|
|
|
|
let mut output = vec![];
|
2020-09-07 02:43:58 +00:00
|
|
|
if let Some(left) = &range.left {
|
|
|
|
output.append(&mut expression_to_flat_shape(left));
|
|
|
|
}
|
2020-09-13 21:53:08 +00:00
|
|
|
output.push(
|
|
|
|
match &range.operator.item {
|
|
|
|
RangeOperator::Inclusive => FlatShape::DotDot,
|
|
|
|
RangeOperator::RightExclusive => FlatShape::DotDotLeftAngleBracket,
|
|
|
|
}
|
|
|
|
.spanned(&range.operator.span),
|
|
|
|
);
|
2020-09-07 02:43:58 +00:00
|
|
|
if let Some(right) = &range.right {
|
|
|
|
output.append(&mut expression_to_flat_shape(right));
|
|
|
|
}
|
2020-04-06 07:16:14 +00:00
|
|
|
output
|
|
|
|
}
|
|
|
|
Expression::Boolean(_) => vec![FlatShape::Keyword.spanned(e.span)],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts a series of commands into a vec of spanned shapes ready for color-highlighting
|
2020-04-20 06:41:51 +00:00
|
|
|
pub fn shapes(commands: &Block) -> Vec<Spanned<FlatShape>> {
|
2020-04-06 07:16:14 +00:00
|
|
|
let mut output = vec![];
|
|
|
|
|
2020-12-18 07:53:49 +00:00
|
|
|
for group in &commands.block {
|
|
|
|
for pipeline in &group.pipelines {
|
|
|
|
for command in &pipeline.list {
|
|
|
|
match command {
|
|
|
|
ClassifiedCommand::Internal(internal) => {
|
|
|
|
output.append(&mut expression_to_flat_shape(&internal.args.head));
|
2020-04-06 07:16:14 +00:00
|
|
|
|
2020-12-18 07:53:49 +00:00
|
|
|
if let Some(positionals) = &internal.args.positional {
|
|
|
|
for positional_arg in positionals {
|
|
|
|
output.append(&mut expression_to_flat_shape(positional_arg));
|
|
|
|
}
|
2020-04-20 06:41:51 +00:00
|
|
|
}
|
2020-04-06 07:16:14 +00:00
|
|
|
|
2020-12-18 07:53:49 +00:00
|
|
|
if let Some(named) = &internal.args.named {
|
|
|
|
for (_, named_arg) in named.iter() {
|
|
|
|
match named_arg {
|
|
|
|
NamedValue::PresentSwitch(span) => {
|
|
|
|
output.push(FlatShape::Flag.spanned(*span));
|
|
|
|
}
|
|
|
|
NamedValue::Value(span, expr) => {
|
|
|
|
output.push(FlatShape::Flag.spanned(*span));
|
|
|
|
output.append(&mut expression_to_flat_shape(expr));
|
|
|
|
}
|
|
|
|
_ => {}
|
2020-04-20 06:41:51 +00:00
|
|
|
}
|
2020-04-06 07:16:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-18 07:53:49 +00:00
|
|
|
ClassifiedCommand::Expr(expr) => {
|
|
|
|
output.append(&mut expression_to_flat_shape(expr))
|
|
|
|
}
|
|
|
|
_ => {}
|
2020-04-06 07:16:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
output
|
|
|
|
}
|