# 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 = { # ── 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 = { command = lib.mkDefault "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd Hyprland"; user = "greeter"; }; # Boot straight into the session once; logout → normal greeter. initial_session = lib.mkIf (cfg.greeter.autoLogin != null) { command = "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; # ── 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 ──────────────────────────────────────────────────────── fonts = { packages = with pkgs; [ nerd-fonts.jetbrains-mono 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"; }; }; }; }