mirror of
https://github.com/nushell/nushell.git
synced 2025-08-12 06:19:18 +02:00
Fix painting
This commit is contained in:
@ -524,6 +524,7 @@ impl Call {
|
||||
#[derive(new, Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Pipeline {
|
||||
crate commands: Vec<Expression>,
|
||||
crate trailing: Span,
|
||||
crate span: Span,
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,10 @@ pub fn baseline_parse_next_expr(
|
||||
vec![string],
|
||||
);
|
||||
let path = hir::RawExpression::Path(Box::new(path));
|
||||
Spanned { item: path, span: first.span }
|
||||
Spanned {
|
||||
item: path,
|
||||
span: first.span,
|
||||
}
|
||||
}
|
||||
Spanned {
|
||||
item: hir::RawExpression::Literal(hir::Literal::String(inner)),
|
||||
@ -114,7 +117,10 @@ pub fn baseline_parse_next_expr(
|
||||
vec![string],
|
||||
);
|
||||
let path = hir::RawExpression::Path(Box::new(path));
|
||||
Spanned { item: path, span: first.span }
|
||||
Spanned {
|
||||
item: path,
|
||||
span: first.span,
|
||||
}
|
||||
}
|
||||
Spanned {
|
||||
item: hir::RawExpression::Variable(..),
|
||||
@ -157,6 +163,7 @@ pub fn baseline_parse_semantic_token(
|
||||
TokenNode::Whitespace(_span) => unreachable!(),
|
||||
TokenNode::Error(error) => Err(*error.item.clone()),
|
||||
TokenNode::Path(_path) => unimplemented!(),
|
||||
TokenNode::EOF(_span) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ crate mod files;
|
||||
crate mod flag;
|
||||
crate mod operator;
|
||||
crate mod parser;
|
||||
crate mod pipeline;
|
||||
crate mod span;
|
||||
crate mod text;
|
||||
crate mod token_tree;
|
||||
@ -10,5 +11,3 @@ crate mod token_tree_builder;
|
||||
crate mod tokens;
|
||||
crate mod unit;
|
||||
crate mod util;
|
||||
|
||||
crate use token_tree::{PipelineElement, TokenNode};
|
||||
|
@ -1,8 +1,8 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use crate::parser::parse2::{
|
||||
call_node::*, flag::*, operator::*, span::*, token_tree::*, token_tree_builder::*, tokens::*,
|
||||
unit::*,
|
||||
call_node::*, flag::*, operator::*, pipeline::*, span::*, token_tree::*, token_tree_builder::*,
|
||||
tokens::*, unit::*,
|
||||
};
|
||||
use nom;
|
||||
use nom::branch::*;
|
||||
@ -429,34 +429,63 @@ pub fn node(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn eof(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
||||
if input.input_len() == 0 {
|
||||
Ok((input, TokenNode::EOF(Span::from(input))))
|
||||
} else {
|
||||
Err(Err::Error(error_position!(
|
||||
input,
|
||||
nom::error::ErrorKind::Eof
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
||||
trace_step(input, "pipeline", |input| {
|
||||
let start = input.offset;
|
||||
let (input, head) = tuple((raw_call, opt(space1)))(input)?;
|
||||
let (input, head) = opt(tuple((raw_call, opt(space1), opt(tag("|")))))(input)?;
|
||||
let (input, items) = trace_step(
|
||||
input,
|
||||
"many0",
|
||||
many0(tuple((tag("|"), opt(space1), raw_call, opt(space1)))),
|
||||
many0(tuple((opt(space1), raw_call, opt(space1), opt(tag("|"))))),
|
||||
)?;
|
||||
|
||||
let (input, tail) = tuple((opt(space1), eof))(input)?;
|
||||
let end = input.offset;
|
||||
|
||||
Ok((
|
||||
input,
|
||||
TokenTreeBuilder::spanned_pipeline(make_call_list(head, items), (start, end)),
|
||||
TokenTreeBuilder::spanned_pipeline(
|
||||
(make_call_list(head, items), tail.0.map(Span::from)),
|
||||
(start, end),
|
||||
),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn make_call_list(
|
||||
head: (Spanned<CallNode>, Option<NomSpan>),
|
||||
tail: Vec<(NomSpan, Option<NomSpan>, Spanned<CallNode>, Option<NomSpan>)>,
|
||||
head: Option<(Spanned<CallNode>, Option<NomSpan>, Option<NomSpan>)>,
|
||||
items: Vec<(
|
||||
Option<NomSpan>,
|
||||
Spanned<CallNode>,
|
||||
Option<NomSpan>,
|
||||
Option<NomSpan>,
|
||||
)>,
|
||||
) -> Vec<PipelineElement> {
|
||||
let mut out = vec![];
|
||||
let el = PipelineElement::new(None, head.0, head.1.map(Span::from));
|
||||
out.push(el);
|
||||
|
||||
for (pipe, ws1, call, ws2) in tail {
|
||||
let el = PipelineElement::new(ws1.map(Span::from), call, ws2.map(Span::from));
|
||||
if let Some(head) = head {
|
||||
let el = PipelineElement::new(None, head.0, head.1.map(Span::from), head.2.map(Span::from));
|
||||
out.push(el);
|
||||
}
|
||||
|
||||
for (ws1, call, ws2, pipe) in items {
|
||||
let el = PipelineElement::new(
|
||||
ws1.map(Span::from),
|
||||
call,
|
||||
ws2.map(Span::from),
|
||||
pipe.map(Span::from),
|
||||
);
|
||||
out.push(el);
|
||||
}
|
||||
|
||||
|
18
src/parser/parse2/pipeline.rs
Normal file
18
src/parser/parse2/pipeline.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::parser::{CallNode, Span, Spanned};
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, new)]
|
||||
pub struct Pipeline {
|
||||
crate parts: Vec<PipelineElement>,
|
||||
crate post_ws: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
|
||||
pub struct PipelineElement {
|
||||
pub pre_ws: Option<Span>,
|
||||
#[get = "crate"]
|
||||
call: Spanned<CallNode>,
|
||||
pub post_ws: Option<Span>,
|
||||
pub post_pipe: Option<Span>,
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
use crate::errors::ShellError;
|
||||
use crate::parser::parse2::{call_node::*, flag::*, operator::*, span::*, tokens::*};
|
||||
use crate::parser::parse2::{call_node::*, flag::*, operator::*, pipeline::*, span::*, tokens::*};
|
||||
use crate::Text;
|
||||
use derive_new::new;
|
||||
use enum_utils::FromStr;
|
||||
use getset::Getters;
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum TokenNode {
|
||||
@ -11,7 +10,7 @@ pub enum TokenNode {
|
||||
#[allow(unused)]
|
||||
Call(Spanned<CallNode>),
|
||||
Delimited(Spanned<DelimitedNode>),
|
||||
Pipeline(Spanned<Vec<PipelineElement>>),
|
||||
Pipeline(Spanned<Pipeline>),
|
||||
Operator(Spanned<Operator>),
|
||||
Flag(Spanned<Flag>),
|
||||
Identifier(Span),
|
||||
@ -19,6 +18,7 @@ pub enum TokenNode {
|
||||
#[allow(unused)]
|
||||
Error(Spanned<Box<ShellError>>),
|
||||
Path(Spanned<PathNode>),
|
||||
EOF(Span),
|
||||
}
|
||||
|
||||
impl TokenNode {
|
||||
@ -34,6 +34,7 @@ impl TokenNode {
|
||||
TokenNode::Whitespace(s) => *s,
|
||||
TokenNode::Error(s) => s.span,
|
||||
TokenNode::Path(s) => s.span,
|
||||
TokenNode::EOF(s) => *s,
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +67,7 @@ impl TokenNode {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_pipeline(&self) -> Result<Vec<PipelineElement>, ShellError> {
|
||||
pub fn as_pipeline(&self) -> Result<Pipeline, ShellError> {
|
||||
match self {
|
||||
TokenNode::Pipeline(Spanned { item, .. }) => Ok(item.clone()),
|
||||
_ => Err(ShellError::string("unimplemented")),
|
||||
@ -92,11 +93,3 @@ pub struct PathNode {
|
||||
head: Box<TokenNode>,
|
||||
tail: Vec<TokenNode>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
|
||||
pub struct PipelineElement {
|
||||
pub pre_ws: Option<Span>,
|
||||
#[get = "crate"]
|
||||
call: Spanned<CallNode>,
|
||||
pub post_ws: Option<Span>,
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ use crate::prelude::*;
|
||||
|
||||
use crate::parser::parse2::flag::{Flag, FlagKind};
|
||||
use crate::parser::parse2::operator::Operator;
|
||||
use crate::parser::parse2::pipeline::{Pipeline, PipelineElement};
|
||||
use crate::parser::parse2::span::{Span, Spanned};
|
||||
use crate::parser::parse2::token_tree::{
|
||||
DelimitedNode, Delimiter, PathNode, PipelineElement, TokenNode,
|
||||
};
|
||||
use crate::parser::parse2::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode};
|
||||
use crate::parser::parse2::tokens::{RawToken, Token};
|
||||
use crate::parser::parse2::unit::Unit;
|
||||
use crate::parser::CallNode;
|
||||
@ -47,7 +46,7 @@ impl TokenTreeBuilder {
|
||||
|
||||
let mut out: Vec<PipelineElement> = vec![];
|
||||
|
||||
let mut input = input.into_iter();
|
||||
let mut input = input.into_iter().peekable();
|
||||
let (pre, call, post) = input
|
||||
.next()
|
||||
.expect("A pipeline must contain at least one element");
|
||||
@ -55,33 +54,48 @@ impl TokenTreeBuilder {
|
||||
let pre_span = pre.map(|pre| b.consume(&pre));
|
||||
let call = call(b);
|
||||
let post_span = post.map(|post| b.consume(&post));
|
||||
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
|
||||
out.push(PipelineElement::new(
|
||||
pre_span.map(Span::from),
|
||||
call,
|
||||
post_span.map(Span::from),
|
||||
pipe,
|
||||
));
|
||||
|
||||
for (pre, call, post) in input {
|
||||
b.consume("|");
|
||||
let pre_span = pre.map(|pre| b.consume(&pre));
|
||||
let call = call(b);
|
||||
let post_span = post.map(|post| b.consume(&post));
|
||||
loop {
|
||||
match input.next() {
|
||||
None => break,
|
||||
Some((pre, call, post)) => {
|
||||
let pre_span = pre.map(|pre| b.consume(&pre));
|
||||
let call = call(b);
|
||||
let post_span = post.map(|post| b.consume(&post));
|
||||
|
||||
out.push(PipelineElement::new(
|
||||
pre_span.map(Span::from),
|
||||
call,
|
||||
post_span.map(Span::from),
|
||||
));
|
||||
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
|
||||
|
||||
out.push(PipelineElement::new(
|
||||
pre_span.map(Span::from),
|
||||
call,
|
||||
post_span.map(Span::from),
|
||||
pipe,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let end = b.pos;
|
||||
|
||||
TokenTreeBuilder::spanned_pipeline(out, (start, end))
|
||||
TokenTreeBuilder::spanned_pipeline((out, None), (start, end))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn spanned_pipeline(input: Vec<PipelineElement>, span: impl Into<Span>) -> TokenNode {
|
||||
TokenNode::Pipeline(Spanned::from_item(input, span))
|
||||
pub fn spanned_pipeline(
|
||||
input: (Vec<PipelineElement>, Option<Span>),
|
||||
span: impl Into<Span>,
|
||||
) -> TokenNode {
|
||||
TokenNode::Pipeline(Spanned::from_item(
|
||||
Pipeline::new(input.0, input.1.into()),
|
||||
span,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn op(input: impl Into<Operator>) -> CurriedToken {
|
||||
|
Reference in New Issue
Block a user