Something went wrong. Try again.
A history browser for git, a replacement for gitk, drawn with Vulkan on Wayland.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193// SPDX-FileCopyrightText: © 2026 Jeffrey C. Ollie <jeff@ocjtech.us>// SPDX-License-Identifier: MIT
//! The colors grebe draws with: a palette for light and one for dark, and//! the one in use, which follows what the desktop prefers.
const aerie = @import("aerie");
pub const Color = [4]u8;
pub const Palette = struct { background: Color, list_background: Color, foreground: Color, dim_foreground: Color, selection_background: Color, selection_foreground: Color, status_background: Color, divider: Color, disabled_foreground: Color, menu_shadow: Color, /// The box around the marked commit. mark: Color, error_foreground: Color,
/// The colors lines of descent in the graph are drawn in, one after /// another: distinct from each other and from the selection, and /// strong enough to read against the list. graph: [8]Color,
/// The details and diff pane: each kind of line's text, and the band /// behind it, if it has one. diff_added: Color, diff_added_background: Color, diff_removed: Color, diff_removed_background: Color, diff_hunk: Color, diff_hunk_background: Color, diff_file_background: Color, /// The pane's bar of controls, and a control under the pointer. bar_background: Color, control_hover: Color,
/// The nodes of the pseudo-commits, as gitk colors them. pseudo_working_tree: Color, pseudo_index: Color,
/// Text selected in a field. text_selection: Color, /// Behind a commit the find matched. find_match: Color, /// A scrollbar's track, its thumb, and its thumb while dragged. scrollbar_track: Color, scrollbar_thumb: Color, scrollbar_thumb_active: Color, /// The labels before a subject naming the refs at a commit: behind a /// local branch, a remote one, a tag, and anything else; and their /// border and text. ref_head: Color, ref_remote: Color, ref_tag: Color, ref_other: Color, ref_border: Color, ref_foreground: Color,};
pub const light: Palette = .{ .background = .{ 0xf6, 0xf5, 0xf3, 255 }, .list_background = .{ 0xff, 0xff, 0xff, 255 }, .foreground = .{ 0x1f, 0x23, 0x28, 255 }, .dim_foreground = .{ 0x59, 0x63, 0x6e, 255 }, .selection_background = .{ 0x2f, 0x6f, 0xb3, 255 }, .selection_foreground = .{ 0xff, 0xff, 0xff, 255 }, .status_background = .{ 0xea, 0xe8, 0xe4, 255 }, .divider = .{ 0xd0, 0xcc, 0xc4, 255 }, .disabled_foreground = .{ 0xa8, 0xa8, 0xa8, 255 }, .menu_shadow = .{ 0, 0, 0, 40 }, .mark = .{ 0x1f, 0x23, 0x28, 255 }, .error_foreground = .{ 0xb3, 0x26, 0x1e, 255 }, .graph = .{ .{ 0x2f, 0x6f, 0xb3, 255 }, .{ 0xc0, 0x39, 0x2b, 255 }, .{ 0x27, 0x8e, 0x50, 255 }, .{ 0x8e, 0x44, 0xad, 255 }, .{ 0xd3, 0x7a, 0x00, 255 }, .{ 0x16, 0x8f, 0x8f, 255 }, .{ 0xb0, 0x3a, 0x7a, 255 }, .{ 0x6d, 0x6a, 0x22, 255 }, }, .diff_added = .{ 0x11, 0x63, 0x29, 255 }, .diff_added_background = .{ 0xe6, 0xff, 0xec, 255 }, .diff_removed = .{ 0xa4, 0x0e, 0x26, 255 }, .diff_removed_background = .{ 0xff, 0xeb, 0xe9, 255 }, .diff_hunk = .{ 0x05, 0x50, 0xae, 255 }, .diff_hunk_background = .{ 0xdd, 0xf4, 0xff, 255 }, .diff_file_background = .{ 0xea, 0xee, 0xf2, 255 }, .bar_background = .{ 0xf0, 0xee, 0xea, 255 }, .control_hover = .{ 0xdc, 0xd8, 0xd0, 255 }, .pseudo_working_tree = .{ 0xd0, 0x30, 0x30, 255 }, .pseudo_index = .{ 0x2a, 0x9d, 0x3a, 255 }, .text_selection = .{ 0xc8, 0xdc, 0xf4, 255 }, .find_match = .{ 0xff, 0xe8, 0x82, 255 }, .scrollbar_track = .{ 0xf0, 0xee, 0xea, 255 }, .scrollbar_thumb = .{ 0xbd, 0xb8, 0xae, 255 }, .scrollbar_thumb_active = .{ 0x8f, 0x89, 0x7f, 255 }, .ref_head = .{ 0xc4, 0xf0, 0xc2, 255 }, .ref_remote = .{ 0xff, 0xdd, 0xaa, 255 }, .ref_tag = .{ 0xff, 0xea, 0x2e, 255 }, .ref_other = .{ 0xe2, 0xe0, 0xec, 255 }, .ref_border = .{ 0x59, 0x63, 0x6e, 255 }, .ref_foreground = .{ 0x1f, 0x23, 0x28, 255 },};
pub const dark: Palette = .{ .background = .{ 0x1c, 0x1e, 0x21, 255 }, .list_background = .{ 0x24, 0x27, 0x2b, 255 }, .foreground = .{ 0xe1, 0xe4, 0xe8, 255 }, .dim_foreground = .{ 0x9a, 0xa3, 0xad, 255 }, .selection_background = .{ 0x2f, 0x6f, 0xb3, 255 }, .selection_foreground = .{ 0xff, 0xff, 0xff, 255 }, .status_background = .{ 0x2a, 0x2d, 0x31, 255 }, .divider = .{ 0x3d, 0x42, 0x48, 255 }, .disabled_foreground = .{ 0x6a, 0x70, 0x77, 255 }, .menu_shadow = .{ 0, 0, 0, 90 }, .mark = .{ 0xe1, 0xe4, 0xe8, 255 }, .error_foreground = .{ 0xff, 0x7b, 0x72, 255 }, .graph = .{ .{ 0x58, 0xa6, 0xff, 255 }, .{ 0xff, 0x7b, 0x72, 255 }, .{ 0x3f, 0xb9, 0x50, 255 }, .{ 0xbc, 0x8c, 0xff, 255 }, .{ 0xf0, 0xa0, 0x30, 255 }, .{ 0x39, 0xc5, 0xcf, 255 }, .{ 0xf7, 0x78, 0xba, 255 }, .{ 0xc9, 0xc2, 0x4a, 255 }, }, .diff_added = .{ 0x7e, 0xe7, 0x87, 255 }, .diff_added_background = .{ 0x1b, 0x3a, 0x26, 255 }, .diff_removed = .{ 0xff, 0xa1, 0x98, 255 }, .diff_removed_background = .{ 0x48, 0x22, 0x23, 255 }, .diff_hunk = .{ 0x79, 0xc0, 0xff, 255 }, .diff_hunk_background = .{ 0x1d, 0x30, 0x46, 255 }, .diff_file_background = .{ 0x30, 0x35, 0x3b, 255 }, .bar_background = .{ 0x2a, 0x2d, 0x31, 255 }, .control_hover = .{ 0x3d, 0x42, 0x48, 255 }, .pseudo_working_tree = .{ 0xf0, 0x50, 0x50, 255 }, .pseudo_index = .{ 0x40, 0xc0, 0x50, 255 }, .text_selection = .{ 0x26, 0x4f, 0x78, 255 }, .find_match = .{ 0x6b, 0x5a, 0x12, 255 }, .scrollbar_track = .{ 0x2a, 0x2d, 0x31, 255 }, .scrollbar_thumb = .{ 0x4f, 0x55, 0x5c, 255 }, .scrollbar_thumb_active = .{ 0x76, 0x7e, 0x88, 255 }, .ref_head = .{ 0x1f, 0x4d, 0x2a, 255 }, .ref_remote = .{ 0x6e, 0x38, 0x12, 255 }, .ref_tag = .{ 0x66, 0x5c, 0x00, 255 }, .ref_other = .{ 0x3a, 0x3e, 0x4c, 255 }, .ref_border = .{ 0x9a, 0xa3, 0xad, 255 }, .ref_foreground = .{ 0xe1, 0xe4, 0xe8, 255 },};
/// The palette drawn with now.pub var current: *const Palette = &light;
/// The palette for what the desktop prefers: dark when it says so, and/// light when it says that or nothing.pub fn forAppearance(a: aerie.desktop.Appearance) *const Palette { return switch (a.color_scheme) { .dark => &dark, .light, .no_preference => &light, };}
/// `c` as the renderer's clear color.pub fn clear(c: Color) [4]f32 { return .{ @as(f32, @floatFromInt(c[0])) / 255, @as(f32, @floatFromInt(c[1])) / 255, @as(f32, @floatFromInt(c[2])) / 255, @as(f32, @floatFromInt(c[3])) / 255, };}
pub fn graphColor(i: u16) Color { return current.graph[i % current.graph.len];}
test "the palette follows the desktop" { const testing = @import("std").testing; try testing.expectEqual(&light, forAppearance(.{})); try testing.expectEqual(&dark, forAppearance(.{ .color_scheme = .dark })); try testing.expectEqual(&light, forAppearance(.{ .color_scheme = .light }));}