╭ changed ───────────╮ │src/ui/Repo/Diff.zig│ ╰────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │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 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │297 try spans.append(allocator, .{ .text = hunk.text[start..end], .style = style }); │ │298 start = end; │ │299 } │ │291 - try addSpans(allocator, box, spans.items, "", ""); │ │300 + try addSpans(allocator, box, spans.items, "", "", .single); │ │301 } │ │302 │ │294 -fn addSpans(allocator: std.mem.Allocator, box: *wgt.Box(ui.Widget), spans: []const wgt.Span, link: []const u8, label: []const u8) !void { │ │295 - var tb = try wgt.TextBox.initSpans(allocator, spans, .{ .border_style = .single, .round_corners = true, .wrap_kind = .none, .label = label }); │ │303 +fn addSpans(allocator: std.mem.Allocator, box: *wgt.Box(ui.Widget), spans: []const wgt.Span, link: []const u8, label: []const u8, border: wgt.Border) !void {│ │304 + var tb = try wgt.TextBox.initSpans(allocator, spans, .{ .border = border, .round_corners = true, .wrap_kind = .none, .top_label = .{ .text = label } }); │ │305 errdefer tb.deinit(allocator); │ │306 tb.getFocus().mode = .all; │ │307 if (link.len != 0) tb.getFocus().kind = .{ .custom = link }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │313 │ │314 pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │315 var view: View = blk: { │ │307 - var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │316 + var box = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .vert }); │ │317 errdefer box.deinit(allocator); │ │318 break :blk .{ .scroll = try wgt.Scroll(ui.Widget).init(allocator, .{ .box = box }, .{ .direction = .both, .web_native = !session.is_terminal, .fill = true }) };│ │319 }; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯