actions.rs

  1use super::Axis;
  2use crate::{
  3    Autoscroll, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom,
  4    SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT, ScrollCursorBottom, ScrollCursorCenter,
  5    ScrollCursorCenterTopBottom, ScrollCursorTop, display_map::DisplayRow, scroll::ScrollOffset,
  6};
  7use gpui::{Context, Point, Window};
  8
  9impl Editor {
 10    pub fn next_screen(&mut self, _: &NextScreen, window: &mut Window, cx: &mut Context<Editor>) {
 11        if self.take_rename(true, window, cx).is_some() {
 12            return;
 13        }
 14
 15        if self.mouse_context_menu.is_some() {
 16            return;
 17        }
 18
 19        if matches!(self.mode, EditorMode::SingleLine) {
 20            cx.propagate();
 21            return;
 22        }
 23        self.request_autoscroll(Autoscroll::Next, cx);
 24    }
 25
 26    pub fn scroll(
 27        &mut self,
 28        scroll_position: Point<ScrollOffset>,
 29        axis: Option<Axis>,
 30        window: &mut Window,
 31        cx: &mut Context<Self>,
 32    ) {
 33        self.scroll_manager.update_ongoing_scroll(axis);
 34        self.set_scroll_position(scroll_position, window, cx);
 35    }
 36
 37    pub fn scroll_cursor_center_top_bottom(
 38        &mut self,
 39        _: &ScrollCursorCenterTopBottom,
 40        window: &mut Window,
 41        cx: &mut Context<Self>,
 42    ) {
 43        match self.next_scroll_position {
 44            NextScrollCursorCenterTopBottom::Center => {
 45                self.scroll_cursor_center(&Default::default(), window, cx);
 46            }
 47            NextScrollCursorCenterTopBottom::Top => {
 48                self.scroll_cursor_top(&Default::default(), window, cx);
 49            }
 50            NextScrollCursorCenterTopBottom::Bottom => {
 51                self.scroll_cursor_bottom(&Default::default(), window, cx);
 52            }
 53        }
 54
 55        self.next_scroll_position = self.next_scroll_position.next();
 56        self._scroll_cursor_center_top_bottom_task = cx.spawn(async move |editor, cx| {
 57            cx.background_executor()
 58                .timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT)
 59                .await;
 60            editor
 61                .update(cx, |editor, _| {
 62                    editor.next_scroll_position = NextScrollCursorCenterTopBottom::default();
 63                })
 64                .ok();
 65        });
 66    }
 67
 68    pub fn scroll_cursor_top(
 69        &mut self,
 70        _: &ScrollCursorTop,
 71        window: &mut Window,
 72        cx: &mut Context<Editor>,
 73    ) {
 74        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
 75        let new_screen_top = self
 76            .selections
 77            .newest_display(&self.display_snapshot(cx))
 78            .head()
 79            .row()
 80            .0;
 81        let new_screen_top = new_screen_top.saturating_sub(scroll_margin_rows);
 82        self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
 83    }
 84
 85    pub fn scroll_cursor_center(
 86        &mut self,
 87        _: &ScrollCursorCenter,
 88        window: &mut Window,
 89        cx: &mut Context<Editor>,
 90    ) {
 91        let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
 92            return;
 93        };
 94        let new_screen_top = self
 95            .selections
 96            .newest_display(&self.display_snapshot(cx))
 97            .head()
 98            .row()
 99            .0;
100        let new_screen_top = new_screen_top.saturating_sub(visible_rows / 2);
101        self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
102    }
103
104    pub fn scroll_cursor_bottom(
105        &mut self,
106        _: &ScrollCursorBottom,
107        window: &mut Window,
108        cx: &mut Context<Editor>,
109    ) {
110        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
111        let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
112            return;
113        };
114        let new_screen_top = self
115            .selections
116            .newest_display(&self.display_snapshot(cx))
117            .head()
118            .row()
119            .0;
120        let new_screen_top =
121            new_screen_top.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
122        self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
123    }
124}