Improve scrolloff behavior (#11323)

* Allow perfect centering of cursor

* Fix horizontal scrolloff

* Fix copypasta in comment
This commit is contained in:
Remo Senekowitsch 2024-07-26 17:20:33 +02:00 committed by GitHub
parent a1e20a3426
commit 229784ccc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -241,13 +241,23 @@ impl View {
let text_fmt = doc.text_format(viewport.width, None); let text_fmt = doc.text_format(viewport.width, None);
let annotations = self.text_annotations(doc, None); let annotations = self.text_annotations(doc, None);
// - 1 so we have at least one gap in the middle. let (scrolloff_top, scrolloff_bottom) = if CENTERING {
// a height of 6 with padding of 3 on each side will keep shifting the view back and forth (0, 0)
// as we type
let scrolloff = if CENTERING {
0
} else { } else {
scrolloff.min(viewport.height.saturating_sub(1) as usize / 2) (
// - 1 from the top so we have at least one gap in the middle.
scrolloff.min(viewport.height.saturating_sub(1) as usize / 2),
scrolloff.min(viewport.height as usize / 2),
)
};
let (scrolloff_left, scrolloff_right) = if CENTERING {
(0, 0)
} else {
(
// - 1 from the left so we have at least one gap in the middle.
scrolloff.min(viewport.width.saturating_sub(1) as usize / 2),
scrolloff.min(viewport.width as usize / 2),
)
}; };
let cursor = doc.selection(self.id).primary().cursor(doc_text); let cursor = doc.selection(self.id).primary().cursor(doc_text);
@ -262,14 +272,14 @@ impl View {
); );
let (new_anchor, at_top) = match off { let (new_anchor, at_top) = match off {
Ok((visual_pos, _)) if visual_pos.row < scrolloff + offset.vertical_offset => { Ok((visual_pos, _)) if visual_pos.row < scrolloff_top + offset.vertical_offset => {
if CENTERING { if CENTERING {
// cursor out of view // cursor out of view
return None; return None;
} }
(true, true) (true, true)
} }
Ok((visual_pos, _)) if visual_pos.row + scrolloff >= vertical_viewport_end => { Ok((visual_pos, _)) if visual_pos.row + scrolloff_bottom >= vertical_viewport_end => {
(true, false) (true, false)
} }
Ok((_, _)) => (false, false), Ok((_, _)) => (false, false),
@ -280,9 +290,9 @@ impl View {
if new_anchor { if new_anchor {
let v_off = if at_top { let v_off = if at_top {
scrolloff as isize scrolloff_top as isize
} else { } else {
viewport.height as isize - scrolloff as isize - 1 viewport.height as isize - scrolloff_bottom as isize - 1
}; };
(offset.anchor, offset.vertical_offset) = (offset.anchor, offset.vertical_offset) =
char_idx_at_visual_offset(doc_text, cursor, -v_off, 0, &text_fmt, &annotations); char_idx_at_visual_offset(doc_text, cursor, -v_off, 0, &text_fmt, &annotations);
@ -306,12 +316,12 @@ impl View {
.col; .col;
let last_col = offset.horizontal_offset + viewport.width.saturating_sub(1) as usize; let last_col = offset.horizontal_offset + viewport.width.saturating_sub(1) as usize;
if col > last_col.saturating_sub(scrolloff) { if col > last_col.saturating_sub(scrolloff_right) {
// scroll right // scroll right
offset.horizontal_offset += col - (last_col.saturating_sub(scrolloff)) offset.horizontal_offset += col - (last_col.saturating_sub(scrolloff_right))
} else if col < offset.horizontal_offset + scrolloff { } else if col < offset.horizontal_offset + scrolloff_left {
// scroll left // scroll left
offset.horizontal_offset = col.saturating_sub(scrolloff) offset.horizontal_offset = col.saturating_sub(scrolloff_left)
}; };
} }