nixpkgs.config.allowUnfree in the system module (covers the live ISO
via useGlobalPkgs and every mkFlake machine) plus the two explicit
`import nixpkgs` sites (repo + lib.nix) so the standalone HM desktop
sees the same package set. Unblocks claude-code for the menu system's
ask-Claude module, vendor drivers, etc. Opt out with
`nixpkgs.config = lib.mkForce { allowUnfree = false; }`.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
169 lines
6.8 KiB
Nix
169 lines
6.8 KiB
Nix
# Nomarchy — reusable system layer (NixOS 26.05).
|
||
#
|
||
# This module is the distro: import it from any host (see
|
||
# nixosModules.nomarchy in flake.nix) and layer your machine specifics
|
||
# (bootloader, hostname, users, hardware) on top. Host concerns are
|
||
# deliberately NOT set here. Everything user-facing (Hyprland config,
|
||
# Waybar, Ghostty, theming) lives in modules/home.
|
||
{ config, lib, pkgs, ... }:
|
||
|
||
let
|
||
cfg = config.nomarchy.system;
|
||
in
|
||
{
|
||
imports = [ ./options.nix ];
|
||
|
||
config = {
|
||
# Unfree allowed distro-wide: pragmatic-desktop territory (claude-code
|
||
# for the menu's ask-Claude module, vendor drivers, …). The custom
|
||
# nixpkgs-config type can't carry a nested mkDefault; disagree with
|
||
# `nixpkgs.config = lib.mkForce { allowUnfree = false; }`.
|
||
nixpkgs.config.allowUnfree = true;
|
||
|
||
# ── Wayland session: Hyprland ────────────────────────────────────
|
||
# Installs the binary, registers the session, wires up
|
||
# xdg-desktop-portal-hyprland. Configuration is Home Manager's job.
|
||
programs.hyprland.enable = lib.mkDefault true;
|
||
|
||
xdg.portal = {
|
||
enable = lib.mkDefault true;
|
||
extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; # file pickers, etc.
|
||
};
|
||
|
||
services.greetd = lib.mkIf cfg.greeter.enable {
|
||
enable = lib.mkDefault true;
|
||
settings = {
|
||
default_session = {
|
||
# start-hyprland is Hyprland 0.55's watchdog launcher; running
|
||
# the bare binary makes every session print a warning.
|
||
command = lib.mkDefault "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd start-hyprland";
|
||
user = "greeter";
|
||
};
|
||
# Boot straight into the session once; logout → normal greeter.
|
||
initial_session = lib.mkIf (cfg.greeter.autoLogin != null) {
|
||
command = "start-hyprland";
|
||
user = cfg.greeter.autoLogin;
|
||
};
|
||
};
|
||
};
|
||
|
||
# ── Audio: Pipewire ──────────────────────────────────────────────
|
||
security.rtkit.enable = lib.mkDefault cfg.audio.enable;
|
||
services.pulseaudio.enable = lib.mkDefault false;
|
||
services.pipewire = lib.mkIf cfg.audio.enable {
|
||
enable = lib.mkDefault true;
|
||
alsa.enable = true;
|
||
alsa.support32Bit = true;
|
||
pulse.enable = true;
|
||
wireplumber.enable = true;
|
||
};
|
||
|
||
# ── Desktop services ─────────────────────────────────────────────
|
||
security.polkit.enable = lib.mkDefault true;
|
||
services.gnome.gnome-keyring.enable = lib.mkDefault true;
|
||
services.dbus.enable = lib.mkDefault true;
|
||
services.upower.enable = lib.mkDefault true;
|
||
networking.networkmanager.enable = lib.mkDefault true;
|
||
|
||
hardware.bluetooth.enable = lib.mkDefault cfg.bluetooth.enable;
|
||
services.blueman.enable = lib.mkDefault cfg.bluetooth.enable;
|
||
|
||
# ── Firmware ─────────────────────────────────────────────────────
|
||
# Blobs for in-kernel drivers: wifi (iwlwifi/ath/rtw/brcm), SOF
|
||
# audio, Bluetooth. Drivers ship with the kernel, but without these
|
||
# a real machine can boot with no wifi — QEMU never catches it.
|
||
# nixos-generate-config also keys CPU microcode off this flag.
|
||
hardware.enableRedistributableFirmware = lib.mkDefault true;
|
||
|
||
# ── BTRFS timeline snapshots (ported from the previous iteration) ─
|
||
# Guarded on the actual filesystem so enabling it on an ext4 machine
|
||
# is a clean no-op rather than a failing timer.
|
||
services.snapper.configs = lib.mkIf
|
||
(cfg.snapper.enable && (config.fileSystems."/".fsType or "") == "btrfs")
|
||
{
|
||
root = {
|
||
SUBVOLUME = "/";
|
||
TIMELINE_CREATE = true;
|
||
TIMELINE_CLEANUP = true;
|
||
TIMELINE_LIMIT_HOURLY = "5";
|
||
TIMELINE_LIMIT_DAILY = "7";
|
||
TIMELINE_LIMIT_WEEKLY = "0";
|
||
TIMELINE_LIMIT_MONTHLY = "0";
|
||
TIMELINE_LIMIT_YEARLY = "0";
|
||
};
|
||
};
|
||
|
||
# ── Fonts ────────────────────────────────────────────────────────
|
||
# The ten most popular Nerd Fonts ship by default, so any of them
|
||
# can be named in the theme state's fonts.mono and actually resolve
|
||
# (nomarchy-theme-sync warns when a configured font is missing).
|
||
fonts = {
|
||
packages = with pkgs; [
|
||
nerd-fonts.jetbrains-mono
|
||
nerd-fonts.fira-code
|
||
nerd-fonts.caskaydia-cove
|
||
nerd-fonts.hack
|
||
nerd-fonts.sauce-code-pro
|
||
nerd-fonts.meslo-lg
|
||
nerd-fonts.roboto-mono
|
||
nerd-fonts.ubuntu-mono
|
||
# iosevka would be next by popularity, but its package is 1.1 GB
|
||
# (every weight × variant) — too heavy for the ISO and closures.
|
||
nerd-fonts.mononoki
|
||
nerd-fonts.inconsolata
|
||
inter
|
||
noto-fonts
|
||
noto-fonts-color-emoji
|
||
];
|
||
fontconfig.defaultFonts = {
|
||
monospace = lib.mkDefault [ "JetBrainsMono Nerd Font" ];
|
||
sansSerif = lib.mkDefault [ "Inter" ];
|
||
emoji = lib.mkDefault [ "Noto Color Emoji" ];
|
||
};
|
||
};
|
||
|
||
# ── Essential packages ───────────────────────────────────────────
|
||
environment.systemPackages = with pkgs; [
|
||
nomarchy-theme-sync # provided by overlays.default
|
||
git
|
||
vim
|
||
wget
|
||
curl
|
||
jq
|
||
brightnessctl
|
||
playerctl
|
||
pamixer
|
||
wl-clipboard
|
||
grim
|
||
slurp
|
||
] ++ lib.optional (cfg.snapper.enable && (config.fileSystems."/".fsType or "") == "btrfs")
|
||
# Snapshot, then rebuild — rollback material for system changes
|
||
# (theme changes don't need it; HM generations already roll back).
|
||
(pkgs.writeShellScriptBin "nixos-rebuild-snap" ''
|
||
if [ "$(id -u)" -ne 0 ]; then
|
||
echo "This script must be run as root (use sudo)" >&2
|
||
exit 1
|
||
fi
|
||
echo "Creating pre-rebuild snapshot..."
|
||
${pkgs.snapper}/bin/snapper -c root create \
|
||
-d "Pre-rebuild $(date +'%Y-%m-%d %H:%M:%S')" \
|
||
--cleanup-algorithm number
|
||
echo "Rebuilding..."
|
||
nixos-rebuild switch --flake /etc/nixos#default "$@"
|
||
'');
|
||
|
||
# ── Nix itself ───────────────────────────────────────────────────
|
||
nix = {
|
||
settings = {
|
||
experimental-features = [ "nix-command" "flakes" ];
|
||
auto-optimise-store = lib.mkDefault true;
|
||
};
|
||
gc = {
|
||
automatic = lib.mkDefault true;
|
||
dates = lib.mkDefault "weekly";
|
||
options = lib.mkDefault "--delete-older-than 14d";
|
||
};
|
||
};
|
||
};
|
||
}
|