forked from extern/nushell
Merge pull request #596 from Porges/improve-pipeline-parsing
Improve parsing of pipelines, require pipes between segments
This commit is contained in:
commit
fd715e1775
@ -552,11 +552,11 @@ pub fn node(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
||||
pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
||||
trace_step(input, "pipeline", |input| {
|
||||
let start = input.offset;
|
||||
let (input, head) = opt(tuple((raw_call, opt(space1), opt(tag("|")))))(input)?;
|
||||
let (input, head) = opt(tuple((opt(space1), raw_call, opt(space1))))(input)?;
|
||||
let (input, items) = trace_step(
|
||||
input,
|
||||
"many0",
|
||||
many0(tuple((opt(space1), raw_call, opt(space1), opt(tag("|"))))),
|
||||
many0(tuple((tag("|"), opt(space1), raw_call, opt(space1)))),
|
||||
)?;
|
||||
|
||||
let (input, tail) = opt(space1)(input)?;
|
||||
@ -582,28 +582,37 @@ pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
||||
}
|
||||
|
||||
fn make_call_list(
|
||||
head: Option<(Tagged<CallNode>, Option<NomSpan>, Option<NomSpan>)>,
|
||||
items: Vec<(
|
||||
head: Option<(
|
||||
Option<NomSpan>,
|
||||
Tagged<CallNode>,
|
||||
Option<NomSpan>
|
||||
)>,
|
||||
items: Vec<(
|
||||
NomSpan,
|
||||
Option<NomSpan>,
|
||||
Tagged<CallNode>,
|
||||
Option<NomSpan>,
|
||||
)>,
|
||||
) -> Vec<PipelineElement> {
|
||||
let mut out = vec![];
|
||||
|
||||
if let Some(head) = head {
|
||||
let el = PipelineElement::new(None, head.0, head.1.map(Span::from), head.2.map(Span::from));
|
||||
let el = PipelineElement::new(
|
||||
None,
|
||||
head.0.map(Span::from),
|
||||
head.1,
|
||||
head.2.map(Span::from));
|
||||
|
||||
out.push(el);
|
||||
}
|
||||
|
||||
for (ws1, call, ws2, pipe) in items {
|
||||
for (pipe, ws1, call, ws2) in items {
|
||||
let el = PipelineElement::new(
|
||||
Some(pipe).map(Span::from),
|
||||
ws1.map(Span::from),
|
||||
call,
|
||||
ws2.map(Span::from),
|
||||
pipe.map(Span::from),
|
||||
);
|
||||
ws2.map(Span::from));
|
||||
|
||||
out.push(el);
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,9 @@ pub struct Pipeline {
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
|
||||
pub struct PipelineElement {
|
||||
pub pipe: Option<Span>,
|
||||
pub pre_ws: Option<Span>,
|
||||
#[get = "pub(crate)"]
|
||||
call: Tagged<CallNode>,
|
||||
pub post_ws: Option<Span>,
|
||||
pub post_pipe: Option<Span>,
|
||||
}
|
||||
|
@ -47,32 +47,31 @@ impl TokenTreeBuilder {
|
||||
.next()
|
||||
.expect("A pipeline must contain at least one element");
|
||||
|
||||
let pipe = None;
|
||||
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(
|
||||
pipe,
|
||||
pre_span.map(Span::from),
|
||||
call,
|
||||
post_span.map(Span::from),
|
||||
pipe,
|
||||
));
|
||||
post_span.map(Span::from)));
|
||||
|
||||
loop {
|
||||
match input.next() {
|
||||
None => break,
|
||||
Some((pre, call, post)) => {
|
||||
let pipe = Some(Span::from(b.consume("|")));
|
||||
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(
|
||||
pipe,
|
||||
pre_span.map(Span::from),
|
||||
call,
|
||||
post_span.map(Span::from),
|
||||
pipe,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +147,10 @@ fn paint_token_node(token_node: &TokenNode, line: &str) -> String {
|
||||
fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> String {
|
||||
let mut styled = String::new();
|
||||
|
||||
if let Some(_) = pipeline_element.pipe {
|
||||
styled.push_str(&Color::Purple.paint("|"));
|
||||
}
|
||||
|
||||
if let Some(ws) = pipeline_element.pre_ws {
|
||||
styled.push_str(&Color::White.normal().paint(ws.slice(line)));
|
||||
}
|
||||
@ -168,10 +172,6 @@ fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> Str
|
||||
styled.push_str(&Color::White.normal().paint(ws.slice(line)));
|
||||
}
|
||||
|
||||
if let Some(_) = pipeline_element.post_pipe {
|
||||
styled.push_str(&Color::Purple.paint("|"));
|
||||
}
|
||||
|
||||
styled.to_string()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user