╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │206 } │ │207 } │ │208 │ │200 - const shown = hunks.items.len; │ │201 - return .{ .hunks = try hunks.toOwnedSlice(arena), .shown_hunks = shown, .has_more = has_more }; │ │209 + return .{ .hunks = try hunks.toOwnedSlice(arena), .has_prev = start > 0, .has_more = has_more };│ │210 } │ │211 │ │212 // append a hunk's header and its edit lines, each prefixed with a right-aligned │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │307 try addRow(allocator, &list_box, commit.message, ""); │ │308 } │ │309 if (data.next_start) |next| { │ │302 - try addRow(allocator, &list_box, "next", try commitsLink(session.page_arena, data.identity, next, 0)); │ │310 + try addRow(allocator, &list_box, "next →", try commitsLink(session.page_arena, data.identity, next, 0));│ │311 } │ │312 if (list_box.children.count() > 0) list_box.getFocus().child_id = list_box.children.keys()[0]; │ │313 break :blk try wgt.Scroll(ui.Widget).init(allocator, .{ .box = list_box }, .{ .direction = .vert }); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │374 try box.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null }); │ │375 } │ │376 │ │369 - // the focusable "load more" row. it's a navigation link to this commit's │ │370 - // route with a larger `after`, so activating it (the host follows the "a:" │ │371 - // link) reloads the page showing more hunks — the same on the TUI and web. │ │372 - fn addLoadMore(self: *View, allocator: std.mem.Allocator, box: *wgt.Box(ui.Widget), oid: []const u8, next_after: usize) !void { │ │373 - const link = try commitsLink(self.session.page_arena, self.data.identity, oid, next_after); │ │374 - var tb = try wgt.TextBox(ui.Widget).init(allocator, "load more", .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .none }); │ │377 + // a focusable window-navigation row ("previous"/"next"). it's a link to this │ │378 + // commit's route at `target_after`, so activating it (the host follows the │ │379 + // "a:" link) reloads the page on the adjacent window — same on TUI and web. │ │380 + fn addNavLink(self: *View, allocator: std.mem.Allocator, box: *wgt.Box(ui.Widget), label: []const u8, oid: []const u8, target_after: usize) !void {│ │381 + const link = try commitsLink(self.session.page_arena, self.data.identity, oid, target_after); │ │382 + var tb = try wgt.TextBox(ui.Widget).init(allocator, label, .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .none }); │ │383 errdefer tb.deinit(allocator); │ │384 tb.getFocus().focusable = true; │ │385 tb.getFocus().kind = .{ .custom = link }; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │436 if (root_focus.grandchild_id) |g| { │ │437 if (self.box.getFocus().children.contains(g)) { │ │438 if (self.selectedCommitIndex()) |sel| { │ │431 - // selection moves reset the diff expansion (after = 0). │ │432 - if (ui.RoutablePage.repoCommitsRoute(self.data.identity, self.data.commits[sel].oid, 0)) |route| │ │439 + // mirror the commit's current diff window so the url stays │ │440 + // linkable (0 for any commit but the windowed start one). │ │441 + if (ui.RoutablePage.repoCommitsRoute(self.data.identity, self.data.commits[sel].oid, self.data.commits[sel].window_start)) |route|│ │442 self.session.data.current_page = route; │ │443 } │ │444 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │508 inner.children.clearAndFree(allocator); │ │509 inner.getFocus().child_id = null; │ │510 │ │511 + // a "previous" row at the top and a "next" row at the bottom reload the │ │512 + // page on the adjacent diff window. │ │513 + if (commit.has_prev) try self.addNavLink(allocator, inner, "← previous", commit.oid, commit.window_start -| diff_page);│ │514 for (commit.hunks) |hunk| { │ │515 if (hunk.path) |path| try self.addPathBox(allocator, inner, path); │ │516 try self.addHunkBox(allocator, inner, hunk.lines); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │517 } │ │506 - // the load-more link reloads showing one more page of this commit's hunks. │ │507 - if (commit.has_more) try self.addLoadMore(allocator, inner, commit.oid, commit.shown_hunks + diff_page); │ │518 + if (commit.has_more) try self.addNavLink(allocator, inner, "next →", commit.oid, commit.window_start + diff_page);│ │519 │ │520 const sc = self.diffScroll(); │ │521 sc.x = 0; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │567 .arrow_down => try self.moveDiff(root_focus, 1), │ │568 .page_up => try self.pageDiff(root_focus, -page_rows), │ │569 .page_down => try self.pageDiff(root_focus, page_rows), │ │559 - // Enter / a click on the "load more" row follow its "a:" link in the │ │560 - // host (it reloads the page with more hunks), so they don't reach here. │ │570 + // Enter / a click on a "previous"/"next" row follow its "a:" link in │ │571 + // the host (it reloads the adjacent window), so they don't reach here. │ │572 .mouse => |mouse| switch (mouse.action) { │ │573 .scroll => |dir| try self.moveDiff(root_focus, if (dir == .up) -1 else 1),│ │574 else => {}, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯