fix: show revision-aware blame in diff buffers

Diff and snapshot sources were excluded before scheduling, and the separate diff renderer never painted attribution. Capture per-side Git provenance, preserve private object stores for historical tabs, and reuse the current-line worker and cache.
This commit is contained in:
Valdemar Lorenzen
2026-10-20 11:47:49 +02:00
parent 8f8d96ead9
commit 4fb1be7972
16 changed files with 819 additions and 91 deletions
+34 -16
View File
@@ -2665,22 +2665,13 @@ fn draw_document(
.find(|(_, (row, _, _))| *row == cursor.row)
{
let line = &editor.lines()[cursor.row];
let end = display_column(line, usize::MAX);
let start = end.saturating_sub(segment.start).saturating_add(2);
let label_width = UnicodeWidthStr::width(label);
if end >= segment.start
&& end <= segment.end
&& (!wrapped || continuation + 1 == document.wrap.segments(cursor.row, line).len())
&& start.saturating_add(label_width) <= width
{
frame.render_widget(
Paragraph::new(label).style(Style::default().fg(Color::DarkGray)),
Rect::new(
viewport.x + start as u16,
viewport.y + screen_row as u16,
label_width as u16,
1,
),
if !wrapped || continuation + 1 == document.wrap.segments(cursor.row, line).len() {
paint_inline_blame(
frame,
label,
line,
Rect::new(viewport.x, viewport.y + screen_row as u16, width as u16, 1),
segment.start,
);
}
}
@@ -3236,6 +3227,18 @@ fn paint_editor_line(
}
}
fn paint_inline_blame(frame: &mut Frame, label: &str, line: &str, area: Rect, left: usize) {
let end = display_column(line, usize::MAX);
let start = end.saturating_sub(left).saturating_add(2);
let label_width = UnicodeWidthStr::width(label);
if end >= left && start.saturating_add(label_width) <= usize::from(area.width) {
frame.render_widget(
Paragraph::new(label).style(Style::default().fg(Color::DarkGray)),
Rect::new(area.x + start as u16, area.y, label_width as u16, 1),
);
}
}
fn paint_diff_editor(
frame: &mut Frame,
editor: &Editor,
@@ -3250,6 +3253,7 @@ fn paint_diff_editor(
let source_cursor = editor.cursor();
let cursor_column = display_column(&editor.lines()[source_cursor.row], source_cursor.column);
let mut cursor = None;
let mut blame_area = None;
let focus = view.info.focus;
for (screen, display, segments) in
diff_screen_rows(view.info.display_len, top, area.height, wrapped)
@@ -3283,6 +3287,20 @@ fn paint_diff_editor(
cursor = Some(Position::new(area.x + (column - left) as u16, line_area.y));
}
}
if source == source_cursor.row
&& (segments.is_none()
|| wrapped.is_some_and(|rows| {
rows[screen].final_segments[usize::from(focus == Focus::After)]
}))
{
blame_area = Some((Rect::new(area.x, line_area.y, area.width, 1), left));
}
}
if cursor.is_some()
&& let Some((area, left)) = blame_area
&& let Some(label) = editor.line_blame()
{
paint_inline_blame(frame, label, &editor.lines()[source_cursor.row], area, left);
}
cursor
}