initial commit

This commit is contained in:
2026-08-05 18:57:23 +01:00
commit dda5d14d63
51 changed files with 1123 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
.session
Generated
+80
View File
@@ -0,0 +1,80 @@
{
"nodes": {
"flake-file": {
"locked": {
"lastModified": 1785193256,
"narHash": "sha256-KsEoDoDbXp1PJqp2s7U64rfxZ6J5TS9utLNM4r6tEzs=",
"owner": "vic",
"repo": "flake-file",
"rev": "cddd6489b9ef8d20b50a57851763c1931390dc2b",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "flake-file",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"import-tree": {
"locked": {
"lastModified": 1784254960,
"narHash": "sha256-iI88R3wHz8wTKQb5orvpc51L/Xr64AJyxid/0MKa/b8=",
"owner": "vic",
"repo": "import-tree",
"rev": "4ebb10ae17d5f1ad366e7aef5b92cb8eecf24f69",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "import-tree",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1785734586,
"narHash": "sha256-ODZkEK9Gy50yg6h98u7KkitZ3oc/uuTFK00bh1CRdNA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "531670d871c0e29724a02f3cbcac170adc65b58c",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-file": "flake-file",
"flake-parts": "flake-parts",
"import-tree": "import-tree",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
+15
View File
@@ -0,0 +1,15 @@
# DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file.
# Use `nix run .#write-flake` to regenerate it.
{
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);
inputs = {
flake-file.url = "github:vic/flake-file";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
import-tree.url = "github:vic/import-tree";
nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05";
};
}
+19
View File
@@ -0,0 +1,19 @@
{
self,
moduleWithSystem,
...
}: {
flake.nixosModules.bottles = moduleWithSystem ({pkgs, ...}: {
environment.systemPackages = with pkgs; [
(bottles.override {
removeWarningPopup = true;
})
wineWow64Packages.stable
winetricks
wine
wine64
freetype
];
});
}
+23
View File
@@ -0,0 +1,23 @@
{
self,
moduleWithSystem,
...
}: {
flake.nixosModules.development = moduleWithSystem ({pkgs, ...}: let
modules = with self.nixosModules; [
git
nvim
opencode-mcp
bun
ssh-agent
];
in {
imports = modules;
environment.systemPackages = with pkgs; [
opencode
devenv
jellyfin-tui
];
});
}
+14
View File
@@ -0,0 +1,14 @@
{
self,
moduleWithSystem,
...
}: {
flake.nixosModules.gaming = moduleWithSystem ({...}: let
modules = with self.nixosModules; [
steam
];
in {
imports = modules;
});
}
+16
View File
@@ -0,0 +1,16 @@
{ inputs, ... }:
{
imports = [
inputs.flake-file.flakeModules.dendritic
];
flake-file.inputs = {
flake-file.url = "github:vic/flake-file";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
import-tree.url = "github:vic/import-tree";
nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05";
};
}
+8
View File
@@ -0,0 +1,8 @@
{...}: {
# Bun JavaScript runtime / package manager / bundler.
flake.nixosModules.bun = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
bun
];
};
}
+8
View File
@@ -0,0 +1,8 @@
{...}: {
# Discord. Launched as `discord` by the hypr autostart (workspace 8).
flake.nixosModules.discord = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
discord
];
};
}
+12
View File
@@ -0,0 +1,12 @@
{...}: {
# Feishin music client (Jellyfin/Navidrome/Subsonic).
# Note: hypr autostart currently launches this via `flatpak run
# org.jeffvli.feishin` on workspace 9. To use this native package instead,
# change that line to `uwsm app feishin`. The window class is `feishin`,
# which already matches the window-rule in window-rules.lua.
flake.nixosModules.feishin = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
feishin
];
};
}
+9
View File
@@ -0,0 +1,9 @@
{...}: {
# Package only. Config is managed via stow (dotfiles: no dedicated fuzzel
# package yet; fuzzel uses its defaults / ~/.config/fuzzel if present).
flake.nixosModules.fuzzel = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
fuzzel
];
};
}
+9
View File
@@ -0,0 +1,9 @@
{...}: {
# Package only. Config is managed via stow (dotfiles: ghostty package).
flake.nixosModules.ghostty = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
ghostty
];
ahmza.stow.packages = ["ghostty"];
};
}
+14
View File
@@ -0,0 +1,14 @@
{...}: {
# git user config (~/.config/git or ~/.gitconfig) is managed via stow.
# We only install git + related tooling and enable the gpg agent.
flake.nixosModules.git = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
git
git-secret
];
programs.gnupg.agent = {
enable = true;
pinentryPackage = pkgs.pinentry-all;
};
};
}
+58
View File
@@ -0,0 +1,58 @@
{self, ...}: {
# Hyprland desktop. The compositor config itself (hyprland.lua + ahmza/*.lua,
# hyprlock, hypridle, hyprsunset) is managed via stow (dotfiles: hypr package).
# Here we enable Hyprland and install the runtime tools that config + the
# helper scripts in the `bin` package expect on PATH.
flake.nixosModules.hyprland = {pkgs, ...}: let
modules = with self.nixosModules; [
audio
systemTheme
fuzzel
ghostty
waybar
];
in {
imports = modules;
programs.hyprland = {
enable = true;
withUWSM = true;
};
# hypr = compositor config, dunst = notifications, wal = pywal templates,
# bin = helper scripts (swp/launch-waybar/passmenu) referenced by keybinds.
ahmza.stow.packages = ["hypr" "dunst" "wal" "bin"];
services.displayManager.defaultSession = "hyprland-uwsm";
services.xserver.enable = true;
security.polkit.enable = true;
environment.systemPackages = with pkgs; [
# hypr* ecosystem (keybinds / hypridle / autostart)
hyprlock
hypridle
hyprsunset
hyprpicker
# launcher / file manager / browser (vars.lua: Picker/FileManager/Browser)
kdePackages.dolphin
firefox
# wallpaper daemon used by the `swp` script + autostart (awww-daemon)
awww
# scripting deps for bin/ helpers (swp uses jq + hyprctl)
jq
# display / applets referenced by autostart
xorg.xrandr
networkmanagerapplet
blueman
udiskie
brightnessctl
# clipboard
wl-clipboard
cliphist
# theming
gsettings-desktop-schemas
dunst
pywal16
];
};
}
+8
View File
@@ -0,0 +1,8 @@
{...}: {
# lazygit config is managed via stow. Package only.
flake.nixosModules.lazygit = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
lazygit
];
};
}
+15
View File
@@ -0,0 +1,15 @@
{...}: {
flake.nixosModules.nvim = {pkgs, ...}: {
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
ahmza.stow.packages = ["nvim"];
environment.systemPackages = with pkgs; [
# TODO: re-add your custom neovim config/distribution here later.
];
};
}
+11
View File
@@ -0,0 +1,11 @@
{...}: {
# Obsidian notes app.
# Note: hypr autostart currently launches this via `flatpak run
# mc.obsidian.Obsidian` on workspace 4. To use this native package instead,
# change that line to `uwsm app obsidian`.
flake.nixosModules.obsidian = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
obsidian
];
};
}
+44
View File
@@ -0,0 +1,44 @@
{...}: {
# opencode MCP servers, installed declaratively instead of via the dotfiles
# `install` script (which downloads prebuilt binaries into ~/.local/bin).
# - gitea-mcp : packaged in nixpkgs as gitea-mcp-server (binary: gitea-mcp)
# - engram : not in nixpkgs, built here from source with buildGoModule
# Both are referenced by bare command name in opencode.jsonc, so they resolve
# from PATH.
flake.nixosModules.opencode-mcp = {pkgs, ...}: let
engram = pkgs.buildGoModule rec {
pname = "engram";
version = "1.20.0";
src = pkgs.fetchFromGitHub {
owner = "Gentleman-Programming";
repo = "engram";
rev = "v${version}";
hash = "sha256-qdKAll7N0HtJRbZYilzatVCUz1Tr+pqM217Y8O+Csjs=";
};
vendorHash = "sha256-O+pC4x4DKNUWr7Sx9iZOjK6a64wrQA4/lnjvkNLBX64=";
subPackages = ["cmd/engram"];
# Inject the version (upstream sets main.version via goreleaser ldflags).
ldflags = ["-s" "-w" "-X" "main.version=${version}"];
# Upstream tests bind network ports (autosync), which fails in the Nix
# build sandbox. The binary itself builds fine.
doCheck = false;
meta = with pkgs.lib; {
description = "Persistent memory MCP server for coding agents";
homepage = "https://github.com/Gentleman-Programming/engram";
license = licenses.mit;
mainProgram = "engram";
};
};
in {
environment.systemPackages = [
pkgs.gitea-mcp-server # provides the `gitea-mcp` binary
engram
];
};
}
+9
View File
@@ -0,0 +1,9 @@
{...}: {
# TODO: quickshell config (shell.qml etc.) previously came from a dedicated flake input
# and was built via the wrappers flake. Re-add your quickshell config later.
flake.nixosModules.quickshell = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
quickshell
];
};
}
+9
View File
@@ -0,0 +1,9 @@
{...}: {
flake.nixosModules.sddm-autologin = {...}: {
services.displayManager = {
autoLogin.enable = true;
autoLogin.user = "ahmza";
};
};
}
+26
View File
@@ -0,0 +1,26 @@
{
self,
inputs,
...
}: {
flake.nixosModules.sddm = {
pkgs,
lib,
...
}: {
environment.systemPackages = [
(pkgs.catppuccin-sddm.override {
flavor = "mocha";
font = "JetBrainsMono Nerd Font";
fontSize = "11";
background = null;
})
];
services.displayManager.sddm = {
enable = true;
theme = "catppuccin-mocha-mauve";
package = pkgs.kdePackages.sddm;
};
};
}
+17
View File
@@ -0,0 +1,17 @@
{...}: {
# System-managed ssh-agent. Enabling startAgent runs an ssh-agent per user
# session and exports SSH_AUTH_SOCK automatically, so the dotfiles zsh
# `ssh-agent` bootstrap finds a reachable agent (its Linux fallback hardcodes
# /usr/bin/ssh-agent, which does not exist on NixOS).
flake.nixosModules.ssh-agent = {pkgs, ...}: {
programs.ssh = {
startAgent = true;
# ed25519-sk / passphrase prompts route through this pinentry.
enableAskPassword = true;
};
environment.systemPackages = with pkgs; [
openssh # provides ssh-add / ssh-agent on PATH
];
};
}
+12
View File
@@ -0,0 +1,12 @@
{...}: {
# TODO: previously injected SLSsteam via LD_AUDIT from the sls-steam flake. Now stock.
flake.nixosModules.steam = {pkgs, ...}: {
programs.steam = {
enable = true;
protontricks.enable = true;
extraCompatPackages = with pkgs; [
proton-ge-bin
];
};
};
}
+14
View File
@@ -0,0 +1,14 @@
{...}: {
# Package only. Config is managed via stow (dotfiles: waybar package).
flake.nixosModules.waybar = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
waybar
# waybar config on-click / modules deps:
mpc # mpd module: "mpc toggle/random"
# nm-connection-editor comes from networkmanagerapplet (hyprland module);
# pavucontrol comes from the audio module.
inotify-tools
];
ahmza.stow.packages = ["waybar"];
};
}
+9
View File
@@ -0,0 +1,9 @@
{...}: {
flake.nixosModules.weylus = {pkgs, ...}: {
programs.weylus = {
enable = true;
package = pkgs.weylus;
users = ["ahmza"];
};
};
}
+24
View File
@@ -0,0 +1,24 @@
{...}: {
# zsh runtime config (.zshrc, plugins, aliases, prompt) is managed via stow
# (dotfiles: zsh + shell + starship packages). We only enable zsh at the system
# level and install the tools the dotfiles expect on PATH.
flake.nixosModules.zsh = {pkgs, ...}: {
programs.zsh.enable = true;
users.defaultUserShell = pkgs.zsh;
ahmza.stow.packages = ["zsh" "shell" "starship"];
environment.systemPackages = with pkgs; [
starship
fzf
ripgrep
fd
lsd
lolcat
zoxide
bat
lazygit
carapace
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
self,
inputs,
...
}: {
flake.nixosConfigurations.t480 = inputs.nixpkgs.lib.nixosSystem {
modules = with self.nixosModules; [
desktop
t480Configuration
# CPU microcode + integrated Intel GPU. The T480 also has an NVIDIA MX150;
# to enable it in PRIME offload mode, swap gpuIntel for gpuNvidiaPrime
# (which includes gpuIntel). Left on Intel-only by default to save power.
cpuIntel
gpuIntel
development
feishin
obsidian
discord
gaming
];
};
}
+12
View File
@@ -0,0 +1,12 @@
{
self,
inputs,
...
}: {
flake.nixosModules.t480Configuration = {...}: {
networking = {
hostName = "t480";
};
};
}
+10
View File
@@ -0,0 +1,10 @@
{
config = {
systems = [
"x86_64-linux"
"x86_64-darwin"
"aarch64-linux"
"aarch64-darwin"
];
};
}
+22
View File
@@ -0,0 +1,22 @@
{...}: {
# PipeWire-based audio. wpctl (used by the Hyprland media keybinds) is provided
# by wireplumber, which PipeWire enables by default.
flake.nixosModules.audio = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
playerctl # media keys (hypr keybinds)
pavucontrol # GUI mixer (waybar pulseaudio on-click)
];
# PipeWire replaces the PulseAudio server; don't run the standalone daemon.
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
jack.enable = true;
};
};
}
+31
View File
@@ -0,0 +1,31 @@
{...}: {
flake.nixosModules.bootloader = {
pkgs,
lib,
...
}: {
boot = {
loader = {
timeout = 2;
efi = {
canTouchEfiVariables = true;
};
grub = {
efiSupport = true;
device = "nodev";
theme = pkgs.catppuccin-grub;
};
};
plymouth = {
enable = true;
theme = "catppuccin-mocha";
themePackages = with pkgs; [
(catppuccin-plymouth.override {
variant = "mocha";
})
];
};
kernelPackages = pkgs.linuxPackages_latest;
};
};
}
+43
View File
@@ -0,0 +1,43 @@
{
self,
inputs,
...
}: {
flake.nixosModules.core = {
pkgs,
lib,
...
}: let
modules = with self.nixosModules; [
user
bootloader
nix
hardware
locale
nix-ld
];
in {
imports =
[
/etc/nixos/hardware-configuration.nix
]
++ modules;
services = {
openssh.enable = true;
avahi.enable = true;
};
environment.systemPackages = with pkgs; [
# neovim is provided by the nvim feature module (programs.neovim.enable).
unzip
p7zip-rar
usbutils
lsof
gvfs
libnotify
python313
curlWithGnuTls
wget
];
system.stateVersion = "26.05";
};
}
+11
View File
@@ -0,0 +1,11 @@
{...}: {
flake.nixosModules.hardware = {...}: {
hardware = {
bluetooth = {
enable = true;
powerOnBoot = true;
};
xpadneo.enable = true;
};
};
}
+32
View File
@@ -0,0 +1,32 @@
{
self,
inputs,
...
}: {
flake.nixosModules.locale = {
pkgs,
lib,
...
}: {
time.timeZone = "Europe/London";
i18n = {
defaultLocale = "en_GB.UTF-8";
extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
};
services.xserver.xkb = {
layout = "gb";
variant = "";
};
console.keyMap = "uk";
};
}
+23
View File
@@ -0,0 +1,23 @@
{inputs, ...}: {
flake.nixosModules.nix = {...}: {
nix = {
settings = {
cores = 6;
trusted-users = ["root" "ahmza"];
download-buffer-size = 524288000;
experimental-features = [
"nix-command"
"flakes"
];
};
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
optimise.automatic = true;
gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 5d";
};
};
nixpkgs.config.allowUnfree = true;
};
}
+30
View File
@@ -0,0 +1,30 @@
{self, ...}: {
flake.nixosModules.user = {
pkgs,
...
}: let
modules = with self.nixosModules; [
zsh
stow
];
in {
imports = modules;
ahmza.stow = {
enable = true;
user = "ahmza";
# repoPath defaults to /home/ahmza/dot
};
users.users.ahmza = {
isNormalUser = true;
initialPassword = "qwer";
shell = pkgs.zsh;
description = "ahmza";
extraGroups = [
"networkmanager"
"wheel"
];
};
};
}
+20
View File
@@ -0,0 +1,20 @@
{
self,
moduleWithSystem,
...
}: {
flake.nixosModules.desktop = moduleWithSystem ({pkgs, ...}: let
modules = with self.nixosModules; [
core
hyprland
sddm
network
];
in {
imports = modules;
environment.systemPackages = with pkgs; [
mpv
];
});
}
+7
View File
@@ -0,0 +1,7 @@
{...}: {
# AMD CPU: microcode updates (applied via initrd at boot).
flake.nixosModules.cpuAmd = {...}: {
hardware.cpu.amd.updateMicrocode = true;
hardware.enableRedistributableFirmware = true;
};
}
+7
View File
@@ -0,0 +1,7 @@
{...}: {
# Intel CPU: microcode updates (applied via initrd at boot).
flake.nixosModules.cpuIntel = {...}: {
hardware.cpu.intel.updateMicrocode = true;
hardware.enableRedistributableFirmware = true;
};
}
+20
View File
@@ -0,0 +1,20 @@
{...}: {
# AMD GPU (mesa + RADV/ROCm).
flake.nixosModules.gpuAmd = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
mesa
vulkan-tools
rocmPackages.rocm-smi
rocmPackages.rocminfo
];
hardware.graphics = {
enable = true;
enable32Bit = true;
extraPackages = with pkgs; [
libva-vdpau-driver
libvdpau-va-gl
rocmPackages.clr.icd
];
};
};
}
+18
View File
@@ -0,0 +1,18 @@
{...}: {
# Intel integrated GPU (mesa + VA-API hardware video acceleration).
flake.nixosModules.gpuIntel = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
mesa
vulkan-tools
];
hardware.graphics = {
enable = true;
enable32Bit = true;
extraPackages = with pkgs; [
intel-media-driver # modern iHD driver (Broadwell+)
intel-vaapi-driver # legacy i965 driver
libva-vdpau-driver
];
};
};
}
@@ -0,0 +1,41 @@
{self, ...}: {
# Hybrid Intel + NVIDIA (PRIME) for laptops like the T480 (Intel UHD 620 +
# NVIDIA MX150). Uses "offload" mode: the dGPU stays powered down by default
# (minimal extra battery drain) and is only used for apps launched with
# `nvidia-offload <cmd>`. It also pulls in the Intel GPU stack (gpuIntel).
#
# Bus IDs below are specific to the T480 (from `lspci`):
# Intel 00:02.0 -> PCI:0:2:0
# NVIDIA 01:00.0 -> PCI:1:0:0
# Adjust for other machines.
flake.nixosModules.gpuNvidiaPrime = {
config,
pkgs,
...
}: {
imports = [self.nixosModules.gpuIntel];
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia = {
modesetting.enable = true;
# MX150 is Pascal (pre-Turing); the proprietary modules are the safe choice.
open = false;
nvidiaSettings = true;
powerManagement.enable = true;
prime = {
# Offload keeps the NVIDIA GPU asleep until explicitly used. This gives
# the `nvidia-offload` helper wrapper. Swap to sync mode if you want the
# dGPU always driving the display (higher power draw).
offload = {
enable = true;
enableOffloadCmd = true; # provides `nvidia-offload` wrapper
};
intelBusId = "PCI:0:2:0";
nvidiaBusId = "PCI:1:0:0";
};
};
};
}
+31
View File
@@ -0,0 +1,31 @@
{...}: {
# Dedicated NVIDIA GPU (single discrete card, no hybrid/PRIME).
# For Intel+NVIDIA laptops (e.g. the T480), use gpuNvidiaPrime instead.
flake.nixosModules.gpuNvidia = {
config,
pkgs,
...
}: {
services.xserver.videoDrivers = ["nvidia"];
hardware.graphics = {
enable = true;
enable32Bit = true;
};
hardware.nvidia = {
modesetting.enable = true;
# Proprietary kernel modules. Set to true only for Turing+ (RTX 20xx and
# newer) where the open modules are well supported.
open = false;
nvidiaSettings = true;
# Fixes suspend/resume corruption on many setups.
powerManagement.enable = true;
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
environment.systemPackages = with pkgs; [
vulkan-tools
];
};
}
+13
View File
@@ -0,0 +1,13 @@
{...}: {
flake.nixosModules.network = {...}: {
networking = {
networkmanager.enable = true;
# Firewall intentionally disabled (trusted LAN; local services like
# weylus / remote play need open ports).
firewall.enable = false;
};
# Don't block boot waiting for a network connection.
systemd.services.NetworkManager-wait-online.enable = false;
};
}
+16
View File
@@ -0,0 +1,16 @@
{moduleWithSystem, ...}: {
flake.nixosModules.nix-ld = moduleWithSystem ({pkgs, ...}: {
programs = {
nix-ld = {
enable = true;
libraries = with pkgs; [
util-linux
stdenv.cc.cc
zlib
libusb1
];
};
};
});
}
+115
View File
@@ -0,0 +1,115 @@
{...}: {
flake.nixosModules.stow = {
config,
pkgs,
lib,
...
}: let
cfg = config.ahmza.stow;
stowScript = pkgs.writeShellApplication {
name = "ahmza-stow";
runtimeInputs = [pkgs.stow pkgs.coreutils pkgs.findutils pkgs.gnused];
text = ''
set -euo pipefail
REPO="${cfg.repoPath}"
TARGET="$HOME"
if [ ! -d "$REPO" ]; then
echo "ahmza-stow: dotfiles repo not found at $REPO; skipping." >&2
echo " (clone it with: git clone ${cfg.repoUrl} $REPO)" >&2
exit 0
fi
packages=(${lib.escapeShellArgs cfg.packages})
if [ ''${#packages[@]} -eq 0 ]; then
echo "ahmza-stow: no packages configured; nothing to do."
exit 0
fi
cd "$REPO"
# Back up any existing non-symlink targets that would block stowing $pkg.
# Mirrors the dotfiles repo's own install script: list the files/links the
# package provides (relative to the package dir) and back up only real
# (non-symlink) targets. Skipping symlinks means we never write through an
# already-stowed folded directory symlink into the repo itself.
# Backups go to <file>.pre-stow.bak.
backup_conflicts() {
local pkg="$1" rel target
while IFS= read -r rel; do
target="$HOME/$rel"
if [ -e "$target" ] && [ ! -L "$target" ]; then
echo "ahmza-stow: backing up existing $target -> $target.pre-stow.bak"
mv "$target" "$target.pre-stow.bak"
fi
done < <(cd "$REPO/$pkg" && find . \( -type f -o -type l \) | sed 's|^\./||')
}
for pkg in "''${packages[@]}"; do
if [ ! -d "$pkg" ]; then
echo "ahmza-stow: package '$pkg' not present in repo; skipping." >&2
continue
fi
echo "ahmza-stow: stow -R $pkg"
# Try to stow first; only back up (and retry) if there's a real conflict.
if ! stow -R --target="$TARGET" "$pkg" 2>/dev/null; then
echo "ahmza-stow: conflicts detected for '$pkg'; backing up and retrying."
backup_conflicts "$pkg"
if ! stow -R --target="$TARGET" "$pkg"; then
echo "ahmza-stow: failed to stow '$pkg' — resolve manually." >&2
fi
fi
done
echo "ahmza-stow: done."
'';
};
in {
options.ahmza.stow = {
enable = lib.mkEnableOption "automatic GNU Stow of dotfiles on login";
user = lib.mkOption {
type = lib.types.str;
description = "User whose dotfiles should be stowed.";
};
repoPath = lib.mkOption {
type = lib.types.str;
default = "/home/${cfg.user}/dot";
defaultText = "/home/\${config.ahmza.stow.user}/dot";
description = "Absolute path to the stow dotfiles repository.";
};
repoUrl = lib.mkOption {
type = lib.types.str;
default = "https://github.com/ahmzaa/dot.git";
description = "URL of the dotfiles repo (used only in help messages).";
};
packages = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = ''
Stow package names (top-level dirs in the dotfiles repo) to link.
Feature modules append to this via lib.mkAfter / list concatenation.
'';
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [pkgs.stow stowScript];
systemd.user.services.ahmza-stow = {
description = "Stow dotfiles for ${cfg.user}";
wantedBy = ["default.target"];
serviceConfig = {
Type = "oneshot";
ExecStart = lib.getExe stowScript;
};
};
};
};
}
+25
View File
@@ -0,0 +1,25 @@
{...}: {
flake.nixosModules.bibataCursors = {pkgs, ...}: {
environment.systemPackages = with pkgs; [
bibata-cursors
];
environment.variables = {
XCURSOR_THEME = "Bibata-Modern-Ice";
XCURSOR_SIZE = "20";
};
programs.dconf.profiles.user.databases = [
{
lockAll = false;
settings = {
"org/gnome/desktop/interface" = {
cursor-theme = "Bibata-Modern-Ice";
font-name = "JetBrainsMono Nerd Font 11";
};
};
}
];
};
}
+21
View File
@@ -0,0 +1,21 @@
{
self,
inputs,
...
}: {
flake.nixosModules.systemTheme = {
config,
pkgs,
lib,
...
}: let
modules = with self.nixosModules; [
bibataCursors
catppuccinGtk
fonts
];
in {
imports = modules;
};
}
+23
View File
@@ -0,0 +1,23 @@
{...}: {
# System-wide fonts. Standardized on JetBrainsMono Nerd Font everywhere
# (terminal, sddm, gtk/dconf, waybar, etc.).
flake.nixosModules.fonts = {pkgs, ...}: {
fonts = {
packages = with pkgs; [
nerd-fonts.jetbrains-mono
# Fallbacks for emoji / CJK / general coverage.
noto-fonts
noto-fonts-color-emoji
];
enableDefaultPackages = true;
fontconfig.defaultFonts = {
monospace = ["JetBrainsMono Nerd Font"];
sansSerif = ["JetBrainsMono Nerd Font"];
serif = ["JetBrainsMono Nerd Font"];
emoji = ["Noto Color Emoji"];
};
};
};
}
+44
View File
@@ -0,0 +1,44 @@
{
self,
inputs,
...
}: {
flake.nixosModules.catppuccinGtk = {
pkgs,
lib,
...
}: let
in {
environment.systemPackages = with pkgs; [
(catppuccin-gtk.override {
variant = "mocha";
accents = ["mauve"];
tweaks = ["rimless"];
size = "compact";
})
(catppuccin-papirus-folders.override {
flavor = "mocha";
accent = "mauve";
})
];
programs = {
xfconf.enable = true;
dconf = {
enable = true;
profiles.user.databases = [
{
lockAll = false;
settings = {
"org/gnome/desktop/interface" = {
gtk-theme = "catppuccin-mocha-mauve-compact+rimless";
icon-theme = "Papirus";
color-scheme = "prefer-dark";
};
};
}
];
};
};
};
}
Symlink
+1
View File
@@ -0,0 +1 @@
/nix/store/dgd4pa9cl1n266zsbf8xi277p304zxcw-nixos-system-t480-26.05.20260803.531670d