From 0599f0fcb6235153af26839895a40377d4cd4d8a Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Fri, 3 Jan 2025 11:37:00 -0300 Subject: [PATCH] Fix vertical alignment when jumping from multibuffers (#22613) Clicking buffer headers and line numbers would sometimes take you to a disorienting scroll position. This PR improves that so the destination line is roughly at the same Y position as it appeared in the multibuffer. https://github.com/user-attachments/assets/3ad71537-cf26-4136-948f-c5a96df57178 **Note**: The alignment won't always be perfect because the multibuffer and target buffer might start at a different absolute Y position (because of open search, breadcrumbs, etc). I wanted to compensate for that, but that requires a fundamental change that I'd prefer to make separately. Release Notes: - Fix vertical alignment when jumping from multibuffers --- crates/editor/src/editor.rs | 12 +++++++++--- crates/editor/src/element.rs | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 899ccb4eada00240aaffad4e5e5519c755693a57..63e081ec5ae686f31dd236d1888b716f8e517fc7 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -993,7 +993,10 @@ pub(crate) struct FocusedBlock { #[derive(Clone)] enum JumpData { - MultiBufferRow(MultiBufferRow), + MultiBufferRow { + row: MultiBufferRow, + line_offset_from_top: u32, + }, MultiBufferPoint { excerpt_id: ExcerptId, position: Point, @@ -12487,7 +12490,10 @@ impl Editor { ); } } - Some(JumpData::MultiBufferRow(row)) => { + Some(JumpData::MultiBufferRow { + row, + line_offset_from_top, + }) => { let point = MultiBufferPoint::new(row.0, 0); if let Some((buffer, buffer_point, _)) = self.buffer.read(cx).point_to_buffer_point(point, cx) @@ -12495,7 +12501,7 @@ impl Editor { let buffer_offset = buffer.read(cx).point_to_offset(buffer_point); new_selections_by_buffer .entry(buffer) - .or_insert((Vec::new(), None)) + .or_insert((Vec::new(), Some(*line_offset_from_top))) .0 .push(buffer_offset..buffer_offset) } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 4fbaf971be9c26e1a314cb92775bd2c8f7611148..79aebc07d440f084d14a7d0ad968b0f5fad62935 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -599,8 +599,15 @@ impl EditorElement { .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; + editor.open_excerpts_common( - Some(JumpData::MultiBufferRow(MultiBufferRow(multi_buffer_row))), + Some(JumpData::MultiBufferRow { + row: MultiBufferRow(multi_buffer_row), + line_offset_from_top, + }), modifiers.alt, cx, ); @@ -2959,7 +2966,12 @@ impl EditorElement { selected_buffer_ids: &Vec, cx: &mut WindowContext, ) -> AnyElement { - let jump_data = header_jump_data(snapshot, DisplayRow(0), FILE_HEADER_HEIGHT, excerpt); + let jump_data = header_jump_data( + snapshot, + DisplayRow(scroll_position as u32), + FILE_HEADER_HEIGHT + MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, + excerpt, + ); let editor_bg_color = cx.theme().colors().editor_background; @@ -5121,13 +5133,12 @@ fn header_jump_data( let offset_from_excerpt_start = if jump_anchor == excerpt_start { 0 } else { - let excerpt_start_row = language::ToPoint::to_point(&jump_anchor, buffer).row; + let excerpt_start_row = language::ToPoint::to_point(&excerpt_start, buffer).row; jump_position.row - excerpt_start_row }; - let line_offset_from_top = block_row_start.0 - + height - + offset_from_excerpt_start.saturating_sub( + let line_offset_from_top = (block_row_start.0 + height + offset_from_excerpt_start) + .saturating_sub( snapshot .scroll_anchor .scroll_position(&snapshot.display_snapshot)