fix: preserve literal whitespace inside strings
This commit is contained in:
+41
-19
@@ -43,6 +43,7 @@ pub struct SyntaxCache {
|
||||
line_starts: Vec<usize>,
|
||||
lines: Vec<Vec<SyntaxSpan>>,
|
||||
highlighted: Vec<bool>,
|
||||
string_spans: Vec<Vec<SyntaxSpan>>,
|
||||
context: Option<LayerContext>,
|
||||
parser: Parser,
|
||||
tree: Option<Tree>,
|
||||
@@ -147,10 +148,11 @@ impl SyntaxCache {
|
||||
start += line.len() + 1;
|
||||
}
|
||||
self.lines.resize_with(lines.len(), Vec::new);
|
||||
self.string_spans.resize_with(lines.len(), Vec::new);
|
||||
self.highlighted.resize(lines.len(), false);
|
||||
}
|
||||
if edit.is_some() || language_changed {
|
||||
for spans in &mut self.lines {
|
||||
for spans in self.lines.iter_mut().chain(&mut self.string_spans) {
|
||||
spans.clear();
|
||||
}
|
||||
self.highlighted.fill(false);
|
||||
@@ -209,7 +211,7 @@ impl SyntaxCache {
|
||||
self.injections.clear();
|
||||
self.context = None;
|
||||
self.highlighted.fill(false);
|
||||
for spans in &mut self.lines {
|
||||
for spans in self.lines.iter_mut().chain(&mut self.string_spans) {
|
||||
spans.clear();
|
||||
}
|
||||
} else {
|
||||
@@ -225,6 +227,11 @@ impl SyntaxCache {
|
||||
self.lines.get(row).map_or(&[], Vec::as_slice)
|
||||
}
|
||||
|
||||
/// String coverage before foreground overrides, including embedded-language highlighting.
|
||||
pub(crate) fn string_spans(&self, row: usize) -> &[SyntaxSpan] {
|
||||
self.string_spans.get(row).map_or(&[], Vec::as_slice)
|
||||
}
|
||||
|
||||
/// Bundled grammar name, or `None` for unknown languages and plain text.
|
||||
pub fn language(&self) -> Option<&str> {
|
||||
self.syntax.map(|syntax| syntax.name)
|
||||
@@ -415,6 +422,7 @@ impl SyntaxCache {
|
||||
&self.source,
|
||||
&self.line_starts,
|
||||
&mut self.lines,
|
||||
&mut self.string_spans,
|
||||
&self.highlights,
|
||||
&mut self.events,
|
||||
visible,
|
||||
@@ -1089,6 +1097,7 @@ fn render_spans(
|
||||
source: &str,
|
||||
starts: &[usize],
|
||||
lines: &mut [Vec<SyntaxSpan>],
|
||||
strings: &mut [Vec<SyntaxSpan>],
|
||||
highlights: &[Highlight],
|
||||
events: &mut Vec<(usize, bool, usize)>,
|
||||
visible: &[Range],
|
||||
@@ -1111,24 +1120,34 @@ fn render_spans(
|
||||
};
|
||||
let mut active: BTreeSet<(_, usize)> = BTreeSet::new();
|
||||
let mut previous = 0;
|
||||
let mut active_strings = 0;
|
||||
for &(byte, entering, index) in events.iter() {
|
||||
if previous < byte
|
||||
&& let Some((_, current)) = active.last()
|
||||
&& let Some(kind) = highlights[*current].kind
|
||||
{
|
||||
let start = visible.partition_point(|range| range.end_byte <= previous);
|
||||
for range in visible[start..]
|
||||
.iter()
|
||||
.take_while(|range| range.start_byte < byte)
|
||||
{
|
||||
append_global(
|
||||
source,
|
||||
starts,
|
||||
lines,
|
||||
previous.max(range.start_byte),
|
||||
byte.min(range.end_byte),
|
||||
kind,
|
||||
);
|
||||
if previous < byte {
|
||||
let kind = active
|
||||
.last()
|
||||
.and_then(|(_, current)| highlights[*current].kind);
|
||||
if kind.is_some() || active_strings > 0 {
|
||||
let start = visible.partition_point(|range| range.end_byte <= previous);
|
||||
for range in visible[start..]
|
||||
.iter()
|
||||
.take_while(|range| range.start_byte < byte)
|
||||
{
|
||||
let low = previous.max(range.start_byte);
|
||||
let high = byte.min(range.end_byte);
|
||||
if let Some(kind) = kind {
|
||||
append_global(source, starts, lines, low, high, kind);
|
||||
}
|
||||
if active_strings > 0 {
|
||||
append_global(source, starts, strings, low, high, SyntaxKind::String);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if highlights[index].kind == Some(SyntaxKind::String) {
|
||||
if entering {
|
||||
active_strings += 1;
|
||||
} else {
|
||||
active_strings -= 1;
|
||||
}
|
||||
}
|
||||
if entering {
|
||||
@@ -1893,6 +1912,7 @@ mod tests {
|
||||
source,
|
||||
&[0],
|
||||
&mut spans,
|
||||
&mut vec![Vec::new(); 1],
|
||||
&highlights,
|
||||
&mut events,
|
||||
&[source_range(source)],
|
||||
@@ -1963,6 +1983,7 @@ mod tests {
|
||||
source,
|
||||
&starts,
|
||||
&mut spans,
|
||||
&mut vec![Vec::new(); 3],
|
||||
&highlights,
|
||||
&mut Vec::new(),
|
||||
&[source_range(source)],
|
||||
@@ -2004,6 +2025,7 @@ mod tests {
|
||||
source,
|
||||
&starts,
|
||||
&mut visible_spans,
|
||||
&mut vec![Vec::new(); 3],
|
||||
&visible_highlights,
|
||||
&mut Vec::new(),
|
||||
&window,
|
||||
|
||||
Reference in New Issue
Block a user