inputs: { config, lib, pkgs, ... }: with lib; let cfg = config.colors; pow = n: i: if i == 1 then n else if i == 0 then 1 else n * pow n (i - 1); alf = [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" "d" "e" "f" ]; fil = c: lib.imap0 (n: x: if (lib.toLower x) == c then n else null) alf; fin = c: builtins.elemAt (builtins.filter (x: x != null) (fil c)) 0; add = l: lib.foldr ({ n, x }: c: (x * (pow 16 n)) + c) 0 (lib.imap0 (n: x: { inherit n x; }) l); calc = s: add (builtins.map fin (builtins.filter (x: builtins.isString x && builtins.stringLength x == 1) (builtins.split "" s))); splitHex = c: let s' = builtins.match "(..)(..)(..)|(.)(.)(.)" c; ss = builtins.elemAt s'; o = if ss 0 == null then 3 else 0; in { r = ss (0 + o); g = ss (1 + o); b = ss (2 + o); }; hexToRgb = c: builtins.mapAttrs (_: calc) (splitHex c); hexToAlphaCss = c: a: with hexToRgb c; "rgba(${r}, ${g}, ${b}, ${a})"; makeScheme = base16: lib.mapAttrs' (k: v: lib.nameValuePair "${k}-hex" v) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-hex-r" (splitHex v).r) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-hex-g" (splitHex v).g) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-hex-b" (splitHex v).b) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-rgb-r" (hexToRgb v).r) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-rgb-g" (hexToRgb v).g) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-rgb-b" (hexToRgb v).b) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-dec-r" ((hexToRgb v).r / 255.0)) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-dec-g" ((hexToRgb v).g / 255.0)) base16 // lib.mapAttrs' (k: v: lib.nameValuePair "${k}-dec-b" ((hexToRgb v).b / 255.0)) base16; mustache = scheme: name: src: pkgs.stdenv.mkDerivation ( { name = lib.strings.sanitizeDerivationName name; inherit src; data = pkgs.writeText "${name}-data" (builtins.toJSON scheme); phases = [ "buildPhase" ]; buildPhase = "${pkgs.mustache-go}/bin/mustache $data $src > $out"; } ); genTheme = repo: mustache (makeScheme cfg.base16 // { scheme-name = cfg.favColors.name; scheme-slug = "idk"; scheme-author = "nixos"; }) cfg.favColors.name "${repo}/templates/default.mustache"; in { options.colors = { enable = mkEnableOption "Enable automatic colors"; i3BarColors = mkOption { description = "Exported color attrset for i3bar/swaybar"; default = {}; }; waybarCss = mkOption { description = "Exported CSS for waybar"; default = ""; }; base16Rgb = mkOption { readOnly = true; type = types.attrsOf (types.attrsOf types.int); }; base16 = mkOption { readOnly = true; type = types.attrsOf types.str; }; favColors = mkOption { description = "Your favourite color scheme"; default = {}; type = types.submodule { options = { name = mkOption { type = types.str; default = "Monokai"; description = "Name of your color scheme"; }; base16 = mkOption { type = types.attrsOf types.str; default = { base00 = "272822"; base01 = "383830"; base02 = "49483e"; base03 = "75715e"; base04 = "a59f85"; base05 = "f8f8f2"; base06 = "f5f4f1"; base07 = "f9f8f5"; base08 = "f92672"; base09 = "fd971f"; base0A = "f4bf75"; base0B = "a6e22e"; base0C = "a1efe4"; base0D = "66d9ef"; base0E = "ae81ff"; base0F = "cc6633"; }; description = "BASE16 color scheme"; }; }; }; }; }; config = let i3config = { config = { colors = { background = "#${cfg.favColors.base16.base07}"; focused = { border = "#${cfg.favColors.base16.base05}"; background = "#${cfg.favColors.base16.base0D}"; text = "#${cfg.favColors.base16.base00}"; indicator = "#${cfg.favColors.base16.base0D}"; childBorder = "#${cfg.favColors.base16.base0D}"; }; focusedInactive = { border = "#${cfg.favColors.base16.base01}"; background = "#${cfg.favColors.base16.base01}"; text = "#${cfg.favColors.base16.base05}"; indicator = "#${cfg.favColors.base16.base03}"; childBorder = "#${cfg.favColors.base16.base01}"; }; unfocused = { border = "#${cfg.favColors.base16.base01}"; background = "#${cfg.favColors.base16.base00}"; text = "#${cfg.favColors.base16.base05}"; indicator = "#${cfg.favColors.base16.base01}"; childBorder = "#${cfg.favColors.base16.base01}"; }; urgent = { border = "#${cfg.favColors.base16.base08}"; background = "#${cfg.favColors.base16.base08}"; text = "#${cfg.favColors.base16.base00}"; indicator = "#${cfg.favColors.base16.base08}"; childBorder = "#${cfg.favColors.base16.base08}"; }; placeholder = { border = "#${cfg.favColors.base16.base00}"; background = "#${cfg.favColors.base16.base00}"; text = "#${cfg.favColors.base16.base05}"; indicator = "#${cfg.favColors.base16.base00}"; childBorder = "#${cfg.favColors.base16.base00}"; }; }; }; }; elementTheme = { name = "Nix colors 11"; is_dark = true; colors = { "accent-color" = "#${cfg.favColors.base16.base02}"; "primary-color" = "#${cfg.favColors.base16.base08}"; "warning-color" = "#${cfg.favColors.base16.base0F}"; "sidebar-color" = "#${cfg.favColors.base16.base01}"; "roomlist-background-color" = "#${cfg.favColors.base16.base00}"; "roomlist-text-color" = "#${cfg.favColors.base16.base05}"; "roomlist-text-secondary-color" = "${cfg.favColors.base16.base06}"; "roomlist-highlights-color" = "#${cfg.favColors.base16.base02}"; "roomlist-separator-color" = "#${cfg.favColors.base16.base05}"; "timeline-background-color" = "#${cfg.favColors.base16.base00}"; "timeline-text-color" = "#${cfg.favColors.base16.base07}"; "timeline-text-secondary-color" = "#${cfg.favColors.base16.base05}"; "timeline-highlights-color" = "#${cfg.favColors.base16.base02}"; "reaction-row-button-selected-bg-color" = "#${cfg.favColors.base16.base0B}"; }; }; elementConfig = { settingDefaults.custom_themes = [ elementTheme ]; settingDefaults.theme = "custom-${elementTheme.name}"; default_theme = "custom-${elementTheme.name}"; showLabsSettings = true; }; in mkIf cfg.enable { # Read only utility attributes colors.base16 = cfg.favColors.base16; colors.base16Rgb = builtins.mapAttrs hexToRgb cfg.favColors.base16; # Element xdg.configFile."Riot/config.json".text = builtins.toJSON elementConfig; xdg.configFile."Element/config.json".text = builtins.toJSON elementConfig; xdg.configFile."element_theme.json".text = builtins.toJSON elementTheme; # Mako programs.mako = { backgroundColor = "#${cfg.favColors.base16.base00}"; textColor = "#${cfg.favColors.base16.base07}"; borderColor = "#${cfg.favColors.base16.base08}"; progressColor = "over #${cfg.favColors.base16.base0D}"; }; # I3/sway wayland.windowManager.sway = i3config; xsession.windowManager.i3 = i3config; colors.i3BarColors = { background = "#${cfg.favColors.base16.base00}"; separator = "#${cfg.favColors.base16.base01}"; statusline = "#${cfg.favColors.base16.base04}"; focusedWorkspace = { border = "#${cfg.favColors.base16.base05}"; background = "#${cfg.favColors.base16.base0D}"; text = "#${cfg.favColors.base16.base00}"; }; activeWorkspace = { border = "#${cfg.favColors.base16.base05}"; background = "#${cfg.favColors.base16.base03}"; text = "#${cfg.favColors.base16.base00}"; }; inactiveWorkspace = { border = "#${cfg.favColors.base16.base03}"; background = "#${cfg.favColors.base16.base01}"; text = "#${cfg.favColors.base16.base05}"; }; urgentWorkspace = { border = "#${cfg.favColors.base16.base08}"; background = "#${cfg.favColors.base16.base08}"; text = "#${cfg.favColors.base16.base00}"; }; bindingMode = { border = "#${cfg.favColors.base16.base00}"; background = "#${cfg.favColors.base16.base0A}"; text = "#${cfg.favColors.base16.base00}"; }; }; # Waybar colors.waybarCss = "\n" + ( (import ../data/waybar-base16.nix) cfg.favColors.name cfg.base16 ); # Dunst services.dunst = { settings = { global = { frame_color = "#${cfg.favColors.base16.base09}"; separator_color = "#${cfg.favColors.base16.base05}"; }; urgency_low = { background = "#${cfg.favColors.base16.base01}"; foreground = "#${cfg.favColors.base16.base03}"; }; urgency_normal = { background = "#${cfg.favColors.base16.base02}"; foreground = "#${cfg.favColors.base16.base05}"; }; urgency_critical = { background = "#${cfg.favColors.base16.base08}"; foreground = "#${cfg.favColors.base16.base06}"; }; }; }; # Rofi programs.rofi.theme = "${genTheme inputs.base16-rofi}"; # Kitty programs.kitty.extraConfig = '' include ${genTheme inputs.base16-kitty} ''; # neovim xdg.configFile."nvim/colors/base16.vim".text = import ../data/vim-base16.nix cfg.favColors.name cfg.favColors.base16; programs.neovim.extraConfig = '' colorscheme base16 set termguicolors ''; # GTK gtk = { enable = true; theme = let materia_colors = pkgs.writeText "gtk-generated-colors" '' BG=${cfg.favColors.base16.base00} FG=${cfg.favColors.base16.base07} BTN_BG=${cfg.favColors.base16.base00} BTN_FG=${cfg.favColors.base16.base07} MENU_BG=${cfg.favColors.base16.base00} MENU_FG=${cfg.favColors.base16.base07} ACCENT_BG=${cfg.favColors.base16.base02} SEL_BG=${cfg.favColors.base16.base0D} SEL_FG=${cfg.favColors.base16.base00} TXT_BG=${cfg.favColors.base16.base00} TXT_FG=${cfg.favColors.base16.base07} HDR_BTN_BG=${cfg.favColors.base16.base00} HDR_BTN_FG=${cfg.favColors.base16.base07} WM_BORDER_FOCUS=${cfg.favColors.base16.base02} WM_BORDER_UNFOCUS=${cfg.favColors.base16.base01} MATERIA_STYLE_COMPACT=True MATERIA_COLOR_VARIANT=dark UNITY_DEFAULT_LAUNCHER_STYLE=False NAME=generated ''; generated-gtk-theme = pkgs.stdenv.mkDerivation { name = "generated-gtk-theme"; src = pkgs.materia-theme.src; buildInputs = with pkgs; [ sassc bc which inkscape optipng ]; installPhase = '' HOME=/build chmod 777 -R . patchShebangs . mkdir -p $out/share/themes substituteInPlace change_color.sh --replace "\$HOME/.themes" "$out/share/themes" echo "Changing colours:" ./change_color.sh -o Generated ${materia_colors} chmod 555 -R . ''; }; in { name = "Generated"; package = generated-gtk-theme; }; gtk2.extraConfig = ( (import ../data/gtk2-base16.nix) cfg.favColors.name cfg.favColors.base16 ); }; # Codium/VSCODE programs.vscode.userSettings = { "workbench.colorTheme" = "nix colors"; }; home.file = lib.mkMerge [ ( mkIf config.programs.vscode.enable { ".vscode-oss/extensions/base16-1.0.0/themes/nix-colors.json".text = (import ../data/codium-base16.nix) cfg.favColors.name cfg.favColors.base16; ".vscode-oss/extensions/base16-1.0.0/package.json".text = builtins.toJSON { name = "nix colors"; displayName = "Automatic Nix-generated base16 colors"; version = "1.0.0"; publisher = "colors"; author = { name = "ezpc usr"; email = "usr@ezpc"; }; engines.vscode = "^1.11.1"; categories = "Themes"; contributes.themes = [ { label = "nix colors"; uiTheme = "vs-dark"; path = "./themes/nix-colors.json"; } ]; }; } ) ]; }; }