theming nirvana

theming nirvana

As I fall deeper and deeper down the nixos rabbit hole, I find myself becoming more and more obsessed with controlling every little thing on my computers declaratively. It starts with: ‘oh this is cool I can specify which desktop environment to use in my configuration.nix’. Next thing you know you’ve discovered home-manager and every program on every linux system you use needs to be controlled in your nix-config. Of course this slightly insane approach has its downsides; it also opens some doors though.

Nix-colors lets you dyanmically change the theming of programs controlled in your nix config. So when you want to change the color of everything and have it match and all be pretty lol, you are able to do so with one word as opposed to poring over everything changing each individual color. For a certain type of person, this is very nice!

how to make it work

This will be a quick rundown of how I’ve got things set up; this is basically just a rehash of this.

First of all, you need to add nix-colors to your flake inputs and then point home-manager in its direction. The relevant parts of my flake.nix look something like this.

{
  inputs = {
    nix-colors.url = "github:misterio77/nix-colors";
  };
  homeConfigurations = {
    "randy@computer" = home-manager.lib.homeManagerConfiguration {
      extraSpecialArgs = { inherit nix-colors; };
  };
}

Then you can import the module into your home-manager config, specify a scheme (available schemes here), and get to theming.

Here’s a simple example where I make my dunst notifications follow the everforest theme.

{ pkgs, config, nix-colors, ... }: {

  imports = [
    nix-colors.homeManagerModule
  ];

  colorScheme = nix-colors.colorSchemes.everforest;
  
  services.dunst = {
    enable = true;
	urgency_normal = {
	  background = "#${config.colorScheme.colors.base01}";
	  foreground = "#${config.colorScheme.colors.base05}";
	};
  };
}

a couple of additional tips and tricks

First tip and trick: generate and dynamically alter gtk themes depending on current nix-colors theme.

{ config, pkgs, inputs, ... }:

let
  inherit (inputs.nix-colors.lib-contrib { inherit pkgs; }) gtkThemeFromScheme;
in rec {
  gtk = {
    enable = true;
    theme = {
      name = "${config.colorScheme.slug}";
      package = gtkThemeFromScheme { scheme = config.colorScheme; };
    };
  };

  services.xsettingsd = {
    enable = true;
    settings = {
      "Net/ThemeName" = "${gtk.theme.name}";
      "Net/IconThemeName" = "${gtk.iconTheme.name}";
    };
  };
}

Second tip and trick: if you’re not using nix to configure everything you can still pass your colors across in the relevant format with home.file. I do this for qtile.

{config, pkgs, ... }:
  let
    c = config.colorScheme.colors;
  in
{
  home.file = {
    ".config/qtile/colors.py" = {
	  text = ''
        scheme = {
          'yellow': "#${c.base0A}",
          'orange': "#${c.base09}",	
          'red': "#${c.base0F}",	
          'magenta': "#${c.base08}",	
          'violet': "#${c.base0E}",
          'blue': "#${c.base0D}",
          'cyan': "#${c.base0C}",	
          'green': "#${c.base0B}",
        }
      '';
	};
  };
}

You can then import the colors into your config.py and use them as you see fit.

from colors import scheme

layouts = [
    layout.MonadTall(
	    border_normal = scheme['yellow'],
	    border_focus = scheme['green'],
	),
]

That’s it for today. Thank you to the hero that made this.