diff --git a/crates/editor/src/scroll/actions.rs b/crates/editor/src/scroll/actions.rs index 5a1c849b2438fe987b24481b824375e188468916..3d22db2a4dc3c9339e51b0dae02d6d598400ad64 100644 --- a/crates/editor/src/scroll/actions.rs +++ b/crates/editor/src/scroll/actions.rs @@ -1,10 +1,12 @@ use super::Axis; use crate::{ - Autoscroll, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom, + Autoscroll, Editor, EditorMode, EditorSettings, NextScreen, NextScrollCursorCenterTopBottom, SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT, ScrollCursorBottom, ScrollCursorCenter, ScrollCursorCenterTopBottom, ScrollCursorTop, display_map::DisplayRow, scroll::ScrollOffset, }; use gpui::{Context, Point, Window}; +use settings::Settings; +use text::ToOffset; impl Editor { pub fn next_screen(&mut self, _: &NextScreen, window: &mut Window, cx: &mut Context) { @@ -73,18 +75,37 @@ impl Editor { ) { let display_snapshot = self.display_snapshot(cx); let scroll_margin_rows = self.vertical_scroll_margin() as u32; - let new_screen_top = self - .selections - .newest_display(&display_snapshot) - .head() - .row() - .0; + let selection_head = self.selections.newest_display(&display_snapshot).head(); + + let sticky_headers_len = if EditorSettings::get_global(cx).sticky_scroll.enabled + && let Some((_, _, buffer_snapshot)) = display_snapshot.buffer_snapshot().as_singleton() + { + let select_head_point = + rope::Point::new(selection_head.to_point(&display_snapshot).row, 0); + buffer_snapshot + .outline_items_containing(select_head_point..select_head_point, false, None) + .iter() + .filter(|outline| { + outline.range.start.offset + < select_head_point.to_offset(&buffer_snapshot) as u32 + }) + .collect::>() + .len() + } else { + 0 + } as u32; + + let new_screen_top = selection_head.row().0; let header_offset = display_snapshot .buffer_snapshot() .show_headers() .then(|| display_snapshot.buffer_header_height()) .unwrap_or(0); - let new_screen_top = new_screen_top.saturating_sub(scroll_margin_rows + header_offset); + + // If the number of sticky headers exceeds the vertical_scroll_margin, + // we need to adjust the scroll top a bit further + let adjustment = scroll_margin_rows.max(sticky_headers_len) + header_offset; + let new_screen_top = new_screen_top.saturating_sub(adjustment); self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx); }