From 790bd536eba76a2a48d61ea6b1bde78cde3d31f3 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 11 Apr 2022 15:39:32 +0200 Subject: [PATCH] Fix incremental bugs Co-Authored-By: Martin Haug --- src/parse/incremental.rs | 15 +++++++++++++-- src/parse/mod.rs | 6 +++--- src/syntax/ast.rs | 4 +--- src/syntax/highlight.rs | 1 - src/syntax/mod.rs | 7 ++----- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/parse/incremental.rs b/src/parse/incremental.rs index 663187909..64fe95ab0 100644 --- a/src/parse/incremental.rs +++ b/src/parse/incremental.rs @@ -45,12 +45,14 @@ impl Reparser<'_> { ) -> Option> { let child_mode = green.kind().only_in_mode().unwrap_or(TokenMode::Code); let original_count = green.children().len(); + let original_offset = offset; let mut search = SearchState::default(); let mut ahead_nontrivia = None; // Whether the first node that should be replaced is at start. let mut at_start = true; + // Whether the last searched child is the outermost child. let mut child_outermost = false; @@ -77,8 +79,12 @@ impl Reparser<'_> { } else if child_span.contains(&self.replace_range.start) { search = SearchState::Inside(pos); } else { - if (!child.kind().is_space() - && child.kind() != &NodeKind::Semicolon) + // We look only for non spaces, non-semicolon and also + // reject text that points to the special case for URL + // evasion and line comments. + if !child.kind().is_space() + && child.kind() != &NodeKind::Semicolon + && child.kind() != &NodeKind::Text('/'.into()) && (ahead_nontrivia.is_none() || self.replace_range.start > child_span.end) { @@ -173,6 +179,8 @@ impl Reparser<'_> { start = ahead; at_start = ahead_at_start; } + } else { + start = GreenPos { idx: 0, offset: original_offset }; } let superseded_span = @@ -350,6 +358,7 @@ mod tests { test("#for", 4 .. 4, "//", 0 .. 6); test("a\n#let \nb", 7 .. 7, "i", 2 .. 9); test("a\n#for i \nb", 9 .. 9, "in", 2 .. 12); + test("a~https://fun/html", 13..14, "n", 2..18); } #[test] @@ -365,6 +374,8 @@ mod tests { test("hey #myfriend", 4 .. 4, "\\", 3 .. 6); test("= foo\nbar\n - a\n - b", 6 .. 9, "", 0 .. 11); test("= foo\n bar\n baz", 6 .. 8, "", 0 .. 9); + test(" // hi", 1 .. 1, " ", 0 .. 7); + test("- \nA", 2..3, "", 0..3); } #[test] diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 88d0c244a..28b7f81d5 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -282,7 +282,7 @@ fn heading(p: &mut Parser, at_start: bool) { marker.end(p, NodeKind::Heading); } else { let text = p.get(current_start .. p.prev_end()).into(); - marker.convert(p, NodeKind::TextInLine(text)); + marker.convert(p, NodeKind::Text(text)); } } @@ -297,7 +297,7 @@ fn list_node(p: &mut Parser, at_start: bool) { markup_indented(p, column); marker.end(p, NodeKind::List); } else { - marker.convert(p, NodeKind::TextInLine(text)); + marker.convert(p, NodeKind::Text(text)); } } @@ -312,7 +312,7 @@ fn enum_node(p: &mut Parser, at_start: bool) { markup_indented(p, column); marker.end(p, NodeKind::Enum); } else { - marker.convert(p, NodeKind::TextInLine(text)); + marker.convert(p, NodeKind::Text(text)); } } diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 97ab055f7..087b8d779 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -63,9 +63,7 @@ impl Markup { NodeKind::Space(2 ..) => Some(MarkupNode::Parbreak), NodeKind::Space(_) => Some(MarkupNode::Space), NodeKind::Linebreak => Some(MarkupNode::Linebreak), - NodeKind::Text(s) | NodeKind::TextInLine(s) => { - Some(MarkupNode::Text(s.clone())) - } + NodeKind::Text(s) => Some(MarkupNode::Text(s.clone())), NodeKind::Escape(c) => Some(MarkupNode::Text((*c).into())), NodeKind::NonBreakingSpace => Some(MarkupNode::Text('\u{00A0}'.into())), NodeKind::EnDash => Some(MarkupNode::Text('\u{2013}'.into())), diff --git a/src/syntax/highlight.rs b/src/syntax/highlight.rs index b0486c7bc..25b458efb 100644 --- a/src/syntax/highlight.rs +++ b/src/syntax/highlight.rs @@ -195,7 +195,6 @@ impl Category { NodeKind::Markup(_) => None, NodeKind::Space(_) => None, NodeKind::Text(_) => None, - NodeKind::TextInLine(_) => None, NodeKind::List => None, NodeKind::Enum => None, NodeKind::CodeBlock => None, diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index b4908ff22..5857940c7 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -590,8 +590,6 @@ pub enum NodeKind { Linebreak, /// A consecutive non-markup string. Text(EcoString), - /// A text node that cannot appear at the beginning of a source line. - TextInLine(EcoString), /// A non-breaking space: `~`. NonBreakingSpace, /// An en-dash: `--`. @@ -757,6 +755,7 @@ impl NodeKind { pub fn only_at_start(&self) -> bool { match self { Self::Heading | Self::Enum | Self::List => true, + Self::Text(t) => t == "-" || t.ends_with('.'), _ => false, } } @@ -767,7 +766,6 @@ impl NodeKind { Self::Markup(_) | Self::Linebreak | Self::Text(_) - | Self::TextInLine(_) | Self::NonBreakingSpace | Self::EnDash | Self::EmDash @@ -859,7 +857,7 @@ impl NodeKind { Self::Space(2 ..) => "paragraph break", Self::Space(_) => "space", Self::Linebreak => "forced linebreak", - Self::Text(_) | Self::TextInLine(_) => "text", + Self::Text(_) => "text", Self::NonBreakingSpace => "non-breaking space", Self::EnDash => "en dash", Self::EmDash => "em dash", @@ -980,7 +978,6 @@ impl Hash for NodeKind { Self::Space(n) => n.hash(state), Self::Linebreak => {} Self::Text(s) => s.hash(state), - Self::TextInLine(s) => s.hash(state), Self::NonBreakingSpace => {} Self::EnDash => {} Self::EmDash => {}