Skip to content

Commit 301ad29

Browse files
authored
Partially collapse blank lines between items (#3274)
1 parent a77f1bc commit 301ad29

8 files changed

Lines changed: 289 additions & 285 deletions

File tree

src/analyzer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ impl<'run, 'src> Analyzer<'run, 'src> {
9898
)?);
9999
}
100100
}
101+
Item::Newline => {}
101102
Item::Recipe(recipe) => {
102103
if recipe.enabled() {
103104
Self::analyze_recipe(recipe)?;

src/ast.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,19 @@ pub(crate) struct Ast<'src> {
1414

1515
impl ColorDisplay for Ast<'_> {
1616
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
17-
let mut iter = self.items.iter().peekable();
18-
19-
while let Some(item) = iter.next() {
20-
writeln!(f, "{}", item.color_display(color))?;
17+
let mut newline = false;
18+
for item in &self.items {
19+
if matches!(item, Item::Newline) {
20+
newline = true;
21+
continue;
22+
}
2123

22-
if let Some(next_item) = iter.peek() {
23-
if matches!(item, Item::Recipe(_))
24-
|| mem::discriminant(item) != mem::discriminant(next_item)
25-
{
26-
writeln!(f)?;
27-
}
24+
if newline {
25+
writeln!(f)?;
26+
newline = false;
2827
}
28+
29+
writeln!(f, "{}", item.color_display(color))?;
2930
}
3031

3132
Ok(())

src/item.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub(crate) enum Item<'src> {
2121
private: bool,
2222
relative: Option<StringLiteral<'src>>,
2323
},
24+
Newline,
2425
Recipe(UnresolvedRecipe<'src>),
2526
Set(Set<'src>),
2627
Unexport {
@@ -85,6 +86,7 @@ impl ColorDisplay for Item<'_> {
8586

8687
Ok(())
8788
}
89+
Self::Newline => Ok(()),
8890
Self::Recipe(recipe) => write!(f, "{}", recipe.color_display(color)),
8991
Self::Set(set) => write!(f, "{set}"),
9092
Self::Unexport { name } => write!(f, "unexport {name}"),

src/lexer.rs

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use {super::*, CompileErrorKind::*, TokenKind::*};
22

3+
static DEDENT_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[ \t\n]*\n[^ \t\n]").unwrap());
4+
35
/// Just language lexer
46
///
57
/// The lexer proceeds character-by-character, as opposed to using regular
@@ -391,6 +393,12 @@ impl<'src> Lexer<'src> {
391393

392394
match indentation {
393395
Blank => {
396+
if DEDENT_RE.is_match(self.rest()) {
397+
while self.indented() {
398+
self.lex_dedent();
399+
}
400+
}
401+
394402
if !whitespace.is_empty() {
395403
while self.next_is_whitespace() {
396404
self.advance()?;
@@ -1472,8 +1480,8 @@ mod tests {
14721480
Indent:" ",
14731481
Text:"a",
14741482
Eol,
1475-
Eol,
14761483
Dedent,
1484+
Eol,
14771485
Identifier:"b",
14781486
Colon,
14791487
Eol,
@@ -1520,8 +1528,8 @@ mod tests {
15201528
Indent,
15211529
Text:"@mv a b",
15221530
Eol,
1523-
Eol,
15241531
Dedent,
1532+
Eol,
15251533
Identifier:"a",
15261534
Colon,
15271535
Eol,
@@ -1531,8 +1539,8 @@ mod tests {
15311539
Whitespace:" ",
15321540
Text:"@touch a",
15331541
Eol,
1534-
Eol,
15351542
Dedent,
1543+
Eol,
15361544
Identifier:"d",
15371545
Colon,
15381546
Whitespace,
@@ -1541,8 +1549,8 @@ mod tests {
15411549
Indent,
15421550
Text:"@rm c",
15431551
Eol,
1544-
Eol,
15451552
Dedent,
1553+
Eol,
15461554
Identifier:"c",
15471555
Colon,
15481556
Whitespace,
@@ -1820,6 +1828,34 @@ mod tests {
18201828
)
18211829
}
18221830

1831+
test! {
1832+
name: tokenize_continued_indent,
1833+
text: "
1834+
hello:
1835+
foo
1836+
1837+
bar
1838+
1839+
baz
1840+
",
1841+
tokens: (
1842+
Identifier:"hello",
1843+
Colon,
1844+
Eol,
1845+
Indent,
1846+
Text:"foo",
1847+
Eol,
1848+
Eol,
1849+
Whitespace:" ",
1850+
Text:"bar",
1851+
Eol,
1852+
Dedent,
1853+
Eol,
1854+
Identifier:"baz",
1855+
Eol,
1856+
),
1857+
}
1858+
18231859
test! {
18241860
name: tokenize_empty_lines,
18251861
text: "
@@ -1856,8 +1892,8 @@ mod tests {
18561892
Whitespace:" ",
18571893
Text:"dsdf # whatever",
18581894
Eol,
1859-
Eol,
18601895
Dedent,
1896+
Eol,
18611897
Comment:"# yolo",
18621898
Eol,
18631899
),
@@ -1978,8 +2014,8 @@ mod tests {
19782014
Whitespace:" ",
19792015
Text:"d",
19802016
Eol,
1981-
Eol,
19822017
Dedent,
2018+
Eol,
19832019
Comment:"# hello",
19842020
Eol,
19852021
Identifier:"bob",
@@ -2038,8 +2074,8 @@ mod tests {
20382074
Indent,
20392075
Text:"@mv a b",
20402076
Eol,
2041-
Eol,
20422077
Dedent,
2078+
Eol,
20432079
Identifier:"a",
20442080
Colon,
20452081
Eol,
@@ -2049,8 +2085,8 @@ mod tests {
20492085
Whitespace:" ",
20502086
Text:"@touch a",
20512087
Eol,
2052-
Eol,
20532088
Dedent,
2089+
Eol,
20542090
Identifier:"d",
20552091
Colon,
20562092
Whitespace,
@@ -2059,8 +2095,8 @@ mod tests {
20592095
Indent,
20602096
Text:"@rm c",
20612097
Eol,
2062-
Eol,
20632098
Dedent,
2099+
Eol,
20642100
Identifier:"c",
20652101
Colon,
20662102
Whitespace,
@@ -2227,6 +2263,23 @@ mod tests {
22272263
),
22282264
}
22292265

2266+
test! {
2267+
name: tokenize_recipe_after_body,
2268+
text: "foo:\n echo FOO\n\nfoo:",
2269+
tokens: (
2270+
Identifier: "foo",
2271+
Colon,
2272+
Eol,
2273+
Indent: " ",
2274+
Text: "echo FOO",
2275+
Eol,
2276+
Dedent,
2277+
Eol,
2278+
Identifier: "foo",
2279+
Colon,
2280+
),
2281+
}
2282+
22302283
error! {
22312284
name: tokenize_space_then_tab,
22322285
input: "a:

src/node.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ pub(crate) trait Node<'src> {
1010
impl<'src> Node<'src> for Ast<'src> {
1111
fn tree(&self) -> Tree<'src> {
1212
Tree::atom("justfile")
13-
.extend(self.items.iter().map(Node::tree))
13+
.extend(
14+
self
15+
.items
16+
.iter()
17+
.filter(|item| !matches!(item, Item::Newline))
18+
.map(Node::tree),
19+
)
1420
.extend(self.warnings.iter().map(Node::tree))
1521
}
1622
}
@@ -52,6 +58,7 @@ impl<'src> Node<'src> for Item<'src> {
5258

5359
tree
5460
}
61+
Self::Newline => unreachable!(),
5562
Self::Function(function) => {
5663
let mut tree = Tree::atom("function");
5764
tree.push_mut(function.name.lexeme());

0 commit comments

Comments
 (0)