diff options
Diffstat (limited to 'src/syntax_highlighting.rs')
| -rw-r--r-- | src/syntax_highlighting.rs | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/syntax_highlighting.rs b/src/syntax_highlighting.rs index 8a369da..0b1e8c5 100644 --- a/src/syntax_highlighting.rs +++ b/src/syntax_highlighting.rs @@ -31,30 +31,65 @@ impl Highlighter { colors: Vec<Highlight>, stdout: &mut dyn std::io::Write, ) -> std::io::Result<()> { + #[derive(PartialEq, Eq, Debug, Clone)] + struct ColorBoundary { + loc: usize, + is_end: bool, + kind: HighlightKind, + } + + impl PartialOrd for ColorBoundary { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + Some(self.cmp(other)) + } + } + + impl Ord for ColorBoundary { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match self.loc.cmp(&other.loc) { + std::cmp::Ordering::Equal => (), + ord => return ord, + } + match self.kind.cmp(&other.kind) { + std::cmp::Ordering::Equal => (), + ord => return ord, + } + self.is_end.cmp(&other.is_end) + } + } + let mut coloring: Vec<_> = colors .into_iter() .flat_map(|hi| { [ - (hi.span.start as usize, false, hi.kind), - (hi.span.end as usize, true, hi.kind), + ColorBoundary { + loc: hi.span.start as usize, + is_end: false, + kind: hi.kind, + }, + ColorBoundary { + loc: hi.span.end as usize, + is_end: true, + kind: hi.kind, + }, ] }) .collect(); - coloring.sort_by_key(|x| (x.0, x.1)); + coloring.sort(); let mut coloring = &coloring[..]; let mut color_stack = Vec::new(); let mut current_color = self.color(HighlightKind::None); for (i, x) in bytes.iter().cloned().enumerate() { - while let Some((k, is_end, kind)) = coloring.first().cloned() - && k == i + while let Some(color_boundary) = coloring.first().cloned() + && color_boundary.loc <= i { coloring = &coloring[1..]; - if is_end { + if color_boundary.is_end { color_stack.pop(); } else { - color_stack.push(kind); + color_stack.push(color_boundary.kind); } let new_color = |
