diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 1eb156334..8b55fc3ed 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -77,6 +77,7 @@ fn tree(&self) -> &Tree { pub fn highlight_iter<'a>( &'a mut self, source: &'a [u8], + range: Option>, cancellation_flag: Option<&'a AtomicUsize>, mut injection_callback: impl FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, ) -> Result> + 'a, Error> { @@ -90,6 +91,12 @@ pub fn highlight_iter<'a>( let query_ref = unsafe { mem::transmute::<_, &'static mut Query>(&mut self.config.query) }; let config_ref = unsafe { mem::transmute::<_, &'static HighlightConfiguration>(&self.config) }; + + // TODO: if reusing cursors this might need resetting + if let Some(range) = &range { + cursor_ref.set_byte_range(range.start, range.end); + } + let captures = cursor_ref .captures(query_ref, tree_ref.root_node(), move |n: Node| { &source[n.byte_range()] @@ -119,7 +126,7 @@ pub fn highlight_iter<'a>( let mut result = HighlightIter { source, - byte_offset: 0, + byte_offset: range.map(|r| r.start).unwrap_or(0), // TODO: simplify injection_callback, cancellation_flag, highlighter: self, @@ -1098,7 +1105,8 @@ fn next(&mut self) -> Option { layer.highlight_end_stack.pop(); return self.emit_event(end_byte, Some(HighlightEvent::HighlightEnd)); } else { - return self.emit_event(self.source.len(), None); + // return self.emit_event(self.source.len(), None); + return None; }; let (mut match_, capture_index) = layer.captures.next().unwrap(); diff --git a/helix-term/src/editor.rs b/helix-term/src/editor.rs index ed2d3a13c..e1288e075 100644 --- a/helix-term/src/editor.rs +++ b/helix-term/src/editor.rs @@ -104,13 +104,24 @@ fn render(&mut self) { state.doc().len_lines() - 1, ); + let range = { + // calculate viewport byte ranges + let start = state.doc().line_to_byte(self.first_line.into()); + let end = state.doc().line_to_byte(last_line) + + state.doc().line(last_line).len_bytes(); + + start..end + }; + + // TODO: range doesn't actually restrict source, just highlight range + // TODO: cache highlight results // TODO: only recalculate when state.doc is actually modified let highlights: Vec<_> = state .syntax .as_mut() .unwrap() - .highlight_iter(source_code.as_bytes(), None, |_| None) + .highlight_iter(source_code.as_bytes(), Some(range), None, |_| None) .unwrap() .collect(); // TODO: we collect here to avoid double borrow, fix later