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::{AsyncWindowContext, Point, ViewContext};
  8
  9impl Editor {
 10    pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) {
 11        if self.take_rename(true, 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        cx: &mut ViewContext<Self>,
 31    ) {
 32        self.scroll_manager.update_ongoing_scroll(axis);
 33        self.set_scroll_position(scroll_position, cx);
 34    }
 35
 36    pub fn scroll_cursor_center_top_bottom(
 37        &mut self,
 38        _: &ScrollCursorCenterTopBottom,
 39        cx: &mut ViewContext<Self>,
 40    ) {
 41        let snapshot = self.snapshot(cx).display_snapshot;
 42        let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
 43            visible_rows as u32
 44        } else {
 45            return;
 46        };
 47
 48        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
 49        let mut new_screen_top = self.selections.newest_display(cx).head();
 50        *new_screen_top.column_mut() = 0;
 51        match self.next_scroll_position {
 52            NextScrollCursorCenterTopBottom::Center => {
 53                *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
 54            }
 55            NextScrollCursorCenterTopBottom::Top => {
 56                *new_screen_top.row_mut() =
 57                    new_screen_top.row().0.saturating_sub(scroll_margin_rows);
 58            }
 59            NextScrollCursorCenterTopBottom::Bottom => {
 60                *new_screen_top.row_mut() = new_screen_top
 61                    .row()
 62                    .0
 63                    .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
 64            }
 65        }
 66        self.set_scroll_anchor(
 67            ScrollAnchor {
 68                anchor: snapshot
 69                    .buffer_snapshot
 70                    .anchor_before(new_screen_top.to_offset(&snapshot, Bias::Left)),
 71                offset: Default::default(),
 72            },
 73            cx,
 74        );
 75
 76        self.next_scroll_position = self.next_scroll_position.next();
 77        self._scroll_cursor_center_top_bottom_task =
 78            cx.spawn(|editor, mut cx: AsyncWindowContext| async move {
 79                cx.background_executor()
 80                    .timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT)
 81                    .await;
 82                editor
 83                    .update(&mut cx, |editor, _| {
 84                        editor.next_scroll_position = NextScrollCursorCenterTopBottom::default();
 85                    })
 86                    .ok();
 87            });
 88    }
 89
 90    pub fn scroll_cursor_top(&mut self, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
 91        let snapshot = self.snapshot(cx).display_snapshot;
 92        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
 93
 94        let mut new_screen_top = self.selections.newest_display(cx).head();
 95        *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(scroll_margin_rows);
 96        *new_screen_top.column_mut() = 0;
 97        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
 98        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
 99
100        self.set_scroll_anchor(
101            ScrollAnchor {
102                anchor: new_anchor,
103                offset: Default::default(),
104            },
105            cx,
106        )
107    }
108
109    pub fn scroll_cursor_center(&mut self, _: &ScrollCursorCenter, cx: &mut ViewContext<Editor>) {
110        let snapshot = self.snapshot(cx).display_snapshot;
111        let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
112            visible_rows as u32
113        } else {
114            return;
115        };
116
117        let mut new_screen_top = self.selections.newest_display(cx).head();
118        *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
119        *new_screen_top.column_mut() = 0;
120        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
121        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
122
123        self.set_scroll_anchor(
124            ScrollAnchor {
125                anchor: new_anchor,
126                offset: Default::default(),
127            },
128            cx,
129        )
130    }
131
132    pub fn scroll_cursor_bottom(&mut self, _: &ScrollCursorBottom, cx: &mut ViewContext<Editor>) {
133        let snapshot = self.snapshot(cx).display_snapshot;
134        let scroll_margin_rows = self.vertical_scroll_margin() as u32;
135        let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
136            visible_rows as u32
137        } else {
138            return;
139        };
140
141        let mut new_screen_top = self.selections.newest_display(cx).head();
142        *new_screen_top.row_mut() = new_screen_top
143            .row()
144            .0
145            .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
146        *new_screen_top.column_mut() = 0;
147        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
148        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
149
150        self.set_scroll_anchor(
151            ScrollAnchor {
152                anchor: new_anchor,
153                offset: Default::default(),
154            },
155            cx,
156        )
157    }
158}