aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-term/src/ui/document.rs84
-rw-r--r--helix-term/src/ui/editor.rs96
-rw-r--r--helix-term/src/ui/picker.rs10
3 files changed, 65 insertions, 125 deletions
diff --git a/helix-term/src/ui/document.rs b/helix-term/src/ui/document.rs
index af218a84..80da1c54 100644
--- a/helix-term/src/ui/document.rs
+++ b/helix-term/src/ui/document.rs
@@ -97,8 +97,7 @@ pub fn render_document(
doc: &Document,
offset: ViewPosition,
doc_annotations: &TextAnnotations,
- syntax_highlight_iter: impl Iterator<Item = HighlightEvent>,
- overlay_highlight_iter: impl Iterator<Item = HighlightEvent>,
+ highlight_iter: impl Iterator<Item = HighlightEvent>,
theme: &Theme,
line_decoration: &mut [Box<dyn LineDecoration + '_>],
translated_positions: &mut [TranslatedPosition],
@@ -110,8 +109,7 @@ pub fn render_document(
offset,
&doc.text_format(viewport.width, Some(theme)),
doc_annotations,
- syntax_highlight_iter,
- overlay_highlight_iter,
+ highlight_iter,
theme,
line_decoration,
translated_positions,
@@ -159,8 +157,7 @@ pub fn render_text<'t>(
offset: ViewPosition,
text_fmt: &TextFormat,
text_annotations: &TextAnnotations,
- syntax_highlight_iter: impl Iterator<Item = HighlightEvent>,
- overlay_highlight_iter: impl Iterator<Item = HighlightEvent>,
+ highlight_iter: impl Iterator<Item = HighlightEvent>,
theme: &Theme,
line_decorations: &mut [Box<dyn LineDecoration + '_>],
translated_positions: &mut [TranslatedPosition],
@@ -181,16 +178,10 @@ pub fn render_text<'t>(
let (mut formatter, mut first_visible_char_idx) =
DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, text_annotations, offset.anchor);
- let mut syntax_styles = StyleIter {
+ let mut styles = StyleIter {
text_style: renderer.text_style,
active_highlights: Vec::with_capacity(64),
- highlight_iter: syntax_highlight_iter,
- theme,
- };
- let mut overlay_styles = StyleIter {
- text_style: renderer.text_style,
- active_highlights: Vec::with_capacity(64),
- highlight_iter: overlay_highlight_iter,
+ highlight_iter,
theme,
};
@@ -202,10 +193,7 @@ pub fn render_text<'t>(
};
let mut is_in_indent_area = true;
let mut last_line_indent_level = 0;
- let mut syntax_style_span = syntax_styles
- .next()
- .unwrap_or_else(|| (Style::default(), usize::MAX));
- let mut overlay_style_span = overlay_styles
+ let mut style_span = styles
.next()
.unwrap_or_else(|| (Style::default(), usize::MAX));
@@ -233,16 +221,9 @@ pub fn render_text<'t>(
// skip any graphemes on visual lines before the block start
if pos.row < row_off {
- if char_pos >= syntax_style_span.1 {
- syntax_style_span = if let Some(syntax_style_span) = syntax_styles.next() {
- syntax_style_span
- } else {
- break;
- }
- }
- if char_pos >= overlay_style_span.1 {
- overlay_style_span = if let Some(overlay_style_span) = overlay_styles.next() {
- overlay_style_span
+ if char_pos >= style_span.1 {
+ style_span = if let Some(style_span) = styles.next() {
+ style_span
} else {
break;
}
@@ -279,15 +260,8 @@ pub fn render_text<'t>(
}
// acquire the correct grapheme style
- if char_pos >= syntax_style_span.1 {
- syntax_style_span = syntax_styles
- .next()
- .unwrap_or((Style::default(), usize::MAX));
- }
- if char_pos >= overlay_style_span.1 {
- overlay_style_span = overlay_styles
- .next()
- .unwrap_or((Style::default(), usize::MAX));
+ if char_pos >= style_span.1 {
+ style_span = styles.next().unwrap_or((Style::default(), usize::MAX));
}
char_pos += grapheme.doc_chars();
@@ -301,25 +275,22 @@ pub fn render_text<'t>(
pos,
);
- let (syntax_style, overlay_style) =
- if let GraphemeSource::VirtualText { highlight } = grapheme.source {
- let mut style = renderer.text_style;
- if let Some(highlight) = highlight {
- style = style.patch(theme.highlight(highlight.0))
- }
- (style, Style::default())
+ let grapheme_style = if let GraphemeSource::VirtualText { highlight } = grapheme.source {
+ let style = renderer.text_style;
+ if let Some(highlight) = highlight {
+ style.patch(theme.highlight(highlight.0))
} else {
- (syntax_style_span.0, overlay_style_span.0)
- };
+ style
+ }
+ } else {
+ style_span.0
+ };
- let is_virtual = grapheme.is_virtual();
+ let virt = grapheme.is_virtual();
renderer.draw_grapheme(
grapheme.grapheme,
- GraphemeStyle {
- syntax_style,
- overlay_style,
- },
- is_virtual,
+ grapheme_style,
+ virt,
&mut last_line_indent_level,
&mut is_in_indent_area,
pos,
@@ -351,11 +322,6 @@ pub struct TextRenderer<'a> {
pub viewport: Rect,
}
-pub struct GraphemeStyle {
- syntax_style: Style,
- overlay_style: Style,
-}
-
impl<'a> TextRenderer<'a> {
pub fn new(
surface: &'a mut Surface,
@@ -429,7 +395,7 @@ impl<'a> TextRenderer<'a> {
pub fn draw_grapheme(
&mut self,
grapheme: Grapheme,
- grapheme_style: GraphemeStyle,
+ mut style: Style,
is_virtual: bool,
last_indent_level: &mut usize,
is_in_indent_area: &mut bool,
@@ -439,11 +405,9 @@ impl<'a> TextRenderer<'a> {
let is_whitespace = grapheme.is_whitespace();
// TODO is it correct to apply the whitespace style to all unicode white spaces?
- let mut style = grapheme_style.syntax_style;
if is_whitespace {
style = style.patch(self.whitespace_style);
}
- style = style.patch(grapheme_style.overlay_style);
let width = grapheme.width();
let space = if is_virtual { " " } else { &self.space };
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 6b85d9a3..31195a4e 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -124,20 +124,16 @@ impl EditorView {
line_decorations.push(Box::new(line_decoration));
}
- let syntax_highlights =
+ let mut highlights =
Self::doc_syntax_highlights(doc, view.offset.anchor, inner.height, theme);
-
- let mut overlay_highlights =
- Self::empty_highlight_iter(doc, view.offset.anchor, inner.height);
- let overlay_syntax_highlights = Self::overlay_syntax_highlights(
+ let overlay_highlights = Self::overlay_syntax_highlights(
doc,
view.offset.anchor,
inner.height,
&text_annotations,
);
- if !overlay_syntax_highlights.is_empty() {
- overlay_highlights =
- Box::new(syntax::merge(overlay_highlights, overlay_syntax_highlights));
+ if !overlay_highlights.is_empty() {
+ highlights = Box::new(syntax::merge(highlights, overlay_highlights));
}
for diagnostic in Self::doc_diagnostics_highlights(doc, theme) {
@@ -146,12 +142,12 @@ impl EditorView {
if diagnostic.is_empty() {
continue;
}
- overlay_highlights = Box::new(syntax::merge(overlay_highlights, diagnostic));
+ highlights = Box::new(syntax::merge(highlights, diagnostic));
}
- if is_focused {
+ let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
let highlights = syntax::merge(
- overlay_highlights,
+ highlights,
Self::doc_selection_highlights(
editor.mode(),
doc,
@@ -162,11 +158,13 @@ impl EditorView {
);
let focused_view_elements = Self::highlight_focused_view_elements(view, doc, theme);
if focused_view_elements.is_empty() {
- overlay_highlights = Box::new(highlights)
+ Box::new(highlights)
} else {
- overlay_highlights = Box::new(syntax::merge(highlights, focused_view_elements))
+ Box::new(syntax::merge(highlights, focused_view_elements))
}
- }
+ } else {
+ Box::new(highlights)
+ };
let gutter_overflow = view.gutter_offset(doc) == 0;
if !gutter_overflow {
@@ -199,8 +197,7 @@ impl EditorView {
doc,
view.offset,
&text_annotations,
- syntax_highlights,
- overlay_highlights,
+ highlights,
theme,
&mut line_decorations,
&mut translated_positions,
@@ -260,39 +257,27 @@ impl EditorView {
.for_each(|area| surface.set_style(area, ruler_theme))
}
- fn viewport_byte_range(
- text: helix_core::RopeSlice,
- row: usize,
- height: u16,
- ) -> std::ops::Range<usize> {
- // Calculate viewport byte ranges:
- // Saturating subs to make it inclusive zero indexing.
- let last_line = text.len_lines().saturating_sub(1);
- let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);
- let start = text.line_to_byte(row.min(last_line));
- let end = text.line_to_byte(last_visible_line + 1);
-
- start..end
- }
-
- pub fn empty_highlight_iter(
+ pub fn overlay_syntax_highlights(
doc: &Document,
anchor: usize,
height: u16,
- ) -> Box<dyn Iterator<Item = HighlightEvent>> {
+ text_annotations: &TextAnnotations,
+ ) -> Vec<(usize, std::ops::Range<usize>)> {
let text = doc.text().slice(..);
let row = text.char_to_line(anchor.min(text.len_chars()));
- // Calculate viewport byte ranges:
- // Saturating subs to make it inclusive zero indexing.
- let range = Self::viewport_byte_range(text, row, height);
- Box::new(
- [HighlightEvent::Source {
- start: text.byte_to_char(range.start),
- end: text.byte_to_char(range.end),
- }]
- .into_iter(),
- )
+ let range = {
+ // Calculate viewport byte ranges:
+ // Saturating subs to make it inclusive zero indexing.
+ let last_line = text.len_lines().saturating_sub(1);
+ let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);
+ let start = text.line_to_byte(row.min(last_line));
+ let end = text.line_to_byte(last_visible_line + 1);
+
+ start..end
+ };
+
+ text_annotations.collect_overlay_highlights(range)
}
/// Get syntax highlights for a document in a view represented by the first line
@@ -307,7 +292,16 @@ impl EditorView {
let text = doc.text().slice(..);
let row = text.char_to_line(anchor.min(text.len_chars()));
- let range = Self::viewport_byte_range(text, row, height);
+ let range = {
+ // Calculate viewport byte ranges:
+ // Saturating subs to make it inclusive zero indexing.
+ let last_line = text.len_lines().saturating_sub(1);
+ let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);
+ let start = text.line_to_byte(row.min(last_line));
+ let end = text.line_to_byte(last_visible_line + 1);
+
+ start..end
+ };
match doc.syntax() {
Some(syntax) => {
@@ -340,20 +334,6 @@ impl EditorView {
}
}
- pub fn overlay_syntax_highlights(
- doc: &Document,
- anchor: usize,
- height: u16,
- text_annotations: &TextAnnotations,
- ) -> Vec<(usize, std::ops::Range<usize>)> {
- let text = doc.text().slice(..);
- let row = text.char_to_line(anchor.min(text.len_chars()));
-
- let range = Self::viewport_byte_range(text, row, height);
-
- text_annotations.collect_overlay_highlights(range)
- }
-
/// Get highlight spans for document diagnostics
pub fn doc_diagnostics_highlights(
doc: &Document,
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index 9ba45335..0214a391 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -736,20 +736,17 @@ impl<T: Item + 'static> Picker<T> {
}
}
- let syntax_highlights = EditorView::doc_syntax_highlights(
+ let mut highlights = EditorView::doc_syntax_highlights(
doc,
offset.anchor,
area.height,
&cx.editor.theme,
);
-
- let mut overlay_highlights =
- EditorView::empty_highlight_iter(doc, offset.anchor, area.height);
for spans in EditorView::doc_diagnostics_highlights(doc, &cx.editor.theme) {
if spans.is_empty() {
continue;
}
- overlay_highlights = Box::new(helix_core::syntax::merge(overlay_highlights, spans));
+ highlights = Box::new(helix_core::syntax::merge(highlights, spans));
}
let mut decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
@@ -780,8 +777,7 @@ impl<T: Item + 'static> Picker<T> {
offset,
// TODO: compute text annotations asynchronously here (like inlay hints)
&TextAnnotations::default(),
- syntax_highlights,
- overlay_highlights,
+ highlights,
&cx.editor.theme,
&mut decorations,
&mut [],