From 229784ccc7833a52bc88c7a8b60ecb1d56303593 Mon Sep 17 00:00:00 2001 From: Remo Senekowitsch Date: Fri, 26 Jul 2024 17:20:33 +0200 Subject: [PATCH] Improve scrolloff behavior (#11323) * Allow perfect centering of cursor * Fix horizontal scrolloff * Fix copypasta in comment --- helix-view/src/view.rs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index fb83c4b86..a229f01ea 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -241,13 +241,23 @@ pub fn offset_coords_to_in_view_center( let text_fmt = doc.text_format(viewport.width, None); let annotations = self.text_annotations(doc, None); - // - 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 = if CENTERING { - 0 + let (scrolloff_top, scrolloff_bottom) = if CENTERING { + (0, 0) } 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); @@ -262,14 +272,14 @@ pub fn offset_coords_to_in_view_center( ); 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 { // cursor out of view return None; } (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) } Ok((_, _)) => (false, false), @@ -280,9 +290,9 @@ pub fn offset_coords_to_in_view_center( if new_anchor { let v_off = if at_top { - scrolloff as isize + scrolloff_top as isize } else { - viewport.height as isize - scrolloff as isize - 1 + viewport.height as isize - scrolloff_bottom as isize - 1 }; (offset.anchor, offset.vertical_offset) = char_idx_at_visual_offset(doc_text, cursor, -v_off, 0, &text_fmt, &annotations); @@ -306,12 +316,12 @@ pub fn offset_coords_to_in_view_center( .col; 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 - offset.horizontal_offset += col - (last_col.saturating_sub(scrolloff)) - } else if col < offset.horizontal_offset + scrolloff { + offset.horizontal_offset += col - (last_col.saturating_sub(scrolloff_right)) + } else if col < offset.horizontal_offset + scrolloff_left { // scroll left - offset.horizontal_offset = col.saturating_sub(scrolloff) + offset.horizontal_offset = col.saturating_sub(scrolloff_left) }; }