Compare commits

..
Author SHA1 Message Date
aaron 95fe2dbc97 chore(flake): update flake file 2026-07-12 14:34:20 +02:00
64 changed files with 791 additions and 1785 deletions
-2
View File
@@ -1,2 +0,0 @@
# nixfmt reformat
2231d2fc3fb4dc140c5f3257523dcdb513ac4dea
-4
View File
@@ -8,7 +8,3 @@ result-*
# vim
*.swp
# devenv
.devenv*
devenv.local.nix
+11 -110
View File
@@ -2,13 +2,8 @@
- The installations presented in this repository are always luks encrypted
- For simplicity I'm using device labels rather than uuids
- Secure Boot has to be disabled in the firmware, the installer iso isn't signed
1. create the partitions with `cfdisk` or `fdisk` (gpt)
- `nvme0n1p1`: 2G, type `EFI System`, otherwise the firmware won't find the bootloader
- `nvme0n1p2`: the rest, type `Linux filesystem`
the layout should look somewhat like this after the installation
1. the partitioning layout should look somewhat like this after the installation
```bash
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 476.9G 0 disk
@@ -35,13 +30,12 @@ cryptsetup luksOpen /dev/nvme0n1p2 cryptroot
pvcreate /dev/mapper/cryptroot
# create a volume group inside
vgcreate lvmroot /dev/mapper/cryptroot
# create the swap volume, half the ram (no hibernation)
lvcreate --size 16G lvmroot --name swap
# create the swap volume
lvcreate --size 8G lvmroot --name swap
# if you desire, create a home volume
lvcreate --size 150G lvmroot --name home
# create the root volume, leave some space in the vg to grow volumes later
# (lvextend -r -L +50G lvmroot/home works while mounted)
lvcreate -l 90%FREE lvmroot --name root
# create the root volume
lvcreate -l 100%FREE lvmroot --name root
# format as usual for root partition
mkfs.ext4 -L "nixroot" /dev/mapper/lvmroot-root
@@ -53,7 +47,7 @@ mkswap -L "nixswap" /dev/mapper/lvmroot-swap
# mount root
mount /dev/disk/by-label/nixroot /mnt
# mount boot
mount --mkdir /dev/disk/by-label/nixboot /mnt/boot
mount --mkdir /dev/nvme0n1p1 /mnt/boot
# again, if you did the home volume
mount --mkdir /dev/disk/by-label/nixhome /mnt/home
# turn on swap
@@ -65,7 +59,8 @@ swapon /dev/disk/by-label/nixswap
# generate templates and update the hardware-configuration.nix
nixos-generate-config --root /mnt
# no extra kernelModules needed, luks and lvm load dm_crypt and dm_mod themselves
# add dm-crypt and dm-mod to the kernelModules
boot.initrd.kernelModules = [ "dm-crypt" "dm-mod" ];
# add file systems using labels
fileSystems."/" =
@@ -75,7 +70,7 @@ fileSystems."/" =
fileSystems."/boot" =
{ device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ]; # only root may read /boot
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-label/nixhome";
@@ -86,13 +81,7 @@ swapDevices =
];
# point the bootloader to the luks device
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-label/nixcrypt";
# without this fstrim never reaches the ssd
allowDiscards = true;
# lower latency on nvme
bypassWorkqueues = true;
};
boot.initrd.luks.devices."cryptroot".device = "/dev/disk/by-label/nixcrypt";
```
4. install nixos
@@ -102,96 +91,8 @@ nixos-install
## how to deploy the initial config
- Don't forget to install the bootloader, if you changed it since `nixos-install`
- The fresh install has no flakes and no git yet, a temporary shell is enough
- If the installer iso is older than the flake's nixpkgs, `--no-reexec` keeps
`nixos-rebuild` from re-executing a newer version of itself, which can fail
against the older systemd of the fresh install (only needed once)
- Set a password for the user before rebooting, `users.nix` doesn't set one
```bash
$ export NIX_CONFIG="experimental-features = nix-command flakes"
$ nix-shell -p git
$ sudo nixos-rebuild --install-bootloader boot --flake .#host_name --no-reexec
$ sudo passwd aaron
```
## how to enable secure boot
Secure Boot uses lanzaboote with our own keys, see `modules/nixos/lanzaboote.nix`.
Do this after the initial config is deployed and boots.
1. create the keys, before the first rebuild with the lanzaboote module
```bash
# the keys end up in /var/lib/sbctl, they never leave the host
$ sudo nix run nixpkgs#sbctl -- create-keys
```
2. import `modules/nixos/lanzaboote.nix` in the host's `configuration.nix`, rebuild and check the signatures
```bash
$ sudo nixos-rebuild switch --flake .#host_name
# EFI/Linux/*.efi and the bootloader must be signed, kernels in EFI/nixos
# are not, lanzaboote checks them by hash
$ sudo sbctl verify
```
3. reboot once with Secure Boot still disabled, to make sure the new entries boot
4. in the firmware (F2), erase all Secure Boot keys, then boot nixos again
```bash
# "Setup Mode: ✗ Enabled", the ✗ only means the state is insecure
$ sudo sbctl status
```
5. enroll the keys
```bash
# only our own keys, no microsoft keys
$ sudo sbctl enroll-keys
```
- sbctl refuses if the TPM eventlog shows option ROMs (e.g. a dedicated gpu).
Don't force it, either trust exactly those with `--tpm-eventlog` or
microsoft's keys with `--microsoft`. Without either, the firmware may not
start the device, in the worst case the machine doesn't boot at all.
- Check what sbctl found first, a real option ROM has a PCI device path:
```bash
$ sudo nix shell nixpkgs#tpm2-tools -c tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements | grep -A14 "EV_EFI_BOOT_SERVICES_DRIVER"
```
- Paths starting with `0407` (firmware volume) are drivers from the firmware
itself, not option ROMs (e.g. on the ThinkPad). `--tpm-eventlog` trusts
exactly those, after a firmware update they may need to be enrolled again
(disable Secure Boot, `sbctl enroll-keys --tpm-eventlog`)
- Without an integrated gpu (argon), the gpu's option ROM draws the firmware
setup too, use `--microsoft` there, a refused gpu means no picture at all
- On the Framework (krypton), keep the firmware's built-in OEM certificates
with `--firmware-builtin`, vendor firmware updates may need them. If an
update fails or the keys were enrolled without them, erase the keys in the
firmware again (Setup Mode) and re-enroll:
```bash
$ sudo sbctl enroll-keys --firmware-builtin
```
6. enable Secure Boot in the firmware and set a firmware password, then check
```bash
$ bootctl status | grep "Secure Boot" # enabled (user)
$ sudo sbctl status # Secure Boot: ✓ Enabled
```
- If it doesn't boot anymore, disabling Secure Boot in the firmware boots as before
- Losing the keys isn't fatal: erase the keys in the firmware and start over at step 1
## how to unlock the disk with the tpm (laptops)
Needs Secure Boot first. The TPM releases the key only with the PIN and while
the Secure Boot state (PCR 7) is unchanged. The passphrase stays as fallback.
1. enroll the TPM with a PIN as an additional key slot
```bash
# asks for the current passphrase, then the new PIN
$ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 --tpm2-with-pin=yes /dev/disk/by-label/nixcrypt
```
2. import `modules/nixos/tpm-unlock.nix` in the host's `configuration.nix`, rebuild and reboot
- If the passphrase is suddenly asked for instead of the PIN, the Secure Boot
state changed. After a firmware update that's expected, otherwise investigate
before typing the passphrase. To re-enroll:
```bash
$ sudo systemd-cryptenroll --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7 --tpm2-with-pin=yes /dev/disk/by-label/nixcrypt
$ sudo nixos-rebuild --install-bootloader switch --flake .#host_name
```
## how to upgrade the system
+10 -10
View File
@@ -6,20 +6,20 @@ My personal NixOS configurations.
```bash
.
├── flake.nix # hosts and home-manager wiring
├── flake.lock
├── flake.nix # flake definition
├── hosts
│ ├── argon # desktop
│ ├── neon # laptop
│ └── krypton # second laptop
│ ├── configuration.nix # host-specific settings and module imports
│ ├── hardware-configuration.nix # generated by nixos-generate-config
│ └── niri.nix # host-specific niri settings (outputs, input)
│   └── neon
│   ├── configuration.nix # import nix-modules for specific host
│   └── hardware-configuration.nix # hardware configs for specific host
├── modules
│ ├── home-manager # user modules, imported by users/aaron/home.nix
│ └── nixos # system modules, imported by the hosts
│   ├── home-manager
│   │   ├── xyz_module.nix
│   └── nixos
│   └── xyz_module.nix
└── users
└── aaron
└── home.nix # imports home-manager modules
└── home.nix # import home-manager modules for specific user
```
## installation
-65
View File
@@ -1,65 +0,0 @@
{
"nodes": {
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1790701375,
"narHash": "sha256-0FpLHIRDYiyo3EMTnMQSobZQknZaa3JuWo6vmMCK76o=",
"owner": "cachix",
"repo": "devenv",
"rev": "fe20b5cba7ab5e93ae73f956a8d3efc50e1753f4",
"type": "github"
},
"original": {
"dir": "src/modules",
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"nixpkgs": {
"inputs": {
"nixpkgs-src": "nixpkgs-src"
},
"locked": {
"lastModified": 1789506231,
"narHash": "sha256-vNkJbtmqyBfFhn/HnzQo4ROuoyYWuy/allqTfJb4kMY=",
"owner": "cachix",
"repo": "devenv-nixpkgs",
"rev": "c2f38fe7f9e04d9aadd354d380f2bd40531d9737",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "rolling",
"repo": "devenv-nixpkgs",
"type": "github"
}
},
"nixpkgs-src": {
"flake": false,
"locked": {
"lastModified": 1789370336,
"narHash": "sha256-6RSEDHIWQtesQKWSu5qRai8L2h4KgCgMEfJHstW99G4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c7def046b9a883d46974757852106483d741586f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
-29
View File
@@ -1,29 +0,0 @@
{ pkgs, ... }:
{
packages = with pkgs; [
# gitea (git.0x29a.ch)
tea
# nix tooling
nixfmt # official formatter (RFC 166 style)
statix # lints for nix anti-patterns
deadnix # finds unused bindings and arguments
nixd # language server
nvd # diff system generations
];
scripts = {
lint.exec = ''
set -e
statix check .
deadnix --fail --exclude hosts/*/hardware-configuration.nix -- .
'';
fmt.exec = ''
nixfmt $(git ls-files '*.nix')
'';
};
enterShell = ''
echo "nixconfig devenv: tea, lint, fmt"
'';
}
-3
View File
@@ -1,3 +0,0 @@
inputs:
nixpkgs:
url: github:cachix/devenv-nixpkgs/rolling
Generated
+13 -413
View File
@@ -1,120 +1,5 @@
{
"nodes": {
"base16": {
"inputs": {
"fromYaml": "fromYaml"
},
"locked": {
"lastModified": 1755819240,
"narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=",
"owner": "SenchoPens",
"repo": "base16.nix",
"rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "base16.nix",
"type": "github"
}
},
"base16-fish": {
"flake": false,
"locked": {
"lastModified": 1765809053,
"narHash": "sha256-XCUQLoLfBJ8saWms2HCIj4NEN+xNsWBlU1NrEPcQG4s=",
"owner": "tomyun",
"repo": "base16-fish",
"rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
"type": "github"
},
"original": {
"owner": "tomyun",
"repo": "base16-fish",
"rev": "86cbea4dca62e08fb7fd83a70e96472f92574782",
"type": "github"
}
},
"base16-helix": {
"flake": false,
"locked": {
"lastModified": 1776754714,
"narHash": "sha256-E3OAK27smtATTmX45uoTSRsVD+Y+ZiVVfgM/tjpbtYg=",
"owner": "tinted-theming",
"repo": "base16-helix",
"rev": "4d508123037e7851ad36ebf7d9c48b0e9e1eb581",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-helix",
"type": "github"
}
},
"base16-vim": {
"flake": false,
"locked": {
"lastModified": 1732806396,
"narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=",
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-vim",
"rev": "577fe8125d74ff456cf942c733a85d769afe58b7",
"type": "github"
}
},
"crane": {
"locked": {
"lastModified": 1789760033,
"narHash": "sha256-jtT4yxZpR8seYnlCMMWSSPlFN92zO6ICuZ8pJrmi86k=",
"owner": "ipetkov",
"repo": "crane",
"rev": "73b980519cefc727a5f6cc8e5c0947a2f9be6edd",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1783570805,
"narHash": "sha256-ptl5aRlCv9/uRSv2u8Hq8UFVFeZ6Q/bT049bpqNgc3w=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "5602ed62d638142c1ab31dccd01dfbfb28841225",
"type": "github"
},
"original": {
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
@@ -122,27 +7,6 @@
"nixpkgs"
]
},
"locked": {
"lastModified": 1790898470,
"narHash": "sha256-zTwuwezD0w3hpga6a6P8emidzAZFyWqlNeRBlpWOOl8=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "024633cd702b10285db5cb19b40ad48d2399ba60",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"stylix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
@@ -157,41 +21,6 @@
"type": "github"
}
},
"fromYaml": {
"flake": false,
"locked": {
"lastModified": 1731966426,
"narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=",
"owner": "SenchoPens",
"repo": "fromYaml",
"rev": "106af9e2f715e2d828df706c386a685698f3223b",
"type": "github"
},
"original": {
"owner": "SenchoPens",
"repo": "fromYaml",
"type": "github"
}
},
"gnome-shell": {
"flake": false,
"locked": {
"host": "gitlab.gnome.org",
"lastModified": 1776175984,
"narHash": "sha256-RJFlFW8GiMei6oqUGrMkGEvVqOH8U7Q8abc1yK4VKD8=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "e0fdc4c13250e9a9b8ea9594c83925274f4a5dca",
"type": "gitlab"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "50.1",
"repo": "gnome-shell",
"type": "gitlab"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -199,11 +28,11 @@
]
},
"locked": {
"lastModified": 1791293500,
"narHash": "sha256-3hwJd2/vG/VYV1P/g7oDgdbNsWODhN5F//Od+hPMm2k=",
"lastModified": 1783823409,
"narHash": "sha256-OI4IkRjRXa1e7hYmCGJDPDq5H/kPwhsyoS80cNUF9fI=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "0e11b7bcba1d74ef8ea10bfdfb1e1a5811a21087",
"rev": "7566825d4652a1b885bd4ce65bd9e8def432fec9",
"type": "github"
},
"original": {
@@ -212,57 +41,13 @@
"type": "github"
}
},
"lanzaboote": {
"inputs": {
"crane": "crane",
"nixpkgs": [
"nixpkgs"
],
"pre-commit": "pre-commit",
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1790423250,
"narHash": "sha256-sr4Kfp6yaXUeyKL6n0Y8/ElcR3momIRC20HFc+LF22s=",
"owner": "nix-community",
"repo": "lanzaboote",
"rev": "c1c5edd31802d181c8aa2c71588995d93425d650",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "v1.2.0",
"repo": "lanzaboote",
"type": "github"
}
},
"nixos-hardware": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1791128201,
"narHash": "sha256-rlsYY/Dg/LhbIj51Aa6TLvRpZeb3KZgUTd7llQ5XcJE=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "31cc5f4d9b9ba601071e8b8504601b9b176e2756",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1791260994,
"narHash": "sha256-Miqqk/ammqnTUxaoCyvtwoPeLbI1ksFyLxi/CazZpWY=",
"lastModified": 1783776592,
"narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "151fa4e8ddfdd8dd25d945ad94ed54a13de9f6e4",
"rev": "e7a3ca8092b61ff85b6a45bf863ea2b2d6a661b3",
"type": "github"
},
"original": {
@@ -281,11 +66,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1791235629,
"narHash": "sha256-ySIbhYpjg8CnfuJTs/cfkEQuGpk02IzT+a3VDz7Cec0=",
"lastModified": 1783647864,
"narHash": "sha256-gtVkWD4SbsvQQ8aSFEsrUTxxyuim4/ZC6lBJmA+sE/k=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "8fbc7d3ff1154fab898895e7c4e71a4d06936ce3",
"rev": "ebffdb62cd1604537ee51d4d23258c002f1c90f8",
"type": "github"
},
"original": {
@@ -301,11 +86,11 @@
]
},
"locked": {
"lastModified": 1791249451,
"narHash": "sha256-ucUgpRWCvXd17/29C1rPYliLTz8mdNeOvsSGdtBGMAY=",
"lastModified": 1783830881,
"narHash": "sha256-V75/tqvYElVWyXnFf+0jh89wMh5a/cbV5YYe/P7RFDM=",
"owner": "noctalia-dev",
"repo": "noctalia-shell",
"rev": "4237bc286bb9db7fec8ba663bfc42779af9b1372",
"rev": "ed3cb98536eaec92c2b523ddf703e1dc6728f535",
"type": "github"
},
"original": {
@@ -314,120 +99,15 @@
"type": "github"
}
},
"nur": {
"inputs": {
"flake-parts": [
"stylix",
"flake-parts"
],
"nixpkgs": [
"stylix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1785549842,
"narHash": "sha256-DCwBZmGsySF7oKGTRgEv2HvpxVXkHT+38VhTM76k0B4=",
"owner": "nix-community",
"repo": "NUR",
"rev": "a9f987b57594e845e3e5cdd423b9a70846d70308",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "NUR",
"type": "github"
}
},
"pre-commit": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"lanzaboote",
"nixpkgs"
]
},
"locked": {
"lastModified": 1789514889,
"narHash": "sha256-PFD1nxptCXJyJoiYO1gf/5Vv43yqGpHtMC6LUhl9/pQ=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "59f4ca0d063a1a3ec722c88b51a33004862e5379",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"home-manager": "home-manager",
"lanzaboote": "lanzaboote",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"nixvim": "nixvim",
"noctalia": "noctalia",
"stylix": "stylix"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"lanzaboote",
"nixpkgs"
]
},
"locked": {
"lastModified": 1789889921,
"narHash": "sha256-aL/ogiN7qZCGeNovS1f9hX73jwYIKb4Pcq6AZm57WtY=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "1fb104a12a8667045559b2575d6d448ae2fbd99b",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"stylix": {
"inputs": {
"base16": "base16",
"base16-fish": "base16-fish",
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_2",
"gnome-shell": "gnome-shell",
"nixpkgs": [
"nixpkgs"
],
"nur": "nur",
"systems": "systems_2",
"tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux",
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1790880877,
"narHash": "sha256-j42XqSKOAtuqtfHiElyHre2YS/h3Y3q1DjFnKODN1/k=",
"owner": "nix-community",
"repo": "stylix",
"rev": "7c065d1ed05381fceb2403b963c5ad150f32fe39",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "stylix",
"type": "github"
"noctalia": "noctalia"
}
},
"systems": {
"flake": false,
"locked": {
"lastModified": 1774449309,
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
@@ -442,86 +122,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1774449309,
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
"owner": "nix-systems",
"repo": "default",
"rev": "c29398b59d2048c4ab79345812849c9bd15e9150",
"type": "github"
},
"original": {
"owner": "nix-systems",
"ref": "future-26.11",
"repo": "default",
"type": "github"
}
},
"tinted-kitty": {
"flake": false,
"locked": {
"lastModified": 1735730497,
"narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=",
"owner": "tinted-theming",
"repo": "tinted-kitty",
"rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-kitty",
"type": "github"
}
},
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1785153830,
"narHash": "sha256-fNdfCTeCXU3tZG3TMincd+u68qBHQgCr2Ljr/M1mWP0=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "9bd28ed313560db3c5b605c63bc4e309e78e3fc8",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "schemes",
"type": "github"
}
},
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1785031658,
"narHash": "sha256-mZp9O2LjzdMzlqQF3l3fjqsuPBzXy+1qTfBEUGjTlpk=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "5d2c67f61ea7af36f16865ab6d541cdba41dc257",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "tinted-tmux",
"type": "github"
}
},
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1785030526,
"narHash": "sha256-klZf8UviewRkxuu74Bhbq6tqy7oxebQC7UVRWbbtQxU=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "16f5a8adf4a6b1310d0a61ab172de963e8f76a02",
"type": "github"
},
"original": {
"owner": "tinted-theming",
"repo": "base16-zed",
"type": "github"
}
}
},
"root": "root",
+23 -49
View File
@@ -11,61 +11,35 @@
url = "github:noctalia-dev/noctalia-shell";
inputs.nixpkgs.follows = "nixpkgs";
};
lanzaboote = {
url = "github:nix-community/lanzaboote/v1.2.0";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-hardware = {
url = "github:NixOS/nixos-hardware";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs";
};
stylix = {
url = "github:nix-community/stylix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
nixpkgs,
home-manager,
nixvim,
stylix,
...
}@inputs:
let
mkHost =
hostName:
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
./hosts/${hostName}/hardware-configuration.nix
./hosts/${hostName}/configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.backupCommand = "mv -f {file} {file}.hm-bak-$(date +%Y%m%d%H%M%S)";
home-manager.extraSpecialArgs = { inherit inputs; };
home-manager.users.aaron.imports = [
nixvim.homeModules.nixvim
stylix.homeModules.stylix
./users/aaron/home.nix
];
}
outputs = { self, nixpkgs, home-manager, nixvim, ... }@inputs:
let
mkHost = hostName: nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
./hosts/${hostName}/hardware-configuration.nix
./hosts/${hostName}/configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.extraSpecialArgs = { inherit inputs; };
home-manager.users.aaron.imports = [
nixvim.homeModules.nixvim
./users/aaron/home.nix
];
};
in
{
nixosConfigurations = {
neon = mkHost "neon";
argon = mkHost "argon";
krypton = mkHost "krypton";
};
}
];
};
in {
nixosConfigurations = {
default = mkHost "default";
neon = mkHost "neon";
argon = mkHost "argon";
};
};
}
+11 -31
View File
@@ -1,18 +1,18 @@
# argon: desktop with an amd gpu and three luks-encrypted data drives.
{ pkgs, ... }:
{ config, pkgs, inputs, ... }:
{
imports = [
../../modules/nixos/appimage.nix
../../modules/nixos/astro.nix
../../modules/nixos/audio.nix
../../modules/nixos/bootloader.nix
../../modules/nixos/calibre.nix
../../modules/nixos/certificates.nix
../../modules/nixos/data-drives.nix
../../modules/nixos/claudecode.nix
../../modules/nixos/drives.nix
../../modules/nixos/gnupg.nix
../../modules/nixos/gnuradio.nix
../../modules/nixos/graphics.nix
../../modules/nixos/greetd.nix
../../modules/nixos/lanzaboote.nix
../../modules/nixos/locales.nix
../../modules/nixos/networking.nix
../../modules/nixos/niri.nix
@@ -24,33 +24,13 @@
../../modules/nixos/settings.nix
../../modules/nixos/steam.nix
../../modules/nixos/thunar.nix
../../modules/nixos/tpm-unlock.nix
../../modules/nixos/users.nix
../../modules/nixos/vial.nix
];
# host-specific niri config (outputs, input devices)
home-manager.users.aaron.imports = [ ./niri.nix ];
# amd gpu: mesa/vulkan, and amdgpu in the initrd for plymouth
hardware.graphics = {
enable = true;
enable32Bit = true;
};
hardware.amdgpu.initrd.enable = true;
# encrypted data drives, see data-drives.nix
local.dataDrives = {
data1 = "dfae62cc-bad1-4879-bf9a-461bde833625";
data2 = "8312edae-9247-481b-a313-52a7f848f027";
nvmecache = "2352250e-4ebe-4f9a-bf66-0d4aaa961bd8";
};
environment.systemPackages = with pkgs; [
amdgpu_top
calibre # ebook management and kobo syncing
];
# set hostname
networking.hostName = "argon";
system.stateVersion = "25.11"; # don't change
# install state version
system.stateVersion = "25.11"; # Don't change
}
+24 -43
View File
@@ -1,57 +1,38 @@
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"ahci"
"usbhid"
"usb_storage"
"sd_mod"
];
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-label/nixcrypt";
allowDiscards = true;
bypassWorkqueues = true;
};
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ "dm-crypt dm-mod" ];
boot.initrd.luks.devices."cryptroot".device = "/dev/disk/by-label/nixcrypt";
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-label/nixroot";
fsType = "ext4";
};
fileSystems."/" =
{ device = "/dev/mapper/lvmroot-root";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/AC1C-20EB";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/home" =
{ device = "/dev/mapper/lvmroot-home";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/mapper/lvmroot-swap"; }
];
};
fileSystems."/home" = {
device = "/dev/disk/by-label/nixhome";
fsType = "ext4";
};
swapDevices = [
{ device = "/dev/disk/by-label/nixswap"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
-37
View File
@@ -1,37 +0,0 @@
# argon: desktop with two 1440p monitors side by side
{
wayland.windowManager.niri.settings = {
input = {
touchpad.off = { };
trackpoint.off = { };
};
_children = [
{
output = {
_args = [ "DP-1" ];
mode = "2560x1440@165.000";
scale = 1;
transform = "normal";
position._props = {
x = 0;
y = 0;
};
};
}
{
output = {
_args = [ "DP-2" ];
mode = "2560x1440@143.912";
scale = 1;
transform = "normal";
position._props = {
x = 2560;
y = 0;
};
};
}
];
};
}
+133
View File
@@ -0,0 +1,133 @@
# 0x29a nixos conifg
{ pkgs, lib, ... }:
{
# use flakes
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# configure bootloader
boot.loader.systemd-boot.enable = false;
boot.loader.grub = {
enable = true;
device = "nodev";
efiSupport = true;
};
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelParams = [
"quiet"
"console.ttyS0,115200n8" # allow terminals on serial console
];
# plymouth boot eye candy
boot.initrd.systemd.enable = true;
boot.plymouth.enable = true;
boot.plymouth.theme = "spinner";
# use latest kernel
boot.kernelPackages = pkgs.linuxPackages_latest;
# guest agent for proxmox
services.qemuGuest.enable = true;
# networking
networking.hostName = "nixos";
networking.networkmanager.enable = true;
# time zone.
time.timeZone = "Europe/Amsterdam";
# select internationalisation properties
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
console = {
font = "Lat2-Terminus16";
keyMap = "de_CH-latin1";
};
# window manager configs
services.xserver = {
enable = true;
xkb.layout = "ch";
xkb.options = "eurosign:e,caps:escape";
windowManager.qtile = {
enable = true;
extraPackages = python3Packages: with python3Packages; [
qtile-extras
];
};
};
environment.pathsToLink = [ "/libexec" ];
environment.variables.EDITOR = "vim";
# enable sound
services.pipewire = {
enable = true;
pulse.enable = true;
};
# define a user account
users.users.aaron = {
isNormalUser = true;
group = "users";
extraGroups = [ "wheel" ];
shell = pkgs.zsh;
packages = with pkgs; [
tree
fastfetch
];
};
# browser
programs.firefox.enable = true;
# zsh config
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestions.enable = true;
ohMyZsh = {
enable = true;
plugins = [ "git" "sudo" ];
theme = "agnoster";
};
};
# system packages
environment.systemPackages = with pkgs; [
vim
neovim
git
ghostty
kitty
wget
gnupg
];
# Some programs need SUID wrappers
programs.mtr.enable = true;
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
# enable the OpenSSH daemon
services.openssh.enable = true;
# firewall configs
networking.firewall.allowedTCPPorts = [ 22 ];
# networking.firewall.allowedUDPPorts = [ ... ];
# install state version
system.stateVersion = "25.05"; # Don't change
}
+40
View File
@@ -0,0 +1,40 @@
# 0x29a nixos hardware configuration
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
# boot and initrd configs
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ "dm-snapshot" "cryptd" ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
boot.initrd.luks.devices."cryptroot".device = "/dev/disk/by-label/nixcrypt";
# file systems
fileSystems."/" =
{ device = "/dev/disk/by-label/nixroot";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-label/nixhome";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-label/nixswap"; }
];
# enable dhcp on all interfaces
networking.useDHCP = lib.mkDefault true;
# set host arch
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
+76
View File
@@ -0,0 +1,76 @@
{ config, pkgs, ... }:
{
# user config
home.username = "aaron";
home.homeDirectory = "/home/aaron";
# packages
home.packages = with pkgs; [
fastfetch
zip
xz
unzip
p7zip
jq
mtr
iperf3
dnsutils
ldns
socat
nmap
cowsay
file
which
tree
zstd
gnupg
btop
iotop
iftop
strace
ltrace
lsof
sysstat
lm_sensors
ethtool
pciutils
usbutils
];
# configure git
programs.git.settings = {
enable = true;
userName = "aaron";
userEmail = "aaron@0x29a.ch";
};
programs.zsh = {
enable = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
oh-my-zsh = {
enable = true;
plugins = [ "git" "sudo" "python" "ansible" ];
theme = "agnoster";
};
};
## deploy qtile config
#home.file."qtile-config" = {
# target = ".config/qtile/config.py";
# source = "${inputs.qtile-config}/qtile_config/config.py";
# force = true;
#};
home.sessionVariables = {
EDITOR = "vim";
};
# enable home manager
programs.home-manager.enable = true;
# don't change
home.stateVersion = "25.05";
}
-44
View File
@@ -1,44 +0,0 @@
# krypton: framework 13 pro, intel core ultra x7 358H
{ inputs, ... }:
{
imports = [
inputs.nixos-hardware.nixosModules.framework-intel-core-ultra-series3
../../modules/nixos/appimage.nix
../../modules/nixos/astro.nix
../../modules/nixos/audio.nix
../../modules/nixos/bootloader.nix
../../modules/nixos/certificates.nix
../../modules/nixos/docker.nix
../../modules/nixos/gnupg.nix
../../modules/nixos/lanzaboote.nix
../../modules/nixos/locales.nix
../../modules/nixos/networking.nix
../../modules/nixos/niri.nix
../../modules/nixos/noctalia.nix
../../modules/nixos/openssh.nix
../../modules/nixos/packages.nix
../../modules/nixos/protonvpn.nix
../../modules/nixos/sddm.nix
../../modules/nixos/services.nix
../../modules/nixos/settings.nix
../../modules/nixos/steam.nix
../../modules/nixos/tpm-unlock.nix
../../modules/nixos/users.nix
../../modules/nixos/vial.nix
];
# host-specific niri config (input devices, laptop binds)
home-manager.users.aaron.imports = [ ./niri.nix ];
# hidpi panel (2880x1920): the sddm greeter runs in weston, which doesn't scale
services.displayManager.sddm.settings.General.GreeterEnvironment = "QT_SCALE_FACTOR=2";
# bigger boot menu font, mode found with "r" in the menu; mode 6 is beyond
# what boot.loader.systemd-boot.consoleMode accepts, so set via lanzaboote
boot.lanzaboote.settings.console-mode = "6";
networking.hostName = "krypton";
system.stateVersion = "26.05"; # don't change
}
-60
View File
@@ -1,60 +0,0 @@
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"xhci_pci"
"thunderbolt"
"nvme"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-label/nixcrypt";
allowDiscards = true;
bypassWorkqueues = true;
};
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-label/nixroot";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
fileSystems."/home" = {
device = "/dev/disk/by-label/nixhome";
fsType = "ext4";
};
swapDevices = [
{ device = "/dev/disk/by-label/nixswap"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.cpu.intel.npu.enable = true;
}
-24
View File
@@ -1,24 +0,0 @@
# krypton: framework 13 laptop, the built-in display is auto-configured by niri
{ lib, ... }:
{
wayland.windowManager.niri.settings = {
input.touchpad = {
tap = { };
natural-scroll = { };
};
layout.gaps = lib.mkForce 10;
binds = {
"Print".screenshot = { };
"Ctrl+Print".screenshot-screen = { };
"Mod+Shift+P".power-off-monitors = { };
# finer brightness steps
"XF86MonBrightnessUp".spawn-sh = lib.mkForce "brightnessctl --class=backlight set +1%";
"XF86MonBrightnessDown".spawn-sh = lib.mkForce "brightnessctl --class=backlight set 1%-";
};
};
}
+7 -27
View File
@@ -1,23 +1,14 @@
# neon: thinkpad t14 gen1 (intel)
{
inputs,
lib,
pkgs,
...
}:
{ config, pkgs, inputs, ... }:
{
imports = [
inputs.nixos-hardware.nixosModules.lenovo-thinkpad-t14-intel-gen1
../../modules/nixos/appimage.nix
../../modules/nixos/astro.nix
../../modules/nixos/audio.nix
../../modules/nixos/bootloader.nix
../../modules/nixos/certificates.nix
../../modules/nixos/claudecode.nix
../../modules/nixos/docker.nix
../../modules/nixos/gnupg.nix
../../modules/nixos/lanzaboote.nix
../../modules/nixos/locales.nix
../../modules/nixos/networking.nix
../../modules/nixos/niri.nix
@@ -29,24 +20,13 @@
../../modules/nixos/services.nix
../../modules/nixos/settings.nix
../../modules/nixos/steam.nix
../../modules/nixos/tpm-unlock.nix
../../modules/nixos/users.nix
../../modules/nixos/vial.nix
];
# host-specific niri config (input devices, laptop binds)
home-manager.users.aaron.imports = [ ./niri.nix ];
# nixos-hardware's intel module adds intel-compute-runtime-legacy1 (opencl),
# which isn't cached and currently fails to build; not needed on neon
hardware.graphics.extraPackages = lib.mkForce (
with pkgs;
[
intel-media-driver
vpl-gpu-rt
]
);
# set hostname
networking.hostName = "neon";
system.stateVersion = "25.11"; # don't change
# install state version
system.stateVersion = "25.11"; # Don't change
}
+24 -46
View File
@@ -1,61 +1,39 @@
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"xhci_pci"
"nvme"
"usb_storage"
"sd_mod"
"rtsx_pci_sdmmc"
];
boot.initrd.kernelModules = [
"dm-snapshot"
"cryptd"
];
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-label/nixcrypt";
allowDiscards = true;
bypassWorkqueues = true;
};
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ "dm-snapshot" "cryptd" ];
boot.initrd.luks.devices."cryptroot".device = "/dev/disk/by-label/nixcrypt";
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-label/nixroot";
fsType = "ext4";
};
fileSystems."/" =
{ device = "/dev/disk/by-label/nixroot";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
fileSystems."/boot" =
{ device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-label/nixhome";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-label/nixswap"; }
];
};
fileSystems."/home" = {
device = "/dev/disk/by-label/nixhome";
fsType = "ext4";
};
swapDevices = [
{ device = "/dev/disk/by-label/nixswap"; }
];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-24
View File
@@ -1,24 +0,0 @@
# neon: laptop, the built-in display is auto-configured by niri
{ lib, ... }:
{
wayland.windowManager.niri.settings = {
input.touchpad = {
tap = { };
natural-scroll = { };
};
layout.gaps = lib.mkForce 10;
binds = {
"Print".screenshot = { };
"Ctrl+Print".screenshot-screen = { };
"Mod+Shift+P".power-off-monitors = { };
# finer brightness steps
"XF86MonBrightnessUp".spawn-sh = lib.mkForce "brightnessctl --class=backlight set +1%";
"XF86MonBrightnessDown".spawn-sh = lib.mkForce "brightnessctl --class=backlight set 1%-";
};
};
}
+1 -1
View File
@@ -1,4 +1,4 @@
{ pkgs, ... }:
{ config, pkgs, inputs, ... }:
{
# user fonts
+5
View File
@@ -1,13 +1,18 @@
{ config, pkgs, inputs, ... }:
{
programs.ghostty = {
enable = true;
settings = {
clipboard-paste-protection = false;
clipboard-read = "allow";
font-family = "0xProto Nerd Font Mono";
font-size = 12;
gtk-titlebar = false;
scrollback-limit = 100000;
shell-integration = "zsh";
shell-integration-features = "ssh-env,ssh-terminfo";
theme = "noctalia"; # generated by noctalia-shell
window-decoration = "auto";
window-padding-x = 10;
window-padding-y = 10;
+5 -30
View File
@@ -1,42 +1,17 @@
# Commits are signed with each machine's ~/.ssh/id_ed25519 through the ssh
# agent. gitea verifies them against the account keys; allowed_signers gives
# the local git the same trust, so `git log --show-signature` resolves too.
{ config, pkgs, inputs, ... }:
{
config,
lib,
pkgs,
...
}:
let
email = "aaron@0x29a.ch";
signingKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHRhwzo1oxaT3fEySSmILKNnu9v30cfjx5G7FKpmfqeX aaron@argon"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGDkhvvTUcBSQdtXjX+Mw2Bp8HHhtiBm8aJi4ZxiBgZR aaron@neon"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5BI+rirjPHZwqgBzO3xOi3m0+07zY0uEou7NSCFh0+ aaron@krypton"
];
in
{
xdg.configFile."git/allowed_signers".text = lib.concatMapStrings (
key: "${email} ${key}\n"
) signingKeys;
programs.git = {
enable = true;
settings = {
push.autoSetupRemote = true;
push = { autoSetupRemote = true; };
user = {
name = "aaron";
inherit email;
name = "aaron";
email = "aaron@0x29a.ch";
};
gpg.ssh.allowedSignersFile = "${config.xdg.configHome}/git/allowed_signers";
};
signing = {
format = "ssh";
# the public key makes ssh-keygen sign through the agent
key = "${config.home.homeDirectory}/.ssh/id_ed25519.pub";
signer = "${pkgs.openssh}/bin/ssh-keygen";
key = "7A830180A05DAC59CDE43B0677D2F5DB48184456";
signByDefault = true;
};
};
-278
View File
@@ -1,278 +0,0 @@
# Only renders ~/.config/niri/config.kdl; niri itself, its session and portals
# come from modules/nixos/niri.nix. Outputs and input devices that differ
# per machine live in hosts/<host>/niri.nix.
{
config,
lib,
osConfig,
...
}:
let
# Mod+1..9 focus a workspace, Mod+Ctrl+1..9 move the column there
workspaceBinds = lib.mergeAttrsList (
map (n: {
"Mod+${toString n}".focus-workspace = n;
"Mod+Ctrl+${toString n}".move-column-to-workspace = n;
}) (lib.range 1 9)
);
# shell command that also works on the lock screen
lockedSh = cmd: {
_props.allow-when-locked = true;
spawn-sh = cmd;
};
# niri has no stylix target, so the colors are picked here
colors = config.lib.stylix.colors.withHashtag;
in
{
wayland.windowManager.niri = {
# only on hosts that run niri
enable = osConfig.programs.niri.enable;
# validate the config against the installed niri
package = osConfig.programs.niri.package;
systemd.enable = false;
portalPackage = null;
xwaylandSatellitePackage = null; # installed system-wide
settings = {
input = {
keyboard = {
xkb.layout = "ch";
numlock = { };
};
mouse = {
natural-scroll = { };
accel-speed = 0.5;
scroll-method = "no-scroll";
};
};
environment.GTK_IM_MODULE = "simple";
layout = {
gaps = 16;
center-focused-column = "never";
preset-column-widths._children = [
{ proportion = 0.33333; }
{ proportion = 0.5; }
{ proportion = 0.66667; }
{ fixed = 2560; }
];
default-column-width.proportion = 0.5;
focus-ring = {
on = { };
width = 2;
active-color = colors.base03;
inactive-color = colors.base00;
urgent-color = colors.base0B;
};
border.off = { };
shadow = {
on = { };
draw-behind-window = true;
softness = 30;
spread = 10;
offset._props = {
x = 0;
y = 5;
};
color = "#0007";
};
};
spawn-at-startup = "noctalia";
hotkey-overlay.skip-at-startup = { };
screenshot-path = "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png";
_children = [
# Open the Firefox picture-in-picture player as floating by default.
{
window-rule._children = [
{
match._props = {
app-id = "firefox$";
title = "^Picture-in-Picture$";
};
}
{ open-floating = true; }
];
}
# Block out the password manager from screen capture.
{
window-rule._children = [
{ match._props.app-id = "^org\\.keepassxc\\.KeePassXC$"; }
{ block-out-from = "screen-capture"; }
];
}
{
window-rule = {
geometry-corner-radius = 12;
clip-to-geometry = true;
};
}
];
binds = workspaceBinds // {
# programs: terminal, app launcher, screen locker
"Mod+Return" = {
_props.hotkey-overlay-title = "Open a Terminal";
spawn = "ghostty";
};
"Mod+D" = {
_props.hotkey-overlay-title = "Run an Application";
spawn-sh = "noctalia msg panel-toggle launcher";
};
"Super+Alt+L" = {
_props.hotkey-overlay-title = "Lock the Screen";
spawn-sh = "noctalia msg session lock";
};
# media keys (PipeWire / WirePlumber)
"XF86AudioRaiseVolume" = lockedSh "wpctl set-volume @DEFAULT_SINK@ 0.01+ -l 1.0";
"XF86AudioLowerVolume" = lockedSh "wpctl set-volume @DEFAULT_SINK@ 0.01-";
"XF86AudioMute" = lockedSh "wpctl set-mute @DEFAULT_SINK@ toggle";
"XF86AudioMicMute" = lockedSh "wpctl set-mute @DEFAULT_SOURCE@ toggle";
"XF86AudioPlay" = lockedSh "playerctl play-pause";
"XF86AudioStop" = lockedSh "playerctl stop";
"XF86AudioPrev" = lockedSh "playerctl previous";
"XF86AudioNext" = lockedSh "playerctl next";
"XF86MonBrightnessUp" = lockedSh "brightnessctl --class=backlight set +10%";
"XF86MonBrightnessDown" = lockedSh "brightnessctl --class=backlight set 10%-";
"Mod+O" = {
_props.repeat = false;
toggle-overview = { };
};
"Mod+Q" = {
_props.repeat = false;
close-window = { };
};
# focus / move columns and windows
"Mod+Left".focus-column-left = { };
"Mod+Down".focus-window-down = { };
"Mod+Up".focus-window-up = { };
"Mod+Right".focus-column-right = { };
"Mod+H".focus-column-left = { };
"Mod+J".focus-window-down = { };
"Mod+K".focus-window-up = { };
"Mod+L".focus-column-right = { };
"Mod+Shift+Left".move-column-left = { };
"Mod+Shift+Down".move-window-down = { };
"Mod+Shift+Up".move-window-up = { };
"Mod+Shift+Right".move-column-right = { };
"Mod+Shift+H".move-column-left = { };
"Mod+Shift+J".move-window-down = { };
"Mod+Shift+K".move-window-up = { };
"Mod+Shift+L".move-column-right = { };
"Mod+Home".focus-column-first = { };
"Mod+End".focus-column-last = { };
"Mod+Ctrl+Home".move-column-to-first = { };
"Mod+Ctrl+End".move-column-to-last = { };
# move columns between monitors
"Mod+Ctrl+Left".move-column-to-monitor-left = { };
"Mod+Ctrl+Down".move-column-to-monitor-down = { };
"Mod+Ctrl+Up".move-column-to-monitor-up = { };
"Mod+Ctrl+Right".move-column-to-monitor-right = { };
"Mod+Ctrl+H".move-column-to-monitor-left = { };
"Mod+Ctrl+J".move-column-to-monitor-down = { };
"Mod+Ctrl+K".move-column-to-monitor-up = { };
"Mod+Ctrl+L".move-column-to-monitor-right = { };
# workspaces
"Mod+Page_Down".focus-workspace-down = { };
"Mod+Page_Up".focus-workspace-up = { };
"Mod+U".focus-workspace-down = { };
"Mod+I".focus-workspace-up = { };
"Mod+Ctrl+Page_Down".move-column-to-workspace-down = { };
"Mod+Ctrl+Page_Up".move-column-to-workspace-up = { };
"Mod+Ctrl+U".move-column-to-workspace-down = { };
"Mod+Ctrl+I".move-column-to-workspace-up = { };
"Mod+Shift+Page_Down".move-workspace-down = { };
"Mod+Shift+Page_Up".move-workspace-up = { };
"Mod+Shift+U".move-workspace-down = { };
"Mod+Shift+I".move-workspace-up = { };
# mouse wheel
"Mod+WheelScrollDown" = {
_props.cooldown-ms = 150;
focus-workspace-down = { };
};
"Mod+WheelScrollUp" = {
_props.cooldown-ms = 150;
focus-workspace-up = { };
};
"Mod+Ctrl+WheelScrollDown" = {
_props.cooldown-ms = 150;
move-column-to-workspace-down = { };
};
"Mod+Ctrl+WheelScrollUp" = {
_props.cooldown-ms = 150;
move-column-to-workspace-up = { };
};
"Mod+WheelScrollRight".focus-column-right = { };
"Mod+WheelScrollLeft".focus-column-left = { };
"Mod+Ctrl+WheelScrollRight".move-column-right = { };
"Mod+Ctrl+WheelScrollLeft".move-column-left = { };
"Mod+Shift+WheelScrollDown".focus-column-right = { };
"Mod+Shift+WheelScrollUp".focus-column-left = { };
"Mod+Ctrl+Shift+WheelScrollDown".move-column-right = { };
"Mod+Ctrl+Shift+WheelScrollUp".move-column-left = { };
# columns
"Mod+BracketLeft".consume-or-expel-window-left = { };
"Mod+BracketRight".consume-or-expel-window-right = { };
"Mod+Comma".consume-window-into-column = { };
"Mod+Period".expel-window-from-column = { };
"Mod+R".switch-preset-column-width = { };
"Mod+Shift+R".switch-preset-window-height = { };
"Mod+Ctrl+R".reset-window-height = { };
"Mod+F".maximize-column = { };
"Mod+Shift+F".fullscreen-window = { };
"Mod+Ctrl+F".expand-column-to-available-width = { };
"Mod+C".center-column = { };
"Mod+Ctrl+C".center-visible-columns = { };
"Mod+Minus".set-column-width = "-10%";
"Mod+Equal".set-column-width = "+10%";
"Mod+Shift+Minus".set-window-height = "-10%";
"Mod+Shift+Equal".set-window-height = "+10%";
"Mod+Space".toggle-window-floating = { };
"Mod+Shift+Space".switch-focus-between-floating-and-tiling = { };
"Mod+W".toggle-column-tabbed-display = { };
# screenshots
"Mod+P".screenshot = { };
"Alt+Print".screenshot-window = { };
# escape hatch for apps that inhibit keyboard shortcuts
"Mod+Escape" = {
_props.allow-inhibiting = false;
toggle-keyboard-shortcuts-inhibit = { };
};
"Mod+Shift+E".quit = { };
};
};
};
}
+13 -16
View File
@@ -1,10 +1,13 @@
{ pkgs, inputs, ... }:
{ config, pkgs, inputs, ... }:
{
programs.nixvim = {
enable = true;
# same nixpkgs as the flake's `follows`, silences nixvim's pin warning
# We keep `inputs.nixvim.inputs.nixpkgs.follows = "nixpkgs"` in flake.nix so
# the whole config shares a single nixpkgs. Setting `source` explicitly to
# that same nixpkgs acknowledges the override and silences nixvim's warning
# about its pinned nixpkgs being bypassed.
nixpkgs.source = inputs.nixpkgs;
# set aliases
@@ -23,7 +26,7 @@
# nvim mapleader for all command below
globals.mapleader = " ";
# set colorscheme to nord, stylix's base16 version is disabled in stylix.nix
# set colorscheme to nord
colorschemes.nord.enable = true;
# nvim plugins
@@ -54,7 +57,7 @@
servers.pyright.enable = true;
servers.ruff.enable = true;
keymaps.lspBuf = {
"<leader>K" = "hover";
"<leader>K" = "hover";
"<leader>gd" = "definition";
"<leader>gr" = "references";
"<leader>f" = "format";
@@ -64,11 +67,7 @@
};
plugins.treesitter = {
enable = true;
settings.ensure_installed = [
"markdown"
"markdown_inline"
"typst"
];
settings.ensure_installed = [ "markdown" "markdown_inline" "typst" ];
};
plugins.typst-preview = {
enable = true;
@@ -88,11 +87,7 @@
enable = true;
settings = {
# render in normal mode, raw source in insert
render_modes = [
"n"
"c"
"t"
];
render_modes = [ "n" "c" "t"];
pipe_table.preset = "round";
heading.width = "block";
file_types = [ "markdown" ];
@@ -101,6 +96,8 @@
};
};
# telescope live_grep
home.packages = [ pkgs.ripgrep ];
# install dependencies
home.packages = with pkgs; [
ripgrep
];
}
+22 -43
View File
@@ -1,35 +1,37 @@
{ pkgs, inputs, ... }:
{ config, pkgs, inputs, ... }:
{
# Noctalia v5 shell, managed via home-manager's built-in programs.noctalia module.
# The noctalia flake's homeModules.default is not imported: it redeclares the same
# options and its disabledModules path ("programs/noctalia.nix") doesn't match HM's.
# Noctalia v5 shell, managed via its upstream home-manager module.
# See https://docs.noctalia.dev/v5/getting-started/nixos/
imports = [ inputs.noctalia.homeModules.default ];
programs.noctalia = {
enable = true;
# Use the package from the noctalia flake rather than nixpkgs.
# The module's `package` option has no default, so it must be set explicitly.
package = inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default;
# settings is rendered to ~/.config/noctalia/config.toml
settings = {
# theme / colors come from stylix, see stylix.nix
# theme / colors
theme = {
source = "builtin";
builtin = "Nord";
mode = "dark";
templates.builtin_ids = [ "ghostty" ];
};
# general
shell = {
font_family = "0xProto Nerd Font";
font_family = "0xProto Nerd Font Mono";
ui_scale = 1.2;
avatar_path = "/home/aaron/syncthing/pictures/Logo-Aaron-Totenkopf-rund-schwarz.png";
telemetry_enabled = false;
clipboard_enabled = true;
password_style = "random";
launcher = {
categories = false;
providers.emoji.global = false;
};
panel = {
launcher_compact = true;
open_near_click_control_center = true;
open_near_click_session = true;
open_near_click_wallpaper = true;
@@ -70,24 +72,9 @@
radius = 0;
scale = 1.2;
widget_spacing = 20;
# no dark gradient on the seam between the bar and attached panels (e.g. control center)
contact_shadow = false;
start = [
"control-center"
"cpu"
"ram"
"temp"
"active_window"
];
start = [ "control-center" "cpu" "ram" "temp" "active_window" ];
center = [ "workspaces" ];
end = [
"tray"
"bluetooth"
"notifications"
"volume"
"network"
"clock"
];
end = [ "tray" "bluetooth" "notifications" "volume" "network" "clock" ];
};
};
@@ -96,7 +83,7 @@
bluetooth.capsule = true;
control-center = {
capsule_radius = 8;
custom_image = "/home/aaron/syncthing/pictures/nix_flake_logo.png";
custom_image = "/home/aaron/Pictures/nix_flake_logo.png";
scale = 1.4;
};
cpu.capsule = true;
@@ -115,25 +102,17 @@
# idle behavior
idle = {
pre_action_fade_seconds = 5;
behavior_order = [
"screen-off"
"lock"
"lock-and-suspend"
];
behavior_order = [ "screen-off" "lock" "lock-and-suspend" ];
behavior = {
"screen-off" = {
action = "screen_off";
enabled = true;
timeout = 300;
};
"lock" = {
action = "lock";
enabled = true;
timeout = 600;
};
"lock" = {
enabled = true;
timeout = 660;
};
"lock-and-suspend" = {
action = "lock_and_suspend";
enabled = true;
timeout = 1800;
};
+1 -2
View File
@@ -1,4 +1,4 @@
{ config, pkgs, ... }:
{ config, pkgs, inputs, ... }:
{
# user packages
@@ -7,7 +7,6 @@
discord
fastfetch
keepassxc
signal-desktop
teamspeak6-client
typst
zathura
+8 -25
View File
@@ -1,26 +1,21 @@
# zsh with oh-my-zsh: agnoster where glyphs render, gentoo on the console.
# Deep paths are shortened to `…/last/two` so the prompt stays on one line:
# `%(4~|…/%2~|%~)` shows the last two components from four levels down.
{ lib, ... }:
{ config, lib, pkgs, inputs, ... }:
{
# configure z-shell to use omz with some plugins
programs.zsh = {
enable = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
oh-my-zsh = {
enable = true;
plugins = [
"git"
"ssh-agent"
"gpg-agent"
];
# runs before oh-my-zsh is sourced
# add git and agents as plugins
plugins = [ "git" "ssh-agent" "gpg-agent" ];
# everything here lands before `source $ZSH/oh-my-zsh.sh`
extraConfig = ''
# faster git status on large repositories
# make omz faster on large repositories
DISABLE_UNTRACKED_FILES_DIRTY=true
# only display a fancy theme when glyphs are rendered
if [[ "$TERM" == "linux" || "$TERM" == "screen" ]]; then
ZSH_THEME="gentoo"
else
@@ -28,21 +23,9 @@
fi
'';
};
# runs after oh-my-zsh, once the theme's prompt exists
initContent = lib.mkAfter ''
if [[ "$ZSH_THEME" == "agnoster" ]]; then
# agnoster renders prompt_dir on every prompt, so override it
prompt_dir() {
prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" '%(4~|…/%2~|%~)'
}
else
# gentoo builds PROMPT once; ascii dots, the console font lacks …
PROMPT="''${PROMPT/\%~/%(4~|.../%2~|%~)}"
fi
'';
};
# set important env vars
home.sessionVariables = {
EDITOR = "vim";
NH_FLAKE = "/home/aaron/git/nixconfig";
+31
View File
@@ -0,0 +1,31 @@
{ config, pkgs, inputs, ... }:
{
# set gtk theme
gtk = {
enable = true;
theme = {
name = "Adwaita-dark";
package = pkgs.gnome-themes-extra;
};
gtk3.extraConfig.gtk-application-prefer-dark-theme = 1;
gtk4.theme = null;
gtk4.extraConfig.gtk-application-prefer-dark-theme = 1;
};
# set qt theme
qt = {
enable = true;
platformTheme.name = "qt6";
style = {
name = "adwaita-dark";
package = pkgs.adwaita-qt;
};
};
# ensure packages are installed
home.packages = with pkgs; [
gnome-themes-extra
adwaita-qt
];
}
-38
View File
@@ -1,38 +0,0 @@
# One Nord palette for everything stylix has a target for: gtk, qt,
# noctalia, ghostty. Niri has no target and reads the colors in niri.nix.
# Only the home-manager module is used, so boot, console and sddm are left alone.
{ pkgs, ... }:
{
stylix = {
enable = true;
base16Scheme = "${pkgs.base16-schemes}/share/themes/nord.yaml";
polarity = "dark";
fonts = {
monospace = {
name = "0xProto Nerd Font Mono";
package = pkgs.nerd-fonts._0xproto;
};
sizes.terminal = 12;
};
# its overlays (nixos-icons, gtksourceview) clash with useGlobalPkgs
overlays.enable = false;
targets = {
# profiles aren't managed by home-manager, declaring one here would
# take over the existing profile
firefox.enable = false;
# the bar keeps 0xProto instead of the sans-serif font
noctalia.fonts.enable = false;
# nord.nvim is calmer than the base16 palette, e.g. no line number
# background, see nixvim.nix
nixvim.enable = false;
# the hand-built status line in tmux.nix uses ANSI color names, which
# already follow the terminal palette
tmux.enable = false;
};
};
}
+25 -60
View File
@@ -1,95 +1,60 @@
# Nord-style status line built natively, no theme plugin.
# The powerline separators (U+E0B0..U+E0B3) are written as escapes via
# fromJSON: literal private-use glyphs get stripped silently on copy/paste.
# Commas inside #{?...} separate arguments, hence the escaped `#,` below.
{ config, pkgs, inputs, ... }:
let
sep = builtins.fromJSON ''
{
"right": "",
"rightThin": "",
"left": "",
"leftThin": ""
}
'';
in
{
programs.tmux = {
enable = true;
prefix = "C-a";
keyMode = "vi";
mouse = true;
terminal = "tmux-256color"; # truecolor, italics and undercurl in nvim
escapeTime = 10; # the 500ms default lags leaving insert mode in nvim
focusEvents = true; # nvim autoread
historyLimit = 50000;
baseIndex = 1; # window numbers match the number row
terminal = "screen-256color";
extraConfig = ''
# Status keys
set -g status-keys vi
# outer terminal does 24-bit colour
set -sa terminal-features ",*:RGB"
# forward Shift+Enter and other extended keys as CSI-u (tmux >= 3.5)
set -s extended-keys always
set -s extended-keys-format csi-u
set -as terminal-features '*:extkeys'
# Status bar options
set -g status-interval 5
set -g status-interval 1
set -g status on
set -g status-justify left
# Clock mode
setw -g clock-mode-colour cyan
# Colors
set -g status-bg black
set -g status-fg white
# Key bindings
bind r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded"
# Panel split and selection, new panes/windows inherit the cwd
# Reload configuration
bind r source-file ~/.config/tmux/tmux.conf
# Panel split and selection
unbind %
unbind '"'
bind v split-window -v -c "#{pane_current_path}"
bind c split-window -h -c "#{pane_current_path}"
bind i new-window -c "#{pane_current_path}"
bind -r b previous-window
bind -r n next-window
bind v split-window -v
bind c split-window -h
bind i new-window
bind b previous-window
bind n next-window
# Move around panes with hjkl
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Resize panes
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# copy to both the clipboard and primary selection
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
bind H resize-pane -L 5
bind J resize-pane -D 5
bind K resize-pane -U 5
bind L resize-pane -R 5
# Wayland clipboard integration
# Copy selection to both clipboard (Ctrl+V / Shift+Insert) and primary (middle-click)
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "wl-copy && wl-copy --primary"
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "wl-copy && wl-copy --primary"
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "wl-copy && wl-copy --primary"
# Kill commands
bind q confirm-before -p "kill window #W? (y/n)" kill-window
bind Q confirm-before -p "kill session #S? (y/n)" kill-session
bind q kill-window
bind Q kill-session
# Bars
set -g status-left-length 24
set -g status-left "#[fg=black,bg=blue,bold] #{=20:session_name} #[fg=blue,bg=black,nobold,noitalics,nounderscore]${sep.right}"
set -g status-right "#{?client_prefix,#[fg=black#,bg=yellow#,bold] ^A ,}#[fg=brightblack,bg=black,nobold,noitalics,nounderscore]${sep.left}#[fg=white,bg=brightblack] %Y-%m-%d #[fg=white,bg=brightblack,nobold,noitalics,nounderscore]${sep.leftThin}#[fg=white,bg=brightblack] %H:%M #[fg=cyan,bg=brightblack,nobold,noitalics,nounderscore]${sep.left}#[fg=black,bg=cyan,bold] #H "
set -g status-left "#[fg=black,bg=blue,bold] #{=20:session_name} #[fg=blue,bg=black,nobold,noitalics,nounderscore]"
set -g status-right "#{prefix_highlight}#[fg=brightblack,bg=black,nobold,noitalics,nounderscore]#[fg=white,bg=brightblack] %Y-%m-%d #[fg=white,bg=brightblack,nobold,noitalics,nounderscore]#[fg=white,bg=brightblack] %H:%M #[fg=cyan,bg=brightblack,nobold,noitalics,nounderscore]#[fg=black,bg=cyan,bold] #H "
# Windows
set -g window-status-format "#[fg=black,bg=brightblack,nobold,noitalics,nounderscore]${sep.right} #[fg=white,bg=brightblack]#I #[fg=white,bg=brightblack,nobold,noitalics,nounderscore]${sep.rightThin} #[fg=white,bg=brightblack]#W #F #[fg=brightblack,bg=black,nobold,noitalics,nounderscore]${sep.right}"
set -g window-status-current-format "#[fg=black,bg=cyan,nobold,noitalics,nounderscore]${sep.right} #[fg=black,bg=cyan]#I #[fg=black,bg=cyan,nobold,noitalics,nounderscore]${sep.rightThin} #[fg=black,bg=cyan]#W #F #[fg=cyan,bg=black,nobold,noitalics,nounderscore]${sep.right}"
set -g window-status-format "#[fg=black,bg=brightblack,nobold,noitalics,nounderscore] #[fg=white,bg=brightblack]#I #[fg=white,bg=brightblack,nobold,noitalics,nounderscore] #[fg=white,bg=brightblack]#W #F #[fg=brightblack,bg=black,nobold,noitalics,nounderscore]"
set -g window-status-current-format "#[fg=black,bg=cyan,nobold,noitalics,nounderscore] #[fg=black,bg=cyan]#I #[fg=black,bg=cyan,nobold,noitalics,nounderscore] #[fg=black,bg=cyan]#W #F #[fg=cyan,bg=black,nobold,noitalics,nounderscore]"
set -g window-status-separator ""
'';
};
-10
View File
@@ -1,10 +0,0 @@
# Running an AppImage directly fails on NixOS: its runtime dlopens
# libfuse.so.2, which nix-ld doesn't cover. appimage-run unpacks the image
# into an FHS sandbox instead. Used for the BitBox02 wallet from bitbox.swiss.
{
programs.appimage = {
enable = true;
binfmt = true; # ./Something.AppImage runs without the appimage-run prefix
};
}
+61 -55
View File
@@ -1,72 +1,78 @@
# Stellarium for target finding, Siril for stacking.
#
# Siril's python plugins run in a venv of foreign manylinux wheels (numpy,
# PyQt6, ...), dlopened by nixpkgs python, so nix-ld doesn't help. The wrapper
# puts their libs on LD_LIBRARY_PATH, a python on PATH to bootstrap the venv,
# and adwaita-qt6 on QT_PLUGIN_PATH so the dark style override resolves.
# The python comes from /etc/siril/bin, a stable symlink: a /nix/store path
# would leave the venv dangling after the next python bump and gc.
#
# StarNet++ has no package: unzip the v2 ORT cli build from starnetastro.com
# to ~/.local/share/siril/starnet/ and point Siril's preferences at ./starnet2.
# It runs through nix-ld and finds its own libs in the bundled ./lib.
{ lib, pkgs, ... }:
{ config, lib, pkgs, ... }:
let
# Siril's Python plugins (sirilpy) run in a venv that pip-installs foreign
# manylinux wheels (numpy, GraXpert deps, ...). Those .so files need
# libstdc++ at runtime. nix-ld does NOT cover this: it only handles the
# initial exec of a foreign binary, but here a *native* nixpkgs python
# dlopen()s the foreign wheel. So we put the libs on LD_LIBRARY_PATH, which
# the python subprocess inherits from the Siril process.
sirilWithPlugins = pkgs.symlinkJoin {
name = "siril-with-plugins";
paths = [ pkgs.siril ];
nativeBuildInputs = [ pkgs.makeWrapper ];
# Siril bootstraps its sirilpy venv at first run by locating a `python3`
# on PATH. nixpkgs only *propagates* python3 from the siril derivation (it
# isn't on the runtime PATH), so without the --prefix PATH below the GUI
# fails with "Python not found in system PATH" and never creates
# ~/.local/share/siril/venv. We add the same interpreter siril references.
#
# The VeraLux PyQt6 wheel ships only the built-in Windows/Fusion styles, so
# the global QT_STYLE_OVERRIDE=adwaita-dark (inherited from the session) is
# rejected ("invalid style override") and windows fall back to a light
# theme. We expose nixpkgs adwaita-qt6's style plugin on QT_PLUGIN_PATH so
# the override resolves. This works because nixpkgs qt6 and the bundled Qt
# share a major.minor (6.11); if they ever drift the plugin is simply
# ignored again (harmless warning + Fusion fallback, no loss of function).
postBuild = ''
wrapProgram $out/bin/siril \
--prefix PATH : /etc/siril/bin \
--prefix PATH : ${lib.makeBinPath [ pkgs.python3 ]} \
--prefix QT_PLUGIN_PATH : ${pkgs.adwaita-qt6}/lib/qt-6/plugins \
--prefix LD_LIBRARY_PATH : ${
lib.makeLibraryPath (
with pkgs;
[
stdenv.cc.cc.lib # libstdc++, libgcc_s, libgomp (numpy)
zlib
zstd # PyQt6
libGL # PyQt6
# Qt needs these even on wayland
glib
fontconfig
freetype
dbus
libxkbcommon
# Qt platform plugins: wayland, and the xcb fallback
wayland
libxcb-cursor
libx11
libxcb
libxcb-util
libxcb-wm
libxcb-image
libxcb-keysyms
libxcb-render-util
]
)
}
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath (with pkgs; [
stdenv.cc.cc.lib # libstdc++ / libgcc_s / libgomp (numpy etc.)
zlib
zstd # libzstd.so.1 (PyQt6)
libGL # libGL.so.1 (PyQt6)
# PyQt6 (VeraLux) — Qt bundles xcb support so it needs these even
# on Wayland; libxkbcommon is the keymap lib used by Wayland too.
glib
fontconfig
freetype
dbus
libxkbcommon
# Qt platform plugins: the wayland plugin (libqwayland.so) needs the
# wayland client libs; the xcb fallback needs libxcb-cursor.so.0.
wayland # libwayland-client/cursor/egl (wayland plugin)
libxcb-cursor # libxcb-cursor.so.0 (xcb plugin)
libx11
libxcb
libxcb-util
libxcb-wm
libxcb-image
libxcb-keysyms
libxcb-render-util
])}
'';
};
in
{
environment.systemPackages = [
pkgs.stellarium
# install stellarium for target finding and siril for stacking
environment.systemPackages = with pkgs; [
stellarium
sirilWithPlugins
];
# same python siril propagates, so sirilpy's abi matches
environment.etc."siril/bin/python3".source = "${pkgs.python3}/bin/python3";
# for StarNet++
programs.nix-ld = {
enable = true;
libraries = with pkgs; [
stdenv.cc.cc.lib
zlib
];
};
# StarNet++ has no nixpkgs package. Download the StarNet v2 ORT CLI build
# (starnet2_linux_*_ORT_x64_cli) from https://www.starnetastro.com/download/
# and unzip it to ~/.local/share/siril/starnet/. Then in Siril set
# Preferences -> Miscellaneous -> StarNet executable
# to the extracted ./starnet2 binary.
#
# The binary is a generic dynamically-linked ELF, so NixOS needs nix-ld to
# run it. Its own opencv/onnxruntime libs are found via the bundled ./lib.
programs.nix-ld.enable = true;
programs.nix-ld.libraries = with pkgs; [
stdenv.cc.cc.lib # libstdc++ / libgcc_s
zlib
];
}
+4 -2
View File
@@ -1,7 +1,9 @@
{ config, lib, pkgs, ... }:
{
# enable sound through pipewire
services.pipewire = {
enable = true;
pulse.enable = true;
enable = true;
pulse.enable = true;
};
}
+2 -13
View File
@@ -1,11 +1,9 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# set bootloader to systemd
boot.loader = {
systemd-boot.enable = true;
# no kernel command line editing at the boot menu (e.g. init=/bin/sh)
systemd-boot.editor = false;
efi.canTouchEfiVariables = true;
};
@@ -19,19 +17,10 @@
};
# kernel options
boot.kernelParams = [
"quiet"
"acpi.debug_level=0"
];
boot.kernelParams = [ "quiet" "acpi.debug_level=0"];
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.consoleLogLevel = 2;
# /tmp in RAM, nix builds go to /var/tmp instead (see settings.nix)
boot.tmp = {
useTmpfs = true;
tmpfsSize = "50%";
};
# Add boot-related packages
environment.systemPackages = with pkgs; [
efibootmgr
+8
View File
@@ -0,0 +1,8 @@
{ config, lib, pkgs, ... }:
{
# install calibre for ebook management and kobo syncing
environment.systemPackages = with pkgs; [
calibre
];
}
+2
View File
@@ -1,3 +1,5 @@
{ config, lib, pkgs, ... }:
let
caddyRootCA = ''
-----BEGIN CERTIFICATE-----
+7
View File
@@ -0,0 +1,7 @@
{ config, lib, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
claude-code
];
}
-37
View File
@@ -1,37 +0,0 @@
# luks-encrypted data drives, unlocked after boot via /etc/crypttab with
# keyfiles from /etc/nixos/keys/<name>.key on the encrypted root.
# Not in boot.initrd.luks on purpose: keyfiles there end up in the initrd
# on the unencrypted /boot.
{ config, lib, ... }:
let
drives = config.local.dataDrives;
in
{
options.local.dataDrives = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = { };
example = {
data1 = "dfae62cc-bad1-4879-bf9a-461bde833625";
};
description = "luks name -> luks partition uuid, mounted at /mnt/<name>";
};
config = lib.mkIf (drives != { }) {
environment.etc.crypttab.text = lib.concatStrings (
lib.mapAttrsToList (
name: uuid: "${name} /dev/disk/by-uuid/${uuid} /etc/nixos/keys/${name}.key luks,discard,nofail\n"
) drives
);
fileSystems = lib.mapAttrs' (
name: _:
lib.nameValuePair "/mnt/${name}" {
device = "/dev/mapper/${name}";
fsType = "ext4";
options = [ "nofail" ];
}
) drives;
};
}
+18 -13
View File
@@ -1,21 +1,26 @@
{ config, lib, pkgs, ...}:
{
# rootless only: no root daemon and no root-equivalent docker group
virtualisation.docker.rootless = {
# add docker group to user
users.users.aaron.extraGroups = [ "docker" ];
virtualisation.docker = {
enable = true;
setSocketVariable = true;
# Customize Docker daemon settings
daemon.settings = {
dns = [
"1.1.1.1"
"8.8.8.8"
];
dns = [ "1.1.1.1" "8.8.8.8" ];
log-driver = "journald";
registry-mirrors = [ "https://mirror.gcr.io" ];
storage-driver = "overlay2";
};
# Use the rootless mode
rootless = {
enable = true;
setSocketVariable = true;
};
# Install docker-compose
extraPackages = with pkgs; [
docker-compose
];
};
# k3s/k3d in rootless docker needs the cpuset controller delegated to the user session
systemd.services."user@".serviceConfig.Delegate = "cpu cpuset io memory pids";
# let rootless docker publish ports 80/443 (e.g. k3d traefik ingress)
boot.kernel.sysctl."net.ipv4.ip_unprivileged_port_start" = 80;
}
+47
View File
@@ -0,0 +1,47 @@
{ config, lib, pkgs, ... }:
# Add encrypted drives to argon
{
# copy keyfiles into initrd to make them available during early boot
boot.initrd.secrets = {
"/etc/nixos/keys/data1.key" = "/etc/nixos/keys/data1.key";
"/etc/nixos/keys/data2.key" = "/etc/nixos/keys/data2.key";
"/etc/nixos/keys/nvmecache.key" = "/etc/nixos/keys/nvmecache.key";
};
# decrypt data drives with keyfiles for argon
boot.initrd.luks.devices = {
"data1" = {
device = "/dev/disk/by-uuid/dfae62cc-bad1-4879-bf9a-461bde833625";
keyFile = "/etc/nixos/keys/data1.key";
};
"data2" = {
device = "/dev/disk/by-uuid/8312edae-9247-481b-a313-52a7f848f027";
keyFile = "/etc/nixos/keys/data2.key";
};
"nvmecache" = {
device = "/dev/disk/by-uuid/2352250e-4ebe-4f9a-bf66-0d4aaa961bd8";
keyFile = "/etc/nixos/keys/nvmecache.key";
};
};
# mount decrypted filesystems
fileSystems."/mnt/data1" = {
device = "/dev/mapper/data1";
fsType = "ext4";
options = [ "nofail" ];
};
fileSystems."/mnt/data2" = {
device = "/dev/mapper/data2";
fsType = "ext4";
options = [ "nofail" ];
};
fileSystems."/mnt/nvmecache" = {
device = "/dev/mapper/nvmecache";
fsType = "ext4";
options = [ "nofail" ];
};
}
+7 -18
View File
@@ -1,26 +1,15 @@
# A graphical pinentry never grabs the tty, so a passphrase prompt can't take
# over a terminal driven by a coding agent. The cache lasts a working day, and
# an unattended signature fails after two minutes instead of blocking forever.
{ config, pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# enable gnupg agent
programs.gnupg.agent = {
enable = true;
pinentryPackage = pkgs.pinentry-qt;
settings = {
default-cache-ttl = 86400;
max-cache-ttl = 86400;
pinentry-timeout = 120;
};
enableSSHSupport = true;
pinentryPackage = pkgs.pinentry-curses;
};
environment.systemPackages = [
pkgs.pinentry-curses # fallback for sessions without a display
# prime the passphrase cache on demand, e.g. before an agent session
(pkgs.writeShellScriptBin "gpg-unlock" ''
echo | ${config.programs.gnupg.package}/bin/gpg --clearsign --output /dev/null
echo "gpg key unlocked"
'')
environment.systemPackages = with pkgs; [
gnupg
pinentry-curses
];
}
+12
View File
@@ -0,0 +1,12 @@
{ config, lib, pkgs, ... }:
{
# install gnuradio companion along with it's osmocom library
environment.systemPackages = with pkgs; [
(gnuradio.override {
extraPackages = with gnuradio.pkgs; [ osmosdr ];
})
gqrx
hackrf
];
}
+17
View File
@@ -0,0 +1,17 @@
{ config, lib, pkgs, ... }:
{
# enable amd GPU acceleration (mesa, vulkan, egl)
hardware.graphics = {
enable = true;
enable32Bit = true;
};
# install amdgpu_top
environment.systemPackages = with pkgs; [
amdgpu_top
];
# add amdgpu to the initrd for plymouth
hardware.amdgpu.initrd.enable = true;
}
+1 -1
View File
@@ -1,4 +1,4 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# greetd display manager with tuigreet
-25
View File
@@ -1,25 +0,0 @@
# Secure Boot with lanzaboote. systemd-boot stays the bootloader, but lanzaboote
# installs it signed and writes signed boot entries instead of the nixos module.
# The keys are created once per host with `sudo sbctl create-keys` before the
# first rebuild, and enrolled into the firmware with `sbctl enroll-keys`.
{
inputs,
lib,
pkgs,
...
}:
{
imports = [ inputs.lanzaboote.nixosModules.lanzaboote ];
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl";
};
# key management and verification
environment.systemPackages = [ pkgs.sbctl ];
}
+2
View File
@@ -1,3 +1,5 @@
{ config, lib, pkgs, ... }:
{
# set the time zone
time.timeZone = "Europe/Zurich";
+10 -2
View File
@@ -1,12 +1,20 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# user networkmanager
networking.networkmanager.enable = true;
# wifi firmware and bluetooth
# firewall default configs
networking.firewall.allowedTCPPorts = [ ];
networking.firewall.allowedUDPPorts = [ ];
# enable wifi firmware
hardware.enableAllFirmware = true;
# enable bluetooth
hardware.bluetooth.enable = true;
# Add network-related packages
environment.systemPackages = with pkgs; [
wireguard-tools
update-systemd-resolved
+7 -3
View File
@@ -1,7 +1,11 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# compositor and session; the config itself lives in home-manager
# just enable and install niri
programs.niri.enable = true;
environment.systemPackages = [ pkgs.xwayland-satellite ];
# Add compositor-related packages
environment.systemPackages = with pkgs; [
xwayland-satellite
];
}
+4 -5
View File
@@ -1,14 +1,13 @@
{ pkgs, ... }:
{ config, lib, pkgs, inputs, ... }:
{
# helpers for the noctalia shell (the shell itself comes from home-manager)
# install noctalia and helper packages
environment.systemPackages = with pkgs; [
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default
adw-gtk3
adwaita-qt
adwaita-qt6
brightnessctl
ddcutil
playerctl
wl-clipboard
wl-mirror
];
}
+2
View File
@@ -1,3 +1,5 @@
{ config, lib, pkgs, ... }:
{
# enable the openssh daemon
services.openssh = {
+8 -3
View File
@@ -1,11 +1,10 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# baseline tools for every host
# system packages
environment.systemPackages = with pkgs; [
btop
cifs-utils
claude-code
cowsay
dnsutils
ethtool
@@ -15,17 +14,22 @@
imv
iperf3
jq
kdePackages.qtmultimedia
ldns
lm_sensors
lsof
ltrace
mtr
neovim
nfs-utils
nh
nix-output-monitor
nmap
nvd
p7zip
pciutils
socat
sof-firmware
strace
sysstat
tree
@@ -34,6 +38,7 @@
vim
wget
which
wl-clipboard
xz
zip
zstd
+8 -3
View File
@@ -1,8 +1,13 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# wireguard replies may leave on another interface, so strict rpfilter drops them
# protonvpn uses wireguard tunnels, which break strict reverse path filtering
# because packets arrive on the tunnel interface but may be routed back differently.
# "loose" checks that the source is routable through *any* interface (not necessarily
# the same one), which is sufficient for wireguard while still preventing IP spoofing.
networking.firewall.checkReversePath = "loose";
environment.systemPackages = [ pkgs.proton-vpn ];
environment.systemPackages = with pkgs; [
proton-vpn
];
}
+14 -4
View File
@@ -1,15 +1,25 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# enable sddm and use astronaut theme
services.displayManager.sddm = {
enable = true;
wayland.enable = true;
autoNumlock = true;
enableHidpi = true;
theme = "sddm-astronaut-theme";
extraPackages = [ pkgs.sddm-astronaut ]; # theme's qml dependencies
settings = {
Theme = {
Current = "sddm-astronaut-theme";
};
};
extraPackages = with pkgs; [
sddm-astronaut
];
};
# sddm looks for themes in the system path
environment.systemPackages = [ pkgs.sddm-astronaut ];
# Make the theme available in the system path so sddm can find it
environment.systemPackages = with pkgs; [
sddm-astronaut
];
}
+2
View File
@@ -1,3 +1,5 @@
{ config, lib, pkgs, ... }:
{
# list of enabled services on the system
services = {
+25 -15
View File
@@ -1,25 +1,30 @@
{ config, lib, pkgs, ... }:
{
nix = {
# nix settings
settings = {
experimental-features = [
"nix-command"
"flakes"
];
# enable flakes and nix-command
experimental-features = [ "nix-command" "flakes" ];
# auto-optimize my nix-store
auto-optimise-store = true;
# parallel builds, each using all cores
# use all cores
max-jobs = "auto";
# use all available cores per job
cores = 0;
# cache.nixos.org is the default, these come on top
extra-substituters = [ "https://nix-community.cachix.org" ];
extra-trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
# add trusted substituters (binary caches)
substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
];
trusted-users = [
"root"
"@wheel"
# add keys
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
# enable automatic garbage collection
gc = {
automatic = true;
dates = "weekly";
@@ -27,12 +32,17 @@
};
};
# build on disk, big builds would fill the /tmp tmpfs
systemd.services.nix-daemon.environment.TMPDIR = "/var/tmp";
# add trusted users (able to modify the nix store)
nix.settings.trusted-users = [ "root" "@wheel" ];
# steam, protonvpn, discord, etc.
# allow unfree packages (steam, protonvpn, discord, etc.)
nixpkgs.config.allowUnfree = true;
# links /libexec from derivations to /run/current-system/sw
environment.pathsToLink = [ "/libexec" ];
# enable home-manager globally
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.backupCommand = "mv -f {file} {file}.hm-bak-$(date +%Y%m%d%H%M%S)";
}
+11 -4
View File
@@ -1,13 +1,20 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# enable steam and open firewall
programs.steam = {
enable = true;
# fix black screen when running under xwayland-satellite
package = pkgs.steam.override { extraArgs = "-system-composer"; };
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
localNetworkGameTransfers.openFirewall = true;
extraCompatPackages = [ pkgs.proton-ge-bin ];
# add proton-glorious-eggroll
extraCompatPackages = with pkgs; [
proton-ge-bin
];
};
# fix black screen in steam when using xwayland-satellite
programs.steam.package = pkgs.steam.override {
extraArgs = "-system-composer";
};
}
+8 -3
View File
@@ -1,9 +1,14 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# Enable Thunar
programs.thunar.enable = true;
# thumbnails: tumbler service plus the path it loads extensions from
environment.systemPackages = [ pkgs.tumbler ];
# Install Tumbler thumbnailer service
environment.systemPackages = with pkgs; [
tumbler
];
# Ensure Thunar can locate the thumbnailer extensions
environment.pathsToLink = [ "share/thumbnailers" ];
}
-8
View File
@@ -1,8 +0,0 @@
# Unlock cryptroot with the TPM and a PIN, the passphrase stays as fallback.
# The TPM only releases the key while PCR 7 (the Secure Boot state) matches,
# so this needs lanzaboote.nix. Enrolled once per host with
# `systemd-cryptenroll`, see INSTALLATION.md.
{
boot.initrd.luks.devices."cryptroot".crypttabExtraOpts = [ "tpm2-device=auto" ];
}
+10 -8
View File
@@ -1,16 +1,18 @@
{ pkgs, ... }:
{ config, lib, pkgs, ... }:
{
# create users
users.users.aaron = {
isNormalUser = true;
extraGroups = [
"wheel"
"networkmanager"
"dialout"
];
group = "users";
extraGroups = [ "wheel" "networkmanager" "dialout" ];
shell = pkgs.zsh;
};
# login shell; plugins and prompt are configured in home-manager
programs.zsh.enable = true;
# add default zsh config
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestions.enable = true;
};
}
-21
View File
@@ -1,21 +0,0 @@
# Vial keyboards (lily58 pro r2g) expose a raw HID interface that vial.rocks
# drives over WebHID; its /dev/hidraw* node is root-only by default.
# The rule ships as 60-vial.rules because uaccess is only applied by
# 73-seat-late.rules, and services.udev.extraRules lands at 99, too late.
{ pkgs, ... }:
{
services.udev.packages = [
(pkgs.writeTextFile {
name = "vial-udev-rules";
destination = "/lib/udev/rules.d/60-vial.rules";
# the magic serial matches any vial board; uaccess grants the seat owner
text = ''
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{serial}=="*vial:f64c2b3c*", TAG+="uaccess"
'';
})
];
environment.systemPackages = [ pkgs.vial ];
}
-8
View File
@@ -1,8 +0,0 @@
# statix configuration (run via `lint` in the devenv)
# Flat assignments like `boot.loader = ...; boot.plymouth = ...;` are the
# preferred style in this repo, so don't ask for them to be merged.
disabled = [ "repeated_keys" ]
# Generated by nixos-generate-config, not maintained by hand.
ignore = [ "hosts/*/hardware-configuration.nix" ]
+3 -2
View File
@@ -1,14 +1,15 @@
{ config, pkgs, ... }:
{
imports = [
../../modules/home-manager/fonts.nix
../../modules/home-manager/git.nix
../../modules/home-manager/ghostty.nix
../../modules/home-manager/nixvim.nix
../../modules/home-manager/niri.nix
../../modules/home-manager/noctalia.nix
../../modules/home-manager/programs.nix
../../modules/home-manager/shell.nix
../../modules/home-manager/stylix.nix
../../modules/home-manager/styling.nix
../../modules/home-manager/tmux.nix
];