From 180521fefec8923bd4082c4a1e9beca599a44d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Wed, 14 Apr 2021 14:27:47 +0900 Subject: [PATCH] Adjust scroll() to match kakoune: only scroll the view if cursor in bounds. --- helix-term/src/commands.rs | 16 +++++++++++----- helix-view/src/view.rs | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index f1c5f8b5a..190ae3b93 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -450,10 +450,11 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) { return; } - let scrolloff = PADDING; // min(user pref, half win width/height) + let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref // cursor visual offset - let cursor_off = cursor.row - view.first_line; + // TODO: only if dragging via mouse? + // let cursor_off = cursor.row - view.first_line; view.first_line = match direction { Forward => view.first_line + offset, @@ -461,14 +462,19 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) { } .min(doc_last_line); + // recalculate last line + let last_line = view.last_line(doc); + // clamp into viewport - let line = (view.first_line + cursor_off) - .max(view.first_line + scrolloff) - .min(last_line.saturating_sub(scrolloff)); + let line = cursor.row.clamp( + view.first_line + scrolloff, + last_line.saturating_sub(scrolloff), + ); let text = doc.text().slice(..); let pos = pos_at_coords(text, Position::new(line, cursor.col)); // this func will properly truncate to line end + // TODO: only manipulate main selection doc.set_selection(view.id, Selection::point(pos)); } diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 93bb005e4..1bf7c370a 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -81,26 +81,28 @@ impl View { let pos = coords_at_pos(doc.text().slice(..), cursor); let line = pos.row; let col = pos.col; - let last_line = self.first_line + (self.area.height as usize).saturating_sub(2); + let last_line = self.last_line(doc); + + let scrolloff = PADDING.min(self.area.height as usize / 2); // TODO: user pref // TODO: not ideal const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter let last_col = self.first_col + (self.area.width as usize - OFFSET); - if line > last_line.saturating_sub(PADDING) { + if line > last_line.saturating_sub(scrolloff) { // scroll down - self.first_line += line - (last_line.saturating_sub(PADDING)); - } else if line < self.first_line + PADDING { + self.first_line += line - (last_line.saturating_sub(scrolloff)); + } else if line < self.first_line + scrolloff { // scroll up - self.first_line = line.saturating_sub(PADDING); + self.first_line = line.saturating_sub(scrolloff); } - if col > last_col.saturating_sub(PADDING) { + if col > last_col.saturating_sub(scrolloff) { // scroll right - self.first_col += col - (last_col.saturating_sub(PADDING)); - } else if col < self.first_col + PADDING { + self.first_col += col - (last_col.saturating_sub(scrolloff)); + } else if col < self.first_col + scrolloff { // scroll left - self.first_col = col.saturating_sub(PADDING); + self.first_col = col.saturating_sub(scrolloff); } }