actions.rs

  1use super::Axis;
  2use crate::{
  3    Autoscroll, Bias, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom,
  4    ScrollAnchor, ScrollCursorBottom, ScrollCursorCenter, ScrollCursorCenterTopBottom,
  5    ScrollCursorTop, SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT,
  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<f32>,
 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        let snapshot = self.snapshot(window, cx).display_snapshot;
 44        let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
 45            visible_rows as u32
 46        } else {
 47            return;
 48        };
 49
 50        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
 51        let mut new_screen_top = self.selections.newest_display(cx).head();
 52        *new_screen_top.column_mut() = 0;
 53        match self.next_scroll_position {
 54            NextScrollCursorCenterTopBottom::Center => {
 55                *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
 56            }
 57            NextScrollCursorCenterTopBottom::Top => {
 58                *new_screen_top.row_mut() =
 59                    new_screen_top.row().0.saturating_sub(scroll_margin_rows);
 60            }
 61            NextScrollCursorCenterTopBottom::Bottom => {
 62                *new_screen_top.row_mut() = new_screen_top
 63                    .row()
 64                    .0
 65                    .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
 66            }
 67        }
 68        self.set_scroll_anchor(
 69            ScrollAnchor {
 70                anchor: snapshot
 71                    .buffer_snapshot
 72                    .anchor_before(new_screen_top.to_offset(&snapshot, Bias::Left)),
 73                offset: Default::default(),
 74            },
 75            window,
 76            cx,
 77        );
 78
 79        self.next_scroll_position = self.next_scroll_position.next();
 80        self._scroll_cursor_center_top_bottom_task = cx.spawn(|editor, mut cx| async move {
 81            cx.background_executor()
 82                .timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT)
 83                .await;
 84            editor
 85                .update(&mut cx, |editor, _| {
 86                    editor.next_scroll_position = NextScrollCursorCenterTopBottom::default();
 87                })
 88                .ok();
 89        });
 90    }
 91
 92    pub fn scroll_cursor_top(
 93        &mut self,
 94        _: &ScrollCursorTop,
 95        window: &mut Window,
 96        cx: &mut Context<Editor>,
 97    ) {
 98        let snapshot = self.snapshot(window, cx).display_snapshot;
 99        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
100
101        let mut new_screen_top = self.selections.newest_display(cx).head();
102        *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(scroll_margin_rows);
103        *new_screen_top.column_mut() = 0;
104        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
105        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
106
107        self.set_scroll_anchor(
108            ScrollAnchor {
109                anchor: new_anchor,
110                offset: Default::default(),
111            },
112            window,
113            cx,
114        )
115    }
116
117    pub fn scroll_cursor_center(
118        &mut self,
119        _: &ScrollCursorCenter,
120        window: &mut Window,
121        cx: &mut Context<Editor>,
122    ) {
123        let snapshot = self.snapshot(window, cx).display_snapshot;
124        let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
125            visible_rows as u32
126        } else {
127            return;
128        };
129
130        let mut new_screen_top = self.selections.newest_display(cx).head();
131        *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
132        *new_screen_top.column_mut() = 0;
133        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
134        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
135
136        self.set_scroll_anchor(
137            ScrollAnchor {
138                anchor: new_anchor,
139                offset: Default::default(),
140            },
141            window,
142            cx,
143        )
144    }
145
146    pub fn scroll_cursor_bottom(
147        &mut self,
148        _: &ScrollCursorBottom,
149        window: &mut Window,
150        cx: &mut Context<Editor>,
151    ) {
152        let snapshot = self.snapshot(window, cx).display_snapshot;
153        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
154        let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
155            visible_rows as u32
156        } else {
157            return;
158        };
159
160        let mut new_screen_top = self.selections.newest_display(cx).head();
161        *new_screen_top.row_mut() = new_screen_top
162            .row()
163            .0
164            .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
165        *new_screen_top.column_mut() = 0;
166        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
167        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
168
169        self.set_scroll_anchor(
170            ScrollAnchor {
171                anchor: new_anchor,
172                offset: Default::default(),
173            },
174            window,
175            cx,
176        )
177    }
178}