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}