diff options
| author | Gabriel Schneider <[email protected]> | 2026-07-06 15:07:28 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-01 15:02:07 -0300 |
| commit | 5552ecb3460a8c91d12e0469ba12debe688cc6f8 (patch) | |
| tree | 100a0c96a0db2f552ad5e356042b9e1a19780d72 /src | |
| parent | de4def3548a6729b0dfd2120495a61beef8c8c2c (diff) | |
| download | pardes-5552ecb3460a8c91d12e0469ba12debe688cc6f8.tar.gz pardes-5552ecb3460a8c91d12e0469ba12debe688cc6f8.zip | |
scrolloff: keyboard cursor moves keep 3 context rows above/below the cursor (vim scrolloff). One reconcile in Pane.ensureCursorVisible — every keyboard path (normal-mode motions, insert entry/edits, delete/yank/paste/undo/redo) already funnels through it; mouse click/wheel untouched. Clamps: line 0 at top, EOF-at-bottom-row for files (terminals let the vt clamp at the live bottom), margin shrinks on panes shorter than 2*off+1. New scrolloff.snap golden proves j-walk scroll at the margin, gg/top-row reachability, k-walk margin, G bottom clamp. 19/19 snapshots green; no existing goldens changed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/pardes.zig | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index c4893b25..eab8aa7e 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -31,6 +31,9 @@ pub const BOX_H: u16 = 1; pub const MINW: u16 = 10; pub const MINH: u16 = 3; pub const PREFIX_W: u16 = 5; +/// vim 'scrolloff': keyboard cursor moves keep this many context rows visible +/// above/below the cursor (clamped at file boundaries and short panes) +const scroll_off = 3; pub const topbar_str = "Kill Newcol Tutor Debug Colors NextColor Dump"; const pane_builtins_str = "Del"; @@ -523,9 +526,19 @@ pub const Pane = struct { } fn ensureCursorVisible(pane: *Pane) void { + // scrolloff margin, shrunk on short panes so the band stays non-empty + const margin: i32 = @min(scroll_off, @divTrunc(@as(i32, pane.rows) - 1, 2)); const off = pane.scroll(); const last = off + @as(i32, pane.rows) - 1; - if (pane.cur_row < off) pane.scrollBy(pane.cur_row - off) else if (pane.cur_row > last) pane.scrollBy(pane.cur_row - last); + if (pane.cur_row < off + margin) { + pane.scrollBy(pane.cur_row - margin - off); // scrollBy clamps at line 0 + } else if (pane.cur_row > last - margin) { + // don't scroll a file past EOF-at-bottom-row (vim's bottom clamp); + // terminals overshoot harmlessly — the vt clamps at the live bottom + var to = pane.cur_row + margin; + if (pane.file) |f| to = @min(to, @as(i32, @intCast(modal.lineCount(f.content) -| 1))); + pane.scrollBy(@max(0, to - last)); + } } /// the last navigable row: file -> last content line; terminal -> viewport bottom |
