editor: Fix inline Git blame not visible on long lines due to overflow (#23374)

Closes #18702

This is take 2 of [my previous
PR](https://github.com/zed-industries/zed/pull/19555), which was closed
due to inactivity and merge conflicts.

**Cause**: 

The editor's horizontal scroll width only considers the longest line in
the buffer, using `layout_line` for `longest_row`. The inline blame
width isn’t included in it because it is just a decoration on top of the
line (think of like CSS absolute) and not part of its actual content.
This causes blame to overflow.

**Solution**:

Along with `longest_row` width we also add that line's inline blame
width for scroll width calculation. We also have to add some padding
that is between inline blame and line's content.

**Alternate Solution**:

In my previous PR, instead of adding the inline blame width of the
longest line for scroll width calculation, I used the inline blame of
the current line the cursor is on (since we only see the blame for the
current line). I added that to the current line's width, giving us the
full width of that row. Then, we compare that row's width with the
longest row width and use the max of the two for the scroll width
calculation.

While this solution seems clever, it's overly complicated and could
cause issues, like the scroll width changing every time you move the
cursor up or down. I don't think we should go with this, but I'm open to
suggestions.

**Preview**:

Before:


https://github.com/user-attachments/assets/01ef90cf-06e7-4ebb-8bd1-637a53e0654e

After:


https://github.com/user-attachments/assets/b13616de-bdea-4da4-b32d-9c4104448166


Release Notes:

- Fixed inline Git blame not visible on long lines due to overflow.
This commit is contained in:
tims 2025-01-28 14:17:11 +05:30 committed by GitHub
parent f314662048
commit 34d0b57945
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -75,6 +75,8 @@ use unicode_segmentation::UnicodeSegmentation;
use util::{RangeExt, ResultExt};
use workspace::{item::Item, notifications::NotifyTaskExt, Workspace};
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DisplayDiffHunk {
Folded {
@ -6623,7 +6625,6 @@ impl Element for EditorElement {
cx,
);
let mut max_visible_line_width = Pixels::ZERO;
let mut line_layouts = Self::layout_lines(
start_row..end_row,
&snapshot,
@ -6633,11 +6634,38 @@ impl Element for EditorElement {
window,
cx,
);
for line_with_invisibles in &line_layouts {
if line_with_invisibles.width > max_visible_line_width {
max_visible_line_width = line_with_invisibles.width;
}
}
let longest_line_blame_width = self
.editor
.update(cx, |editor, cx| {
if !editor.show_git_blame_inline {
return None;
}
let blame = editor.blame.as_ref()?;
let blame_entry = blame
.update(cx, |blame, cx| {
let row_infos =
snapshot.row_infos(snapshot.longest_row()).next()?;
blame.blame_for_rows(&[row_infos], cx).next()
})
.flatten()?;
let workspace = editor.workspace.as_ref().map(|(w, _)| w.to_owned());
let mut element = render_inline_blame_entry(
blame,
blame_entry,
&style,
workspace,
cx,
);
let inline_blame_padding = INLINE_BLAME_PADDING_EM_WIDTHS * em_advance;
Some(
element
.layout_as_root(AvailableSpace::min_size(), window, cx)
.width
+ inline_blame_padding,
)
})
.unwrap_or(Pixels::ZERO);
let longest_line_width = layout_line(
snapshot.longest_row(),
@ -6655,6 +6683,7 @@ impl Element for EditorElement {
letter_size,
&snapshot,
longest_line_width,
longest_line_blame_width,
&style,
cx,
);
@ -7247,6 +7276,7 @@ impl ScrollbarRangeData {
letter_size: Size<Pixels>,
snapshot: &EditorSnapshot,
longest_line_width: Pixels,
longest_line_blame_width: Pixels,
style: &EditorStyle,
cx: &mut App,
@ -7265,7 +7295,7 @@ impl ScrollbarRangeData {
};
let overscroll = size(
scrollbar_width + (letter_size.width / 2.0),
scrollbar_width + (letter_size.width / 2.0) + longest_line_blame_width,
letter_size.height * scroll_beyond_last_line,
);