on master help sign in
fix: Adjust scroll offset/padding calculation to prevent wobble
6d52424Blaž Hrastnik
helix-term/src/commands.rs+11−5
@@ -110,10 +110,12 @@ fn align_view(doc: &Document, view: &mut View, align: Align) {
110 .cursor(doc.text().slice(..));
110 .cursor(doc.text().slice(..));
111 let line = doc.text().char_to_line(pos);
111 let line = doc.text().char_to_line(pos);
112
112
113+ let height = view.area.height.saturating_sub(1) as usize; // -1 for statusline
114+
113 let relative = match align {
115 let relative = match align {
114− Align::Center => view.area.height as usize / 2,
116+ Align::Center => height / 2,
115 Align::Top => 0,
117 Align::Top => 0,
116− Align::Bottom => view.area.height as usize,
118+ Align::Bottom => height,
117 };
119 };
118
120
119 view.first_line = line.saturating_sub(relative);
121 view.first_line = line.saturating_sub(relative);
@@ -448,17 +450,21 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
448fn goto_window(cx: &mut Context, align: Align) {
450fn goto_window(cx: &mut Context, align: Align) {
449 let (view, doc) = current!(cx.editor);
451 let (view, doc) = current!(cx.editor);
450
452
453+ let height = view.area.height.saturating_sub(1) as usize; // -1 for statusline
454+ // - 1 so we have at least one gap in the middle.
455+ // a height of 6 with padding of 3 on each side will keep shifting the view back and forth
456+ // as we type
451 let scrolloff = cx
457 let scrolloff = cx
452 .editor
458 .editor
453 .config
459 .config
454 .scrolloff
460 .scrolloff
455− .min(view.area.height as usize / 2); // TODO: user pref
461+ .min(height.saturating_sub(1) / 2);
456
462
457 let last_line = view.last_line(doc);
463 let last_line = view.last_line(doc);
458
464
459 let line = match align {
465 let line = match align {
460 Align::Top => (view.first_line + scrolloff),
466 Align::Top => (view.first_line + scrolloff),
461− Align::Center => (view.first_line + (view.area.height as usize / 2)),
467+ Align::Center => (view.first_line + (height / 2)),
462 Align::Bottom => last_line.saturating_sub(scrolloff),
468 Align::Bottom => last_line.saturating_sub(scrolloff),
463 }
469 }
464 .min(last_line.saturating_sub(scrolloff));
470 .min(last_line.saturating_sub(scrolloff));
@@ -894,7 +900,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
894 .editor
900 .editor
895 .config
901 .config
896 .scrolloff
902 .scrolloff
897− .min(view.area.height as usize / 2); // TODO: user pref
903+ .min(view.area.height as usize / 2);
898
904
899 view.first_line = match direction {
905 view.first_line = match direction {
900 Forward => view.first_line + offset,
906 Forward => view.first_line + offset,
helix-view/src/view.rs+4−1
@@ -93,7 +93,10 @@ impl View {
93 let height = self.area.height.saturating_sub(1); // - 1 for statusline
93 let height = self.area.height.saturating_sub(1); // - 1 for statusline
94 let last_line = (self.first_line + height as usize).saturating_sub(1);
94 let last_line = (self.first_line + height as usize).saturating_sub(1);
95
95
96+ // - 1 so we have at least one gap in the middle.
97+ // a height of 6 with padding of 3 on each side will keep shifting the view back and forth
98+ // as we type
96− let scrolloff = scrolloff.min(self.area.height as usize / 2);
99+ let scrolloff = scrolloff.min(height.saturating_sub(1) as usize / 2);
97
100
98 // TODO: not ideal
101 // TODO: not ideal
99 const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
102 const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter