diff options
| -rw-r--r-- | src/pardes.zig | 15 | ||||
| -rw-r--r-- | test/snapshots/scrolloff.golden | 217 | ||||
| -rw-r--r-- | test/snapshots/scrolloff.snap | 41 |
3 files changed, 272 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 diff --git a/test/snapshots/scrolloff.golden b/test/snapshots/scrolloff.golden new file mode 100644 index 00000000..ed0992ad --- /dev/null +++ b/test/snapshots/scrolloff.golden @@ -0,0 +1,217 @@ +== snap top grid=100x30 cursor=7,2 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 1 line 1 +| 2 line 2 g.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 line 7 +| 8 line 8 +| 9 line 9 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +== snap edge grid=100x30 cursor=7,7 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 1 line 1 +| 2 line 2 g.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 line 7 +| 8 line 8 +| 9 line 9 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +== snap scrolled1 grid=100x30 cursor=7,7 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 2 line 2 +| 3 line 3 g.txt +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 line 7 +| 8 line 8 +| 9 line 9 +| 10 line 10 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +== snap jdown grid=100x30 cursor=7,7 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 6 line 6 +| 7 line 7 g.txt +| 8 line 8 +| 9 line 9 +| 10 line 10 +| 11 line 11 +| 12 line 12 +| 13 line 13 +| 14 line 14 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +== snap end grid=100x30 cursor=7,10 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 33 line 33 +| 34 line 34 g.txt +| 35 line 35 +| 36 line 36 +| 37 line 37 +| 38 line 38 +| 39 line 39 +| 40 line 40 +| 41 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +== snap kup grid=100x30 cursor=7,5 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 30 line 30 +| 31 line 31 g.txt +| 32 line 32 +| 33 line 33 +| 34 line 34 +| 35 line 35 +| 36 line 36 +| 37 line 37 +| 38 line 38 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +== snap top2 grid=100x30 cursor=7,2 +|Kill Newcol Tutor Debug Colors NextColor Dump +| nm /tmp/pardes-snap/scrolloff/cwd/g.txt Save Del nm /tmp/pardes-snap/scrolloff/cwd Del +| 1 line 1 +| 2 line 2 g.txt +| 3 line 3 +| 4 line 4 +| 5 line 5 +| 6 line 6 +| 7 line 7 +| 8 line 8 +| 9 line 9 +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| +| +| nm /tmp/pardes-snap/scrolloff/cwd Del +| +| g.txt +| +| +| +| +| +| diff --git a/test/snapshots/scrolloff.snap b/test/snapshots/scrolloff.snap new file mode 100644 index 00000000..e231e8de --- /dev/null +++ b/test/snapshots/scrolloff.snap @@ -0,0 +1,41 @@ +# scrolloff: keyboard motion keeps 3 context rows above/below the cursor, +# clamped at file boundaries (cursor may reach the top/bottom body row there) +lines g.txt 40 +start 30 100 +wait 8000 g.txt +stable 700 20000 +# right-click the g.txt name in the greeting ls -> file pane, 9 body rows +press right 4 4 +release right 4 4 +wait 10000 line 3 +stable 700 15000 +press left 10 3 +release left 10 3 +stable 400 5000 +# (b) gg: cursor CAN sit on the top body row, no forced scroll +key g g +stable 400 5000 +snap top +# (a) five j's reach the bottom margin (visual row 5 of 9) without scrolling... +key j j j j j +stable 400 5000 +snap edge +# ...the sixth j scrolls: view slides one line, cursor holds the margin +key j +stable 400 5000 +snap scrolled1 +key j j j j +stable 400 5000 +snap jdown +# (d) G: bottom clamp, view stops at EOF-at-bottom, cursor on the bottom row +key G +stable 400 5000 +snap end +# (c) k-walk up: cursor climbs to the top margin, then the view scrolls +key k k k k k k k k +stable 400 5000 +snap kup +# (b) again from deep in the file: gg puts the cursor back on the top row +key g g +stable 400 5000 +snap top2 |
