summaryrefslogtreecommitdiff
path: root/src/panes.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/panes.zig')
-rw-r--r--src/panes.zig18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/panes.zig b/src/panes.zig
index a7e5c668..47582692 100644
--- a/src/panes.zig
+++ b/src/panes.zig
@@ -512,6 +512,16 @@ pub const Pane = struct {
}
}
+ /// Every line of the file's text fits in the body's rows; the empty
+ /// line after a final newline is no text.
+ pub fn textFits(pane: *Pane) bool {
+ if (pane.file) |*f| {
+ const lines = File.nlines(pane.gpa, f) - @intFromBool(std.mem.endsWith(u8, f.content, "\n"));
+ return lines <= pane.rows;
+ }
+ return false;
+ }
+
pub fn ensureCursorVisible(pane: *Pane) void {
const off = pane.scroll();
var in_context = false;
@@ -539,7 +549,13 @@ pub const Pane = struct {
pane.scrollBy(pane.body.cur_row - margin - off);
} else if (pane.body.cur_row > last - margin) {
var to = pane.body.cur_row + margin;
- if (pane.file) |*f| to = @min(to, @as(i32, @intCast(File.nlines(pane.gpa, f) -| 1)));
+ if (pane.file) |*f| {
+ // The margin only reveals text: a pane its whole text
+ // fits in never scrolls for it. A longer one keeps
+ // helix's clamp at the buffer's last line.
+ const lines: i32 = @intCast(File.nlines(pane.gpa, f));
+ to = @min(to, if (off == 0 and pane.textFits()) @max(pane.body.cur_row, lines - 1 - @intFromBool(std.mem.endsWith(u8, f.content, "\n"))) else lines - 1);
+ }
if (comptime Pdf.enabled) {
if (pane.pdf) |pv|
to = @min(to, @as(i32, @intCast(modal.lineCount(pv.text) -| 1)));