Compare commits
564 Commits
snowfall
...
1731647367
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1731647367 | ||
|
|
9ad06425c8 | ||
| 525cc60739 | |||
|
|
3595428e02 | ||
| 4ed90347f8 | |||
| b92dda099b | |||
|
|
f61dbc7190 | ||
| a48fc8fffe | |||
|
|
4d107533ea | ||
|
|
2c3cc8ed18 | ||
|
|
334d69894e | ||
|
|
31a9957877 | ||
|
|
dc25f02010 | ||
|
|
ef8e52b93f | ||
|
|
bf48d8fcf0 | ||
|
|
a68c91264f | ||
|
|
75d7097e23 | ||
|
|
b738f38267 | ||
|
|
32b0e67a7a | ||
|
|
f352ef1c05 | ||
|
|
1ea8c8b6a9 | ||
|
|
eac9c4b67d | ||
|
|
ce4047b62f | ||
|
|
aff6fa9ec6 | ||
|
|
a9c1d71495 | ||
|
|
4d4808490b | ||
|
|
1f99318fcd | ||
|
|
87fb1c96e5 | ||
|
|
aa7fc9c228 | ||
|
|
f856076452 | ||
|
|
d9d7760e58 | ||
|
|
bd8d1e6485 | ||
|
|
8fa82bce90 | ||
|
|
187b478c5d | ||
|
|
25ef179d3a | ||
|
|
57d1a8d864 | ||
|
|
c83cfcf06b | ||
|
|
59268d1da3 | ||
|
|
bca4a13614 | ||
|
|
044bac7464 | ||
|
|
10fa5498ee | ||
|
|
1331e69b58 | ||
|
|
9c8733431d | ||
|
|
ad15679eb4 | ||
|
|
01ae622391 | ||
|
|
defbd725dd | ||
|
|
d2c1cbf987 | ||
|
|
14db694b90 | ||
|
|
10fc7820e1 | ||
|
|
176d0b7311 | ||
|
|
1fc2ce66cf | ||
|
|
f93d69a259 | ||
|
|
d7afac2fb9 | ||
|
|
3aa0407532 | ||
|
|
c29ff231f9 | ||
| c5481909a1 | |||
|
|
8b4489cf8f | ||
|
|
d1d68e154d | ||
|
|
3ff7bed41d | ||
|
|
19acd60ed7 | ||
|
|
6cfb31fdc9 | ||
|
|
e5dbeadbb6 | ||
|
|
302d7f5af5 | ||
|
|
148229f551 | ||
|
|
5a22ad0f88 | ||
|
|
5b96b59e60 | ||
|
|
bfd5e90613 | ||
|
|
fdaa34191c | ||
|
|
fde852b29b | ||
|
|
d4e0b93e4e | ||
|
|
1410f0fe25 | ||
|
|
5fed9a649f | ||
|
|
9b87aa9d3e | ||
|
|
e7a6fdb644 | ||
|
|
871f099dac | ||
|
|
a07f694806 | ||
|
|
45f40e45d8 | ||
|
|
7c7c1dc3f4 | ||
|
|
bd44913ccc | ||
|
|
a5b53e66e7 | ||
|
|
5d9613ee13 | ||
|
|
3dea6e0a9e | ||
|
|
9ab1c99914 | ||
|
|
62ff7b829a | ||
|
|
477b79bfb8 | ||
|
|
e2e2d814fe | ||
|
|
94c3d6d6ff | ||
|
|
a336b0cf60 | ||
|
|
a94e68514a | ||
|
|
fb68d25008 | ||
|
|
2b9908e760 | ||
|
|
7cc4e8c99e | ||
|
|
fbdbbdf328 | ||
|
|
d4799b6598 | ||
|
|
6a9ec8f933 | ||
|
|
fa236b7076 | ||
|
|
05bd3f1a60 | ||
|
|
a3ade57500 | ||
|
|
e40181ba04 | ||
|
|
cedd4051f7 | ||
|
|
5a992567b8 | ||
|
|
631bdd3c2c | ||
|
|
a968cb4b4f | ||
|
|
d76fdcbab6 | ||
|
|
e2dfca0245 | ||
|
|
59500f3e50 | ||
|
|
a74305a444 | ||
|
|
e39614a9c8 | ||
|
|
b5de056631 | ||
|
|
49680a9188 | ||
|
|
c3865f2742 | ||
|
|
341d522fd4 | ||
|
|
51f4b335b1 | ||
|
|
77dc15e0e1 | ||
|
|
a0c2753f37 | ||
|
|
7320b0ee87 | ||
|
|
10268e7677 | ||
|
|
f57617e268 | ||
|
|
b613f941a6 | ||
|
|
b3138d0fca | ||
|
|
9376005a21 | ||
|
|
549580395f | ||
|
|
3f5634317b | ||
|
|
26746873f3 | ||
|
|
a58a9da64e | ||
|
|
8e7a0343c2 | ||
|
|
d47b092a8c | ||
|
|
4de54dee30 | ||
|
|
455ea26cdc | ||
|
|
7306b08762 | ||
|
|
59b4729636 | ||
|
|
afe04b88b0 | ||
|
|
b1215da790 | ||
|
|
b1f2521260 | ||
|
|
57add82f95 | ||
|
|
49485c91a6 | ||
|
|
a7c25fe70d | ||
|
|
1dc075f405 | ||
|
|
2a17112d50 | ||
|
|
a59d5ce3b1 | ||
|
|
639ce36cb0 | ||
|
|
42e771ef1f | ||
|
|
37d472c7db | ||
|
|
382f059188 | ||
|
|
dfd8d9a1a8 | ||
|
|
fcddde0c06 | ||
|
|
ad16b47827 | ||
|
|
994fddba66 | ||
|
|
0483ea8a67 | ||
|
|
b6e5223d96 | ||
|
|
ed7656cf3e | ||
|
|
76b6255169 | ||
|
|
5f5972f10f | ||
|
|
82dffdf505 | ||
|
|
741ab5c7ec | ||
|
|
3d0d5c878c | ||
|
|
0bb71bbb4f | ||
|
|
741de00ef7 | ||
|
|
c7c5192c0c | ||
|
|
052f7a2838 | ||
|
|
ca17f0fe18 | ||
|
|
e76f74e63a | ||
|
|
88e81c9aaa | ||
|
|
8406714527 | ||
|
|
97e4060b52 | ||
|
|
59121cf43b | ||
|
|
e15d62d03a | ||
|
|
3268c28cc8 | ||
|
|
e4ac3b99cd | ||
|
|
dabd791fac | ||
|
|
98c627531c | ||
|
|
c8f41cf7d8 | ||
|
|
78f8d1a733 | ||
|
|
b05067a3e1 | ||
|
|
3b780d4d78 | ||
|
|
77c76e6483 | ||
|
|
cd03862e4b | ||
|
|
e6a69cc21f | ||
|
|
c6317cdd18 | ||
|
|
ca73743483 | ||
|
|
105ed3bcb8 | ||
|
|
4a6a68dad4 | ||
|
|
56154fe941 | ||
|
|
b7380317b9 | ||
|
|
579c83164e | ||
|
|
56fb195967 | ||
|
|
451f5aa726 | ||
|
|
5c359dca81 | ||
|
|
6b28a8df9c | ||
|
|
dfc2c8faa4 | ||
|
|
0f42ffeebd | ||
|
|
1d5b1cf5e0 | ||
|
|
8fc40f265b | ||
|
|
cdf388cf17 | ||
|
|
8088ea0933 | ||
|
|
9305483e09 | ||
|
|
687a3a6446 | ||
|
|
1e5ef59d56 | ||
|
|
a7389ac9b2 | ||
|
|
501329def1 | ||
|
|
3063d6b161 | ||
|
|
c4ea874ae7 | ||
|
|
68dbe98370 | ||
|
|
374bd4348f | ||
|
|
5ee4da5b08 | ||
|
|
bf31786735 | ||
|
|
b216fe5215 | ||
|
|
b36ae0914c | ||
|
|
edd6291176 | ||
|
|
b91afbc323 | ||
|
|
450dc1ad91 | ||
|
|
eed1d28bd8 | ||
|
|
ae8bcdf690 | ||
|
|
4ac6de479c | ||
|
|
14990b28e4 | ||
|
|
ede0bf5c10 | ||
|
|
ae95786d8e | ||
|
|
209e776640 | ||
|
|
82e062a7e8 | ||
|
|
67fb7d7323 | ||
|
|
462494277a | ||
|
|
8fbf8c54eb | ||
|
|
f549723a61 | ||
|
|
c8aebb9e4a | ||
|
|
afb60fc031 | ||
|
|
4604e24ee5 | ||
|
|
3233955690 | ||
|
|
c9f75a053c | ||
|
|
f7cb1cb217 | ||
|
|
d981fb20c2 | ||
|
|
8f08f24761 | ||
|
|
74e772582d | ||
|
|
15f186e3ce | ||
|
|
7d92e9b1cc | ||
|
|
53a2d01a83 | ||
|
|
abdeddf751 | ||
|
|
1280cf9939 | ||
|
|
76265f9b1b | ||
|
|
66fe87dd23 | ||
|
|
e8fcf96253 | ||
|
|
479ac18f20 | ||
|
|
ba446f408a | ||
|
|
05486efb75 | ||
|
|
e0b1e72431 | ||
|
|
63bd725d64 | ||
|
|
96ce0001c5 | ||
|
|
50345adeb5 | ||
|
|
e74ea5f13b | ||
|
|
367c3a16c5 | ||
|
|
4c784f5f33 | ||
|
|
fa0210e937 | ||
|
|
f803c37105 | ||
|
|
03b00c59b2 | ||
|
|
5c9a42fe71 | ||
|
|
3b95a97921 | ||
|
|
2d03954a9f | ||
|
|
3dc1055b54 | ||
|
|
fedba849a7 | ||
|
|
34539045e5 | ||
|
|
0012a019fc | ||
|
|
f09246dcba | ||
|
|
90daf80a88 | ||
|
|
3c85ea0515 | ||
|
|
06e26e3be2 | ||
|
|
d76eff6f68 | ||
|
|
ce39a330b1 | ||
|
|
41063a1ef7 | ||
|
|
35206c8ed5 | ||
|
|
201ba0b780 | ||
|
|
a273c701ab | ||
|
|
2e4b629805 | ||
|
|
3364ae8fda | ||
|
|
15e0b9563f | ||
|
|
64f34892b7 | ||
|
|
8d1a9312cb | ||
|
|
31202f8b0e | ||
|
|
82ecfba7db | ||
|
|
f86808d86e | ||
|
|
89c5d60be3 | ||
|
|
96c3a34449 | ||
|
|
a5eba8ec68 | ||
|
|
764ce12aea | ||
|
|
989e717e4e | ||
|
|
4b53a89030 | ||
|
|
70a54b208e | ||
|
|
0b4d63fd09 | ||
|
|
f54285bfe6 | ||
|
|
a94f5c20aa | ||
|
|
adf1cc7ca6 | ||
|
|
d32826dc36 | ||
|
|
3c1c5b6292 | ||
|
|
73a11e1ac8 | ||
|
|
88e29f74de | ||
|
|
59702e15cf | ||
|
|
6c8d306d38 | ||
| f172707b15 | |||
|
|
672221f471 | ||
|
|
73581fd8f0 | ||
|
|
421c1e155b | ||
|
|
be9be7a4c5 | ||
|
|
db988e9761 | ||
|
|
e1706274fd | ||
|
|
96eda0dae7 | ||
|
|
33c00f0d7c | ||
|
|
001f465153 | ||
|
|
61532d5149 | ||
|
|
e1ccf848cf | ||
|
|
091ecdc10f | ||
|
|
e9084fe9ca | ||
|
|
f1074d7b24 | ||
|
|
16151dffdb | ||
|
|
34181aa0c9 | ||
|
|
b62f49b362 | ||
|
|
e985d6e104 | ||
|
|
5aaae9ca99 | ||
|
|
875498d07b | ||
|
|
02daab7686 | ||
|
|
821d594292 | ||
|
|
b4c1cb2a9f | ||
|
|
daa85b2ab3 | ||
|
|
c9d5d469c8 | ||
|
|
bb788d1de3 | ||
|
|
f085f17fe8 | ||
|
|
37316dd1c8 | ||
|
|
297a49a8f6 | ||
|
|
eb12e2271d | ||
|
|
bf0290df38 | ||
|
|
4c839eb867 | ||
|
|
98aeb1646d | ||
|
|
c6357aa6a6 | ||
|
|
5de3cc2ba1 | ||
|
|
2e54f153ed | ||
|
|
9334a35d3b | ||
|
|
f91ce5ad84 | ||
|
|
af57fdfb9f | ||
|
|
81b8bd9ec5 | ||
|
|
8705f7336b | ||
|
|
71b8fc9d0f | ||
|
|
66fefbe907 | ||
|
|
9ff8fe8399 | ||
|
|
d49a2744d2 | ||
|
|
9cadcf2eed | ||
|
|
66ab57fce0 | ||
|
|
84b2315aa5 | ||
|
|
f5161b237a | ||
|
|
aee0a4b34b | ||
|
|
75d97dd9ff | ||
|
|
2c4cc7c6b7 | ||
|
|
585689db43 | ||
|
|
140b9b5e32 | ||
|
|
f3cac97463 | ||
|
|
53a64aaf52 | ||
|
|
babe314199 | ||
|
|
778a7c93b3 | ||
|
|
2e3d8e6e7d | ||
|
|
0eed44ef6d | ||
|
|
76f0e8f176 | ||
|
|
3cad7ae079 | ||
|
|
c482cf1106 | ||
|
|
ca69b2294f | ||
|
|
5e4d16297e | ||
|
|
c0dbceefb9 | ||
|
|
c75f1e9131 | ||
|
|
b615cfe2e9 | ||
|
|
e2433d7367 | ||
|
|
ca448410f0 | ||
|
|
f47678cd12 | ||
|
|
31aba7d0a5 | ||
|
|
3f3641bf3d | ||
|
|
2eb2e902b2 | ||
|
|
c71c3b8ed2 | ||
|
|
108bb31e8e | ||
|
|
34b6399d24 | ||
|
|
1c1dc71cd7 | ||
|
|
6dc81d0cbf | ||
|
|
2a77d233f9 | ||
|
|
0e93ea159f | ||
|
|
582561ae12 | ||
|
|
c2766e82af | ||
|
|
b42d9eff71 | ||
|
|
5ae2d51961 | ||
|
|
ed2ec3a875 | ||
|
|
66281a5fd2 | ||
|
|
6068832fe6 | ||
|
|
c9588fbb95 | ||
|
|
627636ab9a | ||
|
|
63173a6262 | ||
|
|
65bdf1124d | ||
|
|
b3f9b50be5 | ||
|
|
97560f1bc9 | ||
|
|
840f3c9120 | ||
|
|
2b5614a07b | ||
|
|
9582ca5392 | ||
|
|
1b125aecd0 | ||
|
|
35733e1044 | ||
|
|
b748aa86a0 | ||
|
|
57c5926dac | ||
|
|
b77f2a3c45 | ||
|
|
8177cfdfdd | ||
|
|
2a4b734b7f | ||
|
|
f90324ca49 | ||
|
|
9f1c57ddf2 | ||
|
|
ee486f52bb | ||
|
|
6b6cf3eee1 | ||
|
|
52fc211dbf | ||
|
|
d9e415870c | ||
|
|
d61dfda3d5 | ||
|
|
2cfbc6d854 | ||
|
|
bf8b3d226a | ||
|
|
843304def7 | ||
|
|
41105e3f5a | ||
|
|
1fecd14b02 | ||
|
|
76c0cd98d8 | ||
|
|
ef22231dd7 | ||
|
|
8677ca747a | ||
|
|
02b5dd32a2 | ||
|
|
ee48ca08bd | ||
|
|
e72d1b5d93 | ||
|
|
5d6e7e35d5 | ||
|
|
751b4f9f69 | ||
|
|
ec23a7fe14 | ||
|
|
117912045c | ||
|
|
5ebb66d7d4 | ||
|
|
7a7b9cc01b | ||
|
|
4a00394402 | ||
|
|
aa0d09d3c9 | ||
|
|
0a40f7712a | ||
|
|
02debc8387 | ||
|
|
e6d386d362 | ||
|
|
208aaf3f27 | ||
|
|
6c9d4ccc86 | ||
|
|
1f0def655c | ||
|
|
c5e8fff07d | ||
|
|
7295254fe9 | ||
|
|
efbbfde6f5 | ||
|
|
fc4096d5d9 | ||
|
|
f58006cf8a | ||
|
|
6567bb1348 | ||
|
|
b71ca02d25 | ||
| 44b17502a0 | |||
|
|
bf70c50b80 | ||
|
|
d50fbb5f73 | ||
|
|
30fb21e062 | ||
|
|
6b44792e06 | ||
|
|
c7ac858ec5 | ||
|
|
73cb9010e2 | ||
|
|
3c1b5d5072 | ||
|
|
a8873d9435 | ||
|
|
d2c60d8157 | ||
|
|
bb96cf2406 | ||
|
|
c4911b9d5f | ||
|
|
67b840c40f | ||
|
|
e7276cadf6 | ||
|
|
36ca3ed90e | ||
|
|
57a079a86f | ||
|
|
0691806032 | ||
|
|
a6167bf31c | ||
|
|
e79ae984a3 | ||
|
|
81471cc582 | ||
|
|
6e1f6c23fe | ||
|
|
93c698c2de | ||
|
|
92855d5d31 | ||
|
|
6c6d6325c9 | ||
|
|
83f8b3543c | ||
|
|
d6ae29f16f | ||
|
|
02085e7ff1 | ||
|
|
68f6ced410 | ||
|
|
3fda24b5ac | ||
|
|
baa831d002 | ||
|
|
9ebb187a85 | ||
|
|
c50bcd4120 | ||
|
|
72d314b1e2 | ||
|
|
d15762b199 | ||
|
|
f66c0726b0 | ||
|
|
b3090b49e2 | ||
|
|
3bbd0d4432 | ||
|
|
281bb7cb55 | ||
|
|
46ea1e681a | ||
|
|
c759baed06 | ||
|
|
d19191bb14 | ||
|
|
81e78a6809 | ||
|
|
5749de77a9 | ||
|
|
921f186665 | ||
|
|
b098c2ad36 | ||
|
|
2ea82a643d | ||
|
|
cfaf900db6 | ||
|
|
7b44863814 | ||
|
|
d3274d8a59 | ||
|
|
b367df3f4e | ||
|
|
ac84ea8a7a | ||
|
|
e0ee270075 | ||
|
|
76134f4533 | ||
|
|
36010a4230 | ||
|
|
c90bd0cd07 | ||
|
|
6c9a010c3c | ||
|
|
c680392513 | ||
|
|
a233606e8d | ||
|
|
bc18b0775b | ||
|
|
a96b8ddf86 | ||
|
|
d6e7be7db1 | ||
|
|
999fbbf022 | ||
|
|
f8adf906e3 | ||
|
|
c2bbac4020 | ||
|
|
5ad754f5e9 | ||
|
|
814451041a | ||
|
|
1f9af9618f | ||
|
|
2601629e47 | ||
|
|
09b3fcb825 | ||
|
|
34746e865b | ||
|
|
7e82df3df7 | ||
|
|
1faa099900 | ||
|
|
f1295e17d6 | ||
|
|
fd34e5719d | ||
|
|
87f0941d61 | ||
|
|
7ebe9a9c8d | ||
|
|
c2d0993d9d | ||
|
|
8b6c35ff3c | ||
|
|
b0c812ac7a | ||
|
|
83116ee596 | ||
|
|
929786cb12 | ||
|
|
0364333921 | ||
|
|
9d93ba8e07 | ||
|
|
aacb72b78d | ||
|
|
83f7f3261c | ||
|
|
022f67554b | ||
|
|
2c339a22f4 | ||
|
|
e4c6f9d7fe | ||
|
|
24c1580452 | ||
|
|
b937a85dcc | ||
|
|
db43ca4b10 | ||
|
|
8e3e1ef6cc | ||
|
|
26ecfe79eb | ||
|
|
5dd2876fb5 | ||
|
|
807e964f34 | ||
|
|
8a1714eeb6 | ||
|
|
2623efc997 | ||
|
|
c053da2e30 | ||
|
|
533d6a4170 | ||
|
|
5b3e01820b | ||
| 5cef58ade0 | |||
|
|
981b41f4c2 | ||
|
|
ae8039dba0 | ||
|
|
54f56c3f83 | ||
|
|
ce142bb64a | ||
|
|
fd3f61a0ac | ||
|
|
d0ac22c211 | ||
|
|
caa326d496 | ||
|
|
04ef2a4b8c | ||
|
|
7e35a27b2e | ||
|
|
48108e693a | ||
|
|
8e3d3e4281 | ||
|
|
c7c99b339b | ||
|
|
c8f5547727 | ||
|
|
6f5e592d8c | ||
|
|
5ae3f1a9ef | ||
|
|
1a3b091588 | ||
|
|
5b34456571 | ||
|
|
5918611469 | ||
|
|
f3aafffcaa | ||
|
|
3d213c8769 | ||
|
|
f05972d6ae | ||
|
|
b77dda0e6f | ||
|
|
3c1a956c81 | ||
|
|
5dc1a96f6d |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,10 +1,14 @@
|
||||
hosts/nas/*.conf
|
||||
hosts/nas/*.users
|
||||
result
|
||||
result*
|
||||
*.raw
|
||||
.codegpt
|
||||
.direnv
|
||||
shell.nix
|
||||
.vscode
|
||||
**/*/*.py
|
||||
.envrc
|
||||
.envrc
|
||||
.DS_Store
|
||||
*.qcow2
|
||||
keys
|
||||
iso-*
|
||||
147
.sops.yaml
147
.sops.yaml
@@ -1,5 +1,6 @@
|
||||
# See https://github.com/Mic92/dotfiles/blob/d6114726d859df36ccaa32891c4963ae5717ef7f/nixos/.sops.yaml
|
||||
keys:
|
||||
- &matt-pgp CBCB9B18A6B8930B0B6ABFD1CCB8CBEB30633684
|
||||
- &matt age157jemphjzg6zmk373vpccuguyw6e75qnkqmz8pcnn2yue85p939swqqhy0
|
||||
- &matt_pi4 age13g9a4d4jrvckfddpgn8sm4kjtzajr67le56pfdg78ktr5pd09phq32j89u
|
||||
- &matt_pi5 age1wpvfpv5n32lruk7c0da4uaeapsmhjxdvg8z4ljehn06l6g2y0e0sum404l
|
||||
@@ -10,81 +11,101 @@ keys:
|
||||
- &pi5 age1t2d5scrukk0guva5sr97a8tge5j8kd865adezrcru7p269pzwvpsamkgje
|
||||
- &deck age1c8qw59ffcq9l77gfmtyc3djtvt3md0u6dwhrjcgsm98ntyf72ufqugj7cg
|
||||
- &steamdeck age1er5qucsc2mugrzrr7n3xhzv7kemkrqrw4m84r544fkk7nkg5g5eswxkqj0
|
||||
- &matt_macbook-pro age1xg6mvj3x6s3t8058c6rsk3q4kskvm6nsffwckxkkjzhyn7r6tczqgkj23p
|
||||
- &macbook-pro age1rdn39ywgzmc8wlsl5lrfe77e652wzjmjx58gx4k2ydghd35kdqvqscrf3h
|
||||
- &nuc age1wurzgc20e6ye79wsg85vvqk4aj3mmc0llxshcy9532ex8f4c6dqql76c78
|
||||
- &admin_nuc age1luyejgmqjj0esydlr2jxqkg48vexmx57gdz7cy5gq7rz8kf5cups2rnfa9
|
||||
- &matt_macbook-pro age12gu9hqhd56yl5x3t5yenkn9yg57du08h77vzjqsmnu5hdppne38qcur5a0
|
||||
- &macbook-pro age1t7378n8kmd3f32fkye2gw3jj6qswv3exjdx0dq8kl0xra3tmcdnsvddq3u
|
||||
- &nuc age102el4snus37dj807rwvsmlvwu2sg2d8rw3vfmtntgczfkz04l9nshetcq0
|
||||
- &admin_nuc age1yn82e39pxt0d0pgny34ux4lkge4ff7wxvsye8ragvwngehemt4ps27phyw
|
||||
- &matt_allyx age1n5frpwgvps7c2348ynu9g7g47kqar4srdplw5kkcyn4x80eqzetqw3ej2m
|
||||
- &allyx age1lvks0rdf743cn9rvvx90mzu3mjldydlzslpmv9608wn4j0m8u3xsmu7yew
|
||||
creation_rules:
|
||||
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *matt_pi4
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- *pi4
|
||||
- *pi5
|
||||
- *deck
|
||||
- *steamdeck
|
||||
- *matt_macbook-pro
|
||||
- *macbook-pro
|
||||
- *admin_nuc
|
||||
- *nuc
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *matt_pi4
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- *pi4
|
||||
- *pi5
|
||||
- *deck
|
||||
- *steamdeck
|
||||
- *matt_macbook-pro
|
||||
- *macbook-pro
|
||||
- *admin_nuc
|
||||
- *nuc
|
||||
- *matt_allyx
|
||||
- *allyx
|
||||
- path_regex: nas-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *desktop
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *desktop
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- path_regex: desktop-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *desktop
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *desktop
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- path_regex: steamdeck-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *desktop
|
||||
- *deck
|
||||
- *steamdeck
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *desktop
|
||||
- *deck
|
||||
- *steamdeck
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- *matt_allyx
|
||||
- *allyx
|
||||
- path_regex: pi4-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *matt_pi4
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *pi4
|
||||
- *pi5
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *matt_pi4
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *pi4
|
||||
- *pi5
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- path_regex: pi5-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *matt_pi4
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *pi4
|
||||
- *pi5
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *matt_pi4
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *pi4
|
||||
- *pi5
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- path_regex: mac-secrets/[^/]+\.(yaml|json|env|ini)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *matt
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *pi5
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- *matt_macbook-pro
|
||||
- *macbook-pro
|
||||
- pgp:
|
||||
- *matt-pgp
|
||||
age:
|
||||
- *matt
|
||||
- *matt_pi5
|
||||
- *desktop
|
||||
- *pi5
|
||||
- *admin
|
||||
- *jallen-nas
|
||||
- *matt_macbook-pro
|
||||
- *macbook-pro
|
||||
|
||||
156
README.md
156
README.md
@@ -1,50 +1,118 @@
|
||||
# nixOS Config
|
||||
# NixOS Configuration Repository
|
||||
|
||||
### Common Files
|
||||
* [flake.nix](./flake.nix)
|
||||
* [impermenance.nix](./share/impermanence/default.nix)
|
||||
* [share](./share)
|
||||
* [overlays](./overlays)
|
||||
This repository contains my personal NixOS configurations for multiple systems, managed using [Snowfall Lib](https://github.com/snowfallorg/lib) and the Nix Flakes system.
|
||||
|
||||
## Overview
|
||||
|
||||
This repository provides a centralized, declarative configuration for all my systems, including:
|
||||
|
||||
- Desktop PC (AMD)
|
||||
- NAS server
|
||||
- Steam Deck
|
||||
- Intel NUC
|
||||
- Raspberry Pi 4
|
||||
- Raspberry Pi 5
|
||||
- MacBook Pro (NixOS on Apple Silicon)
|
||||
- MacBook Pro (Darwin/macOS)
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── checks/ # Pre-commit hooks and other checks
|
||||
├── flake.nix # Main flake configuration
|
||||
├── homes/ # Home-manager configurations for users
|
||||
│ ├── aarch64-darwin/ # macOS home configurations
|
||||
│ ├── aarch64-linux/ # ARM Linux home configurations
|
||||
│ └── x86_64-linux/ # x86 Linux home configurations
|
||||
├── modules/ # Reusable configuration modules
|
||||
│ ├── home/ # Home-manager modules
|
||||
│ └── nixos/ # NixOS system modules
|
||||
├── overlays/ # Nixpkgs overlays
|
||||
├── packages/ # Custom package definitions
|
||||
├── secrets/ # Encrypted secrets (managed with sops-nix)
|
||||
└── systems/ # System-specific configurations
|
||||
├── aarch64-darwin/ # macOS system configurations
|
||||
├── aarch64-linux/ # ARM Linux system configurations
|
||||
└── x86_64-linux/ # x86 Linux system configurations
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Modular Design**: Reusable modules for various system components
|
||||
- **Multi-System Support**: Configurations for different hardware platforms
|
||||
- **Home Manager Integration**: User environment management
|
||||
- **Secret Management**: Encrypted secrets with sops-nix
|
||||
- **Disk Management**: Declarative disk partitioning with disko
|
||||
- **State Management**: Persistent state management with impermanence
|
||||
- **Desktop Environments**: Support for GNOME, Hyprland, and COSMIC
|
||||
- **Hardware-Specific Optimizations**: Tailored configurations for different hardware
|
||||
|
||||
## Key Technologies
|
||||
|
||||
- [Nix](https://nixos.org/) and [NixOS](https://nixos.org/)
|
||||
- [Nix Flakes](https://nixos.wiki/wiki/Flakes)
|
||||
- [Snowfall Lib](https://github.com/snowfallorg/lib)
|
||||
- [Home Manager](https://github.com/nix-community/home-manager)
|
||||
- [sops-nix](https://github.com/Mic92/sops-nix)
|
||||
- [disko](https://github.com/nix-community/disko)
|
||||
- [impermanence](https://github.com/nix-community/impermanence)
|
||||
- [lanzaboote](https://github.com/nix-community/lanzaboote) (Secure Boot)
|
||||
|
||||
## Notable System Configurations
|
||||
|
||||
### Desktop
|
||||
* [boot.nix](./hosts/desktop/boot.nix)
|
||||
* [configuration.nix](./hosts/desktop/configuration.nix)
|
||||
* [hardware-configuration.nix](./hosts/desktop/hardware-configuration.nix)
|
||||
* [filesystems.nix](./hosts/desktop/filesystems.nix)
|
||||
* [home.nix](./hosts/desktop/home.nix)
|
||||
* [sops.nix](./hosts/desktop/sops.nix)
|
||||
* [specialisations.hyprland](./hosts/desktop/hyprland)
|
||||
* [specialisations.gnome](./hosts/desktop/gnome)
|
||||
* [specialisations.cosmic](./hosts/desktop/cosmic)
|
||||
|
||||
A powerful AMD-based desktop with gaming capabilities, featuring:
|
||||
- AMD CPU and GPU optimizations
|
||||
- Multiple desktop environment options (GNOME, Hyprland, COSMIC)
|
||||
- Gaming setup with Steam and related tools
|
||||
|
||||
### NAS
|
||||
* [boot.nix](./hosts/nas/boot.nix)
|
||||
* [configuration.nix](./hosts/nas/configuration.nix)
|
||||
* [hardware-configuration.nix](./hosts/nas/hardware-configuration.nix)
|
||||
* [impermenance.nix](./hosts/nas/impermenance.nix)
|
||||
* [apps.nix](./hosts/desktop/apps.nix)
|
||||
* [home.nix](./hosts/desktop/home.nix)
|
||||
* [networking.nix](./hosts/desktop/networking.nix)
|
||||
* [services.nix](./hosts/desktop/services.nix)
|
||||
* [sops.nix](./hosts/desktop/sops.nix)
|
||||
* [ups.nix](./hosts/desktop/ups.nix)
|
||||
* [samba](./modules/samba)
|
||||
* nas-apps
|
||||
* [arrs](./hosts/nas/apps/arrs/default.nix)
|
||||
* [free-games-claimer](./modules/apps/free-games-claimer)
|
||||
* [jackett](./modules/apps/jackett)
|
||||
* [jellyfin](./hosts/nas/apps/jellyfin/default.nix)
|
||||
* [jellyseerr](./hosts/nas/apps/jellyseerr/default.nix)
|
||||
* [jackett](./modules/apps/manyfold)
|
||||
* [mariadb](./modules/apps/mariadb)
|
||||
* [mealie](./modules/apps/mealie)
|
||||
* [nextcloud+onlyoffice](./hosts/nas/apps/nextcloud/default.nix)
|
||||
* [ollama](./hosts/nas/apps/ollama/default.nix)
|
||||
* [paperless](./hosts/nas/apps/paperless/default.nix)
|
||||
* [tdarr](./modules/apps/tdarr)
|
||||
* [traefik](./hosts/nas/apps/traefik/default.nix)
|
||||
* [wireguard](./modules/apps/your-spotify)
|
||||
|
||||
### Raspberry Pi 4
|
||||
* [configuration.nix](./hosts/pi4/configuration.nix)
|
||||
* [hardware-configuration.nix](./hosts/pi4/hardware-configuration.nix)
|
||||
A home server with various self-hosted services:
|
||||
- Media management (Jellyfin, Jellyseerr)
|
||||
- Download automation (Sonarr, Radarr, etc.)
|
||||
- Document management (Paperless)
|
||||
- File sharing (Samba, Nextcloud)
|
||||
- AI services (Ollama)
|
||||
|
||||
### Raspberry Pi
|
||||
|
||||
Configurations for both Pi 4 and Pi 5:
|
||||
- Hardware-specific optimizations
|
||||
- Disk partitioning suitable for ARM devices
|
||||
- Bluetooth and wireless support
|
||||
|
||||
### Steam Deck
|
||||
|
||||
Custom NixOS configuration for the Steam Deck:
|
||||
- Integration with Jovian for Steam Deck compatibility
|
||||
- Gaming optimizations
|
||||
- Steam ROM Manager
|
||||
|
||||
### MacBook Pro
|
||||
|
||||
Configurations for both:
|
||||
- NixOS on Apple Silicon
|
||||
- nix-darwin for macOS
|
||||
|
||||
## Usage
|
||||
|
||||
### Building a System Configuration
|
||||
|
||||
```bash
|
||||
# Build and activate a system configuration
|
||||
sudo nixos-rebuild switch --flake .#hostname
|
||||
```
|
||||
|
||||
### Building a Home Configuration
|
||||
|
||||
```bash
|
||||
# Build and activate a home configuration
|
||||
home-manager switch --flake .#username@hostname
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
62
checks/disksnstuff.sh
Executable file
62
checks/disksnstuff.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
disk=/dev/mapper/nuc-nixos-cryptroot
|
||||
|
||||
# sudo mkfs.vfat "$disk"1
|
||||
# sudo bcachefs format --label ssd.ssd1 --compression=zstd --discard "$disk"
|
||||
|
||||
sudo mount -t tmpfs -o mode=755 none /mnt
|
||||
sudo mkdir -p /mnt/{boot,home,root,etc,nix,var/log,tmp,persist}
|
||||
sudo mount /dev/disk/by-partlabel/disk-main-nuc-nixos-EFI /mnt/boot
|
||||
# sudo mkdir -p /mnt/boot/firmware
|
||||
# sudo mount "$disk"2 /mnt/boot/firmware
|
||||
# sudo mount "$disk"2 -o compress=zstd,subvol=home /mnt/home
|
||||
# sudo mount "$disk"2 -o compress=zstd,noatime,subvol=root /mnt/root
|
||||
# sudo mount "$disk"2 -o compress=zstd,noatime,subvol=etc /mnt/etc
|
||||
# sudo mount "$disk"2 -o compress=zstd,noatime,subvol=nix /mnt/nix
|
||||
# sudo mount "$disk"2 -o compress=zstd,noatime,subvol=log /mnt/var/log
|
||||
|
||||
# bcachefs unlock -k session /dev/disk/by-partlabel/disk-main-nuc-nixos-bcachefs-root
|
||||
sudo cryptsetup open /dev/disk/by-partlabel/disk-main-nuc-nixos-cryptroot nuc-nixos-cryptroot
|
||||
# sudo bcachefs unlock -k session "$disk"2
|
||||
# sudo mount "$disk" /mnt/tmp
|
||||
# cd /mnt/tmp
|
||||
# ls -alh
|
||||
|
||||
# sudo bcachefs subvolume create nix
|
||||
# sudo bcachefs subvolume create etc
|
||||
# sudo bcachefs subvolume create log
|
||||
# sudo bcachefs subvolume create root
|
||||
# sudo bcachefs subvolume create persist
|
||||
# sudo bcachefs subvolume create home
|
||||
|
||||
# ls -alh
|
||||
# cd /etc/nixos
|
||||
# sudo umount /mnt/tmp
|
||||
|
||||
sudo mount -o noatime,X-mount.subdir=nix "$disk" /mnt/nix
|
||||
sudo mount -o noatime,X-mount.subdir=etc "$disk" /mnt/etc
|
||||
sudo mount -o noatime,X-mount.subdir=log "$disk" /mnt/var/log
|
||||
sudo mount -o noatime,X-mount.subdir=root "$disk" /mnt/root
|
||||
sudo mount -o noatime,X-mount.subdir=persist "$disk" /mnt/persist
|
||||
sudo mount -o X-mount.subdir=home "$disk" /mnt/home
|
||||
|
||||
# tree /mnt
|
||||
|
||||
# sudo nixos-install --flake /etc/nixos#nuc-nixos
|
||||
|
||||
# sudo umount /mnt/boot
|
||||
# sudo umount /mnt/var/log
|
||||
# sudo umount /mnt/persist
|
||||
# sudo umount /mnt/home
|
||||
# sudo umount /mnt/root
|
||||
# sudo umount /mnt/etc
|
||||
# sudo umount /mnt/nix
|
||||
# sudo umount /mnt
|
||||
|
||||
# wpa_passphrase "Joey's Jungle 5G" "kR8v&3Qd" > 5g.conf
|
||||
# wpa_supplicant -i wlp6s0 -c 5g.conf -B
|
||||
# dhcpcd
|
||||
|
||||
# keyctl link @u @s
|
||||
# clevis decrypt < "/etc/clevis/nas_pool.jwe" | bcachefs unlock /dev/disk/by-label/nas_pool
|
||||
@@ -1,19 +1,22 @@
|
||||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (inputs) git-hooks-nix;
|
||||
inherit (inputs) pre-commit-hooks-nix;
|
||||
in
|
||||
git-hooks-nix.lib.${pkgs.system}.run {
|
||||
pre-commit-hooks-nix.lib.${pkgs.stdenv.hostPlatform.system}.run {
|
||||
src = ../..;
|
||||
hooks = {
|
||||
pre-commit-hook-ensure-sops.enable = true;
|
||||
treefmt = {
|
||||
enable = true;
|
||||
settings.fail-on-change = false;
|
||||
packageOverrides.treefmt = inputs.treefmt-nix.lib.mkWrapper pkgs ../../treefmt.nix;
|
||||
enable = lib.mkForce true;
|
||||
settings.fail-on-change = lib.mkForce false;
|
||||
packageOverrides.treefmt = inputs.treefmt-nix.lib.mkWrapper pkgs (
|
||||
lib.snowfall.fs.get-file "treefmt.nix"
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
208
docs/version.schema.json
Normal file
208
docs/version.schema.json
Normal file
@@ -0,0 +1,208 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://example.invalid/version.schema.json",
|
||||
"title": "Unified Package Version Schema",
|
||||
"description": "Schema for a unified version.json used by packages/",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schemaVersion",
|
||||
"sources"
|
||||
],
|
||||
"properties": {
|
||||
"schemaVersion": {
|
||||
"type": "integer",
|
||||
"enum": [1],
|
||||
"description": "Schema version. Start at 1; bump on breaking changes."
|
||||
},
|
||||
"variables": {
|
||||
"type": "object",
|
||||
"description": "Common variables available for template substitution in string fields.",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"defaultVariant": {
|
||||
"type": "string",
|
||||
"description": "Optional default variant name for consumers."
|
||||
},
|
||||
"sources": {
|
||||
"type": "object",
|
||||
"description": "Base component sources keyed by component name.",
|
||||
"minProperties": 1,
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/SourceSpec"
|
||||
}
|
||||
},
|
||||
"variants": {
|
||||
"type": "object",
|
||||
"description": "Optional variants/channels/flavors; each overlays the base.",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/VariantSpec"
|
||||
}
|
||||
},
|
||||
"notes": {
|
||||
"type": "object",
|
||||
"description": "Optional free-form human notes/documentation.",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"SourceSpecBase": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"fetcher": {
|
||||
"type": "string",
|
||||
"enum": ["github", "git", "url", "pypi", "none"],
|
||||
"description": "Fetcher type for this source."
|
||||
},
|
||||
"hash": {
|
||||
"type": "string",
|
||||
"pattern": "^sha[0-9]+-",
|
||||
"description": "SRI hash for the fetched artifact. Required unless fetcher is 'none'."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Optional version string metadata for this component."
|
||||
},
|
||||
"extra": {
|
||||
"type": "object",
|
||||
"description": "Optional free-form metadata for consumer logic.",
|
||||
"additionalProperties": true
|
||||
},
|
||||
|
||||
"owner": { "type": "string", "description": "GitHub owner/org (github fetcher)." },
|
||||
"repo": { "type": "string", "description": "GitHub repository (github fetcher)." },
|
||||
"tag": { "type": "string", "description": "Git tag (github fetcher). Mutually exclusive with 'rev'." },
|
||||
"rev": { "type": "string", "description": "Commit revision (github/git fetchers)." },
|
||||
"submodules": { "type": "boolean", "description": "Whether to fetch submodules (github/git fetchers)." },
|
||||
|
||||
"url": { "type": "string", "description": "Final URL (url fetcher). May be templated." },
|
||||
"urlTemplate": { "type": "string", "description": "Template for URL (url fetcher); supports ${var}." },
|
||||
|
||||
"name": { "type": "string", "description": "PyPI dist name (pypi fetcher)." }
|
||||
}
|
||||
},
|
||||
|
||||
"SourceSpec": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/SourceSpecBase" },
|
||||
{
|
||||
"if": {
|
||||
"properties": { "fetcher": { "const": "github" } },
|
||||
"required": ["fetcher"]
|
||||
},
|
||||
"then": {
|
||||
"required": ["owner", "repo"],
|
||||
"oneOf": [
|
||||
{ "required": ["tag"] },
|
||||
{ "required": ["rev"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": { "fetcher": { "const": "git" } },
|
||||
"required": ["fetcher"]
|
||||
},
|
||||
"then": {
|
||||
"required": ["url", "rev"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": { "fetcher": { "const": "url" } },
|
||||
"required": ["fetcher"]
|
||||
},
|
||||
"then": {
|
||||
"oneOf": [
|
||||
{ "required": ["url"] },
|
||||
{ "required": ["urlTemplate"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": { "fetcher": { "const": "pypi" } },
|
||||
"required": ["fetcher"]
|
||||
},
|
||||
"then": {
|
||||
"required": ["name", "version"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": { "fetcher": { "enum": ["github", "git", "url", "pypi"] } },
|
||||
"required": ["fetcher"]
|
||||
},
|
||||
"then": {
|
||||
"required": ["hash"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"SourceOverride": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Partial override of a source within a variant. All fields optional.",
|
||||
"properties": {
|
||||
"fetcher": { "type": "string", "enum": ["github", "git", "url", "pypi", "none"] },
|
||||
"hash": { "type": "string", "pattern": "^sha[0-9]+-" },
|
||||
"version": { "type": "string" },
|
||||
"extra": { "type": "object", "additionalProperties": true },
|
||||
|
||||
"owner": { "type": "string" },
|
||||
"repo": { "type": "string" },
|
||||
"tag": { "type": "string" },
|
||||
"rev": { "type": "string" },
|
||||
"submodules": { "type": "boolean" },
|
||||
|
||||
"url": { "type": "string" },
|
||||
"urlTemplate": { "type": "string" },
|
||||
|
||||
"name": { "type": "string" }
|
||||
}
|
||||
},
|
||||
|
||||
"VariantSpec": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"inherits": {
|
||||
"type": "string",
|
||||
"description": "Optional base variant to inherit from."
|
||||
},
|
||||
"variables": {
|
||||
"type": "object",
|
||||
"description": "Variant-level variables that overlay top-level variables.",
|
||||
"additionalProperties": { "type": "string" }
|
||||
},
|
||||
"sources": {
|
||||
"type": "object",
|
||||
"description": "Per-component overrides for this variant.",
|
||||
"additionalProperties": { "$ref": "#/$defs/SourceOverride" }
|
||||
},
|
||||
"platforms": {
|
||||
"type": "object",
|
||||
"description": "Optional per-system overrides to support differing hashes/fields by platform.",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"sources": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#/$defs/SourceOverride" }
|
||||
},
|
||||
"variables": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1275
flake.lock
generated
1275
flake.lock
generated
File diff suppressed because it is too large
Load Diff
205
flake.nix
205
flake.nix
@@ -1,25 +1,38 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
inputs = rec {
|
||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
|
||||
nixpkgs-otbr.url = "github:mrene/nixpkgs/openthread-border-router";
|
||||
|
||||
home-manager-stable = {
|
||||
url = "github:nix-community/home-manager/release-25.11";
|
||||
inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||
};
|
||||
|
||||
home-manager-unstable = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
|
||||
nixpkgs = nixpkgs-unstable;
|
||||
home-manager = home-manager-unstable;
|
||||
|
||||
# The name "snowfall-lib" is required due to how Snowfall Lib processes your
|
||||
# flake's inputs.
|
||||
snowfall-lib = {
|
||||
url = "github:snowfallorg/lib";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
chaotic.url = "github:chaotic-cx/nyx/nyxpkgs-unstable";
|
||||
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
url = "github:mjallen18/snowfall-lib";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# nixos-generators = {
|
||||
# url = "github:nix-community/nixos-generators";
|
||||
# inputs.nixpkgs.follows = "nixpkgs";
|
||||
# };
|
||||
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
|
||||
lanzaboote.url = "github:nix-community/lanzaboote/v0.4.2";
|
||||
|
||||
lanzaboote.url = "github:nix-community/lanzaboote/v1.0.0";
|
||||
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
|
||||
@@ -35,24 +48,21 @@
|
||||
|
||||
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
|
||||
|
||||
authentik-nix.url = "github:nix-community/authentik-nix";
|
||||
|
||||
crowdsec.url = "git+https://codeberg.org/kampka/nix-flake-crowdsec.git";
|
||||
authentik-nix = {
|
||||
url = "github:nix-community/authentik-nix";
|
||||
# inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||
};
|
||||
|
||||
nixai.url = "github:olafkfreund/nix-ai-help";
|
||||
|
||||
disko = {
|
||||
# the fork is needed for partition attributes support
|
||||
url = "github:nvmd/disko/gpt-attrs";
|
||||
# url = "github:nix-community/disko";
|
||||
# url = "github:nvmd/disko/gpt-attrs";
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nixos-raspberrypi.url = "github:mjallen18/nixos-raspberrypi";
|
||||
|
||||
jovian.url = "github:Jovian-Experiments/Jovian-NixOS";
|
||||
|
||||
darwin.url = "github:LnL7/nix-darwin";
|
||||
darwin.url = "github:nix-darwin/nix-darwin/master";
|
||||
|
||||
nix-homebrew.url = "github:zhaofengli/nix-homebrew";
|
||||
|
||||
@@ -68,7 +78,10 @@
|
||||
|
||||
nixos-apple-silicon.url = "github:nix-community/nixos-apple-silicon";
|
||||
|
||||
pre-commit-hooks-nix.url = "github:cachix/pre-commit-hooks.nix";
|
||||
pre-commit-hooks-nix = {
|
||||
url = "github:cachix/pre-commit-hooks.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
treefmt-nix = {
|
||||
url = "github:numtide/treefmt-nix";
|
||||
@@ -81,12 +94,39 @@
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
lsfg-vk = {
|
||||
url = "github:pabloaul/lsfg-vk-flake";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nix-plist-manager.url = "github:sushydev/nix-plist-manager";
|
||||
|
||||
nix-rosetta-builder = {
|
||||
url = "github:cpick/nix-rosetta-builder";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
stylix = {
|
||||
url = "github:nix-community/stylix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
end4-dotfiles = {
|
||||
url = "git+https://github.com/end-4/dots-hyprland?submodules=1";
|
||||
flake = false;
|
||||
};
|
||||
illogical-flake = {
|
||||
url = "github:soymou/illogical-flake";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.dotfiles.follows = "end4-dotfiles";
|
||||
};
|
||||
};
|
||||
|
||||
# We will handle this in the next section.
|
||||
outputs = inputs:
|
||||
let
|
||||
snowfall = inputs.snowfall-lib.mkFlake {
|
||||
outputs =
|
||||
inputs:
|
||||
inputs.snowfall-lib.mkFlake {
|
||||
# You must provide our flake inputs to Snowfall Lib.
|
||||
inherit inputs;
|
||||
|
||||
@@ -100,20 +140,28 @@
|
||||
# common modules
|
||||
modules.nixos = with inputs; [
|
||||
authentik-nix.nixosModules.default
|
||||
chaotic.nixosModules.default
|
||||
crowdsec.nixosModules.crowdsec
|
||||
crowdsec.nixosModules.crowdsec-firewall-bouncer
|
||||
disko.nixosModules.disko
|
||||
impermanence.nixosModules.impermanence
|
||||
lanzaboote.nixosModules.lanzaboote
|
||||
sops-nix.nixosModules.sops
|
||||
home-manager.nixosModules.home-manager
|
||||
nix-index-database.nixosModules.nix-index
|
||||
stylix.nixosModules.stylix
|
||||
];
|
||||
|
||||
modules.home = with inputs; [
|
||||
nix-index-database.homeManagerModules.nix-index
|
||||
illogical-flake.homeManagerModules.default
|
||||
];
|
||||
|
||||
# common darwin modules
|
||||
modules.darwin = with inputs; [
|
||||
nix-homebrew.darwinModules.nix-homebrew
|
||||
home-manager.darwinModules.home-manager
|
||||
nix-plist-manager.darwinModules.default
|
||||
nix-rosetta-builder.darwinModules.default
|
||||
nix-index-database.darwinModules.nix-index
|
||||
stylix.darwinModules.stylix
|
||||
];
|
||||
|
||||
# Host config
|
||||
@@ -121,57 +169,41 @@
|
||||
# ######################################################
|
||||
# Desktop #
|
||||
# ######################################################
|
||||
desktop = {
|
||||
matt-nixos = {
|
||||
modules = with inputs; [
|
||||
nixos-hardware.nixosModules.common-cpu-amd
|
||||
nixos-hardware.nixosModules.common-cpu-amd-pstate
|
||||
nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
# nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
nixos-hardware.nixosModules.common-gpu-amd
|
||||
nixos-hardware.nixosModules.common-hidpi
|
||||
nixos-hardware.nixosModules.common-pc
|
||||
lsfg-vk.nixosModules.default
|
||||
];
|
||||
};
|
||||
|
||||
# ######################################################
|
||||
# NAS #
|
||||
# ######################################################
|
||||
nas = {
|
||||
jallen-nas = {
|
||||
modules = with inputs; [
|
||||
nixos-hardware.nixosModules.common-pc
|
||||
nixos-hardware.nixosModules.common-cpu-amd
|
||||
nixos-hardware.nixosModules.common-cpu-amd-pstate
|
||||
nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
# nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
nixos-hardware.nixosModules.common-hidpi
|
||||
home-manager.nixosModules.home-manager
|
||||
];
|
||||
# overlays = with inputs; [ crowdsec.overlays.default ];
|
||||
};
|
||||
|
||||
# ######################################################
|
||||
# Steamdeck #
|
||||
# ######################################################
|
||||
deck = {
|
||||
modules = with inputs; [
|
||||
disko.nixosModules.disko
|
||||
jovian.nixosModules.jovian
|
||||
nixos-hardware.nixosModules.common-cpu-amd
|
||||
nixos-hardware.nixosModules.common-cpu-amd-pstate
|
||||
nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
nixos-hardware.nixosModules.common-gpu-amd
|
||||
nixos-hardware.nixosModules.common-hidpi
|
||||
nixos-hardware.nixosModules.common-pc
|
||||
];
|
||||
};
|
||||
|
||||
# ######################################################
|
||||
# NUC #
|
||||
# ######################################################
|
||||
nuc = {
|
||||
nuc-nixos = {
|
||||
modules = with inputs; [
|
||||
disko.nixosModules.disko
|
||||
nixos-hardware.nixosModules.common-cpu-amd
|
||||
nixos-hardware.nixosModules.common-cpu-amd-pstate
|
||||
nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
# nixos-hardware.nixosModules.common-cpu-amd-zenpower
|
||||
nixos-hardware.nixosModules.common-gpu-amd
|
||||
nixos-hardware.nixosModules.common-hidpi
|
||||
nixos-hardware.nixosModules.common-pc
|
||||
@@ -184,9 +216,6 @@
|
||||
pi4 = {
|
||||
modules = with inputs; [
|
||||
disko.nixosModules.disko
|
||||
nixos-raspberrypi.nixosModules.raspberry-pi-4.base
|
||||
nixos-raspberrypi.nixosModules.raspberry-pi-4.display-vc4
|
||||
nixos-raspberrypi.lib.inject-overlays
|
||||
];
|
||||
};
|
||||
|
||||
@@ -196,10 +225,6 @@
|
||||
pi5 = {
|
||||
modules = with inputs; [
|
||||
disko.nixosModules.disko
|
||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.base
|
||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.display-vc4
|
||||
nixos-raspberrypi.nixosModules.raspberry-pi-5.bluetooth
|
||||
nixos-raspberrypi.lib.inject-overlays
|
||||
];
|
||||
};
|
||||
|
||||
@@ -209,35 +234,14 @@
|
||||
macbook-pro-nixos = {
|
||||
modules = with inputs; [
|
||||
nixos-apple-silicon.nixosModules.default
|
||||
lsfg-vk.nixosModules.default
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
overlays = with inputs; [ nix-vscode-extensions.overlays.default ];
|
||||
|
||||
homes = {
|
||||
modules = with inputs; [
|
||||
nix-index-database.homeModules.nix-index
|
||||
sops-nix.homeManagerModules.sops
|
||||
];
|
||||
|
||||
overlays = with inputs; [
|
||||
nix-vscode-extensions.overlays.default
|
||||
];
|
||||
|
||||
users = {
|
||||
# "matt@desktop" = {
|
||||
# modules = with inputs; [
|
||||
# sops-nix.homeManagerModules.sops
|
||||
# ];
|
||||
# };
|
||||
"deck@deck" = {
|
||||
modules = with inputs; [
|
||||
steam-rom-manager.homeManagerModules.default
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
overlays = with inputs; [
|
||||
nix-vscode-extensions.overlays.default
|
||||
];
|
||||
};
|
||||
|
||||
# Configure Snowfall Lib, all of these settings are optional.
|
||||
@@ -248,20 +252,33 @@
|
||||
|
||||
# Add flake metadata that can be processed by tools like Snowfall Frost.
|
||||
meta = {
|
||||
# A slug to use in documentation when displaying things like file paths.
|
||||
name = "mjallen";
|
||||
# A slug to use in documentation when displaying things like file paths.
|
||||
name = "mjallen";
|
||||
|
||||
# A title to show for your flake, typically the name.
|
||||
title = "mjallen Flake";
|
||||
# A title to show for your flake, typically the name.
|
||||
title = "mjallen Flake";
|
||||
};
|
||||
};
|
||||
|
||||
channels-config = {
|
||||
allowUnfree = true;
|
||||
allowUnsupportedSystem = true;
|
||||
permittedInsecurePackages = [
|
||||
# ...
|
||||
# "libsoup-2.74.3"
|
||||
# "mbedtls-2.28.10"
|
||||
];
|
||||
};
|
||||
|
||||
outputs-builder = channels: {
|
||||
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
|
||||
|
||||
# Add mjallen-lib to the flake outputs
|
||||
overlays = {
|
||||
mjallen-lib = _final: _prev: {
|
||||
mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
snowfall // {
|
||||
nixosConfigurations = snowfall.nixosConfigurations;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
{ lib, pkgs, home, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) enabled disabled;
|
||||
shellAliases = {
|
||||
update-switch = "darwin-rebuild switch --flake ~/nix-config";
|
||||
update-flake = "nix flake update ~/nix-config";
|
||||
@@ -9,20 +15,15 @@ let
|
||||
age
|
||||
cpufetch
|
||||
deadnix
|
||||
direnv
|
||||
nixfmt-rfc-style
|
||||
nixfmt
|
||||
nodePackages.nodejs
|
||||
uv
|
||||
sops
|
||||
tree
|
||||
wget
|
||||
];
|
||||
in
|
||||
{
|
||||
# imports = [
|
||||
# ../../modules/home/defaults.nix
|
||||
# ../../modules/home/git.nix
|
||||
# ../../modules/home/shell.nix
|
||||
# ../../modules/home/vscode.nix
|
||||
# ];
|
||||
# Home Manager needs a bit of information about you and the
|
||||
# paths it should manage.
|
||||
home = {
|
||||
@@ -30,7 +31,7 @@ in
|
||||
homeDirectory = "/Users/mattjallen";
|
||||
packages = lib.mkForce packages;
|
||||
sessionVariables = {
|
||||
NH_DARWIN_FLAKE = "${home.homeDirectory}/nix-config#mac";
|
||||
NH_DARWIN_FLAKE = lib.mkForce "/Users/mattjallen/nix-config";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -40,20 +41,238 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
# programs.nix-plist-manager = {
|
||||
# enable = true;
|
||||
# options = {
|
||||
# applications = {
|
||||
# finder = {
|
||||
# settings = {
|
||||
# general = {
|
||||
# showTheseItemsOnTheDesktop = {
|
||||
# hardDisks = false;
|
||||
# externalDisks = true;
|
||||
# cdsDvdsAndiPods = false;
|
||||
# connectedServers = false;
|
||||
# };
|
||||
# openFoldersInTabsInsteadOfNewWindows = true;
|
||||
# };
|
||||
# sidebar = {
|
||||
# recentTags = true;
|
||||
# };
|
||||
# advanced = {
|
||||
# removeItemsFromTheTrashAfter30Days = true;
|
||||
# showAllFilenameExtensions = true;
|
||||
# showWarningBeforeChangingAnExtension = true;
|
||||
# showWarningBeforeRemovingFromiCloudDrive = true;
|
||||
# showWarningBeforeEmptyingTheTrash = true;
|
||||
# keepFoldersOnTop = {
|
||||
# inWindowsWhenSortingByName = true;
|
||||
# onDesktop = true;
|
||||
# };
|
||||
# whenPerformingASearch = "Search This Mac";
|
||||
# };
|
||||
# };
|
||||
# menuBar = {
|
||||
# view = {
|
||||
# showTabBar = true;
|
||||
# showSidebar = true;
|
||||
# showPathBar = true;
|
||||
# showStatusBar = true;
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# systemSettings = {
|
||||
# appearance = {
|
||||
# appearance = "Dark";
|
||||
# accentColor = "Multicolor";
|
||||
# # clickInTheScrollBarTo = "Jump to the next page";
|
||||
# sidebarIconSize = "Medium";
|
||||
# showScrollBars = "When scrolling";
|
||||
# };
|
||||
# controlCenter = {
|
||||
# wifi = true;
|
||||
# bluetooth = true;
|
||||
# airdrop = true;
|
||||
# stageManager = true;
|
||||
# focusModes = "active";
|
||||
# screenMirroring = "active";
|
||||
# display = "never";
|
||||
# sound = "always";
|
||||
# nowPlaying = "active";
|
||||
# accessibilityShortcuts = "unset";
|
||||
# musicRecognition = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = true;
|
||||
# };
|
||||
# hearing = "unset";
|
||||
# fastUserSwitching = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = true;
|
||||
# };
|
||||
# keyboardBrightness = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = true;
|
||||
# };
|
||||
# battery = {
|
||||
# showInMenuBar = false;
|
||||
# showInControlCenter = false;
|
||||
# };
|
||||
# batteryShowPercentage = true;
|
||||
# # menuBarOnly = {
|
||||
# # spotlight = false;
|
||||
# # siri = true;
|
||||
# # };
|
||||
# # automaticallyHideAndShowTheMenuBar = "In Full Screen Only";
|
||||
# };
|
||||
# desktopAndDock = {
|
||||
# desktopAndStageManager = {
|
||||
# showItems = {
|
||||
# onDesktop = true;
|
||||
# inStageManager = true;
|
||||
# };
|
||||
# clickWallpaperToRevealDesktop = "Always";
|
||||
# stageManager = false;
|
||||
# showRecentAppsInStageManager = true;
|
||||
# showWindowsFromAnApplication = "All at Once";
|
||||
# };
|
||||
# dock = {
|
||||
# animateOpeningApplications = true;
|
||||
# automaticallyHideAndShowTheDock = enabled;
|
||||
# doubleClickAWindowsTitleBarTo = "Minimize";
|
||||
# magnification = disabled;
|
||||
# minimizeWindowsIntoApplicationIcon = true;
|
||||
# minimizeWindowsUsing = "Genie Effect";
|
||||
# positionOnScreen = "Bottom";
|
||||
# showIndicatorsForOpenApplications = true;
|
||||
# showSuggestedAndRecentAppsInDock = false;
|
||||
# size = 64; # 16 - 128
|
||||
# # persistentApps = [
|
||||
# # { app = "/Applications/Clock.app"; }
|
||||
# # { folder = "/Applications"; }
|
||||
# # { app = "/Applications/Safari.app"; }
|
||||
# # { app = "/Applications/Firefox.app"; }
|
||||
# # { app = "/Applications/Tabby.app"; }
|
||||
# # { app = "/Applications/Termius.app"; }
|
||||
# # { app = "/Applications/Muic.app"; }
|
||||
# # { app = "/Applications/Vesktop.app"; }
|
||||
# # { app = "/Applications/Messages.app"; }
|
||||
# # { app = "/Applications/Calendar.app"; }
|
||||
# # { app = "/Applications/Reminders.app"; }
|
||||
# # { app = "/Applications/Notes.app"; }
|
||||
# # { app = "/Applications/Weather.app"; }
|
||||
# # { app = "/Applications/Maps.app"; }
|
||||
# # { app = "/Applications/App Store.app"; }
|
||||
# # { app = "/Applications/System Settings.app"; }
|
||||
# # { app = "/Applications/ChatGPT.app"; }
|
||||
# # { app = "/Applications/Nextcloud.app"; }
|
||||
# # { app = "/Applications/VSCodium.app"; }
|
||||
# # { app = "/Applications/Omnissa Horizon Client.app"; }
|
||||
# # { app = "/Applications/Proton Pass.app"; }
|
||||
# # { app = "/Applications/OrcaSlicer.app"; }
|
||||
# # { app = "/Applications/AlDente.app"; }
|
||||
# # ];
|
||||
# # persistentOthers = [
|
||||
# # "~/Downloads"
|
||||
# # ];
|
||||
# };
|
||||
# hotCorners = {
|
||||
# # ["-" "Mission Control" "Application Windows" "Desktop" "Start Screen Saver" "Disable Screen Saver" "Dashboard" "Put Display to Sleep" "Launchpad" "Notification Center" "Lock Screen" "Quick Note"]
|
||||
# topLeft = "-";
|
||||
# topRight = "-";
|
||||
# bottomLeft = "-";
|
||||
# bottomRight = "-";
|
||||
# };
|
||||
# missionControl = {
|
||||
# automaticallyRearrangeSpacesBasedOnMostRecentUse = true;
|
||||
# displaysHaveSeparateSpaces = true;
|
||||
# dragWindowsToTopOfScreenToEnterMissionControl = true;
|
||||
# groupWindowsByApplication = true;
|
||||
# whenSwitchingToAnApplicationSwitchToAspaceWithOpenWindowsForTheApplication = true;
|
||||
# };
|
||||
# widgets = {
|
||||
# showWidgets = {
|
||||
# onDesktop = true;
|
||||
# inStageManager = true;
|
||||
# };
|
||||
# widgetStyle = "Automatic";
|
||||
# useIphoneWidgets = true;
|
||||
# };
|
||||
# windows = {
|
||||
# askToKeepChangesWhenClosingDocuments = true;
|
||||
# closeWindowsWhenQuittingAnApplication = true;
|
||||
# dragWindowsToScreenEdgesToTile = true;
|
||||
# dragWindowsToMenuBarToFillScreen = true;
|
||||
# holdOptionKeyWhileDraggingWindowsToTile = true;
|
||||
# preferTabsWhenOpeningDocuments = "In Full Screen";
|
||||
# tiledWindowsHaveMargin = false;
|
||||
# };
|
||||
# };
|
||||
# focus = {
|
||||
# shareAcrossDevices = true;
|
||||
# };
|
||||
# # general.dateAndTime."24HourTime" = false;
|
||||
# notifications = {
|
||||
# notificationCenter = {
|
||||
# showPreviews = "When Unlocked";
|
||||
# summarizeNotifications = true;
|
||||
# };
|
||||
# };
|
||||
# sound = {
|
||||
# soundEffects = {
|
||||
# alertSound = "Boop";
|
||||
# alertVolume = 0.7;
|
||||
# playFeedbackWhenVolumeIsChanged = true;
|
||||
# playUserInterfaceSoundEffects = true;
|
||||
# };
|
||||
# };
|
||||
# spotlight = {
|
||||
# helpAppleImproveSearch = false;
|
||||
# # searchResults = {
|
||||
# # applications = true;
|
||||
# # calculator = true;
|
||||
# # contacts = true;
|
||||
# # conversion = true;
|
||||
# # definition = true;
|
||||
# # developer = true;
|
||||
# # documents = true;
|
||||
# # eventsAndReminders = true;
|
||||
# # folders = true;
|
||||
# # fonts = false;
|
||||
# # images = true;
|
||||
# # mailAndMessages = true;
|
||||
# # movies = true;
|
||||
# # music = true;
|
||||
# # other = false;
|
||||
# # pdfDocuments = true;
|
||||
# # presentations = true;
|
||||
# # siriSuggestions = false;
|
||||
# # systemSettings = true;
|
||||
# # tips = false;
|
||||
# # websites = true;
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
# Manage bug in compilations - who uses manpages in 2024 anyways? :P
|
||||
manual.manpages.enable = false;
|
||||
manual.manpages = enabled;
|
||||
|
||||
# Override defaults that arent supported
|
||||
programs = {
|
||||
mangohud.enable = lib.mkForce false;
|
||||
mangohud = lib.mkForce disabled;
|
||||
|
||||
nh = {
|
||||
flake = "${home.homeDirectory}/nix-config";
|
||||
flake = lib.mkForce "/Users/mattjallen/nix-config";
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
pass-secret-service.enable = lib.mkForce false;
|
||||
nextcloud-client.enable = lib.mkForce false;
|
||||
pass-secret-service = lib.mkForce disabled;
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
theme = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix");
|
||||
shellAliases = {
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-flake = "nix flake update mac-nixpkgs mac-nixos-apple-silicon mac-home-manager mac-impermanence mac-sops-nix --flake /etc/nixos";
|
||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||
};
|
||||
fontName = "JetBrainsMono NFM";
|
||||
fontPackage = pkgs.nerd-fonts.jetbrains-mono;
|
||||
inherit (lib.${namespace}) enabled disabled;
|
||||
# Displays
|
||||
display = {
|
||||
input = "eDP-1";
|
||||
@@ -22,17 +19,30 @@ in
|
||||
home.homeDirectory = "/home/matt";
|
||||
home.stateVersion = "23.11";
|
||||
|
||||
mjallen = {
|
||||
desktop.hyprland = {
|
||||
enable = true;
|
||||
${namespace} = {
|
||||
desktop.gnome = enabled;
|
||||
programs.hyprland = {
|
||||
enable = false;
|
||||
primaryDisplay = "eDP-1";
|
||||
debug.disableScaleChecks = true;
|
||||
|
||||
wallpaper = [
|
||||
"${display.input}, /run/wallpaper.jpg"
|
||||
];
|
||||
|
||||
monitor = [
|
||||
"${display.input},${display.resolution}@${display.refreshRate},0x0,1.25,bitdepth,10,cm,hdr,sdrbrightness,1.2,sdrsaturation,0.98"
|
||||
monitorv2 = [
|
||||
{
|
||||
name = display.input;
|
||||
mode = "${display.resolution}@${display.refreshRate}";
|
||||
position = "0x0";
|
||||
scale = 1.25;
|
||||
extra = [
|
||||
"bitdepth"
|
||||
"10"
|
||||
"cm"
|
||||
"hdr"
|
||||
"sdrbrightness"
|
||||
"1.2"
|
||||
"sdrsaturation"
|
||||
"0.98"
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
workspace = [
|
||||
@@ -41,61 +51,54 @@ in
|
||||
"name:steam, monitor:${display.input}, default:false, special, class:(.*[Ss]team.*)"
|
||||
];
|
||||
|
||||
|
||||
windowRule = [
|
||||
"size 2160 3356, tag:horizonrdp"
|
||||
# "size 2160 3356, tag:horizonrdp"
|
||||
];
|
||||
|
||||
hyprpaper = {
|
||||
wallpaperPath = "/run/wallpaper.jpg";
|
||||
};
|
||||
|
||||
keybinds = {
|
||||
bind = [
|
||||
"$mod, A, exec, chromium --app=\"https://music.apple.com\""
|
||||
|
||||
"SHIFT, XF86MonBrightnessUp, exec, lightctl -D kbd_backlight up"
|
||||
"SHIFT, XF86MonBrightnessDown, exec, lightctl -D kbd_backlight down"
|
||||
];
|
||||
};
|
||||
|
||||
defaultApps = {
|
||||
browser = pkgs.firefox;
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
exec-once = brightnessctl -d kbd_backlight s 50%
|
||||
'';
|
||||
};
|
||||
programs = {
|
||||
btop.enable = true;
|
||||
kitty = {
|
||||
enable = true;
|
||||
font = {
|
||||
name = fontName;
|
||||
package = fontPackage;
|
||||
};
|
||||
};
|
||||
mako = {
|
||||
enable = true;
|
||||
fontName = fontName;
|
||||
};
|
||||
nwg-dock.enable = true;
|
||||
nwg-drawer.enable = true;
|
||||
nwg-panel = {
|
||||
enable = true;
|
||||
defaultApps = {
|
||||
browser = pkgs.firefox;
|
||||
};
|
||||
};
|
||||
btop = enabled;
|
||||
kitty = disabled;
|
||||
mako = disabled;
|
||||
nwg-dock = disabled;
|
||||
nwg-drawer = disabled;
|
||||
nwg-panel = disabled;
|
||||
waybar = {
|
||||
enable = true;
|
||||
enable = false;
|
||||
|
||||
layer = "bottom";
|
||||
|
||||
modules-right = [
|
||||
"tray"
|
||||
"temperature"
|
||||
"temperature#gpu"
|
||||
"keyboard-state#capslock"
|
||||
"keyboard-state#numlock"
|
||||
"wireplumber#sink"
|
||||
"bluetooth"
|
||||
"network"
|
||||
"idle_inhibitor"
|
||||
"clock"
|
||||
"battery"
|
||||
"custom/weather"
|
||||
];
|
||||
temperature = {
|
||||
cpu = enabled;
|
||||
gpu = enabled;
|
||||
};
|
||||
|
||||
extraModules = {
|
||||
"custom/lights" = {
|
||||
tooltip = false;
|
||||
exec = "waybar-hass --get_light light.living_room_lights";
|
||||
interval = "once";
|
||||
format = "{text}";#"";
|
||||
format = "{text}"; # "";
|
||||
on-click = "waybar-hass --toggle_light light.living_room_lights";
|
||||
return-type = "json";
|
||||
};
|
||||
@@ -103,32 +106,44 @@ in
|
||||
|
||||
extraModulesStyle = ''
|
||||
#custom-lights {
|
||||
color: ${theme.frost.nord8};
|
||||
background-color: ${theme.polarNight.nord0};
|
||||
${theme.defaultOpacity}
|
||||
${theme.borderLeft}
|
||||
color: @base0C;
|
||||
opacity: 0.85;
|
||||
background-color: @base00;
|
||||
}
|
||||
|
||||
#custom-lights:hover {
|
||||
background: ${theme.polarNight.nord3};
|
||||
background: @base03;
|
||||
}
|
||||
'';
|
||||
|
||||
windowOffset = 75;
|
||||
};
|
||||
wlogout.enable = true;
|
||||
wofi.enable = true;
|
||||
wlogout = disabled;
|
||||
wofi = disabled;
|
||||
};
|
||||
};
|
||||
|
||||
home.packages = with pkgs; [
|
||||
iw
|
||||
iwd
|
||||
orca-slicer
|
||||
vscodium
|
||||
];
|
||||
home.packages =
|
||||
with pkgs.${namespace};
|
||||
[
|
||||
# librepods
|
||||
]
|
||||
++ (with pkgs; [
|
||||
bolt-launcher
|
||||
iw
|
||||
iwd
|
||||
orca-slicer
|
||||
vscodium
|
||||
]);
|
||||
|
||||
services = {
|
||||
kdeconnect = {
|
||||
enable = lib.mkForce true;
|
||||
indicator = lib.mkForce true;
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
password-store.enable = true;
|
||||
|
||||
zsh.shellAliases = shellAliases;
|
||||
password-store = enabled;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,65 +1,54 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
let
|
||||
shellAliases = {
|
||||
ll = "ls -alh";
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-flake = "nix flake update pi4-nixpkgs pi4-home-manager pi4-impermanence pi4-sops-nix pi4-nixos-hardware pi4-nixos-raspberrypi pi4-disko --flake /etc/nixos";
|
||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||
nas-ssh = "kitten ssh admin@10.0.1.3";
|
||||
ducks = "du -cksh * | sort -hr | head -n 15";
|
||||
};
|
||||
inherit (lib.${namespace}) enabled disabled;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
../../../modules/home/home
|
||||
../../../modules/home/programs/git
|
||||
../../../modules/home/programs/zsh
|
||||
];
|
||||
|
||||
home.username = "matt";
|
||||
|
||||
sops = {
|
||||
age.keyFile = "/home/matt/.config/sops/age/keys.txt";
|
||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||
validateSopsFiles = false;
|
||||
secrets = {
|
||||
"ssh-keys-public/pi4" = {
|
||||
path = "/home/matt/.ssh/id_ed25519.pub";
|
||||
mode = "0644";
|
||||
};
|
||||
"ssh-keys-private/pi4" = {
|
||||
path = "/home/matt/.ssh/id_ed25519";
|
||||
mode = "0600";
|
||||
};
|
||||
# "ssh-keys-public/desktop-nixos" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys";
|
||||
# mode = "0600";
|
||||
# };
|
||||
sops = {
|
||||
age.keyFile = "/home/matt/.config/sops/age/keys.txt";
|
||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||
validateSopsFiles = false;
|
||||
secrets = {
|
||||
"ssh-keys-public/pi4" = {
|
||||
path = "/home/matt/.ssh/id_ed25519.pub";
|
||||
mode = "0644";
|
||||
};
|
||||
"ssh-keys-private/pi4" = {
|
||||
path = "/home/matt/.ssh/id_ed25519";
|
||||
mode = "0600";
|
||||
};
|
||||
# "ssh-keys-public/desktop-nixos" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys";
|
||||
# mode = "0600";
|
||||
# };
|
||||
|
||||
# "ssh-keys-public/desktop-nixos-root" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys2";
|
||||
# mode = "0600";
|
||||
# };
|
||||
# "ssh-keys-public/desktop-nixos-root" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys2";
|
||||
# mode = "0600";
|
||||
# };
|
||||
|
||||
# "ssh-keys-public/desktop-windows" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys3";
|
||||
# mode = "0600";
|
||||
# };
|
||||
# "ssh-keys-public/desktop-windows" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys3";
|
||||
# mode = "0600";
|
||||
# };
|
||||
|
||||
# "ssh-keys-public/macbook-macos" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys4";
|
||||
# mode = "0600";
|
||||
# };
|
||||
};
|
||||
};
|
||||
# "ssh-keys-public/macbook-macos" = {
|
||||
# path = "/home/matt/.ssh/authorized_keys4";
|
||||
# mode = "0600";
|
||||
# };
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
mangohud.enable = lib.mkForce true;
|
||||
zsh.shellAliases = shellAliases;
|
||||
mangohud = lib.mkForce enabled;
|
||||
};
|
||||
|
||||
services = {
|
||||
nextcloud-client.enable = lib.mkForce true;
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
{ pkgs, lib, config, namespace, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-flake = "nix flake update pi5-nixpkgs pi5-home-manager pi5-impermanence pi5-nixos-hardware pi5-sops-nix nixos-raspberrypi --flake /etc/nixos";
|
||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||
nas-ssh = "kitten ssh admin@10.0.1.3";
|
||||
};
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
|
||||
@@ -51,7 +50,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
zsh.shellAliases = shellAliases;
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
18
homes/aarch64-linux/root@macbook-pro-nixos/default.nix
Normal file
18
homes/aarch64-linux/root@macbook-pro-nixos/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "nixos-rebuild boot --max-jobs 10";
|
||||
update-switch = "nixos-rebuild switch --max-jobs 10";
|
||||
};
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home = {
|
||||
username = "root";
|
||||
homeDirectory = lib.mkForce "/${config.home.username}";
|
||||
enableNixpkgsReleaseCheck = false;
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
zsh.shellAliases = shellAliases;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
18
homes/aarch64-linux/root@pi5/default.nix
Normal file
18
homes/aarch64-linux/root@pi5/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10";
|
||||
update-flake = "nix flake update nas-nixpkgs nas-authentik-nix nas-cosmic nas-crowdsec nas-home-manager nas-impermanence nas-lanzaboote nas-nixos-hardware nas-sops-nix --flake /etc/nixos";
|
||||
};
|
||||
in
|
||||
{ pkgs, namespace, ... }:
|
||||
{
|
||||
home.username = "admin";
|
||||
home = {
|
||||
username = "admin";
|
||||
packages =
|
||||
with pkgs;
|
||||
[
|
||||
heroic
|
||||
]
|
||||
++ (with pkgs.${namespace}; [
|
||||
moondeck-buddy
|
||||
]);
|
||||
};
|
||||
|
||||
# mjallen.home.enable = true;
|
||||
${namespace} = {
|
||||
sops.enable = true;
|
||||
};
|
||||
|
||||
sops = {
|
||||
age.keyFile = "/home/admin/.config/sops/age/keys.txt";
|
||||
@@ -60,18 +65,23 @@ in
|
||||
}
|
||||
];
|
||||
};
|
||||
steam-rom-manager = {
|
||||
enable = true;
|
||||
steamUsername = "mjallen18";
|
||||
|
||||
zsh.shellAliases = shellAliases;
|
||||
# Optional: override default paths if needed
|
||||
environmentVariables = {
|
||||
romsDirectory = "/home/admin/Emulation/roms";
|
||||
steamDirectory = "/home/admin/.local/share/Steam";
|
||||
};
|
||||
|
||||
emulators = {
|
||||
"Non-SRM Shortcuts" = {
|
||||
enable = true;
|
||||
parserType = "Non-SRM Shortcuts";
|
||||
extraArgs = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# services.nixai = {
|
||||
# enable = true;
|
||||
# mcp = {
|
||||
# enable = true;
|
||||
# # Optional: custom socket path (uses `$HOME` expansion)
|
||||
# socketPath = "$HOME/.local/share/nixai/mcp.sock";
|
||||
# };
|
||||
# # Optional: integrate with VS Code
|
||||
# vscodeIntegration = true;
|
||||
# };
|
||||
}
|
||||
37
homes/x86_64-linux/admin@nuc-nixos/default.nix
Executable file
37
homes/x86_64-linux/admin@nuc-nixos/default.nix
Executable file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "admin";
|
||||
|
||||
# Configure systemd user service for protonmail-bridge
|
||||
systemd.user.services.protonmail-bridge = {
|
||||
Service = {
|
||||
Environment = [
|
||||
"GNUPGHOME=/home/admin/.gnupg"
|
||||
"PASSWORD_STORE_DIR=/home/admin/.local/password-store"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
protonmail-bridge = {
|
||||
enable = true;
|
||||
extraPackages = with pkgs; [
|
||||
pass
|
||||
libsecret
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{ pkgs,... }:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10";
|
||||
update-flake = "nix flake update nas-nixpkgs nas-authentik-nix nas-cosmic nas-crowdsec nas-home-manager nas-impermanence nas-lanzaboote nas-nixos-hardware nas-sops-nix --flake /etc/nixos";
|
||||
};
|
||||
in
|
||||
{
|
||||
home.username = "admin";
|
||||
|
||||
programs = {
|
||||
zsh.shellAliases = shellAliases;
|
||||
};
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10";
|
||||
update-flake = "nix flake update steamdeck-nixpkgs steamdeck-chaotic steamdeck-home-manager steamdeck-impermanence steamdeck-jovian steamdeck-lanzaboote steamdeck-nixos-hardware steamdeck-sops-nix steamdeck-steam-rom-manager --flake /etc/nixos";
|
||||
nas-ssh = "ssh admin@10.0.1.3";
|
||||
};
|
||||
in
|
||||
{
|
||||
home.username = "deck";
|
||||
|
||||
sops = {
|
||||
age.keyFile = "/home/deck/.config/sops/age/keys.txt";
|
||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||
validateSopsFiles = false;
|
||||
secrets = {
|
||||
"ssh-keys-public/deck" = {
|
||||
path = "/home/deck/.ssh/id_ed25519.pub";
|
||||
mode = "0644";
|
||||
};
|
||||
"ssh-keys-private/deck" = {
|
||||
path = "/home/deck/.ssh/id_ed25519";
|
||||
mode = "0600";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
steam-rom-manager = {
|
||||
enable = true;
|
||||
steamUsername = "mjallen18";
|
||||
|
||||
# Optional: override default paths if needed
|
||||
environmentVariables = {
|
||||
romsDirectory = "/home/deck/Emulation/roms";
|
||||
steamDirectory = "/home/deck/.local/share/Steam";
|
||||
};
|
||||
|
||||
emulators = {
|
||||
ryujinx.enable = true;
|
||||
|
||||
dolphin-gamecube = {
|
||||
enable = true;
|
||||
package = pkgs.dolphin-emu;
|
||||
romFolder = "gc";
|
||||
fileTypes = [ ".iso" ".ISO" ".gcm" ".GCM" ".ciso" ".CISO" "rvz" ];
|
||||
extraArgs = "-b -e \"\${filePath}\"";
|
||||
};
|
||||
|
||||
pcsx2.enable = true;
|
||||
mgba.enable = true;
|
||||
|
||||
"Non-SRM Shortcuts" = {
|
||||
enable = true;
|
||||
parserType = "Non-SRM Shortcuts";
|
||||
extraArgs = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
zsh.shellAliases = shellAliases;
|
||||
};
|
||||
|
||||
home.packages = with pkgs; [
|
||||
dolphin-emu
|
||||
heroic
|
||||
mgba
|
||||
prismlauncher
|
||||
ryujinx-greemdev
|
||||
vmware-horizon-client
|
||||
];
|
||||
}
|
||||
88
homes/x86_64-linux/matt@allyx/default.nix
Executable file
88
homes/x86_64-linux/matt@allyx/default.nix
Executable file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) enabled;
|
||||
in
|
||||
{
|
||||
home.username = "matt";
|
||||
|
||||
${namespace}.desktop.gnome = enabled;
|
||||
|
||||
sops = {
|
||||
age.keyFile = "/home/matt/.config/sops/age/keys.txt";
|
||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||
validateSopsFiles = false;
|
||||
secrets = {
|
||||
"ssh-keys-public/matt" = {
|
||||
path = "/home/matt/.ssh/id_ed25519.pub";
|
||||
mode = "0644";
|
||||
};
|
||||
"ssh-keys-private/matt" = {
|
||||
path = "/home/matt/.ssh/id_ed25519";
|
||||
mode = "0600";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
steam-rom-manager = {
|
||||
enable = true;
|
||||
steamUsername = "mjallen18";
|
||||
|
||||
# Optional: override default paths if needed
|
||||
environmentVariables = {
|
||||
romsDirectory = "/home/matt/Emulation/roms";
|
||||
steamDirectory = "/home/matt/.local/share/Steam";
|
||||
};
|
||||
|
||||
emulators = {
|
||||
ryujinx = enabled;
|
||||
|
||||
dolphin-gamecube = {
|
||||
enable = true;
|
||||
package = pkgs.dolphin-emu;
|
||||
romFolder = "gc";
|
||||
fileTypes = [
|
||||
".iso"
|
||||
".ISO"
|
||||
".gcm"
|
||||
".GCM"
|
||||
".ciso"
|
||||
".CISO"
|
||||
"rvz"
|
||||
];
|
||||
extraArgs = "-b -e \"\${filePath}\"";
|
||||
};
|
||||
|
||||
pcsx2 = enabled;
|
||||
mgba = enabled;
|
||||
|
||||
"Non-SRM Shortcuts" = {
|
||||
enable = true;
|
||||
parserType = "Non-SRM Shortcuts";
|
||||
extraArgs = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home.packages =
|
||||
with pkgs;
|
||||
[
|
||||
dolphin-emu
|
||||
heroic
|
||||
mgba
|
||||
moonlight-qt
|
||||
prismlauncher
|
||||
ryubing
|
||||
omnissa-horizon-client
|
||||
]
|
||||
++ (with pkgs.${namespace}; [
|
||||
discord-krisp
|
||||
librepods-beta
|
||||
]);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
{ pkgs, namespace, ... }:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3";
|
||||
update-flake = "nix flake update desktop-nixpkgs desktop-chaotic desktop-home-manager desktop-impermanence desktop-lanzaboote desktop-nixos-hardware desktop-sops-nix desktop-steam-rom-manager --flake /etc/nixos";
|
||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||
};
|
||||
in
|
||||
{
|
||||
home.username = "matt";
|
||||
|
||||
services = {
|
||||
remmina = {
|
||||
enable = true;
|
||||
addRdpMimeTypeAssoc = true;
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
password-store.enable = true;
|
||||
|
||||
zsh.shellAliases = shellAliases;
|
||||
};
|
||||
|
||||
home.packages = with pkgs; [
|
||||
bottles
|
||||
compose2nix
|
||||
discord
|
||||
distrobox
|
||||
heroic
|
||||
stable.vmware-horizon-client
|
||||
jq
|
||||
lutris
|
||||
lzip
|
||||
morph
|
||||
orca-slicer
|
||||
piper
|
||||
prismlauncher
|
||||
protontricks
|
||||
protonvpn-gui
|
||||
python3
|
||||
smile
|
||||
unigine-heaven
|
||||
via
|
||||
virt-manager
|
||||
vorta
|
||||
waydroid-helper
|
||||
];
|
||||
}
|
||||
242
homes/x86_64-linux/matt@matt-nixos/default.nix
Executable file
242
homes/x86_64-linux/matt@matt-nixos/default.nix
Executable file
@@ -0,0 +1,242 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) enabled disabled;
|
||||
displayLeft = {
|
||||
input = "DP-1";
|
||||
resolution = "3840x2160";
|
||||
refreshRate = "120.00000";
|
||||
};
|
||||
displayRight = {
|
||||
input = "DP-2";
|
||||
resolution = "3840x2160";
|
||||
refreshRate = "240.00000";
|
||||
};
|
||||
in
|
||||
{
|
||||
home.username = "matt";
|
||||
|
||||
${namespace} = {
|
||||
sops = {
|
||||
enable = true;
|
||||
};
|
||||
shell-aliases = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
programs = {
|
||||
hyprland = {
|
||||
enable = true;
|
||||
primaryDisplay = "DP-1";
|
||||
|
||||
monitorv2 = [
|
||||
{
|
||||
name = displayLeft.input;
|
||||
mode = "${displayLeft.resolution}@${displayLeft.refreshRate}";
|
||||
position = "0x0";
|
||||
scale = 1.0;
|
||||
extra = [
|
||||
# "bitdepth"
|
||||
# "10"
|
||||
# "cm"
|
||||
# "hdredid"
|
||||
# "sdrbrightness"
|
||||
# "1.2"
|
||||
# "sdrsaturation"
|
||||
# "0.98"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = displayRight.input;
|
||||
mode = "${displayRight.resolution}@${displayRight.refreshRate}";
|
||||
position = "3840x0";
|
||||
scale = 1.0;
|
||||
extra = [
|
||||
# "bitdepth"
|
||||
# "10"
|
||||
# "cm"
|
||||
# "hdredid"
|
||||
# "sdrbrightness"
|
||||
# "1.5"
|
||||
# "sdrsaturation"
|
||||
# "0.98"
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
workspace = [
|
||||
"name:firefox, monitor:${displayRight.input}, default:false, special, class:(.*firefox.*)"
|
||||
"name:discord, monitor:${displayRight.input}, default:true, special, title:(.*vesktop.*), title:(.*Apple Music.*)"
|
||||
"name:steam, monitor:${displayLeft.input}, default:false, special, class:(.*[Ss]team.*)"
|
||||
];
|
||||
|
||||
windowRule = [
|
||||
"match:tag horizonrdp, size 2160 7680"
|
||||
];
|
||||
|
||||
autostartCommands = [
|
||||
"[silent] firefox"
|
||||
"[silent] discord"
|
||||
"[silent] chromium --app=\"https://music.apple.com\""
|
||||
"[silent] steam"
|
||||
];
|
||||
|
||||
hyprpaper = {
|
||||
wallpaperPath = "/run/wallpaper.jpg";
|
||||
};
|
||||
|
||||
keybinds = {
|
||||
bind = [
|
||||
"$mod, A, exec, chromium --app=\"https://music.apple.com\""
|
||||
"$mod, C, exec, discord"
|
||||
"$mod, G, exec, steam"
|
||||
];
|
||||
};
|
||||
|
||||
defaultApps = {
|
||||
browser = pkgs.firefox;
|
||||
};
|
||||
};
|
||||
btop = enabled;
|
||||
kitty = enabled;
|
||||
mako = enabled;
|
||||
nwg-dock = enabled;
|
||||
nwg-drawer = enabled;
|
||||
nwg-panel = {
|
||||
enable = true;
|
||||
defaultApps = {
|
||||
browser = pkgs.firefox;
|
||||
};
|
||||
};
|
||||
waybar = {
|
||||
enable = true;
|
||||
|
||||
layer = "bottom";
|
||||
|
||||
network.interface = "wlp9s0";
|
||||
temperature = {
|
||||
cpu = enabled;
|
||||
gpu = enabled;
|
||||
};
|
||||
|
||||
extraModules = {
|
||||
"custom/lights" = {
|
||||
tooltip = false;
|
||||
exec = "waybar-hass --get_light light.living_room_lights";
|
||||
interval = "once";
|
||||
format = "{text}"; # "";
|
||||
on-click = "waybar-hass --toggle_light light.living_room_lights";
|
||||
return-type = "json";
|
||||
};
|
||||
};
|
||||
|
||||
extraModulesStyle = ''
|
||||
#custom-lights {
|
||||
color: @base0C;
|
||||
background-color: @base00;
|
||||
opacity: 0.85;
|
||||
border-left: 5px solid @base0C;
|
||||
}
|
||||
|
||||
#custom-lights:hover {
|
||||
background: @base03;
|
||||
}
|
||||
'';
|
||||
};
|
||||
wlogout = enabled;
|
||||
wofi = enabled;
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
remmina = {
|
||||
enable = true;
|
||||
addRdpMimeTypeAssoc = true;
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
password-store = enabled;
|
||||
};
|
||||
|
||||
home.packages =
|
||||
with pkgs;
|
||||
[
|
||||
bolt-launcher
|
||||
clevis
|
||||
compose2nix
|
||||
distrobox
|
||||
heroic
|
||||
home-manager
|
||||
omnissa-horizon-client
|
||||
jq
|
||||
lzip
|
||||
morph
|
||||
orca-slicer
|
||||
piper
|
||||
prismlauncher
|
||||
protontricks
|
||||
protonvpn-gui
|
||||
runelite
|
||||
smile
|
||||
via
|
||||
virt-manager
|
||||
vorta
|
||||
waydroid-helper
|
||||
]
|
||||
++ (with pkgs.${namespace}; [
|
||||
discord-krisp
|
||||
# librepods
|
||||
]);
|
||||
|
||||
specialisation = {
|
||||
"end4".configuration = {
|
||||
programs = {
|
||||
illogical-impulse = {
|
||||
enable = true;
|
||||
|
||||
dotfiles = {
|
||||
fish = lib.mkForce disabled;
|
||||
starship = lib.mkForce disabled;
|
||||
};
|
||||
|
||||
hyprland.plugins = [
|
||||
pkgs.hyprlandPlugins.hyprbars
|
||||
pkgs.hyprlandPlugins.hyprexpo
|
||||
];
|
||||
};
|
||||
};
|
||||
stylix.targets.qt = lib.mkForce disabled;
|
||||
${namespace} = {
|
||||
programs = {
|
||||
mako = lib.mkForce disabled;
|
||||
nwg-dock = lib.mkForce disabled;
|
||||
nwg-drawer = lib.mkForce disabled;
|
||||
nwg-panel = lib.mkForce disabled;
|
||||
waybar = lib.mkForce disabled;
|
||||
wlogout = lib.mkForce disabled;
|
||||
wofi = lib.mkForce disabled;
|
||||
};
|
||||
};
|
||||
};
|
||||
"cosmic".configuration = {
|
||||
${namespace} = {
|
||||
programs = {
|
||||
hyprland = lib.mkForce disabled;
|
||||
kitty = lib.mkForce disabled;
|
||||
mako = lib.mkForce disabled;
|
||||
nwg-dock = lib.mkForce disabled;
|
||||
nwg-drawer = lib.mkForce disabled;
|
||||
nwg-panel = lib.mkForce disabled;
|
||||
waybar = lib.mkForce disabled;
|
||||
wlogout = lib.mkForce disabled;
|
||||
wofi = lib.mkForce disabled;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
18
homes/x86_64-linux/nixos@iso-minimal/default.nix
Normal file
18
homes/x86_64-linux/nixos@iso-minimal/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
18
homes/x86_64-linux/root@allyx/default.nix
Normal file
18
homes/x86_64-linux/root@allyx/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
18
homes/x86_64-linux/root@iso-minimal/default.nix
Normal file
18
homes/x86_64-linux/root@iso-minimal/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
18
homes/x86_64-linux/root@jallen-nas/default.nix
Normal file
18
homes/x86_64-linux/root@jallen-nas/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
18
homes/x86_64-linux/root@matt-nixos/default.nix
Normal file
18
homes/x86_64-linux/root@matt-nixos/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
18
homes/x86_64-linux/root@nuc-nixos/default.nix
Normal file
18
homes/x86_64-linux/root@nuc-nixos/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) disabled;
|
||||
in
|
||||
{
|
||||
home.username = "root";
|
||||
services = {
|
||||
nextcloud-client = lib.mkForce disabled;
|
||||
kdeconnect = {
|
||||
enable = false;
|
||||
indicator = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
shellAliases = {
|
||||
update-boot = "nixos-rebuild boot --max-jobs 10";
|
||||
update-switch = "nixos-rebuild switch --max-jobs 10";
|
||||
};
|
||||
in
|
||||
{
|
||||
home = {
|
||||
username = "root";
|
||||
homeDirectory = lib.mkForce "/${config.home.username}";
|
||||
};
|
||||
|
||||
programs = {
|
||||
zsh.shellAliases = shellAliases;
|
||||
};
|
||||
}
|
||||
130
lib/README.md
Normal file
130
lib/README.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# mjallen-lib Utility Functions
|
||||
|
||||
This directory contains utility functions that can be used to enhance your Nix configuration. These functions are inspired by the khanelinix repository and provide a more explicit and modular approach to building Nix configurations.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
- `default.nix`: Main entry point that imports and exposes all utility functions
|
||||
- `module/`: Utilities for module creation and option handling
|
||||
- `file/`: Utilities for file handling and module discovery
|
||||
- `system/`: Utilities for system configuration building
|
||||
|
||||
## How to Use
|
||||
|
||||
### 1. Import the Library
|
||||
|
||||
The library is already imported in your flake.nix file through the outputs-builder:
|
||||
|
||||
```nix
|
||||
outputs-builder = channels: {
|
||||
formatter = inputs.treefmt-nix.lib.mkWrapper channels.nixpkgs ./treefmt.nix;
|
||||
|
||||
# Add mjallen-lib to the flake outputs
|
||||
overlays = {
|
||||
mjallen-lib = final: prev: {
|
||||
mjallen-lib = (import ./lib { inherit inputs; }).mjallen-lib;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
This makes the mjallen-lib available to all your modules through the extended lib.
|
||||
|
||||
### 2. Use the Module Utilities
|
||||
|
||||
The module utilities provide functions for creating modules with consistent options:
|
||||
|
||||
```nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib.mjallen.module) mkModule mkOpt mkBoolOpt;
|
||||
in
|
||||
mkModule {
|
||||
name = "mymodule";
|
||||
description = "My awesome module";
|
||||
options = {
|
||||
setting1 = mkOpt lib.types.str "default" "Description of setting1";
|
||||
setting2 = mkBoolOpt false "Description of setting2";
|
||||
};
|
||||
config = {
|
||||
# Module implementation
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Use the File Utilities
|
||||
|
||||
The file utilities provide functions for file handling and module discovery:
|
||||
|
||||
```nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib.mjallen.file) safeImport importModulesRecursive;
|
||||
in
|
||||
{
|
||||
# Import a file with error handling
|
||||
myConfig = safeImport ./my-config.nix {};
|
||||
|
||||
# Import all modules recursively
|
||||
imports = importModulesRecursive ./modules;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Use the System Utilities
|
||||
|
||||
The system utilities provide functions for building system configurations:
|
||||
|
||||
```nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib.mjallen.system.common) mkHomeManagerConfig;
|
||||
in
|
||||
{
|
||||
# Build home-manager configurations
|
||||
homeManagerConfig = mkHomeManagerConfig {
|
||||
extendedLib = lib;
|
||||
inputs = inputs;
|
||||
system = "x86_64-linux";
|
||||
matchingHomes = { ... };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Available Functions
|
||||
|
||||
### Module Utilities
|
||||
|
||||
- `mkModule`: Create a module with common options
|
||||
- `mkOpt`: Create an option with a type, default value, and description
|
||||
- `mkOpt'`: Create an option with a type and default value (no description)
|
||||
- `mkBoolOpt`: Create a boolean option with a default value and description
|
||||
- `mkBoolOpt'`: Create a boolean option with a default value (no description)
|
||||
- `enabled`: Standard enable pattern
|
||||
- `disabled`: Standard disable pattern
|
||||
- `capitalize`: Capitalize a string
|
||||
- `boolToNum`: Convert a boolean to a number
|
||||
- `default-attrs`: Apply mkDefault to all attributes
|
||||
- `force-attrs`: Apply mkForce to all attributes
|
||||
- `nested-default-attrs`: Apply default-attrs to nested attributes
|
||||
- `nested-force-attrs`: Apply force-attrs to nested attributes
|
||||
|
||||
### File Utilities
|
||||
|
||||
- `readFile`: Read a file and return its contents
|
||||
- `pathExists`: Check if a file exists
|
||||
- `safeImport`: Import a nix file with error handling
|
||||
- `scanDir`: Scan a directory and return directory names
|
||||
- `getFile`: Get a file path relative to the flake root
|
||||
- `importModulesRecursive`: Recursively discover and import all Nix modules in a directory tree
|
||||
- `scanSystems`: Recursively scan systems directory structure
|
||||
- `filterNixOSSystems`: Filter systems for NixOS (Linux)
|
||||
- `filterDarwinSystems`: Filter systems for Darwin (macOS)
|
||||
- `scanHomes`: Scan homes directory structure for home configurations
|
||||
|
||||
### System Utilities
|
||||
|
||||
- `mkExtendedLib`: Extend the nixpkgs lib with mjallen-lib
|
||||
- `mkNixpkgsConfig`: Create a nixpkgs configuration
|
||||
- `mkHomeConfigs`: Create home configurations for a system and hostname
|
||||
- `mkHomeManagerConfig`: Create a home-manager configuration
|
||||
- `mkSpecialArgs`: Create special arguments for a system configuration
|
||||
3
lib/base64/ascii
Normal file
3
lib/base64/ascii
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
|
||||
62
lib/base64/default.nix
Normal file
62
lib/base64/default.nix
Normal file
@@ -0,0 +1,62 @@
|
||||
{ inputs }:
|
||||
let
|
||||
inherit (inputs.nixpkgs.lib)
|
||||
concatLists
|
||||
concatMapStrings
|
||||
foldl'
|
||||
genList
|
||||
hasSuffix
|
||||
imap0
|
||||
length
|
||||
mod
|
||||
nameValuePair
|
||||
stringToCharacters
|
||||
sublist
|
||||
substring
|
||||
take
|
||||
;
|
||||
in
|
||||
rec {
|
||||
base64Table = builtins.listToAttrs (
|
||||
imap0 (i: c: nameValuePair c i) (
|
||||
# The '=' is included so the main algorithm doesn't fail before we can trim the result
|
||||
stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
)
|
||||
);
|
||||
|
||||
# Generated using python3:
|
||||
# print(''.join([ chr(n) for n in range(1, 256) ]), file=open('ascii', 'w'))
|
||||
ascii = builtins.readFile ./ascii;
|
||||
|
||||
decode =
|
||||
str:
|
||||
let
|
||||
paddingCount =
|
||||
if hasSuffix "==" str then
|
||||
2
|
||||
else if hasSuffix "=" str then
|
||||
1
|
||||
else
|
||||
0;
|
||||
|
||||
numbers64 = map (c: base64Table.${c}) (stringToCharacters str);
|
||||
|
||||
allBytes = concatLists (
|
||||
genList (
|
||||
i:
|
||||
let
|
||||
v = foldl' (acc: el: acc * 64 + el) 0 (sublist (i * 4) 4 numbers64);
|
||||
in
|
||||
[
|
||||
(mod (v / 256 / 256) 256)
|
||||
(mod (v / 256) 256)
|
||||
(mod v 256)
|
||||
]
|
||||
) (length numbers64 / 4)
|
||||
);
|
||||
|
||||
finalBytes = take (length allBytes - paddingCount) allBytes;
|
||||
|
||||
in
|
||||
concatMapStrings (n: substring (n - 1) 1 ascii) finalBytes;
|
||||
}
|
||||
25
lib/default.nix
Normal file
25
lib/default.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
mjallen-lib = {
|
||||
# Import module utilities
|
||||
module = import ./module { inherit inputs; };
|
||||
|
||||
# Import file utilities
|
||||
file = import ./file { inherit inputs; };
|
||||
|
||||
# Import system utilities
|
||||
system = import ./system { inherit inputs; };
|
||||
|
||||
# Import reverse proxy utilities
|
||||
reverseproxy = import ./reverseproxy { inherit inputs; };
|
||||
|
||||
# Import examples
|
||||
examples = import ./examples { inherit inputs; };
|
||||
|
||||
# Import versioning utilities
|
||||
versioning = import ./versioning {
|
||||
lib = inputs.nixpkgs.lib;
|
||||
inherit inputs;
|
||||
};
|
||||
};
|
||||
}
|
||||
8
lib/examples/default.nix
Normal file
8
lib/examples/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{ ... }:
|
||||
{
|
||||
# Import all examples
|
||||
sops = import ./sops.nix;
|
||||
homeSops = import ./home-sops.nix;
|
||||
fileUtils = import ./file-utils.nix;
|
||||
systemUtils = import ./system-utils.nix;
|
||||
}
|
||||
60
lib/examples/file-utils.nix
Normal file
60
lib/examples/file-utils.nix
Normal file
@@ -0,0 +1,60 @@
|
||||
{ lib, namespace, ... }:
|
||||
let
|
||||
inherit (lib.${namespace}.file)
|
||||
readFile
|
||||
pathExists
|
||||
safeImport
|
||||
scanDir
|
||||
getFile
|
||||
importModulesRecursive
|
||||
scanSystems
|
||||
filterNixOSSystems
|
||||
filterDarwinSystems
|
||||
scanHomes
|
||||
;
|
||||
in
|
||||
{
|
||||
# Example of reading a file
|
||||
myFileContent = readFile ./example.txt;
|
||||
|
||||
# Example of checking if a file exists
|
||||
fileExists = pathExists ./example.txt;
|
||||
|
||||
# Example of safely importing a file
|
||||
myConfig = safeImport ./my-config.nix { };
|
||||
|
||||
# Example of scanning a directory
|
||||
directoryContents = scanDir ./modules;
|
||||
|
||||
# Example of getting a file path relative to the flake root
|
||||
flakeFile = getFile "flake.nix";
|
||||
|
||||
# Example of importing modules recursively
|
||||
modules = importModulesRecursive ./modules;
|
||||
|
||||
# Example of scanning systems
|
||||
allSystems = scanSystems ./systems;
|
||||
|
||||
# Example of filtering systems
|
||||
nixosSystems = filterNixOSSystems allSystems;
|
||||
darwinSystems = filterDarwinSystems allSystems;
|
||||
|
||||
# Example of scanning homes
|
||||
allHomes = scanHomes ./homes;
|
||||
|
||||
# Example of using these functions together
|
||||
nixosConfigurations = lib.mapAttrs' (
|
||||
_name:
|
||||
{ system, hostname, ... }:
|
||||
{
|
||||
name = hostname;
|
||||
value = lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [
|
||||
{ networking.hostName = hostname; }
|
||||
]
|
||||
++ importModulesRecursive ./modules/nixos;
|
||||
};
|
||||
}
|
||||
) nixosSystems;
|
||||
}
|
||||
40
lib/examples/home-sops.nix
Normal file
40
lib/examples/home-sops.nix
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}.module) mkModule mkOpt;
|
||||
in
|
||||
mkModule {
|
||||
name = "sops";
|
||||
description = "SOPS secret management for home-manager";
|
||||
options = {
|
||||
defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
|
||||
|
||||
sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [ ] "SSH Key paths to use.";
|
||||
};
|
||||
config = {
|
||||
home.packages = with pkgs; [
|
||||
age
|
||||
sops
|
||||
ssh-to-age
|
||||
];
|
||||
|
||||
sops = {
|
||||
inherit (config.${namespace}.sops) defaultSopsFile;
|
||||
defaultSopsFormat = "yaml";
|
||||
|
||||
age = {
|
||||
generateKey = true;
|
||||
keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
|
||||
sshKeyPaths = [
|
||||
"${config.home.homeDirectory}/.ssh/id_ed25519"
|
||||
]
|
||||
++ config.${namespace}.sops.sshKeyPaths;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
117
lib/examples/reverseproxy.nix
Normal file
117
lib/examples/reverseproxy.nix
Normal file
@@ -0,0 +1,117 @@
|
||||
# Example usage of the reverse proxy utilities
|
||||
{ lib, namespace, ... }:
|
||||
let
|
||||
inherit (lib.${namespace} - lib.reverseproxy)
|
||||
mkReverseProxy
|
||||
mkReverseProxies
|
||||
templates
|
||||
middlewares
|
||||
urls
|
||||
;
|
||||
in
|
||||
{
|
||||
# Example 1: Simple reverse proxy for a local service
|
||||
simpleProxy = mkReverseProxy {
|
||||
name = "myapp";
|
||||
subdomain = "myapp";
|
||||
url = "http://127.0.0.1:3000";
|
||||
};
|
||||
|
||||
# Example 2: Authenticated service with custom middlewares
|
||||
authProxy = mkReverseProxy {
|
||||
name = "admin-panel";
|
||||
subdomain = "admin";
|
||||
url = "http://127.0.0.1:8080";
|
||||
middlewares = middlewares.authBasic;
|
||||
};
|
||||
|
||||
# Example 3: Container-based service
|
||||
containerProxy = mkReverseProxy {
|
||||
name = "nextcloud";
|
||||
subdomain = "cloud";
|
||||
url = urls.container "nextcloud" 80;
|
||||
middlewares = middlewares.basic;
|
||||
};
|
||||
|
||||
# Example 4: Multiple proxies at once
|
||||
multipleProxies = mkReverseProxies [
|
||||
{
|
||||
name = "grafana";
|
||||
subdomain = "grafana";
|
||||
url = urls.localhost 3000;
|
||||
middlewares = middlewares.authBasic;
|
||||
}
|
||||
{
|
||||
name = "prometheus";
|
||||
subdomain = "prometheus";
|
||||
url = urls.localhost 9090;
|
||||
middlewares = middlewares.internal;
|
||||
}
|
||||
{
|
||||
name = "alertmanager";
|
||||
subdomain = "alerts";
|
||||
url = urls.localhost 9093;
|
||||
middlewares = middlewares.authBasic;
|
||||
}
|
||||
];
|
||||
|
||||
# Example 5: Using templates for common patterns
|
||||
webappExample = templates.webapp {
|
||||
name = "webapp";
|
||||
subdomain = "app";
|
||||
port = 8080;
|
||||
};
|
||||
|
||||
authWebappExample = templates.authWebapp {
|
||||
name = "secure-app";
|
||||
subdomain = "secure";
|
||||
port = 9000;
|
||||
};
|
||||
|
||||
containerExample = templates.containerService {
|
||||
name = "gitea";
|
||||
subdomain = "git";
|
||||
containerName = "gitea";
|
||||
port = 3000;
|
||||
};
|
||||
|
||||
internalExample = templates.internalService {
|
||||
name = "internal-api";
|
||||
subdomain = "api-internal";
|
||||
port = 8000;
|
||||
};
|
||||
|
||||
# Example 6: Custom domain and advanced configuration
|
||||
customProxy = mkReverseProxy {
|
||||
name = "custom-service";
|
||||
subdomain = "custom";
|
||||
url = "http://10.0.1.100:8080";
|
||||
domain = "example.com";
|
||||
priority = 20;
|
||||
rule = "Host(`custom.example.com`) && PathPrefix(`/api`)";
|
||||
middlewares = [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
"rate-limit"
|
||||
];
|
||||
};
|
||||
|
||||
# Example usage in a Traefik configuration:
|
||||
#
|
||||
# mjallen.services.traefik = {
|
||||
# enable = true;
|
||||
# extraServices = multipleProxies.extraServices;
|
||||
# extraRouters = multipleProxies.extraRouters;
|
||||
# };
|
||||
#
|
||||
# Or for individual proxies:
|
||||
#
|
||||
# mjallen.services.traefik = {
|
||||
# enable = true;
|
||||
# extraServices = [ simpleProxy.service ];
|
||||
# extraRouters = [{
|
||||
# inherit (simpleProxy.router) subdomain entryPoints middlewares;
|
||||
# service = simpleProxy.router.service;
|
||||
# }];
|
||||
# };
|
||||
}
|
||||
45
lib/examples/sops.nix
Normal file
45
lib/examples/sops.nix
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}.module) mkModule mkOpt mkBoolOpt;
|
||||
in
|
||||
mkModule {
|
||||
name = "sops";
|
||||
description = "SOPS secret management";
|
||||
options = {
|
||||
defaultSopsFile = mkOpt lib.types.path null "Default sops file.";
|
||||
|
||||
generateAgeKey = mkBoolOpt true "Whether to automatically generate an age key if one doesn't exist.";
|
||||
|
||||
ageKeyPath =
|
||||
mkOpt (lib.types.nullOr lib.types.str) null
|
||||
"Custom path to the age key file. If null, will use the default path.";
|
||||
|
||||
sshKeyPaths = mkOpt (lib.types.listOf lib.types.str) [
|
||||
"/etc/ssh/ssh_host_ed25519_key"
|
||||
] "SSH Key paths to use.";
|
||||
|
||||
validateSopsFiles = mkBoolOpt false "Whether to validate that sops files exist.";
|
||||
};
|
||||
config = {
|
||||
sops = {
|
||||
inherit (config.${namespace}.sops) defaultSopsFile validateSopsFiles;
|
||||
|
||||
age = {
|
||||
inherit (config.${namespace}.sops) generateAgeKey;
|
||||
|
||||
keyFile =
|
||||
if config.${namespace}.sops.ageKeyPath != null then
|
||||
config.${namespace}.sops.ageKeyPath
|
||||
else
|
||||
"${config.users.users.${config.${namespace}.user.name}.home}/.config/sops/age/keys.txt";
|
||||
|
||||
sshKeyPaths = config.${namespace}.sops.sshKeyPaths;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
132
lib/examples/system-utils.nix
Normal file
132
lib/examples/system-utils.nix
Normal file
@@ -0,0 +1,132 @@
|
||||
{ inputs, namespace, ... }:
|
||||
let
|
||||
inherit (inputs.self.${namespace} - lib.system.common)
|
||||
mkExtendedLib
|
||||
mkNixpkgsConfig
|
||||
mkHomeConfigs
|
||||
mkHomeManagerConfig
|
||||
mkSpecialArgs
|
||||
;
|
||||
in
|
||||
{
|
||||
# Example of creating NixOS configurations
|
||||
nixosConfigurations =
|
||||
let
|
||||
# Get all systems
|
||||
allSystems = inputs.self.${namespace} - lib.file.scanSystems ../systems;
|
||||
|
||||
# Filter for NixOS systems
|
||||
nixosSystems = inputs.self.${namespace} - lib.file.filterNixOSSystems allSystems;
|
||||
in
|
||||
inputs.nixpkgs.lib.mapAttrs' (
|
||||
_name:
|
||||
{ system, hostname, ... }:
|
||||
let
|
||||
# Create extended lib with mjallen-lib
|
||||
extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
|
||||
|
||||
# Find matching home configurations for this system
|
||||
matchingHomes = mkHomeConfigs {
|
||||
flake = inputs.self;
|
||||
inherit system hostname;
|
||||
};
|
||||
|
||||
# Create home-manager configuration
|
||||
homeManagerConfig = mkHomeManagerConfig {
|
||||
inherit
|
||||
extendedLib
|
||||
inputs
|
||||
system
|
||||
matchingHomes
|
||||
;
|
||||
isNixOS = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
name = hostname;
|
||||
value = inputs.nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
|
||||
# Pass special arguments to modules
|
||||
specialArgs = mkSpecialArgs {
|
||||
inherit inputs hostname extendedLib;
|
||||
username = "mjallen";
|
||||
};
|
||||
|
||||
modules = [
|
||||
# Set lib to extended lib
|
||||
{ _module.args.lib = extendedLib; }
|
||||
|
||||
# Configure nixpkgs
|
||||
{
|
||||
nixpkgs = {
|
||||
inherit system;
|
||||
}
|
||||
// mkNixpkgsConfig inputs.self;
|
||||
}
|
||||
|
||||
# Import home-manager module
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
|
||||
# Auto-inject home configurations
|
||||
homeManagerConfig
|
||||
|
||||
# Import all nixos modules recursively
|
||||
../${system}/${hostname}
|
||||
]
|
||||
++ (extendedLib.${namespace}.file.importModulesRecursive ../modules/nixos);
|
||||
};
|
||||
}
|
||||
) nixosSystems;
|
||||
|
||||
# Example of creating home-manager configurations
|
||||
homeConfigurations =
|
||||
let
|
||||
# Get all homes
|
||||
allHomes = inputs.self.${namespace} - lib.file.scanHomes ../homes;
|
||||
in
|
||||
inputs.nixpkgs.lib.mapAttrs' (
|
||||
_name:
|
||||
{
|
||||
system,
|
||||
username,
|
||||
hostname,
|
||||
userAtHost,
|
||||
path,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Create extended lib with mjallen-lib
|
||||
extendedLib = mkExtendedLib inputs.self inputs.nixpkgs;
|
||||
in
|
||||
{
|
||||
name = userAtHost;
|
||||
value = inputs.home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
inherit ((mkNixpkgsConfig inputs.self)) config overlays;
|
||||
};
|
||||
|
||||
extraSpecialArgs = {
|
||||
inherit
|
||||
inputs
|
||||
hostname
|
||||
username
|
||||
system
|
||||
;
|
||||
inherit (inputs) self;
|
||||
lib = extendedLib;
|
||||
};
|
||||
|
||||
modules = [
|
||||
# Set lib to extended lib
|
||||
{ _module.args.lib = extendedLib; }
|
||||
|
||||
# Import the home configuration
|
||||
path
|
||||
]
|
||||
++ (extendedLib.${namespace}.file.importModulesRecursive ../modules/home);
|
||||
};
|
||||
}
|
||||
) allHomes;
|
||||
}
|
||||
127
lib/file/default.nix
Normal file
127
lib/file/default.nix
Normal file
@@ -0,0 +1,127 @@
|
||||
{ inputs, ... }@args:
|
||||
let
|
||||
# Get self from args or default to ../.. (the flake root)
|
||||
self = if args ? self then args.self else ../..;
|
||||
|
||||
inherit (inputs.nixpkgs.lib)
|
||||
genAttrs
|
||||
filterAttrs
|
||||
hasPrefix
|
||||
foldl'
|
||||
;
|
||||
in
|
||||
{
|
||||
# Read a file and return its contents
|
||||
readFile = path: builtins.readFile path;
|
||||
|
||||
# Check if a file exists
|
||||
pathExists = path: builtins.pathExists path;
|
||||
|
||||
# Import a nix file with error handling
|
||||
safeImport = path: default: if builtins.pathExists path then import path else default;
|
||||
|
||||
# Scan a directory and return directory names
|
||||
scanDir = path: builtins.attrNames (builtins.readDir path);
|
||||
|
||||
# Get a file path relative to the flake root (similar to Snowfall's get-file)
|
||||
getFile = relativePath: self + "/${relativePath}";
|
||||
|
||||
# Recursively discover and import all Nix modules in a directory tree
|
||||
importModulesRecursive =
|
||||
path:
|
||||
let
|
||||
# Helper function to recursively walk directories
|
||||
walkDir =
|
||||
currentPath:
|
||||
let
|
||||
currentEntries = builtins.readDir currentPath;
|
||||
entryNames = builtins.attrNames currentEntries;
|
||||
|
||||
# Get all directories that contain default.nix
|
||||
directoriesWithDefault = builtins.filter (
|
||||
name:
|
||||
currentEntries.${name} == "directory" && builtins.pathExists (currentPath + "/${name}/default.nix")
|
||||
) entryNames;
|
||||
|
||||
# Get ALL directories (to recurse into)
|
||||
allDirectories = builtins.filter (name: currentEntries.${name} == "directory") entryNames;
|
||||
|
||||
# Import directories that have default.nix
|
||||
directoryImports = map (name: currentPath + "/${name}") directoriesWithDefault;
|
||||
|
||||
# Recursively walk ALL subdirectories
|
||||
subDirImports = builtins.concatLists (map (dir: walkDir (currentPath + "/${dir}")) allDirectories);
|
||||
|
||||
in
|
||||
directoryImports ++ subDirImports;
|
||||
|
||||
in
|
||||
walkDir path;
|
||||
|
||||
# Recursively scan systems directory structure
|
||||
scanSystems =
|
||||
systemsPath:
|
||||
let
|
||||
systemArchs = builtins.attrNames (builtins.readDir systemsPath);
|
||||
|
||||
generateSystemConfigs =
|
||||
system:
|
||||
let
|
||||
systemPath = systemsPath + "/${system}";
|
||||
hosts = builtins.attrNames (builtins.readDir systemPath);
|
||||
in
|
||||
genAttrs hosts (hostname: {
|
||||
inherit system hostname;
|
||||
path = systemPath + "/${hostname}";
|
||||
});
|
||||
in
|
||||
foldl' (acc: system: acc // generateSystemConfigs system) { } systemArchs;
|
||||
|
||||
# Filter systems for NixOS (Linux)
|
||||
filterNixOSSystems =
|
||||
systems:
|
||||
filterAttrs (
|
||||
_name: { system, ... }: hasPrefix "x86_64-linux" system || hasPrefix "aarch64-linux" system
|
||||
) systems;
|
||||
|
||||
# Filter systems for Darwin (macOS)
|
||||
filterDarwinSystems =
|
||||
systems:
|
||||
filterAttrs (
|
||||
_name: { system, ... }: hasPrefix "aarch64-darwin" system || hasPrefix "x86_64-darwin" system
|
||||
) systems;
|
||||
|
||||
# Scan homes directory structure for home configurations
|
||||
scanHomes =
|
||||
homesPath:
|
||||
let
|
||||
systemArchs = builtins.attrNames (builtins.readDir homesPath);
|
||||
|
||||
generateHomeConfigs =
|
||||
system:
|
||||
let
|
||||
systemPath = homesPath + "/${system}";
|
||||
userAtHosts = builtins.attrNames (builtins.readDir systemPath);
|
||||
|
||||
parseUserAtHost =
|
||||
userAtHost:
|
||||
let
|
||||
# Split "username@hostname" into parts
|
||||
parts = builtins.split "@" userAtHost;
|
||||
username = builtins.head parts;
|
||||
hostname = builtins.elemAt parts 2; # After split: [username, "@", hostname]
|
||||
in
|
||||
{
|
||||
inherit
|
||||
system
|
||||
username
|
||||
hostname
|
||||
userAtHost
|
||||
;
|
||||
path = systemPath + "/${userAtHost}";
|
||||
};
|
||||
in
|
||||
genAttrs userAtHosts parseUserAtHost;
|
||||
in
|
||||
foldl' (acc: system: acc // generateHomeConfigs system) { } systemArchs;
|
||||
}
|
||||
264
lib/module/default.nix
Normal file
264
lib/module/default.nix
Normal file
@@ -0,0 +1,264 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
namespace,
|
||||
}:
|
||||
let
|
||||
inherit (inputs.nixpkgs.lib)
|
||||
mapAttrs
|
||||
mkOption
|
||||
types
|
||||
toUpper
|
||||
substring
|
||||
stringLength
|
||||
mkDefault
|
||||
mkForce
|
||||
;
|
||||
|
||||
base64Lib = import ../base64 { inherit inputs; };
|
||||
in
|
||||
rec {
|
||||
|
||||
# Conditionally enable modules based on system
|
||||
enableForSystem =
|
||||
system: modules:
|
||||
builtins.filter (
|
||||
mod: mod.systems or [ ] == [ ] || builtins.elem system (mod.systems or [ ])
|
||||
) modules;
|
||||
|
||||
# Create a module with common options
|
||||
mkModule =
|
||||
{
|
||||
name,
|
||||
description ? "",
|
||||
options ? { },
|
||||
moduleConfig ? { },
|
||||
domain ? "services",
|
||||
config,
|
||||
serviceName ? name,
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.${domain}.${name};
|
||||
|
||||
# Create reverse proxy configuration using mkReverseProxy
|
||||
reverseProxyConfig = lib.${namespace}.mkReverseProxy {
|
||||
inherit name;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
url = "http://${config.${namespace}.network.ipv4.address}:${toString cfg.port}";
|
||||
middlewares = cfg.reverseProxy.middlewares;
|
||||
};
|
||||
|
||||
defaultConfig = {
|
||||
${namespace}.services.traefik = lib.mkIf cfg.reverseProxy.enable {
|
||||
reverseProxies = [ reverseProxyConfig ];
|
||||
};
|
||||
|
||||
# Open firewall
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
allowedUDPPorts = [ cfg.port ];
|
||||
};
|
||||
|
||||
users = lib.mkIf cfg.createUser {
|
||||
users.${name} = {
|
||||
isSystemUser = true;
|
||||
group = name;
|
||||
home = cfg.configDir;
|
||||
};
|
||||
groups.${name} = { };
|
||||
};
|
||||
|
||||
systemd.services.${serviceName} = {
|
||||
requires = [
|
||||
"media-nas-main.mount"
|
||||
# "openvpn-us.protonvpn.udp.service"
|
||||
];
|
||||
after = lib.mkForce [
|
||||
"media-nas-main.mount"
|
||||
# "openvpn-us.protonvpn.udp.service"
|
||||
];
|
||||
# serviceConfig = {
|
||||
# NetworkNamespacePath = lib.mkIf cfg.enableVpn "/run/netns/vpn";
|
||||
# # Consider also setting DNS *inside* the netns (see note below).
|
||||
# };
|
||||
};
|
||||
|
||||
services = {
|
||||
postgresql = lib.mkIf cfg.configureDb {
|
||||
enable = true;
|
||||
ensureDatabases = [ name ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = name;
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
redis.servers.${name} = lib.mkIf cfg.redis.enable {
|
||||
enable = true;
|
||||
port = cfg.redis.port;
|
||||
};
|
||||
};
|
||||
|
||||
# systemd.tmpfiles.rules = [
|
||||
# "d ${cfg.configDir} 0700 ${name} ${name} - -"
|
||||
# # "d ${cfg.configDir}/server-files 0775 ${name} ${name} - -"
|
||||
# # "d ${cfg.configDir}/user-files 0775 ${name} ${name} - -"
|
||||
# ];
|
||||
}
|
||||
// moduleConfig;
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.${namespace}.${domain}.${name} = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
enable = lib.mkEnableOption description;
|
||||
|
||||
port = mkOpt types.int 80 "Port for ${name} to be hosted on";
|
||||
|
||||
configDir = mkOpt types.str "/media/nas/main/appdata" "Path to the config dir";
|
||||
|
||||
dataDir = mkOpt types.str "/media/nas/main" "Path to the data dir";
|
||||
|
||||
createUser = mkBoolOpt false "create a user for this module/service";
|
||||
|
||||
configureDb = mkBoolOpt false "Manage db for this service";
|
||||
|
||||
environmentFile = mkOpt types.str "" "Environment File";
|
||||
|
||||
puid = mkOpt types.str "911" "default user id";
|
||||
|
||||
pgid = mkOpt types.str "1000" "default group id";
|
||||
|
||||
timeZone = mkOpt types.str "America/Chicago" "default timezone";
|
||||
|
||||
listenAddress = mkOpt types.str "0.0.0.0" "Environment File";
|
||||
|
||||
openFirewall = mkBoolOpt true "Open the firewall";
|
||||
|
||||
enableVpn = mkBoolOpt true "Enable routing through VPN";
|
||||
|
||||
redis = {
|
||||
enable = lib.mkEnableOption "enable redis";
|
||||
|
||||
port = mkOpt types.int 80 "Port for ${name} redis to be hosted on";
|
||||
};
|
||||
|
||||
hashedPassword =
|
||||
mkOpt (types.nullOr types.str)
|
||||
"$y$j9T$EkPXmsmIMFFZ.WRrBYCxS1$P0kwo6e4.WM5DsqUcEqWC3MrZp5KfCjxffraMFZWu06"
|
||||
"Hashed password for code-server authentication";
|
||||
|
||||
extraEnvironment =
|
||||
mkOpt (types.attrsOf types.str) { }
|
||||
"Extra environment variables for code-server";
|
||||
|
||||
reverseProxy = mkReverseProxyOpt name;
|
||||
}
|
||||
// options;
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable defaultConfig;
|
||||
};
|
||||
|
||||
# container
|
||||
mkContainer =
|
||||
{
|
||||
name,
|
||||
localAddress ? "127.0.0.1",
|
||||
ports ? [ 80 ],
|
||||
bindMounts ? { },
|
||||
config ? { },
|
||||
}:
|
||||
{ lib, ... }:
|
||||
{
|
||||
containers.${name} = {
|
||||
inherit localAddress bindMounts;
|
||||
|
||||
config = config // {
|
||||
networking = {
|
||||
firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = ports;
|
||||
};
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
useHostResolvConf = lib.mkForce false;
|
||||
};
|
||||
|
||||
services.resolved.enable = true;
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
autoStart = lib.mkDefault true;
|
||||
privateNetwork = lib.mkDefault true;
|
||||
hostAddress = lib.mkDefault "10.0.1.3";
|
||||
};
|
||||
|
||||
networking = {
|
||||
nat.forwardPorts = map (port: {
|
||||
destination = lib.mkDefault "${localAddress}:${toString port}";
|
||||
sourcePort = lib.mkDefault port;
|
||||
}) ports;
|
||||
firewall = {
|
||||
allowedTCPPorts = ports;
|
||||
allowedUDPPorts = ports;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Migrated mjallen utilities
|
||||
# Option creation helpers
|
||||
mkOpt =
|
||||
type: default: description:
|
||||
mkOption { inherit type default description; };
|
||||
|
||||
mkOpt' = type: default: mkOpt type default null;
|
||||
|
||||
mkBoolOpt = mkOpt types.bool;
|
||||
|
||||
mkBoolOpt' = mkOpt' types.bool;
|
||||
|
||||
mkReverseProxyOpt = name: {
|
||||
enable = mkBoolOpt false "Enable reverse proxy support";
|
||||
|
||||
subdomain = mkOpt types.str name "subdomain of the service";
|
||||
|
||||
middlewares = mkOpt (types.listOf types.str) [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
] "List of middlewares to use";
|
||||
};
|
||||
|
||||
# Standard enable/disable patterns
|
||||
enabled = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
disabled = {
|
||||
enable = false;
|
||||
};
|
||||
|
||||
# String utilities
|
||||
capitalize =
|
||||
s:
|
||||
let
|
||||
len = stringLength s;
|
||||
in
|
||||
if len == 0 then "" else (toUpper (substring 0 1 s)) + (substring 1 len s);
|
||||
|
||||
# Boolean utilities
|
||||
boolToNum = bool: if bool then 1 else 0;
|
||||
|
||||
# Attribute manipulation utilities
|
||||
default-attrs = mapAttrs (_key: mkDefault);
|
||||
|
||||
force-attrs = mapAttrs (_key: mkForce);
|
||||
|
||||
nested-default-attrs = mapAttrs (_key: default-attrs);
|
||||
|
||||
nested-force-attrs = mapAttrs (_key: force-attrs);
|
||||
}
|
||||
// base64Lib
|
||||
220
lib/reverseproxy/default.nix
Normal file
220
lib/reverseproxy/default.nix
Normal file
@@ -0,0 +1,220 @@
|
||||
{ inputs }:
|
||||
let
|
||||
inherit (inputs.nixpkgs.lib)
|
||||
listToAttrs
|
||||
nameValuePair
|
||||
;
|
||||
in
|
||||
rec {
|
||||
# Create a service configuration for Traefik
|
||||
mkService =
|
||||
{
|
||||
name,
|
||||
url,
|
||||
loadBalancer ? { },
|
||||
}:
|
||||
{
|
||||
inherit name url;
|
||||
config = {
|
||||
loadBalancer = {
|
||||
servers = [ { inherit url; } ];
|
||||
}
|
||||
// loadBalancer;
|
||||
};
|
||||
};
|
||||
|
||||
# Create a router configuration for Traefik
|
||||
mkRouter =
|
||||
{
|
||||
subdomain,
|
||||
domain ? "mjallen.dev",
|
||||
service,
|
||||
entryPoints ? [ "websecure" ],
|
||||
middlewares ? [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
],
|
||||
priority ? null,
|
||||
rule ? null,
|
||||
tls ? {
|
||||
certResolver = "letsencrypt";
|
||||
},
|
||||
}:
|
||||
{
|
||||
inherit
|
||||
subdomain
|
||||
service
|
||||
entryPoints
|
||||
middlewares
|
||||
;
|
||||
config = {
|
||||
inherit
|
||||
entryPoints
|
||||
service
|
||||
middlewares
|
||||
tls
|
||||
;
|
||||
rule = if rule != null then rule else "Host(`${subdomain}.${domain}`)";
|
||||
}
|
||||
// (if priority != null then { inherit priority; } else { });
|
||||
};
|
||||
|
||||
# Create both service and router for a simple reverse proxy setup
|
||||
mkReverseProxy =
|
||||
{
|
||||
name,
|
||||
subdomain,
|
||||
url,
|
||||
domain ? "mjallen.dev",
|
||||
entryPoints ? [ "websecure" ],
|
||||
middlewares ? [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
],
|
||||
priority ? null,
|
||||
rule ? null,
|
||||
tls ? {
|
||||
certResolver = "letsencrypt";
|
||||
},
|
||||
loadBalancer ? { },
|
||||
}:
|
||||
{
|
||||
service = mkService {
|
||||
inherit name url loadBalancer;
|
||||
};
|
||||
router = mkRouter {
|
||||
inherit
|
||||
subdomain
|
||||
domain
|
||||
entryPoints
|
||||
middlewares
|
||||
priority
|
||||
rule
|
||||
tls
|
||||
;
|
||||
service = name;
|
||||
};
|
||||
};
|
||||
|
||||
# Convert a list of services to the format expected by Traefik module
|
||||
servicesToConfig =
|
||||
services: listToAttrs (map (service: nameValuePair service.name service.config) services);
|
||||
|
||||
# Convert a list of routers to the format expected by Traefik module
|
||||
routersToConfig =
|
||||
routers: listToAttrs (map (router: nameValuePair router.subdomain router.config) routers);
|
||||
|
||||
# Helper to create multiple reverse proxies at once
|
||||
mkReverseProxies =
|
||||
proxies:
|
||||
let
|
||||
results = map mkReverseProxy proxies;
|
||||
services = map (result: result.service) results;
|
||||
routers = map (result: result.router) results;
|
||||
in
|
||||
{
|
||||
services = servicesToConfig services;
|
||||
routers = routersToConfig routers;
|
||||
extraServices = services;
|
||||
extraRouters = map (router: {
|
||||
inherit (router) subdomain entryPoints middlewares;
|
||||
service = router.service;
|
||||
}) routers;
|
||||
};
|
||||
|
||||
# Common middleware configurations
|
||||
middlewares = {
|
||||
# Authentication middleware
|
||||
auth = [ "authentik" ];
|
||||
|
||||
# Basic security (default)
|
||||
basic = [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
];
|
||||
|
||||
# Internal only access
|
||||
internal = [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
"internal-ipallowlist"
|
||||
];
|
||||
|
||||
# WebSocket support
|
||||
websocket = [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
"onlyoffice-websocket"
|
||||
];
|
||||
|
||||
# Authenticated with basic security
|
||||
authBasic = [
|
||||
"crowdsec"
|
||||
"whitelist-geoblock"
|
||||
"authentik"
|
||||
];
|
||||
};
|
||||
|
||||
# Common service URL builders
|
||||
urls = {
|
||||
# Local container service
|
||||
container =
|
||||
containerName: port: "http://\${config.containers.${containerName}.localAddress}:${toString port}";
|
||||
|
||||
# Local host service
|
||||
localhost = port: "http://127.0.0.1:${toString port}";
|
||||
|
||||
# Network service
|
||||
network = ip: port: "http://${ip}:${toString port}";
|
||||
|
||||
# Server IP service (using your server IP pattern)
|
||||
server = port: "http://\${serverIp}:${toString port}";
|
||||
};
|
||||
|
||||
# Pre-configured reverse proxy templates
|
||||
templates = {
|
||||
# Standard web application
|
||||
webapp =
|
||||
{ port, ... }@args:
|
||||
mkReverseProxy (
|
||||
{
|
||||
url = urls.localhost port;
|
||||
middlewares = middlewares.basic;
|
||||
}
|
||||
// args
|
||||
);
|
||||
|
||||
# Authenticated web application
|
||||
authWebapp =
|
||||
{ port, ... }@args:
|
||||
mkReverseProxy (
|
||||
{
|
||||
url = urls.localhost port;
|
||||
middlewares = middlewares.authBasic;
|
||||
}
|
||||
// args
|
||||
);
|
||||
|
||||
# Container-based service
|
||||
containerService =
|
||||
{ containerName, port, ... }@args:
|
||||
mkReverseProxy (
|
||||
{
|
||||
url = urls.container containerName port;
|
||||
middlewares = middlewares.basic;
|
||||
}
|
||||
// args
|
||||
);
|
||||
|
||||
# Internal-only service
|
||||
internalService =
|
||||
{ port, ... }@args:
|
||||
mkReverseProxy (
|
||||
{
|
||||
url = urls.localhost port;
|
||||
middlewares = middlewares.internal;
|
||||
}
|
||||
// args
|
||||
);
|
||||
};
|
||||
}
|
||||
103
lib/system/common.nix
Normal file
103
lib/system/common.nix
Normal file
@@ -0,0 +1,103 @@
|
||||
{ inputs, namespace }:
|
||||
let
|
||||
inherit (inputs.nixpkgs.lib) filterAttrs mapAttrs';
|
||||
in
|
||||
{
|
||||
mkExtendedLib =
|
||||
flake: nixpkgs:
|
||||
nixpkgs.lib.extend (
|
||||
_final: _prev: {
|
||||
mjallen = flake.${namespace} - lib;
|
||||
}
|
||||
);
|
||||
|
||||
mkNixpkgsConfig = flake: {
|
||||
overlays = builtins.attrValues flake.overlays;
|
||||
config = {
|
||||
allowAliases = false;
|
||||
allowUnfree = true;
|
||||
permittedInsecurePackages = [
|
||||
# Add any permitted insecure packages here
|
||||
"mbedtls-2.28.10"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
mkHomeConfigs =
|
||||
{
|
||||
flake,
|
||||
system,
|
||||
hostname,
|
||||
}:
|
||||
let
|
||||
inherit (flake.${namespace} - lib.file) scanHomes;
|
||||
homesPath = ../../homes;
|
||||
allHomes = scanHomes homesPath;
|
||||
in
|
||||
filterAttrs (
|
||||
_name: homeConfig: homeConfig.system == system && homeConfig.hostname == hostname
|
||||
) allHomes;
|
||||
|
||||
mkHomeManagerConfig =
|
||||
{
|
||||
extendedLib,
|
||||
inputs,
|
||||
system,
|
||||
matchingHomes,
|
||||
isNixOS ? true,
|
||||
}:
|
||||
if matchingHomes != { } then
|
||||
{
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
extraSpecialArgs = {
|
||||
inherit inputs system;
|
||||
inherit (inputs) self;
|
||||
lib = extendedLib;
|
||||
};
|
||||
sharedModules = [
|
||||
{ _module.args.lib = extendedLib; }
|
||||
]
|
||||
++ (extendedLib.${namespace}.file.importModulesRecursive ../../modules/home);
|
||||
users = mapAttrs' (_name: homeConfig: {
|
||||
name = homeConfig.username;
|
||||
value = {
|
||||
imports = [ homeConfig.path ];
|
||||
home = {
|
||||
inherit (homeConfig) username;
|
||||
homeDirectory = inputs.nixpkgs.lib.mkDefault (
|
||||
if isNixOS then "/home/${homeConfig.username}" else "/Users/${homeConfig.username}"
|
||||
);
|
||||
};
|
||||
}
|
||||
// (
|
||||
if isNixOS then
|
||||
{
|
||||
_module.args.username = homeConfig.username;
|
||||
}
|
||||
else
|
||||
{ }
|
||||
);
|
||||
}) matchingHomes;
|
||||
};
|
||||
}
|
||||
else
|
||||
{ };
|
||||
|
||||
mkSpecialArgs =
|
||||
{
|
||||
inputs,
|
||||
hostname,
|
||||
username,
|
||||
extendedLib,
|
||||
}:
|
||||
{
|
||||
inherit inputs hostname username;
|
||||
inherit (inputs) self;
|
||||
lib = extendedLib;
|
||||
namespace = "mjallen";
|
||||
format = "system";
|
||||
host = hostname;
|
||||
};
|
||||
}
|
||||
5
lib/system/default.nix
Normal file
5
lib/system/default.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
{ inputs }:
|
||||
{
|
||||
# Common utilities used by system builders
|
||||
common = import ./common.nix { inherit inputs; };
|
||||
}
|
||||
212
lib/versioning/default.nix
Normal file
212
lib/versioning/default.nix
Normal file
@@ -0,0 +1,212 @@
|
||||
{
|
||||
lib,
|
||||
inputs,
|
||||
system ? "aarch64-linux",
|
||||
}:
|
||||
let
|
||||
pkgs = inputs.nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
let
|
||||
inherit (builtins)
|
||||
isAttrs
|
||||
isList
|
||||
isString
|
||||
hasAttr
|
||||
getAttr
|
||||
attrNames
|
||||
toString
|
||||
replaceStrings
|
||||
;
|
||||
|
||||
mapAttrs = lib.mapAttrs;
|
||||
recursiveUpdate = lib.recursiveUpdate;
|
||||
|
||||
# Deep-merge attrsets (right-biased).
|
||||
deepMerge = a: b: recursiveUpdate a b;
|
||||
|
||||
# Merge component sources: base.sources overlaid by overrides (component-wise deep merge).
|
||||
mergeSources =
|
||||
baseSources: overrides:
|
||||
baseSources
|
||||
// mapAttrs (
|
||||
name: ov: if hasAttr name baseSources then deepMerge (getAttr name baseSources) ov else ov
|
||||
) overrides;
|
||||
|
||||
# Apply a single variant overlay (variables + sources).
|
||||
applyVariantOnce =
|
||||
selected: variant:
|
||||
let
|
||||
vVars = if variant ? variables then variant.variables else { };
|
||||
vSrcs = if variant ? sources then variant.sources else { };
|
||||
in
|
||||
{
|
||||
variables = selected.variables // vVars;
|
||||
sources = mergeSources selected.sources vSrcs;
|
||||
};
|
||||
|
||||
# Apply platform-specific overrides if present for the given system.
|
||||
applyPlatforms =
|
||||
selected: variant: system:
|
||||
if system == null || !(variant ? platforms) || !(hasAttr system variant.platforms) then
|
||||
selected
|
||||
else
|
||||
let
|
||||
p = variant.platforms.${system};
|
||||
pVars = if p ? variables then p.variables else { };
|
||||
pSrcs = if p ? sources then p.sources else { };
|
||||
in
|
||||
{
|
||||
variables = selected.variables // pVars;
|
||||
sources = mergeSources selected.sources pSrcs;
|
||||
};
|
||||
|
||||
# Resolve variant chain via inherits (ancestor first), then apply platforms.
|
||||
resolveVariant =
|
||||
spec: baseSelected: variantName: system:
|
||||
if variantName == null || !(spec ? variants) || !(hasAttr variantName spec.variants) then
|
||||
baseSelected
|
||||
else
|
||||
let
|
||||
v = spec.variants.${variantName};
|
||||
parentSelected =
|
||||
if v ? inherits then resolveVariant spec baseSelected v.inherits system else baseSelected;
|
||||
withVariant = applyVariantOnce parentSelected v;
|
||||
in
|
||||
applyPlatforms withVariant v system;
|
||||
|
||||
# Render ${var} substitutions in any string within attrs/lists.
|
||||
renderValue =
|
||||
value: vars:
|
||||
if isString value then
|
||||
let
|
||||
keys = attrNames vars;
|
||||
patterns = map (k: "\${" + k + "}") keys;
|
||||
replacements = map (k: toString (getAttr k vars)) keys;
|
||||
in
|
||||
replaceStrings patterns replacements value
|
||||
else if isAttrs value then
|
||||
mapAttrs (_: v: renderValue v vars) value
|
||||
else if isList value then
|
||||
map (v: renderValue v vars) value
|
||||
else
|
||||
value;
|
||||
|
||||
# Decide fetcher for URL type based on optional extra.unpack hint.
|
||||
useFetchZip = comp: comp ? extra && comp.extra ? unpack && comp.extra.unpack == "zip";
|
||||
|
||||
# Build a single src from a rendered component spec.
|
||||
mkSrcFromRendered =
|
||||
comp:
|
||||
let
|
||||
fetcher = if comp ? fetcher then comp.fetcher else "none";
|
||||
in
|
||||
if fetcher == "github" then
|
||||
pkgs.fetchFromGitHub (
|
||||
{
|
||||
owner = comp.owner;
|
||||
repo = comp.repo;
|
||||
# Allow tag as rev (ignore null/empty tag)
|
||||
rev = if comp ? tag && comp.tag != null && comp.tag != "" then comp.tag else comp.rev;
|
||||
fetchSubmodules = if comp ? submodules then comp.submodules else false;
|
||||
hash = comp.hash;
|
||||
}
|
||||
// lib.optionalAttrs (comp ? name) { name = comp.name; }
|
||||
)
|
||||
else if fetcher == "git" then
|
||||
pkgs.fetchgit {
|
||||
url = comp.url;
|
||||
rev = comp.rev;
|
||||
fetchSubmodules = if comp ? submodules then comp.submodules else false;
|
||||
hash = comp.hash;
|
||||
}
|
||||
else if fetcher == "url" then
|
||||
let
|
||||
url = if comp ? url then comp.url else comp.urlTemplate;
|
||||
in
|
||||
if useFetchZip comp then
|
||||
pkgs.fetchzip (
|
||||
{
|
||||
inherit url;
|
||||
hash = comp.hash;
|
||||
}
|
||||
// lib.optionalAttrs (comp ? extra && comp.extra ? stripRoot) { stripRoot = comp.extra.stripRoot; }
|
||||
)
|
||||
else
|
||||
pkgs.fetchurl {
|
||||
inherit url;
|
||||
hash = comp.hash;
|
||||
}
|
||||
else if fetcher == "pypi" then
|
||||
pkgs.python3Packages.fetchPypi {
|
||||
pname = comp.name;
|
||||
version = comp.version;
|
||||
hash = comp.hash;
|
||||
}
|
||||
else
|
||||
# fetcher == "none": pass-through (e.g., linux version/hash consumed by custom logic)
|
||||
comp;
|
||||
|
||||
in
|
||||
rec {
|
||||
/*
|
||||
Select a variant from a loaded version.json specification.
|
||||
|
||||
Usage:
|
||||
let selected = versioning.selectVariant spec variantName system;
|
||||
- spec: attrset from lib.importJSON ./version.json
|
||||
- variantName: string or null (when null, uses spec.defaultVariant if present)
|
||||
- system: string like "x86_64-linux" or null (to apply platforms overrides)
|
||||
*/
|
||||
selectVariant =
|
||||
spec: variantName: system:
|
||||
let
|
||||
chosen =
|
||||
if variantName != null then
|
||||
variantName
|
||||
else
|
||||
(if spec ? defaultVariant then spec.defaultVariant else null);
|
||||
baseSelected = {
|
||||
variables = if spec ? variables then spec.variables else { };
|
||||
sources = if spec ? sources then spec.sources else { };
|
||||
};
|
||||
in
|
||||
resolveVariant spec baseSelected chosen system;
|
||||
|
||||
/*
|
||||
Render ${var} template substitutions across any value using provided variables.
|
||||
Strings, attrsets, and lists are traversed.
|
||||
*/
|
||||
render = value: variables: renderValue value variables;
|
||||
|
||||
/*
|
||||
Render a component with variables and then build its src (or pass-through for fetcher "none").
|
||||
Prefer using mkAllSources, which handles rendering for all components.
|
||||
*/
|
||||
mkSrc =
|
||||
comp: variables:
|
||||
let
|
||||
rendered = renderValue comp variables;
|
||||
in
|
||||
mkSrcFromRendered rendered;
|
||||
|
||||
/*
|
||||
Produce an attrset of all sources for a selected spec:
|
||||
mkAllSources selected
|
||||
Where:
|
||||
selected = selectVariant spec variantName system
|
||||
Returns:
|
||||
{ componentName = src | renderedComp (for "none"); ... }
|
||||
*/
|
||||
mkAllSources =
|
||||
selected:
|
||||
mapAttrs (
|
||||
_name: comp:
|
||||
if comp ? fetcher && comp.fetcher == "none" then
|
||||
renderValue comp selected.variables
|
||||
else
|
||||
mkSrc (renderValue comp selected.variables) selected.variables
|
||||
) selected.sources;
|
||||
|
||||
# Expose deepMerge for convenience (right-biased).
|
||||
inherit deepMerge;
|
||||
}
|
||||
57
modules/darwin/home/default.nix
Normal file
57
modules/darwin/home/default.nix
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
lib,
|
||||
options,
|
||||
namespace,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.${namespace}.home = with lib.types; {
|
||||
configFile = lib.mkOption {
|
||||
type = attrs;
|
||||
default = { };
|
||||
description = "A set of files to be managed by home-manager's <option>xdg.configFile</option>.";
|
||||
};
|
||||
extraOptions = lib.mkOption {
|
||||
type = attrs;
|
||||
default = { };
|
||||
description = "Options to pass directly to home-manager.";
|
||||
};
|
||||
file = lib.mkOption {
|
||||
type = attrs;
|
||||
default = { };
|
||||
description = "A set of files to be managed by home-manager's <option>home.file</option>.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
home-manager = {
|
||||
# enables backing up existing files instead of erroring if conflicts exist
|
||||
backupFileExtension = "backup";
|
||||
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
|
||||
# Pass inputs so external modules can access them
|
||||
extraSpecialArgs = {
|
||||
inherit inputs namespace;
|
||||
# overlays = with inputs; [
|
||||
# nix-vscode-extensions.overlays.default
|
||||
# ];
|
||||
};
|
||||
|
||||
# Make ALL external HM modules available globally
|
||||
sharedModules = with inputs; [
|
||||
sops-nix.homeManagerModules.sops
|
||||
nix-plist-manager.homeManagerModules.default
|
||||
nix-index-database.homeModules.nix-index
|
||||
stylix.homeModules.stylix
|
||||
# Add any other external HM modules here
|
||||
];
|
||||
|
||||
users."mattjallen" = lib.mkAliasDefinitions options.${namespace}.home.extraOptions;
|
||||
|
||||
verbose = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
13
modules/darwin/programs/ssh/default.nix
Normal file
13
modules/darwin/programs/ssh/default.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ ... }:
|
||||
{
|
||||
config = {
|
||||
programs.ssh.knownHosts = {
|
||||
desktop = {
|
||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTBMydhOc6SnOdB5WrEd7X07DrboAtagCUgXiOJjLov matt@matt-nixos";
|
||||
};
|
||||
nas = {
|
||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIwoHWOLSTGVif9hAhaMLl0qDA4roIzCNuyR6kyIXDOj admin@jallen-nas";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.mjallen.desktop.gnome;
|
||||
cfg = config.${namespace}.desktop.gnome;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
@@ -17,7 +23,9 @@ in
|
||||
gnomeExtensions.bing-wallpaper-changer
|
||||
gnomeExtensions.dash-to-dock
|
||||
gnomeExtensions.dash-to-panel
|
||||
gnomeExtensions.caffeine
|
||||
gnomeExtensions.gsconnect
|
||||
gnomeExtensions.nasa-apod
|
||||
gnomeExtensions.random-wallpaper
|
||||
gnomeExtensions.tiling-assistant
|
||||
gnomeExtensions.user-themes
|
||||
@@ -48,22 +56,27 @@ in
|
||||
"org/gnome/shell".enabled-extensions = [
|
||||
"allowlockedremotedesktop@kamens.us"
|
||||
"appindicatorsupport@rgcjonas.gmail.com"
|
||||
"user-theme@gnome-shell-extensions.gcampax.github.com"
|
||||
"caffeine@patapon.info"
|
||||
# "user-theme@gnome-shell-extensions.gcampax.github.com"
|
||||
"tiling-assistant@leleat-on-github"
|
||||
"dash-to-dock@micxgx.gmail.com"
|
||||
"BingWallpaper@ineffable-gmail.com"
|
||||
"gsconnect@andyholmes.github.io"
|
||||
];
|
||||
"org/gnome/shell/extensions/bingwallpaper".override-lockscreen-blur = true;
|
||||
"org/gnome/shell/extensions/bingwallpaper".random-mode-enabled = true;
|
||||
"org/gnome/shell/extensions/bingwallpaper".random-mode-enabled = false;
|
||||
"org/gnome/shell/extensions/bingwallpaper".selected-image = "current";
|
||||
"org/gnome/shell/extensions/bingwallpaper".revert-to-current-image = false;
|
||||
"org/gnome/shell/extensions/caffeine".enable-fullscreen = true;
|
||||
"org/gnome/shell/extensions/caffeine".enable-mpris = true;
|
||||
"org/gnome/shell/extensions/dash-to-panel".primary-monitor = 1;
|
||||
"org/gnome/shell/extensions/dash-to-panel".multi-monitors = false;
|
||||
"org/gnome/shell/extensions/gsconnect".id = "4db35bd2-0dcd-42a3-9f77-ef3e8bb83182";
|
||||
"org/gnome/shell/extensions/gsconnect".name = "matt-nixos";
|
||||
"org/gnome/shell/extensions/user-theme".name = lib.mkDefault "Colloid-Dark";
|
||||
"org/gnome/system/location".enabled = true;
|
||||
"org/gtk/settings/file-chooser".clock-format = "12h";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.desktop.gnome = {
|
||||
options.${namespace}.desktop.gnome = {
|
||||
enable = mkEnableOption "enable gnome settings";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,403 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.desktop.hyprland;
|
||||
drawer = "nwg-drawer -fm nautilus -term kitty -mb 10 -mt 10 -ml 10 -mr 10 -pbuseicontheme -i ${cfg.iconThemeName}";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./options.nix
|
||||
./packages.nix
|
||||
./theme.nix
|
||||
./variables.nix
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
services = {
|
||||
hyprpolkitagent.enable = true;
|
||||
};
|
||||
|
||||
programs = {
|
||||
vscode.profiles.default.userSettings."window"."titleBarStyle" = "custom";
|
||||
};
|
||||
|
||||
wayland.windowManager.hyprland = {
|
||||
enable = true;
|
||||
xwayland.enable = true;
|
||||
systemd.enable = true;
|
||||
|
||||
plugins = with pkgs.hyprlandPlugins; [
|
||||
hyprgrass
|
||||
];
|
||||
|
||||
settings = {
|
||||
"$mod" = "SUPER";
|
||||
|
||||
# Mouse
|
||||
# mouse_[up|down] - scroll wheel
|
||||
# middle_mouse - 274
|
||||
# thumb_up - 276
|
||||
# thumb_down - 275
|
||||
|
||||
# l -> locked, will also work when an input inhibitor (e.g. a lockscreen) is active.
|
||||
# r -> release, will trigger on release of a key.
|
||||
# e -> repeat, will repeat when held.
|
||||
# n -> non-consuming, key/mouse events will be passed to the active window in addition to triggering the dispatcher.
|
||||
# m -> mouse, see below.
|
||||
# t -> transparent, cannot be shadowed by other binds.
|
||||
# i -> ignore mods, will ignore modifiers.
|
||||
# s -> separate, will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos) above.
|
||||
# d -> has description, will allow you to write a description for your bind.
|
||||
# p -> bypasses the app's requests to inhibit keybinds.
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Binds/
|
||||
# https://wiki.hyprland.org/Configuring/Binds/#mouse-buttons
|
||||
|
||||
bind = [
|
||||
"$mod, Return, exec, ${cfg.defaultApps.terminal.pname}"
|
||||
"$mod, SPACE, exec, wofi --show drun"
|
||||
", xf86Search, exec, wofi --show drun"
|
||||
"$mod, Q, killactive, "
|
||||
"$mod, M, exec, wlogout --protocol layer-shell"
|
||||
"$mod, E, exec, ${cfg.defaultApps.fileExplorer.pname}"
|
||||
"$mod, V, togglefloating, "
|
||||
"$mod, D, exec, ${drawer}"
|
||||
"$mod, P, pseudo, " # dwindle
|
||||
"$mod, S, togglesplit, " # dwindle
|
||||
"$mod SHIFT, Q, exec, hyprlock"
|
||||
"$mod SHIFT, 4, exec, hyprshot -m region --clipboard-only"
|
||||
"$mod, F, fullscreen, 1"
|
||||
"$mod SHIFT, F, fullscreen, 0"
|
||||
"$mod SHIFT, E, exec, smile"
|
||||
|
||||
"$mod, mouse:276, movecurrentworkspacetomonitor, ${cfg.display1.input}"
|
||||
"$mod, mouse:275, movecurrentworkspacetomonitor, ${cfg.display2.input}"
|
||||
|
||||
# alt-tab between workspaces on active monitor
|
||||
"$mod, Tab, workspace, m+1"
|
||||
"$mod SHIFT, Tab, workspace, m-1"
|
||||
|
||||
"$mod, h, movefocus, l"
|
||||
"$mod, l, movefocus, r"
|
||||
"$mod, k, movefocus, u"
|
||||
"$mod, j, movefocus, d"
|
||||
|
||||
"$mod, 1, workspace, 1"
|
||||
"$mod, 2, workspace, 2"
|
||||
"$mod, 3, workspace, 3"
|
||||
"$mod, 4, workspace, 4"
|
||||
"$mod, 5, workspace, 5"
|
||||
"$mod, 6, workspace, 6"
|
||||
"$mod, 7, workspace, 7"
|
||||
"$mod, 8, workspace, 8"
|
||||
"$mod, 9, workspace, 9"
|
||||
"$mod, 0, workspace, 10"
|
||||
|
||||
"$mod ALT, 1, movetoworkspace, 1"
|
||||
"$mod ALT, 2, movetoworkspace, 2"
|
||||
"$mod ALT, 3, movetoworkspace, 3"
|
||||
"$mod ALT, 4, movetoworkspace, 4"
|
||||
"$mod ALT, 5, movetoworkspace, 5"
|
||||
"$mod ALT, 6, movetoworkspace, 6"
|
||||
"$mod ALT, 7, movetoworkspace, 7"
|
||||
"$mod ALT, 8, movetoworkspace, 8"
|
||||
"$mod ALT, 9, movetoworkspace, 9"
|
||||
"$mod ALT, 0, movetoworkspace, discord"
|
||||
|
||||
"$mod CTRL, l, resizeactive, 10 0"
|
||||
"$mod CTRL, h, resizeactive, -10 0"
|
||||
"$mod CTRL, k, resizeactive, 0 -10"
|
||||
"$mod CTRL, j, resizeactive, 0 10"
|
||||
|
||||
"$mod SHIFT, l, movewindow, r"
|
||||
"$mod SHIFT, h, movewindow, l"
|
||||
"$mod SHIFT, k, movewindow, u"
|
||||
"$mod SHIFT, j, movewindow, d"
|
||||
|
||||
"$mod, b, exec, ${cfg.defaultApps.browser.pname}"
|
||||
];
|
||||
|
||||
bindm = [
|
||||
# Move/resize windows with mod + LMB/RMB and dragging
|
||||
"$mod, mouse:272, movewindow"
|
||||
"$mod, mouse:273, resizewindow"
|
||||
# middle mouse will grab a window, mod + middle mouse will close it
|
||||
"$mod SHIFT, mouse:274, movewindow"
|
||||
];
|
||||
|
||||
bindel = [
|
||||
", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
|
||||
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
|
||||
];
|
||||
|
||||
bindl = [
|
||||
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
|
||||
", XF86AudioPlay, exec, playerctl play-pause"
|
||||
", XF86AudioPrev, exec, playerctl previous"
|
||||
", XF86AudioNext, exec, playerctl next"
|
||||
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
|
||||
|
||||
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
|
||||
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
|
||||
|
||||
"$mod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight set +10%"
|
||||
"$mod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight set 10%-"
|
||||
];
|
||||
|
||||
monitor = cfg.monitor;
|
||||
monitorv2 = cfg.monitorv2 or { };
|
||||
|
||||
render = {
|
||||
cm_fs_passthrough = 1;
|
||||
};
|
||||
|
||||
misc = {
|
||||
vrr = 1;
|
||||
};
|
||||
|
||||
general = {
|
||||
gaps_in = 5;
|
||||
gaps_out = 10;
|
||||
border_size = 1;
|
||||
"col.active_border" = "rgb(8aadf4) rgb(24273A) rgb(24273A) rgb(8aadf4) 45deg";
|
||||
"col.inactive_border" = "rgb(24273A) rgb(24273A) rgb(24273A) rgb(24273A) 45deg";
|
||||
layout = "dwindle";
|
||||
allow_tearing = true;
|
||||
};
|
||||
|
||||
decoration = {
|
||||
rounding = 10;
|
||||
blur = {
|
||||
enabled = true;
|
||||
size = 2;
|
||||
passes = 2;
|
||||
new_optimizations = true;
|
||||
xray = false;
|
||||
};
|
||||
# drop_shadow = "yes";
|
||||
# shadow_range = 4;
|
||||
# shadow_render_power = "3";
|
||||
# "col.shadow" = "rgba(1a1a1aee)";
|
||||
};
|
||||
|
||||
animations = {
|
||||
enabled = "yes";
|
||||
bezier = [
|
||||
"overshot, 0.05, 0.9, 0.1, 1.05"
|
||||
"smoothOut, 0.36, 0, 0.66, -0.56"
|
||||
"smoothIn, 0.25, 1, 0.5, 1"
|
||||
];
|
||||
animation = [
|
||||
"windows, 1, 5, overshot, slide"
|
||||
"windowsOut, 1, 4, smoothOut, slide"
|
||||
"windowsMove, 1, 4, default"
|
||||
"border, 1, 10, default"
|
||||
"fade, 1, 10, smoothIn"
|
||||
"fadeDim, 1, 10, smoothIn"
|
||||
"workspaces, 1, 6, default"
|
||||
];
|
||||
};
|
||||
|
||||
dwindle = {
|
||||
pseudotile = "yes";
|
||||
preserve_split = "yes";
|
||||
};
|
||||
|
||||
misc = {
|
||||
force_default_wallpaper = 0;
|
||||
};
|
||||
|
||||
workspace = cfg.workspace;
|
||||
|
||||
windowrule = [
|
||||
"float, title:(file_progress)"
|
||||
"float, title:(.*[Cc]onfirm.*)"
|
||||
"float, title:(.*[Dd]ialog.*)"
|
||||
"float, title:(.*[Dd]ownload.*)"
|
||||
"float, title:(.*[Nn]otification.*)"
|
||||
"float, title:(.*[Ee]rror.*)"
|
||||
"float, title:(.*[Ss]plash.*)"
|
||||
"float, title:(.*[Cc]onfirmreset.*)"
|
||||
"float, title:(.*[Ss]ign [Ii]n - .*)"
|
||||
"float, title:(.*[Oo]pen [Ff]ile.*)"
|
||||
"float, title:(.*branchdialog.*)"
|
||||
"float, class:(.*pavucontrol.*)"
|
||||
"move onscreen cursor 0% 0%, class:(.*pavucontrol.*)"
|
||||
"float, class:(.*[Oo]verskride.*)"
|
||||
"float, class:(.*FileRoller.*)"
|
||||
"float, class:(.*wlogout.*)"
|
||||
"idleinhibit stayfocused, title:(.*mpv.*)"
|
||||
|
||||
"float, class:(.*nm-connection-editor.*)"
|
||||
"move onscreen cursor 0% 0%, class:(.*nm-connection-editor.*)"
|
||||
|
||||
"float, title:(Media viewer)"
|
||||
"float, class:(it.mijorus.smile),title:(Smile)"
|
||||
"float, class:(.blueman-manager-wrapped)$,title:(Bluetooth Devices)"
|
||||
# Picture in picture windows
|
||||
"float, title:(.*Picture-in-Picture.*)"
|
||||
"pin, title::(.*Picture-in-Picture.*)"
|
||||
|
||||
# discord/vesktop
|
||||
"workspace: name:discord, class:(.*vesktop)"
|
||||
"float, class:(.*vesktop),title:(.*Discord Popout.*)"
|
||||
"pin, class:(.*vesktop),title:(.*Discord Popout.*)"
|
||||
|
||||
# Music
|
||||
"workspace: name:discord, class:(Apple Music.*)"
|
||||
|
||||
# Steam
|
||||
"float, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
||||
"workspace name:steam silent, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
||||
"tile, class:(.*[Ss]team), title:(.*[Ss]team.*)$"
|
||||
"float, class:(.*steam),title:(.*Friends List.*)"
|
||||
|
||||
# Code
|
||||
"pin, class:(.*codium.*),title:(Save As)"
|
||||
"float, class:(.*codium.*),title:(Save As)"
|
||||
"float, class:(xdg-desktop-portal-gtk),title:(Open Workspace from File)"
|
||||
|
||||
# Game Tearing??? https://wiki.hyprland.org/Configuring/Tearing/
|
||||
"immediate, class:(.*gamescope)"
|
||||
|
||||
# vmware
|
||||
# this tag will set the below options to the vdi window
|
||||
# this will have it auto open as a 2160x7680 window
|
||||
# and makes multi-monitor work
|
||||
"tag +horizonrdp, class:(.*[Vv][Mm]ware-view),title:(USPS Next VDI)"
|
||||
|
||||
"noanim, tag:horizonrdp"
|
||||
"noblur, tag:horizonrdp"
|
||||
"norounding, tag:horizonrdp"
|
||||
"noshadow, tag:horizonrdp"
|
||||
"immediate, tag:horizonrdp"
|
||||
"allowsinput, tag:horizonrdp"
|
||||
"noborder, tag:horizonrdp"
|
||||
"nodim, tag:horizonrdp"
|
||||
"nomaxsize, tag:horizonrdp"
|
||||
"renderunfocused, tag:horizonrdp"
|
||||
"idleinhibit, tag:horizonrdp"
|
||||
"float, tag:horizonrdp"
|
||||
# "size 2160 7680, tag:horizonrdp"
|
||||
# "move onscreen 0 0, tag:horizonrdp"
|
||||
# float the vmware window cause its annoying to use in fullscreen
|
||||
"float, class:(.*[Vv][Mm]ware-view),title:([Vv][Mm]ware [Hh]orizon [Cc]lient)"
|
||||
|
||||
"tag +waydroid, class:([Ww]aydroid.*)"
|
||||
"float, tag:waydroid"
|
||||
"pin, tag:waydroid"
|
||||
] ++ cfg.windowRule;
|
||||
|
||||
plugin = {
|
||||
touch_gestures = {
|
||||
# The default sensitivity is probably too low on tablet screens,
|
||||
# I recommend turning it up to 4.0
|
||||
sensitivity = "4.0";
|
||||
|
||||
# must be >= 3
|
||||
workspace_swipe_fingers = "3";
|
||||
|
||||
# switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers
|
||||
# and can be used at the same time
|
||||
# possible values: l, r, u, or d
|
||||
# to disable it set it to anything else
|
||||
workspace_swipe_edge = "d";
|
||||
|
||||
# in milliseconds
|
||||
long_press_delay = "400";
|
||||
|
||||
# resize windows by long-pressing on window borders and gaps.
|
||||
# If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating
|
||||
# windows
|
||||
resize_on_border_long_press = true;
|
||||
|
||||
# in pixels, the distance from the edge that is considered an edge
|
||||
edge_margin = "10";
|
||||
|
||||
# emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe.
|
||||
# ONLY triggers when finger count is equal to workspace_swipe_fingers
|
||||
#
|
||||
# might be removed in the future in favor of event hooks
|
||||
emulate_touchpad_swipe = false;
|
||||
|
||||
experimental = {
|
||||
# send proper cancel events to windows instead of hacky touch_up events,
|
||||
# NOT recommended as it crashed a few times, once it's stabilized I'll make it the default
|
||||
send_cancel = "0";
|
||||
};
|
||||
|
||||
hyprgrass-bind = [
|
||||
# swipe left from right edge
|
||||
", edge:r:l, workspace, +1"
|
||||
|
||||
# swipe up from bottom edge
|
||||
", edge:d:u, exec, ${cfg.defaultApps.browser.pname}"
|
||||
|
||||
# swipe down from left edge
|
||||
", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%"
|
||||
|
||||
# swipe down with 4 fingers
|
||||
", swipe:4:d, killactive"
|
||||
|
||||
# swipe diagonally left and down with 3 fingers
|
||||
# l (or r) must come before d and u
|
||||
", swipe:3:ld, exec, foot"
|
||||
|
||||
# tap with 3 fingers
|
||||
", tap:3, exec, foot"
|
||||
|
||||
# longpress can trigger mouse binds:
|
||||
", longpress:2, movewindow"
|
||||
", longpress:3, resizewindow"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
gestures = {
|
||||
workspace_swipe = true;
|
||||
workspace_swipe_cancel_ratio = "0.15";
|
||||
};
|
||||
|
||||
input = {
|
||||
kb_layout = "us";
|
||||
|
||||
kb_variant = "";
|
||||
kb_model = "";
|
||||
kb_options = "";
|
||||
kb_rules = "";
|
||||
|
||||
numlock_by_default = true;
|
||||
|
||||
follow_mouse = 1;
|
||||
|
||||
touchpad = {
|
||||
clickfinger_behavior = 1;
|
||||
natural_scroll = "yes";
|
||||
};
|
||||
|
||||
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
|
||||
};
|
||||
|
||||
experimental = {
|
||||
xx_color_management_v4 = true;
|
||||
};
|
||||
|
||||
debug = {
|
||||
full_cm_proto = true;
|
||||
disable_logs = true;
|
||||
disable_scale_checks = true;
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
exec-once = dbus-update-activation-environment --systemd --all
|
||||
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
||||
exec-once = xhost +SI:localuser:root
|
||||
exec-once = nwg-look -a
|
||||
exec-once = nwg-dock-hyprland -d
|
||||
'' + cfg.extraConfig or '''';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
{ lib, pkgs, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.desktop.hyprland = {
|
||||
enable = mkEnableOption "enable hyprland desktop";
|
||||
|
||||
primaryDisplay = mkOption {
|
||||
type = types.str;
|
||||
default = "DP-1";
|
||||
};
|
||||
|
||||
display1 = {
|
||||
input = mkOption {
|
||||
type = types.str;
|
||||
default = "DP-1";
|
||||
};
|
||||
|
||||
resolution = mkOption {
|
||||
type = types.str;
|
||||
default = "3840x2160";
|
||||
};
|
||||
|
||||
refreshRate = mkOption {
|
||||
type = types.str;
|
||||
default = "240.00000";
|
||||
};
|
||||
};
|
||||
|
||||
display2 = {
|
||||
input = mkOption {
|
||||
type = types.str;
|
||||
default = "DP-1";
|
||||
};
|
||||
|
||||
resolution = mkOption {
|
||||
type = types.str;
|
||||
default = "3840x2160";
|
||||
};
|
||||
|
||||
refreshRate = mkOption {
|
||||
type = types.str;
|
||||
default = "240.00000";
|
||||
};
|
||||
};
|
||||
|
||||
wallpaper = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "list of hyprland wallpaper configs";
|
||||
};
|
||||
|
||||
monitor = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "list of hyprland monitor configs";
|
||||
};
|
||||
|
||||
monitorv2 = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "list of hyprland monitorv2 configs";
|
||||
};
|
||||
|
||||
workspace = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "list of hyprland workspace definitions";
|
||||
};
|
||||
|
||||
windowRule = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
description = "list of hyprland window rules";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; str;
|
||||
default = '''';
|
||||
description = "any extra options";
|
||||
};
|
||||
|
||||
iconThemeName = mkOption {
|
||||
type = types.str;
|
||||
default = "Colloid-Dark";
|
||||
};
|
||||
|
||||
gtkThemeName = mkOption {
|
||||
type = types.str;
|
||||
default = "Colloid-Dark";
|
||||
};
|
||||
|
||||
defaultApps = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
browser = mkOption { type = types.package; default = pkgs.firefox; };
|
||||
editor = mkOption { type = types.package; default = pkgs.micro; };
|
||||
fileExplorer = mkOption { type = types.package; default = pkgs.nemo; };
|
||||
visual = mkOption { type = types.package; default = pkgs.vscodium; };
|
||||
terminal = mkOption { type = types.package; default = pkgs.kitty; };
|
||||
office = mkOption { type = types.package; default = pkgs.onlyoffice-bin_latest; };
|
||||
video = mkOption { type = types.package; default = pkgs.vlc; };
|
||||
imageViewer = mkOption { type = types.package; default = pkgs.nomacs; };
|
||||
};
|
||||
};
|
||||
description = "Default applications used across the system.";
|
||||
};
|
||||
|
||||
hyprIdle = {
|
||||
lockScreenTimer = mkOption {
|
||||
type = with types; int;
|
||||
default = 5;
|
||||
};
|
||||
screenOffTimer = mkOption {
|
||||
type = with types; int;
|
||||
default = 15;
|
||||
};
|
||||
suspendTimer = mkOption {
|
||||
type = with types; int;
|
||||
default = 30;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.desktop.hyprland;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = with pkgs; [
|
||||
box64
|
||||
brightnessctl
|
||||
ddcutil
|
||||
dunst
|
||||
egl-wayland
|
||||
file-roller
|
||||
glib
|
||||
gnome-calculator
|
||||
gnome-calendar
|
||||
gnome-disk-utility
|
||||
gnome-firmware
|
||||
gnome-firmware-updater
|
||||
gnome-font-viewer
|
||||
gnome-logs
|
||||
gnome-photos
|
||||
gnome-tweaks
|
||||
gnome-weather
|
||||
gsettings-desktop-schemas
|
||||
hyprcursor
|
||||
hyprland
|
||||
hyprpaper
|
||||
hyprshot
|
||||
hyprsysteminfo
|
||||
kdePackages.qtmultimedia
|
||||
libnotify
|
||||
libz
|
||||
mako
|
||||
meson
|
||||
nautilus
|
||||
networkmanagerapplet
|
||||
nm-tray
|
||||
nomacs
|
||||
nwg-look
|
||||
overskride
|
||||
pamixer
|
||||
pavucontrol
|
||||
playerctl
|
||||
polkit
|
||||
polkit_gnome
|
||||
qt5.qtwayland
|
||||
qt6.qtwayland
|
||||
rofi-wayland
|
||||
waybar
|
||||
wayland-protocols
|
||||
wayland-utils
|
||||
waypaper
|
||||
wev
|
||||
wl-clipboard
|
||||
wlogout
|
||||
wlroots
|
||||
xdg-desktop-portal-hyprland
|
||||
xdg-desktop-portal-gtk
|
||||
xdg-desktop-portal-wlr
|
||||
xorg.xhost
|
||||
xsettingsd
|
||||
xwayland
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{ config, lib, namespace, ... }:
|
||||
let
|
||||
cfg = config.${namespace}.desktop.hyprland;
|
||||
in
|
||||
{
|
||||
imports = [ ../../options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.hypridle = {
|
||||
enable = false;
|
||||
settings = {
|
||||
general = {
|
||||
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.
|
||||
ignore_dbus_inhibit = false;
|
||||
lock_cmd = "pidof hyprlock || hyprlock"; # avoid starting multiple hyprlock instances.
|
||||
};
|
||||
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 = cfg.hyprIdle.lockScreenTimer;
|
||||
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
|
||||
}
|
||||
{
|
||||
timeout = cfg.hyprIdle.screenOffTimer;
|
||||
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
|
||||
on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired.
|
||||
}
|
||||
{
|
||||
timeout = cfg.hyprIdle.suspendTimer;
|
||||
on-timeout = "systemctl suspend"; # suspend pc
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
{ config, lib, namespace, ... }:
|
||||
let
|
||||
cfg = config.${namespace}.desktop.hyprland;
|
||||
in
|
||||
{
|
||||
imports = [ ../../options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.hyprlock = {
|
||||
enable = true;
|
||||
settings = {
|
||||
background = [
|
||||
{
|
||||
monitor = "";
|
||||
path = cfg.wallpaper; # supports png, jpg, webp (no animations, though)
|
||||
color = "rgba(25, 20, 20, 1.0)";
|
||||
|
||||
# all these options are taken from hyprland, see https://wiki.hyprland.org/Configuring/Variables/#blur for explanations
|
||||
blur_passes = "3"; # 0 disables blurring
|
||||
blur_size = "7";
|
||||
noise = "0.0117";
|
||||
contrast = "0.8916";
|
||||
brightness = "0.8172";
|
||||
vibrancy = "0.1696";
|
||||
vibrancy_darkness = "0.0";
|
||||
}
|
||||
];
|
||||
input-field = [
|
||||
{
|
||||
size = "200, 50";
|
||||
position = "0, -80";
|
||||
monitor = cfg.primaryDisplay;
|
||||
dots_center = true;
|
||||
fade_on_empty = true;
|
||||
font_color = "rgb(202, 211, 245)";
|
||||
inner_color = "rgb(91, 96, 120)";
|
||||
outer_color = "rgb(24, 25, 38)";
|
||||
bothlock_color = -1;
|
||||
outline_thickness = 5;
|
||||
placeholder_text = ''<span foreground="##cad3f5">Password...</span>'';
|
||||
shadow_passes = 2;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{ config, lib, namespace, ... }:
|
||||
let
|
||||
cfg = config.${namespace}.desktop.hyprland;
|
||||
in
|
||||
{
|
||||
imports = [ ../../options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.hyprpaper = {
|
||||
enable = true;
|
||||
settings = {
|
||||
preload = [ "/run/wallpaper.jpg" ];
|
||||
wallpaper = ",/run/wallpaper.jpg";
|
||||
splash = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.desktop.hyprland;
|
||||
|
||||
themeSize = "compact"; # [ "standard" "compact" ]
|
||||
themeAccent = "all"; # [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ]
|
||||
themeVariant = "nord"; # [ "nord" "dracula" "gruvbox" "everforest" "catppuccin" "all" "black" "rimless" "normal" "float" ]
|
||||
themeColor = "dark"; # [ "standard" "light" "dark" ]
|
||||
iconThemeVariant = "all"; # [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ]
|
||||
iconScheme = "nord"; # [ "default" "nord" "dracula" "gruvbox" "everforest" "catppuccin" "all" ]
|
||||
|
||||
# Cursor
|
||||
cursorTheme = "macOS";
|
||||
cursorThemePkg = pkgs.apple-cursor;
|
||||
cursorSize = 24;
|
||||
|
||||
# GTK
|
||||
# gtkThemeSize = themeSize;
|
||||
# gtkThemeAccent = themeAccent;
|
||||
# gtkThemeVariant = themeVariant;
|
||||
# gtkThemeColor = themeColor;
|
||||
gtkTheme = "Colloid-Dark-Compact-Nord";
|
||||
gtkThemePkg = pkgs.colloid-gtk-theme.override {
|
||||
sizeVariants = [ themeSize ];
|
||||
colorVariants = [ themeColor ];
|
||||
themeVariants = [ themeAccent ];
|
||||
tweaks = [ themeVariant ];
|
||||
};
|
||||
|
||||
# Icons
|
||||
# iconThemeScheme = iconScheme;
|
||||
iconTheme = "Colloid-Nord-Dark";
|
||||
iconThemePkg = pkgs.colloid-icon-theme.override {
|
||||
schemeVariants = [ iconScheme ];
|
||||
colorVariants = [ iconThemeVariant ];
|
||||
};
|
||||
|
||||
# Fonts
|
||||
fontName = "JetBrainsMono NFM";
|
||||
fontPackage = pkgs.nerd-fonts.jetbrains-mono;
|
||||
fontSize = 12;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
home = {
|
||||
pointerCursor = {
|
||||
gtk.enable = true;
|
||||
package = cursorThemePkg;
|
||||
name = cursorTheme;
|
||||
size = cursorSize;
|
||||
};
|
||||
};
|
||||
|
||||
dconf = {
|
||||
enable = true;
|
||||
settings = {
|
||||
"org/gnome/desktop/interface".color-scheme = "prefer-dark";
|
||||
"org/gnome/desktop/interface".cursor-theme = cursorTheme;
|
||||
"org/gnome/desktop/interface".gtk-theme = gtkTheme;
|
||||
"org/gnome/desktop/interface".icon-theme = iconTheme;
|
||||
};
|
||||
};
|
||||
|
||||
gtk = {
|
||||
enable = true;
|
||||
|
||||
cursorTheme = {
|
||||
name = cursorTheme;
|
||||
package = cursorThemePkg;
|
||||
};
|
||||
|
||||
theme = {
|
||||
name = gtkTheme;
|
||||
package = gtkThemePkg;
|
||||
};
|
||||
|
||||
iconTheme = {
|
||||
name = iconTheme;
|
||||
package = iconThemePkg;
|
||||
};
|
||||
|
||||
gtk3.extraConfig = {
|
||||
gtk-application-prefer-dark-theme = true;
|
||||
};
|
||||
|
||||
gtk4.extraConfig = {
|
||||
gtk-application-prefer-dark-theme = true;
|
||||
};
|
||||
|
||||
font = {
|
||||
name = fontName;
|
||||
package = fontPackage;
|
||||
size = fontSize;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.desktop.hyprland;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
home.sessionVariables = {
|
||||
BROWSER = "${cfg.defaultApps.browser.pname}";
|
||||
CLUTTER_BACKEND = "wayland";
|
||||
EDITOR = "${cfg.defaultApps.editor.pname}";
|
||||
VISUAL = "${cfg.defaultApps.visual.pname}";
|
||||
ICON_THEME = cfg.iconThemeName;
|
||||
GTK_CSD = "0";
|
||||
GTK_THEME = cfg.gtkThemeName;
|
||||
GTK_USE_PORTAL = "1";
|
||||
HYPRCURSOR_THEME = config.home.pointerCursor.name;
|
||||
HYPRCURSOR_SIZE = config.home.pointerCursor.size;
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
NIXOS_XDG_OPEN_USE_PORTAL = "1";
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
|
||||
QT_QPA_PLATFORM = "wayland-egl";
|
||||
QT_QPA_PLATFORMTHEME = "gtk3";
|
||||
QT_SCALE_FACTOR = "1";
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
||||
SDL_VIDEODRIVER = "wayland";
|
||||
TERMINAL = "${cfg.defaultApps.terminal.pname}";
|
||||
XCURSOR_THEME = config.home.pointerCursor.name;
|
||||
XCURSOR_SIZE = config.home.pointerCursor.size;
|
||||
XDG_CACHE_HOME = "\${HOME}/.cache";
|
||||
XDG_CONFIG_HOME = "\${HOME}/.config";
|
||||
XDG_CURRENT_DESKTOP = "Hyprland";
|
||||
XDG_DATA_HOME = "\${HOME}/.local/share";
|
||||
XDG_SESSION_DESKTOP = "Hyprland";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
# Nord colors
|
||||
# Opacity Hex alpha
|
||||
# 100% FF
|
||||
# 75% BF
|
||||
# 50% 80
|
||||
# 25% 40
|
||||
# 10% 1A
|
||||
# 0% 00
|
||||
polarNight = {
|
||||
nord0 = "#2e3440";
|
||||
nord1 = "#3b4252";
|
||||
nord2 = "#434c5e";
|
||||
nord3 = "#4c566a";
|
||||
};
|
||||
snowStorm = {
|
||||
nord4 = "#d8dee9";
|
||||
nord5 = "#e5e9f0";
|
||||
nord6 = "#eceff4";
|
||||
};
|
||||
frost = {
|
||||
nord7 = "#8fbcbb";
|
||||
nord8 = "#88c0d0";
|
||||
nord9 = "#81a1c1";
|
||||
nord10 = "#5e81ac";
|
||||
};
|
||||
aurora = {
|
||||
nord11 = "#bf616a";
|
||||
nord12 = "#d08770";
|
||||
nord13 = "#ebcb8b";
|
||||
nord14 = "#a3be8c";
|
||||
nord15 = "#b48ead";
|
||||
};
|
||||
|
||||
defaultOpacity = "opacity: 0.85;";
|
||||
defaultBorderRadius = "border-radius: 1rem;";
|
||||
defaultCenterOptions = ''
|
||||
padding-top: 0.2rem;
|
||||
padding-bottom: 0.2rem;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
margin: 3px 0;
|
||||
'';
|
||||
borderRight = ''
|
||||
padding-top: 0.2rem;
|
||||
padding-bottom: 0.2rem;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
margin: 3px 0;
|
||||
border-radius: 0rem 1rem 1rem 0rem;
|
||||
margin-right: 0.5rem;
|
||||
'';
|
||||
borderLeft = ''
|
||||
padding-top: 0.2rem;
|
||||
padding-bottom: 0.2rem;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
margin: 3px 0;
|
||||
border-radius: 1rem 0rem 0rem 1rem;
|
||||
margin-left: 0.5rem;
|
||||
'';
|
||||
}
|
||||
79
modules/home/gpg/default.nix
Normal file
79
modules/home/gpg/default.nix
Normal file
@@ -0,0 +1,79 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs = {
|
||||
gpg = {
|
||||
enable = true;
|
||||
scdaemonSettings = {
|
||||
disable-ccid = true;
|
||||
pcsc-shared = true;
|
||||
};
|
||||
publicKeys = [
|
||||
{
|
||||
text = ''
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBGipyhUBEADCal3wKbTCJHZ7qBTxe2zrJPGV9vu6V4+x/MBQq07jd33RrdgI
|
||||
5R/YSviZLyTjY84xk+XTpxWe6PNxcrNlPrJgqR48UNYiG7rH2VWg073KQZaAEeX4
|
||||
DRmfANtds9m9N9CadMv1XcHvVkEz+UlD3yYGNwrd1ZnWVBpUobIyZvFrVjpGBtOg
|
||||
jgW3NepPn9SfguF+PV4t3Tn2iAFsDa/U3RpkMvYtfxgtxJPvbaVNc3Zq7UDWaXta
|
||||
zZ7y/o5figLUn3q/2JrbzeXmNpShkTixXJHJwSjoD/27I6fVFz4EfwkBfyo8B9yX
|
||||
goekY00wym0oIT2Jb5ZLFh8b60mX/ezUJcMhDkqTG77caRDRxw76yVxc0Jp+r+xZ
|
||||
3ckcrdm+/UtnnD3VO0ktvhb4pU93Pj0PJhrm7qVZS/SEJ67vUx8Aem3aMWgSRsl5
|
||||
51h08US7yfPaMNqKX9d2KaLSTGnQ2BSoXJEmbIqvlvazUTqVk85TDWZEYXgc2S2K
|
||||
phyDfJiVmmUWekgrYE/Fyx0QJkCA6z8cNQWwpRe7oJG1VrnRjhIcuL+EpJb9Ytd9
|
||||
NT39/6/rBot2iGmn64vdyqirji2shuLwrp34A9KWY3XUC5zv0GlHCFsF8lraFzKz
|
||||
AsYv2cLRRja4kyuzoSwoHgXYu1MsifZHgF2+Y0sFW+odRqlo0A9ziXkB9QARAQAB
|
||||
tCNNYXR0aGV3IEphbGxlbiA8amFsbGUwMDhAcHJvdG9uLm1lPokCVwQTAQgAQRYh
|
||||
BMvLmximuJMLC2q/0cy4y+swYzaEBQJoqcoVAhsDBQkSzAMABQsJCAcCAiICBhUK
|
||||
CQgLAgQWAgMBAh4HAheAAAoJEMy4y+swYzaEsrkP/3c/kW0QNv79dEgEHhpJy7nP
|
||||
XyB8fTGr804Gq0ffaPgmn0G8iNzg9pgjgrA8oHpoP0ZbmKaO7JkpHsS0+fpMNuFE
|
||||
dhthWgsYLAnC6rZb4Ib/b+wbUH19CJJIt6Rj9uqH3vDCxeG5TfiJnVA+x3O6VaM1
|
||||
K2oyrXaXDrUKxFlLlnMOsdfRZwXoyYPuJm8Lip5GawIakHGV17FdwdZOcfy0JtdH
|
||||
CwI0K5D390lQ2WNjIJx0vI8E3QYubciOjDzS+KNB12q4sSY6O3fKTXsi80JZ/y4C
|
||||
z1dwsRxMlndBbK1SBJFmczRy4dZC0WbNaxEF2qnM7RENDpB+73HQ1/mSsFaTu609
|
||||
9clDDjwCAUu4UrbL5veWLB+b+xUNy6Sgkbal1Q+pgGSTF9H8plGN0ymijC9xNmvX
|
||||
JeeSTvfnzAThiJubIpZYLkoMmlyEiGrc4CQDdfbsVR9xFGZcau5akcW3e45kiOZC
|
||||
is1H55HsXlBpezanvJCnX7ZEQlRP8vdquHADvgERf3D/qlVAgD/lGE8bzBKJxt1P
|
||||
kxXvGZFxF0BCN/GCoYib1w3WJeTyxGlf9wHkwa/COjasEBGzsnkLToET637WdmHr
|
||||
hgnTVm6CQQW4EUw6gOznDNQvd1EipAwJB7iEm2PneEAwauWeQN38+hc7QVIEqXRk
|
||||
wdfxlU/9WD+rh6FfQ7d3uQINBGipyhUBEADUGJQW/FUWo3R6X7+Quv3TqZfVXJB/
|
||||
bjX9Uv8SKOomUBAjQK9TklaZJvNiaD4qYV93kPfpclGhxdGahXVBC7SdGenaFig4
|
||||
4WwUe5vrKIGbbfcC+dBW/8eAqueKjCWe6wFqXbKat1/4Y1atsFZX5Lf/GEi1VNXu
|
||||
0NkSPKAqTdXyXrTuC7D5wARGdavbxO3BcF1NqpIPHiROQoOyP10jx8xcMYGoVIIr
|
||||
uscckoqhdbyEua9m9zFesYyqiCfJeSCK8O4w7BU3dgHUz53hfeuNuGBPb/dQ9Ent
|
||||
qKwrMxsPWJC9qN19Wvvsgy89QLn0CWmcUsmc/f4mWnKoSH9AZCuVCSgoSjknXGj0
|
||||
MPBI6jY1gaqZAuyMH24ekUAdUtNK5IuPPPxrlE1ljAWSxvFGG7Dj4p78ELJizlT7
|
||||
XXOtAPggwCFfXauQD+v43ILg5Zxz6fjTd0TZ8iSypqiZIQgQoiUUGcDZmjHhRHNj
|
||||
GHlqmRECyef6mZVhb3zlyzAcQycnZvHtXFMmyrvfFs21pX9WEF3lQFDapnMAwODE
|
||||
2BLQWrh2ed++/An3DJOh/Iwv9WBatDagMObJi3lsUszJ0l5iwteJOfXMR72zV+m7
|
||||
7QzaEdGFDlNRSMmtjni7FLWbDA/CkihRsUtqgrXgj91oqLga0GmjlNnIZGwhcDUx
|
||||
Yuo+kIRRM4DSDwARAQABiQI8BBgBCAAmFiEEy8ubGKa4kwsLar/RzLjL6zBjNoQF
|
||||
AmipyhUCGwwFCRLMAwAACgkQzLjL6zBjNoS5/Q//SPmdM26wUq50A8QTuQ3r8xpc
|
||||
3oGCdBAP7QJk6+W1kJcGVP4r2bFylbWUGyHWuhKTs47r6fh3Sd9MtmGQgtEEbGFW
|
||||
a4pxaYBRPYGHvJuVwb4IvOzDuVj8yabk0c688jz2Wv1DW3+z4623TI2JeOfEoOqg
|
||||
u4DGySVZkXA/F01HShP0QsGEGRkklEvysD101GbJrQuQ6ssHiFVF1m+/w+I8fYzP
|
||||
F9BC61DOEabm62YjELf/xvKQ6aT8rB0F2p9udOmIlw9lkAJMsEz4mB5f4Bq/1vGt
|
||||
aZ7K0tytT3aeTFFgLwtBPcjWvHavEp4/CDXUL58v/X5R+E6Z03zsWwspsACacblq
|
||||
RW15f3aKI2j7u/w6oJ/iJbEXtZq/Hv1XACyZ/kD9WcYIPsNikCS6vSsnj9Hk/o88
|
||||
yG0rQ6v9L7s9gqWm1IajnDQD6g7n3H4pXGJsE4sBGg6FfE0OJDcd4VqZGJGMz9rr
|
||||
+V+3zUxs/RIVWTCdoVPTLBWrtsKbwObgE7SdkaUt4/1uhtdkR++brhr2uz3il0Kt
|
||||
2QZAXJDcK2xzcOEz41lhclgMxUzjYTggQvpD8lu70xlGqgm94NJCBctPx6xJAN9f
|
||||
H6dELHDuLAwB+vKB9YJIvMVaPNKRam8wGnZ0EKHUFvmIqqSOE8GR1LmgslYRNidv
|
||||
ywgEIPcOpJGzt3TQprM=
|
||||
=i8do
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
'';
|
||||
trust = "ultimate";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
gpg-agent = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
enableSshSupport = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,56 +1,88 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
hasDestopEnvironment ? true,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) enabled;
|
||||
in
|
||||
{
|
||||
home = {
|
||||
enableNixpkgsReleaseCheck = lib.mkDefault false;
|
||||
homeDirectory = lib.mkDefault "/home/${config.home.username}";
|
||||
packages = with pkgs; [
|
||||
age
|
||||
chromium
|
||||
clinfo
|
||||
cpufetch
|
||||
deadnix
|
||||
firefox
|
||||
gamescope
|
||||
gamescope-wsi
|
||||
goverlay
|
||||
gparted
|
||||
lm_sensors
|
||||
mission-center
|
||||
nano
|
||||
nixfmt-rfc-style
|
||||
pciutils
|
||||
protonup
|
||||
rsync
|
||||
smartmontools
|
||||
sops
|
||||
tailscale
|
||||
tree
|
||||
usbutils
|
||||
vesktop
|
||||
vim
|
||||
vulkan-tools
|
||||
wget
|
||||
];
|
||||
packages =
|
||||
with pkgs;
|
||||
[
|
||||
age
|
||||
clinfo
|
||||
cpufetch
|
||||
dbus
|
||||
deadnix
|
||||
lm_sensors
|
||||
nano
|
||||
nix-prefetch-scripts
|
||||
nixfmt
|
||||
pciutils
|
||||
protonup-ng
|
||||
rsync
|
||||
smartmontools
|
||||
sops
|
||||
tailscale
|
||||
tree
|
||||
usbutils
|
||||
vim
|
||||
vulkan-tools
|
||||
wget
|
||||
]
|
||||
++ (
|
||||
if hasDestopEnvironment then
|
||||
[
|
||||
boxbuddy
|
||||
stable.chromium
|
||||
firefox
|
||||
gamescope
|
||||
gamescope-wsi
|
||||
gparted
|
||||
pkgs.unstable.goverlay
|
||||
mission-center
|
||||
parted
|
||||
vesktop
|
||||
# winboat
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
);
|
||||
|
||||
stateVersion = lib.mkDefault "23.11";
|
||||
};
|
||||
|
||||
programs = {
|
||||
btop.enable = lib.mkDefault true;
|
||||
fastfetch.enable = lib.mkDefault true;
|
||||
home-manager.enable = lib.mkDefault true;
|
||||
nix-index-database.comma = enabled;
|
||||
btop = {
|
||||
enable = lib.mkDefault true;
|
||||
package = pkgs.unstable.btop;
|
||||
};
|
||||
fastfetch = lib.mkDefault enabled;
|
||||
home-manager = lib.mkDefault enabled;
|
||||
java = {
|
||||
enable = lib.mkDefault true;
|
||||
};
|
||||
mangohud.enable = lib.mkDefault true;
|
||||
password-store.enable = true;
|
||||
mangohud.enable = lib.mkDefault hasDestopEnvironment;
|
||||
password-store = enabled;
|
||||
nh = {
|
||||
enable = true;
|
||||
flake = "/etc/nixos";
|
||||
clean = {
|
||||
enable = true;
|
||||
extraArgs = "--keep 5";
|
||||
};
|
||||
};
|
||||
|
||||
micro = {
|
||||
enable = true;
|
||||
enable = lib.mkDefault true;
|
||||
settings = {
|
||||
autoindent = true;
|
||||
autosu = true;
|
||||
@@ -61,7 +93,7 @@
|
||||
};
|
||||
|
||||
tmux = {
|
||||
enable = true;
|
||||
enable = lib.mkDefault true;
|
||||
terminal = "screen-256color";
|
||||
sensibleOnTop = true;
|
||||
focusEvents = true;
|
||||
@@ -101,11 +133,12 @@
|
||||
};
|
||||
|
||||
services = {
|
||||
nextcloud-client.enable = lib.mkDefault true;
|
||||
pass-secret-service.enable = lib.mkDefault true;
|
||||
nextcloud-client.enable = false; # lib.mkDefault hasDestopEnvironment;
|
||||
pass-secret-service = lib.mkDefault enabled;
|
||||
kdeconnect = {
|
||||
enable = true;
|
||||
indicator = true;
|
||||
enable = lib.mkDefault hasDestopEnvironment;
|
||||
indicator = lib.mkDefault hasDestopEnvironment;
|
||||
package = pkgs.kdePackages.kdeconnect-kde;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.btop;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.btop;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
@@ -10,8 +14,6 @@ in
|
||||
programs.btop = {
|
||||
enable = true;
|
||||
settings = {
|
||||
color_theme = "nord"; # todo
|
||||
theme_background = true;
|
||||
truecolor = true;
|
||||
force_tty = false;
|
||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty";
|
||||
@@ -75,52 +77,6 @@ in
|
||||
selected_battery = "Auto";
|
||||
log_level = "WARNING";
|
||||
};
|
||||
themes = {
|
||||
nord = ''
|
||||
theme[main_bg]="${nord.polarNight.nord0}"
|
||||
theme[main_fg]="${nord.snowStorm.nord6}"
|
||||
theme[title]="${nord.snowStorm.nord6}"
|
||||
theme[hi_fg]="${nord.frost.nord7}"
|
||||
theme[selected_bg]="${nord.polarNight.nord1}"
|
||||
theme[selected_fg]="${nord.frost.nord7}"
|
||||
theme[inactive_fg]="${nord.polarNight.nord2}"
|
||||
theme[graph_text]="${nord.snowStorm.nord6}"
|
||||
theme[meter_bg]="${nord.polarNight.nord1}"
|
||||
theme[proc_misc]="${nord.snowStorm.nord6}"
|
||||
theme[cpu_box]="${nord.aurora.nord15}"
|
||||
theme[mem_box]="${nord.aurora.nord14}"
|
||||
theme[net_box]="${nord.aurora.nord12}"
|
||||
theme[proc_box]="${nord.aurora.nord11}"
|
||||
theme[div_line]="${nord.polarNight.nord1}"
|
||||
theme[temp_start]="${nord.aurora.nord14}"
|
||||
theme[temp_mid]="${nord.aurora.nord13}"
|
||||
theme[temp_end]="${nord.aurora.nord11}"
|
||||
theme[cpu_start]="${nord.aurora.nord15}"
|
||||
theme[cpu_mid]="${nord.aurora.nord12}"
|
||||
theme[cpu_end]="${nord.aurora.nord11}"
|
||||
theme[free_start]="${nord.aurora.nord14}"
|
||||
theme[free_mid]="${nord.aurora.nord13}"
|
||||
theme[free_end]="${nord.aurora.nord12}"
|
||||
theme[cached_start]="${nord.aurora.nord14}"
|
||||
theme[cached_mid]="${nord.aurora.nord13}"
|
||||
theme[cached_end]="${nord.aurora.nord12}"
|
||||
theme[available_start]="${nord.snowStorm.nord6}"
|
||||
theme[available_mid]="${nord.aurora.nord11}"
|
||||
theme[available_end]="${nord.aurora.nord11}"
|
||||
theme[used_start]="${nord.aurora.nord14}"
|
||||
theme[used_mid]="${nord.aurora.nord13}"
|
||||
theme[used_end]="${nord.aurora.nord11}"
|
||||
theme[download_start]="${nord.frost.nord8}"
|
||||
theme[download_mid]="${nord.frost.nord8}"
|
||||
theme[download_end]="${nord.aurora.nord12}"
|
||||
theme[upload_start]="${nord.frost.nord7}"
|
||||
theme[upload_mid]="${nord.frost.nord7}"
|
||||
theme[upload_end]="${nord.aurora.nord12}"
|
||||
theme[process_start]="${nord.aurora.nord15}"
|
||||
theme[process_mid]="${nord.aurora.nord12}"
|
||||
theme[process_end]="${nord.aurora.nord11}"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.btop = {
|
||||
options.${namespace}.programs.btop = {
|
||||
enable = mkEnableOption "enable btop";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,76 @@
|
||||
{ config, lib, pkgs, system, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
system,
|
||||
namespace,
|
||||
hasDestopEnvironment ? true,
|
||||
...
|
||||
}:
|
||||
let
|
||||
isArm = "aarch64-linux" == system;
|
||||
open-remote-ssh = pkgs.vscode-utils.buildVscodeExtension {
|
||||
pname = "open-remote-ssh";
|
||||
version = "0.0.49";
|
||||
vscodeExtPublisher = "jeanp413";
|
||||
vscodeExtName = "open-remote-ssh";
|
||||
vscodeExtUniqueId = "jeanp413.open-remote-ssh";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://open-vsx.org/api/jeanp413/open-remote-ssh/0.0.49/file/jeanp413.open-remote-ssh-0.0.49.vsix";
|
||||
sha256 = "sha256-QfJnAAx+kO2iJ1EzWoO5HLogJKg3RiC3hg1/u2Jm6t4";
|
||||
name = "open-remote-ssh.zip";
|
||||
};
|
||||
};
|
||||
isArm = ("aarch64-linux" == system) || ("aarch64-darwin" == system);
|
||||
|
||||
x86_only = with pkgs; [
|
||||
vscode-extensions.redhat.vscode-xml
|
||||
];
|
||||
open-remote-ssh = pkgs.${namespace}.open-remote-ssh;
|
||||
in
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
nodePackages.nodejs
|
||||
uv
|
||||
];
|
||||
|
||||
programs = {
|
||||
vscode = {
|
||||
enable = true;
|
||||
enable = hasDestopEnvironment;
|
||||
package = pkgs.vscodium;
|
||||
mutableExtensionsDir = false;
|
||||
profiles = {
|
||||
default = {
|
||||
enableUpdateCheck = false;
|
||||
enableExtensionUpdateCheck = false;
|
||||
extensions = with pkgs; [
|
||||
vscode-extensions.arrterian.nix-env-selector
|
||||
vscode-extensions.bbenoist.nix
|
||||
vscode-extensions.brettm12345.nixfmt-vscode
|
||||
vscode-extensions.cweijan.vscode-database-client2
|
||||
vscode-extensions.dendron.dendron-markdown-preview-enhanced
|
||||
vscode-extensions.jnoortheen.nix-ide
|
||||
vscode-extensions.mkhl.direnv
|
||||
vscode-extensions.ms-python.debugpy
|
||||
vscode-extensions.ms-python.pylint
|
||||
vscode-extensions.ms-python.python
|
||||
# vscode-extensions.ms-python.vscode-pylance
|
||||
vscode-extensions.redhat.vscode-yaml
|
||||
vscode-extensions.yy0931.vscode-sqlite3-editor
|
||||
extensions =
|
||||
with pkgs;
|
||||
[
|
||||
vscode-extensions.arrterian.nix-env-selector
|
||||
vscode-extensions.bbenoist.nix
|
||||
vscode-extensions.brettm12345.nixfmt-vscode
|
||||
vscode-extensions.cweijan.vscode-database-client2
|
||||
# vscode-extensions.dendron.dendron-markdown-preview-enhanced
|
||||
vscode-extensions.jnoortheen.nix-ide
|
||||
vscode-extensions.mkhl.direnv
|
||||
vscode-extensions.ms-python.debugpy
|
||||
vscode-extensions.ms-python.pylint
|
||||
vscode-extensions.ms-python.python
|
||||
# vscode-extensions.ms-python.vscode-pylance
|
||||
vscode-extensions.redhat.vscode-yaml
|
||||
vscode-extensions.yy0931.vscode-sqlite3-editor
|
||||
|
||||
# open-remote-ssh
|
||||
# nix-vscode-extensions.open-vsx.jeanp413.open-remote-ssh
|
||||
# open-vsx.jeanp413.open-remote-ssh
|
||||
] ++ ( if !isArm then x86_only else [ ] ) ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
|
||||
{
|
||||
name = "copilot-mcp";
|
||||
publisher = "automatalabs";
|
||||
version = "0.0.49";
|
||||
sha256 = "sha256-+G2OQl5SCN7bh7MzGdYiRclIZefBE7lWnGg1kNpCvnA=";
|
||||
}
|
||||
{
|
||||
name = "mcp-server-runner";
|
||||
publisher = "zebradev";
|
||||
version = "0.1.0";
|
||||
sha256 = "sha256-StydVt3VzQUSS/pYp76jnIwtZlEj8gWAGzOARs93J+E=";
|
||||
}
|
||||
{
|
||||
name = "claude-dev";
|
||||
publisher = "saoudrizwan";
|
||||
version = "3.17.9";
|
||||
sha256 = "sha256-y3bFtMe5vZrO3DFb31KDvkzjD2jM76wK89mKhgJXC70=";
|
||||
}
|
||||
];
|
||||
# open-remote-ssh
|
||||
# nix-vscode-extensions.open-vsx.jeanp413.open-remote-ssh
|
||||
open-remote-ssh
|
||||
]
|
||||
++ (if !isArm then x86_only else [ ])
|
||||
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
|
||||
{
|
||||
name = "copilot-mcp";
|
||||
publisher = "automatalabs";
|
||||
version = "0.0.49";
|
||||
sha256 = "sha256-+G2OQl5SCN7bh7MzGdYiRclIZefBE7lWnGg1kNpCvnA=";
|
||||
}
|
||||
{
|
||||
name = "mcp-server-runner";
|
||||
publisher = "zebradev";
|
||||
version = "0.1.0";
|
||||
sha256 = "sha256-StydVt3VzQUSS/pYp76jnIwtZlEj8gWAGzOARs93J+E=";
|
||||
}
|
||||
{
|
||||
name = "claude-dev";
|
||||
publisher = "saoudrizwan";
|
||||
version = "3.17.9";
|
||||
sha256 = "sha256-y3bFtMe5vZrO3DFb31KDvkzjD2jM76wK89mKhgJXC70=";
|
||||
}
|
||||
];
|
||||
|
||||
userSettings = {
|
||||
|
||||
@@ -79,7 +85,7 @@ in
|
||||
"confirmDelete" = false;
|
||||
"confirmDragAndDrop" = false;
|
||||
};
|
||||
|
||||
|
||||
"git" = {
|
||||
"confirmSync" = false;
|
||||
"enableSmartCommit" = true;
|
||||
@@ -110,10 +116,12 @@ in
|
||||
# You can write arbitary Nix expressions here, to produce valid "options" declaration result.
|
||||
# Tip: for flake-based configuration, utilize `builtins.getFlake`
|
||||
"nixos" = {
|
||||
"expr" = "(builtins.getFlake \"${config.home.homeDirectory}/nix-config\").nixosConfigurations.<name>.options";
|
||||
"expr" =
|
||||
"(builtins.getFlake \"${config.home.homeDirectory}/nix-config\").nixosConfigurations.<name>.options";
|
||||
};
|
||||
"home-manager" = {
|
||||
"expr" = "(builtins.getFlake \"${config.home.homeDirectory}/nix-config\").homeConfigurations.<name>.options";
|
||||
"expr" =
|
||||
"(builtins.getFlake \"${config.home.homeDirectory}/nix-config\").homeConfigurations.<name>.options";
|
||||
};
|
||||
# # Tip: use ${workspaceFolder} variable to define path
|
||||
# "nix-darwin" = {
|
||||
@@ -139,6 +147,8 @@ in
|
||||
"*.db" = "default";
|
||||
};
|
||||
};
|
||||
|
||||
"enable-proposed-api" = [ "jeanp413.open-remote-ssh" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -149,4 +159,4 @@ in
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,12 @@ in
|
||||
{
|
||||
programs.git = {
|
||||
enable = true;
|
||||
userName = "mjallen18";
|
||||
userEmail = "matt.l.jallen@gmail.com";
|
||||
aliases = gitAliases;
|
||||
settings = {
|
||||
user = {
|
||||
name = "mjallen18";
|
||||
email = "matt.l.jallen@gmail.com";
|
||||
};
|
||||
alias = gitAliases;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
25
modules/home/programs/hyprland/avizo.nix
Normal file
25
modules/home/programs/hyprland/avizo.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
config,
|
||||
namespace,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.programs.hyprland;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.avizo = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default = {
|
||||
time = 1.0;
|
||||
y-offset = 0.5;
|
||||
fade-in = 0.1;
|
||||
fade-out = 0.2;
|
||||
padding = 10;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
710
modules/home/programs/hyprland/default.nix
Normal file
710
modules/home/programs/hyprland/default.nix
Normal file
@@ -0,0 +1,710 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.${namespace}.programs.hyprland;
|
||||
drawer = "nwg-drawer -fm nautilus -term kitty -mb 10 -mt 10 -ml 10 -mr 10 -pbuseicontheme -i ${config.stylix.icons.dark}";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./avizo.nix
|
||||
./options.nix
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Home packages
|
||||
home.packages =
|
||||
with pkgs;
|
||||
(
|
||||
[
|
||||
box64
|
||||
brightnessctl
|
||||
ddcutil
|
||||
egl-wayland
|
||||
file-roller
|
||||
glib
|
||||
gnome-calculator
|
||||
gnome-calendar
|
||||
gnome-disk-utility
|
||||
gnome-firmware
|
||||
gnome-font-viewer
|
||||
gnome-logs
|
||||
gnome-photos
|
||||
gnome-tweaks
|
||||
gnome-weather
|
||||
gsettings-desktop-schemas
|
||||
hyprcursor
|
||||
hyprland
|
||||
hyprpaper
|
||||
hyprshot
|
||||
hyprsysteminfo
|
||||
kdePackages.qtmultimedia
|
||||
libnotify
|
||||
libz
|
||||
meson
|
||||
nautilus
|
||||
nomacs
|
||||
nwg-look
|
||||
overskride
|
||||
pamixer
|
||||
pavucontrol
|
||||
playerctl
|
||||
qt5.qtwayland
|
||||
qt6.qtwayland
|
||||
waybar
|
||||
wayland-protocols
|
||||
wayland-utils
|
||||
waypaper
|
||||
wev
|
||||
wl-clipboard
|
||||
wlogout
|
||||
wlroots
|
||||
xhost
|
||||
xsettingsd
|
||||
xwayland
|
||||
]
|
||||
++ (if cfg.notificationDaemon == "mako" then [ mako ] else [ dunst ])
|
||||
++ (if cfg.launcher == "wofi" then [ wofi ] else [ rofi ])
|
||||
++ (with pkgs.${namespace}; [ pipewire-python ])
|
||||
);
|
||||
|
||||
# Session variables
|
||||
home.sessionVariables = {
|
||||
BROWSER = "${cfg.defaultApps.browser.pname}";
|
||||
CLUTTER_BACKEND = "wayland";
|
||||
EDITOR = "${cfg.defaultApps.editor.pname}";
|
||||
VISUAL = "${cfg.defaultApps.visual.pname}";
|
||||
ICON_THEME = config.gtk.iconTheme.name;
|
||||
GTK_CSD = "0";
|
||||
GTK_THEME = config.gtk.theme.name;
|
||||
GTK_USE_PORTAL = "1";
|
||||
HYPRCURSOR_THEME = config.stylix.cursor.name;
|
||||
HYPRCURSOR_SIZE = config.stylix.cursor.size;
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
NIXOS_XDG_OPEN_USE_PORTAL = "1";
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
|
||||
QT_QPA_PLATFORM = "wayland-egl";
|
||||
QT_QPA_PLATFORMTHEME = lib.mkDefault "gtk3";
|
||||
QT_SCALE_FACTOR = "1";
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
||||
SDL_VIDEODRIVER = "wayland";
|
||||
TERMINAL = "${cfg.defaultApps.terminal.pname}";
|
||||
XCURSOR_THEME = config.stylix.cursor.name;
|
||||
XCURSOR_SIZE = config.stylix.cursor.size;
|
||||
XDG_CACHE_HOME = "\${HOME}/.cache";
|
||||
XDG_CONFIG_HOME = "\${HOME}/.config";
|
||||
XDG_CURRENT_DESKTOP = "Hyprland";
|
||||
XDG_DATA_HOME = "\${HOME}/.local/share";
|
||||
XDG_SESSION_DESKTOP = "Hyprland";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
};
|
||||
|
||||
# Services
|
||||
services = {
|
||||
hyprpolkitagent.enable = true;
|
||||
hyprpaper = {
|
||||
enable = true;
|
||||
settings = {
|
||||
preload = [ cfg.hyprpaper.wallpaperPath ];
|
||||
wallpaper = [
|
||||
{
|
||||
monitor = "";
|
||||
path = cfg.hyprpaper.wallpaperPath;
|
||||
}
|
||||
];
|
||||
splash = false;
|
||||
};
|
||||
};
|
||||
|
||||
hypridle = {
|
||||
enable = true;
|
||||
settings = {
|
||||
general = {
|
||||
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.
|
||||
ignore_dbus_inhibit = false;
|
||||
lock_cmd = "pidof hyprlock || hyprlock"; # avoid starting multiple hyprlock instances.
|
||||
};
|
||||
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 = cfg.hyprIdle.lockScreenTimer;
|
||||
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
|
||||
}
|
||||
{
|
||||
timeout = cfg.hyprIdle.screenOffTimer;
|
||||
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
|
||||
on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired.
|
||||
}
|
||||
{
|
||||
timeout = cfg.hyprIdle.suspendTimer;
|
||||
on-timeout = "systemctl suspend"; # suspend pc
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Programs
|
||||
programs = {
|
||||
vscode.profiles.default.userSettings."window"."titleBarStyle" = "custom";
|
||||
|
||||
hyprlock = {
|
||||
enable = true;
|
||||
settings = {
|
||||
background = mkForce [
|
||||
{
|
||||
monitor = "";
|
||||
path = "/run/wallpaper.jpg"; # supports png, jpg, webp (no animations, though)
|
||||
color = mkDefault "rgba(25, 20, 20, 1.0";
|
||||
|
||||
# all these options are taken from hyprland, see https://wiki.hyprland.org/Configuring/Variables/#blur for explanations
|
||||
blur_passes = mkDefault "3"; # 0 disables blurring
|
||||
blur_size = mkDefault "7";
|
||||
noise = "0.0117";
|
||||
contrast = "0.8916";
|
||||
brightness = mkDefault "0.8172";
|
||||
vibrancy = "0.1696";
|
||||
vibrancy_darkness = "0.0";
|
||||
}
|
||||
];
|
||||
label = [
|
||||
# Date display
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
text = "cmd[update:1000] echo -e \"$(LC_TIME=en_US.UTF-8 date +\"%A, %B %d\")\"";
|
||||
color = config.lib.stylix.colors.base06;
|
||||
font_size = "25";
|
||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
||||
position = "0, 350";
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
}
|
||||
# Time display
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
text = "cmd[update:1000] echo \"<span>$(date +\"%I:%M\")</span>\"";
|
||||
color = config.lib.stylix.colors.base06;
|
||||
font_size = "120";
|
||||
font_family = lib.mkDefault "${config.stylix.fonts.monospace.name} Bold";
|
||||
position = "0, 230";
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
}
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
text = "$USER";
|
||||
color = config.lib.stylix.colors.base06;
|
||||
outline_thickness = 2;
|
||||
dots_size = 0.2;
|
||||
dots_spacing = 0.2;
|
||||
dots_center = true;
|
||||
font_size = 18;
|
||||
font_family = lib.mkDefault "${config.stylix.fonts.monospace.name} Bold";
|
||||
position = "0, 0";
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
}
|
||||
# weather
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
text = "cmd[update:30000] waybar-weather --hyprlock";
|
||||
color = config.lib.stylix.colors.base06;
|
||||
font_size = "25";
|
||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
||||
position = "-100, 100";
|
||||
halign = "right";
|
||||
valign = "bottom";
|
||||
}
|
||||
# media
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
text = "cmd[update:1000] waybar-media";
|
||||
color = config.lib.stylix.colors.base06;
|
||||
font_size = "15";
|
||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
||||
position = "100, 100";
|
||||
halign = "left";
|
||||
valign = "bottom";
|
||||
}
|
||||
];
|
||||
# user box
|
||||
shape = [
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
size = "200, 50";
|
||||
color = "rgba(46, 52, 64, .25";
|
||||
rounding = -1;
|
||||
border_size = "0";
|
||||
position = "0, 0";
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
}
|
||||
];
|
||||
input-field = [
|
||||
{
|
||||
size = "200, 50";
|
||||
position = "0, -80";
|
||||
font_family = lib.mkDefault config.stylix.fonts.monospace.name;
|
||||
monitor = cfg.primaryDisplay;
|
||||
dots_center = true;
|
||||
fade_on_empty = true;
|
||||
font_color = config.lib.stylix.colors.base06;
|
||||
inner_color = config.lib.stylix.colors.base03;
|
||||
outer_color = config.lib.stylix.colors.base00;
|
||||
bothlock_color = -1;
|
||||
outline_thickness = 5;
|
||||
placeholder_text = ''<span foreground="#${config.lib.stylix.colors.base00}">Password...</span>'';
|
||||
shadow_passes = 2;
|
||||
}
|
||||
];
|
||||
image = [
|
||||
{
|
||||
monitor = cfg.primaryDisplay;
|
||||
# path = "/tmp/hyprlock-art";
|
||||
reload_cmd = "waybar-media-art";
|
||||
reload_time = 3;
|
||||
size = 150;
|
||||
rounding = 0;
|
||||
position = "100, 150";
|
||||
halign = "left";
|
||||
valign = "bottom";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Wayland configuration
|
||||
wayland.windowManager.hyprland = {
|
||||
enable = true;
|
||||
xwayland.enable = true;
|
||||
systemd = {
|
||||
enable = true;
|
||||
enableXdgAutostart = true;
|
||||
};
|
||||
|
||||
plugins = with pkgs.hyprlandPlugins; [
|
||||
# hyprgrass
|
||||
];
|
||||
|
||||
settings =
|
||||
let
|
||||
useMonitorV2 = (lib.versionAtLeast pkgs.hyprland.version "0.40.0") && (cfg.monitorv2 != [ ]);
|
||||
names =
|
||||
if useMonitorV2 then
|
||||
map (m: m.name) cfg.monitorv2
|
||||
else
|
||||
[
|
||||
cfg.display1.input
|
||||
cfg.display2.input
|
||||
];
|
||||
firstMonitor = builtins.elemAt names 0;
|
||||
secondMonitor = if builtins.length names > 1 then builtins.elemAt names 1 else firstMonitor;
|
||||
in
|
||||
{
|
||||
"$mod" = cfg.modKey;
|
||||
|
||||
# Mouse
|
||||
# mouse_[up|down] - scroll wheel
|
||||
# middle_mouse - 274
|
||||
# thumb_up - 276
|
||||
# thumb_down - 275
|
||||
|
||||
# l -> locked, will also work when an input inhibitor (e.g. a lockscreen) is active.
|
||||
# r -> release, will trigger on release of a key.
|
||||
# e -> repeat, will repeat when held.
|
||||
# n -> non-consuming, key/mouse events will be passed to the active window in addition to triggering the dispatcher.
|
||||
# m -> mouse, see below.
|
||||
# t -> transparent, cannot be shadowed by other binds.
|
||||
# i -> ignore mods, will ignore modifiers.
|
||||
# s -> separate, will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos) above.
|
||||
# d -> has description, will allow you to write a description for your bind.
|
||||
# p -> bypasses the app's requests to inhibit keybinds.
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Binds/
|
||||
# https://wiki.hyprland.org/Configuring/Binds/#mouse-buttons
|
||||
|
||||
bind = [
|
||||
"$mod, Return, exec, ${cfg.defaultApps.terminal.pname}"
|
||||
"$mod, SPACE, exec, ${if cfg.launcher == "wofi" then "wofi --show drun" else "rofi -show drun"}"
|
||||
", xf86Search, exec, ${if cfg.launcher == "wofi" then "wofi --show drun" else "rofi -show drun"}"
|
||||
"$mod, Q, killactive, "
|
||||
"$mod, M, exec, wlogout --protocol layer-shell"
|
||||
"$mod, E, exec, ${cfg.defaultApps.fileExplorer.pname}"
|
||||
"$mod, V, togglefloating, "
|
||||
"$mod, D, exec, ${drawer}"
|
||||
"$mod, P, pseudo, " # dwindle
|
||||
"$mod, S, togglesplit, " # dwindle
|
||||
"$mod SHIFT, Q, exec, hyprlock"
|
||||
"$mod SHIFT, 4, exec, hyprshot -m region --clipboard-only"
|
||||
"$mod, F, fullscreen, 1"
|
||||
"$mod SHIFT, F, fullscreen, 0"
|
||||
"$mod SHIFT, E, exec, smile"
|
||||
|
||||
"$mod, mouse:276, movecurrentworkspacetomonitor, ${firstMonitor}"
|
||||
"$mod, mouse:275, movecurrentworkspacetomonitor, ${secondMonitor}"
|
||||
|
||||
# alt-tab between workspaces on active monitor
|
||||
"$mod, Tab, workspace, m+1"
|
||||
"$mod SHIFT, Tab, workspace, m-1"
|
||||
|
||||
"$mod, h, movefocus, l"
|
||||
"$mod, l, movefocus, r"
|
||||
"$mod, k, movefocus, u"
|
||||
"$mod, j, movefocus, d"
|
||||
|
||||
"$mod, 1, workspace, 1"
|
||||
"$mod, 2, workspace, 2"
|
||||
"$mod, 3, workspace, 3"
|
||||
"$mod, 4, workspace, 4"
|
||||
"$mod, 5, workspace, 5"
|
||||
"$mod, 6, workspace, 6"
|
||||
"$mod, 7, workspace, 7"
|
||||
"$mod, 8, workspace, 8"
|
||||
"$mod, 9, workspace, 9"
|
||||
"$mod, 0, workspace, 10"
|
||||
|
||||
"$mod ALT, 1, movetoworkspace, 1"
|
||||
"$mod ALT, 2, movetoworkspace, 2"
|
||||
"$mod ALT, 3, movetoworkspace, 3"
|
||||
"$mod ALT, 4, movetoworkspace, 4"
|
||||
"$mod ALT, 5, movetoworkspace, 5"
|
||||
"$mod ALT, 6, movetoworkspace, 6"
|
||||
"$mod ALT, 7, movetoworkspace, 7"
|
||||
"$mod ALT, 8, movetoworkspace, 8"
|
||||
"$mod ALT, 9, movetoworkspace, 9"
|
||||
"$mod ALT, 0, movetoworkspace, discord"
|
||||
|
||||
"$mod CTRL, l, resizeactive, 10 0"
|
||||
"$mod CTRL, h, resizeactive, -10 0"
|
||||
"$mod CTRL, k, resizeactive, 0 -10"
|
||||
"$mod CTRL, j, resizeactive, 0 10"
|
||||
|
||||
"$mod SHIFT, l, movewindow, r"
|
||||
"$mod SHIFT, h, movewindow, l"
|
||||
"$mod SHIFT, k, movewindow, u"
|
||||
"$mod SHIFT, j, movewindow, d"
|
||||
|
||||
"$mod, b, exec, ${cfg.defaultApps.browser.pname}"
|
||||
]
|
||||
++ cfg.keybinds.bind;
|
||||
|
||||
bindm = [
|
||||
# Move/resize windows with mod + LMB/RMB and dragging
|
||||
"$mod, mouse:272, movewindow"
|
||||
"$mod, mouse:273, resizewindow"
|
||||
# middle mouse will grab a window, mod + middle mouse will close it
|
||||
"$mod SHIFT, mouse:274, movewindow"
|
||||
]
|
||||
++ cfg.keybinds.bindm;
|
||||
|
||||
bindel = [
|
||||
", XF86AudioRaiseVolume, exec, volumectl -u up"
|
||||
", XF86AudioLowerVolume, exec, volumectl -u down"
|
||||
]
|
||||
++ cfg.keybinds.bindel;
|
||||
|
||||
bindl = [
|
||||
", XF86AudioMute, exec, volumectl toggle-mute"
|
||||
", XF86AudioPlay, exec, playerctl play-pause"
|
||||
", XF86AudioPrev, exec, playerctl previous"
|
||||
", XF86AudioNext, exec, playerctl next"
|
||||
", XF86AudioMicMute, exec, volumectl -m toggle-mute"
|
||||
|
||||
", XF86MonBrightnessUp, exec, lightctl up"
|
||||
", XF86MonBrightnessDown, exec, lightctl down"
|
||||
]
|
||||
++ cfg.keybinds.bindl;
|
||||
|
||||
monitor =
|
||||
cfg.monitor
|
||||
++ map (
|
||||
m:
|
||||
if m.disabled then
|
||||
"${m.name}, disable"
|
||||
else if m.mirrorOf != null then
|
||||
"${m.name}, mirror, ${m.mirrorOf}"
|
||||
else
|
||||
let
|
||||
mode = if m.mode == null then "preferred" else m.mode;
|
||||
position = if m.position == null then "0x0" else m.position;
|
||||
scale = if m.scale == null then "1" else (toString m.scale);
|
||||
parts = [
|
||||
m.name
|
||||
mode
|
||||
position
|
||||
scale
|
||||
];
|
||||
# Append transform only when set, as "transform, <value>"
|
||||
transformTokens =
|
||||
if m.transform == null then
|
||||
[ ]
|
||||
else
|
||||
[
|
||||
"transform"
|
||||
m.transform
|
||||
];
|
||||
tokens = parts ++ transformTokens ++ m.extra;
|
||||
in
|
||||
builtins.concatStringsSep ", " tokens
|
||||
) cfg.monitorv2;
|
||||
|
||||
render = {
|
||||
cm_fs_passthrough = 1;
|
||||
};
|
||||
|
||||
misc = {
|
||||
vrr = if cfg.enableVRR then 1 else 0;
|
||||
force_default_wallpaper = 0;
|
||||
};
|
||||
|
||||
general = {
|
||||
gaps_in = 5;
|
||||
gaps_out = 10;
|
||||
border_size = 1;
|
||||
# "col.active_border" = "rgb(8aadf4) rgb(24273A) rgb(24273A) rgb(8aadf4) 45deg";
|
||||
# "col.inactive_border" = "rgb(24273A) rgb(24273A) rgb(24273A) rgb(24273A) 45deg";
|
||||
layout = "dwindle";
|
||||
allow_tearing = cfg.allowTearing;
|
||||
};
|
||||
|
||||
decoration = {
|
||||
rounding = 10;
|
||||
blur = {
|
||||
enabled = true;
|
||||
size = 2;
|
||||
passes = 2;
|
||||
new_optimizations = true;
|
||||
xray = false;
|
||||
};
|
||||
};
|
||||
|
||||
animations = {
|
||||
enabled = "yes";
|
||||
bezier = [
|
||||
"overshot, 0.05, 0.9, 0.1, 1.05"
|
||||
"smoothOut, 0.36, 0, 0.66, -0.56"
|
||||
"smoothIn, 0.25, 1, 0.5, 1"
|
||||
];
|
||||
animation = [
|
||||
"windows, 1, 5, overshot, slide"
|
||||
"windowsOut, 1, 4, smoothOut, slide"
|
||||
"windowsMove, 1, 4, default"
|
||||
"border, 1, 10, default"
|
||||
"fade, 1, 10, smoothIn"
|
||||
"fadeDim, 1, 10, smoothIn"
|
||||
"workspaces, 1, 6, default"
|
||||
];
|
||||
};
|
||||
|
||||
dwindle = {
|
||||
pseudotile = "yes";
|
||||
preserve_split = "yes";
|
||||
};
|
||||
|
||||
workspace = cfg.workspace;
|
||||
|
||||
windowrule = [
|
||||
"match:title file_progress, float 1"
|
||||
"match:title .*[Cc]onfirm.*, float 1"
|
||||
"match:title .*[Dd]ialog.*, float 1"
|
||||
"match:title .*[Dd]ownload.*, float 1"
|
||||
"match:title .*[Nn]otification.*, float 1"
|
||||
"match:title .*[Ee]rror.*, float 1"
|
||||
"match:title .*[Ss]plash.*, float 1"
|
||||
"match:title .*[Cc]onfirmreset.*, float 1"
|
||||
"match:title .*[Ss]ign [Ii]n - .*, float 1"
|
||||
"match:title .*[Oo]pen [Ff]ile.*, float 1"
|
||||
"match:title .*branchdialog.*, float 1"
|
||||
"match:class .*pavucontrol.*, float 1"
|
||||
"match:class .*pavucontrol.*, move onscreen cursor 0% 0%"
|
||||
"match:class .*[Oo]verskride.*, float 1"
|
||||
"match:class .*FileRoller.*, float 1"
|
||||
"match:class .*wlogout.*, float 1"
|
||||
"match:title .*mpv.*, idle_inhibit stayfocused"
|
||||
|
||||
"match:class .*nm-connection-editor.*, float 1"
|
||||
"match:class .*nm-connection-editor.*, move onscreen cursor 0% 0%"
|
||||
|
||||
"match:title Media viewer, float 1"
|
||||
"match:class it.mijorus.smile),match:title Smile, float 1"
|
||||
"match:class .blueman-manager-wrapped)$,match:title Bluetooth Devices, float 1"
|
||||
# Picture in picture windows
|
||||
"match:title .*Picture-in-Picture.*, float 1"
|
||||
"match:title .*Picture-in-Picture.*, pin 1"
|
||||
|
||||
# discord/vesktop
|
||||
# "workspace: name:discord, match:class .*vesktop"
|
||||
# "match:class .*vesktop),match:title .*Discord Popout.*, float 1"
|
||||
# "pin, match:class .*vesktop),match:title .*Discord Popout.*"
|
||||
|
||||
# Music
|
||||
# "workspace: name:discord, match:class Apple Music.*"
|
||||
|
||||
# Steam
|
||||
"match:class .*[Ss]team, match:title .*[Ss]team.*, float 1"
|
||||
"match:class .*[Ss]team, match:title .*[Ss]team.*, workspace name:steam silent"
|
||||
"match:class .*[Ss]team, match:title .*[Ss]team.*, tile 1"
|
||||
"match:class .*steam,match:title .*Friends List.*, float 1"
|
||||
|
||||
# Code
|
||||
"match:class .*codium.*, match:title Save As, pin 1"
|
||||
"match:class .*codium.*, match:title Save As, float 1"
|
||||
"match:class xdg-desktop-portal-gtk, match:title Open Workspace from File, float 1"
|
||||
|
||||
# Game Tearing??? https://wiki.hypr.land/Configuring/Tearing/
|
||||
"match:class .*gamescope.*, idle_inhibit fullscreen, content game, immediate 1"
|
||||
"match:xdg_tag proton-game, idle_inhibit fullscreen, content game, immediate 1"
|
||||
"match:class steam_app_.*, idle_inhibit fullscreen, content game, immediate 1"
|
||||
|
||||
# vmware
|
||||
# this tag will set the below options to the vdi window
|
||||
# this will have it auto open as a 2160x7680 window
|
||||
# and makes multi-monitor work
|
||||
"match:class .*[Hh]orizon-client, match:title USPS Next VDI, tag +horizonrdp"
|
||||
|
||||
"match:tag horizonrdp, no_anim 1"
|
||||
"match:tag horizonrdp, no_blur 1"
|
||||
"match:tag horizonrdp, rounding 0"
|
||||
"match:tag horizonrdp, no_shadow 1"
|
||||
"match:tag horizonrdp, immediate 1"
|
||||
"match:tag horizonrdp, allows_input 1"
|
||||
"match:tag horizonrdp, border_size 0"
|
||||
"match:tag horizonrdp, max_size 2160 7680"
|
||||
"match:tag horizonrdp, min_size 1920 1080"
|
||||
"match:tag horizonrdp, render_unfocused 1"
|
||||
"match:tag horizonrdp, idle_inhibit 1"
|
||||
"match:tag horizonrdp, float 1"
|
||||
# float the vmware window cause its annoying to use in fullscreen
|
||||
"match:class .*[Hh]orizon-client),match:title [Oo]mnissa [Hh]orizon [Cc]lient, float 1"
|
||||
]
|
||||
++ cfg.windowRule;
|
||||
|
||||
plugin = {
|
||||
# touch_gestures = {
|
||||
# # The default sensitivity is probably too low on tablet screens,
|
||||
# # I recommend turning it up to 4.0
|
||||
# sensitivity = "4.0";
|
||||
|
||||
# # must be >= 3
|
||||
# workspace_swipe_fingers = "3";
|
||||
|
||||
# # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers
|
||||
# # and can be used at the same time
|
||||
# # possible values: l, r, u, or d
|
||||
# # to disable it set it to anything else
|
||||
# workspace_swipe_edge = "d";
|
||||
|
||||
# # in milliseconds
|
||||
# long_press_delay = "400";
|
||||
|
||||
# # resize windows by long-pressing on window borders and gaps.
|
||||
# # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating
|
||||
# # windows
|
||||
# resize_on_border_long_press = true;
|
||||
|
||||
# # in pixels, the distance from the edge that is considered an edge
|
||||
# edge_margin = "10";
|
||||
|
||||
# # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe.
|
||||
# # ONLY triggers when finger count is equal to workspace_swipe_fingers
|
||||
# #
|
||||
# # might be removed in the future in favor of event hooks
|
||||
# emulate_touchpad_swipe = false;
|
||||
|
||||
# experimental = {
|
||||
# # send proper cancel events to windows instead of hacky touch_up events,
|
||||
# # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default
|
||||
# send_cancel = "0";
|
||||
# };
|
||||
|
||||
# hyprgrass-bind = [
|
||||
# # swipe left from right edge
|
||||
# ", edge:r:l, workspace, +1"
|
||||
|
||||
# # swipe up from bottom edge
|
||||
# ", edge:d:u, exec, ${cfg.defaultApps.browser.pname}"
|
||||
|
||||
# # swipe down from left edge
|
||||
# ", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%"
|
||||
|
||||
# # swipe down with 4 fingers
|
||||
# ", swipe:4:d, killactive"
|
||||
|
||||
# # swipe diagonally left and down with 3 fingers
|
||||
# # l (or r) must come before d and u
|
||||
# ", swipe:3:ld, exec, foot"
|
||||
|
||||
# # tap with 3 fingers
|
||||
# ", tap:3, exec, foot"
|
||||
|
||||
# # longpress can trigger mouse binds:
|
||||
# ", longpress:2, movewindow"
|
||||
# ", longpress:3, resizewindow"
|
||||
# ];
|
||||
# };
|
||||
};
|
||||
|
||||
gesture = [
|
||||
"3, horizontal, scale: 0.75, workspace" # swipe 3 fingers to change workspace
|
||||
"3, pinch, mod: SUPER, resize"
|
||||
"4, pinch, fullscreen"
|
||||
];
|
||||
|
||||
input = {
|
||||
kb_layout = "us";
|
||||
|
||||
kb_variant = "";
|
||||
kb_model = "";
|
||||
kb_options = "";
|
||||
kb_rules = "";
|
||||
|
||||
numlock_by_default = true;
|
||||
|
||||
follow_mouse = 1;
|
||||
|
||||
touchpad = {
|
||||
clickfinger_behavior = 1;
|
||||
natural_scroll = "yes";
|
||||
};
|
||||
|
||||
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
|
||||
};
|
||||
|
||||
# experimental = {
|
||||
# xx_color_management_v4 = true;
|
||||
# };
|
||||
|
||||
debug = {
|
||||
# full_cm_proto = cfg.debug.fullCmProto;
|
||||
disable_logs = cfg.debug.disableLogs;
|
||||
disable_scale_checks = cfg.debug.disableScaleChecks;
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig =
|
||||
let
|
||||
autostarts = builtins.concatStringsSep "\n" (map (cmd: "exec-once = ${cmd}") cfg.autostartCommands);
|
||||
in
|
||||
''
|
||||
exec-once = dbus-update-activation-environment --systemd --all
|
||||
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||
exec-once = xhost +SI:localuser:root
|
||||
''
|
||||
+ autostarts
|
||||
+ "\n"
|
||||
+ (cfg.extraConfig or "");
|
||||
};
|
||||
};
|
||||
}
|
||||
330
modules/home/programs/hyprland/options.nix
Normal file
330
modules/home/programs/hyprland/options.nix
Normal file
@@ -0,0 +1,330 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
{
|
||||
options.${namespace}.programs.hyprland = {
|
||||
enable = mkEnableOption "enable hyprland";
|
||||
|
||||
primaryDisplay = mkOption {
|
||||
type = types.str;
|
||||
default = "DP-1";
|
||||
description = "Primary display identifier";
|
||||
};
|
||||
|
||||
display1 = {
|
||||
input = mkOption {
|
||||
type = types.str;
|
||||
default = "DP-1";
|
||||
description = "First display identifier (Deprecated: prefer monitorv2)";
|
||||
};
|
||||
|
||||
resolution = mkOption {
|
||||
type = types.str;
|
||||
default = "3840x2160";
|
||||
description = "First display resolution (Deprecated: prefer monitorv2)";
|
||||
};
|
||||
|
||||
refreshRate = mkOption {
|
||||
type = types.str;
|
||||
default = "240.00000";
|
||||
description = "First display refresh rate (Deprecated: prefer monitorv2)";
|
||||
};
|
||||
};
|
||||
|
||||
display2 = {
|
||||
input = mkOption {
|
||||
type = types.str;
|
||||
default = "DP-1";
|
||||
description = "Second display identifier (Deprecated: prefer monitorv2)";
|
||||
};
|
||||
|
||||
resolution = mkOption {
|
||||
type = types.str;
|
||||
default = "3840x2160";
|
||||
description = "Second display resolution (Deprecated: prefer monitorv2)";
|
||||
};
|
||||
|
||||
refreshRate = mkOption {
|
||||
type = types.str;
|
||||
default = "240.00000";
|
||||
description = "Second display refresh rate (Deprecated: prefer monitorv2)";
|
||||
};
|
||||
};
|
||||
|
||||
# Deprecated: prefer hyprpaper.* options
|
||||
wallpaper = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Deprecated: no longer used; prefer hyprpaper.wallpaperPath and hyprpaper.usePerMonitor.";
|
||||
};
|
||||
|
||||
hyprpaper = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
wallpaperPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/wallpaper.jpg";
|
||||
description = "Path to the wallpaper used by hyprpaper.";
|
||||
};
|
||||
usePerMonitor = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "If true, generate one wallpaper entry per monitor (monitorv2 preferred, falls back to display1/display2).";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Hyprpaper configuration.";
|
||||
};
|
||||
|
||||
monitor = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "List of Hyprland monitor configs (legacy). Example: [ \"eDP-1, 1920x1080@60, 0x0, 1\" ]";
|
||||
};
|
||||
|
||||
monitorv2 = mkOption {
|
||||
type =
|
||||
with types;
|
||||
listOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = "Monitor name (e.g., DP-1, eDP-1).";
|
||||
};
|
||||
mode = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Resolution@Hz or keyword (e.g., \"3840x2160@144\" or \"preferred\").";
|
||||
};
|
||||
position = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Position like \"0x0\" or \"auto\".";
|
||||
};
|
||||
scale = mkOption {
|
||||
type = types.nullOr types.float;
|
||||
default = null;
|
||||
description = "Scale factor (e.g., 1.0).";
|
||||
};
|
||||
transform = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Rotation/transform (e.g., \"normal\", \"90\", \"180\", \"270\", \"flipped\").";
|
||||
};
|
||||
disabled = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Disable this monitor.";
|
||||
};
|
||||
mirrorOf = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Mirror another monitor by name.";
|
||||
};
|
||||
extra = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Additional monitorv2 flags appended as-is.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
description = "Hyprland monitorv2 entries as structured options; rendered to lines like \"name, mode, position, scale, transform, ...\".";
|
||||
};
|
||||
|
||||
workspace = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "List of hyprland workspace definitions";
|
||||
};
|
||||
|
||||
windowRule = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "List of hyprland window rules";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; str;
|
||||
default = "";
|
||||
description = "Any extra configuration options";
|
||||
};
|
||||
|
||||
defaultApps = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
browser = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.firefox;
|
||||
description = "Default browser";
|
||||
};
|
||||
editor = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.micro;
|
||||
description = "Default text editor";
|
||||
};
|
||||
fileExplorer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.nautilus;
|
||||
description = "Default file explorer";
|
||||
};
|
||||
visual = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vscodium;
|
||||
description = "Default visual editor";
|
||||
};
|
||||
terminal = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.kitty;
|
||||
description = "Default terminal";
|
||||
};
|
||||
office = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.onlyoffice-desktopeditors;
|
||||
description = "Default office suite";
|
||||
};
|
||||
video = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vlc;
|
||||
description = "Default video player";
|
||||
};
|
||||
imageViewer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.nomacs;
|
||||
description = "Default image viewer";
|
||||
};
|
||||
};
|
||||
};
|
||||
description = "Default applications used across the system";
|
||||
};
|
||||
|
||||
autostartCommands = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [
|
||||
"nwg-look -a"
|
||||
"nwg-dock-hyprland -x"
|
||||
];
|
||||
description = "Commands to run via Hyprland exec-once";
|
||||
};
|
||||
|
||||
launcher = mkOption {
|
||||
type = types.enum [
|
||||
"wofi"
|
||||
"rofi"
|
||||
];
|
||||
default = "wofi";
|
||||
description = "Application launcher to use in keybinds and packages.";
|
||||
};
|
||||
|
||||
notificationDaemon = mkOption {
|
||||
type = types.enum [
|
||||
"mako"
|
||||
"dunst"
|
||||
];
|
||||
default = "mako";
|
||||
description = "Notification daemon to install.";
|
||||
};
|
||||
|
||||
modKey = mkOption {
|
||||
type = types.str;
|
||||
default = "SUPER";
|
||||
description = "Modifier key used for Hyprland binds (e.g., SUPER, ALT).";
|
||||
};
|
||||
|
||||
enableVRR = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable variable refresh rate (maps to Hyprland misc.vrr).";
|
||||
};
|
||||
|
||||
allowTearing = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Allow tearing (maps to Hyprland general.allow_tearing).";
|
||||
};
|
||||
|
||||
debug = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
disableLogs = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Set Hyprland debug.disable_logs.";
|
||||
};
|
||||
fullCmProto = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Set Hyprland debug.full_cm_proto.";
|
||||
};
|
||||
disableScaleChecks = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Set Hyprland debug.disable_scale_checks.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Hyprland debug flags.";
|
||||
};
|
||||
|
||||
keybinds = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
bind = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Hyprland bind entries.";
|
||||
};
|
||||
bindm = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Hyprland bindm entries.";
|
||||
};
|
||||
bindel = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Hyprland bindel entries.";
|
||||
};
|
||||
bindl = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Hyprland bindl entries.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Keybinding lists for Hyprland; useful for host-level overrides.";
|
||||
};
|
||||
|
||||
gestures = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
description = "Hyprland gesture entries.";
|
||||
};
|
||||
|
||||
hyprIdle = {
|
||||
lockScreenTimer = mkOption {
|
||||
type = with types; int;
|
||||
default = 300;
|
||||
description = "Time in seconds before locking the screen";
|
||||
};
|
||||
screenOffTimer = mkOption {
|
||||
type = with types; int;
|
||||
default = 900;
|
||||
description = "Time in seconds before turning off the screen";
|
||||
};
|
||||
suspendTimer = mkOption {
|
||||
type = with types; int;
|
||||
default = 1800;
|
||||
description = "Time in seconds before suspending";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
{ lib, config, ... }:
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.kitty;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.kitty;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
@@ -12,12 +16,6 @@ in
|
||||
enable = true;
|
||||
shellIntegration.enableZshIntegration = true;
|
||||
|
||||
font = {
|
||||
name = cfg.font.name;
|
||||
package = cfg.font.package;
|
||||
size = cfg.font.size;
|
||||
};
|
||||
|
||||
settings = {
|
||||
bold_font = "auto";
|
||||
italic_font = "auto";
|
||||
@@ -26,80 +24,6 @@ in
|
||||
cursor_shape = "block";
|
||||
url_style = "dotted";
|
||||
confirm_os_window_close = "0";
|
||||
background_opacity = "0.85";
|
||||
|
||||
# The basic colors
|
||||
foreground = nord.snowStorm.nord6;
|
||||
background = nord.polarNight.nord0;
|
||||
selection_foreground = nord.polarNight.nord0;
|
||||
selection_background = nord.aurora.nord15;
|
||||
|
||||
# Cursor colors
|
||||
cursor = nord.aurora.nord15;
|
||||
cursor_text_color = nord.polarNight.nord0;
|
||||
|
||||
# URL underline color when hovering with mouse
|
||||
url_color = nord.aurora.nord15;
|
||||
|
||||
# Kitty window border colors
|
||||
active_border_color = nord.frost.nord10;
|
||||
inactive_border_color = nord.polarNight.nord1;
|
||||
bell_border_color = nord.aurora.nord13;
|
||||
|
||||
# OS Window titlebar colors
|
||||
wayland_titlebar_color = nord.polarNight.nord0;
|
||||
macos_titlebar_color = nord.polarNight.nord0;
|
||||
|
||||
# Tab bar colors
|
||||
active_tab_foreground = nord.polarNight.nord3;
|
||||
active_tab_background = nord.aurora.nord15;
|
||||
inactive_tab_foreground = nord.snowStorm.nord6;
|
||||
inactive_tab_background = nord.polarNight.nord1;
|
||||
tab_bar_background = nord.polarNight.nord3;
|
||||
|
||||
# Colors for marks (marked text in the terminal)
|
||||
mark1_foreground = nord.polarNight.nord0;
|
||||
mark1_background = nord.frost.nord10;
|
||||
mark2_foreground = nord.polarNight.nord0;
|
||||
mark2_background = nord.aurora.nord15;
|
||||
mark3_foreground = nord.polarNight.nord0;
|
||||
mark3_background = nord.frost.nord8;
|
||||
|
||||
# The 16 terminal colors
|
||||
|
||||
# black
|
||||
color0 = nord.polarNight.nord0;
|
||||
|
||||
# Autosuggestion
|
||||
color8 = nord.frost.nord10;
|
||||
|
||||
# red
|
||||
color1 = nord.aurora.nord11;
|
||||
color9 = nord.aurora.nord11;
|
||||
|
||||
# green
|
||||
color2 = nord.aurora.nord14;
|
||||
color10 = nord.aurora.nord14;
|
||||
|
||||
# yellow
|
||||
color3 = nord.aurora.nord13;
|
||||
color11 = nord.aurora.nord13;
|
||||
|
||||
# blue
|
||||
color4 = nord.frost.nord10;
|
||||
color12 = nord.frost.nord10;
|
||||
|
||||
# magenta
|
||||
color5 = nord.aurora.nord15;
|
||||
color13 = nord.aurora.nord15;
|
||||
|
||||
# cyan
|
||||
color6 = nord.frost.nord8;
|
||||
color14 = nord.frost.nord8;
|
||||
|
||||
# white
|
||||
color7 = nord.snowStorm.nord5;
|
||||
color15 = nord.snowStorm.nord4;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.kitty = {
|
||||
options.${namespace}.programs.kitty = {
|
||||
enable = mkEnableOption "enable kitty terminal";
|
||||
|
||||
font = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "DejaVu Sans";
|
||||
};
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.dejavu_fonts;
|
||||
};
|
||||
size = mkOption {
|
||||
type = with types; int;
|
||||
default = 8;
|
||||
};
|
||||
};
|
||||
|
||||
theme = mkOption {
|
||||
type = types.attrs;
|
||||
default = import ../../desktop/theme/nord.nix;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
"browser.newtabpage.activity-stream.topSitesRows" = 3; # Set number of rows for top sites on new tab page
|
||||
"layout.css.light-dark.enabled" = true; # Enable light/dark theme support
|
||||
"extensions.activeThemeID" = "default-theme@mozilla.org"; # Set active theme
|
||||
"extensions.webextensions.uuids" = "{\"formautofill@mozilla.org\" =\"851c83b7-26d5-449c-8cc9-d8951a0ce78d\",\"pictureinpicture@mozilla.org\" =\"42fa2650-5134-4bef-bafa-b73f9ae51bad\",\"screenshots@mozilla.org\" =\"efd2b692-43c4-433a-aea5-0cb79f8312d4\",\"webcompat-reporter@mozilla.org\" =\"c43a6be2-fb56-4253-b384-ce8e09a89999\",\"webcompat@mozilla.org\" =\"e25fd1bb-7c53-413f-9528-bb922c322a56\",\"default-theme@mozilla.org\" =\"610b67c3-9145-46f7-814f-d8ee2cc8edff\",\"addons-search-detection@mozilla.com\:\"caedb3ca-5cf5-4e23-a251-d742f23e6fc8\",\"uBlock0@raymondhill.net\" =\"7e7d9fd9-12bf-42d3-9c7c-9ffd05420ec7\",\"78272b6fa58f4a1abaac99321d503a20@proton.me\" =\"7242a067-06d8-430b-94a3-00d264cdd57b\",\"addon@darkreader.org\" =\"2f02b112-6acd-4bdc-af2c-1432eb527339\",\"jid1-xUfzOsOFlzSOXg@jetpack\" =\"d0c72046-9903-4118-8160-a028840bf928\",\"chrome-gnome-shell@gnome.org\" =\"a1ab53e6-b765-4f25-8349-383cc04682a0\",\"user-agent-switcher@ninetailed.ninja\" =\"259d07cc-bb32-4ed5-b90f-6d73abdeb7bb\",\"firefoxdav@icloud.com\" =\"110e6e2c-18f8-461d-9f26-b8f04482b6f1\",\"ciscowebexstart1@cisco.com\" =\"a4062240-e73a-4353-bddb-d608d84881f7\",\"{a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7}\" =\"9164e437-812b-4a07-8dfd-2fd73b39329b\",\"{036a55b4-5e72-4d05-a06c-cba2dfcc134a}\" =\"648fc678-a6fb-47cd-9792-fb9520678c17\",\"{446900e4-71c2-419f-a6a7-df9c091e268b}\" =\"f0b43422-070e-466e-85c9-6543f209f075\",\"jid1-MnnxcxisBPnSXQ@jetpack\" =\"4c448202-c843-4cae-b5c3-d11f2da58fa3\",\"soundfixer@unrelenting.technology\" =\"59b35eb8-1c85-4919-a905-80d120993ddc\",\"floccus@handmadeideas.org\" =\"8ad2956c-8091-41af-a689-7d2108f5958d\",\"{79b9dbcf-cc5a-4cda-89ef-c4ab097eb074}\" =\"c2a223a7-32e0-4726-9f20-17236702b1f5\",\"linkgopher@oooninja.com\" =\"a257858c-0dce-415b-b123-6222876cf843\"}";
|
||||
"extensions.webextensions.uuids" =
|
||||
"{\"formautofill@mozilla.org\" =\"851c83b7-26d5-449c-8cc9-d8951a0ce78d\",\"pictureinpicture@mozilla.org\" =\"42fa2650-5134-4bef-bafa-b73f9ae51bad\",\"screenshots@mozilla.org\" =\"efd2b692-43c4-433a-aea5-0cb79f8312d4\",\"webcompat-reporter@mozilla.org\" =\"c43a6be2-fb56-4253-b384-ce8e09a89999\",\"webcompat@mozilla.org\" =\"e25fd1bb-7c53-413f-9528-bb922c322a56\",\"default-theme@mozilla.org\" =\"610b67c3-9145-46f7-814f-d8ee2cc8edff\",\"addons-search-detection@mozilla.com\:\"caedb3ca-5cf5-4e23-a251-d742f23e6fc8\",\"uBlock0@raymondhill.net\" =\"7e7d9fd9-12bf-42d3-9c7c-9ffd05420ec7\",\"78272b6fa58f4a1abaac99321d503a20@proton.me\" =\"7242a067-06d8-430b-94a3-00d264cdd57b\",\"addon@darkreader.org\" =\"2f02b112-6acd-4bdc-af2c-1432eb527339\",\"jid1-xUfzOsOFlzSOXg@jetpack\" =\"d0c72046-9903-4118-8160-a028840bf928\",\"chrome-gnome-shell@gnome.org\" =\"a1ab53e6-b765-4f25-8349-383cc04682a0\",\"user-agent-switcher@ninetailed.ninja\" =\"259d07cc-bb32-4ed5-b90f-6d73abdeb7bb\",\"firefoxdav@icloud.com\" =\"110e6e2c-18f8-461d-9f26-b8f04482b6f1\",\"ciscowebexstart1@cisco.com\" =\"a4062240-e73a-4353-bddb-d608d84881f7\",\"{a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7}\" =\"9164e437-812b-4a07-8dfd-2fd73b39329b\",\"{036a55b4-5e72-4d05-a06c-cba2dfcc134a}\" =\"648fc678-a6fb-47cd-9792-fb9520678c17\",\"{446900e4-71c2-419f-a6a7-df9c091e268b}\" =\"f0b43422-070e-466e-85c9-6543f209f075\",\"jid1-MnnxcxisBPnSXQ@jetpack\" =\"4c448202-c843-4cae-b5c3-d11f2da58fa3\",\"soundfixer@unrelenting.technology\" =\"59b35eb8-1c85-4919-a905-80d120993ddc\",\"floccus@handmadeideas.org\" =\"8ad2956c-8091-41af-a689-7d2108f5958d\",\"{79b9dbcf-cc5a-4cda-89ef-c4ab097eb074}\" =\"c2a223a7-32e0-4726-9f20-17236702b1f5\",\"linkgopher@oooninja.com\" =\"a257858c-0dce-415b-b123-6222876cf843\"}";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.mako;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.mako;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
@@ -10,7 +14,7 @@ in
|
||||
services.mako = {
|
||||
enable = true;
|
||||
settings = {
|
||||
font = cfg.fontName;
|
||||
font = mkDefault cfg.fontName;
|
||||
icons = true;
|
||||
ignore-timeout = true;
|
||||
sort = "-time";
|
||||
@@ -22,10 +26,10 @@ in
|
||||
max-icon-size = 64;
|
||||
default-timeout = 5000;
|
||||
|
||||
background-color = nord.polarNight.nord0;
|
||||
text-color = nord.snowStorm.nord6;
|
||||
border-color = nord.frost.nord10;
|
||||
progress-color = "over ${nord.frost.nord8}";
|
||||
# background-color = mkDefault config.lib.stylix.colors.base00;
|
||||
# text-color = mkDefault config.lib.stylix.colors.base06;
|
||||
# border-color = mkDefault config.lib.stylix.colors.base0F;
|
||||
# progress-color = mkDefault "over ${config.lib.stylix.colors.base0C}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.mako = {
|
||||
options.${namespace}.programs.mako = {
|
||||
enable = mkEnableOption "enable mako";
|
||||
|
||||
fontName = mkOption {
|
||||
@@ -9,4 +9,4 @@ with lib;
|
||||
default = "DejaVu Sans";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,56 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.nwg-dock;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.nwg-dock;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = with pkgs; [ nwg-dock-hyprland ];
|
||||
|
||||
|
||||
home.file = {
|
||||
".config/nwg-dock-hyprland/drawer.css".text = ''
|
||||
".config/nwg-dock-hyprland/config.json".text = ''
|
||||
{
|
||||
"position": "bottom",
|
||||
"anchor": "center",
|
||||
"margin": 12,
|
||||
"icon_size": 48,
|
||||
"icon_size_hover": 64,
|
||||
"spacing": 6,
|
||||
"padding": 8,
|
||||
"autohide": false,
|
||||
"autohide_timeout": 0.3,
|
||||
"exclusive": true,
|
||||
"layer": "top",
|
||||
"height": 72,
|
||||
"background_alpha": 0.55,
|
||||
"rounded_corners": 16,
|
||||
"show_labels": false,
|
||||
"show_running": true,
|
||||
"show_pinned": true,
|
||||
"pinned": [
|
||||
"firefox.desktop",
|
||||
"org.wezfurlong.wezterm.desktop",
|
||||
"codium.desktop",
|
||||
"org.gnome.Nautilus.desktop"
|
||||
]
|
||||
}
|
||||
'';
|
||||
|
||||
".config/nwg-dock-hyprland/style.css".text = ''
|
||||
window {
|
||||
background: ${nord.polarNight.nord0};
|
||||
background: #36364f;
|
||||
border-radius: 10px;
|
||||
border-style: none;
|
||||
border-width: 1px;
|
||||
border-color: ${nord.aurora.nord15}b0
|
||||
border-color: rgba(156, 142, 122, 0.7)
|
||||
}
|
||||
|
||||
#box {
|
||||
@@ -25,17 +58,17 @@ in
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
active {
|
||||
#active {
|
||||
/* This is to underline the button representing the currently active window */
|
||||
border-bottom: solid 1px;
|
||||
border-color: ${nord.aurora.nord14}1a
|
||||
border-color: rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
|
||||
button, image {
|
||||
background: none;
|
||||
border-style: none;
|
||||
box-shadow: none;
|
||||
color: ${nord.frost.nord10}
|
||||
color: #999
|
||||
}
|
||||
|
||||
button {
|
||||
@@ -47,7 +80,52 @@ in
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: ${nord.polarNight.nord0}1a;
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
box-shadow: none
|
||||
}
|
||||
'';
|
||||
|
||||
".config/nwg-dock-hyprland/drawer.css".text = ''
|
||||
window {
|
||||
background: ${config.lib.stylix.colors.base00};
|
||||
border-radius: 10px;
|
||||
border-style: none;
|
||||
border-width: 1px;
|
||||
border-color: ${config.lib.stylix.colors.base0E}b0
|
||||
}
|
||||
|
||||
#box {
|
||||
/* Define attributes of the box surrounding icons here */
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
active {
|
||||
/* This is to underline the button representing the currently active window */
|
||||
border-bottom: solid 1px;
|
||||
border-color: ${config.lib.stylix.colors.base0B}1a
|
||||
}
|
||||
|
||||
button, image {
|
||||
background: none;
|
||||
border-style: none;
|
||||
box-shadow: none;
|
||||
color: ${config.lib.stylix.colors.base0F}
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 4px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
color: #eee;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: ${config.lib.stylix.colors.base00}1a;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.nwg-dock = {
|
||||
options.${namespace}.programs.nwg-dock = {
|
||||
enable = mkEnableOption "enable nwg-dock";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,57 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.nwg-drawer;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.nwg-drawer;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = with pkgs; [ nwg-drawer ];
|
||||
|
||||
|
||||
home.file = {
|
||||
".config/nwg-drawer/drawer.css".text = ''
|
||||
window {
|
||||
background-color: ${nord.polarNight.nord0}bf;
|
||||
color: ${nord.snowStorm.nord5}00
|
||||
}
|
||||
".config/nwg-drawer/drawer.css".text = ''
|
||||
window {
|
||||
background-color: ${config.lib.stylix.colors.base00}bf;
|
||||
color: ${config.lib.stylix.colors.base05}00
|
||||
}
|
||||
|
||||
/* search entry */
|
||||
entry {
|
||||
background-color: ${nord.polarNight.nord1}0f
|
||||
}
|
||||
/* search entry */
|
||||
entry {
|
||||
background-color: ${config.lib.stylix.colors.base01}0f
|
||||
}
|
||||
|
||||
button, image {
|
||||
background: none;
|
||||
border: none
|
||||
}
|
||||
button, image {
|
||||
background: none;
|
||||
border: none
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: ${nord.frost.nord10}1a
|
||||
}
|
||||
button:hover {
|
||||
background-color: ${config.lib.stylix.colors.base0F}1a
|
||||
}
|
||||
|
||||
/* in case you wanted to give category buttons a different look */
|
||||
#category-button {
|
||||
margin: 0 10px 0 10px
|
||||
}
|
||||
/* in case you wanted to give category buttons a different look */
|
||||
#category-button {
|
||||
margin: 0 10px 0 10px
|
||||
}
|
||||
|
||||
#pinned-box {
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px dotted ${nord.polarNight.nord3}
|
||||
}
|
||||
#pinned-box {
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px dotted ${config.lib.stylix.colors.base03}
|
||||
}
|
||||
|
||||
#files-box {
|
||||
padding: 5px;
|
||||
border: 1px dotted ${nord.polarNight.nord3};
|
||||
border-radius: 15px
|
||||
}
|
||||
'';
|
||||
#files-box {
|
||||
padding: 5px;
|
||||
border: 1px dotted ${config.lib.stylix.colors.base03};
|
||||
border-radius: 15px
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.nwg-drawer = {
|
||||
options.${namespace}.programs.nwg-drawer = {
|
||||
enable = mkEnableOption "enable nwg-drawer";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.nwg-panel;
|
||||
cfg = config.${namespace}.programs.nwg-panel;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
@@ -12,15 +17,15 @@ in
|
||||
|
||||
'';
|
||||
".config/nwg-panel/preferred-apps.json".text = ''
|
||||
{
|
||||
"\\.pdf$": "${cfg.defaultApps.browser.pname}",
|
||||
"\\.svg$": "inkscape",
|
||||
"\\.(jpg|png|tiff|gif)$": "${cfg.defaultApps.imageViewer.pname}",
|
||||
"\\.(mp3|ogg|flac|wav|wma)$": "audacious",
|
||||
"\\.(avi|mp4|mkv|mov|wav)$": "${cfg.defaultApps.video.pname}",
|
||||
"\\.(doc|docx|xls|xlsx)$": "${cfg.defaultApps.office.pname}"
|
||||
}
|
||||
{
|
||||
"\\.pdf$": "${cfg.defaultApps.browser.pname}",
|
||||
"\\.svg$": "inkscape",
|
||||
"\\.(jpg|png|tiff|gif)$": "${cfg.defaultApps.imageViewer.pname}",
|
||||
"\\.(mp3|ogg|flac|wav|wma)$": "audacious",
|
||||
"\\.(avi|mp4|mkv|mov|wav)$": "${cfg.defaultApps.video.pname}",
|
||||
"\\.(doc|docx|xls|xlsx)$": "${cfg.defaultApps.office.pname}"
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,52 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.nwg-panel = {
|
||||
options.${namespace}.programs.nwg-panel = {
|
||||
enable = mkEnableOption "enable nwg-panel";
|
||||
|
||||
defaultApps = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
browser = mkOption { type = types.package; default = pkgs.firefox; };
|
||||
editor = mkOption { type = types.package; default = pkgs.micro; };
|
||||
fileExplorer = mkOption { type = types.package; default = pkgs.nemo; };
|
||||
visual = mkOption { type = types.package; default = pkgs.vscodium; };
|
||||
terminal = mkOption { type = types.package; default = pkgs.kitty; };
|
||||
office = mkOption { type = types.package; default = pkgs.onlyoffice-bin_latest; };
|
||||
video = mkOption { type = types.package; default = pkgs.vlc; };
|
||||
imageViewer = mkOption { type = types.package; default = pkgs.gnome-photos; };
|
||||
browser = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.firefox;
|
||||
};
|
||||
editor = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.micro;
|
||||
};
|
||||
fileExplorer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.nautilus;
|
||||
};
|
||||
visual = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vscodium;
|
||||
};
|
||||
terminal = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.kitty;
|
||||
};
|
||||
office = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.onlyoffice-desktopeditors;
|
||||
};
|
||||
video = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vlc;
|
||||
};
|
||||
imageViewer = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.gnome-photos;
|
||||
};
|
||||
};
|
||||
};
|
||||
description = "Default applications used across the system.";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
{ lib, system, ... }:
|
||||
{
|
||||
lib,
|
||||
system,
|
||||
hasDestopEnvironment ? true,
|
||||
...
|
||||
}:
|
||||
let
|
||||
isArm = builtins.match "aarch64*" system != null;
|
||||
isArm = "aarch64-linux" == system;
|
||||
in
|
||||
{
|
||||
programs.onlyoffice = {
|
||||
enable = lib.mkDefault (!isArm);
|
||||
enable = lib.mkDefault (!isArm && hasDestopEnvironment);
|
||||
settings = {
|
||||
UITheme = "theme-contrast-dark";
|
||||
forcedRtl = false;
|
||||
maximized = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
290
modules/home/programs/update-checker/default.nix
Normal file
290
modules/home/programs/update-checker/default.nix
Normal file
@@ -0,0 +1,290 @@
|
||||
{
|
||||
config,
|
||||
namespace,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
git-token = config.sops.secrets."github-token".path;
|
||||
|
||||
update-checker = pkgs.writeScriptBin "update-checker" ''
|
||||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i python3 --pure
|
||||
#! nix-shell -p python3 python3Packages.pygithub python3Packages.feedparser python3Packages.requests nix-prefetch-scripts nix
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
from github import Github
|
||||
from github import Auth
|
||||
import feedparser
|
||||
import requests
|
||||
|
||||
token = None
|
||||
|
||||
with open('${git-token}', 'r') as token_file:
|
||||
token = token_file.readline()
|
||||
|
||||
auth = Auth.Token(token)
|
||||
|
||||
def check_github(owner, repo, version):
|
||||
try:
|
||||
release = None
|
||||
result = None
|
||||
prefetch = None
|
||||
ghub = Github(auth=auth)
|
||||
print(' getting repo ' + owner + '/' + repo)
|
||||
repo = ghub.get_repo(owner + '/' + repo)
|
||||
if '-b' in version:
|
||||
release = repo.get_releases()[0]
|
||||
latest_version = release.name
|
||||
else:
|
||||
try:
|
||||
release = repo.get_latest_release()
|
||||
latest_version = release.tag_name
|
||||
except:
|
||||
tags = repo.get_tags()
|
||||
try:
|
||||
if tags is not None:
|
||||
latest_version = tags[0].name
|
||||
except:
|
||||
commits = repo.get_commits()
|
||||
latest_version = commits[0].sha
|
||||
|
||||
if latest_version is not None:
|
||||
|
||||
if latest_version.replace('v',''\'') != version.replace('v',''\''):
|
||||
print(' update found')
|
||||
print(' Current version: ' + version)
|
||||
print(' Latest version: ' + latest_version)
|
||||
result = subprocess.check_output(['nix-prefetch-git', '--quiet', repo.clone_url, '--rev', latest_version])
|
||||
prefetch = json.loads(result)
|
||||
print(' New hash: ' + prefetch.get('hash'))
|
||||
else:
|
||||
print(' no update')
|
||||
ghub.close()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def check_codeberg(owner, repo, version):
|
||||
feed = feedparser.parse('https://codeberg.org/{0}/{1}/releases.rss'.format(owner, repo))
|
||||
if feed.status == 200:
|
||||
entry = feed.entries[0]
|
||||
if entry.title.replace('v',''\'') != version.replace('v',''\''):
|
||||
print(' update found')
|
||||
print(' Current version: ' + version)
|
||||
print(' Latest version: ' + entry.title)
|
||||
sha256 = subprocess.check_output(['nix-prefetch-url', url.replace(''\'''\${version}', entry.title.replace('v', ''\''))])
|
||||
prefetch = subprocess.check_output(['nix', 'hash', 'convert', '--hash-algo', 'sha256', str(sha256.decode('utf-8').strip())])
|
||||
print(' New hash: ' + prefetch.decode('utf-8').strip())
|
||||
else:
|
||||
print(' no update')
|
||||
|
||||
def check_open_vsx(publisher, name, version):
|
||||
open_vsx = requests.get('https://open-vsx.org/api/' + publisher + '/' + name)
|
||||
if open_vsx.status_code == 200:
|
||||
extension = open_vsx.json()
|
||||
latest_version = extension.get('version')
|
||||
url = extension.get('files').get('download')
|
||||
if latest_version.replace('v',''\'') != version.replace('v',''\''):
|
||||
print(' update found')
|
||||
print(' Current version: ' + version)
|
||||
print(' Latest version: ' + latest_version)
|
||||
sha256 = subprocess.check_output(['nix-prefetch-url', url])
|
||||
prefetch = subprocess.check_output(['nix', 'hash', 'convert', '--hash-algo', 'sha256', str(sha256.decode('utf-8').strip())])
|
||||
print(' New hash: ' + prefetch.decode('utf-8').strip())
|
||||
else:
|
||||
print(' no update')
|
||||
|
||||
def parse_nix(package_spec):
|
||||
version = None
|
||||
url = None
|
||||
current_hash = None
|
||||
owner = None
|
||||
repo = None
|
||||
pname = None
|
||||
name = None
|
||||
publisher = None
|
||||
for line in package_spec.readlines():
|
||||
if 'owner = "' in line and owner is None:
|
||||
owner = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'repo = "' in line and repo is None:
|
||||
repo = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'version = "' in line and version is None:
|
||||
version = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'rev = "' in line and ''\'''\${version}' not in line:
|
||||
version = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'url = "' in line and url is None:
|
||||
url = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'sha256 = "' in line or ' hash = "' in line and current_hash is None:
|
||||
current_hash = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'pname = "' in line and pname is None:
|
||||
pname = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if ' name = "' in line and name is None:
|
||||
name = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
if 'publisher = "' in line and publisher is None:
|
||||
publisher = line.split(' = ')[-1].replace('"', ''\'').replace(';\n', ''\'')
|
||||
|
||||
if url is None and repo is not None:
|
||||
if 'pname' in repo:
|
||||
repo = repo.replace(''\'''\${pname}', pname)
|
||||
url = 'https://github.com/{0}/{1}/releases/tag/{2}'.format(owner, repo, version)
|
||||
|
||||
if url is not None and repo is None and 'github' in url:
|
||||
owner = url.split('github.com/')[-1].split('/')[0]
|
||||
repo = url.split('github.com/')[-1].split('/')[1]
|
||||
|
||||
if url is not None and repo is None and 'codeberg' in url:
|
||||
owner = url.split('codeberg.org/')[-1].split('/')[0]
|
||||
repo = url.split('codeberg.org/')[-1].split('/')[1]
|
||||
|
||||
if url is not None and version is None:
|
||||
version = url.split('/')[-1].replace('.tar.gz', ''\'')
|
||||
|
||||
if url is not None and publisher is not None:
|
||||
url = url.replace(''\'''\${publisher}', publisher).replace(''\'''\${name}', name)
|
||||
|
||||
return url, current_hash, owner, repo, pname, name, publisher, version
|
||||
|
||||
def parse_json(json_versions, flavor=''\''):
|
||||
versions = json.load(json_versions)
|
||||
linux_versions = versions.get('linux')
|
||||
config_versions = versions.get('config')
|
||||
patch_versions = versions.get('patches')
|
||||
zfs_versions = versions.get('zfs')
|
||||
|
||||
check_kernel(linux_versions, flavor)
|
||||
check_cachy_config(config_versions, flavor)
|
||||
check_patch_versions(patch_versions, flavor)
|
||||
check_zfs_versions(zfs_versions, flavor)
|
||||
|
||||
def check_kernel(linux_versions, flavor=''\''):
|
||||
srcinfo = requests.get('https://raw.githubusercontent.com/CachyOS/linux-cachyos/master/linux-cachyos' + flavor + '/.SRCINFO')
|
||||
for line in srcinfo.text.split('\n'):
|
||||
if 'pkgver = ' in line:
|
||||
kernel_version = line.split('=')[-1].strip()
|
||||
if kernel_version[-2:] == '.0':
|
||||
kernel_version = kernel_version[:-2]
|
||||
if flavor in [''\'', '-lts', '-server', '-gcc', '-hardened']:
|
||||
release_src = 'https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-' + kernel_version + '.tar.xz'
|
||||
if flavor == '-rc':
|
||||
release_src = 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/snapshot/linux-' + kernel_version.replace('.rc', '-rc') + '.tar.gz'
|
||||
sha256 = subprocess.check_output(['nix-prefetch-url', release_src])
|
||||
prefetch = subprocess.check_output(['nix', 'hash', 'convert', '--hash-algo', 'sha256', str(sha256.decode('utf-8').strip())])
|
||||
current_version = linux_versions.get('version')
|
||||
current_hash = linux_versions.get('hash')
|
||||
latest_hash = prefetch.decode('utf-8').strip()
|
||||
print(' Checking linux versions...')
|
||||
if current_hash != latest_hash:
|
||||
print(' Current rev: ' + current_version)
|
||||
print(' Current hash: ' + current_hash)
|
||||
print(' New rev: ' + kernel_version)
|
||||
print(' New hash: ' + latest_hash)
|
||||
else:
|
||||
print(' no update')
|
||||
|
||||
def check_cachy_config(config_versions, flavor=''\''):
|
||||
result = subprocess.check_output(['nix-prefetch-git', '--quiet', 'https://github.com/CachyOS/linux-cachyos.git'])
|
||||
prefetch = json.loads(result)
|
||||
current_version = config_versions.get('rev')
|
||||
latest_version = prefetch.get('rev')
|
||||
print(' Checking config versions...')
|
||||
if current_version != latest_version:
|
||||
print(' Current rev: ' + current_version)
|
||||
print(' New rev: ' + latest_version)
|
||||
print(' New hash: ' + prefetch.get('hash'))
|
||||
else:
|
||||
print(' no update')
|
||||
|
||||
def check_patch_versions(patch_versions, flavor=''\''):
|
||||
result = subprocess.check_output(['nix-prefetch-git', '--quiet', 'https://github.com/CachyOS/kernel-patches.git'])
|
||||
prefetch = json.loads(result)
|
||||
current_version = patch_versions.get('rev')
|
||||
latest_version = prefetch.get('rev')
|
||||
print(' Checking patch versions...')
|
||||
if current_version != latest_version:
|
||||
print(' Current rev: ' + current_version)
|
||||
print(' New rev: ' + latest_version)
|
||||
print(' New hash: ' + prefetch.get('hash'))
|
||||
else:
|
||||
print(' no update')
|
||||
|
||||
def kconfig_to_nix(flavor=''\''):
|
||||
kconfig_result = subprocess.check_output(['nix', 'build', '.#nixosConfigurations.jallen-nas.pkgs.linuxPackages_cachyos' + flavor + '.kernel.kconfigToNix', '--no-link', '--print-out-paths'])
|
||||
config_file = kconfig_result.decode('utf-8').strip()
|
||||
if flavor == ''\'':
|
||||
cachy_flavor = '-gcc'
|
||||
result = subprocess.check_output(['cat', config_file])
|
||||
with open('/etc/nixos/packages/linux-cachyos/config-nix/cachyos' + cachy_flavor + '.x86_64-linux.nix', 'w') as config:
|
||||
config.write(result.decode('utf-8').strip())
|
||||
|
||||
def check_zfs_versions(zfs_versions, flavor=''\''):
|
||||
result = requests.get('https://raw.githubusercontent.com/CachyOS/linux-cachyos/master/linux-cachyos' + flavor + '/PKGBUILD')
|
||||
for line in result.text.split('\n'):
|
||||
if 'git+https://github.com/cachyos/zfs.git#commit=' in line:
|
||||
zfs_rev = line.split('zfs.git#commit=')[-1].replace('")', ''\'')
|
||||
result = subprocess.check_output(['nix-prefetch-git', '--quiet', 'https://github.com/CachyOS/zfs.git', '--rev', zfs_rev])
|
||||
prefetch = json.loads(result)
|
||||
current_version = zfs_versions.get('rev')
|
||||
latest_version = prefetch.get('rev')
|
||||
print(' Checking zfs versions...')
|
||||
if current_version != latest_version:
|
||||
print(' Current rev: ' + current_version)
|
||||
print(' New rev: ' + latest_version)
|
||||
print(' New hash: ' + prefetch.get('hash'))
|
||||
else:
|
||||
print(' no update')
|
||||
|
||||
for (root,dirs,files) in os.walk('/etc/nixos/packages',topdown=True):
|
||||
if 'default.nix' in files and 'versions.json' not in files:
|
||||
print(root.split('/')[-1])
|
||||
with open(root + '/default.nix', 'r') as package_spec:
|
||||
url, current_hash, owner, repo, pname, name, publisher, version = parse_nix(package_spec)
|
||||
|
||||
if owner is not None and repo is not None and 'codeberg' in url:
|
||||
check_codeberg(owner, repo, version)
|
||||
|
||||
elif owner is not None and repo is not None and 'github' in url:
|
||||
check_github(owner, repo, version)
|
||||
|
||||
elif publisher is not None and 'open-vsx' in url:
|
||||
check_open_vsx(publisher, name, version)
|
||||
|
||||
else:
|
||||
if url is not None:
|
||||
print(url)
|
||||
|
||||
if 'default.nix' in files and 'versions.json' in files:
|
||||
with open(root + '/versions.json', 'r') as json_versions:
|
||||
print('Checking Linux CachyOS')
|
||||
parse_json(json_versions)
|
||||
with open(root + '/versions-rc.json', 'r') as json_versions:
|
||||
print('Checking Linux CachyOS RC')
|
||||
parse_json(json_versions, '-rc')
|
||||
with open(root + '/versions-lts.json', 'r') as json_versions:
|
||||
print('Checking Linux CachyOS LTS')
|
||||
parse_json(json_versions, '-lts')
|
||||
with open(root + '/versions-hardened.json', 'r') as json_versions:
|
||||
print('Checking Linux CachyOS Hardened')
|
||||
parse_json(json_versions, '-hardened')
|
||||
'';
|
||||
in
|
||||
{
|
||||
config = {
|
||||
|
||||
sops = {
|
||||
age.keyFile = "/home/${config.${namespace}.user.name}/.config/sops/age/keys.txt";
|
||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||
validateSopsFiles = false;
|
||||
secrets = {
|
||||
"github-token" = { };
|
||||
};
|
||||
templates = {
|
||||
".env".content = ''
|
||||
GITHUB_TOKEN = "${config.sops.placeholder.github-token}"
|
||||
'';
|
||||
};
|
||||
};
|
||||
home.packages = [ update-checker ];
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,32 +1,333 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
let
|
||||
inherit (types)
|
||||
str
|
||||
int
|
||||
bool
|
||||
listOf
|
||||
attrs
|
||||
path
|
||||
nullOr
|
||||
submodule
|
||||
;
|
||||
in
|
||||
{
|
||||
options.mjallen.programs.waybar = {
|
||||
enable = mkEnableOption "enable waybar";
|
||||
options.${namespace}.programs.waybar = {
|
||||
enable = mkEnableOption "Waybar status bar";
|
||||
|
||||
# Legacy/compat options (kept for backwards compatibility)
|
||||
layer = mkOption {
|
||||
type = types.str;
|
||||
type = str;
|
||||
default = "top";
|
||||
};
|
||||
|
||||
modules-right = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
};
|
||||
|
||||
networkInterface = mkOption {
|
||||
type = types.str;
|
||||
default = "wlan0";
|
||||
description = "Waybar layer (compat). Prefer layout + feature flags.";
|
||||
};
|
||||
|
||||
extraModules = mkOption {
|
||||
type = types.attrs;
|
||||
type = attrs;
|
||||
default = { };
|
||||
description = "Extra settings bars at top-level (compat with older module).";
|
||||
};
|
||||
|
||||
extraModulesStyle = mkOption {
|
||||
type = types.str;
|
||||
type = str;
|
||||
default = "";
|
||||
description = "Extra CSS appended (compat). Prefer extra.style.";
|
||||
};
|
||||
|
||||
windowOffset = mkOption {
|
||||
type = int;
|
||||
default = 4;
|
||||
description = "Right margin offset for the hyprland/window module (in rem).";
|
||||
};
|
||||
|
||||
# Layout
|
||||
layout = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
left = mkOption {
|
||||
type = listOf str;
|
||||
default = [ "hyprland/workspaces" ];
|
||||
description = "Modules shown on the left.";
|
||||
};
|
||||
center = mkOption {
|
||||
type = listOf str;
|
||||
default = [ "hyprland/window" ];
|
||||
description = "Modules shown in the center.";
|
||||
};
|
||||
right = mkOption {
|
||||
type = listOf str;
|
||||
default = [
|
||||
"tray"
|
||||
"custom/left-end"
|
||||
"temperature"
|
||||
"temperature#gpu"
|
||||
"keyboard-state#capslock"
|
||||
"keyboard-state#numlock"
|
||||
"wireplumber#sink"
|
||||
"bluetooth"
|
||||
"network"
|
||||
"idle_inhibitor"
|
||||
"custom/right-end"
|
||||
"custom/left-end"
|
||||
"clock"
|
||||
"battery"
|
||||
"custom/notifications"
|
||||
"custom/weather"
|
||||
"custom/power"
|
||||
"custom/right-end"
|
||||
];
|
||||
description = "Modules shown on the right.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Waybar module layout.";
|
||||
};
|
||||
|
||||
# Network
|
||||
network = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
interface = mkOption {
|
||||
type = str;
|
||||
default = "wlan0";
|
||||
description = "Primary network interface name.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Network configuration.";
|
||||
};
|
||||
|
||||
# Temperatures
|
||||
temperature = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
cpu = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = "Enable CPU temperature module.";
|
||||
};
|
||||
hwmonPath = mkOption {
|
||||
type = str;
|
||||
default = "/sys/devices/pci0000:00/0000:00:18.3/hwmon";
|
||||
description = "CPU temperature hwmon path.";
|
||||
};
|
||||
hwmonFile = mkOption {
|
||||
type = str;
|
||||
default = "temp1_input";
|
||||
description = "CPU temperature hwmon file.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
gpu = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = "Enable GPU temperature module.";
|
||||
};
|
||||
hwmonPath = mkOption {
|
||||
type = str;
|
||||
default = "/sys/devices/pci0000:00/0000:00:01.1/0000:01:00.0/0000:02:00.0/0000:03:00.0/hwmon";
|
||||
description = "GPU temperature hwmon path.";
|
||||
};
|
||||
hwmonFile = mkOption {
|
||||
type = str;
|
||||
default = "temp1_input";
|
||||
description = "GPU temperature hwmon file.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Temperature module configuration.";
|
||||
};
|
||||
|
||||
# Features
|
||||
features = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
tray = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
bluetooth = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
idleInhibitor = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
keyboardIndicators = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
audio = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
sink = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
source = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
weather = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
hass = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
clock = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
battery = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Toggle optional Waybar features.";
|
||||
};
|
||||
|
||||
# Styling
|
||||
style = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
file = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
description = "Optional external CSS file to use instead of the inline style.";
|
||||
};
|
||||
fragmentsDir = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
description = "Optional directory of CSS fragments to append.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Styling configuration.";
|
||||
};
|
||||
|
||||
# Extra overrides
|
||||
extra = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
settings = mkOption {
|
||||
type = attrs;
|
||||
default = { };
|
||||
description = "Extra settings merged into settings.mainBar.";
|
||||
};
|
||||
style = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = "Extra CSS appended to the computed style.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Extra settings/style hooks.";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
40
modules/home/programs/waybar/scripts/audio-control.nix
Normal file
40
modules/home/programs/waybar/scripts/audio-control.nix
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.programs.waybar;
|
||||
|
||||
waybar-audio = pkgs.writeScriptBin "waybar-audio" ''
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Extract sink entries: "ID Description"
|
||||
choices=$(pw-dump | jq -r '
|
||||
.. | objects
|
||||
| select(.["media.class"] == "Audio/Sink")
|
||||
| "\(.["object.id"]) \(.["node.description"])"
|
||||
'
|
||||
)
|
||||
|
||||
# Show wofi menu
|
||||
selected=$(printf "%s\n" "$choices" | wofi --dmenu --prompt "Audio Output")
|
||||
|
||||
# Extract ID
|
||||
id=$(echo "$selected" | awk '{print $1}')
|
||||
|
||||
# Switch to the selected device
|
||||
if [ -n "$id" ]; then
|
||||
wpctl set-default "$id"
|
||||
fi
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [ ../options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ waybar-audio ];
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,18 @@
|
||||
{ config, lib, namespace, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.mjallen.programs.waybar;
|
||||
cfg = config.${namespace}.programs.waybar;
|
||||
|
||||
pythonEnv = pkgs.python3.withPackages (ps: [
|
||||
pkgs.${namespace}.homeassistant-api
|
||||
]);
|
||||
pythonEnv = pkgs.python3.withPackages (
|
||||
_ps: with pkgs.${namespace}; [
|
||||
homeassistant-api
|
||||
]
|
||||
);
|
||||
|
||||
waybar-hass = pkgs.writeScriptBin "waybar-hass" ''
|
||||
#!${pythonEnv}/bin/python
|
||||
|
||||
61
modules/home/programs/waybar/scripts/media.nix
Normal file
61
modules/home/programs/waybar/scripts/media.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.programs.waybar;
|
||||
|
||||
waybar-media = pkgs.writeScriptBin "waybar-media" ''
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Get current playing song from playerctl
|
||||
if command -v playerctl &> /dev/null; then
|
||||
# Check if any player is running
|
||||
if playerctl status &> /dev/null; then
|
||||
artist=$(playerctl metadata xesam:artist 2>/dev/null)
|
||||
title=$(playerctl metadata xesam:title 2>/dev/null)
|
||||
|
||||
if [[ -n "$artist" && -n "$title" ]]; then
|
||||
echo "♪ $artist - $title"
|
||||
elif [[ -n "$title" ]]; then
|
||||
echo "♪ ''\${title//&/&}"
|
||||
else
|
||||
echo "♪ Music Playing"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
'';
|
||||
|
||||
waybar-media-art = pkgs.writeScriptBin "waybar-media-art" ''
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Get current playing song from playerctl
|
||||
if command -v playerctl &> /dev/null; then
|
||||
# Check if any player is running
|
||||
if playerctl status &> /dev/null; then
|
||||
art=$(playerctl metadata mpris:artUrl 2>/dev/null)
|
||||
|
||||
if [[ -n "$art" ]]; then
|
||||
echo ''\${art#file://}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [ ../options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
waybar-media
|
||||
waybar-media-art
|
||||
];
|
||||
};
|
||||
}
|
||||
95
modules/home/programs/waybar/scripts/notifications.nix
Normal file
95
modules/home/programs/waybar/scripts/notifications.nix
Normal file
@@ -0,0 +1,95 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.programs.waybar;
|
||||
|
||||
waybar-notifications = pkgs.writeScriptBin "waybar-notifications" ''
|
||||
#!/usr/bin/env python
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import codecs
|
||||
import re
|
||||
|
||||
def check_notifications(args = "history"):
|
||||
notifications = []
|
||||
number = None
|
||||
content = None
|
||||
appname = None
|
||||
urgency = None
|
||||
cmd = "makoctl"
|
||||
temp = subprocess.Popen([cmd, args], stdout = subprocess.PIPE)
|
||||
output = str(temp.communicate()).replace("(b\'", "").replace("\', None)", "")
|
||||
lines = output.split("\\n")
|
||||
for line in lines:
|
||||
if "Notification" in line:
|
||||
number = line.split(":")[0].replace("Notification ", "")
|
||||
content = re.sub(r"[\u2066\u2067\u2068\u2069, \u00e2\u0081\u00a8]", "", codecs.decode(line.split(": ")[-1].encode("latin1").decode("utf-8"), "unicode_escape"))
|
||||
content = re.sub(r"[\u00a9]", " ", content)
|
||||
|
||||
if "App name" in line:
|
||||
appname = line.split(": ")[-1]
|
||||
if "Urgency" in line:
|
||||
urgency = line.split(": ")[-1]
|
||||
|
||||
if number is not None and content is not None and appname is not None and urgency is not None:
|
||||
notifications.append((number, content, appname, urgency))
|
||||
number = None
|
||||
content = None
|
||||
appname = None
|
||||
urgency = None
|
||||
|
||||
return notifications
|
||||
|
||||
def get_icon(notifications):
|
||||
status = ""
|
||||
icon = ""
|
||||
|
||||
for number, content, appname, urgency in notifications:
|
||||
status = "notify"
|
||||
if urgency != "normal":
|
||||
status = "alert"
|
||||
break
|
||||
|
||||
if status == "notify":
|
||||
icon = ""
|
||||
if status == "alert":
|
||||
icon = ""
|
||||
|
||||
return icon, status
|
||||
|
||||
def build_tooltip(notifications):
|
||||
tooltip = ""
|
||||
for number, content, appname, urgency in notifications:
|
||||
tooltip += "{0}: {1}\n".format(appname, content)
|
||||
|
||||
return tooltip
|
||||
|
||||
def main():
|
||||
notifications = check_notifications()
|
||||
data = {}
|
||||
|
||||
icon, status = get_icon(notifications)
|
||||
|
||||
data["text"] = icon
|
||||
data["tooltip"] = build_tooltip(notifications)
|
||||
data["class"] = status
|
||||
|
||||
print(json.dumps(data, ensure_ascii=False))
|
||||
|
||||
main()
|
||||
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [ ../options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ waybar-notifications ];
|
||||
};
|
||||
}
|
||||
@@ -1,20 +1,34 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.mjallen.programs.waybar;
|
||||
cfg = config.${namespace}.programs.waybar;
|
||||
|
||||
waybar-weather = pkgs.writeScriptBin "waybar-weather" ''
|
||||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i python3 --pure
|
||||
#! nix-shell -p python3 python3Packages.requests
|
||||
|
||||
"""get waybar weather"""
|
||||
import os
|
||||
import json
|
||||
import shutil
|
||||
from datetime import datetime, timedelta
|
||||
import argparse
|
||||
import math
|
||||
|
||||
import requests
|
||||
|
||||
parser = argparse.ArgumentParser(prog='waybar-weather')
|
||||
parser.add_argument('--waybar', action='store_true')
|
||||
parser.add_argument('--hyprlock', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
# --- MAPPINGS ---
|
||||
|
||||
WWO_CODE = {
|
||||
"113": "Sunny",
|
||||
"116": "PartlyCloudy",
|
||||
@@ -66,6 +80,38 @@ let
|
||||
"395": "HeavySnowShowers",
|
||||
}
|
||||
|
||||
# Maps WMO codes (OpenMeteo) to WWO codes (wttr.in)
|
||||
WMO_TO_WWO = {
|
||||
0: "113", # Clear sky -> Sunny
|
||||
1: "113", # Mainly clear -> Sunny
|
||||
2: "116", # Partly cloudy
|
||||
3: "122", # Overcast -> VeryCloudy
|
||||
45: "143", # Fog
|
||||
48: "248", # Depositing rime fog
|
||||
51: "266", # Drizzle: Light
|
||||
53: "266", # Drizzle: Moderate (mapped to LightRain)
|
||||
55: "296", # Drizzle: Dense intensity (LightRain usually suits better than heavy)
|
||||
56: "281", # Freezing Drizzle: Light
|
||||
57: "284", # Freezing Drizzle: Dense
|
||||
61: "296", # Rain: Slight
|
||||
63: "302", # Rain: Moderate
|
||||
65: "308", # Rain: Heavy
|
||||
66: "311", # Freezing Rain: Light
|
||||
67: "314", # Freezing Rain: Heavy
|
||||
71: "326", # Snow fall: Slight
|
||||
73: "332", # Snow fall: Moderate
|
||||
75: "338", # Snow fall: Heavy
|
||||
77: "350", # Snow grains
|
||||
80: "353", # Rain showers: Slight
|
||||
81: "356", # Rain showers: Moderate
|
||||
82: "359", # Rain showers: Violent
|
||||
85: "368", # Snow showers: Slight
|
||||
86: "371", # Snow showers: Heavy
|
||||
95: "386", # Thunderstorm: Slight or moderate
|
||||
96: "389", # Thunderstorm with slight hail
|
||||
99: "395", # Thunderstorm with heavy hail
|
||||
}
|
||||
|
||||
WEATHER_SYMBOL = {
|
||||
"Unknown": "",
|
||||
"Cloudy": "",
|
||||
@@ -93,18 +139,18 @@ let
|
||||
WIND_DIRECTION = {
|
||||
"S": "↓",
|
||||
"SW": "↙",
|
||||
"SSW": "↙",
|
||||
"W": "←",
|
||||
"NW": "↖",
|
||||
"NNW": "↖",
|
||||
"N": "↑",
|
||||
"NE": "↗",
|
||||
"NNE": "↗",
|
||||
"E": "→",
|
||||
"SE": "↘",
|
||||
"SSE": "↘",
|
||||
}
|
||||
|
||||
MOON_PHASES = (
|
||||
"", "", "", "", "", "", "", ""
|
||||
)
|
||||
|
||||
WEATHER_SYMBOL_WI_DAY = {
|
||||
"Unknown": "",
|
||||
"Cloudy": "",
|
||||
@@ -181,117 +227,117 @@ let
|
||||
' '],
|
||||
"VeryCloudy": [
|
||||
' ',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> .--. </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> .-( ). </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> (___.__)__) </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> .--. </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> .-( ). </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> (___.__)__) </span>',
|
||||
' '],
|
||||
"LightShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>'],
|
||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>',
|
||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>'],
|
||||
"HeavyShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\"; font-weight: bold;">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\"; font-weight: bold;">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\"; font-weight: bold;">(___(__) </span>',
|
||||
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚‘‚‘‚‘‚‘ </span>',
|
||||
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚’‚’‚’‚’ </span>'],
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\" font-weight="bold">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\" font-weight="bold">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\" font-weight="bold">(___(__) </span>',
|
||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚‘‚‘‚‘‚‘ </span>',
|
||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚’‚’‚’‚’ </span>'],
|
||||
"LightSnowShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\";"> * * * </span>',
|
||||
'<span foreground=\"#eeeeee\";"> * * * </span>'],
|
||||
'<span foreground=\"#eeeeee\"> * * * </span>',
|
||||
'<span foreground=\"#eeeeee\"> * * * </span>'],
|
||||
"HeavySnowShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\"; font-weight: bold;">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\"; font-weight: bold;">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\"; font-weight: bold;">(___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>',
|
||||
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>'],
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\" font-weight="bold">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#585858\" font-weight="bold">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#585858\" font-weight="bold">(___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>',
|
||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>'],
|
||||
"LightSleetShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">* </span>',
|
||||
'<span foreground=\"#eeeeee\";"> *</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>'],
|
||||
'<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">* </span>',
|
||||
'<span foreground=\"#eeeeee\"> *</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>'],
|
||||
"ThunderyShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||
'<span foreground=\"#ffff87\";"> ⚡\\</span>"<span foreground=\"#87afff\";">‘ ‘</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#87afff\";">‘ ‘ </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>'],
|
||||
'<span foreground=\"#ffff87\"> ⚡\\</span>"<span foreground=\"#87afff\">‘ ‘</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#87afff\">‘ ‘ </span>',
|
||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>'],
|
||||
"ThunderyHeavyRain": [
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> .-. </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> ( ). </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> (___(__) </span>',
|
||||
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚‘</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">‘‚</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">‚‘ </span>',
|
||||
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚’‚’</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">’‚’ </span>'],
|
||||
'<span foreground=\"#585858\" font-weight="bold"> .-. </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> ( ). </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> (___(__) </span>',
|
||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚‘</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#0000ff\">‘‚</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#0000ff\">‚‘ </span>',
|
||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚’‚’</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#0000ff\">’‚’ </span>'],
|
||||
"ThunderySnowShowers": [
|
||||
'<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-. </span>',
|
||||
'<span foreground=\"#FFFF00\"> ,\\_</span>"<span foreground=\"#BBBBBB\">( ). </span>',
|
||||
'<span foreground=\"#FFFF00\"> /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\";"> *</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#eeeeee\";">* </span>',
|
||||
'<span foreground=\"#eeeeee\";"> * * * </span>'],
|
||||
'<span foreground=\"#eeeeee\"> *</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#ffff87\">⚡\\</span>"<span foreground=\"#eeeeee\">* </span>',
|
||||
'<span foreground=\"#eeeeee\"> * * * </span>'],
|
||||
"LightRain": [
|
||||
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
||||
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
||||
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ ‘ ‘ ‘ </span>'],
|
||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>',
|
||||
'<span foreground=\"#87afff\"> ‘ ‘ ‘ ‘ </span>'],
|
||||
"HeavyRain": [
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> .-. </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> ( ). </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> (___(__) </span>',
|
||||
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚‘‚‘‚‘‚‘ </span>',
|
||||
'<span foreground=\"#0000ff\"; font-weight: bold;"> ‚’‚’‚’‚’ </span>'],
|
||||
'<span foreground=\"#585858\" font-weight="bold"> .-. </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> ( ). </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> (___(__) </span>',
|
||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚‘‚‘‚‘‚‘ </span>',
|
||||
'<span foreground=\"#0000ff\" font-weight="bold"> ‚’‚’‚’‚’ </span>'],
|
||||
"LightSnow": [
|
||||
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
||||
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
||||
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\";"> * * * </span>',
|
||||
'<span foreground=\"#eeeeee\";"> * * * </span>'],
|
||||
'<span foreground=\"#eeeeee\"> * * * </span>',
|
||||
'<span foreground=\"#eeeeee\"> * * * </span>'],
|
||||
"HeavySnow": [
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> .-. </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> ( ). </span>',
|
||||
'<span foreground=\"#585858\"; font-weight: bold;"> (___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>',
|
||||
'<span foreground=\"#eeeeee\"; font-weight: bold;"> * * * * </span>'],
|
||||
'<span foreground=\"#585858\" font-weight="bold"> .-. </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> ( ). </span>',
|
||||
'<span foreground=\"#585858\" font-weight="bold"> (___(__) </span>',
|
||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>',
|
||||
'<span foreground=\"#eeeeee\" font-weight="bold"> * * * * </span>'],
|
||||
"LightSleet": [
|
||||
'<span foreground=\"#BBBBBB\"> .-. </span>',
|
||||
'<span foreground=\"#BBBBBB\"> ( ). </span>',
|
||||
'<span foreground=\"#BBBBBB\"> (___(__) </span>',
|
||||
'<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">* </span>',
|
||||
'<span foreground=\"#eeeeee\";"> *</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>'],
|
||||
'<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">* </span>',
|
||||
'<span foreground=\"#eeeeee\"> *</span>"<span foreground=\"#87afff\"> ‘ </span>"<span foreground=\"#eeeeee\">*</span>"<span foreground=\"#87afff\"> ‘ </span>'],
|
||||
"Fog": [
|
||||
' ',
|
||||
'<span foreground=\"#c0c0c0\";"> _ - _ - _ - </span>',
|
||||
'<span foreground=\"#c0c0c0\";"> _ - _ - _ </span>',
|
||||
'<span foreground=\"#c0c0c0\";"> _ - _ - _ - </span>',
|
||||
'<span foreground=\"#c0c0c0\"> _ - _ - _ - </span>',
|
||||
'<span foreground=\"#c0c0c0\"> _ - _ - _ </span>',
|
||||
'<span foreground=\"#c0c0c0\"> _ - _ - _ - </span>',
|
||||
' '],
|
||||
}
|
||||
|
||||
WEATHER_CODES_WEGO = {key: WEATHER_SYMBOL_WEGO[value] for key, value in WWO_CODE.items()}
|
||||
|
||||
data = {}
|
||||
CACHE_DIR = os.path.join(os.environ.get("XDG_CACHE_HOME", os.path.expanduser("~/.cache")), "waybar-weather")
|
||||
CACHE_FILE = os.path.join(CACHE_DIR, "wttr.json")
|
||||
CACHE_MOON_FILE = os.path.join(CACHE_DIR, "moon.json")
|
||||
CACHE_MOON_ICON_FILE = os.path.join(CACHE_DIR, "moon-icon")
|
||||
CACHE_TTL = timedelta(minutes=10)
|
||||
|
||||
data = {}
|
||||
data["text"] = ""
|
||||
|
||||
def format_time(time):
|
||||
"""get the time formatted"""
|
||||
return datetime.strptime(format_24_time(time), "%H").strftime("%I %p")
|
||||
|
||||
def format_24_time(time):
|
||||
"""get the time formatted"""
|
||||
return time.replace("00", "").zfill(2)
|
||||
|
||||
|
||||
def format_temp(temp):
|
||||
"""get the temp formatted"""
|
||||
return (temp + "°").ljust(3)
|
||||
|
||||
return (str(temp) + "°").ljust(3)
|
||||
|
||||
def format_chances(hour):
|
||||
"""get the chances formatted"""
|
||||
chances = {
|
||||
"chanceoffog": "Fog",
|
||||
"chanceoffrost": "Frost",
|
||||
@@ -302,60 +348,67 @@ let
|
||||
"chanceofthunder": "Thunder",
|
||||
"chanceofwindy": "Wind",
|
||||
}
|
||||
|
||||
conditions = []
|
||||
for chance, event in chances.items():
|
||||
if int(hour[chance]) > 0:
|
||||
conditions.append(event + " " + hour[chance] + "%")
|
||||
if int(hour.get(chance, 0)) > 0:
|
||||
conditions.append(event + " " + str(hour[chance]) + "%")
|
||||
return ", ".join(conditions)
|
||||
|
||||
def deg_to_compass(num):
|
||||
val = int((num / 22.5) + 0.5)
|
||||
arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"]
|
||||
return arr[(val % 16)]
|
||||
|
||||
def build_text(current_condition):
|
||||
"""build the text string"""
|
||||
feels_like_f = current_condition["FeelsLikeF"]
|
||||
weather_code = current_condition["weatherCode"]
|
||||
# Check if we have a mapped format; if not, fallback to Unknown
|
||||
if weather_code not in WEATHER_CODES:
|
||||
weather_code = "113" # Fallback to sunny/default to prevent crash
|
||||
|
||||
tempint = int(feels_like_f)
|
||||
tempint = int(float(feels_like_f)) # float cast just in case
|
||||
extrachar = ""
|
||||
if 0 < tempint < 10:
|
||||
extrachar = "+"
|
||||
|
||||
current_weather = f"{WEATHER_CODES[weather_code]} {extrachar} {feels_like_f}°F"
|
||||
|
||||
current_weather = f"{WEATHER_CODES[weather_code]} {extrachar} {int(feels_like_f)}°F"
|
||||
return current_weather
|
||||
|
||||
def build_tooltip(current_condition, astronomy, moon_icon):
|
||||
"""build the tooltip text"""
|
||||
weather_description = current_condition['weatherDesc'][0]['value']
|
||||
feels_like_f = current_condition["FeelsLikeF"]
|
||||
temp_f = current_condition['temp_F']
|
||||
humidity = current_condition['humidity']
|
||||
wind_speed = current_condition['windspeedMiles']
|
||||
wind_dir = current_condition['winddir16Point']
|
||||
moon_phase = astronomy['moon_phase']
|
||||
wego = WEATHER_CODES_WEGO[current_condition['weatherCode']]
|
||||
moon_phase = astronomy.get('moon_phase', 'Unknown')
|
||||
|
||||
weather_code = current_condition['weatherCode']
|
||||
if weather_code not in WEATHER_CODES_WEGO:
|
||||
weather_code = "113"
|
||||
|
||||
tooltip = f"{wego[0]}{weather_description} {temp_f}°\n"
|
||||
tooltip += f"{wego[1]}Feels like: {feels_like_f}°\n"
|
||||
tooltip += f"{wego[2]}Wind: {wind_speed}mph {WIND_DIRECTION[wind_dir]}\n"
|
||||
tooltip += f"{wego[3]}Humidity: {humidity}%\n"
|
||||
tooltip += f"{wego[4]}Moon phase: {moon_phase} " + moon_icon + "\n"
|
||||
wego = WEATHER_CODES_WEGO[weather_code]
|
||||
|
||||
current = f"{wego[0]}{weather_description} {temp_f}°\n"
|
||||
feels = f"{wego[1]}Feels like: {feels_like_f}°\n"
|
||||
wind = f"{wego[2]}Wind: {wind_speed}mph {WIND_DIRECTION.get(wind_dir, ''\'')}\n" # Safe get for direction
|
||||
humidityl = f"{wego[3]}Humidity: {humidity}%\n"
|
||||
moon = f"{wego[4]}Moon phase: {moon_phase} " + moon_icon + "\n"
|
||||
|
||||
tooltip = current + feels + wind + humidityl + moon
|
||||
return tooltip
|
||||
|
||||
def build_forecast(weather):
|
||||
"""build a 3 day forecast"""
|
||||
tooltip = "\n"
|
||||
|
||||
for i, day in enumerate(weather):
|
||||
# determine day
|
||||
if i == 0:
|
||||
tooltip += "Today, "
|
||||
if i == 1:
|
||||
tooltip += "Tomorrow, "
|
||||
# format the date
|
||||
|
||||
date = datetime.strptime(day['date'], "%Y-%m-%d").strftime("%a %b %d %Y")
|
||||
tooltip += f"<b>{date}</b>\n"
|
||||
# set the high and low
|
||||
|
||||
max_temp = day['maxtempF']
|
||||
min_temp = day['mintempF']
|
||||
tooltip += f" {max_temp}°F {min_temp}°F"
|
||||
@@ -367,29 +420,34 @@ let
|
||||
tooltip += build_hourly_forecast(i, day['hourly'], sunrise, sunset)
|
||||
return tooltip
|
||||
|
||||
|
||||
def build_hourly_forecast(day_num, hourly, sunrise, sunset):
|
||||
"""build an hourly forecast"""
|
||||
sunrise_hour = datetime.strptime(sunrise, "%I:%M %p").hour
|
||||
sunset_hour = datetime.strptime(sunset, "%I:%M %p").hour
|
||||
try:
|
||||
sunrise_hour = datetime.strptime(sunrise, "%I:%M %p").hour
|
||||
sunset_hour = datetime.strptime(sunset, "%I:%M %p").hour
|
||||
except ValueError:
|
||||
# Fallback if time format is different (OpenMeteo might send 24h)
|
||||
sunrise_hour = int(sunrise.split(':')[0])
|
||||
sunset_hour = int(sunset.split(':')[0])
|
||||
|
||||
current_hour = datetime.now().hour
|
||||
tooltip = ""
|
||||
|
||||
for hour in hourly:
|
||||
time_24_hr = int(format_24_time(hour["time"]))
|
||||
|
||||
if day_num == 0:
|
||||
if time_24_hr < current_hour - 2:
|
||||
continue
|
||||
|
||||
# determine which code to use
|
||||
if is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
|
||||
codes = WEATHER_CODES_WI_NIGHT
|
||||
else:
|
||||
codes = WEATHER_CODES_WI_DAY
|
||||
|
||||
current_time = format_time(hour['time'])
|
||||
current_weather_code = codes[hour['weatherCode']]
|
||||
wcode = hour['weatherCode']
|
||||
if wcode not in codes: wcode = "113" # Fallback
|
||||
|
||||
current_weather_code = codes[wcode]
|
||||
feels_like = format_temp(hour['FeelsLikeF'])
|
||||
weather_desc = hour['weatherDesc'][0]['value']
|
||||
current_chances = format_chances(hour)
|
||||
@@ -400,34 +458,188 @@ let
|
||||
return tooltip
|
||||
|
||||
def is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
|
||||
"""returns true if the hour is night"""
|
||||
before_sunrise = time_24_hr < sunrise_hour
|
||||
after_sunset = time_24_hr > sunset_hour
|
||||
return after_sunset or before_sunrise
|
||||
|
||||
def get_wttr_json():
|
||||
"""get the weather json"""
|
||||
weather = requests.get("https://wttr.in/?u&format=j1", timeout=30).json()
|
||||
moon = requests.get("https://wttr.in/?format=%m", timeout=30)
|
||||
moon_icon = moon.text
|
||||
def load_cache(path, ttl):
|
||||
try:
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
mtime = datetime.fromtimestamp(os.path.getmtime(path))
|
||||
if datetime.now() - mtime > ttl:
|
||||
return None
|
||||
with open(path, "r") as f:
|
||||
if path.endswith(".json"):
|
||||
return json.load(f)
|
||||
return f.read().strip()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
current_condition = weather["current_condition"][0]
|
||||
astronomy = weather["weather"][0]['astronomy'][0]
|
||||
def save_cache(path, data):
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
tmp = path + ".tmp"
|
||||
try:
|
||||
with open(tmp, "w") as f:
|
||||
if isinstance(data, dict):
|
||||
json.dump(data, f)
|
||||
else:
|
||||
f.write(str(data))
|
||||
shutil.move(tmp, path)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
data["text"] = build_text(current_condition)
|
||||
data["tooltip"] = build_tooltip(current_condition, astronomy, moon_icon)
|
||||
data["tooltip"] += build_forecast(weather["weather"])
|
||||
# --- OPEN-METEO INTEGRATION HELPER FUNCTIONS ---
|
||||
|
||||
return json.dumps(data)
|
||||
def get_lat_lon():
|
||||
"""Attempt to get location via IP if using OpenMeteo"""
|
||||
try:
|
||||
resp = requests.get("http://ip-api.com/json/", timeout=5).json()
|
||||
return resp.get('lat'), resp.get('lon')
|
||||
except:
|
||||
# Default to a generic location if IP fetch fails (NYC)
|
||||
return 40.71, -74.00
|
||||
|
||||
def fetch_open_meteo():
|
||||
"""Fetch and Transform OpenMeteo data to match Wttr.in JSON structure"""
|
||||
lat, lon = get_lat_lon()
|
||||
url = "https://api.open-meteo.com/v1/forecast"
|
||||
params = {
|
||||
"latitude": lat,
|
||||
"longitude": lon,
|
||||
"current": "temperature_2m,apparent_temperature,precipitation,weather_code,wind_speed_10m,wind_direction_10m,relative_humidity_2m",
|
||||
"daily": "weather_code,temperature_2m_max,temperature_2m_min,sunrise,sunset,precipitation_probability_max",
|
||||
"hourly": "temperature_2m,apparent_temperature,precipitation_probability,weather_code",
|
||||
"temperature_unit": "fahrenheit",
|
||||
"wind_speed_unit": "mph",
|
||||
"precipitation_unit": "inch",
|
||||
"timezone": "auto"
|
||||
}
|
||||
|
||||
response = requests.get(url, params=params, timeout=10)
|
||||
om_data = response.json()
|
||||
|
||||
# Transform Current Condition
|
||||
current = om_data["current"]
|
||||
wmo_code = current["weather_code"]
|
||||
wwo_code = WMO_TO_WWO.get(wmo_code, "113")
|
||||
|
||||
wttr_current = {
|
||||
"temp_F": str(int(current["temperature_2m"])),
|
||||
"FeelsLikeF": str(int(current["apparent_temperature"])),
|
||||
"weatherCode": wwo_code,
|
||||
"weatherDesc": [{"value": WWO_CODE.get(wwo_code, "Unknown")}],
|
||||
"humidity": str(current["relative_humidity_2m"]),
|
||||
"windspeedMiles": str(int(current["wind_speed_10m"])),
|
||||
"winddir16Point": deg_to_compass(current["wind_direction_10m"]),
|
||||
}
|
||||
|
||||
# Transform Daily Forecast (OpenMeteo gives 7 days, we need 3)
|
||||
wttr_weather = []
|
||||
daily = om_data["daily"]
|
||||
hourly = om_data["hourly"]
|
||||
|
||||
for i in range(3):
|
||||
date_str = daily["time"][i]
|
||||
|
||||
# Build Hourly for this day (wttr uses 3-hour intervals: 0, 300, 600...)
|
||||
# OpenMeteo gives 0, 1, 2...
|
||||
wttr_hourly = []
|
||||
for h in range(0, 24, 3): # Step by 3 hours to mimic wttr
|
||||
idx = (i * 24) + h
|
||||
h_code = hourly["weather_code"][idx]
|
||||
h_wwo = WMO_TO_WWO.get(h_code, "113")
|
||||
|
||||
wttr_hourly.append({
|
||||
"time": str(h * 100), # 0, 300, 600
|
||||
"weatherCode": h_wwo,
|
||||
"weatherDesc": [{"value": WWO_CODE.get(h_wwo, "Unknown")}],
|
||||
"FeelsLikeF": str(int(hourly["apparent_temperature"][idx])),
|
||||
"chanceofrain": str(hourly["precipitation_probability"][idx]),
|
||||
# Fill other chances with 0 as API doesn't provide them easily
|
||||
"chanceoffog": "0", "chanceofsnow": "0", "chanceofthunder": "0",
|
||||
"chanceofwindy": "0", "chanceofsunshine": "0"
|
||||
})
|
||||
|
||||
# Astronomy
|
||||
sunrise = datetime.fromisoformat(daily["sunrise"][i]).strftime("%I:%M %p")
|
||||
sunset = datetime.fromisoformat(daily["sunset"][i]).strftime("%I:%M %p")
|
||||
|
||||
wttr_weather.append({
|
||||
"date": date_str,
|
||||
"maxtempF": str(int(daily["temperature_2m_max"][i])),
|
||||
"mintempF": str(int(daily["temperature_2m_min"][i])),
|
||||
"astronomy": [{"sunrise": sunrise, "sunset": sunset, "moon_phase": "Unknown"}],
|
||||
"hourly": wttr_hourly
|
||||
})
|
||||
|
||||
return {
|
||||
"current_condition": [wttr_current],
|
||||
"weather": wttr_weather
|
||||
}
|
||||
|
||||
def get_wttr_json(hyprlock=False):
|
||||
# Try loading cached JSON
|
||||
cached = load_cache(CACHE_FILE, CACHE_TTL)
|
||||
cached_moon = load_cache(CACHE_MOON_FILE, CACHE_TTL)
|
||||
cached_moon_icon = load_cache(CACHE_MOON_ICON_FILE, CACHE_TTL)
|
||||
|
||||
if cached and cached_moon and cached_moon_icon:
|
||||
weather = cached
|
||||
current_condition = weather["current_condition"][0]
|
||||
astronomy = cached_moon
|
||||
moon_icon = cached_moon_icon
|
||||
else:
|
||||
try:
|
||||
# Primary Source: wttr.in
|
||||
weather = requests.get("https://wttr.in/?u&format=j1", timeout=5).json()
|
||||
moon = requests.get("https://wttr.in/?format=%m", timeout=5)
|
||||
moon_icon = moon.text
|
||||
|
||||
current_condition = weather["current_condition"][0]
|
||||
astronomy = weather["weather"][0]['astronomy'][0]
|
||||
except Exception:
|
||||
# Fallback Source: Open-Meteo
|
||||
try:
|
||||
print("open_mateo fallback")
|
||||
weather = fetch_open_meteo()
|
||||
current_condition = weather["current_condition"][0]
|
||||
astronomy = weather["weather"][0]['astronomy'][0]
|
||||
moon_icon = "" # Generic moon icon for fallback
|
||||
except Exception as e:
|
||||
# If both fail
|
||||
raise e
|
||||
|
||||
# Save cache (works for both sources since we transformed OM data)
|
||||
save_cache(CACHE_FILE, weather)
|
||||
save_cache(CACHE_MOON_FILE, astronomy)
|
||||
save_cache(CACHE_MOON_ICON_FILE, moon_icon)
|
||||
|
||||
if hyprlock:
|
||||
return build_tooltip(current_condition, astronomy, moon_icon)
|
||||
else:
|
||||
text = build_text(current_condition)
|
||||
tooltip = build_tooltip(current_condition, astronomy, moon_icon) + build_forecast(weather["weather"])
|
||||
data["text"] = text
|
||||
data["tooltip"] = tooltip
|
||||
return json.dumps(data)
|
||||
|
||||
def main():
|
||||
"""main"""
|
||||
try:
|
||||
print(get_wttr_json())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
if args.hyprlock:
|
||||
try:
|
||||
print(get_wttr_json(hyprlock=True))
|
||||
except Exception as e:
|
||||
print("error")
|
||||
# print(e) # Uncomment for debug
|
||||
else:
|
||||
try:
|
||||
print(get_wttr_json())
|
||||
except Exception as e:
|
||||
print(json.dumps({"text": "Err", "tooltip": str(e)}))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
main()
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.wlogout;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.wlogout;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
imports = [ ./options.nix ];
|
||||
config = mkIf cfg.enable {
|
||||
programs.wlogout = {
|
||||
enable = false;
|
||||
@@ -53,13 +57,13 @@ in
|
||||
}
|
||||
|
||||
window {
|
||||
background-color: ${nord.polarNight.nord0}f0
|
||||
background-color: ${config.lib.stylix.colors.base00}f0
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 8px;
|
||||
color: ${nord.frost.nord7};
|
||||
background-color: ${nord.polarNight.nord1};
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
background-color: ${config.lib.stylix.colors.base01};
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
background-repeat: no-repeat;
|
||||
@@ -70,8 +74,8 @@ in
|
||||
button:active,
|
||||
button:focus,
|
||||
button:hover {
|
||||
color: ${nord.frost.nord8};
|
||||
background-color: ${nord.polarNight.nord2};
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
background-color: ${config.lib.stylix.colors.base02Alt};
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
@@ -101,4 +105,4 @@ in
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.wlogout = {
|
||||
options.${namespace}.programs.wlogout = {
|
||||
enable = mkEnableOption "enable wlogout";
|
||||
|
||||
fontName = mkOption {
|
||||
type = types.str;
|
||||
default = "Deja Vu Sans";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.mjallen.programs.wofi;
|
||||
nord = import ../../desktop/theme/nord.nix;
|
||||
cfg = config.${namespace}.programs.wofi;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
@@ -20,9 +24,9 @@ in
|
||||
window {
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: 0.16em solid ${nord.aurora.nord15};
|
||||
border: 0.16em solid ${config.lib.stylix.colors.base0E};
|
||||
border-radius: 0.1em;
|
||||
background-color: ${nord.polarNight.nord0};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Inner Box */
|
||||
@@ -30,7 +34,7 @@ in
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${nord.polarNight.nord0};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Outer Box */
|
||||
@@ -38,7 +42,7 @@ in
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${nord.polarNight.nord0};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Scroll */
|
||||
@@ -46,7 +50,7 @@ in
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background-color: ${nord.polarNight.nord0};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
/* Input */
|
||||
@@ -55,46 +59,46 @@ in
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 0.1em;
|
||||
color: ${nord.snowStorm.nord6};
|
||||
background-color: ${nord.polarNight.nord0};
|
||||
color: ${config.lib.stylix.colors.base06};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
#input image {
|
||||
border: none;
|
||||
color: ${nord.aurora.nord11};
|
||||
color: ${config.lib.stylix.colors.base08};
|
||||
}
|
||||
|
||||
#input * {
|
||||
outline: 4px solid ${nord.aurora.nord11}!important;
|
||||
outline: 4px solid ${config.lib.stylix.colors.base08}!important;
|
||||
}
|
||||
|
||||
/* Text */
|
||||
#text {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: ${nord.snowStorm.nord6};
|
||||
color: ${config.lib.stylix.colors.base06};
|
||||
}
|
||||
|
||||
#entry {
|
||||
background-color: ${nord.polarNight.nord0};
|
||||
background-color: ${config.lib.stylix.colors.base00};
|
||||
}
|
||||
|
||||
#entry arrow {
|
||||
border: none;
|
||||
color: ${nord.aurora.nord15};
|
||||
color: ${config.lib.stylix.colors.base0E};
|
||||
}
|
||||
|
||||
/* Selected Entry */
|
||||
#entry:selected {
|
||||
border: 0.11em solid ${nord.aurora.nord15};
|
||||
border: 0.11em solid ${config.lib.stylix.colors.base0E};
|
||||
}
|
||||
|
||||
#entry:selected #text {
|
||||
color: ${nord.frost.nord7};
|
||||
color: ${config.lib.stylix.colors.base0C};
|
||||
}
|
||||
|
||||
#entry:drop(active) {
|
||||
background-color: ${nord.aurora.nord15}!important;
|
||||
background-color: ${config.lib.stylix.colors.base0E}!important;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.programs.wofi = {
|
||||
options.${namespace}.programs.wofi = {
|
||||
enable = mkEnableOption "enable wofi";
|
||||
|
||||
fontName = mkOption {
|
||||
@@ -9,4 +9,4 @@ with lib;
|
||||
default = "Deja Vu Sans";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@ in
|
||||
# fi
|
||||
# '';
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
11
modules/home/services/pass/default.nix
Normal file
11
modules/home/services/pass/default.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
...
|
||||
}:
|
||||
{
|
||||
#services.gnome-keyring.enable = false;
|
||||
#home.packages = [ pkgs.gcr ];
|
||||
|
||||
services.pass-secret-service = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
||||
58
modules/home/shell-aliases/default.nix
Normal file
58
modules/home/shell-aliases/default.nix
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.shell-aliases;
|
||||
in
|
||||
{
|
||||
options.${namespace}.shell-aliases = {
|
||||
enable = lib.mkEnableOption "Common shell aliases";
|
||||
|
||||
buildHost = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "admin@10.0.1.3";
|
||||
description = "Build host for nixos-rebuild commands";
|
||||
};
|
||||
|
||||
flakeInputs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "List of flake inputs to update";
|
||||
};
|
||||
|
||||
extraAliases = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = { };
|
||||
description = "Additional host-specific aliases";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.zsh.shellAliases = {
|
||||
# Common file operations
|
||||
ll = "ls -alh";
|
||||
ducks = "du -cksh * | sort -hr | head -n 15";
|
||||
|
||||
# NixOS rebuild commands
|
||||
update-boot =
|
||||
"sudo nixos-rebuild boot --max-jobs 10"
|
||||
+ lib.optionalString (cfg.buildHost != "") " --build-host ${cfg.buildHost}";
|
||||
update-switch =
|
||||
"sudo nixos-rebuild switch --max-jobs 10"
|
||||
+ lib.optionalString (cfg.buildHost != "") " --build-host ${cfg.buildHost}";
|
||||
|
||||
# Flake update command
|
||||
update-flake = lib.mkIf (
|
||||
cfg.flakeInputs != [ ]
|
||||
) "nix flake update ${lib.concatStringsSep " " cfg.flakeInputs} --flake /etc/nixos";
|
||||
|
||||
# NAS management
|
||||
update-nas = "nixos-rebuild switch --use-remote-sudo --target-host admin@10.0.1.3 --build-host admin@10.0.1.3 --flake ~/nix-config#jallen-nas";
|
||||
nas-ssh = "kitten ssh admin@10.0.1.3";
|
||||
}
|
||||
// cfg.extraAliases;
|
||||
};
|
||||
}
|
||||
@@ -1,28 +1,28 @@
|
||||
{ config, lib, namespace, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.mjallen.sops;
|
||||
|
||||
user = config.${namespace}.user.name;
|
||||
hostname = config.${namespace}.network.hostname;
|
||||
cfg = config.${namespace}.sops;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
sops = {
|
||||
age.keyFile = "/home/${user}/.config/sops/age/keys.txt";
|
||||
age.keyFile = "/home/${config.${namespace}.user.name}/.config/sops/age/keys.txt";
|
||||
defaultSopsFile = "/etc/nixos/secrets/secrets.yaml";
|
||||
validateSopsFiles = false;
|
||||
secrets = {
|
||||
"ssh-keys-public/desktop-nixos" = {
|
||||
path = "/home/${user}/.ssh/id_ed25519.pub";
|
||||
mode = "0644";
|
||||
};
|
||||
"ssh-keys-private/desktop-nixos" = {
|
||||
path = "/home/${user}/.ssh/id_ed25519";
|
||||
mode = "0600";
|
||||
};
|
||||
};
|
||||
# secrets = {
|
||||
# "github-token" = { };
|
||||
# };
|
||||
# templates = {
|
||||
# ".env".content = ''
|
||||
# GITHUB_TOKEN = "${config.sops.placeholder.github-token}"
|
||||
# '';
|
||||
# };
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, ... }:
|
||||
{ lib, namespace, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.mjallen.sops = {
|
||||
options.${namespace}.sops = {
|
||||
enable = mkEnableOption "enable sops";
|
||||
|
||||
defaultSopsFile = mkOption {
|
||||
@@ -9,4 +9,4 @@ with lib;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
105
modules/home/stylix/default.nix
Normal file
105
modules/home/stylix/default.nix
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# # Pull from global theme options
|
||||
# themeSize = "standard"; # "standard" | "compact"
|
||||
# themeAccent = "default"; # "default" | ... | "all"
|
||||
# themeTweak = "normal"; # "normal" | "rimless" | "float" | "black"
|
||||
# themeColor = "dark"; # "light" | "dark"
|
||||
# iconThemeVariant = "default"; # "default" | ... | "all"
|
||||
# iconScheme = "nord"; # "default" | "nord" | "dracula" | ...
|
||||
|
||||
# # GTK
|
||||
# gtkTheme = "Colloid-dark-standard";
|
||||
# gtkThemePkg = pkgs.colloid-gtk-theme.override {
|
||||
# sizeVariants = [ themeSize ];
|
||||
# colorVariants = [ themeColor ];
|
||||
# themeVariants = [ themeAccent ];
|
||||
# tweaks = [ themeTweak ];
|
||||
# };
|
||||
|
||||
# # Icons
|
||||
# iconTheme = "Colloid-nord-dark";
|
||||
# iconThemePkg = pkgs.colloid-icon-theme.override {
|
||||
# schemeVariants = [ iconScheme ];
|
||||
# colorVariants = [ iconThemeVariant ];
|
||||
# };
|
||||
isDarwin = system == "aarch64-darwin";
|
||||
in
|
||||
{
|
||||
stylix = {
|
||||
enable = true;
|
||||
overlays.enable = false;
|
||||
enableReleaseChecks = false;
|
||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/nord.yaml";
|
||||
polarity = "dark";
|
||||
|
||||
cursor = {
|
||||
name = "macOS";
|
||||
size = 24;
|
||||
package = pkgs.apple-cursor;
|
||||
};
|
||||
|
||||
fonts = {
|
||||
serif = {
|
||||
package = pkgs.dejavu_fonts;
|
||||
name = "DejaVu Serif";
|
||||
};
|
||||
|
||||
sansSerif = {
|
||||
package = pkgs.dejavu_fonts;
|
||||
name = "DejaVu Sans";
|
||||
};
|
||||
|
||||
monospace = {
|
||||
package = pkgs.nerd-fonts.jetbrains-mono;
|
||||
name = "JetBrainsMono NFM";
|
||||
};
|
||||
|
||||
emoji = {
|
||||
package = pkgs.noto-fonts-color-emoji;
|
||||
name = "Noto Color Emoji";
|
||||
};
|
||||
|
||||
sizes = {
|
||||
applications = if isDarwin then 10 else 12;
|
||||
desktop = if isDarwin then 12 else 14;
|
||||
popups = config.stylix.fonts.sizes.desktop;
|
||||
terminal = config.stylix.fonts.sizes.applications;
|
||||
};
|
||||
};
|
||||
|
||||
icons = {
|
||||
enable = true;
|
||||
package = pkgs.colloid-icon-theme.override {
|
||||
schemeVariants = [ "nord" ];
|
||||
colorVariants = [ "default" ];
|
||||
};
|
||||
dark = "Colloid-Nord-Dark";
|
||||
light = "Colloid-Nord-Light";
|
||||
};
|
||||
|
||||
opacity = {
|
||||
terminal = 0.85;
|
||||
};
|
||||
|
||||
targets = {
|
||||
hyprlock = {
|
||||
enable = false;
|
||||
useWallpaper = false;
|
||||
};
|
||||
kde.enable = false;
|
||||
firefox = {
|
||||
enable = false;
|
||||
profileNames = [
|
||||
"default"
|
||||
"954lxlok.default"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -34,7 +34,7 @@ in
|
||||
default = "Austin Horstman";
|
||||
description = "The full name of the user.";
|
||||
};
|
||||
home = mkOption {
|
||||
home = mkOption {
|
||||
type = (types.nullOr types.str);
|
||||
default = home-directory;
|
||||
description = "The user's home directory.";
|
||||
@@ -65,20 +65,19 @@ in
|
||||
];
|
||||
|
||||
home = {
|
||||
file =
|
||||
{
|
||||
"Desktop/.keep".text = "";
|
||||
"Documents/.keep".text = "";
|
||||
"Downloads/.keep".text = "";
|
||||
"Music/.keep".text = "";
|
||||
"Pictures/.keep".text = "";
|
||||
"Videos/.keep".text = "";
|
||||
}
|
||||
// lib.optionalAttrs (cfg.icon != null) {
|
||||
".face".source = cfg.icon;
|
||||
".face.icon".source = cfg.icon;
|
||||
"Pictures/${cfg.icon.fileName or (builtins.baseNameOf cfg.icon)}".source = cfg.icon;
|
||||
};
|
||||
file = {
|
||||
"Desktop/.keep".text = "";
|
||||
"Documents/.keep".text = "";
|
||||
"Downloads/.keep".text = "";
|
||||
"Music/.keep".text = "";
|
||||
"Pictures/.keep".text = "";
|
||||
"Videos/.keep".text = "";
|
||||
}
|
||||
// lib.optionalAttrs (cfg.icon != null) {
|
||||
".face".source = cfg.icon;
|
||||
".face.icon".source = cfg.icon;
|
||||
"Pictures/${cfg.icon.fileName or (builtins.baseNameOf cfg.icon)}".source = cfg.icon;
|
||||
};
|
||||
|
||||
homeDirectory = mkDefault cfg.home;
|
||||
|
||||
@@ -116,8 +115,8 @@ in
|
||||
tarnow = "${getExe pkgs.gnutar} -acf ";
|
||||
untar = "${getExe pkgs.gnutar} -zxvf ";
|
||||
wget = "${getExe pkgs.wget} -c ";
|
||||
remove-empty = ''${getExe' pkgs.findutils "find"} . -type d --empty --delete'';
|
||||
print-empty = ''${getExe' pkgs.findutils "find"} . -type d --empty --print'';
|
||||
remove-empty = "${getExe' pkgs.findutils "find"} . -type d --empty --delete";
|
||||
print-empty = "${getExe' pkgs.findutils "find"} . -type d --empty --print";
|
||||
dfh = "${getExe' pkgs.coreutils "df"} -h";
|
||||
duh = "${getExe' pkgs.coreutils "du"} -h";
|
||||
usage = "${getExe' pkgs.coreutils "du"} -ah -d1 | sort -rn 2>/dev/null";
|
||||
@@ -154,4 +153,4 @@ in
|
||||
};
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.nas-apps.actual;
|
||||
dataDir = "/data";
|
||||
hostAddress = "10.0.1.3";
|
||||
actualUserId = config.users.users.nix-apps.uid;
|
||||
actualGroupId = config.users.groups.jallen-nas.gid;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
containers.actual = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostAddress;
|
||||
localAddress = cfg.localAddress;
|
||||
|
||||
bindMounts = {
|
||||
${dataDir} = {
|
||||
hostPath = cfg.dataDir;
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
|
||||
config = { lib, ... }:
|
||||
{
|
||||
services.actual = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
settings = {
|
||||
trustedProxies = [ hostAddress ];
|
||||
port = cfg.port;
|
||||
dataDir = dataDir;
|
||||
serverFiles = "${dataDir}/server-files";
|
||||
userFiles = "${dataDir}/user-files";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.actual = {
|
||||
isSystemUser = true;
|
||||
uid = lib.mkForce actualUserId;
|
||||
group = "actual";
|
||||
};
|
||||
|
||||
users.groups = {
|
||||
actual = {
|
||||
gid = lib.mkForce actualGroupId;
|
||||
};
|
||||
};
|
||||
|
||||
# System packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
sqlite
|
||||
];
|
||||
|
||||
# Create and set permissions for required directories
|
||||
system.activationScripts.actual-dirs = ''
|
||||
mkdir -p ${dataDir}
|
||||
chown -R actual:actual ${dataDir}
|
||||
chmod -R 0700 ${dataDir}
|
||||
'';
|
||||
|
||||
systemd.services = {
|
||||
actual = {
|
||||
environment.ACTUAL_CONFIG_PATH = lib.mkForce "${dataDir}/config.json";
|
||||
serviceConfig = {
|
||||
ExecStart = lib.mkForce "${pkgs.actual-server}/bin/actual-server --config ${dataDir}/config.json";
|
||||
WorkingDirectory = lib.mkForce dataDir;
|
||||
StateDirectory = lib.mkForce dataDir;
|
||||
StateDirectoryMode = lib.mkForce 0700;
|
||||
DynamicUser = lib.mkForce false;
|
||||
ProtectSystem = lib.mkForce null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
# Use systemd-resolved inside the container
|
||||
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
|
||||
useHostResolvConf = lib.mkForce false;
|
||||
};
|
||||
|
||||
services.resolved.enable = true;
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
};
|
||||
|
||||
services.traefik.dynamicConfigOptions = lib.mkIf cfg.reverseProxy.enable {
|
||||
services.actual.loadBalancer.servers = [
|
||||
{
|
||||
url = "http://${cfg.localAddress}:${toString cfg.port}";
|
||||
}
|
||||
];
|
||||
routers.actual = {
|
||||
entryPoints = [ "websecure" ];
|
||||
rule = "Host(`${cfg.reverseProxy.host}`)";
|
||||
service = "actual";
|
||||
middlewares = cfg.reverseProxy.middlewares;
|
||||
tls.certResolver = "letsencrypt";
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
nat = {
|
||||
forwardPorts = [
|
||||
{
|
||||
destination = "${cfg.localAddress}:${toString cfg.port}";
|
||||
sourcePort = cfg.port;
|
||||
}
|
||||
];
|
||||
};
|
||||
firewall = {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
allowedUDPPorts = [ cfg.port ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{ lib, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.nas-apps.actual = {
|
||||
enable = mkEnableOption "actual service";
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 80;
|
||||
};
|
||||
|
||||
localAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
|
||||
reverseProxy = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
middlewares = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user