Compare commits

...

200 Commits

Author SHA1 Message Date
383c7bb15e [Gluetun] Switches to Wireguard config 2026-02-24 16:40:02 -08:00
a4bb91e68e [Wallabag] Adds wallabag 2026-02-24 16:40:02 -08:00
13f301c4fb [Obelisk] Adds Reflex FRP binary caches to the system 2026-02-12 15:53:26 -08:00
114a1ae125 [notes] Update Syncthing config for Proxima 2026-02-06 09:47:12 -08:00
9a4ab98506 [Jellyfin] Update to 10.11.6 2026-02-03 15:42:41 -08:00
bf0d4a11d2 [nix] Fixes deprecated function usage. 2026-02-02 17:18:04 -08:00
0950758532 [3d printing] Fix FreeCAD launcher 2026-01-27 23:20:31 -08:00
31907ff47b [Haskell] Adds support to the LSP. [neovim] Merges and checks in lazyvim.json 2026-01-26 12:44:23 -08:00
a985e8a0da [Browser,Firefox,Librewolf] Switch back to Firefox as default browser for better sync and features 2026-01-22 10:02:31 -08:00
8add79d14c [flake] Update 2026-01-09 16:19:43 -08:00
93523c54f2 [altair] Cleans up hardware config 2026-01-09 16:15:41 -08:00
c07dfe4259 [neovim] Check in extras config. 2026-01-06 15:29:51 -08:00
978b7ac2b7 [flake] update to 25.11 2026-01-02 12:37:18 -08:00
d1ccaa1c57 [hyprland] Adds a keybind for saving screenshots to files 2026-01-02 12:36:06 -08:00
1c098a032b [neovim] Switch to tab-completion so that I don't get confused when switching editors 2025-12-30 11:10:30 -08:00
b951779a92 [audio] Adds script to inhibit sleep while media is playing. 2025-12-30 11:05:10 -08:00
889d0b1057 [nvim] Adds a commented section about images in markdown docs, though it won't work in Foot tty. 2025-12-20 12:17:00 -08:00
64cac2b167 [printing] Adds Brother printer 2025-12-14 17:26:25 -08:00
2f278b5ecb [nvim] Adds link to do documentation for RenderMarkdown plugin 2025-12-12 12:25:51 -08:00
a0448def04 [desktop] Adds inkscape and groups some similar apps 2025-12-08 16:15:27 -08:00
edb0f18989 [nvim] Updates a few plugins to new versions/repositories 2025-12-08 16:06:55 -08:00
cfde735570 [nvim] Removes copilot 2025-11-21 12:18:06 -08:00
9bbb4aa2dc [astronomy] Added to Altair, removed from Vega 2025-11-21 12:18:06 -08:00
9818771f7c [dm-companion] Fixes deployment script? 2025-11-21 12:09:29 -08:00
f7af96c497 [scrutiny] Switches to UUIDs, removes missing device. 2025-11-21 12:09:29 -08:00
499b0f4334 [astronomy] Adds Stellarium, KStars and Celestia to Vega 2025-10-21 11:58:35 -07:00
879ad11d96 [flake] update 2025-10-19 20:18:27 -07:00
640eaec8a1 [3d printing] Adds Orynt 2025-10-16 20:10:02 -07:00
898e1bdde0 [3d printing] Adds openscad 2025-10-15 17:42:32 -07:00
a6d4c40beb [notes, syncthing] Adds proxima to syncing. 2025-10-14 15:32:00 -07:00
a13e8cea19 [docker dev] Remove rootless mode because some apps (Bambu Studio) do not work in rootless mode 2025-10-07 16:59:44 -07:00
3b8e38e702 [immich] Adds but disabled Immich because it's crashing on start-up 2025-09-25 17:23:01 -07:00
05c001081e [Containers] Adds GPU support for docker 2025-09-22 20:17:01 -07:00
3e2e3aca21 [Flake] Update 2025-09-19 14:50:05 -07:00
1837a545a4 [3d printing] Adds freecad 2025-09-19 14:32:14 -07:00
5c7649d3df [3d printing] Adds slicers, blender 2025-09-16 20:59:34 -07:00
3bb9ebf875 [desktop] Removes QuteBrowser and adds Chromium 2025-09-16 20:59:34 -07:00
ee3b7c2c53 [wow.blazestar.net] Adds static site 2025-09-15 17:08:03 -07:00
746e31dca2 [nextcloud] Move back to a stable version after some bugs 2025-09-15 17:08:03 -07:00
9a59e60044 [nextcloud] Remove unused env vars 2025-09-15 17:08:03 -07:00
646221721e [Tandoor] Adds tandoor service 2025-09-15 17:08:03 -07:00
554b2863f3 [notes] Fixes alias. [discord] Adds skeleton for PTT hotkey passthrough 2025-09-10 12:05:13 -07:00
5829dc294e [Flake] Updates dependencies 2025-09-02 15:18:59 -07:00
0645912626 [hyprctl] Tweaks for Cyberpunk 2025-09-01 17:49:50 -07:00
430a041724 Adds Nexus-Mods app. 2025-09-01 17:48:04 -07:00
80512c29ea [notes] Adds alias for editing notes 2025-08-21 10:32:21 -07:00
392d6fe537 [discord] Attempts to fix the keybinding issue 2025-08-21 10:31:05 -07:00
6d1e715d9c [neovim] Add link-openining to Obsidian 2025-08-18 11:22:44 -07:00
94b8065dba [gaming] Update warcraft logs client 2025-08-15 22:09:02 -07:00
ea902faf43 [neovim] Cleans up some Snacks config 2025-08-03 11:10:49 -07:00
3d3fa1ed68 [eww] Remove launcher I never use. 2025-08-03 10:36:52 -07:00
cd4367e252 [gaming] Updates Raider.io launcher, still doesn't run properly. 2025-08-03 10:36:52 -07:00
cf4d54ebfd [Webkooks] Switches the NPM deploy to rsync the directory instead of link it because docker will follow the link and then not update. 2025-07-31 17:09:56 -07:00
3b46856b66 [Uptime Kuma] Adds Uptime Kuma to blazestar.net 2025-07-31 16:05:15 -07:00
1d1702bd9b [webhook] Updates the NPM install hooks to do a new directory on each deploy. Clean will come later 2025-07-31 15:34:45 -07:00
8a566715db [habits] Removes Beaver Habits because it seems underdeveloped 2025-07-25 13:43:27 -07:00
19d8c5c097 [habits] Adds beaver habits. [oidc] Sets up OIDC auth forwarding, it works, but not sure which header. 2025-07-25 12:22:33 -07:00
b3c6e951ee [mcp] Removes specific kernel packages for ZFS, preferring the default which should be compatible. 2025-07-18 18:11:05 -07:00
44ac6ce262 [shell] Adds fuser util 2025-07-18 18:10:26 -07:00
1c2cd59f1f [web-containers] Adds an explicit service in case we want to have two services. 2025-07-18 17:54:41 -07:00
ca4d4d714c Enables android dev on altair 2025-07-14 15:29:56 -07:00
8791432964 [goatcounter] Fixes instance for blazestar.net 2025-07-14 15:14:13 -07:00
638f34c2d3 [goatcounter] Adds instance for blazestar.net 2025-07-10 15:35:57 -07:00
743ce58b14 [graphics] Modularizes graphics config. Applies it to vega. 2025-07-01 16:13:08 -07:00
0a1d7a24e7 [dm-companion] Fixes deployment script to apply migrations. 2025-06-28 20:21:41 -07:00
81cb09176c [nvim] Use snacks as the primary picker, no relying on extras 2025-06-27 20:31:26 -07:00
7f04c3aa4c [nvim] Remove less from treesitter installed grammars 2025-06-27 20:01:11 -07:00
bded723261 [nix] Updates again because signal isn't building properly on the last version 2025-06-27 18:16:06 -07:00
0776b9d7e5 [eww] Use the correct network interface for Vega 2025-06-27 17:54:53 -07:00
0ac07e4256 Ensure some grammars are installed for treesitter 2025-06-26 17:46:20 -07:00
cedf51580e [dm-companion] Serves index for all unrecognized files, sets some cache directives 2025-06-26 16:32:39 -07:00
1dc7d7b355 [matrix] Got Blazestar.net working, but federation and cross-server joining isn't quite right. 2025-06-25 15:49:25 -07:00
b1510c3670 [containers] Disables some containers, adds some docker config. 2025-06-24 18:32:15 -07:00
f4dd4583db [nix] Modularized the container backend so I can easily switch it with an option 2025-06-24 17:31:30 -07:00
c74e40e69e [nix,flake] Moves some container files around. Also updates the flake lock. [synapse] Gets the federation working 2025-06-24 16:57:38 -07:00
514746686f [matrix] Moves secrets into sops 2025-06-24 14:29:08 -07:00
286701ba83 [blazestar.net] Sets up auto-deploy of an npm-based app. 2025-06-24 14:28:59 -07:00
1bfec397b5 [goatcounter] Adds back the rewrite for count.js 2025-06-22 10:37:49 -07:00
84d05be93b [goatcounter] Removes the special rewrite rules. Leaves them as comments for reference 2025-06-17 16:00:53 -07:00
03b3fe16b1 [goatcounter] Adds goatcounter.terakoda.com 2025-06-17 15:34:18 -07:00
cda32ea550 [dm-companion] Sets up auto-deploy and moves it to terakoda.com 2025-06-15 11:00:50 -07:00
32e10284d0 [desktop] Fixes XDG mime types for default browser 2025-06-11 15:16:46 -07:00
b9c439f5a9 [nvim] Some extra todo states 2025-06-11 15:12:28 -07:00
449662db8c [desktop] Adds gimp 2025-06-11 10:36:42 -07:00
6601377ece [terakoda.com] Moves www2 to the main site. 2025-06-09 16:04:11 -07:00
d432ef8014 [webhook] Switches match rule to just use an IP whitelist. 2025-06-09 16:04:11 -07:00
9acaae9277 [homemanager] Fixes env vars 2025-06-09 15:47:16 -07:00
f46c5948e5 [flake] Update 2025-06-09 10:15:09 -07:00
1d94f2574c [desktop] Set Librewolf as the default browser. 2025-06-08 20:57:13 -07:00
0a64c5cd4b [hypridle] Tweaks timings 2025-06-06 22:07:14 -07:00
2f44b67e9e [nvim] Remove augment plugin 2025-06-04 21:30:17 -07:00
f8378354fb [webhook] Adds webhook for redeploying npm projects 2025-06-04 17:35:31 -07:00
104cd2fd2e [arr] Adds bazarr. 2025-06-03 23:47:43 -07:00
075613c5a5 [ghost] Removes ghost demo. 2025-06-03 15:15:50 -07:00
dd8ec9035e [ghost] Adds ghost demo. 2025-06-03 15:15:28 -07:00
e5861f8e6b [dm-companion] Routes the API through the same host as the frontend 2025-06-03 15:15:28 -07:00
1ae798e30c [swaylock] Increase pixelation to 20 2025-05-30 16:31:16 -07:00
fec3b3a1e2 [oauth-proxy] Making some progress on this. It's not working, but it's now redirecting and getting 'invalid status code' 2025-05-30 10:25:00 -07:00
9411f87dbc [timetagger,traefik] Adds timetagger back, and attempts to put it behind an oauth proxy, but the traefik config isn't quite right. 2025-05-29 17:05:53 -07:00
07123a0fc2 [lock,idle] Fixes the swaylock script to work for multiple monitors and fixes it's invocation 2025-05-29 12:36:03 -07:00
5299c6d72c [shell] Adds mprocs 2025-05-29 10:26:58 -07:00
aa6402cf7c [idle;lock] Switches to swaylock 2025-05-28 12:23:14 -07:00
efab3866c2 [vega] Removes lock because it isn't working. [shell] Fixes aliases 2025-05-28 11:32:36 -07:00
b56d904c4e [vega] Switches back to stable. 2025-05-27 10:23:46 -07:00
fbf475f179 [nvim] Updates obsidian options: better file names 2025-05-27 10:23:10 -07:00
30ad37c30f [shell] Adds lots of little utilities 2025-05-26 20:37:34 -07:00
2253423fc4 [XCompose] Adds greek letters 2025-05-23 10:36:50 -07:00
bfa912f513 [vega] Attempting to fix some audio popping. 2025-05-22 17:36:12 -07:00
7e7ffa6fa7 [nvim,vscode] VSCode/Copilot config 2025-05-22 17:35:46 -07:00
447fe20041 [vega] Moves to unstable to fix issues building hy3 2025-05-21 15:47:13 -07:00
a219966688 [mcp] Updates to 25.05 and adds FreshRSS. Removes Focalboard and Bookstack 2025-05-20 20:21:51 -07:00
f2875caabb [Rofi] Fixes rendering and updates styles 2025-05-20 17:50:59 -07:00
d5bc7c3143 [Hypr] Sets up hypridle. [Nvim] Sets up nix formatting 2025-05-19 15:52:29 -07:00
a5ceae0912 [Rofi] Adds focus-holding in Hyprland 2025-05-19 12:04:34 -07:00
af07210253 [altair] Adds VSCode 2025-05-17 10:38:31 -07:00
f5fd69ab28 Adds more VScode extensions 2025-05-12 19:43:56 -07:00
8796f36a68 [docker] sets the docker socket variable 2025-05-12 17:27:09 -07:00
4caddc6959 [nvim] Re-enables Augment Code 2025-05-12 17:26:52 -07:00
9263d2752f [vscode] Sets up VScode with some extensions on Vega. 2025-05-12 17:26:31 -07:00
23d71b3a09 [nix] Allow unfree for shells. [docker] Correctly export DOCKER_HOST. [nvim] Disable augment and turn on vtsls 2025-05-11 11:21:36 -07:00
945d3aa002 [nvim] Adds augment plugin. 2025-05-10 10:38:25 -07:00
f76969136e [nvim] Maybe finally fixes snacks smart picker 2025-05-09 18:20:44 -07:00
4dc66c25f6 [vega] Adds Zoom app 2025-05-09 18:20:29 -07:00
5e2c997cdc [linux-desktop] Adds a few more apps and reorganizes the config 2025-05-09 18:20:14 -07:00
b1ae2d56fb [markdown] Adds marksman languages server and telescope picker for obsidian 2025-05-09 11:02:11 -07:00
d814aa9465 [shell] Add dysk as alternative to df 2025-05-09 10:31:37 -07:00
bedce7a93c [neovim] Snacks smart-picker config 2025-05-09 10:31:27 -07:00
e2e32fb6cd [hyprland] Re-configure swayidle as a service 2025-05-09 10:31:00 -07:00
aa2cec9f70 [nvim] Improves markdown checkbox experience 2025-05-06 11:25:28 -07:00
2c3ab47daa [vega] Adds slack for business communication 2025-05-05 16:22:05 -07:00
4c9d2e90c3 [neovim] Sets up surround, emoji auto-complete, indentation 2025-05-05 14:29:29 -07:00
8d4febc16f [hyprland] Adds some gaming window rules 2025-05-05 13:14:11 -07:00
69bfb463fe [hyprland] Run eww only once. 2025-05-05 13:07:21 -07:00
73f2bcb362 [Altair] Switches to unstable 2025-05-05 13:05:23 -07:00
0914c02547 [nix] Cleans up warnings about options and reduces duplication 2025-05-05 10:33:00 -07:00
29317386a9 [gaming] Adds protonplus 2025-05-03 16:52:27 -07:00
177e91c658 [hyprland] Moves env to uswm/env as recommended in whe wiki 2025-05-03 16:52:27 -07:00
2643d3801f [development] More TS dev fixes, adds direnv. Fixes some markdown rendering. 2025-05-01 12:19:54 -07:00
8884bd51fd [container-dev] Switch to rootless docker. [nvim] Update snacks options. [hyprland] Use clipboard fixes globally 2025-04-30 14:29:31 -07:00
55bd116fde [wayland] Adds clipboard fix for wine 2025-04-30 10:42:39 -07:00
99da063b14 [eww] Fixes some errors due to missing functions or null values 2025-04-29 17:31:12 -07:00
0a7e176c1e [dev] Sets up podman as a system package instead of homemanager. 2025-04-29 17:31:12 -07:00
db8d2a3a23 [eww] Show only root partition on vega 2025-04-29 17:31:12 -07:00
828750087d [eww] Fixes networking. [swayosd] Removes instances started by hyprland 2025-04-29 17:31:12 -07:00
1153e9086a [eww] Fixes some stuff with the vertical statusbar 2025-04-29 17:31:12 -07:00
e405610baf [mcp] Adds back the user changes I accidentally clobbered. 2025-04-29 13:10:38 -07:00
35a3ec8f7c [vega] Enables running app-images as binaries 2025-04-29 11:45:52 -07:00
39b2c4301c [mcp] Some user setup on the way to automated deployments 2025-04-28 19:31:55 -07:00
3da928a7a8 [mcp] Adds gitea runners 2025-04-28 19:30:27 -07:00
6fd171ae12 [development] Adds more development utils. 2025-04-28 19:28:55 -07:00
58665f6fcb [nvim] Change suggestion keymaps: C-space to suggest, C-enter to accept. 2025-04-27 10:06:40 -07:00
a912dc5b54 [nvim] Cleans up plugins, adds transparency. 2025-04-26 09:40:19 -07:00
36e847d35a [hyprlock] Adds hyprlock config 2025-04-25 15:32:41 -07:00
28e9c221ad [nix] Adds GC 2025-04-25 15:24:33 -07:00
59ae2bd981 [vega;hyprland] Set up only one-monitor workspaces 2025-04-25 15:18:58 -07:00
5b8cc6eb8d [eww] Filters out empty workspaces, again. 2025-04-25 15:16:45 -07:00
8da2bc8cfe [Offen] Sets up offen. 2025-04-25 15:13:40 -07:00
83ca3abf20 [podman] Remove hostname option so that DNS resolves correctly. 2025-04-25 15:13:40 -07:00
4105a6ff38 [gaming] Adds raider.io client 2025-04-24 22:51:27 -07:00
a2f9956824 [vega] Update config; make gui config generic. [nvim] Use Snacks smart finder instead of fzf and avoid race condition 2025-04-24 13:54:05 -07:00
3198414be4 [wpaperd] Update deprecated settings 2025-04-24 11:29:27 -07:00
3a20c72206 [Term] Switches to foot as a terminal 2025-04-24 11:25:43 -07:00
771c3618bc [hyprland] Uses mainline packages, updates config as necessary 2025-04-24 10:57:50 -07:00
5645867776 [hyprland] Adds window resizing 2025-04-24 10:15:42 -07:00
7761067283 [gaming] Adds warcraft logs app. 2025-04-24 10:15:42 -07:00
0367ecd919 [blazestar.net;havenisms.com] Moves them to the new static-site setup 2025-04-23 17:09:05 -07:00
4a49cd3dfe [terakoda.com] Adds page 2025-04-23 17:09:05 -07:00
f59ed4e280 [git] Set default branch to main 2025-04-23 15:58:39 -07:00
e3a0548ca4 [wpaperd] Adds wallpaper rotation 2025-04-23 15:57:59 -07:00
53e29f3911 [eww] Adds workspaces to the vertical statusbar for vega. 2025-04-22 16:19:20 -07:00
c88845ea2a [Focalboard] Sets up Focalboard with storage, database and secrets. [OpenProject] Removes the container 2025-04-21 16:45:27 -07:00
089541916a [vega] Downgrade to 24.11. Switch to mkNixos. 2025-04-21 11:56:55 -07:00
0dbcb541b3 [eww] Remove uninstalled steam game. [nix] adds some comments. 2025-04-20 17:11:44 -07:00
c2a5e0a709 [nix] Messing around with how to override desktop files 2025-04-17 20:03:18 -07:00
828aaa5d40 [gaming] Add launch options for wowup 2025-04-17 13:02:23 -07:00
1afddefdbf [sway] Adds sway as an option, with minimal config 2025-04-17 13:02:23 -07:00
8533f0c9cc [sway] Switches to sway over hyprland 2025-04-17 13:02:23 -07:00
b2b99f12cc [flake] Move MCP back to 24.11 for stability. Probably move the rest soon too. 2025-04-10 16:11:52 -07:00
b0852ad15a [discord] Fix some ozone/wayland stuff 2025-04-09 18:03:02 -07:00
0b013f215e [email] Removes email server. 2025-04-08 16:34:41 -07:00
a468e87d49 [email] WIP 2025-04-08 16:32:19 -07:00
604617f4f4 [email] Adds the verbose env file to the repo 2025-04-07 16:44:47 -07:00
932f78bfe4 [traefik] Moves traefik config into the repo 2025-04-07 15:31:59 -07:00
a0987c0e11 [email] WIP 2025-04-07 13:48:25 -07:00
09329465f5 [hyprland] Removes special fix for wpaperd 2025-04-07 12:26:15 -07:00
0e6505557d [nix] Full system update 2025-04-07 12:26:15 -07:00
7bcb061492 [nvim] Add imagemagick dep for image previews 2025-04-07 11:58:43 -07:00
889ce082f5 [eww] Set proper size on vertical statusbar 2025-04-07 11:58:43 -07:00
ead7739e2d [openproject] Adds openproject 2025-04-03 12:28:49 -07:00
ac8db1d9fd [mcp] Enable linger for drew 2025-04-02 23:05:46 -07:00
c41b295d88 [syncthing] More relay config 2025-04-02 17:44:54 -07:00
b31594b567 [syncthing] Properly configures listen addresses 2025-04-02 11:30:07 -07:00
289406ddf0 [ssh] Adds vega's key. [syncthing] Sets up static config 2025-04-02 11:25:23 -07:00
8711bd8968 [hyprland] Fix wpaperd
rendering of textures on vertical monitors
2025-03-31 18:24:45 -07:00
a17e8c0ec6 [altair] Renames from drew-desktop 2025-03-31 18:19:48 -07:00
a99b91994e [drew-desktop] Switch to wpaperd 2025-03-31 18:16:07 -07:00
bec89ba571 [desktop] Sets up wpaperd to pull wallpaper from monitor-named folders 2025-03-31 17:41:31 -07:00
938dfd49bf [desktop] Declaratively sets dark-mode options 2025-03-31 17:11:45 -07:00
74d939d062 [eww] Fix launcher for bnet 2025-03-31 14:05:11 -07:00
47cf2e3d71 [qmk] Adds QMK support 2025-03-31 14:05:11 -07:00
126 changed files with 4122 additions and 1894 deletions

516
flake.lock generated
View File

@@ -1,76 +1,5 @@
{ {
"nodes": { "nodes": {
"aquamarine": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"hyprwayland-scanner": [
"hyprland",
"hyprwayland-scanner"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1739103745,
"narHash": "sha256-c53dcRaw0F4Os9WD05HwIRs9kTDZw4Mxe1XK4edEALo=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "a3dda0d10ce9aa1d1dfb7a6c139ea8c2872c74bd",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "aquamarine",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"hyprland",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -78,385 +7,41 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1739658904, "lastModified": 1767910483,
"narHash": "sha256-2o/JuD6qD0CtPNVvdPNL3bEDFITaSfSLceajHcIzmw4=", "narHash": "sha256-MOU5YdVu4DVwuT5ztXgQpPuRRBjSjUGIdUzOQr9iQOY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "45c07fcf7d28b5fb3ee189c260dee0a2e4d14317", "rev": "82fb7dedaad83e5e279127a38ef410bcfac6d77c",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "master", "ref": "release-25.11",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
}, },
"hy3": {
"inputs": {
"hyprland": [
"hyprland"
]
},
"locked": {
"lastModified": 1738976400,
"narHash": "sha256-V5akAPMR311XTVtNPalGowcVSlGDGUGj26Bq1cgo76E=",
"owner": "outfoxxed",
"repo": "hy3",
"rev": "833c52e642afbf6a5a95a078580a0fbce118848f",
"type": "github"
},
"original": {
"owner": "outfoxxed",
"repo": "hy3",
"type": "github"
}
},
"hyprcursor": {
"inputs": {
"hyprlang": [
"hyprland",
"hyprlang"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1738664950,
"narHash": "sha256-xIeGNM+iivwVHkv9tHwOqoUP5dDrtees34bbFKKMZYs=",
"owner": "hyprwm",
"repo": "hyprcursor",
"rev": "7c6d165e1eb9045a996551eb9f121b6d1b30adc3",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprcursor",
"type": "github"
}
},
"hyprgraphics": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1739049071,
"narHash": "sha256-3+7TpXMrbsUXSwgr5VAKAnmkzMb6JO+Rvc9XRb5NMg4=",
"owner": "hyprwm",
"repo": "hyprgraphics",
"rev": "175c6b29b6ff82100539e7c4363a35a02c74dd73",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprgraphics",
"type": "github"
}
},
"hyprland": {
"inputs": {
"aquamarine": "aquamarine",
"hyprcursor": "hyprcursor",
"hyprgraphics": "hyprgraphics",
"hyprland-protocols": "hyprland-protocols",
"hyprland-qtutils": "hyprland-qtutils",
"hyprlang": "hyprlang",
"hyprutils": "hyprutils",
"hyprwayland-scanner": "hyprwayland-scanner",
"nixpkgs": [
"nixpkgs"
],
"pre-commit-hooks": "pre-commit-hooks",
"systems": "systems",
"xdph": "xdph"
},
"locked": {
"lastModified": 1739665242,
"narHash": "sha256-iY4DtNDebYHt0uuN0EWWeNQ8K/SYix8KeUe2tcFzW0A=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "897ee276dc0a8a6b11a8102b225a9e969faac0bf",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "Hyprland",
"type": "github"
}
},
"hyprland-protocols": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1738422629,
"narHash": "sha256-5v+bv75wJWvahyM2xcMTSNNxmV8a7hb01Eey5zYnBJw=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "755aef8dab49d0fc4663c715fa4ad221b2aedaed",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-protocols",
"type": "github"
}
},
"hyprland-qt-support": {
"inputs": {
"hyprlang": [
"hyprland",
"hyprland-qtutils",
"hyprlang"
],
"nixpkgs": [
"hyprland",
"hyprland-qtutils",
"nixpkgs"
],
"systems": [
"hyprland",
"hyprland-qtutils",
"systems"
]
},
"locked": {
"lastModified": 1737634706,
"narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=",
"owner": "hyprwm",
"repo": "hyprland-qt-support",
"rev": "8810df502cdee755993cb803eba7b23f189db795",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-qt-support",
"type": "github"
}
},
"hyprland-qtutils": {
"inputs": {
"hyprland-qt-support": "hyprland-qt-support",
"hyprlang": [
"hyprland",
"hyprlang"
],
"hyprutils": [
"hyprland",
"hyprland-qtutils",
"hyprlang",
"hyprutils"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1739048983,
"narHash": "sha256-REhTcXq4qs3B3cCDtLlYDz0GZvmsBSh947Ub6pQWGTQ=",
"owner": "hyprwm",
"repo": "hyprland-qtutils",
"rev": "3504a293c8f8db4127cb0f7cfc1a318ffb4316f8",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-qtutils",
"type": "github"
}
},
"hyprlang": {
"inputs": {
"hyprutils": [
"hyprland",
"hyprutils"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1739048914,
"narHash": "sha256-vd5rJBTmp2w7SDgfv23Zcd84ktI5eDA7e5UBzx+pKrU=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "a7334904d591f38757c46fbe2ab68651877d9099",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprlang",
"type": "github"
}
},
"hyprutils": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1739048933,
"narHash": "sha256-ck6MaoYvISBQKqZR+HcxXnx0wOhyCauxfVMaV5zhJxQ=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "e4e018a2ca6f5a9c33511973454199e1c7c85499",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprutils",
"type": "github"
}
},
"hyprwayland-scanner": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1739049028,
"narHash": "sha256-RleJp7LYbr6s+M1xgbmhtBs+fYa3ZdIiF7+QalJ4D1g=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "04146df74a8d5ec0b579657307be01f1e241125f",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1739548217,
"narHash": "sha256-rlv64erpr36xdmMDPgf9rhRXBYZ0BZb5nrw2ZPSk1sQ=",
"owner": "LnL7",
"repo": "nix-darwin",
"rev": "678b22642abde2ee77ae2218ab41d802f010e5b0",
"type": "github"
},
"original": {
"owner": "LnL7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"nix-filter": {
"locked": {
"lastModified": 1693833173,
"narHash": "sha256-hlMABKrGbEiJD5dwUSfnw1CQ3bG7KKwDV+Nx3bEZd7U=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "ac030bd9ba98e318e1f4c4328d60766ade8ebe8b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-filter",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1739446958, "lastModified": 1767799921,
"narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", "narHash": "sha256-r4GVX+FToWVE2My8VVZH4V0pTIpnu2ZE8/Z4uxGEMBE=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2ff53fe64443980e139eaa286017f53f88336dd0", "rev": "d351d0653aeb7877273920cd3e823994e7579b0b",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nixos",
"ref": "nixos-unstable", "ref": "nixos-25.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1737465171,
"narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"home-manager": "home-manager", "home-manager": "home-manager",
"hy3": "hy3",
"hyprland": "hyprland",
"nix-darwin": "nix-darwin",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"sops-nix": "sops-nix", "sops-nix": "sops-nix"
"split-monitor-workspaces": "split-monitor-workspaces"
} }
}, },
"sops-nix": { "sops-nix": {
@@ -466,11 +51,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1742239755, "lastModified": 1767826491,
"narHash": "sha256-ptn8dR4Uat3UUadGYNnB7CIH9SQm8mK69D2A/twBUXQ=", "narHash": "sha256-WSBENPotD2MIhZwolL6GC9npqgaS5fkM7j07V2i/Ur8=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "787afce414bcce803b605c510b60bf43c11f4b55", "rev": "ea3adcb6d2a000d9a69d0e23cad1f2cacb3a9fbe",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -478,83 +63,6 @@
"repo": "sops-nix", "repo": "sops-nix",
"type": "github" "type": "github"
} }
},
"split-monitor-workspaces": {
"inputs": {
"hyprland": [
"hyprland"
],
"nix-filter": "nix-filter"
},
"locked": {
"lastModified": 1738490537,
"narHash": "sha256-AxrlbJgHb5ECeEDi2qumeR2xeu7sl5AG/ssjdUx33Pg=",
"owner": "Duckonaut",
"repo": "split-monitor-workspaces",
"rev": "917e9ad52e910ffa0ab7d61fecd5a2e3d3f66d87",
"type": "github"
},
"original": {
"owner": "Duckonaut",
"repo": "split-monitor-workspaces",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
},
"xdph": {
"inputs": {
"hyprland-protocols": [
"hyprland",
"hyprland-protocols"
],
"hyprlang": [
"hyprland",
"hyprlang"
],
"hyprutils": [
"hyprland",
"hyprutils"
],
"hyprwayland-scanner": [
"hyprland",
"hyprwayland-scanner"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1737634991,
"narHash": "sha256-dBAnb7Kbnier30cA7AgxVSxxARmxKZ1vHZT33THSIr8=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "e09dfe2726c8008f983e45a0aa1a3b7416aaeb8a",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View File

@@ -2,27 +2,9 @@
description = "System Configuration"; description = "System Configuration";
inputs = { inputs = {
nixpkgs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.11";
url = "github:nixos/nixpkgs?ref=nixos-unstable";
};
home-manager = { home-manager = {
url = "github:nix-community/home-manager/master"; url = "github:nix-community/home-manager?ref=release-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprland = {
url = "github:hyprwm/Hyprland";
inputs.nixpkgs.follows = "nixpkgs";
};
hy3 = {
url = "github:outfoxxed/hy3";
inputs.hyprland.follows = "hyprland";
};
split-monitor-workspaces = {
url = "github:Duckonaut/split-monitor-workspaces";
inputs.hyprland.follows = "hyprland";
};
nix-darwin = {
url = "github:LnL7/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
sops-nix = { sops-nix = {
@@ -32,31 +14,54 @@
}; };
outputs = outputs =
{ self, nixpkgs, ... }@inputs: {
self,
nixpkgs,
...
}@inputs:
let
local = import ./lib;
mkNixosConfig =
{
path,
system ? "x86_64-linux",
nixpkgs ? inputs.nixpkgs,
home-manager ? inputs.home-manager,
}:
nixpkgs.lib.nixosSystem {
inherit system;
modules = [
home-manager.nixosModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = {
inherit inputs local;
};
};
}
path
];
specialArgs = {
inherit inputs local;
};
};
in
{ {
nixosConfigurations = { nixosConfigurations = {
drew-desktop = (import ./system/hosts/drew-desktop) { altair = mkNixosConfig {
inherit inputs; path = ./system/hosts/altair;
inherit self;
inherit nixpkgs;
}; };
mcp = (import ./system/hosts/mcp) { vega = mkNixosConfig {
inherit inputs; path = ./system/hosts/vega;
inherit self;
inherit nixpkgs;
}; };
vega = (import ./system/hosts/vega) { mcp = mkNixosConfig {
inherit inputs; path = ./system/hosts/mcp;
inherit self;
inherit nixpkgs;
}; };
}; };
darwinConfigurations = {
# Removed. See 133a3f82073f03e62cb3e7902c85fb3fc6292fe2 for when the
# last one was removed.
};
features = { features = {
development = (import ./home-manager/features/development/development.nix); development = import ./home-manager/features/development/development.nix;
}; };
}; };
} }

View File

@@ -0,0 +1,18 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
discord
];
xdg.desktopEntries = {
discord = {
name = "Discord";
# Custom options to reduce flickering under wayland.
exec = "env ELECTRON_OZONE_PLATFORM_HINT= discord --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu";
};
};
wayland.windowManager.hyprland.settings.bind = [
# Pass Mouse4 through to discord
# ", mouse:275, pass, class:^discord$"
];
}

View File

@@ -0,0 +1,64 @@
{
pkgs,
...
}:
let
freecad-wrapped = pkgs.symlinkJoin {
name = "freecad-wrapped";
paths = [ pkgs.freecad ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/freecad \
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
'';
};
bambu-studio-wrapped = pkgs.symlinkJoin {
name = "bambu-studio-wrapped";
paths = [ pkgs.bambu-studio ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/bambu-studio \
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
'';
};
in
{
home.packages = with pkgs; [
bambu-studio-wrapped
LycheeSlicer
orca-slicer
blender
freecad-wrapped
openscad
];
xdg.desktopEntries.orynt3d =
let
orynt3d-appimage = pkgs.fetchurl {
name = "orynt3d-appimage";
url = "https://files.orynt3d.com/client/Orynt3D-0.15.3.AppImage";
sha256 = "0j10myj06ff4frsd4yv7z3lb3qgw3ha70hc5hdc9idbryica801y";
};
in
{
name = "Orynt3D";
exec = "env __EGL_VENDOR_LIBRARY_FILENAMES=/run/opengl-driver/share/glvnd/egl_vendor.d/10_nvidia.json ${pkgs.appimage-run}/bin/appimage-run ${orynt3d-appimage}";
terminal = false;
type = "Application";
# icon = "";
comment = "3D model viewer and organizer";
categories = [
"Science"
"Development"
];
};
# Options to get Bambu Studio to run:
# __GLX_VENDOR_LIBRARY_NAME=mesa __EGL_VENDOR_LIBRARY_FILENAMES=/nix/store/js9cfbjvlsls14nddk39fw74vyvlhz4l-mesa-25.0.7/share/glvnd/egl_vendor.d/50_mesa.json MESA_LOADER_DRIVER_OVERRIDE=zink GALLIUM_DRIVER=zink WEBKIT_DISABLE_DMABUF_RENDERER=1 bambu-studio
}

View File

@@ -0,0 +1,8 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
stellarium
kstars
celestia
];
}

View File

@@ -1,7 +1,41 @@
{ pkgs, ... }: { pkgs, ... }:
with pkgs;
let
# A script that runs as long as media is playing.
isMediaPlaying = writeShellApplication {
name = "isMediaPlaying";
runtimeInputs = [
playerctl
];
text = ''
set -e
while [ "$(playerctl status)" = "Playing" ]; do
echo -n "."
sleep 1
done
'';
};
# A script that prevents the system from going to sleep while media is playing
mediaCaffeine = writeShellApplication {
name = "media-caffeine";
runtimeInputs = [
isMediaPlaying
systemd
];
text = ''
set -e
systemd-inhibit --what=sleep --why="Media is playing" --mode=block isMediaPlaying
'';
};
in
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
pulseaudio # for pactl and other tools pulseaudio # for pactl and other tools
pavucontrol # GUI volume control with lots of options pavucontrol # GUI volume control with lots of options
mediaCaffeine
]; ];
} }

View File

@@ -0,0 +1,11 @@
{ pkgs, ... }:
{
imports = [
../apps/element.nix
../apps/discord.nix
];
home.packages = with pkgs; [
signal-desktop
];
}

View File

@@ -1,7 +1,64 @@
include "%L" include "%L"
<Multi_key> <m> <u> : "μ" <Multi_key> <m> <u> : "μ"
<Multi_key> <p> <i> : "π"
<Multi_key> <minus> <comma> : "¬" <Multi_key> <minus> <comma> : "¬"
<Multi_key> <asciicircum> <asciicircum> : "∧" <Multi_key> <asciicircum> <asciicircum> : "∧"
<Multi_key> <v> <v> : "" <Multi_key> <v> <v> : ""
# GREEK CAPITAL LETTERS
<Multi_key> <G> <A> : "Α" U0391 # GREEK CAPITAL LETTER ALPHA
<Multi_key> <G> <B> : "Β" U0392 # GREEK CAPITAL LETTER BETA
<Multi_key> <G> <G> : "Γ" U0393 # GREEK CAPITAL LETTER GAMMA
<Multi_key> <G> <D> : "Δ" U0394 # GREEK CAPITAL LETTER DELTA
<Multi_key> <G> <E> : "Ε" U0395 # GREEK CAPITAL LETTER EPSILON
<Multi_key> <G> <Z> : "Ζ" U0396 # GREEK CAPITAL LETTER ZETA
<Multi_key> <G> <H> : "Η" U0397 # GREEK CAPITAL LETTER ETA
<Multi_key> <G> <I> : "Ι" U0399 # GREEK CAPITAL LETTER IOTA
<Multi_key> <G> <K> : "Κ" U039A # GREEK CAPITAL LETTER KAPPA
<Multi_key> <G> <L> : "Λ" U039B # GREEK CAPITAL LETTER LAMDA
<Multi_key> <G> <M> : "Μ" U039C # GREEK CAPITAL LETTER MU
<Multi_key> <G> <N> : "Ν" U039D # GREEK CAPITAL LETTER NU
<Multi_key> <G> <P> : "Π" U03A0 # GREEK CAPITAL LETTER PI
<Multi_key> <G> <R> : "Ρ" U03A1 # GREEK CAPITAL LETTER RHO
<Multi_key> <G> <S> : "Σ" U03A3 # GREEK CAPITAL LETTER SIGMA
<Multi_key> <G> <T> : "Τ" U03A4 # GREEK CAPITAL LETTER TAU
<Multi_key> <G> <U> : "Υ" U03A5 # GREEK CAPITAL LETTER UPSILON
<Multi_key> <G> <F> : "Φ" U03A6 # GREEK CAPITAL LETTER PHI
<Multi_key> <G> <X> : "Χ" U03A7 # GREEK CAPITAL LETTER CHI
<Multi_key> <G> <O> : "Ω" U03A9 # GREEK CAPITAL LETTER OMEGA
# DOUBLES (additional stroke <Q>)
<Multi_key> <G> <Q> <T> : "Θ" U0398 # GREEK CAPITAL LETTER THETA
<Multi_key> <G> <Q> <O> : "Ο" U039F # GREEK CAPITAL LETTER OMICRON
<Multi_key> <G> <Q> <X> : "Ξ" U039E # GREEK CAPITAL LETTER XI
<Multi_key> <G> <Q> <P> : "Ψ" U03A8 # GREEK CAPITAL LETTER PSI
# greek small letters
<Multi_key> <g> <a> : "α" U03B1 # GREEK SMALL LETTER ALPHA
<Multi_key> <g> <b> : "β" U03B2 # GREEK SMALL LETTER BETA
<Multi_key> <g> <g> : "γ" U03B3 # GREEK SMALL LETTER GAMMA
<Multi_key> <g> <d> : "δ" U03B4 # GREEK SMALL LETTER DELTA
<Multi_key> <g> <e> : "ε" U03B5 # GREEK SMALL LETTER EPSILON
<Multi_key> <g> <z> : "ζ" U03B6 # GREEK SMALL LETTER ZETA
<Multi_key> <g> <h> : "η" U03B7 # GREEK SMALL LETTER ETA
<Multi_key> <g> <i> : "ι" U03B9 # GREEK SMALL LETTER IOTA
<Multi_key> <g> <k> : "κ" U03BA # GREEK SMALL LETTER KAPPA
<Multi_key> <g> <l> : "λ" U03BB # GREEK SMALL LETTER LAMDA
<Multi_key> <g> <m> : "μ" U03BC # GREEK SMALL LETTER MU
<Multi_key> <g> <n> : "ν" U03BD # GREEK SMALL LETTER NU
<Multi_key> <g> <p> : "π" U03C0 # GREEK SMALL LETTER PI
<Multi_key> <g> <r> : "ρ" U03C1 # GREEK SMALL LETTER RHO
<Multi_key> <g> <s> : "σ" U03C3 # GREEK SMALL LETTER SIGMA
<Multi_key> <g> <t> : "τ" U03C4 # GREEK SMALL LETTER TAU
<Multi_key> <g> <u> : "υ" U03C5 # GREEK SMALL LETTER UPSILON
<Multi_key> <g> <f> : "φ" U03C6 # GREEK SMALL LETTER PHI
<Multi_key> <g> <x> : "χ" U03C7 # GREEK SMALL LETTER CHI
<Multi_key> <g> <o> : "ω" U03C9 # GREEK SMALL LETTER OMEGA
# doubles (additional stroke <q>)
<Multi_key> <g> <q> <t> : "θ" U03B8 # GREEK SMALL LETTER THETA
<Multi_key> <g> <q> <o> : "ο" U03BF # GREEK SMALL LETTER OMICRON
<Multi_key> <g> <q> <p> : "ψ" U03C8 # GREEK SMALL LETTER PSI
<Multi_key> <g> <q> <s> : "ς" U03C2 # GREEK SMALL LETTER FINAL SIGMA
<Multi_key> <g> <q> <x> : "ξ" U03BE # GREEK SMALL LETTER X

View File

@@ -10,10 +10,17 @@
# Base languages that should always be available # Base languages that should always be available
./nix.nix ./nix.nix
./lua.nix ./lua.nix
./sh.nix
]; ];
home.packages = with pkgs; [ home.packages = with pkgs; [
# Dev helpers hyperfine # Benchmarking tool
direnv
]; ];
programs.direnv = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
nix-direnv.enable = true;
};
} }

View File

@@ -0,0 +1,6 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
docker-compose
];
}

View File

@@ -0,0 +1,7 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
markdownlint-cli2 # linter
marksman # language server
];
}

View File

@@ -6,11 +6,12 @@
nixfmt-rfc-style # Formatter nixfmt-rfc-style # Formatter
nil # Language Server nil # Language Server
statix # Lints and suggestions for Nix
]; ];
home.shellAliases = { home.shellAliases = {
# This assumes that the repository is in ~/system-config # This assumes that the repository is in ~/system-config
rebuild = "sudo nixos-rebuild switch --flake ~/system-config --show-trace --print-build-logs --verbose"; rebuild-switch = "sudo nixos-rebuild switch --flake ~/system-config --show-trace --print-build-logs --verbose";
rebuild-boot = "sudo nixos-rebuild boot --flake ~/system-config --show-trace --print-build-logs --verbose";
}; };
} }

View File

@@ -0,0 +1,6 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
shfmt # Formatter
];
}

View File

@@ -0,0 +1,9 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
vtsls # Language Server
eslint # Linter
nodePackages.prettier # Formatter
tailwindcss-language-server # Language server for tailwind CSS
];
}

View File

@@ -0,0 +1,20 @@
{ pkgs, ... }:
{
programs.vscode = {
enable = true;
extensions = with pkgs.vscode-extensions; [
asvetliakov.vscode-neovim # Use embedded neovim editor
enkia.tokyo-night # Color theme
eamodio.gitlens # Show git info inline
mechatroner.rainbow-csv # Make it easier to read CSV files
aaron-bond.better-comments # Provides some highlighting in comments
# Typescript
esbenp.prettier-vscode # Auto-formatting
# AI Agents
github.copilot
];
};
}

View File

@@ -33,6 +33,16 @@ $color-standout-dark: darker($color-standout);
font-family: 'Noto Sans Nerd Font', sans-serif; font-family: 'Noto Sans Nerd Font', sans-serif;
} }
window.vertical-statusbar {
background-color: $color-background;
// background-image: linear-gradient(160deg, rgba(255,00,00,0.5), $color-background);
color: $color-foreground;
padding: 16px;
font-size: 14px;
border-right: 3px solid $color-border;
font-family: 'Noto Sans Nerd Font', sans-serif;
}
.system-monitor { .system-monitor {
padding-top: 8px; padding-top: 8px;
padding-right: 8px; padding-right: 8px;

View File

@@ -3,5 +3,4 @@
(include "./primary-statusbar.yuck") (include "./primary-statusbar.yuck")
(include "./secondary-statusbar.yuck") (include "./secondary-statusbar.yuck")
(include "./system-monitor.yuck") (include "./system-monitor.yuck")
(include "./launcher.yuck")
(include "./vertical-statusbar.yuck") (include "./vertical-statusbar.yuck")

View File

@@ -1,82 +0,0 @@
(defwindow launcher
:monitor '[ "<primary>", "DP-2", 0 ]'
:geometry (geometry
:x "100px"
:y "100px"
:anchor "top left"
)
:stacking "bottom"
:exclusive false
:focusable false
(box
:class "launcher-window stand-alone"
:orientation "v"
:spacing 4
:visible { arraylength(jq(workspaces-json-dp2, "map(select(.active and (.has_windows | not)))")) > 0 }
(box
:orientation "v"
:halign "start"
:spacing 4
:space-evenly false
(label
:text "Apps"
:halign "start"
)
(box
:orientation "h"
:halign "start"
:spacing 4
:space-evenly false
(button
:onclick "firefox"
(image
:class "launcher-icon"
:icon "firefox"
:icon-size "dialog"
)
)
)
)
(box
:orientation "v"
:halign "start"
:spacing 4
:space-evenly false
(label
:text "Games"
:halign "start"
)
(box
:orientation "h"
:halign "start"
:spacing 4
:space-evenly false
(button
;; :onclick "env LUTRIS_SKIP_INIT=1 lutris lutris:rungameid/1"
:onclick "notify-send 'Launching Lutris' && env LUTRIS_SKIP_INIT=1 lutris lutris:rungameid/1"
(image
:class "launcher-icon"
:image-width 48
:path "/home/drew/.local/share/icons/hicolor/128x128/apps/lutris_battlenet.png"
)
)
(button
:onclick "steam steam://rungameid/1091500"
(image
:class "launcher-icon"
:icon "steam_icon_1091500"
:icon-size "dialog"
)
)
;; (button
;; :onclick "steam steam://rungameid/1145350"
;; (image
;; :class "launcher-icon"
;; :icon "steam_icon_1145350"
;; :icon-size "dialog"
;; )
;;)
)
)
)
)

View File

@@ -30,7 +30,7 @@
) )
(defwindow primary-statusbar (defwindow primary-statusbar
:monitor '[ "<primary>", "DP-2", 0 ]' :monitor '[ "<primary>", "DP-2", 1 ]'
:geometry (geometry :geometry (geometry
:x "0%" :x "0%"
:y "0%" :y "0%"

View File

@@ -47,7 +47,7 @@
) )
(defwindow secondary-statusbar (defwindow secondary-statusbar
:monitor '[ "<secondary>", "DP-1" ]' :monitor '[ "<secondary>", "DP-1", "0" ]'
:geometry (geometry :geometry (geometry
:x "0px" :x "0px"
:y "0px" :y "0px"

View File

@@ -30,7 +30,7 @@
:spacing 8 :spacing 8
(system-monitor-perf) (system-monitor-perf)
(system-monitor-disks) (system-monitor-disks)
(system-monitor-net) (system-monitor-net :interface "wlo1")
) )
(box (box
:orientation "h" :orientation "h"
@@ -145,13 +145,13 @@
:name "Disks" :name "Disks"
(system-monitor-gauge (system-monitor-gauge
:name "Root" :name "Root"
:text-value {EWW_DISK['/'].free / powi(2, 30)} :text-value {EWW_DISK['/'].free / 1000000000}
:gauge-pct {EWW_DISK['/'].used_perc} :gauge-pct {EWW_DISK['/'].used_perc}
:units " GB" :units " GB"
) )
(system-monitor-gauge (system-monitor-gauge
:name "Home" :name "Home"
:text-value {EWW_DISK['/home'].free / powi(2, 30)} :text-value {EWW_DISK['/home'].free / 1000000000}
:gauge-pct {EWW_DISK['/home'].used_perc} :gauge-pct {EWW_DISK['/home'].used_perc}
:units " GB" :units " GB"
) )
@@ -164,7 +164,7 @@
`iwgetid -r` `iwgetid -r`
) )
(defwidget system-monitor-net [] (defwidget system-monitor-net [ interface ]
(system-monitor-group (system-monitor-group
:name "Network" :name "Network"
:orientation "v" :orientation "v"
@@ -174,12 +174,12 @@
) )
(system-monitor-sparkgraph (system-monitor-sparkgraph
:name "Down" :name "Down"
:value {EWW_NET["wlo1"]["NET_DOWN"] / 1000000} :value {EWW_NET[interface]["NET_DOWN"] / 1000000}
:units " MB/s" :units " MB/s"
) )
(system-monitor-sparkgraph (system-monitor-sparkgraph
:name "Up" :name "Up"
:value {EWW_NET["wlo1"]["NET_UP"] / 1000000} :value {EWW_NET[interface]["NET_UP"] / 1000000}
:units " MB/s" :units " MB/s"
) )
) )

View File

@@ -8,13 +8,35 @@
) )
) )
(deflisten workspaces-json-hdmi-a-1
:initial "[]"
`~/.config/eww/scripts/workspaces.sh HDMI-A-1`
)
(defwidget workspaces-vega []
(workspaces :workspaces-json workspaces-json-hdmi-a-1)
)
(defwidget disks-vega []
(system-monitor-group
:name "Disks"
(system-monitor-gauge
:name "Root"
:text-value {EWW_DISK['/'].free / 1000000000}
:gauge-pct {EWW_DISK['/'].used_perc}
:units " GB"
)
)
)
(defwidget vertical-statusbar [] (defwidget vertical-statusbar []
(box (box
:class "statusbar"
:orientation "v" :orientation "v"
:halign "fill"
:spacing 8 :spacing 8
:space-evenly false :space-evenly false
(clock-large) (clock-large)
(workspaces-vega)
(vertical-statusbar-systray) (vertical-statusbar-systray)
(system-monitor-group (system-monitor-group
:name "Performance" :name "Performance"
@@ -22,8 +44,8 @@
(system-monitor-perf-cpu) (system-monitor-perf-cpu)
(system-monitor-perf-gpu) (system-monitor-perf-gpu)
) )
(system-monitor-disks) (disks-vega)
(system-monitor-net) (system-monitor-net :interface "wlp5s0")
(system-monitor-audio) (system-monitor-audio)
) )
) )
@@ -36,7 +58,7 @@
:geometry (geometry :geometry (geometry
:x "0%" :x "0%"
:y "0%" :y "0%"
:width "60px" :width "250px"
:height "100%" :height "100%"
:anchor "center left" :anchor "center left"
) )

View File

@@ -1,5 +1,13 @@
{ ... }: { pkgs, ... }:
{ {
home.packages = with pkgs; [
# For Noto Sans NF
# 25.05
nerd-fonts.noto
# 24.11
# (nerdfonts.override { fonts = [ "NotoSans" ]; })
];
programs.eww = { programs.eww = {
enable = true; enable = true;
configDir = ./config; configDir = ./config;

View File

@@ -1,4 +1,40 @@
{ pkgs, ... }: { pkgs, local, ... }:
let
# TODO: This is an attempt to patch the desktop file by actually using the old
# one so I don't have to put in all the options like below. This will generate
# the correct file, however, xdg.dataFile."applications/wowup-cf.desktop"
# doesn't seem to actually overrwite it, even with force = true.
# patched-desktop =
# pkgs.runCommand "patched-wowup-cf-desktop"
# {
# desktop = "${pkgs.wowup-cf}/share/applications/wowup-cf.desktop";
# }
# ''
# mkdir -p $out
# substitute "$desktop" "$out/wowup-cf.desktop" \
# --replace-fail 'Exec=wowup-cf' 'Exec=wowup-cf --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu'
# '';
warcraftLogsUploader = pkgs.fetchurl {
name = "warcraftlogs-client";
url = "https://github.com/RPGLogs/Uploaders-warcraftlogs/releases/download/v8.17.47/warcraftlogs-v8.17.47.AppImage";
sha256 = "1aypr3ffy6lq0qj64d48c7n54nfs72404xb2kpxsw5slqh66imw6";
};
warcraftLogsIcon = pkgs.fetchurl {
name = "warcraftlogs-icon";
url = "https://assets.rpglogs.com/img/warcraft/favicon.png";
sha256 = "0hil7rj7a0bmls0h4w3xmfzcp1gm5yfagbziv1967lmy70ri0bc9";
};
raiderioClient = pkgs.fetchurl {
name = "raiderio-client";
url = "https://raider.io/client/download/linux";
sha256 = "0wcw53bgr9dr02x1ci2jlnc5irpiqxqxgs2hpbrsnj67q50nvlm9";
};
raiderioIcon = pkgs.fetchurl {
name = "raiderio-icon";
url = "https://cdn.raiderio.net/images/brand/Mark_2ColorWhite.png";
sha256 = "13311vi04lv6bp7jvnhinbcfah4ghn9h85cl3wzysz3aaxs73988";
};
in
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
# Gaming # Gaming
@@ -10,9 +46,74 @@
]; ];
}) })
protonup-ng protonup-ng
protonplus
protontricks
vulkan-tools # useful for debugging Vulkan issues vulkan-tools # useful for debugging Vulkan issues
# WoW addon updater # WoW addon updater
wowup-cf wowup-cf
# Nexus Mod Manager
nexusmods-app-unfree
];
# xdg.dataFile."applications/wowup-cf.desktop" = {
# force = true;
# source = "${patched-desktop}/wowup-cf.desktop";
# };
# wowup needs options to work under wayland.
xdg.desktopEntries.wowup-cf = local.electronDesktopEntry {
name = "WowUp";
exec = "wowup-cf --no-sandbox";
terminal = false;
type = "Application";
icon = "wowup-cf";
comment = "World of Warcraft addon updater";
categories = [
"Game"
];
};
xdg.desktopEntries.warcraftLogs = {
name = "WarcraftLogs";
exec = "${pkgs.appimage-run}/bin/appimage-run ${warcraftLogsUploader}";
terminal = false;
type = "Application";
icon = "${warcraftLogsIcon}";
comment = "WarcraftLogs uploader";
categories = [ "Game" ];
};
xdg.desktopEntries.raiderio = {
name = "Raider.io";
exec = "${pkgs.appimage-run}/bin/appimage-run ${raiderioClient}";
terminal = false;
type = "Application";
icon = "${raiderioIcon}";
comment = "Raider.io Client";
categories = [ "Game" ];
};
wayland.windowManager.hyprland.settings.windowrulev2 = [
# Set up full-screen games on monitor 1 (since window 0 is the vertical one.)
"monitor 1,class:^steam_app_\d+$"
"float,class:^steam_app_\d+$"
"monitor 1,fullscreen:1"
"center,class:^steam_app_\d+$"
# Make sure WoW spawns on the right monitor and that Battlenet floats so it renders correctly
"monitor 1,title:^World of Warcraft$"
"fullscreen,title:^World of Warcraft$"
"monitor 1,title:^Battle.net$"
"float,title:^Battle.net$"
# Make Balatro into a regular window.
"monitor 1,title:^Balatro$"
"tile,title:^Balatro$"
# Load Cyberpunk 2077 on the right monitor.
"monitor 1,class:steam_app_1091500"
"fullscreen,class:steam_app_1091500"
]; ];
} }

View File

@@ -12,15 +12,17 @@
"l" = "log --oneline"; "l" = "log --oneline";
}; };
extraConfig = { extraConfig = {
core = {
pager = "";
};
pull = { pull = {
rebase = true; rebase = true;
}; };
log = { log = {
date = "iso"; date = "iso";
}; };
init = {
defaultBranch = "main";
}; };
}; };
# Enable the delta diff pager.
delta.enable = true;
};
} }

View File

@@ -0,0 +1,34 @@
{ ... }:
{
services.hypridle = {
enable = true;
settings = {
general = {
lock_cmd = "pidof swaylock || ~/.config/swaylock/swaylock.sh"; # avoid starting multiple lock instances.
before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
};
listener = [
{
timeout = 300; # 5min
on-timeout = "brightnessctl -s set 10"; # set monitor backlight to minimum, avoid 0 on OLED monitor.
on-resume = "brightnessctl -r"; # monitor backlight restore.
}
{
timeout = 330; # 5.5 min
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
}
{
timeout = 600; # 10 min
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
on-resume = "hyprctl dispatch dpms on && brightnessctl -r"; # screen on when activity is detected after timeout has fired.
}
{
timeout = 1800; # 30min
on-timeout = "systemctl suspend"; # suspend pc
}
];
};
};
}

View File

@@ -1,10 +1,28 @@
{ pkgs, inputs, ... }: { pkgs, ... }:
{ {
imports = [
./swaylock.nix
./hypr/hypridle.nix
];
home.packages = with pkgs; [
swayosd # volume pop-up
swaynotificationcenter # notifications
hyprpolkitagent # Privilege managent
hyprshot # Screenshot utility
# For clipboard management. See below.
wl-clipboard
xclip
];
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
plugins = [ plugins = [
inputs.hy3.packages.${pkgs.system}.hy3 # https://github.com/outfoxxed/hy3
inputs.split-monitor-workspaces.packages.${pkgs.system}.split-monitor-workspaces pkgs.hyprlandPlugins.hy3
# https://github.com/shezdy/hyprsplit
pkgs.hyprlandPlugins.hyprsplit
]; ];
# Disable systemd because it conflicts with UWSM # Disable systemd because it conflicts with UWSM
@@ -16,31 +34,22 @@
"DP-1, 2560x1440, -1440x-510, 1, transform, 1" "DP-1, 2560x1440, -1440x-510, 1, transform, 1"
]; ];
"$terminal" = "wezterm"; "$terminal" = "foot";
"$fileManager" = "dolphin";
"$menu" = "rofi -show combi -combi-modes drun,ssh,run -theme ~/.config/rofi/launcher/style.rasi"; "$menu" = "rofi -show combi -combi-modes drun,ssh,run -theme ~/.config/rofi/launcher/style.rasi";
"$browser" = "firefox"; "$browser" = "firefox --new-window";
exec-once = [ exec-once = [
"nm-applet" "nm-applet"
"sleep 2 && hyprpm reload -n" "sleep 2 && hyprpm reload -n"
"swayidle -w before-sleep hyprlock"
"swayosd-server"
"systemctl --user start hyprpolkitagent" "systemctl --user start hyprpolkitagent"
];
env = [ "gsettings set org.gnome.desktop.interface color-scheme \"prefer-dark\""
"XCURSOR_SIZE,32" "gsettings set org.gnome.desktop.interface gtk-theme \"Adwaita-dark\""
"HYPRCURSOR_SIZE,32" # Hyprland doesn't paste into Firefox or Wine apps. This program is a workaround.
"HYPRCURSOR_THEME,phinger" # See https://github.com/hyprwm/Hyprland/issues/2319
# -t text = Only handle text
# Nvidia config # -w xclip -selection clipboard = Watch for events and invoke xclip
"LIBVA_DRIVER_NAME,nvidia" "wl-paste -t text -w xclip -selection clipboard"
"__GLX_VENDOR_LIBRARY_NAME,nvidia"
# For window theming
"QT_QPA_PLATFORMTHEME,qt6ct # for Qt apps"
"GTK_THEME,Adwaita-dark"
]; ];
general = { general = {
@@ -54,7 +63,7 @@
"col.inactive_border" = "rgba(595959aa)"; "col.inactive_border" = "rgba(595959aa)";
# Set to true enable resizing windows by clicking and dragging on borders and gaps # Set to true enable resizing windows by clicking and dragging on borders and gaps
resize_on_border = false; resize_on_border = true;
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
allow_tearing = false; allow_tearing = false;
@@ -232,12 +241,9 @@
}; };
}; };
split-monitor-workspaces = { hyprsplit = {
# Keep the focus when reloading. num_workspaces = 10;
keep_focused = true; persistent_workspaces = true;
# Allocate persistent workspaces. If this is off there are some bugs
# when trying to move to a new workspace if it doesn't already exist.
enable_persistent_workspaces = true;
}; };
}; };
@@ -280,8 +286,8 @@
"$mainMod, T, exec, $terminal" "$mainMod, T, exec, $terminal"
"$mainMod, B, exec, $browser" "$mainMod, B, exec, $browser"
"$mainMod, D, exec, $menu" "$mainMod, D, exec, $menu"
"$mainMod, E, exec, $fileManager"
"$mainMod + SHIFT, S, exec, hyprshot -m region --clipboard-only" "$mainMod + SHIFT, S, exec, hyprshot -m region --clipboard-only"
"$mainMod + CTRL + SHIFT, S, exec, hyprshot -m region -o ~/Pictures"
"$mainMod, C, exec, swaync-client -t" "$mainMod, C, exec, swaync-client -t"
"$mainMod + L_CONTROL, Q, exec, /home/drew/.config/rofi/powermenu/powermenu.sh" "$mainMod + L_CONTROL, Q, exec, /home/drew/.config/rofi/powermenu/powermenu.sh"
@@ -291,6 +297,10 @@
"$mainMod, F, togglefloating," "$mainMod, F, togglefloating,"
"$mainMod + SHIFT, F, fullscreen, 1" "$mainMod + SHIFT, F, fullscreen, 1"
"$mainMod + CTRL, left, resizeactive, -20 0"
"$mainMod + CTRL, right, resizeactive, 20 0"
"$mainMod + CTRL, down, resizeactive, 0 20"
"$mainMod + CTRL, up, resizeactive, 0 -20"
# Monitors # Monitors
"$mainMod, R, focusmonitor, next" "$mainMod, R, focusmonitor, next"
@@ -302,42 +312,46 @@
"$mainMod, G, hy3:makegroup, opposite, ephemeral" "$mainMod, G, hy3:makegroup, opposite, ephemeral"
"$mainMod, W, hy3:makegroup, tab, ephemeral" "$mainMod, W, hy3:makegroup, tab, ephemeral"
"$mainMod + SHIFT, W, hy3:changegroup, toggletab" "$mainMod + SHIFT, W, hy3:changegroup, toggletab"
"$mainMod, A, hy3:changefocus, raise"
"$mainMod, Z, hy3:changefocus, lower"
"$mainMod, O, hy3:changegroup, opposite" "$mainMod, O, hy3:changegroup, opposite"
"$mainMod, left, hy3:movefocus, l" "$mainMod, left, hy3:movefocus, l"
"$mainMod, right, hy3:movefocus, r" "$mainMod, right, hy3:movefocus, r"
"$mainMod, up, hy3:movefocus, u" "$mainMod, up, hy3:movefocus, u"
"$mainMod, down, hy3:movefocus, d" "$mainMod, down, hy3:movefocus, d"
"$mainMod, A, hy3:changefocus, raise" "$mainMod, r, focusmonitor, l"
"$mainMod, Z, hy3:changefocus, lower" "$mainMod, s, focusmonitor, r"
"$mainMod + SHIFT, left, hy3:movewindow, l" "$mainMod + SHIFT, left, hy3:movewindow, l"
"$mainMod + SHIFT, right, hy3:movewindow, r" "$mainMod + SHIFT, right, hy3:movewindow, r"
"$mainMod + SHIFT, up, hy3:movewindow, u" "$mainMod + SHIFT, up, hy3:movewindow, u"
"$mainMod + SHIFT, down, hy3:movewindow, d" "$mainMod + SHIFT, down, hy3:movewindow, d"
# Switch workspaces with mainMod + [0-9] # Switch workspaces with mainMod + [0-9]
"$mainMod, 1, split-workspace, 1" "$mainMod, 1, split:workspace, 1"
"$mainMod, 2, split-workspace, 2" "$mainMod, 2, split:workspace, 2"
"$mainMod, 3, split-workspace, 3" "$mainMod, 3, split:workspace, 3"
"$mainMod, 4, split-workspace, 4" "$mainMod, 4, split:workspace, 4"
"$mainMod, 5, split-workspace, 5" "$mainMod, 5, split:workspace, 5"
"$mainMod, 6, split-workspace, 6" "$mainMod, 6, split:workspace, 6"
"$mainMod, 7, split-workspace, 7" "$mainMod, 7, split:workspace, 7"
"$mainMod, 8, split-workspace, 8" "$mainMod, 8, split:workspace, 8"
"$mainMod, 9, split-workspace, 9" "$mainMod, 9, split:workspace, 9"
"$mainMod, 0, split-workspace, 10" "$mainMod, 0, split:workspace, 10"
# Move active window to a workspace with mainMod + SHIFT + [0-9] # Move active window to a workspace with mainMod + SHIFT + [0-9]
"$mainMod SHIFT, 1, split-movetoworkspace, 1, follow" # Note: using hy3:movetoworkspace instead of split:movetoworkspace.
"$mainMod SHIFT, 2, split-movetoworkspace, 2, follow" # The plugins are compatible.
"$mainMod SHIFT, 3, split-movetoworkspace, 3, follow" "$mainMod SHIFT, 1, hy3:movetoworkspace, 1, follow"
"$mainMod SHIFT, 4, split-movetoworkspace, 4, follow" "$mainMod SHIFT, 2, hy3:movetoworkspace, 2, follow"
"$mainMod SHIFT, 5, split-movetoworkspace, 5, follow" "$mainMod SHIFT, 3, hy3:movetoworkspace, 3, follow"
"$mainMod SHIFT, 6, split-movetoworkspace, 6, follow" "$mainMod SHIFT, 4, hy3:movetoworkspace, 4, follow"
"$mainMod SHIFT, 7, split-movetoworkspace, 7, follow" "$mainMod SHIFT, 5, hy3:movetoworkspace, 5, follow"
"$mainMod SHIFT, 8, split-movetoworkspace, 8, follow" "$mainMod SHIFT, 6, hy3:movetoworkspace, 6, follow"
"$mainMod SHIFT, 9, split-movetoworkspace, 9, follow" "$mainMod SHIFT, 7, hy3:movetoworkspace, 7, follow"
"$mainMod SHIFT, 0, split-movetoworkspace, 10, follow" "$mainMod SHIFT, 8, hy3:movetoworkspace, 8, follow"
"$mainMod SHIFT, 9, hy3:movetoworkspace, 9, follow"
"$mainMod SHIFT, 0, hy3:movetoworkspace, 10, follow"
# These don't take monitor numbers, but rather differences. It's next/prev but # These don't take monitor numbers, but rather differences. It's next/prev but
# it'll always just move it to the other monitor # it'll always just move it to the other monitor
"$mainMod SHIFT, r, split-changemonitor, prev" "$mainMod SHIFT, r, movewindow, mon:+1"
]; ];
# m = mouse bindings # m = mouse bindings
@@ -385,31 +399,101 @@
"opaque,class:(),title:()" "opaque,class:(),title:()"
"noshadow,class:(),title:()" "noshadow,class:(),title:()"
"noblur,class:(),title:()" "noblur,class:(),title:()"
# Set up full-screen games on monitor 1
"monitor 1,class:^steam_app_\d+$"
"float,class:^steam_app_\d+$"
"monitor 1,fullscreen:1"
"center,class:^steam_app_\d+$"
"monitor 1,title:^World of Warcraft$"
"monitor 1,title:^Battle.net$"
"float,title:^Battle.net$"
]; ];
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules # See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
workspace = [ workspace = [
"11, defaultName:1" "1, defaultName:L1"
"12, defaultName:2" "2, defaultName:L2"
"13, defaultName:3" "3, defaultName:L3"
"14, defaultName:4" "4, defaultName:L4"
"15, defaultName:5" "5, defaultName:L5"
"16, defaultName:6" "6, defaultName:L6"
"17, defaultName:7" "7, defaultName:L7"
"18, defaultName:8" "8, defaultName:L8"
"19, defaultName:9" "9, defaultName:L9"
"20, defaultName:10" "10, defaultName:L10"
"11, defaultName:R1"
"12, defaultName:R2"
"13, defaultName:R3"
"14, defaultName:R4"
"15, defaultName:R5"
"16, defaultName:R6"
"17, defaultName:R7"
"18, defaultName:R8"
"19, defaultName:R9"
"20, defaultName:R10"
]; ];
}; };
}; };
programs.hyprlock = {
enable = false;
settings = {
general = {
disable_loading_bar = true;
hide_cursor = true;
};
background = {
monitor = "";
color = "rgb(000000)";
};
# Time
label = {
monitor = "";
text = ''
cmd[update:1000] echo "$(date '+%F %T')"
'';
font_size = 96;
font_family = "NotoSans Nerd Font";
color = "rgb(990000)";
position = "0, 0";
halign = "center";
valign = "center";
};
input-field = {
monitor = "";
size = "300, 40";
fade_on_empty = true;
outline_thickness = 2;
outer_color = "rgb(cc2222) rgb(661111)";
inner_color = "rgb(221111)";
font_color = "rgb(cc2222)";
dots_size = 0.2;
dots_spacing = 0.1;
placeholder_text = "";
fail_color = "rgb(cc3333)";
capslock_color = "rgb(cccc33)";
halign = "center";
valign = "center";
position = "0, -300px";
};
};
};
# UWSM sessions should not use Hyprland's variables but instead use UWSM's variable management.
# See https://wiki.hyprland.org/Configuring/Environment-variables/
home.file.".config/uwsm/env".text = ''
export XCURSOR_SIZE="32"
export HYPRCURSOR_SIZE="32"
export HYPRCURSOR_THEME="phinger"
# Nvidia config
export LIBVA_DRIVER_NAME="nvidia"
export __GLX_VENDOR_LIBRARY_NAME="nvidia"
# For window theming
export QT_QPA_PLATFORMTHEME="qt6ct # for Qt apps"
export GTK_THEME="Adwaita-dark"
# Tell electron apps they should use OZone for Wayland
export ELECTRON_OZONE_PLATFORM_HINT="auto"
'';
} }

View File

@@ -1,28 +0,0 @@
{ ... }:
{
services.hyprpaper = {
enable = true;
settings =
let
clouds1 = "/home/drew/Pictures/Wallpaper/2025-02-18 - Haleakela Clouds.jpg";
clouds2 = "/home/drew/Pictures/Wallpaper/2025-02-18 - Haleakela Clouds 2.jpg";
sunset_wide = "/home/drew/Pictures/Wallpaper/2025-02-19 - Hawaii Sunset.jpg";
sunset_tall = "/home/drew/Pictures/Wallpaper/2025-02-20 - Hawaii Sunset - Tall.jpg";
in
{
ipc = "on";
splash = false;
preload = [
clouds1
clouds2
sunset_wide
sunset_tall
];
wallpaper = [
"DP-2,${clouds1}"
"DP-1,${sunset_tall}"
];
};
};
}

View File

@@ -0,0 +1,7 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
gimp3
inkscape
];
}

View File

@@ -1,43 +1,58 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
imports = [ imports = [
./hyprland.nix
./hyprpaper.nix
./audio.nix ./audio.nix
./nix.nix ./hyprland.nix
./rofi/rofi.nix ./rofi/rofi.nix
./sway.nix
../apps/element.nix ../apps/element.nix
../apps/discord.nix
./terminal.nix ./terminal.nix
]; ];
home.packages = with pkgs; [ home = {
packages = with pkgs; [
# Desktop Applications
gimp3
# Common utilities
feh feh
networkmanagerapplet # network control networkmanagerapplet # network control
hyprlock # lock screen
swayidle # lock on idle
swayosd # volume pop-up
swaynotificationcenter # notifications
hyprpolkitagent # Privilege managent
gnome-keyring # Secret management gnome-keyring # Secret management
glib # for Gnome/GTK settings glib # for Gnome/GTK settings
gsettings-desktop-schemas # So that we can access gnome settings
xdg-desktop-portal-hyprland xdg-desktop-portal-hyprland
xdg-desktop-portal-gtk # GTK backend for XDG components like pickers xdg-desktop-portal-gtk # GTK backend for XDG components like pickers
grim # Screenshot provider grim # Screenshot provider
hyprshot # Screenshot utility
nwg-look # GTK settings editor nwg-look # GTK settings editor
playerctl # for universal play/pause etc playerctl # for universal play/pause etc
wirelesstools wirelesstools
waypaper # Wallpaper switcher waypaper # Wallpaper switcher
phinger-cursors # Mouse cursors
]; ];
# Hint for electron apps to use wayland pointerCursor = {
home.sessionVariables.NIXOS_OZONE_WL = "1"; enable = true;
gtk.enable = true;
name = "phinger-cursors";
size = 16;
package = pkgs.phinger-cursors;
};
# Micelaneious config files # Hint for electron apps to use wayland
home.file = { sessionVariables.NIXOS_OZONE_WL = "1";
# Miscelaneous config files
file = {
".XCompose".source = ./config/XCompose; ".XCompose".source = ./config/XCompose;
}; };
};
programs = {
# browsers
firefox.enable = true;
librewolf.enable = true;
chromium.enable = true;
};
# GTK settings # GTK settings
gtk = { gtk = {
@@ -54,10 +69,32 @@
}; };
}; };
# This is where the real magic happens to tell the applications to prefer
# dark mode. For example, Element reads from this setting.
dconf.settings = {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
};
# QT theming # QT theming
qt = { qt = {
enable = true; enable = true;
platformTheme.name = "adwaita"; platformTheme.name = "adwaita";
style.name = "adwaita-dark"; style.name = "adwaita-dark";
}; };
# Default apps
xdg.mimeApps = {
enable = true;
defaultApplications = {
"text/html" = [ "firefox.desktop" ];
"default-web-browser" = [ "firefox.desktop" ];
"x-scheme-handler/http" = [ "firefox.desktop" ];
"x-scheme-handler/https" = [ "firefox.desktop" ];
"x-scheme-handler/about" = [ "firefox.desktop" ];
"x-scheme-handler/unknown" = [ "firefox.desktop" ];
};
};
home.sessionVariables.DEFAULT_BROWSER = "${pkgs.firefox}/bin/firefox";
} }

View File

@@ -0,0 +1,18 @@
{
"extras": [
"lazyvim.plugins.extras.coding.mini-comment",
"lazyvim.plugins.extras.coding.mini-surround",
"lazyvim.plugins.extras.editor.snacks_picker",
"lazyvim.plugins.extras.lang.astro",
"lazyvim.plugins.extras.lang.haskell",
"lazyvim.plugins.extras.lang.json",
"lazyvim.plugins.extras.lang.markdown",
"lazyvim.plugins.extras.lang.nix",
"lazyvim.plugins.extras.lang.rust",
"lazyvim.plugins.extras.lang.tailwind",
"lazyvim.plugins.extras.lang.toml",
"lazyvim.plugins.extras.lang.typescript"
],
"install_version": 8,
"version": 8
}

View File

@@ -10,8 +10,8 @@
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
pattern = { "markdown" }, pattern = { "markdown" },
callback = function() callback = function()
vim.bo.shiftwidth = 4 vim.o.shiftwidth = 2
vim.bo.tabstop = 4 vim.o.tabstop = 2
vim.bo.softtabstop = 4 vim.o.softtabstop = 2
end, end,
}) })

View File

@@ -18,6 +18,10 @@ require("lazy").setup({
spec = { spec = {
-- add LazyVim and import its plugins -- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" }, { "LazyVim/LazyVim", import = "lazyvim.plugins" },
-- Integrate ESlint for fixes and prettier for formatting
-- See: https://www.lazyvim.org/configuration/recipes
{ import = "lazyvim.plugins.extras.linting.eslint" },
{ import = "lazyvim.plugins.extras.formatting.prettier" },
-- import/override with your plugins -- import/override with your plugins
{ import = "plugins" }, { import = "plugins" },
}, },

View File

@@ -4,3 +4,6 @@
-- Creates a shortcut for adding the directory of the current buffer when specifying a file -- Creates a shortcut for adding the directory of the current buffer when specifying a file
vim.cmd("cnoreabbrev %. %:h<Tab>") vim.cmd("cnoreabbrev %. %:h<Tab>")
-- Set snacks as the preferred picker.
vim.g.lazyvim_picker = "snacks"

View File

@@ -0,0 +1,37 @@
return {
"saghen/blink.cmp",
dependencies = {
"moyiz/blink-emoji.nvim",
},
opts = {
sources = {
default = { "lsp", "buffer", "snippets", "path", "emoji" },
providers = {
-- https://github.com/moyiz/blink-emoji.nvim
emoji = {
module = "blink-emoji",
name = "Emoji",
score_offset = 15, -- Tune by preference
opts = { insert = true }, -- Insert emoji (default) or complete its name
should_show_items = function()
return vim.tbl_contains(
-- Enable emoji completion only for git commits and markdown.
-- By default, enabled for all file-types.
{ "gitcommit", "markdown" },
vim.o.filetype
)
end,
},
},
},
keymap = {
preset = "default",
["<C-space>"] = {
function(cmp)
cmp.show()
end,
},
["<Tab>"] = { "select_and_accept", "snippet_forward", "fallback" },
},
},
}

View File

@@ -0,0 +1,8 @@
return {
"stevearc/conform.nvim",
opts = {
formatters_by_ft = {
nix = { "nixfmt" },
},
},
}

View File

@@ -1,9 +0,0 @@
return {
"zbirenbaum/copilot.lua",
opts = {
filetypes = {
markdown = false,
help = false,
},
},
}

View File

@@ -1,5 +1,5 @@
return { return {
-- Maeson installs it's own binaries that are incompatible with NixOS. -- Maeson installs it's own binaries that are incompatible with NixOS.
{ "williamboman/mason.nvim", enabled = false }, { "mason-org/mason.nvim", enabled = false },
{ "williamboman/mason-lspconfig.nvim", enabled = false }, { "mason-org/mason-lspconfig.nvim", enabled = false },
} }

View File

@@ -1,11 +0,0 @@
return {
-- https://www.lazyvim.org/extras/editor/fzf
"ibhagwan/fzf-lua",
keys = {
{
"<leader><space>",
"<cmd>FzfLua buffers sort_mru=true sort_lastused=true<cr>",
desc = "Switch Buffer",
},
},
}

View File

@@ -3,8 +3,17 @@ return {
"neovim/nvim-lspconfig", "neovim/nvim-lspconfig",
opts = { opts = {
servers = { servers = {
-- Lua
lua_ls = {}, lua_ls = {},
-- Nix
nil_ls = {}, nil_ls = {},
-- Typescript
vtsls = {},
-- Haskell
hls = {},
},
codelens = {
enable = true,
}, },
}, },
}, },

View File

@@ -0,0 +1,45 @@
-- https://github.com/MeanderingProgrammer/render-markdown.nvim?tab=readme-ov-file#setup
return {
"MeanderingProgrammer/render-markdown.nvim",
opts = {
checkbox = {
enabled = true,
render_modes = true,
unchecked = {
icon = "󰄱 ",
highlight = "RenderMarkdownUnchecked",
scope_highlight = nil,
},
checked = {
-- Replaces '[x]' of 'task_list_marker_checked'.
icon = "󰱒 ",
-- Highlight for the checked icon.
highlight = "RenderMarkdownChecked",
-- Highlight for item associated with checked checkbox.
scope_highlight = nil,
},
-- Define custom checkbox states, more involved, not part of the markdown grammar.
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
-- The key is for healthcheck and to allow users to change its values, value type below.
-- | raw | matched against the raw text of a 'shortcut_link' |
-- | rendered | replaces the 'raw' value when rendering |
-- | highlight | highlight for the 'rendered' icon |
-- | scope_highlight | optional highlight for item associated with custom checkbox |
-- stylua: ignore
custom = {
partial = {
raw = '[/]',
rendered = '',
highlight = 'RenderMarkdownTodo',
scope_highlight = nil
},
deferred = {
raw = '[>]',
rendered = '',
highlight = 'RenderMarkdownWarn',
scope_highlight = nil
},
},
},
},
}

View File

@@ -1,10 +1,38 @@
return { return {
{ {
"echasnovski/mini.surround", "nvim-mini/mini.surround",
enable = true, enable = true,
keys = function(_, keys)
-- Populate the keys based on the user's options
local opts = LazyVim.opts("mini.surround")
local mappings = {
{ opts.mappings.add, desc = "Add Surrounding", mode = { "n", "v" } },
{ opts.mappings.delete, desc = "Delete Surrounding" },
{ opts.mappings.find, desc = "Find Right Surrounding" },
{ opts.mappings.find_left, desc = "Find Left Surrounding" },
{ opts.mappings.highlight, desc = "Highlight Surrounding" },
{ opts.mappings.replace, desc = "Replace Surrounding" },
{ opts.mappings.update_n_lines, desc = "Update `MiniSurround.config.n_lines`" },
}
mappings = vim.tbl_filter(function(m)
return m[1] and #m[1] > 0
end, mappings)
return vim.list_extend(mappings, keys)
end,
opts = {
mappings = {
add = "gsa", -- Add surrounding in Normal and Visual modes
delete = "gsd", -- Delete surrounding
find = "gsf", -- Find surrounding (to the right)
find_left = "gsF", -- Find surrounding (to the left)
highlight = "gsh", -- Highlight surrounding
replace = "gsr", -- Replace surrounding
update_n_lines = "gsn", -- Update `n_lines`
},
},
}, },
{ {
"echasnovski/mini.comment", "nvim-mini/mini.comment",
enable = true, enable = true,
}, },
} }

View File

@@ -1,20 +1,7 @@
return { return {
"epwalsh/obsidian.nvim", "obsidian-nvim/obsidian.nvim",
version = "*", -- recommended, use latest release instead of latest commit version = "*", -- recommended, use latest release instead of latest commit
lazy = true,
ft = "markdown", ft = "markdown",
-- Replace the above line with this if you only want to load obsidian.nvim for markdown files in your vault:
-- event = {
-- -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand'.
-- -- E.g. "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/*.md"
-- -- refer to `:h file-pattern` for more examples
-- "BufReadPre path/to/my-vault/*.md",
-- "BufNewFile path/to/my-vault/*.md",
-- },
dependencies = {
-- Required.
"nvim-lua/plenary.nvim",
},
opts = { opts = {
workspaces = { workspaces = {
{ {
@@ -22,18 +9,65 @@ return {
path = "~/Documents/Notes", path = "~/Documents/Notes",
}, },
}, },
-- Can I enable this somehow? I'm using blink.cmp but this is triggering
-- it to look for nvim-cmp directly.
-- completion = {
-- nvim_cmp = true,
-- min_chars = 2,
-- },
daily_notes = { daily_notes = {
-- Optional, if you keep daily notes in a separate directory. -- Optional, if you keep daily notes in a separate directory.
folder = "Daily Notes", folder = "Daily Notes",
-- Optional, if you want to change the date format for the ID of daily notes. -- Optional, if you want to change the date format for the ID of daily notes.
date_format = "%Y-%m-%d", date_format = "%Y-%m-%d",
-- Optional, if you want to automatically insert a template from your template directory like '' -- Optional, if you want to automatically insert a template from your template directory like ''
template = nil, template = "Daily Note",
}, },
templates = { templates = {
folder = "Templates", folder = "Templates",
date_format = "%Y-%m-%d", date_format = "%Y-%m-%d",
time_format = "%H:%M", time_format = "%H:%M",
}, },
ui = {
-- Disable the UI features and let render-markdown.nvim handle it.
enable = false,
-- Even with UI disabled, this determines the order of checkbox states for the smart action.
checkboxes = {
[" "] = { char = "", hl_group = "ObsidianTodo" },
["x"] = { char = "", hl_group = "ObsidianDone" },
["/"] = { char = "", hl_group = "ObsidianTodo" },
[">"] = { char = "»", hl_group = "ObsidianRightArrow" },
["~"] = { char = "»", hl_group = "ObsidianTilde" },
["!"] = { char = "", hl_group = "ObsidianDone" },
},
},
-- Put the note ID in the wiki links
wiki_link_func = "prepend_note_id",
preferred_link_style = "wiki",
-- Customize how note IDs are generated given an optional title.
---@param title string|?
---@return string
note_id_func = function(title)
if title ~= nil then
-- If title is given, transform it into valid file name by removing most special characters
-- Note that parens are not supported because they interfere with markdown links.
return title:gsub("[^A-Za-z0-9-_]", ""):lower()
else
-- If title is nil, just put the date and four random characters
for _ = 1, 4 do
return os.date("%Y-%m-%d ") .. string.char(math.random(65, 90))
end
end
end,
follow_url_func = function(url)
vim.ui.open(url) -- Use the built-in open, need Neovim 0.10.0+
end,
}, },
} }

View File

@@ -0,0 +1,65 @@
return {
"folke/snacks.nvim",
opts = function(_, opts)
vim.tbl_deep_extend("force", opts, {
picker = {
smart = {
-- Remove the "recent" picker so we don't get things from other directories.
multi = { "buffers", "files" },
matcher = {
-- sort even when the search string is empty
sort_empty = true,
-- Enable frecensy for matchers. This puts more common files near the top
frecency = false,
-- Make sure files in the current directory are prioritized
cwd_bonus = true,
-- Give more weight to files that are more recent
history_bonus = true,
-- Give more weight to places where the filename is part of the match
filename_bonus = true,
},
},
sources = {
explorer = {
layout = { layout = { position = "right" } },
},
},
-- This only supports the Kitty graphics protocol.
-- See
-- https://github.com/folke/snacks.nvim/blob/main/docs/image.md
-- https://github.com/obsidian-nvim/obsidian.nvim/wiki/Images
-- image = {
-- resolve = function(path, src)
-- if require("obsidian.api").path_is_note(path) then
-- return require("obsidian.api").resolve_image_path(src)
-- end
-- end,
-- },
},
})
Snacks.toggle({
name = "Color Column",
get = function()
return vim.o.colorcolumn == "80"
end,
set = function(state)
if state then
vim.o.colorcolumn = "80"
vim.cmd([[highlight ColorColumn guibg=#202020]])
else
vim.o.colorcolumn = ""
vim.cmd([[highlight ColorColumn guibg=None]])
end
end,
}):map("<leader>ut", { desc = "Toggle Color Column" })
end,
keys = {
{
"<leader><space>",
function()
Snacks.picker.smart()
end,
desc = "Smart Find Files",
},
},
}

View File

@@ -1,14 +0,0 @@
return {
"nvim-telescope/telescope.nvim",
enabled = false,
keys = {
-- Switch the default keybind to switch buffers instead of find files
{
"<leader><space>",
"<cmd>Telescope buffers sort_mru=true sort_lastused=true<cr>",
desc = "Open Files",
},
-- Disable the <leader><comma> since it's so hard to type and redundant with the above.
{ "<leader><comma>", false },
},
}

View File

@@ -0,0 +1,10 @@
return {
"folke/tokyonight.nvim",
opts = {
transparent = true,
styles = {
sidebars = "transparent",
-- floats = "transparent",
},
},
}

View File

@@ -0,0 +1,23 @@
return {
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = {
"astro",
"bash",
"html",
"css",
"javascript",
"json",
"lua",
"markdown",
"markdown_inline",
"python",
"query",
"regex",
"tsx",
"typescript",
"vim",
"yaml",
},
},
}

View File

@@ -9,6 +9,7 @@
extraPackages = with pkgs; [ extraPackages = with pkgs; [
gcc # For treesitter complation gcc # For treesitter complation
tree-sitter # For treesitter binaries
ripgrep # Search support ripgrep # Search support
wayclip # Clipboard support wayclip # Clipboard support
fd # finder for telescope fd # finder for telescope
@@ -16,6 +17,8 @@
lazygit # LazyVim dep? lazygit # LazyVim dep?
wget # LazyVim dep? wget # LazyVim dep?
sqlite # For Snacks sqlite # For Snacks
imagemagick # For image conversion/display
vscode-langservers-extracted # For language servers (it wants this version of eslint for some reason)
]; ];
}; };

View File

@@ -1,10 +0,0 @@
{ pkgs, ... }:
{
# Enable flakes and nix-commnands.
nix.settings.experimental-features = ["flakes" "nix-command"];
# Allow unfree code
nixpkgs.config = {
allowUnfree = true;
};
}

View File

@@ -1,20 +1,83 @@
{ lib, ... }: { lib, pkgs, ... }:
{ {
home.packages = with pkgs; [
obsidian
];
home.shellAliases = {
"notes" = "(cd ~/Documents/Notes && nvim)";
};
services.syncthing = { services.syncthing = {
enable = true; enable = true;
tray = { tray = {
enable = lib.mkDefault true; enable = lib.mkDefault true;
}; };
# This will override any locally configured devices and folders
overrideDevices = true;
overrideFolders = true;
settings = { settings = {
folders.Notes = { folders = {
Notes = {
label = "Notes";
path = "~/Documents/Notes"; path = "~/Documents/Notes";
devices = [
"altair"
"mcp"
"vega"
"proxima"
];
};
};
devices = {
mcp = {
id = "6O3U5QK-PR4RAAB-L32TR6K-USM7PER-VJBIKCI-FOWNA2G-7CQU5HF-R2OXNQ2";
name = "mcp";
addresses = [
# "tcp://mcp.blazestar.net"
"relay://syncthing.blazestar.net:22067"
];
compression = "always";
};
vega = {
id = "U55HQDN-YTUQAGA-G4O4LMZ-OAVAUVZ-RBDD2S6-JAWAUF2-Z4VZ7BM-TIIVUA4";
name = "vega";
addresses = [
# "tcp://vega.blazestar.net"
"relay://syncthing.blazestar.net:22067"
];
compression = "always";
};
altair = {
id = "W5QZDM6-CUVQJIG-DR4BJCU-IQ7UGTJ-NQUSW73-E3GWSLU-A2QEMKR-BRDH3Q3";
name = "altair";
addresses = [
# "tcp://altair.blazestar.net"
"relay://syncthing.blazestar.net:22067"
];
compression = "always";
};
proxima = {
id = "NWZL6LY-ULJQMZE-EWY3MQU-XPDAFQB-LTIBZV7-GPKIABJ-WBJE36F-SK6LVAY";
name = "Proxima";
addresses = [
"relay://syncthing.blazestar.net:22067"
];
compression = "always";
};
}; };
options = { options = {
localAnnounceEnabled = false; localAnnounceEnabled = false;
globalAnnounceEnabled = false;
relaysEnabled = true; relaysEnabled = true;
globalAnnounceEnabled = true; listenAddresses = [
globalAnnounceServer = "relay://mcp:22067"; "relay://syncthing.blazestar.net:22067/?id=TITGK5I-55GDSAF-HHPCSMZ-AHD2YKT-LZSKYRQ-5B6MGE4-LMLNEP6-KQ4UJQF&networkTimeout=2m0s&pingInterval=1m0s&statusAddr=%3A22070"
listenAddress = "relay://mcp:22067"; ];
# Whether the user has accepted submitting usage data. 0 is no-choice.
# -1 means no. A positive integer means yes.
urAccepted = -1;
# Disable NAT port-mapping
natEnabled = false;
}; };
}; };
}; };

View File

@@ -7,7 +7,7 @@
**/ **/
* { * {
background: #15161EFF; background: #15161ECC;
background-alt: #1A1B26FF; background-alt: #1A1B26FF;
foreground: #C0CAF5FF; foreground: #C0CAF5FF;
selected: #33467CFF; selected: #33467CFF;

View File

@@ -1,3 +1,3 @@
configuration { configuration {
ssh-command: "wezterm ssh {host}"; ssh-command: "foot ssh {host}";
} }

View File

@@ -15,4 +15,4 @@
/* Import color-scheme from `colors` directory */ /* Import color-scheme from `colors` directory */
@import "~/.config/rofi/colors/onedark.rasi" @import "~/.config/rofi/colors/tokyonight.rasi"

View File

@@ -32,8 +32,8 @@ window {
enabled: true; enabled: true;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
border: 0px solid; border: 2px solid;
border-radius: 0px; border-radius: 5px;
border-color: @selected; border-color: @selected;
background-color: @background; background-color: @background;
cursor: "default"; cursor: "default";

View File

@@ -15,4 +15,4 @@
/* Import color-scheme from `colors` directory */ /* Import color-scheme from `colors` directory */
@import "~/.config/rofi/colors/onedark.rasi" @import "~/.config/rofi/colors/tokyonight.rasi"

View File

@@ -11,7 +11,7 @@ dir="${HOME}/.config/rofi/powermenu"
# CMDs # CMDs
uptime="$(uptime | awk -F ' ' '{print $2}' | sed -e 's/,//g')" uptime="$(uptime | awk -F ' ' '{print $2}' | sed -e 's/,//g')"
host=`hostname` host=$(hostname)
# Options # Options
shutdown='󰐥' shutdown='󰐥'
@@ -76,7 +76,9 @@ run_cmd() {
qdbus org.kde.ksmserver /KSMServer logout 0 0 0 qdbus org.kde.ksmserver /KSMServer logout 0 0 0
elif [[ "$DESKTOP_SESSION" == 'plasma' ]]; then elif [[ "$DESKTOP_SESSION" == 'plasma' ]]; then
qdbus org.kde.ksmserver /KSMServer logout 0 0 0 qdbus org.kde.ksmserver /KSMServer logout 0 0 0
elif command -v hyprctl &>/dev/null; then elif [[ "$DESKTOP_SESSION" == 'hyprland-uwsm' ]]; then
hyprctl dispatch exit
elif [[ "$DESKTOP_SESSION" == 'hyprland' ]]; then
hyprctl dispatch exit hyprctl dispatch exit
fi fi
fi fi
@@ -88,25 +90,28 @@ run_cmd() {
# Actions # Actions
chosen="$(run_rofi)" chosen="$(run_rofi)"
case ${chosen} in case ${chosen} in
$shutdown) $shutdown)
run_cmd --shutdown run_cmd --shutdown
;; ;;
$reboot) $reboot)
run_cmd --reboot run_cmd --reboot
;; ;;
$lock) $lock)
if [[ -x '/usr/bin/betterlockscreen' ]]; then loginctl lock-session
betterlockscreen -l # if [[ -x '/usr/bin/betterlockscreen' ]]; then
elif [[ -x '/usr/bin/i3lock' ]]; then # betterlockscreen -l
i3lock # elif [[ -x '/usr/bin/i3lock' ]]; then
elif command -v hyprlock &>/dev/null; then # i3lock
hyprlock # elif command -v hyprlock &>/dev/null; then
fi # hyprlock
# elif command -v swaylock &>/dev/null; then
# swaylock
# fi
;; ;;
$suspend) $suspend)
run_cmd --suspend run_cmd --suspend
;; ;;
$logout) $logout)
run_cmd --logout run_cmd --logout
;; ;;
esac esac

View File

@@ -35,8 +35,8 @@ window {
enabled: true; enabled: true;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
border: 0px solid; border: 2px solid;
border-radius: 0px; border-radius: 5px;
border-color: @selected; border-color: @selected;
cursor: "default"; cursor: "default";
background-color: @background; background-color: @background;

View File

@@ -8,4 +8,10 @@
source = ./config; source = ./config;
recursive = true; recursive = true;
}; };
wayland.windowManager.hyprland.settings.windowrulev2 = [
# Forces the Rofi window to hold focus so that it gets input even if
# something else opens or the mouse is outside the window.
"stayfocused, class:Rofi"
];
} }

View File

@@ -2,6 +2,10 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
imports = [
./uutils.nix
];
# These are all the sort of shell commands that we want available whereever # These are all the sort of shell commands that we want available whereever
# there is shell. These include just a lot of useful utilities for managing # there is shell. These include just a lot of useful utilities for managing
# a system or working with other shell commands. Packages more specific to # a system or working with other shell commands. Packages more specific to
@@ -11,35 +15,53 @@
htop htop
btop btop
neofetch neofetch
killall psmisc # fuser, killal, pstree
# Files # Archives
zip zip
xz xz
unzip unzip
p7zip p7zip
unrar-wrapper
# File manipulation
file file
tree tree
ranger yazi # File manager
ueberzugpp # for image previews
w3m # terminal browser for image previews w3m # terminal browser for image previews
dysk # better disk info
ripgrep # better grep
fd # Better find
bat # cat with wings
eza # Modern replacement for ls
dust # More intuitive du
dua # Interactive disk usage analyzer
# Networking # Networking
dnsutils dnsutils
inetutils inetutils
socat socat
httpie xh
# devices # devices
usbutils usbutils
# Other # Other
jq jq
mprocs # Manage multiple long-running processes
]; ];
home.shellAliases = { home.shellAliases = {
"p?" = "ps ax | grep"; "p?" = "ps ax | rg";
# Dysk is basically just better.
"df" = "echo 'Do you mean: dysk?'";
"grep" = "echo 'Do you mean: rg?'";
"find" = "echo 'Do you mean: fd'";
"cat" = "bat";
"ls" = "eza";
"http" = "echo 'Do you mean: xh'";
"du" = "echo 'Do you mean: dust or dua?'";
"ranger" = "echo 'Do you mean: yazi'";
}; };
programs.zsh = { programs.zsh = {
@@ -48,7 +70,7 @@
PATH=$PATH:$HOME/.local/bin PATH=$PATH:$HOME/.local/bin
GITHUB_USERNAME=periodic GITHUB_USERNAME=periodic
''; '';
initExtra = '' initContent = ''
# Make ^U work like it does in Bash # Make ^U work like it does in Bash
bindkey "^U" backward-kill-line bindkey "^U" backward-kill-line
@@ -94,6 +116,12 @@
]; ];
}; };
programs.zoxide = {
# TODO: Learn all the capabilities of zoxide and use them.
enable = true;
enableZshIntegration = true;
};
programs.starship = { programs.starship = {
enable = true; enable = true;
settings = { settings = {

View File

@@ -0,0 +1,154 @@
{
config,
lib,
...
}:
{
imports = [
./swaync.nix
./swaylock.nix
];
services.swayosd = {
enable = true;
topMargin = 0.7;
};
# Enable sway config generation for home.pointerCursor
home.pointerCursor.sway.enable = true;
wayland.windowManager.sway = {
enable = true;
extraOptions = [
# Required for NVIDIA GPUs
"--unsupported-gpu"
];
checkConfig = true;
systemd = {
enable = true;
xdgAutostart = true;
};
config = {
# Workspace assignments
# Example:
# {
# "1: web" = [{ class = "^Firefox$"; }];
# "0: extra" = [{ class = "^Firefox$"; window_role = "About"; }];
# }
assigns = { };
colors = {
background = "#333333";
focused = {
background = "#285577";
border = "#4c7899";
childBorder = "#285577";
indicator = "#2e9ef4";
text = "#ffffff";
};
focusedInactive = {
background = "#5f676a";
border = "#333333";
childBorder = "#5f676a";
indicator = "#484e50";
text = "#ffffff";
};
placeholder = {
background = "#0c0c0c";
border = "#000000";
childBorder = "#0c0c0c";
indicator = "#000000";
text = "#ffffff";
};
unfocused = {
background = "#222222";
border = "#333333";
childBorder = "#222222";
indicator = "#292d2e";
text = "#888888";
};
urgent = {
background = "#900000";
border = "#2f343a";
childBorder = "#900000";
indicator = "#900000";
text = "#ffffff";
};
};
modifier = "Mod4"; # Super key
keybindings =
let
modifier = config.wayland.windowManager.sway.config.modifier;
terminal = "foot";
browser = "firefox";
menu = "rofi -show drun";
in
lib.mkOptionDefault {
"${modifier}+t" = "exec ${terminal}";
"${modifier}+b" = "exec ${browser}";
"${modifier}+d" = "exec ${menu}";
"${modifier}+Shift+s" = "exec hyprshot -m region --clipboard-only";
"${modifier}+c" = "exec swaync-client -t";
"${modifier}+Control+q" = "exec /home/drew/.config/rofi/powermenu/powermenu.sh";
"${modifier}+x" = "exec /home/drew/.config/rofi/powermenu/powermenu.sh";
"${modifier}+f" = "floating toggle";
"${modifier}+Shift+f" = "fullscreen toggle";
"${modifier}+r" = "focus output right"; # sway does not have `focusmonitor next`
"${modifier}+Control+r" = "move workspace to output left";
"${modifier}+Control+s" = "move workspace to output right";
"${modifier}+q" = "kill";
"${modifier}+Left" = "focus left";
"${modifier}+Right" = "focus right";
"${modifier}+Up" = "focus up";
"${modifier}+Down" = "focus down";
"${modifier}+Shift+Left" = "move left";
"${modifier}+Shift+Right" = "move right";
"${modifier}+Shift+Up" = "move up";
"${modifier}+Shift+Down" = "move down";
# Workspace switching
"${modifier}+1" = "workspace number 1";
"${modifier}+2" = "workspace number 2";
"${modifier}+3" = "workspace number 3";
"${modifier}+4" = "workspace number 4";
"${modifier}+5" = "workspace number 5";
"${modifier}+6" = "workspace number 6";
"${modifier}+7" = "workspace number 7";
"${modifier}+8" = "workspace number 8";
"${modifier}+9" = "workspace number 9";
"${modifier}+0" = "workspace number 10";
"${modifier}+Shift+1" = "move container to workspace number 1; workspace number 1";
"${modifier}+Shift+2" = "move container to workspace number 2; workspace number 2";
"${modifier}+Shift+3" = "move container to workspace number 3; workspace number 3";
"${modifier}+Shift+4" = "move container to workspace number 4; workspace number 4";
"${modifier}+Shift+5" = "move container to workspace number 5; workspace number 5";
"${modifier}+Shift+6" = "move container to workspace number 6; workspace number 6";
"${modifier}+Shift+7" = "move container to workspace number 7; workspace number 7";
"${modifier}+Shift+8" = "move container to workspace number 8; workspace number 8";
"${modifier}+Shift+9" = "move container to workspace number 9; workspace number 9";
"${modifier}+Shift+0" = "move container to workspace number 10; workspace number 10";
"${modifier}+Shift+r" = "move container to output left"; # approximating hyprland\u2019s split-changemonitor
"${modifier}+button1" = "move";
"${modifier}+button2" = "resize";
"XF86AudioRaiseVolume" = "exec swayosd-client --output-volume raise";
"XF86AudioLowerVolume" = "exec swayosd-client --output-volume lower";
"XF86AudioMute" = "exec swayosd-client --output-volume mute-toggle";
"XF86AudioMicMute" = "exec swayosd-client --input-volume mute-toggle";
"XF86AudioNext" = "exec playerctl next";
"XF86AudioPause" = "exec playerctl play-pause";
"XF86AudioPlay" = "exec playerctl play-pause";
"XF86AudioPrev" = "exec playerctl previous";
};
};
};
}

View File

@@ -0,0 +1,37 @@
{ pkgs, ... }:
{
programs.swaylock = {
enable = true;
package = pkgs.swaylock-effects;
settings = {
clock = true;
indicator = true;
effect-pixelate = 20;
};
};
home.file.".config/swaylock/swaylock.sh" = {
executable = true;
# A script that will take the wallpaper folder for each monitor (see
# wallpaper.nix) and use a random image as the background on each monitor.
text = ''
#!/usr/bin/env sh
wallpaper_dir="$HOME/Pictures/Wallpaper"
cmd="swaylock"
for monitor in $(hyprctl monitors | awk '/^Monitor/ { print $2 }'); do
dir="$wallpaper_dir/$monitor"
if [ -d "$dir" ]; then
image=$(find "$dir" -type f | shuf -n 1)
if [ -n "$image" ]; then
cmd="$cmd --image \"$monitor:$image\""
fi
fi
done
# Eval to handle the quoted image paths correctly
eval $cmd
'';
};
}

View File

@@ -0,0 +1,98 @@
{ ... }:
{
services.swaync = {
enable = true;
settings = {
"positionX" = "right";
"positionY" = "top";
"layer" = "overlay";
"control-center-layer" = "top";
"layer-shell" = true;
"cssPriority" = "application";
"control-center-margin-top" = 0;
"control-center-margin-bottom" = 0;
"control-center-margin-right" = 0;
"control-center-margin-left" = 0;
"notification-2fa-action" = true;
"notification-inline-replies" = false;
"notification-icon-size" = 64;
"notification-body-image-height" = 100;
"notification-body-image-width" = 200;
"timeout" = 10;
"timeout-low" = 5;
"timeout-critical" = 0;
"fit-to-screen" = true;
"relative-timestamps" = true;
"control-center-width" = 500;
"control-center-height" = 600;
"notification-window-width" = 500;
"keyboard-shortcuts" = true;
"image-visibility" = "when-available";
"transition-time" = 200;
"hide-on-clear" = false;
"hide-on-action" = true;
"script-fail-notify" = true;
"scripts" = {
"example-script" = {
"exec" = "echo 'Do something...'";
"urgency" = "Normal";
};
"example-action-script" = {
"exec" = "echo 'Do something actionable!'";
"urgency" = "Normal";
"run-on" = "action";
};
};
"notification-visibility" = {
"example-name" = {
"state" = "muted";
"urgency" = "Low";
"app-name" = "Spotify";
};
};
"widgets" = [
"inhibitors"
"title"
"dnd"
"notifications"
];
"widget-config" = {
"inhibitors" = {
"text" = "Inhibitors";
"button-text" = "Clear All";
"clear-all-button" = true;
};
"title" = {
"text" = "Notifications";
"clear-all-button" = true;
"button-text" = "Clear All";
};
"dnd" = {
"text" = "Do Not Disturb";
};
"label" = {
"max-lines" = 5;
"text" = "Label Text";
};
"mpris" = {
"image-size" = 96;
"image-radius" = 12;
};
"buttons-grid" = {
"actions" = [
{
"label" = "";
"type" = "toggle";
"active" = true;
"command" =
"sh -c '[[ $SWAYNC_TOGGLE_STATE == true ]] && nmcli radio wifi on || nmcli radio wifi off'";
"update_command" = "sh -c '[[ $(nmcli radio wifi) == \"enabled\" ]] && echo true || echo false'";
}
];
};
};
};
};
}

View File

@@ -4,9 +4,16 @@
home.packages = with pkgs; [ home.packages = with pkgs; [
# Font # Font
# 24.11
# inconsolata-nerdfont
# fira-code-nerdfont
# 25.05
nerd-fonts.inconsolata nerd-fonts.inconsolata
nerd-fonts.fira-code nerd-fonts.fira-code
nerd-fonts.jetbrains-mono nerd-fonts.jetbrains-mono
libsixel # For working with images in terminals
ueberzugpp # for image previews
]; ];
# Allow Home Manager to set fonts. # Allow Home Manager to set fonts.
@@ -37,6 +44,45 @@
}; };
home.shellAliases = { home.shellAliases = {
"imgcat" = "wezterm imgcat"; "imgcat" = "img2sixel";
};
programs.foot = {
enable = true;
settings = {
main = {
font = "FiraCode Nerd Font:size=12";
selection-target = "primary";
pad = "8x8";
};
scrollback = {
lines = 5000;
};
colors = {
alpha = 0.9;
# Tokionight Night theme
# From https://codeberg.org/dnkl/foot/src/branch/master/themes/tokyonight-night
background = "1a1b26";
foreground = "c0caf5";
regular0 = "15161E";
regular1 = "f7768e";
regular2 = "9ece6a";
regular3 = "e0af68";
regular4 = "7aa2f7";
regular5 = "bb9af7";
regular6 = "7dcfff";
regular7 = "a9b1d6";
bright0 = "414868";
bright1 = "f7768e";
bright2 = "9ece6a";
bright3 = "e0af68";
bright4 = "7aa2f7";
bright5 = "bb9af7";
bright6 = "7dcfff";
bright7 = "c0caf5";
};
};
}; };
} }

View File

@@ -0,0 +1,7 @@
{ pkgs, lib, ... }:
{
home.packages = with pkgs; [
# Use uutils core-utils with no prefix so they override the GNU coreutils
(lib.hiPrio uutils-coreutils-noprefix)
];
}

View File

@@ -0,0 +1,28 @@
monitors:
{ ... }:
{
wayland.windowManager.hyprland.settings.exec-once = [
"wpaperd"
];
services.wpaperd = {
enable = true;
settings =
builtins.listToAttrs (
map (mon: {
name = mon;
value = {
# Each monitor gets a folder under wallpaper that containes the current images.
path = "~/Pictures/Wallpaper/${mon}";
};
}) monitors
)
// {
default = {
duration = "1h";
mode = "center";
sorting = "random";
};
};
};
}

3
lib/default.nix Normal file
View File

@@ -0,0 +1,3 @@
{
inherit (import ./electron.nix) electronDesktopEntry;
}

9
lib/electron.nix Normal file
View File

@@ -0,0 +1,9 @@
{
# Adds extra arguments to avoid flickering under wayland.
electronDesktopEntry =
desktop:
desktop
// {
exec = "${desktop.exec} --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu";
};
}

View File

@@ -1,12 +1,33 @@
gitea_db_password: ENC[AES256_GCM,data:G2YqiDk0msBRjUJkoPxWmayQ9dI=,iv:FsojIJIi61K7rD2VULDgIx6uSYX3iDiA6W744HlgHl0=,tag:BlmsM7LZHnBCKtfuqlhoKA==,type:str] gitea:
db_password: ENC[AES256_GCM,data:12FYMsc8HdTMdPegoPLCidaHMMU=,iv:Uat0g7Nvota1yvj6InIAo7Dzv3cBtVVzlRa1d09gx1s=,tag:sFavpAHW0k/Fv1uzPVuGcA==,type:str]
registration_token: ENC[AES256_GCM,data:zYfFATOuqACrGUyt6xPhiisz293uomKc6BLPKz8I+MFFBrBdzT9FqA==,iv:gyp2WsUHMMrNBmssWGPLSJmZqlAtopc6HeAtX9+oCXs=,tag:mLEPTapn7OM3bm5c9TKB0A==,type:str]
bookstack_app_key: ENC[AES256_GCM,data:N79JVlQSoVCXOsIHCxd19HFm6LkrYyXQu/xWenEdUlQWqwZEi3PuHXG7fQgvzQY4KI7S,iv:cd2l2eOv+wAJ5sih3YhHgQTdy1qrvaIsoHcywOnHuYM=,tag:5QvCHlQX8wUz3tI2NXl+8A==,type:str] bookstack_app_key: ENC[AES256_GCM,data:N79JVlQSoVCXOsIHCxd19HFm6LkrYyXQu/xWenEdUlQWqwZEi3PuHXG7fQgvzQY4KI7S,iv:cd2l2eOv+wAJ5sih3YhHgQTdy1qrvaIsoHcywOnHuYM=,tag:5QvCHlQX8wUz3tI2NXl+8A==,type:str]
bookstack_db: ENC[AES256_GCM,data:m8fGgAfmJu1rEaxmTVH4FfBhyiU=,iv:OnBT/6sp9zmcJ1+kBmdmvaE630hifxBpvKnu3XrVXcE=,tag:SSVQcYkAymlbFOnf0MB6KA==,type:str] bookstack_db: ENC[AES256_GCM,data:m8fGgAfmJu1rEaxmTVH4FfBhyiU=,iv:OnBT/6sp9zmcJ1+kBmdmvaE630hifxBpvKnu3XrVXcE=,tag:SSVQcYkAymlbFOnf0MB6KA==,type:str]
mariadb_root_password: ENC[AES256_GCM,data:p965ZhFQqqX+Ub1yhgklVYlBH6A=,iv:qC5WwTvZGvlbAkYiv35xHizMYAnP0V0Vw79EkvL32wQ=,tag:gOJQvHeOC9turFKOMQ9DNg==,type:str] mariadb_root_password: ENC[AES256_GCM,data:p965ZhFQqqX+Ub1yhgklVYlBH6A=,iv:qC5WwTvZGvlbAkYiv35xHizMYAnP0V0Vw79EkvL32wQ=,tag:gOJQvHeOC9turFKOMQ9DNg==,type:str]
openproject:
secret-key-base: ENC[AES256_GCM,data:luTuUtxL/SGx6O10y9cRiAzJHw==,iv:8qVJm+obsHr9eV0h+jdpsreeFGxEM+UFZHHiIUUPs6w=,tag:+zpjhKoIiNNSSYxe1QkQ7Q==,type:str]
focalboard:
database: ENC[AES256_GCM,data:GDxYdkVV+tl3qHxWMMoetmMnLnY=,iv:JujgNPyUEHCmD/yW3UKCTj9GTk9a7EkvUiyFLF4sF8A=,tag:46YZ7AthpiiaX69aN9a3Bg==,type:str]
offen:
secret: ENC[AES256_GCM,data:sH2siPc/QH1O2M7ZlJwqhqlHRIeLIG9r,iv:eD29ALx2ji0rm1t9j6RulTZT3f6VLK7dxpPOze3qDKA=,tag:zqJTgT2UeA/ecBS4VremUw==,type:str]
smtp-token: ENC[AES256_GCM,data:ZTfe65g3JykPvG2l0AN8UQ==,iv:GTruGo/vcP+imfJyqB3NX9ic8dz5jvTEh6SF+OeqMDM=,tag:kgwd59pG/WUt8OAaVzi39Q==,type:str]
traefik:
oauth2-client-secret: ENC[AES256_GCM,data:p7/6OsN2ytBj8mQiK0YL7J6NYLtMHOXIIs/6+bIDpsU=,iv:k6jLZifJEFLYKSFMkyn/kA7iBE+EFB8O/3/3fyTh1SY=,tag:6s49O2+tdlZoXyAGEamuMQ==,type:str]
oauth2-plugin-secret: ENC[AES256_GCM,data:sArqwKHAdW35o5kD7DGfXSYCXFUXqvKQdoVnXutsNLw=,iv:qWf597QS3BqkVQkeAb99HbpDB0kUhdD+qKdpUPZEB0o=,tag:vXnb93npaklItWkMZ+/M9Q==,type:str]
protonvpn:
private_key: ENC[AES256_GCM,data:41pfbR1klj1F24v3HlCCA4ofW2sCEnyE5TH8iX4Ug8D+kmwstTaj5RG2Zz8=,iv:P6XyQnDVoOmdkP8ilBR9DyfqPZA6GsQ6VUwY/tSGhx4=,tag:Bzgdv29lbk/gYlADPZMGVA==,type:str]
deploy-key:
mcp: ENC[AES256_GCM,data:eQcX8xdz5qZ6nU8ISOvZo+ZtP4Z/ePd+/ZZReX1BKvTUqGQPPFxConbLMwFzvzpD6xAUbA1MLkcR/bT98QbNx6LJYlhbofuDUg2DI79RB0fcrAcj/wUV0YPhmgofUdYYDaimH5A2PSvtmKfB3CtKKuA5HNeLymoXeLEpFzbckkGhzPee/CHiUmxayogp6za6btsDJsiT8hdHbrzyD2S6fhMJrzX+PlRzT32M/6eaFuFWE8EUO1gbkRlNfKPXw/EM2GXWJfR4qXfN2YKIKigqrtlAAoxnrUbp5EBrn/hGHS2ZYZXeRUFr3avFjcI0bLX423PWRHAylfQCPxgYVEtbcRv11CAFmq4rfFl0ZdvnAKbTLNmWcrQNijBATZPaAdQzgKPDHs8pwPUFR9Tcg8pZNbzw0mK9kPolniAOL2PBKUHv6LP/uEkB1E6Pxc7yms0kGpeJyo7hrFVOiVAckCey+SI9dpbJMSB3md070I1xk6Ik7PywrWh2QDeUtOU1U28UkYgnJ/9MJelWsNlUX9SR,iv:oCNeanaV/7UZ3dhmq4ZmJUZ5hb61AnHpHCfskM2Jsm8=,tag:F2uJKN5beM/rfiBMSyUP7w==,type:str]
matrix:
syncv3:
db-password: ENC[AES256_GCM,data:N/IO0k/2BZpmaDTbKZmSgZNzmdk=,iv:p0jGjJ9mTCh5FPM/Oe1vxusYvlyg14UeggE5ynpDVL8=,tag:tZbddwxJf6wSH6L1QRUQVg==,type:str]
secret: ENC[AES256_GCM,data:KZjYxjUxGgkY1I5jGF7XMEhkHK+khDaQzxugoKxpLsROmVs722tFfbUAxhp71llam55gy9+eUWGxIPlmvOySlw==,iv:OoThGcT08Z11kpnAMQ7w59wj5JheNFGEk1jfFENsmy0=,tag:8EeKT7dh2/a52Amf6LsL1w==,type:str]
blazestar-registration-token: ENC[AES256_GCM,data:TB3bR+E4H4c2l9pRcEOAZr35+vBVaJUcuCs9K0Pjd0aW+M35x5LgZ8+F99Y=,iv:e28sie6LSI5UX41BPb+yN+3n+Yw9Ssfsqe4zppwbPkU=,tag:cQPgZcRFbYSiZnmPVtZxHg==,type:str]
tandoor:
secret_key: ENC[AES256_GCM,data:nl7S2fS1wENrT5k2iZfLEAGc99lCUktgwR5L5KklF69BNVKQkW1rUgb3aIv50VpXZa+3OxV/vdPmG9NhKMy96I5+Dno=,iv:FFyGQBARz0B5zrONZELzUMsOIn8TWrDNTKGsAHPlS7w=,tag:/c4MnDfLXQpBZDqVxZ0DTg==,type:str]
immich:
database: ENC[AES256_GCM,data:1fjOQsLZcq/T+r+AkzomWwCQWw==,iv:c4pn2rC+3xkxLJ7uAdhnTE6zVTRQkfuKK3tjUyDhfAw=,tag:kvk7DOv6X/+RDxfPxVak7w==,type:str]
sops: sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: age:
- recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue - recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
enc: | enc: |
@@ -26,8 +47,7 @@ sops:
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q== vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-03-25T21:23:10Z" lastmodified: "2026-02-25T00:28:13Z"
mac: ENC[AES256_GCM,data:BTmAMxauVjQaMoQhDCCAloniVfEaxB5vUhI6Cvu1YFMesLv3yhnZ9lgRB4SXsyd7Kf3xefY7Wg+PtMnl2aX6BR4Tdss5H+UTHzsa3M888TI3EAEykXbPFUfOapAiboP71aibiDj8L0lbcKimGJpg3llzeNtK370fjAp7hsnh7aE=,iv:YTMrTtqDkq9L2y42X2nmEKruSKp7v70GStMw/JjPrL8=,tag:x1LclBpygFZQBWPYkE9chw==,type:str] mac: ENC[AES256_GCM,data:hDmqObrtfoVkQqz8JPkqlyXMbiuyBophjdZNLvTFrZw3pAVNCuzsH4zxFBOaxJttkzLc65DWDHDeEIBY5YZam1GLFFXUQ5E3Dxno7hnyzOoM2ipgDTOacI0gbKJAWgGUF3LNDdqVoREA9LC91LoNUJoNmzpTSFtuLb7ORuwCrH4=,iv:8+W3n1Cr6woEiPU9ECaMYM64HNmFHr2AIw6UohCJi00=,tag:7drkZiPAUHaEx5PagXA9JQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.9.4 version: 3.11.0

View File

@@ -1,7 +1,8 @@
{ ... }: { ... }:
{ {
users.users.drew.openssh.authorizedKeys.keys = [ users.users.drew.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPL+uF46A1oe+TgYoCcBQFcWtx5UJMdgczX+/rG/i55t drew@drew-desktop" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPL+uF46A1oe+TgYoCcBQFcWtx5UJMdgczX+/rG/i55t drew@altair"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB0NbnQByo8sFmzsX5/0I6kWh+unTKxns2TsEPSzgYbD drew@mcp" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB0NbnQByo8sFmzsX5/0I6kWh+unTKxns2TsEPSzgYbD drew@mcp"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPiqbLAXpBkjXnHLvz3VCd5i+VmYdd9dAcRt+8E1OQX drew@vega"
]; ];
} }

View File

@@ -0,0 +1,5 @@
{ ... }:
{
programs.adb.enable = true;
users.users.drew.extraGroups = [ "adbusers" ];
}

22
system/features/audio.nix Normal file
View File

@@ -0,0 +1,22 @@
{ ... }:
{
# RealtimeKit hands out realtime scheduling priority to user processes on
# demand, e.g. audio
security.rtkit.enable = true;
# Enable sound with pipewire.
services.pulseaudio = {
enable = false;
daemon.config = {
exit-idle-time = -1;
};
};
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
#jack.enable = true;
};
}

View File

@@ -0,0 +1,26 @@
{ ... }:
{
virtualisation = {
docker = {
enable = true;
# rootless = {
# enable = true;
# setSocketVariable = true;
# };
};
# Do not use Podman in Wayland/Hyperland. It will crash the session. Very annoying.
# podman.enable = true;
};
hardware.nvidia-container-toolkit.enable = true;
home-manager.users.drew =
{ ... }:
{
# Add the path to the docker socket to the environment.
programs.zsh.envExtra = ''
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
'';
};
}

View File

@@ -0,0 +1,12 @@
{ pkgs, ... }:
{
services.flatpak.enable = true;
systemd.services.flatpak-repo = {
wantedBy = [ "multi-user.target" ];
path = [ pkgs.flatpak ];
script = ''
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
'';
};
}

8
system/features/gc.nix Normal file
View File

@@ -0,0 +1,8 @@
{ ... }: {
# Automatic
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
}

View File

@@ -0,0 +1,50 @@
{ config, lib, ... }:
{
options =
with lib;
with types;
{
graphics = {
enable = mkEnableOption "graphics support";
driverChannel = mkOption {
type = str;
# Default to production because I often want new features, but I don't want bleeding edge.
default = "production";
description = "Driver channel to use (in order of oldest to newest): stable, beta, latest";
};
};
};
config = lib.mkIf config.graphics.enable {
# Graphics settings
hardware.graphics = {
enable = true;
enable32Bit = true;
};
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia = {
package = config.boot.kernelPackages.nvidiaPackages."${config.graphics.driverChannel}";
modesetting.enable = true;
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
# Enable this if you have graphical corruption issues or application crashes after waking
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
# of just the bare essentials.
powerManagement.enable = true;
# Fine-grained power management for PRIME. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
# Requires offload to be enabled.
# powerManagement.finegrained = false;
# Use the open-source driver?
open = false;
# Enable the nvidia-settings menu?
nvidiaSettings = true;
};
};
}

37
system/features/gui.nix Normal file
View File

@@ -0,0 +1,37 @@
{ ... }: {
# Enable the X11 windowing system and a display manager
services.xserver = {
enable = true;
displayManager.gdm = {
enable = true;
wayland = true;
};
# displayManager.sddm = {
# enable = true;
# wayland.enable = true;
# };
# Configure keymap in X11
xkb = {
layout = "us";
variant = "";
};
};
# services.displayManager.ly.enable = true;
# Enable Hyprland so it shows up in the menu
programs.hyprland = {
enable = true;
withUWSM = true;
xwayland.enable = true;
};
programs.sway = {
enable = true;
xwayland.enable = true;
wrapperFeatures = {
gtk = true;
base = true;
};
};
}

View File

@@ -0,0 +1,21 @@
{ pkgs, ... }:
{
services.printing = {
enable = true;
drivers = [ pkgs.brlaser ];
};
hardware.printers = {
ensurePrinters = [
{
name = "Brother_HL-L2370DW_series";
location = "Home";
deviceUri = "dnssd://Brother%20HL-L2370DW%20series._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-3c2af4f28c38";
model = "drv:///brlaser.drv/brl2370d.ppd";
ppdOptions = {
PageSize = "Letter";
};
}
];
ensureDefaultPrinter = "Brother_HL-L2370DW_series";
};
}

View File

@@ -0,0 +1,127 @@
{ config, lib, ... }:
{
options =
with lib;
with types;
{
virtualisation.web-containers = {
enable = mkEnableOption "web containers";
containers = mkOption {
type = lazyAttrsOf (submodule {
options =
let
strOpt = mkOption { type = str; };
intOpt = mkOption { type = int; };
boolOpt = mkOption {
type = bool;
default = false;
};
strList = mkOption {
type = listOf str;
default = [ ];
};
attrOpt = mkOption {
type = attrsOf str;
default = { };
};
in
{
image = strOpt;
hostname = strOpt;
port = intOpt;
homepageOpts = attrOpt;
dependsOn = strList;
domain = strOpt;
volumes = strList;
environment = attrOpt;
environmentFiles = strList;
public = boolOpt;
user = mkOption {
type = nullOr str;
default = null;
};
extraOptions = strList;
oauthProxy = boolOpt;
extraLabels = attrOpt;
};
});
default = { };
description = "";
};
};
};
config = {
virtualisation.oci-containers.containers = lib.mkIf config.virtualisation.web-containers.enable (
let
hostRule = host: domain: "Host(`${host}.${domain}`)";
localNet = "192.168.0.0/16";
dockerNet = "10.88.0.0/16";
localNetRule = "(ClientIP(`${localNet}`) || ClientIP(`${dockerNet}`))";
localHostRule = host: domain: "${localNetRule} && ${hostRule host domain}";
mkContainer =
key:
{
image,
hostname,
port,
homepageOpts,
dependsOn,
domain,
volumes,
environment,
environmentFiles,
public,
user,
extraOptions,
oauthProxy,
extraLabels,
}:
let
fqn = "${hostname}.${domain}";
serviceName = builtins.replaceStrings [ "." ] [ "-" ] fqn;
routerRule = if public then hostRule hostname domain else localHostRule hostname domain;
homepageLabels =
if homepageOpts == { } then
{ }
else
{
"homepage.group" = "${homepageOpts.group}";
"homepage.name" = "${homepageOpts.name}";
"homepage.icon" = "${homepageOpts.icon}";
"homepage.href" = "https://${fqn}";
"homepage.description" = "${homepageOpts.description}";
};
oauthLabels =
if oauthProxy then
{ "traefik.http.routers.${serviceName}.middlewares" = "oidc-auth@file"; }
else
{ };
in
{
inherit
image
dependsOn
volumes
environment
environmentFiles
user
extraOptions
;
autoStart = true;
labels = {
"traefik.enable" = "true";
"traefik.http.routers.${serviceName}.rule" = "${routerRule}";
"traefik.http.routers.${serviceName}.service" = "${serviceName}";
"traefik.http.routers.${serviceName}.entrypoints" = "web,websecure";
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
}
// oauthLabels
// homepageLabels
// extraLabels;
};
in
builtins.mapAttrs mkContainer config.virtualisation.web-containers.containers
);
};
}

View File

@@ -4,12 +4,11 @@
{ {
pkgs, pkgs,
inputs,
... ...
}: }:
{ {
networking.hostName = "drew-desktop"; # Define your hostname. networking.hostName = "altair"; # Define your hostname.
# Configure network proxy if necessary # Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/"; # networking.proxy.default = "http://user:password@proxy:port/";
@@ -38,15 +37,9 @@
LC_TIME = "en_US.UTF-8"; LC_TIME = "en_US.UTF-8";
}; };
# Enable the X11 windowing system. # Enable Ozone Wayland support in chromium and electron apps.
# You can disable this if you're only using the Wayland session. # https://nixos.wiki/wiki/Wayland
services.xserver.enable = true; environment.sessionVariables.NIXOS_OZONE_WL = "1";
services.displayManager.sddm = {
enable = true;
theme = "sddm-astronaut-theme";
};
# Unlock the default keyring on login to hyprland # Unlock the default keyring on login to hyprland
security.pam.services.hyprland.enableGnomeKeyring = true; security.pam.services.hyprland.enableGnomeKeyring = true;
@@ -59,21 +52,6 @@
''; '';
}; };
# Enable Hyprland so it shows up in the menu
programs.hyprland = {
enable = true;
withUWSM = true;
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
portalPackage =
inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland;
};
# Configure keymap in X11
services.xserver.xkb = {
layout = "us";
variant = "";
};
# Enable CUPS to print documents. # Enable CUPS to print documents.
services.printing = { services.printing = {
enable = true; enable = true;
@@ -92,7 +70,7 @@
services.gnome.gnome-keyring.enable = true; services.gnome.gnome-keyring.enable = true;
# Enable sound with pipewire. # Enable sound with pipewire.
services.pulseaudio.enable = false; hardware.pulseaudio.enable = false;
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {
enable = true; enable = true;
@@ -110,16 +88,10 @@
# Enable touchpad support (enabled default in most desktopManager). # Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true; # services.xserver.libinput.enable = true;
# Allow unfree packages
nixpkgs.config = {
allowUnfree = true;
};
# List packages installed in system profile. To search, run: # List packages installed in system profile. To search, run:
# $ nix search wget # $ nix search wget
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
vim vim
sddm-astronaut
]; ];
# Some programs need SUID wrappers, can be configured further or are # Some programs need SUID wrappers, can be configured further or are

View File

@@ -0,0 +1,25 @@
{ ... }:
{
imports = [
./configuration.nix
./hardware-configuration.nix
./qmk.nix
../../authorized-keys.nix
../../features/audio.nix
../../features/gc.nix
../../features/gui.nix
../../features/container-dev.nix
../../features/android-dev.nix
../../features/flatpak.nix
];
nixpkgs.config.allowUnfree = true;
home-manager.users.drew =
{ ... }:
{
imports = [
./drew.nix
];
};
}

View File

@@ -0,0 +1,58 @@
{ ... }:
let
monitors = [
"DP-1"
"DP-2"
];
in
{
imports =
map (x: ../../../home-manager + x) [
"/features/astronomy.nix"
"/features/chat.nix"
"/features/development/development.nix"
"/features/development/docker.nix"
"/features/development/haskell.nix"
"/features/development/markdown.nix"
"/features/development/typescript.nix"
"/features/development/vscode.nix"
"/features/eww"
"/features/gaming.nix"
"/features/image-editing.nix"
"/features/linux-desktop.nix"
"/features/notes.nix"
"/features/3d-printing.nix"
]
++ [
(import ../../../home-manager/features/wallpaper.nix monitors)
];
# This config file is needed for nix shell to allow unfree programs. I'm not
# sure why this isn't a home-manager option.
home.file.".config/nixpkgs/config.nix".text = ''
{ allowUnfree = true; }
'';
home.stateVersion = "24.11";
home.username = "drew";
home.homeDirectory = "/home/drew";
programs.git = {
userName = "Drew Haven";
userEmail = "drew.haven@gmail.com";
};
wayland.windowManager.hyprland.settings = {
exec-once = [
# Set up eww here because it's based on the monitor configuration
"sleep 2 && eww open-many primary-statusbar secondary-statusbar"
# Set DP-2 as the primary monitor, otherwise it defaults to DP-1 because it's first in the list.
"xrandr --output DP-2 --primary"
];
windowrulev2 = [
# Rofi doesn't center properly when I have the two asymetric monitors, so we need hyprland to manage it.
"center, class:Rofi"
];
};
}

View File

@@ -0,0 +1,121 @@
# 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,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
# Bootloader.
boot = {
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
initrd = {
availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
kernelModules = [ ];
};
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/343c0ac5-3973-49b3-964a-6ad90c36b89c";
fsType = "ext4";
};
"/boot" = {
device = "/dev/disk/by-uuid/5F99-043D";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
"/home" = {
device = "/dev/disk/by-uuid/28f4fb41-9414-4504-a767-c2e8bf5eb2c8";
fsType = "ext4";
};
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
services.xserver.videoDrivers = [ "nvidia" ];
hardware = {
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
graphics = {
enable = true;
enable32Bit = true;
};
nvidia = {
# Other options include:
# stable - Current stable
# production - Same as stable
# latest - Bleeding edge
# beta - latest beta
#
# See https://nixos.wiki/wiki/Nvidia
#
# Current versions can be found in https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/os-specific/linux/nvidia-x11/default.nix
#
package = config.boot.kernelPackages.nvidiaPackages.beta;
modesetting.enable = true;
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
# Enable this if you have graphical corruption issues or application crashes after waking
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
# of just the bare essentials.
powerManagement.enable = true;
# Fine-grained power management for PRIME. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
# Requires offload to be enabled.
# powerManagement.finegrained = false;
# Use the open-source driver?
open = false;
# Enable the nvidia-settings menu?
nvidiaSettings = true;
};
};
# Add a udev rule to prevent the mouse from waking the system. Note that it
# has two entries depending on whether it's plugged in or not.
# Bus 001 Device 009: ID 046d:c539 Logitech, Inc. Lightspeed Receiver
# Bus 001 Device 015: ID 046d:c08d Logitech, Inc. G502 LIGHTSPEED Wireless Gaming Mouse
# Note: Still seem to require `sudo udevadm trigger` or reconnecting the device after the change.
services.udev.extraRules = ''
ACTION=="add|change", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c539", ATTR{power/wakeup}="disabled"
ACTION=="add|change", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c08d", ATTR{power/wakeup}="disabled"
'';
}

View File

@@ -0,0 +1,12 @@
# See https://nixos.wiki/wiki/Qmk
{ pkgs, ... }:
{
# Allows access to keyboard configuration as a non-root user.
hardware.keyboard.qmk.enable = true;
# Add VIA to udev for firmwares that support it.
environment.systemPackages = with pkgs; [
via
];
services.udev.packages = [ pkgs.via ];
}

View File

@@ -1,28 +0,0 @@
{ nixpkgs, inputs, ... }:
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
./hardware-configuration.nix
../../authorized-keys.nix
inputs.home-manager.nixosModules.home-manager
{
nixpkgs.config.allowUnfree = true;
home-manager.users.drew =
{ ... }:
{
imports = [
./drew.nix
];
};
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = {
inherit inputs;
};
}
];
specialArgs = {
inherit inputs;
};
}

View File

@@ -1,35 +0,0 @@
{ pkgs, ... }:
{
imports = map (x: ../../../home-manager + x) [
"/features/development/development.nix"
"/features/development/haskell.nix"
"/features/gaming.nix"
"/features/linux-desktop.nix"
"/features/notes.nix"
"/features/eww"
];
home.stateVersion = "24.11";
home.username = "drew";
home.homeDirectory = "/home/drew";
programs.git = {
userName = "Drew Haven";
userEmail = "drew.haven@gmail.com";
};
home.packages = with pkgs; [
# Applications
discord
signal-desktop
obsidian
firefox
];
# Set up eww here because it's based on the monitor configuration
# Eww is idempotent, so it's fine to just run it on every reload to make sure things are open
wayland.windowManager.hyprland.settings.execr-once = [
"eww open-many primary-statusbar secondary-statusbar launcher"
];
}

View File

@@ -1,103 +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,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/343c0ac5-3973-49b3-964a-6ad90c36b89c";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/5F99-043D";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
fileSystems."/home" = {
device = "/dev/disk/by-uuid/28f4fb41-9414-4504-a767-c2e8bf5eb2c8";
fsType = "ext4";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Graphics settings
hardware.graphics = {
enable = true;
enable32Bit = true;
};
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia = {
package = config.boot.kernelPackages.nvidiaPackages.beta;
modesetting.enable = true;
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
# Enable this if you have graphical corruption issues or application crashes after waking
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
# of just the bare essentials.
powerManagement.enable = true;
# Fine-grained power management for PRIME. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
# Requires offload to be enabled.
# powerManagement.finegrained = false;
# Use the open-source driver?
open = false;
# Enable the nvidia-settings menu?
nvidiaSettings = true;
};
# Add a udev rule to prevent the mouse from waking the system. Note that it
# has two entries depending on whether it's plugged in or not.
# Bus 001 Device 009: ID 046d:c539 Logitech, Inc. Lightspeed Receiver
# Bus 001 Device 015: ID 046d:c08d Logitech, Inc. G502 LIGHTSPEED Wireless Gaming Mouse
# Note: Still seem to require `sudo udevadm trigger` or reconnecting the device after the change.
services.udev.extraRules = ''
ACTION=="add|change", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c539", ATTR{power/wakeup}="disabled"
ACTION=="add|change", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c08d", ATTR{power/wakeup}="disabled"
'';
}

View File

@@ -1,4 +1,4 @@
{ config, pkgs, ... }: { pkgs, ... }:
{ {
imports = [ imports = [
./vars.nix ./vars.nix
@@ -16,9 +16,6 @@
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
# Set the kernel to be compatible with ZFS
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
networking.hostName = "mcp"; # Define your hostname. networking.hostName = "mcp"; # Define your hostname.
networking.hostId = "5e292f2d"; # Define a host ID for ZFS with `head -c 8 /etc/machine-id` networking.hostId = "5e292f2d"; # Define a host ID for ZFS with `head -c 8 /etc/machine-id`
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
@@ -62,8 +59,12 @@
"networkmanager" "networkmanager"
"wheel" "wheel"
"docker-registry" "docker-registry"
"docker"
]; ];
shell = pkgs.zsh; shell = pkgs.zsh;
# Enable linger so that systemd services run for this user are started and
# persist even without an active session.
linger = true;
}; };
# List packages installed in system profile. To search, run: # List packages installed in system profile. To search, run:
@@ -93,7 +94,8 @@
port = 5000; port = 5000;
openFirewall = true; openFirewall = true;
# Bind to the podman network so Traefik can route to it. # Bind to the podman network so Traefik can route to it.
# Note that it may fail to start if this network has not been created yet. # Note that it may fail to start if this network has not been created yet,
# so this has to be manually restarted when the system boots.
listenAddress = "10.88.0.1"; listenAddress = "10.88.0.1";
}; };
@@ -104,8 +106,10 @@
enabledCollectors = [ "systemd" ]; enabledCollectors = [ "systemd" ];
port = 9002; port = 9002;
# Open the firewall, but only listen on the internal address # Open the firewall, but only listen on the internal address
# TODO: Add some form authentication
openFirewall = true; openFirewall = true;
# Bind to the podman network so Traefik can route to it.
# Note that it may fail to start if this network has not been created yet,
# so this has to be manually restarted when the system boots.
listenAddress = "10.88.0.1"; listenAddress = "10.88.0.1";
}; };
}; };
@@ -115,6 +119,7 @@
# So I don't have to use public relays # So I don't have to use public relays
services.syncthing.relay = { services.syncthing.relay = {
enable = true; enable = true;
# Leave this empty, meaning it won't join any public pools.
pools = [ ]; pools = [ ];
}; };
@@ -122,6 +127,7 @@
# Open ports in the firewall. # Open ports in the firewall.
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [
22067 # Syncthing relay 22067 # Syncthing relay
22070 # Syncthing relay status
]; ];
# networking.firewall.allowedUDPPorts = [ ... ]; # networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether. # Or disable the firewall altogether.

View File

@@ -1,26 +1,100 @@
# Started from https://nixos.wiki/wiki/Podman {
{ config, pkgs, ... }: config,
pkgs,
lib,
...
}:
{ {
# Additional configuration # Additional configuration
imports = [ imports = [
./containers/bookstack.nix ./containers/havenisms.com
./containers/blazestar.net
# Docker containers
./containers/dm-companion.nix
./containers/freshrss.nix
./containers/gitea.nix ./containers/gitea.nix
./containers/goatcounter.nix
./containers/grafana.nix ./containers/grafana.nix
./containers/jobhunt.nix # ./containers/jobhunt.nix
./containers/mariadb.nix ./containers/mariadb.nix
./containers/media-system.nix
./containers/nextcloud.nix ./containers/nextcloud.nix
./containers/prometheus.nix # ./containers/offen.nix
./containers/pocket-id.nix ./containers/pocket-id.nix
./containers/prometheus.nix
./containers/public-homepage.nix ./containers/public-homepage.nix
./containers/searxng.nix ./containers/searxng.nix
./containers/shared-postgres.nix ./containers/shared-postgres.nix
./containers/synapse.nix # ./containers/timetagger.nix
./containers/traefik.nix
./containers/users.nix
# NixOS Containers
./static-site-hooks.nix
]; ];
options.local = with lib; {
container-backend = mkOption {
type = with types; uniq str;
default = "docker";
example = "docker";
description = "Which backend to use for containers: docker or podman";
};
container-socket = mkOption {
type = with types; uniq str;
default = "/var/run/docker.sock";
example = "/var/run/docker.sock";
description = "Path to the container management deamon's socket.";
};
};
config = {
# local = {
# container-backend = "docker";
# container-socket = "/var/run/docker.sock";
# };
local = {
container-backend = "podman";
container-socket = "/var/run/podman/podman.sock";
};
# Enable common container config files in /etc/containers # Enable common container config files in /etc/containers
virtualisation.containers.enable = true;
virtualisation = { virtualisation = {
podman = { containers.enable = true;
oci-containers.backend = config.local.container-backend;
docker = lib.mkIf (config.local.container-backend == "docker") {
enable = true;
# Enable rootless so that I can run containers as other users for security.
rootless = {
enable = true;
# Set this to make the default DOCKER_HOST be the rootless version for normal users.
setSocketVariable = true;
daemon = {
settings = {
default-address-pools = [
{
base = "10.88.0.0/16";
size = 24;
}
];
};
};
};
daemon = {
settings = {
default-address-pools = [
{
base = "10.88.0.0/16";
size = 24;
}
];
};
};
};
podman = lib.mkIf (config.local.container-backend == "podman") {
enable = true; enable = true;
# Create a `docker` alias for podman, to use it as a drop-in replacement # Create a `docker` alias for podman, to use it as a drop-in replacement
@@ -36,286 +110,17 @@
# Useful other development tools # Useful other development tools
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
dive # look into docker image layers dive # look into docker image layers
podman-tui # status of containers in the terminal
docker-compose # start group of containers for dev docker-compose # start group of containers for dev
#podman-compose # start group of containers for dev
]; ];
users.groups = {
git = { };
timetagger = { };
};
users.users = {
gitea = {
uid = 2001;
isSystemUser = true;
description = "System User for Gitea";
extraGroups = [ "git" ];
group = "git";
};
timetagger = {
uid = 2002;
isSystemUser = true;
description = "System User for TimeTagger";
group = "timetagger";
};
};
virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers = virtualisation.oci-containers.containers =
let let
inherit (import ./containers/lib.nix config) inherit (import ./containers/lib.nix config)
hostRuleHavenisms
localHostRuleHavenisms localHostRuleHavenisms
havenisms; havenisms
;
in in
{ {
traefik = {
image = "traefik";
autoStart = true;
cmd = [ ];
extraOptions = [
# Proxying Traefik itself
"-l=traefik.enable=true"
"-l=traefik.http.routers.traefik.rule=${localHostRuleHavenisms "proxy"}"
"-l=traefik.http.services.traefik.loadbalancer.server.port=8080"
"-l=homepage.group=Infra"
"-l=homepage.name=Traefik"
"-l=homepage.icon=traefik.svg"
"-l=homepage.href=https://proxy.${havenisms}"
"-l=homepage.description=Reverse proxy"
"-l=homepage.widget.type=traefik"
"-l=homepage.widget.url=http://traefik:8080"
];
ports = [
"443:443"
"80:80"
];
environmentFiles = [
];
volumes = [
"/var/run/podman/podman.sock:/var/run/docker.sock:ro"
"/tank/config/traefik:/etc/traefik"
];
};
jellyfin = {
image = "lscr.io/linuxserver/jellyfin";
autoStart = true;
extraOptions = [
"--device=/dev/dri:/dev/dri"
"-l=traefik.enable=true"
"-l=traefik.http.routers.jellyfin.rule=${hostRuleHavenisms "jellyfin"}"
"-l=traefik.http.services.jellyfin.loadbalancer.server.port=8096"
"-l=homepage.group=Apps"
"-l=homepage.name=Jellyfin"
"-l=homepage.icon=jellyfin.svg"
"-l=homepage.href=https://jellyfin.${havenisms}"
"-l=homepage.description=Media player"
"-l=homepage.widget.type=jellyfin"
"-l=homepage.widget.key={{HOMEPAGE_FILE_JELLYFIN_KEY}}"
"-l=homepage.widget.url=http://jellyfin:8096"
"-l=homepage.widget.enableBlocks=true"
];
volumes = [
"/tank/media/collection:/data"
"/tank/config/jellyfin:/config"
];
# environment = {
# TZ = vars.timeZone;
# PUID = "994";
# UMASK = "002";
# GUID = "993";
# };
};
deluge = {
image = "linuxserver/deluge:latest";
autoStart = true;
dependsOn = [
"gluetun"
];
extraOptions = [
"--network=container:gluetun"
"-l=homepage.group=Arr"
"-l=homepage.name=Deluge"
"-l=homepage.icon=deluge.svg"
"-l=homepage.href=https://deluge.${havenisms}"
"-l=homepage.description=Torrent client"
"-l=homepage.widget.type=deluge"
"-l=homepage.widget.password={{HOMEPAGE_FILE_DELUGE_PASSWORD}}"
"-l=homepage.widget.url=http://gluetun:8112"
];
volumes = [
"/tank/media:/data"
"/tank/config/deluge:/config"
];
};
qbittorrent = {
image = "linuxserver/qbittorrent:latest";
autoStart = true;
dependsOn = [
"gluetun"
];
extraOptions = [
"--network=container:gluetun"
"-l=homepage.group=Arr"
"-l=homepage.name=qBitTorrent"
"-l=homepage.icon=qbittorrent.svg"
"-l=homepage.href=https://torrents.${havenisms}"
"-l=homepage.description=Torrent client"
"-l=homepage.widget.type=qbittorrent"
"-l=homepage.widget.url=http://torrents.${havenisms}"
];
volumes = [
"/tank/media/Downloads:/downloads"
"/tank/config/qbittorrent:/config"
];
environment = {
PUID = "911";
PGID = "911";
UMASK = "002";
};
};
gluetun = {
image = "qmcgaw/gluetun:latest";
autoStart = true;
extraOptions = [
# add network admin capability.
"--cap-add=NET_ADMIN"
"--device=/dev/net/tun:/dev/net/tun"
"-l=traefik.enable=true"
"-l=traefik.http.routers.torrents.rule=${localHostRuleHavenisms "torrents"}"
"-l=traefik.http.routers.torrents.service=torrents"
"-l=traefik.http.services.torrents.loadbalancer.server.port=8080"
"-l=homepage.group=Infra"
"-l=homepage.name=GlueTun"
"-l=homepage.icon=gluetun.svg"
"-l=homepage.href=https://torrents.${havenisms}"
"-l=homepage.description=VPN killswitch"
"-l=homepage.widget.type=gluetun"
"-l=homepage.widget.url=http://gluetun:8000"
];
ports = [
"127.0.0.1:8083:8000"
];
environmentFiles = [
"/tank/config/gluetun/vpn.env"
];
environment = {
VPN_SERVICE_PROVIDER = "protonvpn";
UMASK = "002";
};
};
prowlarr = {
image = "lscr.io/linuxserver/prowlarr";
autoStart = true;
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.prowlarr.rule=${localHostRuleHavenisms "prowlarr"}"
"-l=traefik.http.services.prowlarr.loadbalancer.server.port=9696"
"-l=homepage.group=Arr"
"-l=homepage.name=Prowlarr"
"-l=homepage.icon=prowlarr.svg"
"-l=homepage.href=https://prowlarr.${havenisms}"
"-l=homepage.description=Torrent indexer"
];
volumes = [
"/tank/config/prowlarr:/config"
];
environment = {
UMASK = "002";
};
};
# Currently broken and doesn't work. :(
# flaresolverr = {
# image = "ghcr.io/flaresolverr/flaresolverr:latest";
# autoStart = true;
# extraOptions = [
# "-l=homepage.group=Infra"
# "-l=homepage.name=FlareSolverr"
# "-l=homepage.icon=flaresolverr.svg"
# "-l=homepage.href=https://flaresolverr.${domain}"
# "-l=homepage.description=Cloudflare bypass"
# ];
# volumes = [
# "/tank/config/flaresolverr:/config"
# ];
# environment = {
# UMASK = "002";
# };
# };
radarr = {
image = "lscr.io/linuxserver/radarr";
autoStart = true;
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.radarr.rule=${localHostRuleHavenisms "radarr"}"
"-l=traefik.http.services.radarr.loadbalancer.server.port=7878"
"-l=homepage.group=Arr"
"-l=homepage.name=Radarr"
"-l=homepage.icon=radarr.svg"
"-l=homepage.href=https://radarr.${havenisms}"
"-l=homepage.description=Movie acquisition"
"-l=homepage.widget.type=radarr"
"-l=homepage.widget.url=http://radarr:7878"
"-l=homepage.widget.key={{HOMEPAGE_FILE_RADARR_KEY}}"
];
volumes = [
"/tank/media:/data"
"/tank/config/radarr:/config"
];
environment = {
UMASK = "002";
};
};
sonarr = {
image = "lscr.io/linuxserver/sonarr";
autoStart = true;
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.sonarr.rule=${localHostRuleHavenisms "sonarr"}"
"-l=traefik.http.services.sonarr.loadbalancer.server.port=8989"
"-l=homepage.group=Arr"
"-l=homepage.name=Sonarr"
"-l=homepage.icon=sonarr.svg"
"-l=homepage.href=https://sonarr.${havenisms}"
"-l=homepage.description=Show acquisition"
"-l=homepage.widget.type=sonarr"
"-l=homepage.widget.url=http://sonarr:8989"
"-l=homepage.widget.key={{HOMEPAGE_FILE_SONARR_KEY}}"
];
volumes = [
"/tank/media:/data"
"/tank/config/sonarr:/config"
];
environment = {
UMASK = "002";
};
};
readarr = {
# The Linuxserver version of this image doesn't have a latest tag. Odd.
image = "lscr.io/linuxserver/readarr:develop";
autoStart = true;
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.readarr.rule=${localHostRuleHavenisms "readarr"}"
"-l=traefik.http.services.readarr.loadbalancer.server.port=8787"
"-l=homepage.group=Arr"
"-l=homepage.name=Readarr"
"-l=homepage.icon=readarr.svg"
"-l=homepage.href=https://readarr.${havenisms}"
"-l=homepage.description=E-book acquisition"
"-l=homepage.widget.type=readarr"
"-l=homepage.widget.url=http://readarr.havenisms.com:8787"
"-l=homepage.widget.key={{HOMEPAGE_FILE_READARR_KEY}}"
];
volumes = [
"/tank/media:/data"
"/tank/config/readarr:/config"
];
environment = {
UMASK = "002";
};
};
homepage = { homepage = {
image = "ghcr.io/gethomepage/homepage:latest"; image = "ghcr.io/gethomepage/homepage:latest";
autoStart = true; autoStart = true;
@@ -330,7 +135,7 @@
"/tank/secrets/jellyfin.key:/app/config/secrets/jellyfin.key" "/tank/secrets/jellyfin.key:/app/config/secrets/jellyfin.key"
"/tank/secrets/radarr.key:/app/config/secrets/radarr.key" "/tank/secrets/radarr.key:/app/config/secrets/radarr.key"
"/tank/secrets/sonarr.key:/app/config/secrets/sonarr.key" "/tank/secrets/sonarr.key:/app/config/secrets/sonarr.key"
"/var/run/podman/podman.sock:/var/run/docker.sock:ro" "${config.local.container-socket}:/var/run/docker.sock:ro"
]; ];
environment = { environment = {
HOMEPAGE_FILE_JELLYFIN_KEY = "/app/config/secrets/jellyfin.key"; HOMEPAGE_FILE_JELLYFIN_KEY = "/app/config/secrets/jellyfin.key";
@@ -355,10 +160,10 @@
"-l=homepage.widget.type=scrutiny" "-l=homepage.widget.type=scrutiny"
"-l=homepage.widget.url=http://scrutiny:8080" "-l=homepage.widget.url=http://scrutiny:8080"
"--cap-add=SYS_RAWIO" "--cap-add=SYS_RAWIO"
"--device=/dev/sda:/dev/sda" "--device=/dev/disk/by-id/wwn-0x5000cca26fca1aed:/dev/disk/by-id/wwn-0x5000cca26fca1aed"
"--device=/dev/sdb:/dev/sdb" "--device=/dev/disk/by-id/wwn-0x5000cca26fef696c:/dev/disk/by-id/wwm-0x5000cca26fef696c"
"--device=/dev/sdc:/dev/sdc" "--device=/dev/disk/by-id/wwn-0x5000cca270db1d0e:/dev/disk/by-id/wwn-0x5000cca270db1d0e"
"--device=/dev/sdd:/dev/sdd" # "--device=/dev/sdd:/dev/sdd" Removing this one while the disk is down
]; ];
volumes = [ volumes = [
"/run/udev:/run/udev:ro" "/run/udev:/run/udev:ro"
@@ -374,4 +179,5 @@
]; ];
}; };
}; };
};
} }

View File

@@ -0,0 +1,104 @@
{ config, ... }:
let
inherit (import ../lib.nix config) mkContainer blazestar;
matrixHost = "matrix";
serviceName = "matrix-blazestar-net";
dbPath = "/var/lib/matrix";
port = 8448;
in
{
sops.secrets = {
"matrix/blazestar-registration-token" = {
restartUnits = [ "${config.local.container-backend}-matrix-blazestar-net.service" ];
};
};
sops.templates."matrix-blazestar-net.env".content = ''
TUWUNEL_REGISTRATION_TOKEN=${config.sops.placeholder."matrix/blazestar-registration-token"}
'';
# This isn't using any of my usual helpers because I wanted to set a custom
# serviceName in Traefik that is different from the hostname to avoid
# conflicts with the havenisms.com server.
virtualisation.oci-containers.containers."${serviceName}" = {
# The 1.1.0 version has an issue with the compression being incorrectly tagged.
# See: https://github.com/matrix-construct/tuwunel/issues/79
image = "ghcr.io/matrix-construct/tuwunel:v1.0.0-release-all-x86_64-linux-gnu";
autoStart = true;
volumes = [
"matrix-blazestar-net-db:${dbPath}"
];
environment = {
TUWUNEL_PORT = toString port;
TUWUNEL_ADDRESS = "0.0.0.0"; # It'll bind to localhost by default with Podman
TUWUNEL_SERVER_NAME = "blazestar.net";
TUWUNEL_ALLOW_REGISTRATION = "true";
TUWUNEL_ALLOW_CHECK_FOR_UPDATES = "true";
TUWUNEL_ALLOW_FEDERATION = "true";
TUWUNEL_DATABASE_BACKEND = "rocksdb";
TUWUNEL_DATABASE_PATH = dbPath;
TUWUNEL_WELL_KNOWN = ''
{
client=https://${matrixHost}.blazestar.net,
server=${matrixHost}.blazestar.net:443
}
'';
TUWUNEL_TRUSTED_SERVERS = ''["matrix.org", "chat.havenisms.com"]'';
};
environmentFiles = [
config.sops.templates."matrix-blazestar-net.env".path
];
labels = {
"traefik.enable" = "true";
"traefik.http.routers.${serviceName}.rule" = "Host(`${matrixHost}.${blazestar}`)";
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
# Redirect well-known requests to this host.
"traefik.http.routers.${matrixHost}-blazestar-net-well-known.rule" =
"Host(`blazestar.net`) && PathPrefix(`/.well-known/matrix`)";
"traefik.http.routers.${matrixHost}-blazestar-net-well-known.service" = serviceName;
};
};
# virtualisation.oci-containers.containers.matrix-blazestar-net =
# mkContainer {
# image = "registry.gitlab.com/famedly/conduit/matrix-conduit:latest";
# hostName = hostname;
# domain = blazestar;
# port = port;
# ports = [
# "8449:6167"
# ];
# volumes = [
# "chat-blazestar-net-db:${dbPath}"
# ];
# environment = {
# CONDUIT_PORT = "6167";
# CONDUIT_SERVER_NAME = "blazestar.net";
# CONDUIT_ALLOW_REGISTRATION = "true";
# CONDUIT_DATABASE_BACKEND = "rocksdb";
# CONDUIT_DATABASE_PATH = dbPath;
# CONDUIT_ALLOW_CHECK_FOR_UPDATES = "true";
# CONDUIT_ALLOW_FEDERATION = "true";
# CONDUIT_MAX_REQUEST_SIZE = "20000000";
# CONDUIT_TRUSTED_SERVERS = "[\"matrix.org\"]";
# CONDUIT_MAX_CONCURRENT_REQUESTS = "100";
# CONDUIT_WELL_KNOWN_CLIENT = "https://${hostname}.blazestar.net";
# CONDUIT_WELL_KNOWN_SERVER = "${hostname}.blazestar.net:443";
# CONDUIT_CONFIG = ""; # Ignore the config file
# };
# extraLabels = {
# "traefik.http.routers.${hostname}-blazestar-net-well-known.rule" =
# "Host(`blazestar.net`) && PathPrefix(`/.well-known`)";
# "traefik.http.routers.${hostname}-blazestar-net-well-known.service" = "${hostname}-blazestar-net";
# };
# };
virtualisation.oci-containers.containers.chat = mkContainer {
image = "vectorim/element-web:latest";
hostName = "chat";
port = 8080;
domain = blazestar;
environment = {
ELEMENT_WEB_PORT = "8080";
};
};
}

View File

@@ -0,0 +1,7 @@
{ ... }:
{
imports = [
./chat.nix
./uptime.nix
];
}

View File

@@ -0,0 +1,15 @@
{ config, ... }:
let
inherit (import ../lib.nix config) blazestar;
in
{
virtualisation.web-containers.containers.uptime = {
image = "louislam/uptime-kuma:1";
hostname = "uptime";
domain = blazestar;
port = 3001;
volumes = [
"uptime-kuma:/app/data"
];
};
}

View File

@@ -1,37 +1,26 @@
{ config, ... }: { config, ... }:
let let
inherit (import ./lib.nix config) mkContainer mkMariaDbContainer havenisms; inherit (import ./lib.nix config) mkContainer mkMariaDbContainer havenisms;
userIds = import ./user-ids.nix; in
in { {
imports = [ imports = [
(mkMariaDbContainer { (mkMariaDbContainer {
name = "bookstack"; name = "bookstack";
uid = userIds.bookstack.uid; uid = config.users.users.bookstack.uid;
gid = userIds.bookstack.gid; gid = config.users.groups.bookstack.gid;
directory = "/tank/bookstack/db"; directory = "/tank/bookstack/db";
passwordSecret = "bookstack_db"; passwordSecret = "bookstack_db";
}) })
]; ];
users.groups.bookstack = {
gid = userIds.bookstack.gid;
};
users.users.bookstack = {
uid = userIds.bookstack.uid;
isSystemUser = true;
description = "System User for Bookstack";
group = "bookstack";
};
sops.secrets = { sops.secrets = {
bookstack_app_key = { bookstack_app_key = {
restartUnits = [ "podman-bookstack.service" ]; restartUnits = [ "${config.local.container-backend}-bookstack.service" ];
mode = "0400"; mode = "0400";
owner = config.users.users.bookstack.name; owner = config.users.users.bookstack.name;
}; };
bookstack_db = { bookstack_db = {
restartUnits = [ "podman-bookstack-mariadb.service" ]; restartUnits = [ "${config.local.container-backend}-bookstack-mariadb.service" ];
mode = "0400"; mode = "0400";
owner = config.users.users.bookstack.name; owner = config.users.users.bookstack.name;
}; };
@@ -55,8 +44,8 @@ in {
]; ];
environment = { environment = {
APP_URL = "https://bookstack.${havenisms}"; APP_URL = "https://bookstack.${havenisms}";
PID = toString userIds.bookstack.uid; PID = toString config.users.users.bookstack.uid;
GID = toString userIds.bookstack.gid; GID = toString config.users.groups.bookstack.gid;
DB_HOST = "bookstack-mariadb"; DB_HOST = "bookstack-mariadb";
DB_USERNAME = "bookstack"; DB_USERNAME = "bookstack";
DB_DATABASE = "bookstack"; DB_DATABASE = "bookstack";

View File

@@ -0,0 +1,108 @@
{ config, pkgs, ... }:
let
inherit (import ./lib.nix config) mkContainer localHostRule terakoda;
nginxConf = pkgs.writeText "dm-companion-nginx.conf" ''
user nginx;
worker_processes auto;
# error.log is symlinked to /dev/stderr
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# access.log is symlinked to /dev/stdout
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name dm.blazestar.net;
root /usr/share/nginx/html;
# X-Frame-Options is to prevent from clickJacking attack
add_header X-Frame-Options SAMEORIGIN;
# disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;
# This header enables the Cross-site scripting (XSS) filter
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "no-referrer-when-downgrade";
# Enables response header of "Vary: Accept-Encoding"
# This lets the cache have different entries depending on the encoding, e.g. compression
gzip_vary on;
# Serve static files separately.
location ~ ^/(robots.txt|manifest.json) {
expires modified 1y;
add_header Cache-Control "public";
access_log off;
}
location / {
try_files $uri $uri/ /index.html;
index index.html;
expires -1;
add_header Cache-Control "no-store, no-cache, must-revalidate";
}
}
}
'';
in
{
virtualisation.oci-containers.containers = {
dm-companion-pocketbase =
let
hostName = "dm-pocketbase";
in
mkContainer {
inherit hostName;
image = "docker.havenisms.com/lazy-dm/pocketbase";
domain = terakoda;
port = 8080;
volumes = [
"/tank/web/dm.terakoda.com/pb_data:/pb/pb_data"
"/tank/web/dm.terakoda.com/pb_migrations:/pb/pb_migrations:ro"
];
environment = { };
extraLabels = {
"traefik.http.routers.${hostName}-api.rule" =
"PathPrefix(`/api`) && ${localHostRule "dm" terakoda}";
"traefik.http.routers.${hostName}-api.service" = "${hostName}";
};
};
dm-companion = mkContainer {
image = "nginx:alpine";
hostName = "dm";
domain = terakoda;
port = 80;
dependsOn = [
"dm-companion-pocketbase"
];
volumes = [
"/tank/web/dm.terakoda.com/deployed:/usr/share/nginx/html:ro"
"${nginxConf}:/etc/nginx/nginx.conf:ro"
];
};
};
}

View File

@@ -0,0 +1,67 @@
{ config, ... }:
let
inherit (import ./lib.nix config) mkContainer mkPostgresContainer terakoda;
in
{
imports = [
(mkPostgresContainer {
name = "focalboard";
directory = "/tank/focalboard/db";
uid = config.users.users.focalboard.uid;
gid = config.users.groups.focalboard.gid;
passwordSecret = "focalboard/database";
})
];
sops.secrets = {
"focalboard/database" = {
restartUnits = [
"${config.local.container-backend}-focalboard.service"
"${config.local.container-backend}-focalboard-postgres.service"
];
mode = "0400";
owner = config.users.users.focalboard.name;
};
};
sops.templates."focalboard-config.json" = {
restartUnits = [ "${config.local.container-backend}-focalboard.service" ];
owner = config.users.users.focalboard.name;
content = builtins.toJSON {
# Defaults from https://github.com/mattermost-community/focalboard/blob/main/config.json
"serverRoot" = "https://focalboard.terakoda.com";
"port" = 8000;
"dbtype" = "postgres";
"dbconfig" = "postgres://focalboard:${
config.sops.placeholder."focalboard/database"
}@focalboard-postgres/focalboard?sslmode=disable&connect_timeout=10";
"useSSL" = true;
"prometheus_address" = ":9092";
"session_expire_time" = 2592000;
"session_refresh_time" = 18000;
"postgres_dbconfig" = "dbname=focalboard sslmode=disable";
"webpath" = "./pack";
"filespath" = "./data/files";
"telemetry" = true;
"prometheusaddress" = ":9092";
"enableLocalMode" = true;
"localModeSocketLocation" = "/var/tmp/focalboard_local.socket";
};
};
virtualisation.oci-containers.containers = {
focalboard = mkContainer {
image = "mattermost/focalboard";
hostName = "focalboard";
domain = terakoda;
dependsOn = [ "focalboard-postgres" ];
port = 8000;
user = "${toString config.users.users.focalboard.uid}:${toString config.users.groups.focalboard.gid}";
volumes = [
"/tank/focalboard/data/files:/opt/focalboard/data/files"
"${config.sops.templates."focalboard-config.json".path}:/opt/focalboard/config.json:ro"
];
};
};
}

View File

@@ -0,0 +1,20 @@
{ config, ... }:
let
inherit (import ./lib.nix config) mkContainer havenisms;
in {
virtualisation.oci-containers.containers.freshrss = mkContainer {
image = "lscr.io/linuxserver/freshrss:latest";
hostName = "freshrss";
domain = havenisms;
port = "80";
homepageOpts = {
group = "Apps";
name = "FreshRSS";
icon = "freshrss.svg";
description = "Feed aggregator";
};
volumes = [
"/tank/config/freshrss:/config"
];
};
}

View File

@@ -1,24 +1,40 @@
{ config, ... }: { config, ... }:
let let
inherit (import ./lib.nix config) hostRule blazestar; inherit (import ./lib.nix config) mkContainer blazestar;
in in
{ {
virtualisation.oci-containers.containers.gitea = { sops.secrets = {
"gitea/db_password" = {
restartUnits = [ "${config.local.container-backend}-gitea.service" ];
};
"gitea/registration_token" = {
restartUnits = [ "${config.local.container-backend}-gitea-runner.service" ];
};
};
sops.templates."gitea.env".content = ''
GITEA__database__DB_TYPE="postgres"
GITEA__database__HOST="db"
GITEA__database__NAME="gitea"
GITEA__database__USER="gitea"
GITEA__database__PASSWD="${config.sops.placeholder."gitea/db_password"}"
'';
virtualisation.oci-containers.containers.gitea = mkContainer {
image = "gitea/gitea:latest-rootless"; image = "gitea/gitea:latest-rootless";
autoStart = true;
dependsOn = [ dependsOn = [
"db" "db"
]; ];
extraOptions = [ hostName = "git";
"-l=traefik.enable=true" domain = blazestar;
"-l=traefik.http.routers.gitea.rule=${hostRule "git" blazestar}" public = true;
"-l=traefik.http.services.gitea.loadbalancer.server.port=3000" port = 3000;
"-l=homepage.group=Apps" homepageOpts = {
"-l=homepage.name=Gitea" name = "Gitea";
"-l=homepage.icon=gitea.png" icon = "gitea.png";
"-l=homepage.href=https://git.${blazestar}" description = "Git Server";
"-l=homepage.description=Git Server" group = "Apps";
]; };
ports = [ ports = [
"2222:2222" "2222:2222"
]; ];
@@ -36,14 +52,21 @@ in
]; ];
}; };
sops.secrets."gitea_db_password" = { sops.templates."gitea-runner.env".content = ''
restartUnits = [ "podman-gitea.service" ]; GITEA_RUNNER_NAME=MCP
}; GITEA_INSTANCE_URL=https://git.${blazestar}
sops.templates."gitea.env".content = '' GITEA_RUNNER_REGISTRATION_TOKEN=${config.sops.placeholder."gitea/registration_token"}
GITEA__database__DB_TYPE="postgres"
GITEA__database__HOST="db"
GITEA__database__NAME="gitea"
GITEA__database__USER="gitea"
GITEA__database__PASSWD="${config.sops.placeholder."gitea_db_password"}"
''; '';
virtualisation.oci-containers.containers.gitea-runner = {
image = "gitea/act_runner:latest";
autoStart = true;
environmentFiles = [
config.sops.templates."gitea-runner.env".path
];
volumes = [
# The runner will spawn new containers to run the actions
"${config.local.container-socket}:/var/run/docker.sock:ro"
];
};
} }

View File

@@ -0,0 +1,58 @@
{ config, ... }:
let
inherit (import ./lib.nix config)
terakoda
blazestar
hostRule
;
in
{
imports = [
../../../features/web-containers.nix
];
virtualisation.web-containers = {
enable = true;
containers = {
goatcounter-terakoda = {
image = "arp242/goatcounter";
hostname = "goatcounter";
domain = terakoda;
public = true;
port = 8080;
volumes = [
"goatcounter-data:/home/goatcounter/goatcounter-data"
];
extraLabels = {
# "traefik.http.middlewares.strip-analytics.stripprefix.prefixes" = "/analytics";
# "traefik.http.routers.www-terakoda-com-goatcounter.middlewares" = "strip-analytics";
# Host the script on www.terakoda.com so that it is easy to fetch
"traefik.http.routers.www-terakoda-com-goatcounter.rule" =
"PathPrefix(`/count`) && ${hostRule "www" terakoda}";
"traefik.http.routers.www-terakoda-com-goatcounter.entrypoints" = "websecure";
"traefik.http.routers.www-terakoda-com-goatcounter.service" = "goatcounter-terakoda-com";
};
};
goatcounter-blazestar = {
image = "arp242/goatcounter";
hostname = "goatcounter";
domain = blazestar;
public = true;
port = 8080;
volumes = [
"goatcounter-data-blazestar:/home/goatcounter/goatcounter-data"
];
extraLabels = {
# "traefik.http.middlewares.strip-analytics.stripprefix.prefixes" = "/analytics";
# "traefik.http.routers.www-blazestar-net-goatcounter.middlewares" = "strip-analytics";
# Host the script on www.blazestar.net so that it is easy to fetch
"traefik.http.routers.www-blazestar-net-goatcounter.rule" =
"PathPrefix(`/count`) && ${hostRule "www" blazestar}";
"traefik.http.routers.www-blazestar-net-goatcounter.entrypoints" = "websecure";
"traefik.http.routers.www-blazestar-net-goatcounter.service" = "goatcounter-blazestar-net@docker";
};
};
};
};
}

View File

@@ -0,0 +1,84 @@
{ config, ... }:
let
inherit (import ../lib.nix config) hostRule havenisms;
syncRule = "(PathPrefix(`/client/`) || PathPrefix(`/_matrix/client/unstable/org.matrix.msc3575/sync`))";
wellKnownRule = "(Host(`havenisms.com`) || Host(`chat.havenisms.com`)) && PathPrefix(`/.well-known`)";
in
{
sops.secrets = {
"matrix/syncv3/db-password" = {
restartUnits = [ "${config.local.container-backend}-matrix-sliding-sync.service" ];
};
"matrix/syncv3/secret" = {
restartUnits = [ "${config.local.container-backend}-matrix-sliding-sync.service" ];
};
};
sops.templates."matrix-sliding-sync.env".content = ''
SYNCV3_SERVER=http://synapse:8008
SYNCV3_DB=postgres://syncv3:${
config.sops.placeholder."matrix/syncv3/db-password"
}@db:5432/syncv3?sslmode=disable
SYNCV3_SECRET=${config.sops.placeholder."matrix/syncv3/secret"}
SYNCV3_BINDADDR=:8009
'';
virtualisation.oci-containers.containers = {
synapse = {
image = "docker.io/matrixdotorg/synapse:latest";
autoStart = true;
dependsOn = [
"db"
];
volumes = [
"/tank/config/synapse/data:/data"
];
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.synapse.rule=${hostRule "chat" havenisms} && !(${syncRule} || ${wellKnownRule})"
"-l=traefik.http.routers.synapse.service=synapse"
"-l=traefik.http.services.synapse.loadbalancer.server.port=8008"
# Federation forwarding
"-l=traefik.http.routers.synapse-federation.rule=${hostRule "chat" havenisms}"
"-l=traefik.http.routers.synapse-federation.service=synapse-federation"
"-l=traefik.http.routers.synapse-federation.entrypoints=matrix-federation"
"-l=traefik.http.services.synapse-federation.loadbalancer.server.port=8448"
];
};
matrix-sliding-sync = {
image = "ghcr.io/matrix-org/sliding-sync:latest";
dependsOn = [
"db"
"synapse"
];
environmentFiles = [
config.sops.templates."matrix-sliding-sync.env".path
];
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.syncv3.rule=${hostRule "chat" havenisms} && ${syncRule}"
"-l=traefik.http.services.syncv3.loadbalancer.server.port=8009"
];
};
# This server helps to serve the .well-known files that are required by clients to find the sync server.
matrix-well-known = {
image = "nginx";
dependsOn = [ "synapse" ];
volumes = [
"/tank/config/synapse/static-files:/usr/share/nginx/html:ro"
];
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.middlewares.strip-well-known.stripprefix.prefixes=/.well-known"
"-l=traefik.http.routers.matrix-well-known.rule=${wellKnownRule}"
"-l=traefik.http.routers.matrix-well-known.middlewares=strip-well-known"
"-l=traefik.http.services.matrix-well-known.loadbalancer.server.port=80"
];
};
};
}

View File

@@ -0,0 +1,11 @@
{ ... }:
{
imports = [
./chat.nix
# Currently disabled because it doesn't start up properly
# ./immich.nix
./storyden.nix
./tandoor.nix
./wallabag.nix
];
}

View File

@@ -0,0 +1,73 @@
{ config, ... }:
let
inherit (import ../lib.nix config) havenisms mkPostgresContainer;
in
{
imports = [
(mkPostgresContainer {
# Immich wants a custom build of postgres with the vectors extensions.
image = "ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:c44be5f2871c59362966d71eab4268170eb6f5653c0e6170184e72b38ffdf107";
name = "immich";
directory = "/tank/immich/db";
uid = config.users.users.immich.uid;
gid = config.users.groups.immich.gid;
passwordSecret = "immich/database";
})
];
sops.secrets = {
"immich/database" = {
restartUnits = [
"${config.local.container-backend}-immich-db.service"
];
mode = "0400";
owner = config.users.users.immich.name;
};
};
sops.templates."immich.env" = {
restartUnits = [ "${config.local.container-backend}-immich.service" ];
owner = config.users.users.immich.name;
content = ''
DB_HOSTNAME=immich-postgres
DB_PASSWORD=${config.sops.placeholder."immich/database"}
DB_USERNAME=immich
DB_DATABASE_NAME=immich
REDIS_HOSTNAME=immich-redis
IMMICH_LOG_LEVEL=verbose
'';
};
virtualisation.web-containers.containers.immich = {
image = "ghcr.io/immich-app/immich-server:release";
hostname = "immich";
domain = havenisms;
port = 2283;
volumes = [
"/tank/photos/immich:/data"
"/etc/localtime:/etc/localtime:ro"
];
dependsOn = [
"immich-redis"
"immich-postgres"
];
environmentFiles = [
"${config.sops.templates."immich.env".path}"
];
};
virtualisation.oci-containers.containers = {
"immich-redis" = {
image = "docker.io/valkey/valkey";
};
"immich-machine-learning" = {
image = "ghcr.io/immich-app/immich-machine-learning:release";
volumes = [
"model-cache:/cache"
];
environmentFiles = [
"${config.sops.templates."immich.env".path}"
];
};
};
}

Some files were not shown because too many files have changed in this diff Show More