Fix active line number highlight (#23266)

Closes #22734

Release Notes:

- Fixed active line number highlight.

---------

Co-authored-by: Danilo <danilo@zed.dev>
This commit is contained in:
João Marcos 2025-01-16 22:23:28 -03:00 committed by GitHub
parent b472bd992f
commit 7ee78a4d35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 51 additions and 36 deletions

View file

@ -510,7 +510,7 @@ impl EditorElement {
position_map: &PositionMap,
text_hitbox: &Hitbox,
gutter_hitbox: &Hitbox,
line_numbers: &HashMap<MultiBufferRow, (ShapedLine, Option<Hitbox>)>,
line_numbers: &HashMap<MultiBufferRow, LineNumberLayout>,
cx: &mut ViewContext<Editor>,
) {
if cx.default_prevented() {
@ -618,22 +618,24 @@ impl EditorElement {
.snapshot
.display_point_to_point(DisplayPoint::new(DisplayRow(display_row), 0), Bias::Right)
.row;
if let Some((_, Some(hitbox))) = line_numbers.get(&MultiBufferRow(multi_buffer_row)) {
if hitbox.contains(&event.position) {
let scroll_position_row =
position_map.scroll_pixel_position.y / position_map.line_height;
let line_offset_from_top = display_row - scroll_position_row as u32;
if line_numbers
.get(&MultiBufferRow(multi_buffer_row))
.and_then(|line_number| line_number.hitbox.as_ref())
.is_some_and(|hitbox| hitbox.contains(&event.position))
{
let scroll_position_row =
position_map.scroll_pixel_position.y / position_map.line_height;
let line_offset_from_top = display_row - scroll_position_row as u32;
editor.open_excerpts_common(
Some(JumpData::MultiBufferRow {
row: MultiBufferRow(multi_buffer_row),
line_offset_from_top,
}),
modifiers.alt,
cx,
);
cx.stop_propagation();
}
editor.open_excerpts_common(
Some(JumpData::MultiBufferRow {
row: MultiBufferRow(multi_buffer_row),
line_offset_from_top,
}),
modifiers.alt,
cx,
);
cx.stop_propagation();
}
}
}
@ -2033,11 +2035,10 @@ impl EditorElement {
scroll_position: gpui::Point<f32>,
rows: Range<DisplayRow>,
buffer_rows: impl Iterator<Item = Option<MultiBufferRow>>,
active_rows: &BTreeMap<DisplayRow, bool>,
newest_selection_head: Option<DisplayPoint>,
snapshot: &EditorSnapshot,
cx: &mut WindowContext,
) -> Arc<HashMap<MultiBufferRow, (ShapedLine, Option<Hitbox>)>> {
) -> Arc<HashMap<MultiBufferRow, LineNumberLayout>> {
let include_line_numbers = snapshot.show_line_numbers.unwrap_or_else(|| {
EditorSettings::get_global(cx).gutter.line_numbers && snapshot.mode == EditorMode::Full
});
@ -2075,19 +2076,15 @@ impl EditorElement {
.enumerate()
.flat_map(|(ix, buffer_row)| {
let buffer_row = buffer_row?;
let display_row = DisplayRow(rows.start.0 + ix as u32);
let color = if active_rows.contains_key(&display_row) {
cx.theme().colors().editor_active_line_number
} else {
cx.theme().colors().editor_line_number
};
line_number.clear();
let default_number = buffer_row.0 + 1;
let display_row = DisplayRow(rows.start.0 + ix as u32);
let non_relative_number = buffer_row.0 + 1;
let number = relative_rows
.get(&DisplayRow(ix as u32 + rows.start.0))
.unwrap_or(&default_number);
.get(&display_row)
.unwrap_or(&non_relative_number);
write!(&mut line_number, "{number}").unwrap();
let color = cx.theme().colors().editor_line_number;
let shaped_line = self
.shape_line_number(SharedString::from(&line_number), color, cx)
.log_err()?;
@ -2115,7 +2112,12 @@ impl EditorElement {
let multi_buffer_row = DisplayPoint::new(display_row, 0).to_point(snapshot).row;
let multi_buffer_row = MultiBufferRow(multi_buffer_row);
Some((multi_buffer_row, (shaped_line, hitbox)))
let line_number = LineNumberLayout {
shaped_line,
hitbox,
display_row,
};
Some((multi_buffer_row, line_number))
})
.collect();
Arc::new(line_numbers)
@ -3961,17 +3963,26 @@ impl EditorElement {
let line_height = layout.position_map.line_height;
cx.set_cursor_style(CursorStyle::Arrow, &layout.gutter_hitbox);
for (_, (line, hitbox)) in layout.line_numbers.iter() {
for LineNumberLayout {
shaped_line,
hitbox,
display_row,
} in layout.line_numbers.values()
{
let Some(hitbox) = hitbox else {
continue;
};
let color = if !is_singleton && hitbox.is_hovered(cx) {
let is_active = layout.active_rows.contains_key(&display_row);
let color = if is_active {
cx.theme().colors().editor_active_line_number
} else {
cx.theme().colors().editor_line_number
};
let Some(line) = self
.shape_line_number(line.text.clone(), color, cx)
.shape_line_number(shaped_line.text.clone(), color, cx)
.log_err()
else {
continue;
@ -6280,7 +6291,6 @@ impl Element for EditorElement {
scroll_position,
start_row..end_row,
buffer_rows.iter().copied(),
&active_rows,
newest_selection_head,
&snapshot,
cx,
@ -6991,7 +7001,7 @@ pub struct EditorLayout {
active_rows: BTreeMap<DisplayRow, bool>,
highlighted_rows: BTreeMap<DisplayRow, Hsla>,
line_elements: SmallVec<[AnyElement; 1]>,
line_numbers: Arc<HashMap<MultiBufferRow, (ShapedLine, Option<Hitbox>)>>,
line_numbers: Arc<HashMap<MultiBufferRow, LineNumberLayout>>,
display_hunks: Vec<(DisplayDiffHunk, Option<Hitbox>)>,
blamed_display_rows: Option<Vec<AnyElement>>,
inline_blame: Option<AnyElement>,
@ -7019,6 +7029,12 @@ impl EditorLayout {
}
}
struct LineNumberLayout {
shaped_line: ShapedLine,
hitbox: Option<Hitbox>,
display_row: DisplayRow,
}
struct ColoredRange<T> {
start: T,
end: T,
@ -7661,7 +7677,6 @@ mod tests {
gpui::Point::default(),
DisplayRow(0)..DisplayRow(6),
(0..6).map(MultiBufferRow).map(Some),
&Default::default(),
Some(DisplayPoint::new(DisplayRow(0), 0)),
&snapshot,
cx,
@ -7911,7 +7926,7 @@ mod tests {
state
.line_numbers
.get(&MultiBufferRow(0))
.and_then(|(line, _)| line.text.as_str()),
.and_then(|line_number| line_number.shaped_line.text.as_str()),
Some("1")
);
}

View file

@ -20,7 +20,7 @@ use crate::{
ProjectEnvironment,
};
#[expect(clippy::large_enum_variant)]
#[allow(clippy::large_enum_variant)] // platform-dependent warning
pub enum TaskStore {
Functional(StoreState),
Noop,