summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorIan Wrzesinski <wrzian@umich.edu>2024-11-03 20:35:21 -0500
committerIan Wrzesinski <wrzian@umich.edu>2024-11-03 22:04:06 -0500
commit2c9728f53b318a6cae092f30ad0956a536af7ccb (patch)
treec30909de62b6d2d87c02393542d38b56ddd4beec /crates
parent9d9a1b1e33cdc379200c1d3881c34fe05c496894 (diff)
18. Restore list indent behavior
Diffstat (limited to 'crates')
-rw-r--r--crates/typst-syntax/src/lexer.rs8
-rw-r--r--crates/typst-syntax/src/parser.rs41
2 files changed, 22 insertions, 27 deletions
diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs
index d09c6f84..1314016f 100644
--- a/crates/typst-syntax/src/lexer.rs
+++ b/crates/typst-syntax/src/lexer.rs
@@ -69,9 +69,11 @@ impl<'s> Lexer<'s> {
self.newline
}
- /// The number of characters until the most recent newline.
- pub fn column(&self) -> usize {
- self.s.before().chars().rev().take_while(|&c| !is_newline(c)).count()
+ /// The number of characters until the most recent newline from an index.
+ pub fn column(&self, index: usize) -> usize {
+ let mut s = self.s; // Make a new temporary scanner (cheap).
+ s.jump(index);
+ s.before().chars().rev().take_while(|&c| !is_newline(c)).count()
}
}
diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs
index b26cc002..5fc621d6 100644
--- a/crates/typst-syntax/src/parser.rs
+++ b/crates/typst-syntax/src/parser.rs
@@ -1545,11 +1545,7 @@ struct Token {
/// Information about a newline if present (currently only relevant in Markup).
#[derive(Debug, Clone, Copy)]
struct Newline {
- /// The column of our token in its line.
- ///
- /// Note that this is actually the column of the first non-whitespace
- /// `SyntaxKind` in the line, so `\n /**/- list` has column 2 (not 6)
- /// because the block comment is the first non-space kind.
+ /// The column of the start of our token in its line.
column: Option<usize>,
/// Whether any of our newlines were paragraph breaks.
parbreak: bool,
@@ -1684,10 +1680,6 @@ impl<'s> Parser<'s> {
/// The number of characters until the most recent newline from the current
/// token, or 0 if it did not follow a newline.
- ///
- /// Note that this is actually the column of the first non-whitespace
- /// `SyntaxKind` in the line, so `\n /**/- list` has column 2 (not 6)
- /// because the block comment is the first non-space kind.
fn current_column(&self) -> usize {
self.token.newline.and_then(|newline| newline.column).unwrap_or(0)
}
@@ -1852,29 +1844,30 @@ impl<'s> Parser<'s> {
let (mut kind, mut node) = lexer.next();
let mut n_trivia = 0;
let mut had_newline = false;
- let mut newline = Newline { column: None, parbreak: false };
+ let mut parbreak = false;
while kind.is_trivia() {
- if lexer.newline() {
- // Newlines are always trivia.
- had_newline = true;
- newline.parbreak |= kind == SyntaxKind::Parbreak;
- if lexer.mode() == LexMode::Markup {
- newline.column = Some(lexer.column());
- }
- }
+ had_newline |= lexer.newline(); // Newlines are always trivia.
+ parbreak |= kind == SyntaxKind::Parbreak;
n_trivia += 1;
nodes.push(node);
start = lexer.cursor();
(kind, node) = lexer.next();
}
- if had_newline && nl_mode.stop_at(newline, kind) {
- // Insert a temporary `SyntaxKind::End` to halt the parser.
- // The actual kind will be restored from `node` later.
- kind = SyntaxKind::End;
- }
- let newline = had_newline.then_some(newline);
+ let newline = if had_newline {
+ let column = (lexer.mode() == LexMode::Markup).then(|| lexer.column(start));
+ let newline = Newline { column, parbreak };
+ if nl_mode.stop_at(newline, kind) {
+ // Insert a temporary `SyntaxKind::End` to halt the parser.
+ // The actual kind will be restored from `node` later.
+ kind = SyntaxKind::End;
+ }
+ Some(newline)
+ } else {
+ None
+ };
+
Token { kind, node, n_trivia, newline, start, prev_end }
}
}