on master help sign in
Adjust scroll() to match kakoune: only scroll the view if cursor in bounds.
180521fBlaž Hrastnik
helix-term/src/commands.rs+11−5
@@ -450,10 +450,11 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
450 return;
450 return;
451 }
451 }
452
452
453− let scrolloff = PADDING; // min(user pref, half win width/height)
453+ let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref
454
454
455 // cursor visual offset
455 // cursor visual offset
456+ // TODO: only if dragging via mouse?
456− let cursor_off = cursor.row - view.first_line;
457+ // let cursor_off = cursor.row - view.first_line;
457
458
458 view.first_line = match direction {
459 view.first_line = match direction {
459 Forward => view.first_line + offset,
460 Forward => view.first_line + offset,
@@ -461,14 +462,19 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
461 }
462 }
462 .min(doc_last_line);
463 .min(doc_last_line);
463
464
465+ // recalculate last line
466+ let last_line = view.last_line(doc);
467+
464 // clamp into viewport
468 // clamp into viewport
465− let line = (view.first_line + cursor_off)
469+ let line = cursor.row.clamp(
466− .max(view.first_line + scrolloff)
470+ view.first_line + scrolloff,
467− .min(last_line.saturating_sub(scrolloff));
471+ last_line.saturating_sub(scrolloff),
472+ );
468
473
469 let text = doc.text().slice(..);
474 let text = doc.text().slice(..);
470 let pos = pos_at_coords(text, Position::new(line, cursor.col)); // this func will properly truncate to line end
475 let pos = pos_at_coords(text, Position::new(line, cursor.col)); // this func will properly truncate to line end
471
476
477+ // TODO: only manipulate main selection
472 doc.set_selection(view.id, Selection::point(pos));
478 doc.set_selection(view.id, Selection::point(pos));
473}
479}
474
480
helix-view/src/view.rs+11−9
@@ -81,26 +81,28 @@ impl View {
81 let pos = coords_at_pos(doc.text().slice(..), cursor);
81 let pos = coords_at_pos(doc.text().slice(..), cursor);
82 let line = pos.row;
82 let line = pos.row;
83 let col = pos.col;
83 let col = pos.col;
84− let last_line = self.first_line + (self.area.height as usize).saturating_sub(2);
84+ let last_line = self.last_line(doc);
85+
86+ let scrolloff = PADDING.min(self.area.height as usize / 2); // TODO: user pref
85
87
86 // TODO: not ideal
88 // TODO: not ideal
87 const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
89 const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
88 let last_col = self.first_col + (self.area.width as usize - OFFSET);
90 let last_col = self.first_col + (self.area.width as usize - OFFSET);
89
91
90− if line > last_line.saturating_sub(PADDING) {
92+ if line > last_line.saturating_sub(scrolloff) {
91 // scroll down
93 // scroll down
92− self.first_line += line - (last_line.saturating_sub(PADDING));
94+ self.first_line += line - (last_line.saturating_sub(scrolloff));
93− } else if line < self.first_line + PADDING {
95+ } else if line < self.first_line + scrolloff {
94 // scroll up
96 // scroll up
95− self.first_line = line.saturating_sub(PADDING);
97+ self.first_line = line.saturating_sub(scrolloff);
96 }
98 }
97
99
98− if col > last_col.saturating_sub(PADDING) {
100+ if col > last_col.saturating_sub(scrolloff) {
99 // scroll right
101 // scroll right
100− self.first_col += col - (last_col.saturating_sub(PADDING));
102+ self.first_col += col - (last_col.saturating_sub(scrolloff));
101− } else if col < self.first_col + PADDING {
103+ } else if col < self.first_col + scrolloff {
102 // scroll left
104 // scroll left
103− self.first_col = col.saturating_sub(PADDING);
105+ self.first_col = col.saturating_sub(scrolloff);
104 }
106 }
105 }
107 }
106
108