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.rs23
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 {