╭ changed ────────────╮ │src/ui/Repo/Files.zig│ ╰─────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │14 const inp = @import("../input.zig"); │ │15 │ │16 // how many lines of a file's content one window shows before a "next" link. │ │17 -const file_page = 2000; │ │17 +const file_page = 5000; │ │18 │ │19 // how many files in a directory get their content preloaded (windowed) so │ │20 // selecting them shows contents without a reload. every entry is still listed;│ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │33 // pane shows a placeholder rather than its bytes. │ │34 is_binary: bool = false, │ │35 // the line index this window starts at (0 = the first window). non-zero only│ │36 - // for the route's selected file, paginated by the url's `start`. │ │36 + // for the route's selected file, paginated by the url's `line`. │ │37 window_start: usize = 0, │ │38 // whether more lines exist after this window. │ │39 has_more: bool = false, │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────╮ │75 requested_ref_or_oid: ?ui.RoutablePage.RefOrOid,│ │76 requested_value: []const u8, │ │77 path: []const u8, │ │78 - start: usize, │ │78 + line: usize, │ │79 ) !Self { │ │80 const aa = arena.allocator(); │ │81 │ ╰────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │129 if (preloaded < max_preloaded or is_selected or isReadme(name)) { │ │130 preloaded += 1; │ │131 const file_path = try childDir(aa, dir, name); │ │132 - const window_start = if (is_selected) start else 0; │ │132 + // the url's `line` is 1-based (0 = unset); the window │ │133 + // index is 0-based. │ │134 + const window_start = if (is_selected) line -| 1 else 0; │ │135 const content = readFileContent(repo_kind, repo_opts, state, io, gpa, aa, file_path, tree_entry, window_start) catch│ │136 FileContent{ .lines = &.{} }; │ │137 entry.lines = content.lines; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │445 if (self.box.getFocus().children.contains(g)) { │ │446 var buf: [ui.RoutablePage.repo_route_max_len]u8 = undefined;│ │447 var sel_path = self.data.dir; │ │446 - var sel_start: usize = 0; │ │448 + var sel_line: usize = 0; │ │449 if (self.selectedEntry()) |entry| { │ │450 if (!entry.is_dir and entry.loaded) { │ │451 sel_path = if (self.data.dir.len == 0) │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │452 entry.name │ │453 else │ │454 std.fmt.bufPrint(&buf, "{s}/{s}", .{ self.data.dir, entry.name }) catch self.data.dir; │ │453 - sel_start = entry.window_start; │ │455 + sel_line = lineNumber(entry.window_start); │ │456 } │ │457 } │ │456 - if (ui.RoutablePage.repoFilesRoute(self.data.identity, self.data.ref_or_oid, self.data.ref_or_oid_value, sel_path, sel_start)) |route|│ │458 + if (ui.RoutablePage.repoFilesRoute(self.data.identity, self.data.ref_or_oid, self.data.ref_or_oid_value, sel_path, sel_line)) |route| │ │459 self.session.data.current_page = route; │ │460 } │ │461 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │538 // the window links sit above the scroll, so they stay put │ │539 // while the content scrolls. │ │540 if (entry.window_start > 0) try self.addNavLink(allocator, nav_box, "scroll to top", entry, 0); │ │539 - if (entry.has_more) try self.addNavLink(allocator, nav_box, "next lines →", entry, entry.window_start + file_page); │ │541 + if (entry.has_more) try self.addNavLink(allocator, nav_box, "next lines →", entry, lineNumber(entry.window_start + file_page));│ │542 if (!entry.loaded) { │ │543 // the placeholder carries the file's "a:" link, so enter │ │544 // (or a click) here loads the file like on its list row. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │812 const route = ui.RoutablePage.repoFilesRoute(data.identity, data.ref_or_oid, data.ref_or_oid_value, path, 0) orelse return error.RouteTooLong;│ │813 const prefix = if (loaded) "ai:" else "a:"; │ │814 return std.fmt.allocPrint(page_arena.allocator(), "{s}{s}", .{ prefix, try route.toUrl(page_arena) }); │ │815 +} │ │816 + │ │817 +// the url `line` value for a content window: its first line's 1-based number, │ │818 +// except the first window, which serializes as unset (0). │ │819 +fn lineNumber(window_start: usize) usize { │ │820 + return if (window_start == 0) 0 else window_start + 1; │ │821 } │ │822 │ │823 // `dir`/`name`, or just `name` at the root. │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯