From 1a0dad36b75e95e1b264536c5a5696186efece17 Mon Sep 17 00:00:00 2001 From: Nik Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Sun, 30 Mar 2025 11:42:43 +0100 Subject: [PATCH] perf: only render inline blame for visible lines when `all-lines` is set Previously, we rendereded the inline blame for lines in 3X the range of the viewport This is not necessary because when we scroll down, the rendering will occur before we see the new content --- helix-term/src/ui/editor.rs | 20 ++++---------------- helix-view/src/view.rs | 12 ++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index e23ccb3f5..0e40775e1 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -254,13 +254,14 @@ impl EditorView { theme: &Theme, ) { const INLINE_BLAME_SCOPE: &str = "ui.virtual.inline-blame"; + let text = doc.text(); match inline_blame.behaviour { InlineBlameBehaviour::Hidden => (), InlineBlameBehaviour::CursorLine => { let cursor_line_idx = doc.cursor_line(view.id); // do not render inline blame for empty lines to reduce visual noise - if doc.text().line(cursor_line_idx) != doc.line_ending.as_str() { + if text.line(cursor_line_idx) != doc.line_ending.as_str() { if let Ok(line_blame) = doc.line_blame(cursor_line_idx as u32, &inline_blame.format) { @@ -275,22 +276,9 @@ impl EditorView { } } InlineBlameBehaviour::AllLines => { - let text = doc.text(); - let text_line_count = text.len_lines(); - let view_height = view.inner_height(); - let first_visible_line = - text.char_to_line(doc.view_offset(view.id).anchor.min(text.len_chars())); - let first_line = first_visible_line.saturating_sub(view_height); - let last_line = first_visible_line - .saturating_add(view_height.saturating_mul(2)) - .min(text_line_count); + let mut blame_lines = vec![None; text.len_lines()]; - let mut blame_lines = vec![None; text_line_count]; - - // Compute ~3 times the current view height of inline blame, that way some scrolling - // will not show half the view with inline blame and half without while still being faster - // than rendering inline blame for the full file. - let blame_for_all_lines = (first_line..last_line).filter_map(|line_idx| { + let blame_for_all_lines = view.line_range(doc).filter_map(|line_idx| { // do not render inline blame for empty lines to reduce visual noise if text.line(line_idx) != doc.line_ending.as_str() { doc.line_blame(line_idx as u32, &inline_blame.format) diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index d6f10753a..b4863700d 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -190,6 +190,18 @@ impl View { self.docs_access_history.push(id); } + /// The range of lines in the document that the view sees + pub fn line_range(&self, doc: &Document) -> std::ops::Range { + let text = doc.text(); + let text_line_count = text.len_lines(); + let first_line = text.char_to_line(doc.view_offset(self.id).anchor.min(text.len_chars())); + let last_line = first_line + .saturating_add(self.inner_height()) + .min(text_line_count); + + first_line..last_line + } + pub fn inner_area(&self, doc: &Document) -> Rect { self.area.clip_left(self.gutter_offset(doc)).clip_bottom(1) // -1 for statusline }