╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Files.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
176 const next = if (delta < 0) cur - 1 else cur + 1; 177 try root_focus.setFocus(keys[next]); 178 if (box.children.values()[next].rect) |rect| self.scroll.scrollToRect(rect); 179 } 180 181 pub fn clearGrid(self: *View) void { 182 self.scroll.clearGrid(); 183 } 184 185 pub fn getGrid(self: View) ?Grid { 186 return self.scroll.getGrid(); 187 } 188 189 pub fn getFocus(self: *View) *Focus { 190 return self.scroll.getFocus(); 191 } 192 193 pub fn getSelectedIndex(self: View) ?usize { 194 const box = &self.scroll.child.box; 195 const child_id = box.focus.child_id orelse return null; 196 return box.children.getIndex(child_id); 197 } 198 }; 199 200 // the "a:" link for the files route at `dir` within `identity` ("owner/name"). 201 fn dirLink(page_arena: *std.heap.ArenaAllocator, identity: []const u8, dir: []const u8) ![]const u8 { 202 const route = ui.RoutablePage.repoFilesRoute(identity, dir) orelse return error.RouteTooLong; 203 const url = try route.urlAlloc(page_arena); 204 return std.fmt.allocPrint(page_arena.allocator(), "a:{s}", .{url}); 205 } 206 207 // `dir`/`name`, or just `name` at the root. 208 fn childDir(arena: std.mem.Allocator, dir: []const u8, name: []const u8) ![]const u8 { 209 return if (dir.len == 0) name else std.fmt.allocPrint(arena, "{s}/{s}", .{ dir, name }); 210 } 211 212 // `dir` with its last segment removed ("" when `dir` has a single segment). 213 fn parentDir(dir: []const u8) []const u8 { 214 const slash = std.mem.lastIndexOfScalar(u8, dir, '/') orelse return ""; 215 return dir[0..slash]; 216 } 217