home | section main page


NixOS Configuration

Table of Contents

1. Introduction

This is my NixOS configuration. It is a part of my monorepo, and this file automatically tangles to all the under the nix/ directory in my monorepo git repository. My monorepo also stores my website, as my website stores my elfeed and emacs configurations. Additionally, I want to track my emacs configuration with my Nix configuration. Having them in one repository means that my emacs configuration is pinned to my flake.

Hence, my monorepo serves a dual purpose, as do many of the files within my monorepo. They are often data files used in my configuration (i.e. emacs, elfeed, org-roam, agenda, journal, etc…) and they are webpages as well. This page is one such example of this concept.

2. Flake.nix

The flake is the entry point of the NixOS configuration. Here, I have a list of all the systems that I use with all the modules that they use. My NixOS configuration is heavily modularized, so that adding new configurations that add modifications is made simple.

{
  description = "Emacs centric configurations for a complete networked system";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";

    home-manager = {
      url = "github:nix-community/home-manager/release-24.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    lanzaboote = {
      url = "github:nix-community/lanzaboote/v0.4.1";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    nur.url = "github:nix-community/NUR";
    sops-nix.url = "github:Mic92/sops-nix";
    scripts.url = "github:ret2pop/scripts";
    wallpapers.url = "github:ret2pop/wallpapers";
    sounds.url = "github:ret2pop/sounds";
  };

  outputs = { nixpkgs, home-manager, nur, disko, lanzaboote, sops-nix, ... }@attrs: {
    nixosConfigurations = {
      installer = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          (
            { pkgs, modulesPath, ... }:
            {
              imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") ];
            }
          )
          ./systems/installer/default.nix
        ];
      };

      continuity = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        specialArgs = attrs;
        modules = [
          lanzaboote.nixosModules.lanzaboote
          disko.nixosModules.disko
          home-manager.nixosModules.home-manager
          sops-nix.nixosModules.sops
          { nixpkgs.overlays = [ nur.overlays.default ]; }
          { home-manager.extraSpecialArgs = attrs; }

          ./modules/sda-simple.nix
          ./systems/continuity/default.nix
        ];
      };

      spontaneity = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        specialArgs = attrs;
        modules = [];
      };

      affinity = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        specialArgs = attrs;
        modules = [];
      };
    };
  };
}

Listed here is my installer as well, which is used to install the systems in my configuration.

3. Sops Configuration

In order to use the sops configuration, you must change the age public key to the one that you own:

keys:
  - &primary age165ul43e8rc0qwzz2f2q9cw02psm2mkudsrwavq2e0pxs280p64yqy2z0dr
creation_rules:
  - path_regex: secrets/secrets.yaml$
    key_groups:
      - age:
        - *primary

also note that you will have to write your own secrets.yaml file, with an entry called mail, which is used for the imaps and smtps password.

4. Modules

4.1. Vars

Variables used for regular configuration in your system defafult.nix file. The options are largely self-documenting.

{ lib, ... }:
{
  options.monorepo.vars = {
    hostName = lib.mkOption {
      type = lib.types.str;
      default = "continuity";
      example = "hostname";
      description = "system hostname";
    };

    userName = lib.mkOption {
      type = lib.types.str;
      default = "preston";
      example = "myUser";
      description = "system username";
    };

    fullName = lib.mkOption {
      type = lib.types.str;
      default = "Preston Pan";
      example = "John Doe";
      description = "Full Name";
    };

    gpgKey = lib.mkOption {
      type = lib.types.str;
      default = "AEC273BF75B6F54D81343A1AC1FE6CED393AE6C1";
      example = "1234567890ABCDEF...";
      description = "GPG key fingerprint";
    };

    remoteHost = lib.mkOption {
      type = lib.types.str;
      default = "nullring.xyz";
      example = "example.com";
      description = "Address to push to and pull from for website and git repos";
    };

    timeZone = lib.mkOption {
      type = lib.types.str;
      default = "America/Vancouver";
      example = "America/Chicago";
      description = "Linux timezone";
    };

    monitors = lib.mkOption {
      type = lib.types.listOf lib.types.str;
      default = [
        "HDMI-A-1"
        "eDP-1"
        "DP-2"
        "DP-3"
        "LVDS-1"
      ];
      example = [];
      description = "Monitors that waybar will use";
    };
  };
}

4.2. Default Profile

Again, these are self documenting variables that you may see used below. These are to be used under default.nix in the systems folder.

{ lib, config, pkgs, ... }:
{
  imports = [
    ./configuration.nix
    ./home/home.nix
    ./vars.nix
  ];

  options = {
    monorepo = {
      profiles = {
        cuda.enable = lib.mkEnableOption "Enables CUDA support";
        documentation.enable = lib.mkEnableOption "Enables documentation on system.";
        secureBoot.enable = lib.mkEnableOption "Enables secure boot. See sbctl.";
        pipewire.enable = lib.mkEnableOption "Enables pipewire low latency audio setup";
        tor.enable = lib.mkEnableOption "Enables tor along with torsocks";
        home.enable = lib.mkEnableOption "Enables home user";
      };
    };
  };

  config = {
    home-manager.users."${config.monorepo.vars.userName}" = {
      programs.home-manager.enable = config.monorepo.profiles.home.enable;
    };

    environment.systemPackages = lib.mkIf config.monorepo.profiles.documentation.enable (with pkgs; [
      linux-manual
      man-pages
      man-pages-posix
    ]);

    monorepo = {
      profiles = {
        documentation.enable = lib.mkDefault true;
        pipewire.enable = lib.mkDefault true;
        tor.enable = lib.mkDefault true;
        home.enable = lib.mkDefault true;
      };
    };
  };
}

4.3. X11

My Xorg configuration is used as a backup for when wayland applications don't work. Note that using this configuration is extremely inefficient and my i3 configuration is unoptimized. Still, it is suitable for using Krita.

{ lib, pkgs, ... }:
{
  services.xserver = {
    enable = lib.mkDefault true;
    displayManager = {
      startx.enable = true;
    };

    windowManager = {
      i3 = {
        enable = true;
        package = pkgs.i3-gaps;
      };
    };

    desktopManager = {
      runXdgAutostartIfNone = true;
    };

    xkb = {
      layout = "us";
      variant = "";
      options = "caps:escape";
    };

    videoDrivers = [];
  };
}

You should add your own video drivers in a custom machine configuration.

4.4. Pipewire

My low latency pipewire configuration is used for music production, as well as for regular desktop usage. Pipewire is much better than pulseaudio because it supports jack with the same underlying interface and it breaks significantly less often.

{ lib, config, ... }:
{
  services.pipewire = {
    enable = lib.mkDefault config.monorepo.profiles.pipewire.enable;
    alsa = {
      enable = true;
      support32Bit = true;
    };
    pulse.enable = true;
    jack.enable = true;
    wireplumber.enable = true;
    extraConfig.pipewire-pulse."92-low-latency" = {
      "context.properties" = [
        {
          name = "libpipewire-module-protocol-pulse";
          args = { };
        }
      ];
      "pulse.properties" = {
        "pulse.min.req" = "32/48000";
        "pulse.default.req" = "32/48000";
        "pulse.max.req" = "32/48000";
        "pulse.min.quantum" = "32/48000";
        "pulse.max.quantum" = "32/48000";
      };
      "stream.properties" = {
        "node.latency" = "32/48000";
        "resample.quality" = 1;
      };
    };
  };
}

4.5. SSH

My SSH daemon configuration.

{ config, ... }:
{
  services.openssh = {
    enable = true;
    settings = {
      PasswordAuthentication = true;
      AllowUsers = [ config.monorepo.vars.userName ];
      PermitRootLogin = "no";
      KbdInteractiveAuthentication = false;
    };
  };
}

4.6. Tor

This is my tor configuration, used for my cryptocurrency wallets and whatever else I want it to do.

{ config, lib, ... }:
{
  services.tor = {
    enable = lib.mkDefault config.monorepo.profiles.tor.enable;
    openFirewall = true;
    client = {
      enable = lib.mkDefault config.monorepo.profiles.tor.enable;
      socksListenAddress = {
        IsolateDestAddr = true;
        addr = "127.0.0.1";
        port = 9050;
      };
      dns.enable = true;
    };
    torsocks = {
      enable = lib.mkDefault config.monorepo.profiles.tor.enable;
      server = "127.0.0.1:9050";
    };
  };
}

4.7. Kubo IPFS

I use IPFS for my website and also for my ISOs for truly declarative and deterministic configuration. NixOS might be moving to IPFS for binary cache distribution and package distribution soon, and I'm waiting on that.

{ config, pkgs, ... }:
{
  services.kubo = {
    enable = true;
  };
}

4.8. Main Configuration

This is the backbone of the all the NixOS configurations, with all these options being shared because they enhance security.

{ config, pkgs, lib, ... }:
{
  imports = [
    ./xserver.nix
    ./ssh.nix
    ./pipewire.nix
    ./tor.nix
    ./kubo.nix
  ];

  documentation = {
    enable = lib.mkDefault config.monorepo.profiles.documentation.enable;
    man.enable = lib.mkDefault config.monorepo.profiles.documentation.enable;
    dev.enable = lib.mkDefault config.monorepo.profiles.documentation.enable;
  };

  environment = {
    etc = {
      securetty.text = ''
          # /etc/securetty: list of terminals on which root is allowed to login.
          # See securetty(5) and login(1).
          '';
    };
  };

  systemd = {
    coredump.enable = false;
    network.config.networkConfig.IPv6PrivacyExtensions = "kernel";
    tmpfiles.settings = {
      "restricthome"."/home/*".Z.mode = "~0700";

      "restrictetcnixos"."/etc/nixos/*".Z = {
        mode = "0000";
        user = "root";
        group = "root";
      };
    };
  };


  boot = {
    extraModulePackages = [ ];

    initrd = {
      availableKernelModules = [
        "xhci_pci"
        "ahci"
        "usb_storage"
        "sd_mod"
        "nvme"
        "sd_mod"
        "ehci_pci"
        "rtsx_pci_sdmmc"
        "usbhid"
      ];

      kernelModules = [ ];
    };

    lanzaboote = {
      enable = config.monorepo.profiles.secureBoot.enable;
      pkiBundle = "/etc/secureboot";
    };

    loader = {
      systemd-boot.enable = lib.mkForce (! config.monorepo.profiles.secureBoot.enable);
      efi.canTouchEfiVariables = true;
    };

    kernelModules = [
      "snd-seq"
      "snd-rawmidi"
      "xhci_hcd"
      "kvm_intel"
    ];

    kernelParams = [
      "debugfs=off"
      "page_alloc.shuffle=1"
      "slab_nomerge"
      "page_poison=1"

      # madaidan
      "pti=on"
      "randomize_kstack_offset=on"
      "vsyscall=none"
      "module.sig_enforce=1"
      "lockdown=confidentiality"

      # cpu
      "spectre_v2=on"
      "spec_store_bypass_disable=on"
      "tsx=off"
      "tsx_async_abort=full,nosmt"
      "mds=full,nosmt"
      "l1tf=full,force"
      "nosmt=force"
      "kvm.nx_huge_pages=force"

      # hardened
      "extra_latent_entropy"

      # mineral
      "init_on_alloc=1"
      "random.trust_cpu=off"
      "random.trust_bootloader=off"
      "intel_iommu=on"
      "amd_iommu=force_isolation"
      "iommu=force"
      "iommu.strict=1"
      "init_on_free=1"
      "quiet"
      "loglevel=0"
    ];

    blacklistedKernelModules = [
      "netrom"
      "rose"

      "adfs"
      "affs"
      "bfs"
      "befs"
      "cramfs"
      "efs"
      "erofs"
      "exofs"
      "freevxfs"
      "f2fs"
      "hfs"
      "hpfs"
      "jfs"
      "minix"
      "nilfs2"
      "ntfs"
      "omfs"
      "qnx4"
      "qnx6"
      "sysv"
      "ufs"
    ];

    kernel.sysctl = {
      "kernel.ftrace_enabled" = false;
      "net.core.bpf_jit_enable" = false;
      "kernel.kptr_restrict" = 2;

      # madaidan
      "vm.swappiness" = 1;
      "vm.unprivileged_userfaultfd" = 0;
      "dev.tty.ldisc_autoload" = 0;
      "kernel.kexec_load_disabled" = 1;
      "kernel.sysrq" = 4;
      "kernel.perf_event_paranoid" = 3;

      # net
      "net.ipv4.icmp_echo_ignore_broadcasts" = true;

      "net.ipv4.conf.all.accept_redirects" = false;
      "net.ipv4.conf.all.secure_redirects" = false;
      "net.ipv4.conf.default.accept_redirects" = false;
      "net.ipv4.conf.default.secure_redirects" = false;
      "net.ipv6.conf.all.accept_redirects" = false;
      "net.ipv6.conf.default.accept_redirects" = false;
    };
  };

  networking = {
    useDHCP = lib.mkDefault true;
    hostName = config.monorepo.vars.hostName;
    networkmanager = {
      enable = true;
      # wifi.macAddress = "";
    };
    firewall = {
      allowedTCPPorts = [ ];
      allowedUDPPorts = [ ];
    };
  };

  hardware = {
    enableAllFirmware = true;
    cpu.intel.updateMicrocode = true;
    graphics.enable = true;
    pulseaudio.enable = ! config.monorepo.profiles.pipewire.enable;

    bluetooth = {
      enable = true;
      powerOnBoot = true;
    };
  };

  services = {
    chrony = {
      enable = true;
      enableNTS = true;
      servers = [ "time.cloudflare.com" "ptbtime1.ptb.de" "ptbtime2.ptb.de" ];
    };

    jitterentropy-rngd.enable = true;
    resolved.dnssec = true;
    # usbguard.enable = true;
    usbguard.enable = false;
    dbus.apparmor = "enabled";

    kanata.enable = true;

    # Misc.
    udev = {
      extraRules = '''';
      packages = with pkgs; [ 
        platformio-core
        platformio-core.udev
        openocd
      ];
    };

    printing.enable = true;
    udisks2.enable = true;
  };

  programs = {
    nix-ld.enable = true;
    zsh.enable = true;
    light.enable = true;
    ssh.enableAskPassword = false;
  };

  nixpkgs = {
    hostPlatform = lib.mkDefault "x86_64-linux";
    config = {
      allowUnfree = true;
      cudaSupport = lib.mkDefault config.monorepo.profiles.cuda.enable;
    };
  };

  security = {
    apparmor = {
      enable = true;
      killUnconfinedConfinables = true;
    };

    pam.loginLimits = [
      { domain = "*"; item = "nofile"; type = "-"; value = "32768"; }
      { domain = "*"; item = "memlock"; type = "-"; value = "32768"; }
    ];
    rtkit.enable = true;

    lockKernelModules = true;
    protectKernelImage = true;
    allowSimultaneousMultithreading = false;
    forcePageTableIsolation = true;

    tpm2 = {
      enable = true;
      pkcs11.enable = true;
      tctiEnvironment.enable = true;
    };

    auditd.enable = true;
    audit.enable = true;
    chromiumSuidSandbox.enable = true;
    sudo.enable = true;
  };

  xdg.portal = {
    enable = true;
    wlr.enable = true;
    extraPortals = with pkgs; [
      xdg-desktop-portal-gtk
      xdg-desktop-portal
      xdg-desktop-portal-hyprland
    ];
    config.common.default = "*";
  };

  environment.systemPackages = with pkgs; [
    restic
    sbctl
    git
    vim
    curl
  ];

  users.users = {
    root.openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINSshvS1N/42pH9Unp3Zj4gjqs9BXoin99oaFWYHXZDJ preston@preston-arch"
    ];

    "${config.monorepo.vars.userName}" = {
      initialPassword = "${config.monorepo.vars.userName}";
      isNormalUser = true;
      description = config.monorepo.vars.fullName;
      extraGroups = [ "networkmanager" "wheel" "video" "docker" "jackaudio" "tss" "dialout" ];
      shell = pkgs.zsh;
      packages = [];
    };
  };

  nix.settings.experimental-features = "nix-command flakes";
  time.timeZone = config.monorepo.vars.timeZone;
  i18n.defaultLocale = "en_CA.UTF-8";
  system.stateVersion = "24.11";
}

4.9. Disko

This is the disko configuration for my continuity system. It features a boot and ext4 partition, on disk /dev/sda. All my SATA disks have this location by default, but if you want to use nvme, you will have to import that configuration in your systems/xxx/default.nix.

{
  disko.devices = {
    disk = {
      my-disk = {
        device = "/dev/sda";
        type = "disk";
        content = {
          type = "gpt";
          partitions = {
            ESP = {
              type = "EF00";
              size = "500M";
              priority = 1;
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                mountOptions = [ "umask=0077" ];
              };
            };
            root = {
              size = "100%";
              priority = 2;
              content = {
                type = "filesystem";
                format = "ext4";
                mountpoint = "/";
              };
            };
          };
        };
      };
    };
  };
}

4.10. Home

Time for my home user configuration, which is managed by home-manager. First we start off with this module to enter us into the home-manager namespace:

{ config, sops-nix, ... }:
{
  home-manager = {
    sharedModules = [
      sops-nix.homeManagerModules.sops
    ];
    useGlobalPkgs = true;
    useUserPackages = true;
    users."${config.monorepo.vars.userName}" = import ./default.nix;
  };
}

as you can see, we import default.nix which puts us in the home-manager namespace. Everything in the top level from now on will implicitly be located at users."${config.monorepo.vars.userName}".xxxxx, and we will look at default.nix next.

4.10.1. Default Home Profile

As you can see, I have my installed home packages installed based on the profiles enabled. Also, I have many imports that we'll go through next.

{ lib, config, pkgs, ... }:
{
  imports = [
    ../vars.nix
    ./fcitx.nix
    ./secrets.nix
    ./emacs.nix
    ./firefox.nix
    ./git.nix
    ./hyprland.nix
    ./mpv.nix
    ./yt-dlp.nix
    ./wofi.nix
    ./kitty.nix
    ./waybar.nix
    ./zsh.nix
    ./mbsync.nix
    ./msmtp.nix
    ./gammastep.nix
    ./mpd.nix
    ./mako.nix
    ./user.nix
  ];

  options = {
    monorepo.profiles = {
      enable = lib.mkEnableOption "Enables home manager desktop configuration";
      # Programs
      lang-c.enable = lib.mkEnableOption "Enables C language support";
      lang-sh.enable = lib.mkEnableOption "Enables sh language support";
      lang-rust.enable = lib.mkEnableOption "Enables Rust language support";
      lang-python.enable = lib.mkEnableOption "Enables python language support";
      lang-sol.enable = lib.mkEnableOption "Enables solidity language support";
      lang-openscad.enable = lib.mkEnableOption "Enables openscad language support";
      lang-js.enable = lib.mkEnableOption "Enables javascript language support";
      lang-nix.enable = lib.mkEnableOption "Enables nix language support";
      lang-coq.enable = lib.mkEnableOption "Enables coq language support";

      crypto.enable = lib.mkEnableOption "Enables various cryptocurrency wallets";
      art.enable = lib.mkEnableOption "Enables various art programs";
      music.enable = lib.mkEnableOption "Enables mpd";

      hyprland = {
        enable = lib.mkEnableOption "Enables hyprland";
        monitors = lib.mkOption {
          type = lib.types.listOf lib.types.str;
          default = [
            "HDMI-A-1"
            "eDP-1"
            "DP-2"
            "DP-3"
            "LVDS-1"
          ];
          example = [];
          description = "Hyprland monitors";
        };
      };
      email = {
        email = lib.mkOption {
          type = lib.types.str;
          default = "ret2pop@gmail.com";
          example = "john@example.com";
          description = "Email address and imaps/smtps account";
        };
        imapsServer = lib.mkOption {
          type = lib.types.str;
          default = "imap.gmail.com";
          example = "imap.example.com";
          description = "imaps server address";
        };
        smtpsServer = lib.mkOption {
          type = lib.types.str;
          default = "smtp.gmail.com";
          example = "smtp.example.com";
          description = "smtp server address";
        };
        enable = lib.mkEnableOption "Enables email";
      };
    };
  };

  config = {
    home.packages = (if config.monorepo.profiles.email.enable then [ pkgs.mu ] else [])
                    ++
                    (if config.monorepo.profiles.lang-c.enable then (with pkgs; [
                      autobuild
                      clang
                      gdb
                      gnumake
                      bear
                      clang-tools
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-js.enable then (with pkgs; [
                      nodejs
                      bun
                      yarn
                      typescript
                      vscode-langservers-extracted
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-rust.enable then (with pkgs; [
                      cargo
                      rust-analyzer
                      rustfmt
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-python.enable then (with pkgs; [
                      poetry
                      python3
                      python312Packages.jedi
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-sol.enable then (with pkgs; [
                      solc
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-openscad.enable then (with pkgs; [
                      openscad
                      openscad-lsp
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-sh.enable then (with pkgs; [
                      bash-language-server
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-coq.enable then (with pkgs; [
                      coq
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.lang-nix.enable then (with pkgs; [
                      nil
                      nixd
                      nixfmt-rfc-style
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.crypto.enable then (with pkgs; [
                      bitcoin
                      electrum
                      monero-cli
                      monero-gui
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.art.enable then (with pkgs; [
                      inkscape
                      krita
                    ]) else [])
                    ++
                    (if config.monorepo.profiles.music.enable then (with pkgs; [
                      mpc-cli
                      sox
                    ]) else []);

    monorepo.profiles = {
      enable = lib.mkDefault true;
      music.enable = lib.mkDefault true;
      hyprland.enable = lib.mkDefault true;
      email.enable = lib.mkDefault true;

      # Programming
      lang-c.enable = lib.mkDefault true;
      lang-rust.enable = lib.mkDefault true;
      lang-python.enable = lib.mkDefault true;
      lang-sol.enable = lib.mkDefault true;
      lang-sh.enable = lib.mkDefault true;
      lang-openscad.enable = lib.mkDefault true;
      lang-js.enable = lib.mkDefault true;
      lang-nix.enable = lib.mkDefault true;
      lang-coq.enable = lib.mkDefault true;

      crypto.enable = lib.mkDefault true;
      art.enable = lib.mkDefault true;
    };
  };
}

4.10.2. Firefox

I conditionally enable metamask based on the cryptocurrency option. Everything else here should be straightforward.

{ lib, config, pkgs, ... }:
{
  programs.firefox = {
    enable = true;
    policies = {
      EnableTrackingProtection = true;
      OfferToSaveLogins = false;
    };
    package = pkgs.firefox-wayland;
    profiles = {
      default = {
        id = 0;
        name = "default";
        isDefault = true;

        extensions = with pkgs.nur.repos.rycee.firefox-addons; [
          ublock-origin
          tree-style-tab
          firefox-color
          vimium
        ]
        ++ (lib.optional
          config.monorepo.profiles.crypto.enable pkgs.nur.repos.rycee.firefox-addons.metamask);

        settings = {
          media = {
            memory_cache_max_size = 65536;
            cache_readahead_limit = 7200;
            cache_resume_threshold = 3600;
            peerconnection.ice = {
              proxy_only_if_behind_proxy = true;
              default_address_only = true;
            };
          };

          gfx = {
            content.skia-font-cache-size = 20;
            canvas.accelerated = {
              cache-items = 4096;
              cache-size = 512;
            };
          };

          network = {
            http = {
              max-connections = 1800;
              max-persistent-connections-per-server = 10;
              max-urgent-start-excessive-connections-per-host = 5;
              referer.XOriginTrimmingPolicy = 2;
            };

            buffer.cache = {
              size = 262144;
              count = 128;
            };

            dns = {
              max_high_priority_threads = 8;
              disablePrefetch = true;
            };

            pacing.requests.enabled = false;
            dnsCacheExpiration = 3600;
            ssl_tokens_cache_capacity = 10240;
            prefetch-next = false;
            predictor.enabled = false;
            cookie.sameSite.noneRequiresSecure = true;
            IDN_show_punycode = true;
            auth.subresource-http-auth-allow = 1;
            captive-portal-service.enabled = false;
            connectivity-service.enabled = false;
          };

          browser = {
            download = {
              always_ask_before_handling_new_types = true;
              manager.addToRecentDocs = false;
              open_pdf_attachments_inline = true;
              start_downloads_in_tmp_dir = true;
            };

            urlbar = {
              suggest.quicksuggest.sponsored = false;
              suggest.quicksuggest.nonsponsored = false;
              suggest.calculator = true;
              update2.engineAliasRefresh = true;
              unitConversion.enabled = true;
              trending.featureGate = false;
            };

            search = {
              separatePrivateDefault.ui.enabled = true;
              suggest.enabled = false;
            };

            newtabpage.activity-stream = {
              feeds = {
                topsites = false;
                section.topstories = false;
                telemetry = false;
              };
              asrouter.userprefs.cfr = {
                addons = false;
                features = false;
              };
              telemetry = false;
            };

            privatebrowsing = {
              vpnpromourl = "";
              forceMediaMemoryCache = true;
            };

            display = {
              focus_ring_on_anything = true;
              focus_ring_style = 0;
              focus_ring_width = 0;
            };

            cache.jsbc_compression_level = 3;
            helperApps.deleteTempFileOnExit = true;
            uitour.enabled = false;
            sessionstore.interval = 60000;
            formfill.enable = false;
            xul.error_pages.expert_bad_cert = true;
            contentblocking.category = "strict";
            ping-centre.telemetry = false;
            discovery.enabled = false;
            shell.checkDefaultBrowser = false;
            preferences.moreFromMozilla = false;
            tabs.tabmanager.enabled = false;
            aboutConfig.showWarning = false;
            aboutwelcome.enabled = false;
            bookmarks.openInTabClosesMenu = false;
            menu.showViewImageInfo = true;
            compactmode.show = true;
            safebrowsing.downloads.remote.enabled = false;
            tabs.crashReporting.sendReport = false;
            crashReports.unsubmittedCheck.autoSubmit2 = false;
            privateWindowSeparation.enabled = false;
          };

          security = {
            mixed_content = {
              block_display_content = true;
              upgrade_display_content = true;
            };
            insecure_connection_text = {
              enabled = true;
              pbmode.enabled = true;
            };
            OCSP.enabled = 0;
            remote_settings.crlite_filters.enabled = true;
            pki.crlite_mode = 2;
            ssl.treat_unsafe_negotiation_as_broken = true;
            tls.enable_0rtt_data = false;
          };

          toolkit = {
            telemetry = {
              unified = false;
              enabled = false;
              server = "data:,";
              archive.enabled = false;
              newProfilePing.enabled = false;
              shutdownPingSender.enabled = false;
              updatePing.enabled = false;
              bhrPing.enabled = false;
              firstShutdownPing.enabled = false;
              coverage.opt-out = true;
            };
            coverage = {
              opt-out = true;
              endpoint.base = "";
            };
            legacyUserProfileCustomizations.stylesheets = true;
          };

          dom = {
            security = {
              https_first = true;
              https_first_schemeless = true;
              sanitizer.enabled = true;
            };
            enable_web_task_scheduling = true;
          };

          layout = {
            css = {
              grid-template-masonry-value.enabled = true;
              has-selector.enabled = true;
              prefers-color-scheme.content-override = 2;
            };
            word_select.eat_space_to_next_word = false;
          };

          urlclassifier = {
            trackingSkipURLs = "*.reddit.com, *.twitter.com, *.twimg.com, *.tiktok.com";
            features.socialtracking.skipURLs = "*.instagram.com, *.twitter.com, *.twimg.com";
          };

          privacy = {
            globalprivacycontrol.enabled = true;
            history.custom = true;
            userContext.ui.enabled = true;
            trackingprotection = {
              enabled = true;
              pbmode.enabled = true;
              socialtracking.enabled = true;
            };
          };

          full-screen-api = {
            transition-duration = {
              enter = "0 0";
              leave = "0 0";
            };
            warning = {
              delay = -1;
              timeout = 0;
            };
          };

          permissions.default = {
            desktop-notification = 2;
            geo = 2;
          };

          signon = {
            formlessCapture.enabled = false;
            privateBrowsingCapture.enabled = false;
          };

          datareporting = {
            policy.dataSubmissionEnabled = false;
            healthreport.uploadEnabled = false;
          };

          extensions = {
            pocket.enabled = false;
            getAddons.showPane = false;
            htmlaboutaddons.recommendations.enabled = false;
            postDownloadThirdPartyPrompt = false;
          };

          app = {
            shield.optoutstudies.enabled = false;
            normandy.enabled = false;
            normandy.api_url = "";
          };

          image.mem.decode_bytes_at_a_time = 32768;
          editor.truncate_user_pastes = false;
          pdfjs.enableScripting = false;
          geo.provider.network.url = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%";
          permissions.manager.defaultsUrl = "";
          webchannel.allowObject.urlWhitelist = "";
          breakpad.reportURL = "";
          captivedetect.canonicalURL = "";
          cookiebanners.service.mode = 1;
          findbar.highlightAll = true;
          content.notify.interval = 100000;
        };
      };
    };
  };
}

4.10.3. Fcitx

This is a virtual keyboard program for writing in multiple languages. I use this sometimes.

{ pkgs, ... }:
{
  i18n.inputMethod = {
    enabled = "fcitx5";
    fcitx5.addons = with pkgs; [
      fcitx5-gtk
      fcitx5-chinese-addons
      fcitx5-configtool
      fcitx5-mozc
      fcitx5-rime
    ];
  };
}

Note that I configure fcitx with chinese and some japanese input enabled.

4.10.4. Emacs

I install all my emacs packages within Nix so that they build deterministically with native compilation, and because I can fetch their exact versions. Note that I have a stub configuration here that tells emacs to load my real configuration at ~/monorepo/config/emacs.org as an org file which gets automatically tangled to an emacs-lisp file.

{ lib, config, pkgs, ... }:
{
  programs.emacs = 
    {
      enable = true;
      package = pkgs.emacs29-pgtk;
      extraConfig = ''
      (setq debug-on-error t)
      (org-babel-load-file
        (expand-file-name "~/monorepo/config/emacs.org"))'';
      extraPackages = epkgs: [
        epkgs.all-the-icons
        epkgs.auctex
        epkgs.catppuccin-theme
        epkgs.chatgpt-shell
        epkgs.company
        epkgs.company-solidity
        epkgs.counsel
        epkgs.dashboard
        epkgs.doom-modeline
        epkgs.elfeed
        epkgs.elfeed-org
        epkgs.elfeed-tube
        epkgs.elfeed-tube-mpv
        epkgs.ellama
        epkgs.elpher
        epkgs.ement
        epkgs.emmet-mode
        epkgs.emms
        epkgs.enwc
        epkgs.evil
        epkgs.evil-collection
        epkgs.evil-commentary
        epkgs.evil-org
        epkgs.f
        epkgs.flycheck
        epkgs.general
        epkgs.gptel
        epkgs.gruvbox-theme
        epkgs.htmlize
        epkgs.irony-eldoc
        epkgs.ivy
        epkgs.ivy-pass
        epkgs.latex-preview-pane
        epkgs.lsp-ivy
        epkgs.lsp-mode
        epkgs.lyrics-fetcher
        epkgs.magit
        epkgs.magit-delta
        epkgs.mu4e
        epkgs.nix-mode
        epkgs.org-fragtog
        epkgs.org-journal
        epkgs.org-roam
        epkgs.org-roam-ui
        epkgs.org-superstar
        epkgs.page-break-lines
        epkgs.password-store
        epkgs.pdf-tools
        epkgs.pinentry
        epkgs.platformio-mode
        epkgs.projectile
        epkgs.rustic
        epkgs.scad-mode
        epkgs.simple-httpd
        epkgs.solidity-flycheck
        epkgs.solidity-mode
        epkgs.sudo-edit
        epkgs.treemacs
        epkgs.treemacs-evil
        epkgs.treemacs-magit
        epkgs.treemacs-projectile
        epkgs.treesit-auto
        epkgs.typescript-mode
        epkgs.unicode-fonts
        epkgs.use-package
        epkgs.vterm
        epkgs.web-mode
        epkgs.websocket
        epkgs.which-key
        epkgs.writegood-mode
        epkgs.writeroom-mode
        epkgs.yaml-mode
        epkgs.yasnippet
        epkgs.yasnippet-snippets
      ];
    };
}

4.10.5. Gammastep

This is a program like redshift for making your screen emit more red and less blue light. Here I have the long and lat set for Vancouver, but you should replace it if you live outside the timezone.

{ lib, config, ... }:
{
  services.gammastep = {
    enable = true;
    provider = "manual";
    latitude = 49.282730;
    longitude = -123.120735;

    temperature = {
      day = 5000;
      night = 3000;
    };

    settings = {
      general = {
        adjustment-method = "wayland";
      };
    };
  };
}

4.10.6. Git

My git configuration uses information set in the vars.nix in order to set configuration options. Make sure those are set correctly. I've set it to sign by default.

{ lib, config, ... }:
{
  programs.git = {
    enable = true;
    userName = config.monorepo.vars.fullName;
    userEmail = config.monorepo.profiles.email.email;
    signing = {
      key = config.monorepo.vars.gpgKey;
      signByDefault = true;
    };

    extraConfig = {
      init.defaultBranch = "main";
    };

    aliases = {
      co = "checkout";
      c = "commit";
      a = "add";
      s = "switch";
      b = "branch";
    };
  };
}

4.10.7. Hyprland

My compositor/window manager. This automatically starts on startup. Instructions on how to use this component will come soon.

{ lib, config, wallpapers, pkgs, scripts, ... }:
{
  wayland.windowManager.hyprland = {
    enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
    package = pkgs.hyprland;
    xwayland.enable = true;
    systemd.enable = true;
    settings = {
      "$mod" = "SUPER";
      exec-once = [
        "waybar"
        "swww-daemon --format xrgb"
        "swww img ${wallpapers}/imagination.png"
        "fcitx5-remote -r"
        "fcitx5 -d --replace"
        "fcitx5-remote -r"
        "emacs"
        "firefox"
      ];
      env = [
        "LIBVA_DRIVER_NAME,nvidia"
        "XDG_SESSION_TYPE,wayland"
        "GBM_BACKEND,nvidia-drm"
        "__GLX_VENDOR_LIBRARY_NAME,nvidia"
        "ELECTRON_OZONE_PLATFORM_HINT,auto"
      ];
      blurls = [
        "waybar"
      ];
      monitor = [
        "Unknown-1,disable"
      ];
      windowrule = [
        "workspace 1, ^(.*emacs.*)$"
        "workspace 2, ^(.*firefox.*)$"
        "workspace 2, ^(.*Tor Browser.*)$"
        "workspace 2, ^(.*Chromium-browser.*)$"
        "workspace 2, ^(.*chromium.*)$"
        "workspace 3, ^(.*discord.*)$"
        "workspace 3, ^(.*vesktop.*)$"
        "workspace 3, ^(.*fluffychat.*)$"
        "workspace 3, ^(.*element-desktop.*)$"
        "workspace 4, ^(.*qpwgraph.*)$"
        "workspace 4, ^(.*mpv.*)$"
        "workspace 5, ^(.*Monero.*)$"
        "workspace 5, ^(.*org\.bitcoin\..*)$"
        "workspace 5, ^(.*Bitcoin Core - preston.*)$"
        "workspace 5, ^(.*org\.getmonero\..*)$"
        "workspace 5, ^(.*Monero - preston.*)$"
        "workspace 5, ^(.*electrum.*)$"
        "pseudo,fcitx"
      ];
      bind = [
        "$mod, F, exec, firefox"
        "$mod, T, exec, tor-browser"
        "$mod, Return, exec, kitty"
        "$mod, E, exec, emacs"
        "$mod, B, exec, bitcoin-qt"
        "$mod, M, exec, monero-wallet-gui"
        "$mod, V, exec, vesktop"
        "$mod, D, exec, wofi --show run"
        "$mod, P, exec, bash ${scripts}/powermenu.sh"
        "$mod, Q, killactive"
        "$mod SHIFT, H, movewindow, l"
        "$mod SHIFT, L, movewindow, r"
        "$mod SHIFT, K, movewindow, u"
        "$mod SHIFT, J, movewindow, d"
        "$mod, H, movefocus, l"
        "$mod, L, movefocus, r"
        "$mod, K, movefocus, u"
        "$mod, J, movefocus, d"
        ", XF86AudioPlay, exec, mpc toggle"
        ", Print, exec, grim"
      ]
      ++ (
        builtins.concatLists (builtins.genList
          (
            x:
            let
              ws =
                let
                  c = (x + 1) / 10;
                in
                  builtins.toString (x + 1 - (c * 10));
            in
              [
                "$mod, ${ws}, workspace, ${toString (x + 1)}"
                "$mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}"
              ]
          )
          10)
      );
      bindm = [
        "$mod, mouse:272, movewindow"
        "$mod, mouse:273, resizewindow"
        "$mod ALT, mouse:272, resizewindow"
      ];
      binde = [
        ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
        ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-"
        ", XF86AudioNext, exec, mpc next"
        ", XF86AudioPrev, exec, mpc prev"
        ", XF86MonBrightnessUp , exec, xbacklight -inc 10"
        ", XF86MonBrightnessDown, exec, xbacklight -dec 10"
      ];
      decoration = {
        blur = {
          enabled = true;
          size = 5;
          passes = 2;
        };
        rounding = 5;
      };
      input = {
        kb_options = "caps:swapescape";
        repeat_delay = 300;
        repeat_rate = 50;
        natural_scroll = true;
        touchpad = {
          natural_scroll = true;
          disable_while_typing = true;
          tap-to-click = true;
        };
      };
      cursor = {
        no_hardware_cursors = true;
      };
      misc = {
        force_default_wallpaper = 0;
        disable_hyprland_logo = true;
      };
    };
  };
}

4.10.8. Kitty

I've set my terminal, kitty, to use catppuccin colors.

{ lib, config, ... }:
{
  programs.kitty = {
    enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
    settings = {
      enable_audio_bell = false;
      font_family = "Iosevka Nerd Font";
      font_size = 14;
      confirm_os_window_close = 0;
      background_opacity = "0.9";
      # Catppuccin theme
      foreground = "#cdd6f4";
      background = "#1e1e2e";
      selection_foreground = "#1e1e2e";
      selection_background = "#f5e0dc";
      cursor = "#f5e0dc";
      cursor_text_color = "#1e1e2e";
      url_color = "#f5e0dc";
      active_border_color = "#B4BEFE";
      inactive_border_color = "#6C7086";
      bell_border_color = "#F9E2AF";
      wayland_titlebar_color = "#1E1E2E";
      macos_titlebar_color = "#1E1E2E";
      active_tab_foreground = "#11111B";
      active_tab_background = "#CBA6F7";
      inactive_tab_foreground = "#CDD6F4";
      inactive_tab_background = "#181825";
      tab_bar_background = "#11111B";
      mark1_foreground = "#1E1E2E";
      mark1_background = "#B4BEFE";
      mark2_foreground = "#1E1E2E";
      mark2_background = "#CBA6F7";
      mark3_foreground = "#1E1E2E";
      mark3_background = "#74C7EC";
      color0 = "#45475A";
      color8 = "#585B70";
      color1 = "#F38BA8";
      color9 = "#F38BA8";
      color2 = "#A6E3A1";
      color10 = "#A6E3A1";
      color3 = "#F9E2AF";
      color11 = "#F9E2AF";
      color4 = "#89B4FA";
      color12 = "#89B4FA";
      color5 = "#F5C2E7";
      color13 = "#F5C2E7";
      color6 = "#94E2D5";
      color14 = "#94E2D5";
      color7 = "#BAC2DE";
      color15 = "#A6ADC8";
    };
  };
}

4.10.9. Mako

This is my notification system. My flake automatically fetches the notification sound, so you are all set from the get-go!

{ lib, config, sounds, ... }:
{
  services.mako = {
    enable = true;
    backgroundColor = "#11111bf8";
    textColor = "#cdd6f4";
    borderColor = "#89b4faff";
    borderRadius = 1;
    font = "Fira Code 10";
    defaultTimeout = 3000;
    extraConfig = ''
on-notify=exec mpv ${sounds}/polite.ogg --no-config --no-video
'';
  };
}

4.10.10. Mbsync

Note that in order to use my email configuration, your imaps and smtps servers must be encrypted. This module uses the vars.nix as well as the home default.nix options.

{ lib, config, ... }:
{
  programs.mbsync = {
    enable = lib.mkDefault config.monorepo.profiles.email.enable;
    extraConfig = ''
      IMAPAccount ret2pop
      Host ${config.monorepo.profiles.email.imapsServer}
      User ${config.monorepo.profiles.email.email}
      PassCmd "cat ${config.sops.secrets.mail.path}"
      Port 993
      TLSType IMAPS
      AuthMechs *
      CertificateFile /etc/ssl/certs/ca-certificates.crt

      IMAPStore ret2pop-remote
      Account ret2pop

      MaildirStore ret2pop-local
      Path ~/email/ret2pop/
      Inbox ~/email/ret2pop/INBOX
      SubFolders Verbatim

      Channel ret2pop 
      Far :ret2pop-remote:
      Near :ret2pop-local:
      Patterns *
      Create Near
      Sync All
      Expunge None
      SyncState *
    '';
  };
}

4.10.11. MSMTP

This is the program I use to send email from emacs. It is really the same thing as above, just set the options to the ones you want in your system default.nix.

{ lib, config, ... }:
{
  programs.msmtp = {
    enable = lib.mkDefault config.monorepo.profiles.email.enable;
    extraConfig = ''
      # Set default values for all following accounts.
      defaults
      auth           on
      tls            on
      tls_trust_file /etc/ssl/certs/ca-certificates.crt
      tls_certcheck  off
      logfile        ~/.msmtp.log

      # Gmail
      account        ${config.monorepo.vars.userName}
      host           ${config.monorepo.profiles.email.smtpsServer}
      port           587
      from           ${config.monorepo.profiles.email.email}
      user           ${config.monorepo.profiles.email.email}
      passwordeval   "cat ${config.sops.secrets.mail.path}"


      # Set a default account
      account default : ${config.monorepo.vars.userName}
    '';
  };
}

4.10.12. Mpd

This mpd configuration uses pipewire by default, and it should just work if you place music in the ~/music directory and then run mpc add / afterwards.

{ lib, config, ... }:
{
  services.mpd = {
  enable = lib.mkDefault config.monorepo.profiles.music.enable;
  dbFile = "/home/${config.monorepo.vars.userName}/.config/mpd/db";
  dataDir = "/home/${config.monorepo.vars.userName}/.config/mpd/";
  network.port = 6600;
  musicDirectory = "/home/${config.monorepo.vars.userName}/music";
  playlistDirectory = "/home/${config.monorepo.vars.userName}/.config/mpd/playlists";
  network.listenAddress = "0.0.0.0";
  extraConfig = ''
      audio_output {
        type "pipewire"
        name "pipewire output"
      }
      audio_output {
        type    "httpd"
        name    "My HTTP Stream"
        encoder   "opus"    # optional
        port    "8000"
     #  quality   "5.0"     # do not define if bitrate is defined
        bitrate   "128000"      # do not define if quality is defined
        format    "48000:16:1"
        always_on       "yes" # prevent MPD from disconnecting all listeners when playback is stopped.
        tags            "yes" # httpd supports sending tags to listening streams.
      }
    '';
  };
}

4.10.13. MPV

I have some emacs + yt-dlp integrations with mpv with my rss feed, and therefore we need it here:

{ lib, config, ... }:
{
  programs.mpv = {
    enable = true;
    config = {
      profile = "gpu-hq";
      force-window = true;
      ytdl-format = "bestvideo+bestaudio";
      cache-default = 4000000;
    };
  };
}

4.10.14. Secrets

This uses sops in order to declaratively create the secrets on my system by unencrypting the yaml file specified. Yes, this is safe to include in the repo.

{ config, ... }:
{
  sops = {
    defaultSopsFile = ../../secrets/secrets.yaml;
    age = {
      keyFile = "/home/${config.monorepo.vars.userName}/.ssh/keys.txt";
    };
    secrets.mail = {
      format = "yaml";
      path = "${config.sops.defaultSymlinkPath}/mail";
    };
    secrets.digikey = {
      format = "yaml";
      path = "${config.sops.defaultSymlinkPath}/digikey";
    };

    defaultSymlinkPath = "/run/user/1000/secrets";
    defaultSecretsMountPoint = "/run/user/1000/secrets.d";
  };
}

4.10.15. Waybar

This is the bar I use for my hyprland configuration. You will need to adjust the monitors field in the default.nix for it to really appear.

{ lib, config, ... }:
{
  programs.waybar = {
    enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
    style = ''
      * {
          border: none;
          border-radius: 0px;
          font-family: Iosevka Nerd Font, FontAwesome, Noto Sans CJK;
          font-size: 14px;
          font-style: normal;
          min-height: 0;
      }

      window#waybar {
          background: rgba(30, 30, 46, 0.5);
          border-bottom: 1px solid #45475a;
          color: #cdd6f4;
      }

      #workspaces {
        background: #45475a;
        margin: 5px 5px 5px 5px;
        padding: 0px 5px 0px 5px;
        border-radius: 16px;
        border: solid 0px #f4d9e1;
        font-weight: normal;
        font-style: normal;
      }
      #workspaces button {
          padding: 0px 5px;
          border-radius: 16px;
          color: #a6adc8;
      }

      #workspaces button.active {
          color: #f4d9e1;
          background-color: transparent;
          border-radius: 16px;
      }

      #workspaces button:hover {
        background-color: #cdd6f4;
        color: black;
        border-radius: 16px;
      }

      #custom-date, #clock, #battery, #pulseaudio, #network, #custom-randwall, #custom-launcher {
        background: transparent;
        padding: 5px 5px 5px 5px;
        margin: 5px 5px 5px 5px;
        border-radius: 8px;
        border: solid 0px #f4d9e1;
      }

      #custom-date {
        color: #D3869B;
      }

      #custom-power {
        color: #24283b;
        background-color: #db4b4b;
        border-radius: 5px;
        margin-right: 10px;
        margin-top: 5px;
        margin-bottom: 5px;
        margin-left: 0px;
        padding: 5px 10px;
      }

      #tray {
          background: #45475a;
          margin: 5px 5px 5px 5px;
          border-radius: 16px;
          padding: 0px 5px;
          /*border-right: solid 1px #282738;*/
      }

      #clock {
          color: #cdd6f4;
          background-color: #45475a;
          border-radius: 0px 0px 0px 24px;
          padding-left: 13px;
          padding-right: 15px;
          margin-right: 0px;
          margin-left: 10px;
          margin-top: 0px;
          margin-bottom: 0px;
          font-weight: bold;
          /*border-left: solid 1px #282738;*/
      }

      #battery {
          color: #89b4fa;
      }

      #battery.charging {
          color: #a6e3a1;
      }

      #battery.warning:not(.charging) {
          background-color: #f7768e;
          color: #f38ba8;
          border-radius: 5px 5px 5px 5px;
      }

      #backlight {
          background-color: #24283b;
          color: #db4b4b;
          border-radius: 0px 0px 0px 0px;
          margin: 5px;
          margin-left: 0px;
          margin-right: 0px;
          padding: 0px 0px;
      }

      #network {
          color: #f4d9e1;
          border-radius: 8px;
          margin-right: 5px;
      }

      #pulseaudio {
          color: #f4d9e1;
          border-radius: 8px;
          margin-left: 0px;
      }

      #pulseaudio.muted {
          background: transparent;
          color: #928374;
          border-radius: 8px;
          margin-left: 0px;
      }

      #custom-randwall {
          color: #f4d9e1;
          border-radius: 8px;
          margin-right: 0px;
      }

      #custom-launcher {
          color: #e5809e;
          background-color: #45475a;
          border-radius: 0px 24px 0px 0px;
          margin: 0px 0px 0px 0px;
          padding: 0 20px 0 13px;
          /*border-right: solid 1px #282738;*/
          font-size: 20px;
      }

      #custom-launcher button:hover {
          background-color: #FB4934;
          color: transparent;
          border-radius: 8px;
          margin-right: -5px;
          margin-left: 10px;
      }

      #custom-playerctl {
        background: #45475a;
        padding-left: 15px;
        padding-right: 14px;
        border-radius: 16px;
        /*border-left: solid 1px #282738;*/
        /*border-right: solid 1px #282738;*/
        margin-top: 5px;
        margin-bottom: 5px;
        margin-left: 0px;
        font-weight: normal;
        font-style: normal;
        font-size: 16px;
      }

      #custom-playerlabel {
          background: transparent;
          padding-left: 10px;
          padding-right: 15px;
          border-radius: 16px;
          /*border-left: solid 1px #282738;*/
          /*border-right: solid 1px #282738;*/
          margin-top: 5px;
          margin-bottom: 5px;
          font-weight: normal;
          font-style: normal;
      }

      #window {
          background: #45475a;
          padding-left: 15px;
          padding-right: 15px;
          border-radius: 16px;
          /*border-left: solid 1px #282738;*/
          /*border-right: solid 1px #282738;*/
          margin-top: 5px;
          margin-bottom: 5px;
          font-weight: normal;
          font-style: normal;
      }

      #custom-wf-recorder {
          padding: 0 20px;
          color: #e5809e;
          background-color: #1E1E2E;
      }

      #cpu {
          background-color: #45475a;
          /*color: #FABD2D;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 10px 0px 10px;
          font-weight: bold;
      }

      #memory {
          background-color: #45475a;
          /*color: #83A598;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 10px 0px 10px;
          font-weight: bold;
      }

      #disk {
          background-color: #45475a;
          /*color: #8EC07C;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 10px 0px 10px;
          font-weight: bold;
      }

      #custom-hyprpicker {
          background-color: #45475a;
          /*color: #8EC07C;*/
          border-radius: 16px;
          margin: 5px;
          margin-left: 5px;
          margin-right: 5px;
          padding: 0px 11px 0px 9px;
          font-weight: bold;
      }
    '';
    settings = {
      mainBar = {
        layer = "top";
        position = "top";
        height = 50;

        output = config.monorepo.vars.monitors;

        modules-left = [ "hyprland/workspaces" ];
        modules-center = [ "hyprland/window" ];
        modules-right = [ "battery" "clock" ];

        battery = {
          format = "{icon}  {capacity}%";
          format-icons = ["" "" "" "" "" ];
        };

        clock = {
          format = "⏰ {:%a %d, %b %H:%M}";
        };
      };
    };
  };
}

4.10.16. Wofi

This is a run launcher for wayland. I also use it for my powermenu.

{ lib, config, ... }:
{
  programs.wofi = {
    enable = true; 
    settings = {
      location = "bottom-right";
      allow_markup = true;
      show = "drun";
      width = 750;
      height = 400;
      always_parse_args = true;
      show_all = false;
      term = "kitty";
      hide_scroll = true;
      print_command = true;
      insensitive = true;
      prompt = "Run what, Commander?";
      columns = 2;
    };

    style = ''
      @define-color rosewater  #f5e0dc;
      @define-color rosewater-rgb  rgb(245, 224, 220);
      @define-color flamingo  #f2cdcd;
      @define-color flamingo-rgb  rgb(242, 205, 205);
      @define-color pink  #f5c2e7;
      @define-color pink-rgb  rgb(245, 194, 231);
      @define-color mauve  #cba6f7;
      @define-color mauve-rgb  rgb(203, 166, 247);
      @define-color red  #f38ba8;
      @define-color red-rgb  rgb(243, 139, 168);
      @define-color maroon  #eba0ac;
      @define-color maroon-rgb  rgb(235, 160, 172);
      @define-color peach  #fab387;
      @define-color peach-rgb  rgb(250, 179, 135);
      @define-color yellow  #f9e2af;
      @define-color yellow-rgb  rgb(249, 226, 175);
      @define-color green  #a6e3a1;
      @define-color green-rgb  rgb(166, 227, 161);
      @define-color teal  #94e2d5;
      @define-color teal-rgb  rgb(148, 226, 213);
      @define-color sky  #89dceb;
      @define-color sky-rgb  rgb(137, 220, 235);
      @define-color sapphire  #74c7ec;
      @define-color sapphire-rgb  rgb(116, 199, 236);
      @define-color blue  #89b4fa;
      @define-color blue-rgb  rgb(137, 180, 250);
      @define-color lavender  #b4befe;
      @define-color lavender-rgb  rgb(180, 190, 254);
      @define-color text  #cdd6f4;
      @define-color text-rgb  rgb(205, 214, 244);
      @define-color subtext1  #bac2de;
      @define-color subtext1-rgb  rgb(186, 194, 222);
      @define-color subtext0  #a6adc8;
      @define-color subtext0-rgb  rgb(166, 173, 200);
      @define-color overlay2  #9399b2;
      @define-color overlay2-rgb  rgb(147, 153, 178);
      @define-color overlay1  #7f849c;
      @define-color overlay1-rgb  rgb(127, 132, 156);
      @define-color overlay0  #6c7086;
      @define-color overlay0-rgb  rgb(108, 112, 134);
      @define-color surface2  #585b70;
      @define-color surface2-rgb  rgb(88, 91, 112);
      @define-color surface1  #45475a;
      @define-color surface1-rgb  rgb(69, 71, 90);
      @define-color surface0  #313244;
      @define-color surface0-rgb  rgb(49, 50, 68);
      @define-color base  #1e1e2e;
      @define-color base-rgb  rgb(30, 30, 46);
      @define-color mantle  #181825;
      @define-color mantle-rgb  rgb(24, 24, 37);
      @define-color crust  #11111b;
      @define-color crust-rgb  rgb(17, 17, 27);

      * {
        font-family: 'Iosevka Nerd Font', monospace;
        font-size: 14px;
      }

      /* Window */
      window {
        margin: 0px;
        padding: 10px;
        border: 0.16em solid @lavender;
        border-radius: 0.1em;
        background-color: @base;
        animation: slideIn 0.5s ease-in-out both;
      }

      /* Slide In */
      @keyframes slideIn {
        0% {
           opacity: 0;
        }

        100% {
           opacity: 1;
        }
      }

      /* Inner Box */
      #inner-box {
        margin: 5px;
        padding: 10px;
        border: none;
        background-color: @base;
        animation: fadeIn 0.5s ease-in-out both;
      }

      /* Fade In */
      @keyframes fadeIn {
        0% {
           opacity: 0;
        }

        100% {
           opacity: 1;
        }
      }

      /* Outer Box */
      #outer-box {
        margin: 5px;
        padding: 10px;
        border: none;
        background-color: @base;
      }

      /* Scroll */
      #scroll {
        margin: 0px;
        padding: 10px;
        border: none;
        background-color: @base;
      }

      /* Input */
      #input {
        margin: 5px 20px;
        padding: 10px;
        border: none;
        border-radius: 0.1em;
        color: @text;
        background-color: @base;
        animation: fadeIn 0.5s ease-in-out both;
      }

      #input image {
          border: none;
          color: @red;
      }

      #input * {
        outline: 4px solid @red!important;
      }

      /* Text */
      #text {
        margin: 5px;
        border: none;
        color: @text;
        animation: fadeIn 0.5s ease-in-out both;
      }

      #entry {
        background-color: @base;
      }

      #entry arrow {
        border: none;
        color: @lavender;
      }

      /* Selected Entry */
      #entry:selected {
        border: 0.11em solid @lavender;
      }

      #entry:selected #text {
        color: @mauve;
      }

      #entry:drop(active) {
        background-color: @lavender!important;
      }
    '';
  };
}

4.10.17. yt-dlp

A classic program that allows you to download from youtube. Also has integrations with mpv.

{ lib, config, ... }:
{
  programs.yt-dlp = {
    enable = true;
    settings = {
      embed-thumbnail = true;
      embed-subs = true;
      sub-langs = "all";
      downloader = "aria2c";
      downloader-args = "aria2c:'-c -x8 -s8 -k1M'";
    };
  };
}

4.10.18. Zsh

My zsh config has some useful aliases that one should read through. Otherwise it is pretty standard.

{ lib, config, pkgs, ... }:
{
  programs.zsh = {
    enable = true;
    initExtra = ''
    umask 0077
    export EXTRA_CCFLAGS="-I/usr/include"
    source ${pkgs.zsh-vi-mode}/share/zsh-vi-mode/zsh-vi-mode.plugin.zsh
    export QT_QPA_PLATFORM="wayland"
    '';

    localVariables = {
      EDITOR = "emacsclient --create-frame --alternate-editor=vim";
      INPUT_METHOD = "fcitx";
      QT_IM_MODULE = "fcitx";
      GTK_IM_MODULE = "fcitx";
      XMODIFIERS = "@im=fcitx";
      XIM_SERVERS = "fcitx";
      WXSUPPRESS_SIZER_FLAGS_CHECK = "1";
    };

    shellAliases = {
      c = "clear";
      g = "git";
      v = "vim";
      py = "python3";
      rb = "sudo nixos-rebuild switch --flake .#continuity";
      nfu = "cd ~/monorepo/nix && git add . && git commit -m \"new flake lock\" &&  nix flake update";
      usite
      = "cd ~/monorepo/publish-org-roam-ui && bash local.sh && rm -rf ~/website_html/graph_view; cp -r ~/monorepo/publish-org-roam-ui/out ~/website_html/graph_view && rsync -azvP --chmod=\"Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r\" ~/website_html/ root@${config.monorepo.vars.remoteHost}:/usr/share/nginx/ret2pop/";
      sai = "eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && ssh-add -l";
      i3 = "exec ${pkgs.i3-gaps}/bin/i3";
    };
    loginExtra = ''
      if [[ "$(tty)" = "/dev/tty1" ]]; then
          exec Hyprland
      fi
    '';
  };
}

4.10.19. User

This configuration is the backbone configuration for the default user. It specifies some generally useful packages and something every home should have, as well as some dependencies for these configurations.

{ lib, config, pkgs, ... }:
{
  home = {
    activation.startup-files = lib.hm.dag.entryAfter [ "installPackages" ] ''
    if [ ! -d "/home/${config.monorepo.vars.userName}/email/ret2pop/" ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/email/ret2pop/
    fi
    if [ ! -d "/home/${config.monorepo.vars.userName}/music" ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/music
    fi
    if [ ! -d /home/${config.monorepo.vars.userName}/org ]; then
      mkdir -p /home/${config.monorepo.vars.userName}/org
    fi
    touch /home/${config.monorepo.vars.userName}/org/agenda.org
    touch /home/${config.monorepo.vars.userName}/org/notes.org
    '';

    enableNixpkgsReleaseCheck = false;
    username = config.monorepo.vars.userName;
    homeDirectory = "/home/${config.monorepo.vars.userName}";
    stateVersion = "24.11";

    packages = with pkgs; [
      # passwords
      age sops

      # formatting
      ghostscript texliveFull pandoc

      # Emacs Deps
      graphviz jq

      # Apps
      octaveFull vesktop grim swww vim 

      # Sound/media
      pavucontrol alsa-utils imagemagick ffmpeg helvum

      # Net
      curl rsync git

      # Tor
      torsocks tor-browser

      # fonts
      noto-fonts
      noto-fonts-cjk-sans
      noto-fonts-emoji
      fira-code
      font-awesome_6
      (aspellWithDicts
        (dicts: with dicts; [ en en-computers en-science ]))
      (nerdfonts.override { fonts = [ "Iosevka" ]; })

      # Misc.
      pinentry
      x11_ssh_askpass
      xdg-utils
      acpilight
      pfetch
      libnotify
    ];
  };

  services = {
    gpg-agent = {
      pinentryPackage = pkgs.pinentry-emacs;
      enable = true;
      extraConfig = ''
      allow-emacs-pinentry
      allow-loopback-pinentry
    '';
    };
  };

  programs.bash.enable = true;

  gtk = {
    enable = true;
    theme = null;
    iconTheme = null;
  };

  fonts.fontconfig.enable = true;
  nixpkgs.config.cudaSupport = lib.mkDefault config.monorepo.profiles.cuda.enable;
}

5. Systems

5.1. Continuity

This is pretty understandable, if you understand all the above.

{ ... }:
{
  imports = [
    ../../modules/default.nix
  ];
}

5.2. Installer

My installer installs my systems almost completely without interaction. You can also make them install the exact version of the system that you want it to by pinning the commits to make it always work in the exact same deterministic way.

5.2.1. Commit Hash Pinning

Modify this to pin the installer image hash to make the installer image always work deterministically.

{
  diskoCommitHash = "latest";
  monorepoCommitHash = "HEAD";
}

5.2.2. ISO Default Profile

This contains the installation script I use to install my systems.

{ pkgs, config, ... }:
let
  commits = import ./commits.nix;
in
{
  networking = {
    hostName = "nixos";
    networkmanager = {
      enable = true;
    };
    firewall = {
      allowedTCPPorts = [ ];
      allowedUDPPorts = [ ];
    };
    wireless.enable = false;
  };

  users.extraUsers.root.password = "nixos";
  users.extraUsers.nixos.password = "nixos";
  users.users = {
    nixos = {
      packages = with pkgs; [
        git
        curl
        gum
        (writeShellScriptBin "nix_installer"
          ''
#!/usr/bin/env bash

set -euo pipefail
if [ "$(id -u)" -eq 0 ]; then
  echo "ERROR! $(basename "$0") should be run as a regular user"
  exit 1
fi
ping -q -c1 google.com &>/dev/null && echo "online! Proceeding with the installation..." || nmtui
cd
if [ ! -d "$HOME/monorepo/" ]; then
  git clone --recurse-submodules https://git.nullring.xyz/monorepo.git
  cd monorepo
  git checkout "${commits.monorepoCommitHash}"
fi
vim "$HOME/monorepo/nix/systems/continuity/default.nix"
sudo nix --experimental-features "nix-command flakes" run "github:nix-community/disko/${commits.diskoCommitHash}" -- --mode destroy,format,mount "$HOME/monorepo/nix/modules/sda-simple.nix"
cd /mnt
sudo nixos-install --flake $HOME/monorepo/nix#continuity
sudo cp -r $HOME/monorepo "/mnt/home/$(ls /mnt/home/)/"
echo "rebooting..."; sleep 3; reboot
'')
      ];
    };
  };

  systemd = {
    services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
    targets = {
      sleep.enable = false;
      suspend.enable = false;
      hibernate.enable = false;
      hybrid-sleep.enable = false;
    };
  };
}
Copyright © 2024 Preston Pan