╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │479 │ │480 // a focusable row following the "a:" `link`. │ │481 fn addLink(allocator: std.mem.Allocator, box: *wgt.Box(ui.Widget), label: []const u8, link: []const u8) !void { │ │482 - var tb = try wgt.TextBox.init(allocator, label, .{ .border_style = .single, .round_corners = true, .wrap_kind = .none });│ │482 + var tb = try wgt.TextBox.init(allocator, label, .{ .border = .single, .round_corners = true, .wrap_kind = .none }); │ │483 errdefer tb.deinit(allocator); │ │484 tb.getFocus().mode = .all; │ │485 tb.getFocus().kind = .{ .custom = link }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │627 } else { │ │628 const pa = self.session.page_arena; │ │629 { │ │630 - var row = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │630 + var row = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .horiz }); │ │631 errdefer row.deinit(allocator); │ │632 const diff_route = self.data.handle.location.commitDiffRoute(commit.oid, commit.parent_oid) orelse return error.RouteTooLong;│ │633 try addLink(allocator, &row, "view diff", try pa.allocator().print("a:{s}", .{try diff_route.toUrl(pa)})); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │639 try addLink(allocator, inner, "view commits from this merge", try pa.allocator().print("a:{s}", .{try route.toUrl(pa)}));│ │640 }; │ │641 if (commit.author != .unknown or commit.committer != .unknown) { │ │642 - var row = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │642 + var row = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .horiz }); │ │643 errdefer row.deinit(allocator); │ │644 if (commit.author != .unknown) { │ │645 var tb = try ui.authorBox(allocator, pa, commit.author); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │649 if (commit.committer != .unknown) { │ │650 var tb = try ui.authorBox(allocator, pa, commit.committer); │ │651 errdefer tb.deinit(allocator); │ │652 - tb.options.label = " committer "; │ │652 + tb.options.top_label.text = " committer "; │ │653 try row.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null });│ │654 } │ │655 row.getFocus().child_id = row.children.keys()[0]; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │656 try inner.children.put(allocator, row.getFocus().id, .{ .widget = .{ .box = row }, .rect = null, .min_size = null }); │ │657 } │ │658 { │ │659 - var tb = try wgt.TextBox.init(allocator, commit.timestamp, .{ .border_style = .single, .round_corners = true, .wrap_kind = .none, .label = " timestamp " }); │ │659 + var tb = try wgt.TextBox.init(allocator, commit.timestamp, .{ .border = .single, .round_corners = true, .wrap_kind = .none, .top_label = .{ .text = " timestamp " } });│ │660 errdefer tb.deinit(allocator); │ │661 tb.getFocus().mode = .all; │ │662 try inner.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null }); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │672 if (bytes_added) "added" else "removed", bytes, stats.files_added + stats.files_changed, │ │673 }); │ │674 if (stats.files_removed != 0) try text.writer.print("\nfiles removed: {d}", .{stats.files_removed}); │ │675 - var tb = try wgt.TextBox.init(allocator, text.written(), .{ .border_style = .single, .round_corners = true, .wrap_kind = .none, .label = " stats " }); │ │675 + var tb = try wgt.TextBox.init(allocator, text.written(), .{ .border = .single, .round_corners = true, .wrap_kind = .none, .top_label = .{ .text = " stats " } });│ │676 errdefer tb.deinit(allocator); │ │677 tb.getFocus().mode = .all; │ │678 try inner.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null }); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────╮ │src/ui/Repo/Diff.zig│ ╰────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │29 .added => " added ", │ │30 .removed => " removed ", │ │31 .changed => " changed ", │ │32 + }; │ │33 + } │ │34 + │ │35 + fn border(self: Status) wgt.Border { │ │36 + const color: Grid.Color.Ansi = switch (self) { │ │37 + .added => .green, │ │38 + .removed => .red, │ │39 + .changed => return .single, │ │40 }; │ │41 + return .{ .kind = .single, .style = .{ .fg = .{ .ansi = color } } };│ │42 } │ │43 }; │ │44 pub const Window = struct { │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │261 fn appendWindow(data: @This(), allocator: std.mem.Allocator, session: *ui.Session, box: *wgt.Box(ui.Widget)) !void { │ │262 if (data.path.len != 0) { │ │263 const status = if (data.window.hunks.len > 0) data.window.hunks[0].status else .changed; │ │255 - try addSpans(allocator, box, &.{.{ .text = data.path }}, try data.route.fileLink(session.page_arena, data.path, status), status.label()); │ │264 + try addSpans(allocator, box, &.{.{ .text = data.path }}, try data.route.fileLink(session.page_arena, data.path, status), status.label(), status.border());│ │265 try addLink(allocator, box, "← all files", try data.route.link(session.page_arena, 0, "")); │ │266 } │ │267 if (data.window.start > 0) try addLink(allocator, box, "← previous", try data.route.link(session.page_arena, data.window.start -| page_size, data.path)); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │269 if (data.path.len == 0) if (hunk.path) |path| { │ │270 // a changed file's path narrows the diff to it, the others open the file │ │271 const link = if (hunk.status == .changed) try data.route.link(session.page_arena, 0, path) else try data.route.fileLink(session.page_arena, path, hunk.status);│ │263 - try addSpans(allocator, box, &.{.{ .text = path }}, link, hunk.status.label()); │ │272 + try addSpans(allocator, box, &.{.{ .text = path }}, link, hunk.status.label(), hunk.status.border()); │ │273 }; │ │274 if (hunk.text.len != 0) try addHunk(allocator, box, hunk); │ │275 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │277 } │ │278 │ │279 fn addLink(allocator: std.mem.Allocator, box: *wgt.Box(ui.Widget), text: []const u8, link: []const u8) !void {│ │271 - try addSpans(allocator, box, &.{.{ .text = text }}, link, ""); │ │280 + try addSpans(allocator, box, &.{.{ .text = text }}, link, "", .single); │ │281 } │ │282 │ │283 // one span per line, inserted lines green and deleted lines red. the text │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯