Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/ui/document.rs')
| -rw-r--r-- | helix-term/src/ui/document.rs | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/helix-term/src/ui/document.rs b/helix-term/src/ui/document.rs index b571b83c..bcbaa351 100644 --- a/helix-term/src/ui/document.rs +++ b/helix-term/src/ui/document.rs @@ -7,6 +7,7 @@ use helix_core::syntax::Highlight; use helix_core::syntax::HighlightEvent; use helix_core::text_annotations::TextAnnotations; use helix_core::{visual_offset_from_block, Position, RopeSlice}; +use helix_stdx::rope::RopeSliceExt; use helix_view::editor::{WhitespaceConfig, WhitespaceRenderValue}; use helix_view::graphics::Rect; use helix_view::theme::Style; @@ -32,14 +33,27 @@ impl<F: FnMut(&mut TextRenderer, LinePos)> LineDecoration for F { } } +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum StyleIterKind { + /// base highlights (usually emitted by TS), byte indices (potentially not codepoint aligned) + BaseHighlights, + /// overlay highlights (emitted by custom code from selections), char indices + Overlay, +} + /// A wrapper around a HighlightIterator /// that merges the layered highlights to create the final text style /// and yields the active text style and the char_idx where the active /// style will have to be recomputed. +/// +/// TODO(ropey2): hopefully one day helix and ropey will operate entirely +/// on byte ranges and we can remove this struct StyleIter<'a, H: Iterator<Item = HighlightEvent>> { text_style: Style, active_highlights: Vec<Highlight>, highlight_iter: H, + kind: StyleIterKind, + text: RopeSlice<'a>, theme: &'a Theme, } @@ -54,7 +68,7 @@ impl<H: Iterator<Item = HighlightEvent>> Iterator for StyleIter<'_, H> { HighlightEvent::HighlightEnd => { self.active_highlights.pop(); } - HighlightEvent::Source { start, end } => { + HighlightEvent::Source { start, mut end } => { if start == end { continue; } @@ -64,6 +78,9 @@ impl<H: Iterator<Item = HighlightEvent>> Iterator for StyleIter<'_, H> { .fold(self.text_style, |acc, span| { acc.patch(self.theme.highlight(span.0)) }); + if self.kind == StyleIterKind::BaseHighlights { + end = self.text.byte_to_next_char(end); + } return Some((style, end)); } } @@ -185,13 +202,17 @@ pub fn render_text<'t>( text_style: renderer.text_style, active_highlights: Vec::with_capacity(64), highlight_iter: syntax_highlight_iter, + kind: StyleIterKind::BaseHighlights, theme, + text, }; let mut overlay_styles = StyleIter { text_style: Style::default(), active_highlights: Vec::with_capacity(64), highlight_iter: overlay_highlight_iter, + kind: StyleIterKind::Overlay, theme, + text, }; let mut last_line_pos = LinePos { |