use super::Axis;use crate::{ Autoscroll, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom, SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT, ScrollCursorBottom, ScrollCursorCenter, ScrollCursorCenterTopBottom, ScrollCursorTop, display_map::DisplayRow, scroll::ScrollOffset,};use gpui::{Context, Point, Window}; impl Editor { pub fn next_screen(&mut self, _: &NextScreen, window: &mut Window, cx: &mut Context<Editor>) { if self.take_rename(true, window, cx).is_some() { return; } if self.mouse_context_menu.is_some() { return; } if matches!(self.mode, EditorMode::SingleLine) { cx.propagate(); return; } self.request_autoscroll(Autoscroll::Next, cx); } pub fn scroll( &mut self, scroll_position: Point<ScrollOffset>, axis: Option<Axis>, window: &mut Window, cx: &mut Context<Self>, ) { self.scroll_manager.update_ongoing_scroll(axis); self.set_scroll_position(scroll_position, window, cx); } pub fn scroll_cursor_center_top_bottom( &mut self, _: &ScrollCursorCenterTopBottom, window: &mut Window, cx: &mut Context<Self>, ) { match self.next_scroll_position { NextScrollCursorCenterTopBottom::Center => { self.scroll_cursor_center(&Default::default(), window, cx); } NextScrollCursorCenterTopBottom::Top => { self.scroll_cursor_top(&Default::default(), window, cx); } NextScrollCursorCenterTopBottom::Bottom => { self.scroll_cursor_bottom(&Default::default(), window, cx); } } self.next_scroll_position = self.next_scroll_position.next(); self._scroll_cursor_center_top_bottom_task = cx.spawn(async move |editor, cx| { cx.background_executor() .timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT) .await; editor .update(cx, |editor, _| { editor.next_scroll_position = NextScrollCursorCenterTopBottom::default(); }) .ok(); }); } pub fn scroll_cursor_top( &mut self, _: &ScrollCursorTop, window: &mut Window, cx: &mut Context<Editor>, ) { let display_snapshot = self.display_snapshot(cx); let scroll_margin_rows = self.vertical_scroll_margin() as u32; let selection_head = self.selections.newest_display(&display_snapshot).head(); let sticky_headers_len = self.visible_sticky_header_count_for_point(&display_snapshot, selection_head, cx) 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); // 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); } pub fn scroll_cursor_center( &mut self, _: &ScrollCursorCenter, window: &mut Window, cx: &mut Context<Editor>, ) { let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else { return; }; let new_screen_top = self .selections .newest_display(&self.display_snapshot(cx)) .head() .row() .0; let new_screen_top = new_screen_top.saturating_sub(visible_rows / 2); self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx); } pub fn scroll_cursor_bottom( &mut self, _: &ScrollCursorBottom, window: &mut Window, cx: &mut Context<Editor>, ) { let scroll_margin_rows = self.vertical_scroll_margin() as u32; let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else { return; }; let new_screen_top = self .selections .newest_display(&self.display_snapshot(cx)) .head() .row() .0; let new_screen_top = new_screen_top.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows)); self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx); }}
use super::Axis;
use crate::{
Autoscroll, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom,
SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT, ScrollCursorBottom, ScrollCursorCenter,
ScrollCursorCenterTopBottom, ScrollCursorTop, display_map::DisplayRow, scroll::ScrollOffset,
};
use gpui::{Context, Point, Window};
impl Editor {
pub fn next_screen(&mut self, _: &NextScreen, window: &mut Window, cx: &mut Context<Editor>) {
if self.take_rename(true, window, cx).is_some() {
return;
}
if self.mouse_context_menu.is_some() {
return;
}
if matches!(self.mode, EditorMode::SingleLine) {
cx.propagate();
return;
}
self.request_autoscroll(Autoscroll::Next, cx);
}
pub fn scroll(
&mut self,
scroll_position: Point<ScrollOffset>,
axis: Option<Axis>,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.scroll_manager.update_ongoing_scroll(axis);
self.set_scroll_position(scroll_position, window, cx);
}
pub fn scroll_cursor_center_top_bottom(
&mut self,
_: &ScrollCursorCenterTopBottom,
window: &mut Window,
cx: &mut Context<Self>,
) {
match self.next_scroll_position {
NextScrollCursorCenterTopBottom::Center => {
self.scroll_cursor_center(&Default::default(), window, cx);
}
NextScrollCursorCenterTopBottom::Top => {
self.scroll_cursor_top(&Default::default(), window, cx);
}
NextScrollCursorCenterTopBottom::Bottom => {
self.scroll_cursor_bottom(&Default::default(), window, cx);
}
}
self.next_scroll_position = self.next_scroll_position.next();
self._scroll_cursor_center_top_bottom_task = cx.spawn(async move |editor, cx| {
cx.background_executor()
.timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT)
.await;
editor
.update(cx, |editor, _| {
editor.next_scroll_position = NextScrollCursorCenterTopBottom::default();
})
.ok();
});
}
pub fn scroll_cursor_top(
&mut self,
_: &ScrollCursorTop,
window: &mut Window,
cx: &mut Context<Editor>,
) {
let display_snapshot = self.display_snapshot(cx);
let scroll_margin_rows = self.vertical_scroll_margin() as u32;
let selection_head = self.selections.newest_display(&display_snapshot).head();
let sticky_headers_len =
self.visible_sticky_header_count_for_point(&display_snapshot, selection_head, cx)
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);
// 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);
}
pub fn scroll_cursor_center(
&mut self,
_: &ScrollCursorCenter,
window: &mut Window,
cx: &mut Context<Editor>,
) {
let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
return;
};
let new_screen_top = self
.selections
.newest_display(&self.display_snapshot(cx))
.head()
.row()
.0;
let new_screen_top = new_screen_top.saturating_sub(visible_rows / 2);
self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
}
pub fn scroll_cursor_bottom(
&mut self,
_: &ScrollCursorBottom,
window: &mut Window,
cx: &mut Context<Editor>,
) {
let scroll_margin_rows = self.vertical_scroll_margin() as u32;
let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
return;
};
let new_screen_top = self
.selections
.newest_display(&self.display_snapshot(cx))
.head()
.row()
.0;
let new_screen_top =
new_screen_top.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
}
}