fix: only render inline blame once per line at most

Renders inline blame for the last visual line
pull/13133/head
Nik Revenco 2025-05-06 18:22:25 +01:00
parent be5fbff319
commit 7effac92aa
2 changed files with 19 additions and 0 deletions

View File

@ -81,6 +81,8 @@ pub struct LinePos {
pub doc_line: usize,
/// Vertical offset from the top of the inner view area
pub visual_line: u16,
/// The given visual line is the last visual line of the document line
pub is_last_visual_line: bool,
}
#[allow(clippy::too_many_arguments)]
@ -154,6 +156,7 @@ pub fn render_text(
first_visual_line: false,
doc_line: usize::MAX,
visual_line: u16::MAX,
is_last_visual_line: true,
};
let mut last_line_end = 0;
let mut is_in_indent_area = true;
@ -188,6 +191,10 @@ pub fn render_text(
// apply decorations before rendering a new line
if grapheme.visual_pos.row as u16 != last_line_pos.visual_line {
if last_line_pos.doc_line == grapheme.line_idx {
last_line_pos.is_last_visual_line = false;
}
// we initiate doc_line with usize::MAX because no file
// can reach that size (memory allocations are limited to isize::MAX)
// initially there is no "previous" line (so doc_line is set to usize::MAX)
@ -202,6 +209,7 @@ pub fn render_text(
first_visual_line: grapheme.line_idx != last_line_pos.doc_line,
doc_line: grapheme.line_idx,
visual_line: grapheme.visual_pos.row as u16,
is_last_visual_line: true,
};
decorations.decorate_line(renderer, last_line_pos);
}

View File

@ -31,6 +31,17 @@ impl Decoration for InlineBlame {
pos: LinePos,
virt_off: Position,
) -> Position {
// Only render inline blame on the last visual line
// This prevents it being rendered multiple times per line, if the
// line is wrapping.
//
// We want to render it on the last visual line because unless the user
// has `soft-wrap.wrap-at-text-width` enabled, for a document line that wraps
// there will only be space to render inline blame at the last doc line
if !pos.is_last_visual_line {
return Position::new(0, 0);
}
let blame = match &self.lines {
LineBlame::OneLine((line, blame)) => {
if line == &pos.doc_line {