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 display_snapshot = self.display_snapshot(cx);
 75        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
 76        let new_screen_top = self
 77            .selections
 78            .newest_display(&display_snapshot)
 79            .head()
 80            .row()
 81            .0;
 82        let header_offset = display_snapshot
 83            .buffer_snapshot()
 84            .show_headers()
 85            .then(|| display_snapshot.buffer_header_height())
 86            .unwrap_or(0);
 87        let new_screen_top = new_screen_top.saturating_sub(scroll_margin_rows + header_offset);
 88        self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
 89    }
 90
 91    pub fn scroll_cursor_center(
 92        &mut self,
 93        _: &ScrollCursorCenter,
 94        window: &mut Window,
 95        cx: &mut Context<Editor>,
 96    ) {
 97        let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
 98            return;
 99        };
100        let new_screen_top = self
101            .selections
102            .newest_display(&self.display_snapshot(cx))
103            .head()
104            .row()
105            .0;
106        let new_screen_top = new_screen_top.saturating_sub(visible_rows / 2);
107        self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
108    }
109
110    pub fn scroll_cursor_bottom(
111        &mut self,
112        _: &ScrollCursorBottom,
113        window: &mut Window,
114        cx: &mut Context<Editor>,
115    ) {
116        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
117        let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
118            return;
119        };
120        let new_screen_top = self
121            .selections
122            .newest_display(&self.display_snapshot(cx))
123            .head()
124            .row()
125            .0;
126        let new_screen_top =
127            new_screen_top.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
128        self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
129    }
130}