actions.rs

  1use gpui::{actions, geometry::vector::Vector2F, AppContext, Axis, ViewContext};
  2use language::Bias;
  3
  4use crate::{Editor, EditorMode};
  5
  6use super::{autoscroll::Autoscroll, scroll_amount::ScrollAmount, ScrollAnchor};
  7
  8actions!(
  9    editor,
 10    [
 11        LineDown,
 12        LineUp,
 13        HalfPageDown,
 14        HalfPageUp,
 15        PageDown,
 16        PageUp,
 17        NextScreen,
 18        ScrollCursorTop,
 19        ScrollCursorCenter,
 20        ScrollCursorBottom,
 21    ]
 22);
 23
 24pub fn init(cx: &mut AppContext) {
 25    cx.add_action(Editor::next_screen);
 26    cx.add_action(Editor::scroll_cursor_top);
 27    cx.add_action(Editor::scroll_cursor_center);
 28    cx.add_action(Editor::scroll_cursor_bottom);
 29    cx.add_action(|this: &mut Editor, _: &LineDown, cx| {
 30        this.scroll_screen(&ScrollAmount::Line(1.), cx)
 31    });
 32    cx.add_action(|this: &mut Editor, _: &LineUp, cx| {
 33        this.scroll_screen(&ScrollAmount::Line(-1.), cx)
 34    });
 35    cx.add_action(|this: &mut Editor, _: &HalfPageDown, cx| {
 36        this.scroll_screen(&ScrollAmount::Page(0.5), cx)
 37    });
 38    cx.add_action(|this: &mut Editor, _: &HalfPageUp, cx| {
 39        this.scroll_screen(&ScrollAmount::Page(-0.5), cx)
 40    });
 41    cx.add_action(|this: &mut Editor, _: &PageDown, cx| {
 42        this.scroll_screen(&ScrollAmount::Page(1.), cx)
 43    });
 44    cx.add_action(|this: &mut Editor, _: &PageUp, cx| {
 45        this.scroll_screen(&ScrollAmount::Page(-1.), cx)
 46    });
 47}
 48
 49impl Editor {
 50    pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) -> Option<()> {
 51        if self.take_rename(true, cx).is_some() {
 52            return None;
 53        }
 54
 55        if self.mouse_context_menu.read(cx).visible() {
 56            return None;
 57        }
 58
 59        if matches!(self.mode, EditorMode::SingleLine) {
 60            cx.propagate_action();
 61            return None;
 62        }
 63        self.request_autoscroll(Autoscroll::Next, cx);
 64        Some(())
 65    }
 66
 67    pub fn scroll(
 68        &mut self,
 69        scroll_position: Vector2F,
 70        axis: Option<Axis>,
 71        cx: &mut ViewContext<Self>,
 72    ) {
 73        self.scroll_manager.update_ongoing_scroll(axis);
 74        self.set_scroll_position(scroll_position, cx);
 75    }
 76
 77    fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
 78        let snapshot = editor.snapshot(cx).display_snapshot;
 79        let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
 80
 81        let mut new_screen_top = editor.selections.newest_display(cx).head();
 82        *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
 83        *new_screen_top.column_mut() = 0;
 84        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
 85        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
 86
 87        editor.set_scroll_anchor(
 88            ScrollAnchor {
 89                anchor: new_anchor,
 90                offset: Default::default(),
 91            },
 92            cx,
 93        )
 94    }
 95
 96    fn scroll_cursor_center(
 97        editor: &mut Editor,
 98        _: &ScrollCursorCenter,
 99        cx: &mut ViewContext<Editor>,
100    ) {
101        let snapshot = editor.snapshot(cx).display_snapshot;
102        let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
103            visible_rows as u32
104        } else {
105            return;
106        };
107
108        let mut new_screen_top = editor.selections.newest_display(cx).head();
109        *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
110        *new_screen_top.column_mut() = 0;
111        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
112        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
113
114        editor.set_scroll_anchor(
115            ScrollAnchor {
116                anchor: new_anchor,
117                offset: Default::default(),
118            },
119            cx,
120        )
121    }
122
123    fn scroll_cursor_bottom(
124        editor: &mut Editor,
125        _: &ScrollCursorBottom,
126        cx: &mut ViewContext<Editor>,
127    ) {
128        let snapshot = editor.snapshot(cx).display_snapshot;
129        let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
130        let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
131            visible_rows as u32
132        } else {
133            return;
134        };
135
136        let mut new_screen_top = editor.selections.newest_display(cx).head();
137        *new_screen_top.row_mut() = new_screen_top
138            .row()
139            .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
140        *new_screen_top.column_mut() = 0;
141        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
142        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
143
144        editor.set_scroll_anchor(
145            ScrollAnchor {
146                anchor: new_anchor,
147                offset: Default::default(),
148            },
149            cx,
150        )
151    }
152}