fix: Adjust scroll offset/padding calculation to prevent wobble

Fixes #324
pull/579/head
Blaž Hrastnik 3 years ago
parent 55f1f04717
commit 6d52424303

@ -110,10 +110,12 @@ fn align_view(doc: &Document, view: &mut View, align: Align) {
.cursor(doc.text().slice(..)); .cursor(doc.text().slice(..));
let line = doc.text().char_to_line(pos); let line = doc.text().char_to_line(pos);
let height = view.area.height.saturating_sub(1) as usize; // -1 for statusline
let relative = match align { let relative = match align {
Align::Center => view.area.height as usize / 2, Align::Center => height / 2,
Align::Top => 0, Align::Top => 0,
Align::Bottom => view.area.height as usize, Align::Bottom => height,
}; };
view.first_line = line.saturating_sub(relative); view.first_line = line.saturating_sub(relative);
@ -448,17 +450,21 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
fn goto_window(cx: &mut Context, align: Align) { fn goto_window(cx: &mut Context, align: Align) {
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
let height = view.area.height.saturating_sub(1) as usize; // -1 for statusline
// - 1 so we have at least one gap in the middle.
// a height of 6 with padding of 3 on each side will keep shifting the view back and forth
// as we type
let scrolloff = cx let scrolloff = cx
.editor .editor
.config .config
.scrolloff .scrolloff
.min(view.area.height as usize / 2); // TODO: user pref .min(height.saturating_sub(1) / 2);
let last_line = view.last_line(doc); let last_line = view.last_line(doc);
let line = match align { let line = match align {
Align::Top => (view.first_line + scrolloff), Align::Top => (view.first_line + scrolloff),
Align::Center => (view.first_line + (view.area.height as usize / 2)), Align::Center => (view.first_line + (height / 2)),
Align::Bottom => last_line.saturating_sub(scrolloff), Align::Bottom => last_line.saturating_sub(scrolloff),
} }
.min(last_line.saturating_sub(scrolloff)); .min(last_line.saturating_sub(scrolloff));
@ -894,7 +900,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
.editor .editor
.config .config
.scrolloff .scrolloff
.min(view.area.height as usize / 2); // TODO: user pref .min(view.area.height as usize / 2);
view.first_line = match direction { view.first_line = match direction {
Forward => view.first_line + offset, Forward => view.first_line + offset,

@ -93,7 +93,10 @@ impl View {
let height = self.area.height.saturating_sub(1); // - 1 for statusline let height = self.area.height.saturating_sub(1); // - 1 for statusline
let last_line = (self.first_line + height as usize).saturating_sub(1); let last_line = (self.first_line + height as usize).saturating_sub(1);
let scrolloff = scrolloff.min(self.area.height as usize / 2); // - 1 so we have at least one gap in the middle.
// a height of 6 with padding of 3 on each side will keep shifting the view back and forth
// as we type
let scrolloff = scrolloff.min(height.saturating_sub(1) as usize / 2);
// TODO: not ideal // TODO: not ideal
const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter

Loading…
Cancel
Save