mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-12 01:59:37 +08:00
Compare commits
1540 Commits
release-17
...
generation
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de0070c4cf | ||
|
|
47ad3655ec | ||
|
|
f6f6990fc8 | ||
|
|
addc78bea0 | ||
|
|
0423a7b40c | ||
|
|
996b439739 | ||
|
|
cc6909d407 | ||
|
|
784da32958 | ||
|
|
6c984bd675 | ||
|
|
ddeeb031fd | ||
|
|
41101d0e62 | ||
|
|
fa483b82ab | ||
|
|
d7e089699a | ||
|
|
2b75633b2c | ||
|
|
41903a14b0 | ||
|
|
82b06103ae | ||
|
|
5f433eb164 | ||
|
|
1617e56c2f | ||
|
|
c476cc61b2 | ||
|
|
f56a087cbc | ||
|
|
775cb20bd4 | ||
|
|
9e3c402972 | ||
|
|
4971b9cad0 | ||
|
|
3ab254aff4 | ||
|
|
9ed7a73ae2 | ||
|
|
ae636c09f4 | ||
|
|
2c9fe368c1 | ||
|
|
d7d7bbbf20 | ||
|
|
06ee8ec8df | ||
|
|
97d183e2e4 | ||
|
|
ac319fd314 | ||
|
|
7df6656b11 | ||
|
|
9ad0024d4d | ||
|
|
3f6cb409ca | ||
|
|
5b08b33e8f | ||
|
|
9b7a90daa1 | ||
|
|
85d67b0a6e | ||
|
|
dc4337d9fe | ||
|
|
a17bc3217f | ||
|
|
2aeaf65e8f | ||
|
|
f4998f0adc | ||
|
|
8d3b273afe | ||
|
|
8eee5f5272 | ||
|
|
0ada50fc9c | ||
|
|
7e2b1a42aa | ||
|
|
ab0e6c3e0e | ||
|
|
21ac4c499b | ||
|
|
b42fce7aaa | ||
|
|
49864a4370 | ||
|
|
762f860cfb | ||
|
|
04955ca970 | ||
|
|
cd11c02c28 | ||
|
|
a73e619377 | ||
|
|
dc1b6b8349 | ||
|
|
e70524cd2b | ||
|
|
2f6d5c90f4 | ||
|
|
6d9bff77ed | ||
|
|
d04e52b0c0 | ||
|
|
3aa479d551 | ||
|
|
a01fe9f81e | ||
|
|
6cd92c643a | ||
|
|
5a19e0ea9c | ||
|
|
63af2d3e4c | ||
|
|
e92f5bb79e | ||
|
|
1e8d0beae4 | ||
|
|
9b39fd7eb4 | ||
|
|
be0e73a308 | ||
|
|
e0f2949c98 | ||
|
|
1375fd4a03 | ||
|
|
b6613a8544 | ||
|
|
c982c19f53 | ||
|
|
4ed6705b0f | ||
|
|
25bf3d7953 | ||
|
|
fb50102daf | ||
|
|
666eee4f72 | ||
|
|
42847469b3 | ||
|
|
aa36e2d6b4 | ||
|
|
06a98ba0fd | ||
|
|
f74dc9c70b | ||
|
|
9424f31f86 | ||
|
|
3ffe2a4cdf | ||
|
|
afb5fd962c | ||
|
|
7591c8041d | ||
|
|
5060262b79 | ||
|
|
ac82c036d8 | ||
|
|
e9ed9c2e11 | ||
|
|
5eb199e937 | ||
|
|
dba802c1d9 | ||
|
|
e4c55ed4e6 | ||
|
|
19d95258ac | ||
|
|
5c1415d67f | ||
|
|
45f9cb06a9 | ||
|
|
c12d53dd7c | ||
|
|
d3cdabb5c9 | ||
|
|
c7e79b5337 | ||
|
|
95da56b783 | ||
|
|
30102ea9e5 | ||
|
|
d6bbd02e95 | ||
|
|
b917624670 | ||
|
|
cb227dc6c2 | ||
|
|
2a4ab0d891 | ||
|
|
9e253a8c30 | ||
|
|
5573c10ea4 | ||
|
|
0e329cee4c | ||
|
|
d2aaeac42c | ||
|
|
07ad6a4f76 | ||
|
|
ab64dc3249 | ||
|
|
3591cd2b3b | ||
|
|
0e6c61a440 | ||
|
|
ddf35436b7 | ||
|
|
b840707a87 | ||
|
|
90493027e3 | ||
|
|
64607f58b7 | ||
|
|
4f70f49cec | ||
|
|
82ab1ad467 | ||
|
|
3d18912f5a | ||
|
|
b449cb77b1 | ||
|
|
cced902dda | ||
|
|
91450f23ce | ||
|
|
ff616b2734 | ||
|
|
73ecbd3722 | ||
|
|
3612ca58e8 | ||
|
|
f9e45390de | ||
|
|
adbabcd0a0 | ||
|
|
e9b7d12e06 | ||
|
|
794d08a1d8 | ||
|
|
b0688a631b | ||
|
|
6a471f1b11 | ||
|
|
01ec2aaefe | ||
|
|
77188bcd6e | ||
|
|
23769994e8 | ||
|
|
3b799f6ea4 | ||
|
|
7d765d8f46 | ||
|
|
15a2953c81 | ||
|
|
e42e147b58 | ||
|
|
4896c50074 | ||
|
|
b2dec35b86 | ||
|
|
ff959fd49a | ||
|
|
86944b0fb1 | ||
|
|
30355f8ee6 | ||
|
|
f298705ae4 | ||
|
|
90dd375eba | ||
|
|
64c5228c08 | ||
|
|
9ffb206050 | ||
|
|
e0ee5068dd | ||
|
|
225bf275ba | ||
|
|
cdc774f337 | ||
|
|
ca7868dc29 | ||
|
|
2f857761d0 | ||
|
|
5709b5f953 | ||
|
|
19fc0917c0 | ||
|
|
614a5b55bf | ||
|
|
2eed138026 | ||
|
|
5e6f09795c | ||
|
|
d57c59e7cb | ||
|
|
137a584e22 | ||
|
|
55ef8d3a10 | ||
|
|
5ae7817dc5 | ||
|
|
4727b0543d | ||
|
|
4edc2091e0 | ||
|
|
2d421b30ad | ||
|
|
b706d101eb | ||
|
|
19ebab97e8 | ||
|
|
a759143ae1 | ||
|
|
a513fbc395 | ||
|
|
c0ba8c526d | ||
|
|
18ad12d52b | ||
|
|
d437baa41c | ||
|
|
865e404826 | ||
|
|
d4278212b5 | ||
|
|
b4e3f069f1 | ||
|
|
827636c619 | ||
|
|
c2c26120d7 | ||
|
|
839645caf3 | ||
|
|
e00dd0d7d2 | ||
|
|
26fa84ebce | ||
|
|
db00b39a9a | ||
|
|
0c236e13bc | ||
|
|
1e7e8ac75d | ||
|
|
6aa6556bca | ||
|
|
ebbbd4f2b5 | ||
|
|
348b5a5a69 | ||
|
|
0a6227d667 | ||
|
|
7cf69a3b8d | ||
|
|
073710d7f2 | ||
|
|
f7159a0f76 | ||
|
|
18930aaf75 | ||
|
|
5c5d562266 | ||
|
|
91418d3e57 | ||
|
|
f567ea8228 | ||
|
|
17a10287d2 | ||
|
|
56f5f41ed4 | ||
|
|
be56b6f2c5 | ||
|
|
c12897e8e1 | ||
|
|
4fd4066d2f | ||
|
|
7fcfd9b565 | ||
|
|
3a16ebdf72 | ||
|
|
e5a260a569 | ||
|
|
33edf558a0 | ||
|
|
cc60c22c69 | ||
|
|
25a6a6d298 | ||
|
|
6e3d93d7cc | ||
|
|
ad04237d51 | ||
|
|
447ed0fbcb | ||
|
|
90223cf3eb | ||
|
|
cbf0667037 | ||
|
|
c1761366b5 | ||
|
|
7b30fc9922 | ||
|
|
fedfd430f9 | ||
|
|
ddcd476603 | ||
|
|
f30b62a74d | ||
|
|
f9b5172d95 | ||
|
|
de1fa8defb | ||
|
|
6245dd11cf | ||
|
|
ffbc3819e4 | ||
|
|
920ea74afe | ||
|
|
b42d987ad9 | ||
|
|
07f6c6481e | ||
|
|
1ee1835a3e | ||
|
|
42bb553544 | ||
|
|
19c7d4e29f | ||
|
|
a4e146693e | ||
|
|
040ea28e44 | ||
|
|
57a7e5e2c5 | ||
|
|
5fbb33cff5 | ||
|
|
abc9d96d19 | ||
|
|
73559e0dbc | ||
|
|
0e2dc4be30 | ||
|
|
39e4991856 | ||
|
|
69e2693342 | ||
|
|
ddee030dc7 | ||
|
|
e72e241d7a | ||
|
|
9068ff292c | ||
|
|
f45c7000d5 | ||
|
|
aa479b0124 | ||
|
|
3327cbe1f9 | ||
|
|
fb9bf032fb | ||
|
|
e7b1491fb8 | ||
|
|
0933fb8765 | ||
|
|
7582090eb0 | ||
|
|
21952f1cab | ||
|
|
029767ca63 | ||
|
|
aa9affb53f | ||
|
|
82d6ba7003 | ||
|
|
eb3a0342a8 | ||
|
|
2b7a73071a | ||
|
|
da92360208 | ||
|
|
55030c8302 | ||
|
|
2e795f3efd | ||
|
|
1ee1d01daa | ||
|
|
87e2ec341b | ||
|
|
e6f2687a83 | ||
|
|
b220d5c446 | ||
|
|
88e05a5472 | ||
|
|
d8dd2a09b0 | ||
|
|
ef4370bedc | ||
|
|
bdee1be7b3 | ||
|
|
dd6ee694df | ||
|
|
6dfa9ef85c | ||
|
|
fc87ac92af | ||
|
|
d420287583 | ||
|
|
46a750f94f | ||
|
|
63d5d28db6 | ||
|
|
22ecd0e568 | ||
|
|
3f2f7f8efa | ||
|
|
9dad146639 | ||
|
|
bbb6d30001 | ||
|
|
0fa2b16a07 | ||
|
|
df7d81b0b3 | ||
|
|
98d030f723 | ||
|
|
7313258b45 | ||
|
|
db88b625f9 | ||
|
|
7de0d07dd9 | ||
|
|
6b15b03898 | ||
|
|
c137866bd7 | ||
|
|
3d634914ce | ||
|
|
e44faef21c | ||
|
|
6f7074d21d | ||
|
|
9a12cd7e81 | ||
|
|
08fc1586c0 | ||
|
|
4e86d65aee | ||
|
|
2c0e3f61da | ||
|
|
5280360d6c | ||
|
|
c33b1777b6 | ||
|
|
b0c8727286 | ||
|
|
6f5fa6350d | ||
|
|
9d680ec662 | ||
|
|
7e80e034cc | ||
|
|
8f24ed4c7f | ||
|
|
3fe2a57b95 | ||
|
|
8127799f79 | ||
|
|
4b772fd698 | ||
|
|
65d0e2d241 | ||
|
|
d62bdaf938 | ||
|
|
45e3b0ce0e | ||
|
|
cc89be5a30 | ||
|
|
e8358125d9 | ||
|
|
cb1ed0d2f3 | ||
|
|
32371301d3 | ||
|
|
cf5dad76c1 | ||
|
|
a361541c10 | ||
|
|
b9597e5774 | ||
|
|
68dfc86173 | ||
|
|
73506f947c | ||
|
|
f0e6396b78 | ||
|
|
6acc6bc651 | ||
|
|
f6fd7e3fa4 | ||
|
|
05448dcedb | ||
|
|
374649a15b | ||
|
|
118b36bf45 | ||
|
|
3e218f2600 | ||
|
|
f4b5ae026c | ||
|
|
9d53afb709 | ||
|
|
4dedfcfd95 | ||
|
|
8e0c1c55fb | ||
|
|
99f0074362 | ||
|
|
5263fe4594 | ||
|
|
cd86c2638b | ||
|
|
bcbf09a202 | ||
|
|
ca7fd5a643 | ||
|
|
3627ec4de5 | ||
|
|
2901044520 | ||
|
|
cb136f37c7 | ||
|
|
76de0632ac | ||
|
|
8b3fca4ec5 | ||
|
|
2b1892e646 | ||
|
|
a1162e04b3 | ||
|
|
e87bccabc3 | ||
|
|
1a7f190cb9 | ||
|
|
66a68b4a58 | ||
|
|
6dc8de259a | ||
|
|
708cb61e82 | ||
|
|
b6ed605d4a | ||
|
|
6739d8bb50 | ||
|
|
4f0b0d78af | ||
|
|
9d775bad07 | ||
|
|
e6a58a7e71 | ||
|
|
e3828769e8 | ||
|
|
275d1b5212 | ||
|
|
aaa5329d39 | ||
|
|
005ea6cc18 | ||
|
|
0654364426 | ||
|
|
0027b0e76b | ||
|
|
33407189c1 | ||
|
|
44f9d68d8c | ||
|
|
c1faa848c5 | ||
|
|
c6263347de | ||
|
|
a3a0f1289a | ||
|
|
7b6ebf2785 | ||
|
|
6dc68b1d16 | ||
|
|
99b75f99df | ||
|
|
964f698095 | ||
|
|
4f20ee61c2 | ||
|
|
9e01441c5c | ||
|
|
9fe15dc83b | ||
|
|
b9b8a42fda | ||
|
|
b04aa56503 | ||
|
|
cde1d33e61 | ||
|
|
b3fdbfdf42 | ||
|
|
f3372bf982 | ||
|
|
234de0270a | ||
|
|
9c14bbe988 | ||
|
|
7c3c64208e | ||
|
|
b5e7817de2 | ||
|
|
fe849640ad | ||
|
|
fd79015c0f | ||
|
|
4cc1b77c3f | ||
|
|
9e9d8ffc7c | ||
|
|
faca77d77d | ||
|
|
ef72617c4a | ||
|
|
249e31b656 | ||
|
|
0261950395 | ||
|
|
1066e01707 | ||
|
|
61e63c10dc | ||
|
|
5125fc0a47 | ||
|
|
cabf9ddd98 | ||
|
|
612afee126 | ||
|
|
072a6ea333 | ||
|
|
a98ec6ec15 | ||
|
|
c8746fb588 | ||
|
|
99fbae0ec5 | ||
|
|
b5291e995f | ||
|
|
28eb093a1e | ||
|
|
abaebf3b34 | ||
|
|
9bf1f40af1 | ||
|
|
22a3a5651d | ||
|
|
308ee310de | ||
|
|
0778a80ee0 | ||
|
|
10df7a7eee | ||
|
|
9cf5f764e1 | ||
|
|
014d8deb60 | ||
|
|
1c4ced745c | ||
|
|
731959ef0e | ||
|
|
18429f1d1d | ||
|
|
77913ff17e | ||
|
|
dc5239b5ce | ||
|
|
c5e47e25a6 | ||
|
|
e7d5531cfa | ||
|
|
aecd4acfb4 | ||
|
|
18a05a9604 | ||
|
|
7339784e07 | ||
|
|
0e9b6e6dc9 | ||
|
|
fc5619764e | ||
|
|
57518cd0bf | ||
|
|
b584745506 | ||
|
|
473d9acdad | ||
|
|
8537920706 | ||
|
|
7e5fee4268 | ||
|
|
0006da1381 | ||
|
|
9ff2188c5d | ||
|
|
da6077a899 | ||
|
|
41147ae09a | ||
|
|
6fed10a09a | ||
|
|
f0fc2a8702 | ||
|
|
521a808151 | ||
|
|
abfb4cde51 | ||
|
|
43ab2f40b9 | ||
|
|
690d93c22a | ||
|
|
8a160f01ab | ||
|
|
a6a3abb295 | ||
|
|
84bcce3c25 | ||
|
|
96d7de6db1 | ||
|
|
9b1b55ba02 | ||
|
|
b3498cccb3 | ||
|
|
92c682cd10 | ||
|
|
472ca211ca | ||
|
|
812b64d4d3 | ||
|
|
605a8fc92e | ||
|
|
b819d2cc41 | ||
|
|
1f04af74f2 | ||
|
|
249650a07e | ||
|
|
4ebb7d1715 | ||
|
|
1a6d6b8ace | ||
|
|
f146620897 | ||
|
|
41b1af808f | ||
|
|
182454fe6b | ||
|
|
a063b73d5c | ||
|
|
d3aee544b6 | ||
|
|
bd4c2b0651 | ||
|
|
1f34c048b3 | ||
|
|
bfc66df13d | ||
|
|
1ed8e7ef98 | ||
|
|
e6e49ad73c | ||
|
|
0399839271 | ||
|
|
4b702bf6b7 | ||
|
|
4fe5afa755 | ||
|
|
209fb62d49 | ||
|
|
6cf6b587b5 | ||
|
|
a79d31fcfd | ||
|
|
0869e23700 | ||
|
|
625b92cbba | ||
|
|
9854342b9f | ||
|
|
a3dd580adc | ||
|
|
2bcd96928e | ||
|
|
2c6a023744 | ||
|
|
9a473b693a | ||
|
|
f4f9f1a618 | ||
|
|
2a54c353a9 | ||
|
|
96e2f1bdf0 | ||
|
|
3886f8db33 | ||
|
|
baea46c5ac | ||
|
|
fceef469c2 | ||
|
|
ae8f432a75 | ||
|
|
e1fbb74b41 | ||
|
|
d1f4d1514d | ||
|
|
861690ff29 | ||
|
|
223e3c38a1 | ||
|
|
9c0fe3957b | ||
|
|
152769aed9 | ||
|
|
dbf6b2d2ab | ||
|
|
f119d4d142 | ||
|
|
79a2320fd0 | ||
|
|
bb6eb9b13e | ||
|
|
2e7935767f | ||
|
|
89adfc9f01 | ||
|
|
7b73f84071 | ||
|
|
5cd7865c6c | ||
|
|
3f1be69359 | ||
|
|
83301ca787 | ||
|
|
8ad5580021 | ||
|
|
e2e8b7371d | ||
|
|
4bd0ca2cd7 | ||
|
|
5c639ff68a | ||
|
|
a49ce0e9ed | ||
|
|
1a8ab9d9de | ||
|
|
e0fb488e57 | ||
|
|
05565a0145 | ||
|
|
5f189acce4 | ||
|
|
7dc322c1eb | ||
|
|
8736190743 | ||
|
|
7f7348b470 | ||
|
|
58716b7541 | ||
|
|
600f39f966 | ||
|
|
a94c8b072e | ||
|
|
5a15f3833d | ||
|
|
54b69d2ef8 | ||
|
|
8f2342e13a | ||
|
|
8ab1139891 | ||
|
|
1f174f6681 | ||
|
|
bf7297d55c | ||
|
|
ad4f33cfc4 | ||
|
|
ecb93ab9ae | ||
|
|
dc227b579d | ||
|
|
7682eb88c4 | ||
|
|
b0e8a1569e | ||
|
|
1b210e7143 | ||
|
|
bb567e20b3 | ||
|
|
507e446475 | ||
|
|
478022afad | ||
|
|
edc3bede6e | ||
|
|
21fbc5e5ad | ||
|
|
43ef16c3e1 | ||
|
|
561b3d5650 | ||
|
|
a3cb63265d | ||
|
|
4ba9cedd68 | ||
|
|
6f683d9726 | ||
|
|
2209d3cb51 | ||
|
|
3815248786 | ||
|
|
02c1f8d416 | ||
|
|
c378c1cbcd | ||
|
|
89be0943e1 | ||
|
|
abcddfe090 | ||
|
|
5a97bf30d4 | ||
|
|
b33802ca7f | ||
|
|
575cd4b8ba | ||
|
|
68b931aef8 | ||
|
|
2dbe637478 | ||
|
|
479274775f | ||
|
|
ba91ac5948 | ||
|
|
cca5161289 | ||
|
|
354344d971 | ||
|
|
248dc17394 | ||
|
|
410d2febbb | ||
|
|
42fd47b246 | ||
|
|
46cd37abc9 | ||
|
|
b2a7d24770 | ||
|
|
3b33862b04 | ||
|
|
85748171ec | ||
|
|
0ee5c9536b | ||
|
|
ca6fcc92a1 | ||
|
|
8e8210b441 | ||
|
|
a21c97d011 | ||
|
|
dd50dc4c13 | ||
|
|
b567d27394 | ||
|
|
d64fff1fe0 | ||
|
|
c8b73e415a | ||
|
|
728c3eba67 | ||
|
|
a505bb5253 | ||
|
|
8bbefa77f7 | ||
|
|
3a80ece9fa | ||
|
|
fe59b5bbc7 | ||
|
|
8af92f844f | ||
|
|
f36c8a09e6 | ||
|
|
0e2858af94 | ||
|
|
5ba71ef91f | ||
|
|
a957e2dc6b | ||
|
|
99a97c917a | ||
|
|
09304026ae | ||
|
|
b95ad63201 | ||
|
|
2ed978eb79 | ||
|
|
31ed6f1604 | ||
|
|
ac6235e53d | ||
|
|
f90b86b577 | ||
|
|
1c71bd1242 | ||
|
|
a0d9a58616 | ||
|
|
d99f54b51b | ||
|
|
4d49cee194 | ||
|
|
dcbe0f2a31 | ||
|
|
cc48e15f28 | ||
|
|
a43e7112e5 | ||
|
|
6c7a031367 | ||
|
|
645149d77b | ||
|
|
9ec9f004e1 | ||
|
|
0fe984d575 | ||
|
|
69f8e47e9e | ||
|
|
db6e261794 | ||
|
|
5cfc9fed79 | ||
|
|
40b1c5c448 | ||
|
|
e9945ee6ee | ||
|
|
cca024da2b | ||
|
|
1ec45b11ab | ||
|
|
4ae188bfc7 | ||
|
|
7f4053084c | ||
|
|
37202a1b70 | ||
|
|
b886cbea0b | ||
|
|
9f396fddc6 | ||
|
|
2434984336 | ||
|
|
1afa5e257b | ||
|
|
cba7b6ee6e | ||
|
|
03b4f81679 | ||
|
|
1dd226fde7 | ||
|
|
ded327b9fc | ||
|
|
ecc1f2310c | ||
|
|
866d7d5152 | ||
|
|
91551c09d4 | ||
|
|
70f7c9f355 | ||
|
|
10673bff4c | ||
|
|
642d9ffe24 | ||
|
|
8b82f52e75 | ||
|
|
a7cdfaa325 | ||
|
|
a6037a9eb8 | ||
|
|
23220d43f3 | ||
|
|
ad8b644de1 | ||
|
|
95b95b1407 | ||
|
|
cfaf213980 | ||
|
|
5baa0c300f | ||
|
|
2d88cbe496 | ||
|
|
8369624512 | ||
|
|
ee1c40e5c5 | ||
|
|
2f2a4396c6 | ||
|
|
cb17f1ede2 | ||
|
|
42e4eef749 | ||
|
|
7613fd12ec | ||
|
|
f735fac91b | ||
|
|
f0710115c5 | ||
|
|
8c920682e6 | ||
|
|
9905ab5087 | ||
|
|
b3bbc8b769 | ||
|
|
3a5cd90631 | ||
|
|
3e3de8cee2 | ||
|
|
687395ebda | ||
|
|
e5325c2274 | ||
|
|
3461ceebc0 | ||
|
|
133badb297 | ||
|
|
86ccd8fecb | ||
|
|
f6afd95ef8 | ||
|
|
022228e0aa | ||
|
|
8ad4bd6c1b | ||
|
|
9f223e98b7 | ||
|
|
2102b4e7b3 | ||
|
|
ebdfa06685 | ||
|
|
41094aa3c7 | ||
|
|
09abc29b73 | ||
|
|
5b7b9821e0 | ||
|
|
ee18288eeb | ||
|
|
f856da6690 | ||
|
|
5cdbfc9064 | ||
|
|
068ff76a10 | ||
|
|
b7737f1732 | ||
|
|
d06bcf4c97 | ||
|
|
dd538c2969 | ||
|
|
f56c4187a4 | ||
|
|
1fd874b7ea | ||
|
|
5ff245790d | ||
|
|
1cfc0a3203 | ||
|
|
a128e35927 | ||
|
|
dd93c300bb | ||
|
|
14f83a46d0 | ||
|
|
5969551a5c | ||
|
|
7fa890462d | ||
|
|
78a0bbb38b | ||
|
|
e2414c4a4f | ||
|
|
d11803d7b4 | ||
|
|
19dd9866da | ||
|
|
f080f29292 | ||
|
|
8571e568e0 | ||
|
|
fe145b12cd | ||
|
|
0f11a79e02 | ||
|
|
ac9e44a831 | ||
|
|
3673107bc4 | ||
|
|
b9d4f55228 | ||
|
|
37694e9f51 | ||
|
|
2cd168467e | ||
|
|
cc386e4b3b | ||
|
|
2681568f2b | ||
|
|
5c1e7349bb | ||
|
|
9f46d516fa | ||
|
|
60a939bd01 | ||
|
|
0056a5aea1 | ||
|
|
b36d3e0261 | ||
|
|
efbe1383e6 | ||
|
|
c7b43786ad | ||
|
|
a11cf1decd | ||
|
|
9a1feb5b10 | ||
|
|
71c7aaee83 | ||
|
|
faa2945606 | ||
|
|
1a4c10e950 | ||
|
|
f3fbb50b68 | ||
|
|
a6657d6b21 | ||
|
|
0a1ce53990 | ||
|
|
2678fb3441 | ||
|
|
6fc6c736f9 | ||
|
|
28401ddd91 | ||
|
|
7bd043e9ee | ||
|
|
acf106ced0 | ||
|
|
2f726bbd1c | ||
|
|
02d6040003 | ||
|
|
2fcdf3df34 | ||
|
|
aedde6dcde | ||
|
|
ef148ab3cb | ||
|
|
03b622b356 | ||
|
|
9ab59dd6ac | ||
|
|
9ab4e70d17 | ||
|
|
91c7059d98 | ||
|
|
d90ae6dffa | ||
|
|
9ab0d2305c | ||
|
|
9bddef74df | ||
|
|
4e50809c78 | ||
|
|
7f748f27bc | ||
|
|
543118ac70 | ||
|
|
57bd27b3e7 | ||
|
|
5ca224f75b | ||
|
|
89239d554d | ||
|
|
a08dabf015 | ||
|
|
9a258edc10 | ||
|
|
111011b2c2 | ||
|
|
108259925a | ||
|
|
639f6fea8c | ||
|
|
f5b24635b6 | ||
|
|
0522c7c1f6 | ||
|
|
2f51b9e418 | ||
|
|
4f532948f7 | ||
|
|
0740c257b1 | ||
|
|
490f5fc585 | ||
|
|
642bd67126 | ||
|
|
4833a8b532 | ||
|
|
d45e1c4adc | ||
|
|
3de8102e7f | ||
|
|
665766f8bb | ||
|
|
2eb1cb077d | ||
|
|
c22f3e1d29 | ||
|
|
b18d302d44 | ||
|
|
5be9aa417a | ||
|
|
7a3e2cc063 | ||
|
|
e1153f4d2e | ||
|
|
7b7499dd70 | ||
|
|
f0fe18cd22 | ||
|
|
f487b527ec | ||
|
|
6cc4fd6ede | ||
|
|
115e76ae12 | ||
|
|
a4a07ba996 | ||
|
|
70af3b126a | ||
|
|
45abf3d38a | ||
|
|
9799d3de2d | ||
|
|
a591e8f9e4 | ||
|
|
de8033747c | ||
|
|
fba87f8998 | ||
|
|
d8d5f85ab7 | ||
|
|
b4e8d9869f | ||
|
|
b270fcef2f | ||
|
|
244d795325 | ||
|
|
e5fb259872 | ||
|
|
ba097beb17 | ||
|
|
1397570eea | ||
|
|
57ede1369f | ||
|
|
95c8007b8f | ||
|
|
805d82e1be | ||
|
|
6e4b9af080 | ||
|
|
c8323a0bf1 | ||
|
|
4b04050953 | ||
|
|
f65510b1d1 | ||
|
|
7f87329fca | ||
|
|
6c127efb2d | ||
|
|
b053dc8697 | ||
|
|
bff499113e | ||
|
|
ee01d24a45 | ||
|
|
e9beef31eb | ||
|
|
cff9ee7cce | ||
|
|
07dc3e5425 | ||
|
|
e857249d86 | ||
|
|
8ace1ab1b0 | ||
|
|
00e26ceffe | ||
|
|
4ad3fe78f9 | ||
|
|
297ed97166 | ||
|
|
0fce533e70 | ||
|
|
3a3657b107 | ||
|
|
d677556e62 | ||
|
|
1b7b1bc294 | ||
|
|
ef6674d1d1 | ||
|
|
e70912df26 | ||
|
|
0bb2d87cfd | ||
|
|
ebf1df58da | ||
|
|
7c30831e8f | ||
|
|
df4db50632 | ||
|
|
54f367b119 | ||
|
|
f66cc1b851 | ||
|
|
a0ab0b16fe | ||
|
|
5992c1b469 | ||
|
|
8d14ffbe88 | ||
|
|
a5d3d6f665 | ||
|
|
a12a8f7977 | ||
|
|
0f1c9f25cf | ||
|
|
8abaa025ec | ||
|
|
621c98f15a | ||
|
|
bcfc52cb85 | ||
|
|
5c9ec0d8e9 | ||
|
|
284b8d94d4 | ||
|
|
bb5dea02b9 | ||
|
|
711109d468 | ||
|
|
ed9a6e34ad | ||
|
|
571989f564 | ||
|
|
fdd65e5fad | ||
|
|
7c2532d9f9 | ||
|
|
94d183eaaa | ||
|
|
9d09738e4d | ||
|
|
ef11164c0c | ||
|
|
34dc4a5e03 | ||
|
|
0e9b7aab3c | ||
|
|
9781f3766d | ||
|
|
9e716025b6 | ||
|
|
eee6ae33e8 | ||
|
|
b1dd373f5a | ||
|
|
286dd9b308 | ||
|
|
595150be86 | ||
|
|
08094f3cc2 | ||
|
|
24dbac8da7 | ||
|
|
18dc4153c7 | ||
|
|
4505710565 | ||
|
|
05dabb7239 | ||
|
|
49852220f9 | ||
|
|
6b6f759e7a | ||
|
|
149c0593ab | ||
|
|
26defdf205 | ||
|
|
5161dd3b2e | ||
|
|
a93d01fb4d | ||
|
|
797c77a00a | ||
|
|
a177d0282f | ||
|
|
1b987952b5 | ||
|
|
410f573226 | ||
|
|
024d1aa227 | ||
|
|
b1d8c0f9c3 | ||
|
|
90bf989002 | ||
|
|
79c16b9a90 | ||
|
|
83018ac54a | ||
|
|
ad52dbe044 | ||
|
|
8bddc1adab | ||
|
|
e8dbc35613 | ||
|
|
3d546e0d01 | ||
|
|
a5999a62cd | ||
|
|
761b3d0c12 | ||
|
|
bdb4cf6c59 | ||
|
|
7205d3b2d2 | ||
|
|
bb5c29107e | ||
|
|
3f45630180 | ||
|
|
51581b7e43 | ||
|
|
b0544c8cde | ||
|
|
e347e932af | ||
|
|
0dfa1eef25 | ||
|
|
aa5ba177cc | ||
|
|
41f918499b | ||
|
|
d3e316eec5 | ||
|
|
45ec65e1cc | ||
|
|
05d91c5f50 | ||
|
|
d6b36f12ff | ||
|
|
824d31a21c | ||
|
|
0083087e01 | ||
|
|
1923ac3358 | ||
|
|
698d0f0a44 | ||
|
|
ec0459e139 | ||
|
|
d5e73c39fc | ||
|
|
a144c723a1 | ||
|
|
a28614e65d | ||
|
|
8ab1d22a82 | ||
|
|
b6289f7022 | ||
|
|
875eea1330 | ||
|
|
7c76ae1814 | ||
|
|
c142e5264d | ||
|
|
5d7eabb93f | ||
|
|
f1146a1fef | ||
|
|
55b71223d4 | ||
|
|
db86bd6c01 | ||
|
|
13fa61744c | ||
|
|
8fe4e0879c | ||
|
|
6bec9547c6 | ||
|
|
bfc28cacbe | ||
|
|
b2a787ca69 | ||
|
|
eb1b86a5ec | ||
|
|
7159c293af | ||
|
|
eb0ccf7286 | ||
|
|
35752e07fa | ||
|
|
57925c50bf | ||
|
|
0e871b490e | ||
|
|
ed4f66185f | ||
|
|
3d645c0ce1 | ||
|
|
8830b8d082 | ||
|
|
73641e492c | ||
|
|
c2429ca0cf | ||
|
|
7834ffbbf1 | ||
|
|
fa82ced414 | ||
|
|
9cc30b18f7 | ||
|
|
db0dfb4b08 | ||
|
|
5eed33ef08 | ||
|
|
31ae1bc2ff | ||
|
|
6932e6330e | ||
|
|
a124dae35a | ||
|
|
5203340b64 | ||
|
|
ed0e40dee8 | ||
|
|
8b759c24e6 | ||
|
|
1499b85ac6 | ||
|
|
fcdab6a62d | ||
|
|
5c94538c7d | ||
|
|
2eae9daae7 | ||
|
|
55c962fda2 | ||
|
|
eb7f39f0aa | ||
|
|
7310cfc557 | ||
|
|
42ad0effdd | ||
|
|
bce63e4dff | ||
|
|
9302523d34 | ||
|
|
a9ecef1fa9 | ||
|
|
e59b8b0c37 | ||
|
|
3743e8995a | ||
|
|
4c9b40ca0e | ||
|
|
d625186ce5 | ||
|
|
caf3349f01 | ||
|
|
6239ce20af | ||
|
|
54de0e1d79 | ||
|
|
056443ccbd | ||
|
|
7d68c46feb | ||
|
|
734128930f | ||
|
|
cc0cd538e6 | ||
|
|
ca4f22be85 | ||
|
|
c3520bfa52 | ||
|
|
2029e104d4 | ||
|
|
7c76f4a71f | ||
|
|
95382060eb | ||
|
|
472d7731d6 | ||
|
|
28f2dd612e | ||
|
|
8467e7e10a | ||
|
|
8f7cd53204 | ||
|
|
68fe8623ad | ||
|
|
8243cc0a5d | ||
|
|
95d55b8da1 | ||
|
|
f83c49baa3 | ||
|
|
cf0aad391c | ||
|
|
42732990cd | ||
|
|
f82246171b | ||
|
|
5b50eb18fc | ||
|
|
29824a8cf6 | ||
|
|
0db26fc3ab | ||
|
|
8991fe2e90 | ||
|
|
2211770d8b | ||
|
|
e25113bcf0 | ||
|
|
e1535d2bd8 | ||
|
|
d5bf68d77d | ||
|
|
5b95fd0521 | ||
|
|
fcacba268d | ||
|
|
d7eaeaf636 | ||
|
|
2e13c3cdfd | ||
|
|
d726afd9e4 | ||
|
|
1480a6ca14 | ||
|
|
02a07f19a1 | ||
|
|
d2ed39f103 | ||
|
|
8b15f18993 | ||
|
|
b256e3a44f | ||
|
|
939274281a | ||
|
|
be4b100ae5 | ||
|
|
f99d4ba7c4 | ||
|
|
1f4e9681f7 | ||
|
|
f56256f488 | ||
|
|
f18e2933d4 | ||
|
|
2f819d1647 | ||
|
|
821df406c9 | ||
|
|
3bb7c75db3 | ||
|
|
c94eaa0e6c | ||
|
|
a16439e38e | ||
|
|
b6e613c771 | ||
|
|
c5f230e682 | ||
|
|
ba0375bf06 | ||
|
|
13ad532412 | ||
|
|
8ecc311bcc | ||
|
|
e3831d8ecc | ||
|
|
9c0536deda | ||
|
|
6b42bd7abf | ||
|
|
0d246aa435 | ||
|
|
c5f35b7ff9 | ||
|
|
ff602cb906 | ||
|
|
1806e5511e | ||
|
|
cb93316fed | ||
|
|
a6f0fa90f7 | ||
|
|
30a16e3a87 | ||
|
|
3db46fa9bf | ||
|
|
12cb82af91 | ||
|
|
d49b514aa6 | ||
|
|
b6e1d82685 | ||
|
|
6cd5c8fca5 | ||
|
|
67aee78fdf | ||
|
|
c48db4fbba | ||
|
|
f8b03f5750 | ||
|
|
2c07829be2 | ||
|
|
652c694244 | ||
|
|
995fa3af36 | ||
|
|
4323b35198 | ||
|
|
fd50f5465f | ||
|
|
13d2c470be | ||
|
|
b690a8be2f | ||
|
|
e85804efa2 | ||
|
|
e26ad2026c | ||
|
|
03162970cd | ||
|
|
bc2b7d4f09 | ||
|
|
f77d6b7a2d | ||
|
|
1fdb16866b | ||
|
|
6ebf14143a | ||
|
|
cf5dac9563 | ||
|
|
2e1c825b90 | ||
|
|
a974ce6257 | ||
|
|
5d81cb6ac7 | ||
|
|
41356ac267 | ||
|
|
86af599a18 | ||
|
|
95e36dfe74 | ||
|
|
24b5f62090 | ||
|
|
989e636d98 | ||
|
|
eec78fbd1e | ||
|
|
70d4cf2cd9 | ||
|
|
52692e299d | ||
|
|
fd2bc150d8 | ||
|
|
267afa5a3b | ||
|
|
7ec153889c | ||
|
|
efc795920b | ||
|
|
d3fd287efb | ||
|
|
0fa19ed555 | ||
|
|
52fdf5b7ec | ||
|
|
a09196c4ae | ||
|
|
1d8997633c | ||
|
|
0898b6b482 | ||
|
|
848b8b983e | ||
|
|
465d08d99f | ||
|
|
f07510e2b6 | ||
|
|
b8b391ad18 | ||
|
|
81dae2f88e | ||
|
|
74811679b7 | ||
|
|
93f5fcae1e | ||
|
|
92d4e3e75a | ||
|
|
03f1aea069 | ||
|
|
6da88339f5 | ||
|
|
e0e8d5061d | ||
|
|
62e73b17d2 | ||
|
|
799a90ecfa | ||
|
|
ef168979bf | ||
|
|
2093cf425f | ||
|
|
a3462daeb1 | ||
|
|
a334a941c4 | ||
|
|
1cdb8abf30 | ||
|
|
fbdb5beb59 | ||
|
|
2f372ab4d6 | ||
|
|
524ce43e23 | ||
|
|
7f8e139413 | ||
|
|
99d79d0a80 | ||
|
|
0ca1bf3cfd | ||
|
|
c18984c452 | ||
|
|
445c0b1482 | ||
|
|
0590c2a4f6 | ||
|
|
81ec856a0f | ||
|
|
2410bc603b | ||
|
|
45cadbd4f3 | ||
|
|
02a5a678f6 | ||
|
|
98f534e172 | ||
|
|
a68c8cf5f1 | ||
|
|
604fc92943 | ||
|
|
008d93928f | ||
|
|
601619660d | ||
|
|
4aa07c3547 | ||
|
|
f3f7c5cc57 | ||
|
|
c035046999 | ||
|
|
e15cd64ac9 | ||
|
|
59a4ac71f9 | ||
|
|
7c04351a57 | ||
|
|
46f787950a | ||
|
|
6a244b3a8d | ||
|
|
3cf8b9ea86 | ||
|
|
df8a14e12a | ||
|
|
f6ec26075d | ||
|
|
c42206db02 | ||
|
|
bb64012914 | ||
|
|
d5cc53a4e1 | ||
|
|
55100918cc | ||
|
|
faee571850 | ||
|
|
6f422785c3 | ||
|
|
a7affc93ba | ||
|
|
9052131aef | ||
|
|
6b5e0efd1e | ||
|
|
62eb7ebeba | ||
|
|
c48fd9d842 | ||
|
|
e150dd4a66 | ||
|
|
b3d73e0aff | ||
|
|
16946a6f00 | ||
|
|
a4383075af | ||
|
|
20a60be550 | ||
|
|
7afefcf75d | ||
|
|
40b3443c8f | ||
|
|
e3167068d9 | ||
|
|
cc964b4609 | ||
|
|
370a84192e | ||
|
|
4104ff2b6a | ||
|
|
a0162dacf6 | ||
|
|
b2cc186d22 | ||
|
|
235a6617c4 | ||
|
|
218a8c4d90 | ||
|
|
e68d6e7924 | ||
|
|
dc72aa2305 | ||
|
|
93b10bcf3c | ||
|
|
4971e3735e | ||
|
|
6d56abcec1 | ||
|
|
5d63abb473 | ||
|
|
6e67bb7ae6 | ||
|
|
d67835260d | ||
|
|
b085344b91 | ||
|
|
c108eaba42 | ||
|
|
6ce3ce69b9 | ||
|
|
6826521ec5 | ||
|
|
5fe62660aa | ||
|
|
7a28f68ad0 | ||
|
|
ea9d44bede | ||
|
|
fd3692b36f | ||
|
|
cd7b6fdbc1 | ||
|
|
571e17410a | ||
|
|
797fbbf826 | ||
|
|
a37b5c9c61 | ||
|
|
30f3baabaf | ||
|
|
ef29f321e0 | ||
|
|
15bca92b2c | ||
|
|
71f6bc41eb | ||
|
|
6d2f16a7ae | ||
|
|
40b279e3a3 | ||
|
|
5d8b089188 | ||
|
|
9686d93ff6 | ||
|
|
67ebe16b40 | ||
|
|
6ab6488e5a | ||
|
|
ffdbefe22c | ||
|
|
456e2d7ed5 | ||
|
|
fa3d1f98e0 | ||
|
|
c21b69e73e | ||
|
|
9318bd3b0d | ||
|
|
59448d635c | ||
|
|
a9a4fb641f | ||
|
|
f247b3b99b | ||
|
|
fa62c5afb6 | ||
|
|
061c7b633f | ||
|
|
dacc07136c | ||
|
|
abfc37076a | ||
|
|
9a0f388f66 | ||
|
|
b08e6221e0 | ||
|
|
0efda9cd6b | ||
|
|
f4ebbcbf70 | ||
|
|
36ecad6cbe | ||
|
|
22568a3d26 | ||
|
|
8e798e4c28 | ||
|
|
736e340bde | ||
|
|
05c93ff3ae | ||
|
|
8d4c65f259 | ||
|
|
0435d9c338 | ||
|
|
15a5f3278a | ||
|
|
34bbd0ded1 | ||
|
|
c17f37857c | ||
|
|
a2e09b4c9d | ||
|
|
5013155e58 | ||
|
|
7575e119d6 | ||
|
|
3b9b897af3 | ||
|
|
0cfd21cc15 | ||
|
|
05a98b6be0 | ||
|
|
52b9363745 | ||
|
|
f947fafec9 | ||
|
|
68d3cdd722 | ||
|
|
5770dc58b9 | ||
|
|
36da7a918f | ||
|
|
782d2fab83 | ||
|
|
d9c5d3c868 | ||
|
|
9b3122e92c | ||
|
|
f44d4a1d86 | ||
|
|
33a2943e8c | ||
|
|
a1a7e7cd24 | ||
|
|
6957911657 | ||
|
|
7cc36b7703 | ||
|
|
9407b42f97 | ||
|
|
151f29a17a | ||
|
|
f7dc354f42 | ||
|
|
4d870f665b | ||
|
|
0635423e73 | ||
|
|
3f34bf4465 | ||
|
|
9f0fdc68a9 | ||
|
|
701b4130bd | ||
|
|
d27bccdff1 | ||
|
|
5ff03ce5ac | ||
|
|
6eea2a409e | ||
|
|
ea74820176 | ||
|
|
50de1a6885 | ||
|
|
055d100548 | ||
|
|
63efd26767 | ||
|
|
8d2cb0ef9b | ||
|
|
2bff6e5188 | ||
|
|
453d0494fb | ||
|
|
97c6073d39 | ||
|
|
9fe6fa7f44 | ||
|
|
7699ed3fc8 | ||
|
|
5eca556fe7 | ||
|
|
4602c00dcf | ||
|
|
629d66e0b9 | ||
|
|
859c132ee2 | ||
|
|
99a0e2469b | ||
|
|
2548c43175 | ||
|
|
90bcaaf582 | ||
|
|
da8307cd26 | ||
|
|
cfa06c3f38 | ||
|
|
906965b48b | ||
|
|
d5bbbbd41d | ||
|
|
8e05229e62 | ||
|
|
7a8d50a803 | ||
|
|
6630cfbe16 | ||
|
|
dd25fbcb4b | ||
|
|
f9ac73732b | ||
|
|
26342588ab | ||
|
|
29191eb2c7 | ||
|
|
168d546304 | ||
|
|
34133ca7f3 | ||
|
|
4b32f16747 | ||
|
|
99c900946d | ||
|
|
39213a1847 | ||
|
|
c18b1328a5 | ||
|
|
93ef6aefce | ||
|
|
2e9e1909da | ||
|
|
4f67e8d0c3 | ||
|
|
30cba446f2 | ||
|
|
dda65c0877 | ||
|
|
cf80199bfc | ||
|
|
6694330bb2 | ||
|
|
a5a49c350d | ||
|
|
6ae2d74fca | ||
|
|
29ad012763 | ||
|
|
9570cedff6 | ||
|
|
d3871ed774 | ||
|
|
34db8df6d9 | ||
|
|
092706eff8 | ||
|
|
f4a1a5e94c | ||
|
|
dadfaed829 | ||
|
|
e365943a70 | ||
|
|
86fcfc74da | ||
|
|
eecebbf186 | ||
|
|
8dc1737e39 | ||
|
|
34bb9b5766 | ||
|
|
299e01722f | ||
|
|
97ee4578c9 | ||
|
|
0d3f9ba913 | ||
|
|
6aa44d62ad | ||
|
|
5641ee3f94 | ||
|
|
2e9fbbc978 | ||
|
|
ad634c0a94 | ||
|
|
7190f46938 | ||
|
|
e27cd96494 | ||
|
|
4caa45b8bb | ||
|
|
f3473b9eba | ||
|
|
06a984e4ff | ||
|
|
53f10f4d46 | ||
|
|
ed0cd78e05 | ||
|
|
faf04b009b | ||
|
|
965bad626a | ||
|
|
69445cb4a0 | ||
|
|
30c97391d7 | ||
|
|
cacb8d410e | ||
|
|
4b388ee902 | ||
|
|
10865f9952 | ||
|
|
dfaccdd03b | ||
|
|
f812260c23 | ||
|
|
b6da6569c4 | ||
|
|
bbcef2fd33 | ||
|
|
ec3cbf81c4 | ||
|
|
1a471b0a45 | ||
|
|
73b8aa8bcc | ||
|
|
394045f68a | ||
|
|
f9af8e0390 | ||
|
|
1260349384 | ||
|
|
74f4ed5fd2 | ||
|
|
91725ddced | ||
|
|
e055e4a092 | ||
|
|
f26cc3b957 | ||
|
|
9a3b1ec222 | ||
|
|
9141d11a7d | ||
|
|
6dc4f31ba1 | ||
|
|
d294aa4356 | ||
|
|
f314ee3d6a | ||
|
|
581ad6fc29 | ||
|
|
8ff7d934b2 | ||
|
|
5bdebf5ab0 | ||
|
|
96250b7ad3 | ||
|
|
7c9278bd92 | ||
|
|
4205c91609 | ||
|
|
75c4075345 | ||
|
|
f8398339a3 | ||
|
|
9bf9e7ac5c | ||
|
|
567b21b1d6 | ||
|
|
fa7d63d9d1 | ||
|
|
46a94cce56 | ||
|
|
bc50202d0d | ||
|
|
8fc8e158e2 | ||
|
|
06e7d087f2 | ||
|
|
fbff38de33 | ||
|
|
19b4002f25 | ||
|
|
b47cc4bc66 | ||
|
|
e307ceeee7 | ||
|
|
4745c7a00d | ||
|
|
5c783e1a63 | ||
|
|
05ad0c9e06 | ||
|
|
6d7b5c9513 | ||
|
|
de001e05da | ||
|
|
08ce0579aa | ||
|
|
be60600a47 | ||
|
|
f2265b10e4 | ||
|
|
afa865587e | ||
|
|
9ea353569a | ||
|
|
1bc59f7290 | ||
|
|
563a20fc82 | ||
|
|
6cca1fc512 | ||
|
|
6833f96c14 | ||
|
|
2304c145f3 | ||
|
|
fa6f697dbb | ||
|
|
91a98f919d | ||
|
|
616dbd67f7 | ||
|
|
6fc0fd315c | ||
|
|
9de2549dfb | ||
|
|
81fb420457 | ||
|
|
8b77f1db2c | ||
|
|
a154e2ea1a | ||
|
|
5fe8d574ca | ||
|
|
a9dc7fa7cc | ||
|
|
9d3d7426aa | ||
|
|
a597c66afe | ||
|
|
21fefbc8f6 | ||
|
|
38020d9068 | ||
|
|
1b0a5eb54a | ||
|
|
071f7aea82 | ||
|
|
32b3f7f2d2 | ||
|
|
576217d33a | ||
|
|
b8b595c6b2 | ||
|
|
a93445f3fe | ||
|
|
dbcb3dd1ae | ||
|
|
d6ab6ee370 | ||
|
|
c9294e30d9 | ||
|
|
d7715f71ad | ||
|
|
b2ed0a902b | ||
|
|
18159c85b9 | ||
|
|
d7755de116 | ||
|
|
7631921366 | ||
|
|
803abb58f9 | ||
|
|
a3250dfac7 | ||
|
|
4f9158e533 | ||
|
|
e624b9aa6a | ||
|
|
2fc1b9b5e0 | ||
|
|
026375da49 | ||
|
|
58a629b02e | ||
|
|
df6590abfc | ||
|
|
33af9948e5 | ||
|
|
8ab6298f30 | ||
|
|
78c308c835 | ||
|
|
8a2bf21cee | ||
|
|
59f44c1189 | ||
|
|
02219dcd79 | ||
|
|
f0d207f380 | ||
|
|
7dd09cecda | ||
|
|
e75b68e391 | ||
|
|
8d360c5a57 | ||
|
|
f6900f0689 | ||
|
|
8759a5a63e | ||
|
|
52bdbc42bb | ||
|
|
28e00b68fd | ||
|
|
2ff09158f3 | ||
|
|
6764c26954 | ||
|
|
040159c02f | ||
|
|
61c6c83de4 | ||
|
|
0be32c9d42 | ||
|
|
aa1bf31bcb | ||
|
|
c023b0532a | ||
|
|
f8aaba6704 | ||
|
|
26cf42049d | ||
|
|
06d4f39e7b | ||
|
|
a1e36a9a37 | ||
|
|
11da41e106 | ||
|
|
7a5b9152e9 | ||
|
|
7876d533cf | ||
|
|
e99de88c5c | ||
|
|
bcb82da88f | ||
|
|
592fd61788 | ||
|
|
3c875267af | ||
|
|
455ce37398 | ||
|
|
64befb27eb | ||
|
|
177565567e | ||
|
|
8045e56df2 | ||
|
|
206a4e17b5 | ||
|
|
2785bf9cb2 | ||
|
|
bc2f2ad546 | ||
|
|
4fce730326 | ||
|
|
9206f363ff | ||
|
|
130e33a4e7 | ||
|
|
a36989a860 | ||
|
|
1946343d5b | ||
|
|
4ccf43d753 | ||
|
|
7ca68c6492 | ||
|
|
61a869a1f5 | ||
|
|
c718951e97 | ||
|
|
04ea044917 | ||
|
|
66219f23bb | ||
|
|
187a12e90a | ||
|
|
356c0bf751 | ||
|
|
7a9c873093 | ||
|
|
d7537777c3 | ||
|
|
145aefc9d1 | ||
|
|
2b2e20da24 | ||
|
|
a977c79f9f | ||
|
|
f52ec0df7c | ||
|
|
54043df8fb | ||
|
|
fad1e108d8 | ||
|
|
fc3e82584b | ||
|
|
a0afb6ec8e | ||
|
|
549deb51d6 | ||
|
|
4f842d9f1b | ||
|
|
9627fe6be6 | ||
|
|
b8ddb11796 | ||
|
|
f04cc227a6 | ||
|
|
811bc1b8e5 | ||
|
|
ccb291ce66 | ||
|
|
676f5c4b31 | ||
|
|
14083a0857 | ||
|
|
b4f5b5556f | ||
|
|
fa4f9197ee | ||
|
|
bfb5a678d2 | ||
|
|
d2572315ca | ||
|
|
467b774d13 | ||
|
|
78a1424582 | ||
|
|
82d6aa0c97 | ||
|
|
1213578eb7 | ||
|
|
268d027770 | ||
|
|
f55fbe037a | ||
|
|
3a95ff7435 | ||
|
|
d70715a635 | ||
|
|
54a9058ee0 | ||
|
|
efb5256d28 | ||
|
|
a4c0fead1f | ||
|
|
35775b3bc5 | ||
|
|
7417d8e86e | ||
|
|
df84c466c1 | ||
|
|
bf3a8c6383 | ||
|
|
5605e46acb | ||
|
|
3346c7f455 | ||
|
|
b78b2b6b35 | ||
|
|
0f43d5df6a | ||
|
|
30b9d7f00e | ||
|
|
b9f49cee45 | ||
|
|
c144580c98 | ||
|
|
2ff8c12bf9 | ||
|
|
335cffe9a9 | ||
|
|
bc40ab378c | ||
|
|
d81276607c | ||
|
|
3bc3b34d97 | ||
|
|
f0a1d69f50 | ||
|
|
0672936134 | ||
|
|
3632478b8d | ||
|
|
c07fa70d58 | ||
|
|
ee7f2413ed | ||
|
|
12ebf21be5 | ||
|
|
691eea9b45 | ||
|
|
7e6f3364bc | ||
|
|
3f430627df | ||
|
|
3160c03843 | ||
|
|
420a3f4a01 | ||
|
|
9eb48312c7 | ||
|
|
469caa1a14 | ||
|
|
3aca8a938c | ||
|
|
01d46a1751 | ||
|
|
9c859d2655 | ||
|
|
fb5dbe13c2 | ||
|
|
e4c359d8b9 | ||
|
|
52256d7a73 | ||
|
|
aa974c0dc3 | ||
|
|
23d3539fcb | ||
|
|
bcff7274f4 | ||
|
|
e9deaf2ca5 | ||
|
|
e1bceb2adb | ||
|
|
34428fc709 | ||
|
|
393274d142 | ||
|
|
a8e08d14bb | ||
|
|
bf9b9026d9 | ||
|
|
0f096f9ad4 | ||
|
|
db55e596d2 | ||
|
|
82c5aa82d2 | ||
|
|
742d1889c5 | ||
|
|
61042c7606 | ||
|
|
3e4f7228a0 | ||
|
|
76e0e09aca | ||
|
|
e4deffcbe8 | ||
|
|
de5f902487 | ||
|
|
cab9237d95 | ||
|
|
6ecf9e091c | ||
|
|
aa69598b57 | ||
|
|
f47084968d | ||
|
|
6a8e8e92a7 | ||
|
|
c7edde6ca4 | ||
|
|
379e2c694b | ||
|
|
29d5f5d760 | ||
|
|
258bc85b9c | ||
|
|
fc1d4f5362 | ||
|
|
cda222d2ec | ||
|
|
07b4228988 | ||
|
|
ad1eee7aa5 | ||
|
|
9c1b3735b4 | ||
|
|
ab0338f6ae | ||
|
|
39fc16954b | ||
|
|
f5289c546e | ||
|
|
721f924e15 | ||
|
|
6611c16099 | ||
|
|
2c5151726c | ||
|
|
5eff7f38df | ||
|
|
e9ca4305a6 | ||
|
|
125deafc84 | ||
|
|
1445673e18 | ||
|
|
4a17d8ef97 | ||
|
|
b4fff6b9b7 | ||
|
|
2245b0ac94 | ||
|
|
e561beab44 | ||
|
|
3bcd9d747b | ||
|
|
85a71a3923 | ||
|
|
a30751464a | ||
|
|
1678548353 | ||
|
|
7218c45443 | ||
|
|
bd914d49f1 | ||
|
|
fed112e497 | ||
|
|
c3be4c4629 | ||
|
|
286d678785 | ||
|
|
42ae135d38 | ||
|
|
42f5d4404d | ||
|
|
5c098dc7ad | ||
|
|
3dba6fc95c | ||
|
|
1eee82272a | ||
|
|
da5b7bea78 | ||
|
|
910cdc0537 | ||
|
|
02a501705a | ||
|
|
a9d9fb5d75 | ||
|
|
ffbc7e723d | ||
|
|
3ef56576d3 | ||
|
|
cde8e02bf2 | ||
|
|
1d24e96074 | ||
|
|
be432c8654 | ||
|
|
3778a69fbe | ||
|
|
d807a5c314 | ||
|
|
5862a05fb1 | ||
|
|
dba14bfe90 | ||
|
|
2e257f40e6 | ||
|
|
cdb2bec909 | ||
|
|
dd5061d73b | ||
|
|
7a18a0fb34 | ||
|
|
28d3f74614 | ||
|
|
98c7b23178 | ||
|
|
89dc8c2004 | ||
|
|
e274fc732b |
346
.github/CODEOWNERS
vendored
Normal file
346
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
* @rycee
|
||||||
|
|
||||||
|
/flake.nix @bqv @kisik21
|
||||||
|
|
||||||
|
/modules/home-environment.nix @rycee
|
||||||
|
|
||||||
|
/modules/i18n/input-method @Kranzes
|
||||||
|
/tests/modules/i18n/input-method @Kranzes
|
||||||
|
|
||||||
|
/modules/misc/dconf.nix @gnidorah @rycee
|
||||||
|
|
||||||
|
/modules/misc/fontconfig.nix @rycee
|
||||||
|
/tests/modules/misc/fontconfig @rycee
|
||||||
|
|
||||||
|
/modules/misc/gtk.nix @rycee
|
||||||
|
|
||||||
|
/modules/config/i18n.nix @midchildan
|
||||||
|
/tests/modules/config/i18n @midchildan
|
||||||
|
|
||||||
|
/modules/misc/news.nix @rycee
|
||||||
|
|
||||||
|
/modules/misc/numlock.nix @evanjs
|
||||||
|
/tests/modules/misc/numlock @evanjs
|
||||||
|
|
||||||
|
/modules/misc/pam.nix @rycee
|
||||||
|
/tests/modules/misc/pam @rycee
|
||||||
|
|
||||||
|
/modules/misc/qt.nix @rycee
|
||||||
|
|
||||||
|
/modules/misc/submodule-support.nix @rycee
|
||||||
|
|
||||||
|
/modules/misc/tmpfiles.nix @dawidsowa
|
||||||
|
|
||||||
|
/modules/misc/vte.nix @rycee
|
||||||
|
|
||||||
|
/modules/misc/xdg-mime-apps.nix @pacien
|
||||||
|
|
||||||
|
/modules/misc/xdg-user-dirs.nix @pacien
|
||||||
|
|
||||||
|
/modules/misc/xdg-system-dirs.nix @tadfisher
|
||||||
|
/tests/modules/misc/xdg/system-dirs.nix @tadfisher
|
||||||
|
|
||||||
|
/modules/misc/xdg-desktop-entries.nix @cwyc
|
||||||
|
/tests/modules/misc/xdg/desktop-entries.nix @cwyc
|
||||||
|
/tests/modules/misc/xdg/desktop-full-expected.desktop @cwyc
|
||||||
|
/tests/modules/misc/xdg/desktop-min-expected.desktop @cwyc
|
||||||
|
|
||||||
|
/modules/programs/aria2.nix @JustinLovinger
|
||||||
|
|
||||||
|
/modules/programs/autojump.nix @evanjs
|
||||||
|
/tests/modules/programs/autojump @evanjs
|
||||||
|
|
||||||
|
/modules/programs/autorandr.nix @uvNikita
|
||||||
|
|
||||||
|
/modules/programs/bash.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/bat.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/beets.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/broot.nix @aheaume
|
||||||
|
|
||||||
|
/modules/programs/dircolors.nix @JustinLovinger
|
||||||
|
|
||||||
|
/modules/programs/direnv.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/eclipse.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/emacs.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/exa.nix @kalhauge
|
||||||
|
|
||||||
|
/modules/programs/firefox.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/foot.nix @plabadens
|
||||||
|
/tests/modules/programs/foot @plabadens
|
||||||
|
|
||||||
|
/modules/programs/gh.nix @Gerschtli
|
||||||
|
/tests/modules/programs/gh @Gerschtli
|
||||||
|
|
||||||
|
/modules/programs/git.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/gnome-terminal.nix @kamadorueda @rycee
|
||||||
|
|
||||||
|
/modules/programs/go.nix @rvolosatovs
|
||||||
|
|
||||||
|
/modules/programs/himalaya.nix @ambroisie
|
||||||
|
/tests/modules/programs/himalaya @ambroisie
|
||||||
|
|
||||||
|
/modules/programs/home-manager.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/htop.nix @bjpbakker
|
||||||
|
|
||||||
|
/modules/programs/i3status.nix @JustinLovinger
|
||||||
|
|
||||||
|
/modules/programs/i3status-rust.nix @workflow
|
||||||
|
|
||||||
|
/modules/programs/keychain.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/lazygit.nix @kalhauge
|
||||||
|
|
||||||
|
/modules/programs/lesspipe.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/lf.nix @owm111
|
||||||
|
/tests/modules/programs/lf @owm111
|
||||||
|
|
||||||
|
/modules/programs/lieer.nix @tadfisher
|
||||||
|
|
||||||
|
/modules/programs/lsd.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/matplotlib.nix @rprospero
|
||||||
|
|
||||||
|
/modules/programs/mangohud.nix @ZerataX
|
||||||
|
/tests/modules/programs/mangohud @ZerataX
|
||||||
|
|
||||||
|
/modules/programs/mbsync.nix @KarlJoad
|
||||||
|
/tests/modules/programs/mbsync @KarlJoad
|
||||||
|
|
||||||
|
/modules/programs/mcfly.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/mpv.nix @tadeokondrak @thiagokokada
|
||||||
|
/tests/modules/programs/mpv @thiagokokada
|
||||||
|
|
||||||
|
/modules/programs/mu.nix @KarlJoad
|
||||||
|
|
||||||
|
/modules/programs/ncmpcpp.nix @olmokramer
|
||||||
|
/tests/modules/programs/ncmpcpp @olmokramer
|
||||||
|
/tests/modules/programs/ncmpcpp-linux @olmokramer
|
||||||
|
|
||||||
|
/modules/programs/ncspot.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/ne.nix @cwyc
|
||||||
|
/tests/modules/programs/ne @cwyc
|
||||||
|
|
||||||
|
/modules/programs/newsboat.nix @sumnerevans
|
||||||
|
/tests/modules/programs/newsboat @sumnerevans
|
||||||
|
|
||||||
|
/modules/programs/nix-index.nix @ambroisie
|
||||||
|
/tests/modules/programs/nix-index @ambroisie
|
||||||
|
|
||||||
|
/modules/programs/noti.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/nushell.nix @Philipp-M
|
||||||
|
/tests/modules/programs/nushell @Philipp-M
|
||||||
|
|
||||||
|
/modules/programs/obs-studio.nix @adisbladis
|
||||||
|
|
||||||
|
/modules/programs/octant.nix @06kellyjac
|
||||||
|
|
||||||
|
/modules/programs/opam.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/openssh.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/password-store.nix @pacien
|
||||||
|
|
||||||
|
/modules/programs/pazi.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/pidgin.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/piston-cli.nix @ethancedwards8
|
||||||
|
|
||||||
|
/modules/programs/powerline-go.nix @DamienCassou
|
||||||
|
|
||||||
|
/modules/programs/rbw.nix @ambroisie
|
||||||
|
/tests/modules/programs/rbw @ambroisie
|
||||||
|
|
||||||
|
/modules/programs/rofi.nix @thiagokokada
|
||||||
|
/tests/modules/programs/rofi @thiagokokada
|
||||||
|
|
||||||
|
/modules/programs/rofi-pass.nix @seylerius
|
||||||
|
/tests/modules/programs/rofi-pass @seylerius
|
||||||
|
|
||||||
|
/modules/programs/rtorrent.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/sbt.nix @kubukoz
|
||||||
|
/tests/modules/programs/sbt @kubukoz
|
||||||
|
|
||||||
|
/modules/programs/scmpuff.nix @cpcloud
|
||||||
|
/tests/modules/programs/scmpuff @cpcloud
|
||||||
|
|
||||||
|
/modules/programs/senpai.nix @malte-v
|
||||||
|
|
||||||
|
/modules/programs/sm64ex.nix @ivarwithoutbones
|
||||||
|
/tests/modules/programs/sm64ex @ivarwithoutbones
|
||||||
|
|
||||||
|
/modules/programs/ssh.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/starship.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/terminator.nix @chisui
|
||||||
|
|
||||||
|
/modules/programs/texlive.nix @rycee
|
||||||
|
|
||||||
|
/modules/programs/topgrade.nix @msfjarvis
|
||||||
|
/tests/modules/programs/topgrade @msfjarvis
|
||||||
|
|
||||||
|
/modules/programs/waybar.nix @berbiche
|
||||||
|
/tests/modules/programs/waybar @berbiche
|
||||||
|
|
||||||
|
/modules/programs/xmobar.nix @t4ccer
|
||||||
|
/tests/modules/programs/xmobar @t4ccer
|
||||||
|
|
||||||
|
/modules/programs/z-lua.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/zathura.nix @rprospero
|
||||||
|
|
||||||
|
/modules/programs/zoxide.nix @marsam
|
||||||
|
|
||||||
|
/modules/programs/zsh/prezto.nix @NickHu
|
||||||
|
|
||||||
|
/modules/services/barrier.nix @Kritnich
|
||||||
|
/tests/modules/services/barrier @Kritnich
|
||||||
|
|
||||||
|
/modules/services/caffeine.nix @uvNikita
|
||||||
|
|
||||||
|
/modules/services/cbatticon.nix @pmiddend
|
||||||
|
|
||||||
|
/modules/services/clipmenu.nix @DamienCassou
|
||||||
|
|
||||||
|
/modules/services/devilspie2.nix @dawidsowa
|
||||||
|
/tests/modules/services/devilspie2 @dawidsowa
|
||||||
|
|
||||||
|
/modules/services/dropbox.nix @eyJhb
|
||||||
|
/tests/modules/services/dropbox @eyJhb
|
||||||
|
|
||||||
|
/modules/services/dunst.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/emacs.nix @tadfisher
|
||||||
|
|
||||||
|
/modules/services/etesync-dav.nix @Valodim
|
||||||
|
|
||||||
|
/modules/services/flameshot.nix @moredhel
|
||||||
|
|
||||||
|
/modules/services/fluidsynth.nix @Valodim
|
||||||
|
|
||||||
|
/modules/services/gnome-keyring.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/gpg-agent.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/grobi.nix @mbrgm
|
||||||
|
|
||||||
|
/modules/services/hound.nix @adisbladis
|
||||||
|
|
||||||
|
/modules/services/imapnotify.nix @nickhu
|
||||||
|
|
||||||
|
/modules/services/kanshi.nix @nurelin
|
||||||
|
/tests/modules/services/kanshi @nurelin
|
||||||
|
|
||||||
|
/modules/services/kdeconnect.nix @adisbladis
|
||||||
|
|
||||||
|
/modules/services/keepassx.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/lieer.nix @tadfisher
|
||||||
|
|
||||||
|
/modules/services/lorri.nix @Gerschtli
|
||||||
|
|
||||||
|
/modules/services/mako.nix @onny
|
||||||
|
|
||||||
|
/modules/services/mbsync.nix @pjones
|
||||||
|
|
||||||
|
/modules/services/mpdris2.nix @pjones
|
||||||
|
|
||||||
|
/modules/services/mpris-proxy.nix @ThibautMarty
|
||||||
|
|
||||||
|
/modules/services/muchsync.nix @pacien
|
||||||
|
|
||||||
|
/modules/services/network-manager-applet.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/pantalaimon.nix @jojosch
|
||||||
|
/tests/modules/services/pantalaimon @jojosch
|
||||||
|
|
||||||
|
/modules/services/parcellite.nix @gleber
|
||||||
|
|
||||||
|
/modules/services/pass-secret-service.nix @cab404
|
||||||
|
|
||||||
|
/modules/services/password-store-sync.nix @pacien
|
||||||
|
|
||||||
|
/modules/services/pasystray.nix @pltanton
|
||||||
|
|
||||||
|
/modules/services/pbgopy.nix @ivarwithoutbones
|
||||||
|
/tests/modules/services/pbgopy @ivarwithoutbones
|
||||||
|
|
||||||
|
/modules/services/plan9port.nix @ehmry
|
||||||
|
|
||||||
|
/modules/services/playerctld.nix @fendse
|
||||||
|
/tests/modules/playerctld @fendse
|
||||||
|
|
||||||
|
/modules/services/poweralertd.nix @ThibautMarty
|
||||||
|
|
||||||
|
/modules/services/pulseeffects.nix @jonringer
|
||||||
|
|
||||||
|
/modules/services/random-background.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada
|
||||||
|
/tests/modules/redshift-gammastep @thiagokokada
|
||||||
|
|
||||||
|
/modules/services/status-notifier-watcher.nix @pltanton
|
||||||
|
|
||||||
|
/modules/services/syncthing.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/taffybar.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/tahoe-lafs.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/taskwarrior-sync.nix @minijackson @pacien
|
||||||
|
|
||||||
|
/modules/services/trayer.nix @AndreasMager
|
||||||
|
/tests/modules/services/trayer @AndreasMager
|
||||||
|
|
||||||
|
/modules/services/udiskie.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/unison.nix @pacien
|
||||||
|
|
||||||
|
/modules/services/window-managers/bspwm @ncfavier
|
||||||
|
/tests/modules/services/window-managers/bspwm @ncfavier
|
||||||
|
|
||||||
|
/modules/services/window-managers/i3-sway/i3.nix @sumnerevans
|
||||||
|
/tests/modules/services/window-managers/i3 @sumnerevans
|
||||||
|
|
||||||
|
/modules/services/window-managers/i3-sway/lib @sumnerevans
|
||||||
|
|
||||||
|
/modules/services/window-managers/i3-sway/sway.nix @alexarice @sumnerevans
|
||||||
|
/tests/modules/services/window-managers/sway @sumnerevans
|
||||||
|
|
||||||
|
/modules/services/wlsunset.nix @matrss
|
||||||
|
/tests/modules/services/wlsunset @matrss
|
||||||
|
|
||||||
|
/modules/services/xcape.nix @nickhu
|
||||||
|
|
||||||
|
/modules/services/xembed-sni-proxy.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/xidlehook.nix @dschrempf
|
||||||
|
|
||||||
|
/modules/services/xscreensaver.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/xsuspender.nix @offlinehacker
|
||||||
|
|
||||||
|
/modules/systemd.nix @rycee
|
||||||
|
|
||||||
|
/modules/xcursor.nix @league
|
||||||
|
|
||||||
|
/modules/xresources.nix @rycee
|
||||||
|
|
||||||
|
/modules/xsession.nix @rycee
|
||||||
|
|
||||||
|
/modules/services/volnoti.nix @IvanMalison
|
||||||
15
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Ask for a new feature to be added (module, program, etc.)
|
||||||
|
title: ''
|
||||||
|
labels: feature request
|
||||||
|
assignees: rycee, berbiche, sumnerevans
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Note: Please search to see if the feature has already been requested
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
|
||||||
46
.github/ISSUE_TEMPLATE/issue.yaml
vendored
Normal file
46
.github/ISSUE_TEMPLATE/issue.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: File a bug/issue
|
||||||
|
title: 'bug: '
|
||||||
|
labels: [bug, triage]
|
||||||
|
|
||||||
|
# We cannot use nix-community/home-manager
|
||||||
|
# See https://github.com/dear-github/dear-github/issues/170
|
||||||
|
assignees: [rycee, berbiche, sumnerevans]
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Is there an existing issue for this?
|
||||||
|
description: |
|
||||||
|
Please search to see if an issue already exists for the bug you encountered.
|
||||||
|
options:
|
||||||
|
- label: I have searched the existing issues
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Issue description
|
||||||
|
description: |
|
||||||
|
Please describe the issue.
|
||||||
|
|
||||||
|
For support and help please use the IRC channel #home-manager at irc.oftc.net or
|
||||||
|
Matrix room <https://matrix.to/#/#hm:rycee.net> instead.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Maintainer CC
|
||||||
|
description: |
|
||||||
|
Please @ people who are in the `meta.maintainers` list of the offending module.
|
||||||
|
If in doubt, check `git blame` for whoever last touched something.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: system
|
||||||
|
attributes:
|
||||||
|
label: System information
|
||||||
|
description: |
|
||||||
|
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.
|
||||||
|
render: markdown
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
### Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Please provide a brief description of your change.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Please go through the following checklist before opening a non-WIP
|
||||||
|
pull-request.
|
||||||
|
|
||||||
|
Also make sure to read the guidelines found at
|
||||||
|
|
||||||
|
https://github.com/nix-community/home-manager/blob/master/doc/contributing.adoc#sec-guidelines
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] Change is backwards compatible.
|
||||||
|
|
||||||
|
- [ ] Code formatted with `./format`.
|
||||||
|
|
||||||
|
- [ ] Code tested through `nix-shell --pure tests -A run.all`.
|
||||||
|
|
||||||
|
- [ ] Test cases updated/added. See [example](https://github.com/nix-community/home-manager/commit/f3fbb50b68df20da47f9b0def5607857fcc0d021#diff-b61a6d542f9036550ba9c401c80f00ef).
|
||||||
|
|
||||||
|
- [ ] Commit messages are formatted like
|
||||||
|
|
||||||
|
```
|
||||||
|
{component}: {description}
|
||||||
|
|
||||||
|
{long description}
|
||||||
|
```
|
||||||
|
|
||||||
|
See [CONTRIBUTING](https://github.com/nix-community/home-manager/blob/master/doc/contributing.adoc#sec-commit-style) for more information and [recent commit messages](https://github.com/nix-community/home-manager/commits/master) for examples.
|
||||||
|
|
||||||
|
- If this PR adds a new module
|
||||||
|
|
||||||
|
- [ ] Added myself as module maintainer. See [example](https://github.com/nix-community/home-manager/blob/068ff76a10e95820f886ac46957edcff4e44621d/modules/programs/lesspipe.nix#L6).
|
||||||
|
|
||||||
|
- [ ] Added myself and the module files to `.github/CODEOWNERS`.
|
||||||
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
target-branch: "master"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
commit-message:
|
||||||
|
prefix: "ci:"
|
||||||
|
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
target-branch: "release-20.09"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
commit-message:
|
||||||
|
prefix: "ci:"
|
||||||
75
.github/stale.yml
vendored
Normal file
75
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Configuration for probot-stale - https://github.com/probot/stale
|
||||||
|
daysUntilStale: 90
|
||||||
|
daysUntilClose: 7
|
||||||
|
staleLabel: "status: stale"
|
||||||
|
closeComment: false
|
||||||
|
issues:
|
||||||
|
markComment: |
|
||||||
|
<p>
|
||||||
|
Thank you for your contribution!
|
||||||
|
I marked this issue as stale due to inactivity.
|
||||||
|
If this remains inactive for another 7 days, I will close this issue.
|
||||||
|
<b>Please read the relevant sections below before commenting.</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>If you are the original author of the issue</b></summary>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
* If this is resolved, please consider closing it so that the maintainers know not to focus on this.
|
||||||
|
* If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
|
||||||
|
* If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>If you are <i>not</i> the original author of the issue</b></summary>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
* If you are also experiencing this issue, please add details of your situation to help with the debugging process.
|
||||||
|
* If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Memorandum on closing issues</b></summary>
|
||||||
|
<p>
|
||||||
|
If you have nothing of substance to add, please refrain from commenting and allow the bot close the issue.
|
||||||
|
Also, don't be afraid to manually close an issue, even if it holds valuable information.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost!
|
||||||
|
Closing obsolete issues is an important way to help maintainers focus their time and effort.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
pulls:
|
||||||
|
markComment: |
|
||||||
|
<p>
|
||||||
|
Thank you for your contribution!
|
||||||
|
I marked this pull request as stale due to inactivity.
|
||||||
|
If this remains inactive for another 7 days, I will close this PR.
|
||||||
|
<b>Please read the relevant sections below before commenting.</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>If you are the original author of the PR</b></summary>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
* GitHub sometimes doesn't notify people who commented / reviewed a PR previously, when you (force) push commits. *If you have addressed the reviews* you can [officially ask for a review](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from those who commented to you or anyone else.
|
||||||
|
* If it is unfinished but you plan to finish it, please mark it as a draft.
|
||||||
|
* If you don't expect to work on it any time soon, please consider closing it with a short comment encouraging someone else to pick up your work.
|
||||||
|
* To get things rolling again, rebase the PR against the target branch and address valid comments.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>If you are <i>not</i> the original author of the issue</b></summary>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
* If you want to pick up the work on this PR, please create a new PR and indicate that it supercedes and closes this PR.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
28
.github/workflows/github_pages.yml
vendored
Normal file
28
.github/workflows/github_pages.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: GitHub Pages
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: cachix/install-nix-action@v13
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@v10
|
||||||
|
with:
|
||||||
|
name: nix-community
|
||||||
|
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||||
|
- run: |
|
||||||
|
nix-build -A docs.html
|
||||||
|
cp -r result/share/doc/home-manager public
|
||||||
|
- name: Deploy
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: ./public
|
||||||
23
.github/workflows/test.yml
vendored
Normal file
23
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: Test
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 2 * * *"
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: cachix/install-nix-action@v13
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
|
- uses: cachix/cachix-action@v10
|
||||||
|
with:
|
||||||
|
name: nix-community
|
||||||
|
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||||
|
- run: ./format -c
|
||||||
|
- run: nix-shell . -A install
|
||||||
|
- run: nix-shell --pure tests -A run.all
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/flake.lock
|
||||||
|
/result*
|
||||||
43
.gitlab-ci.yml
Normal file
43
.gitlab-ci.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
image: nixos/nix:latest
|
||||||
|
|
||||||
|
variables:
|
||||||
|
NIX_PATH: "nixpkgs=channel:nixos-unstable"
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- test
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
Run tests:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- nix-shell --pure tests -A run.files-text
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
when: always
|
||||||
|
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- mkdir -p ~/.config/nixpkgs
|
||||||
|
- echo '{ manual.html.enable = true; }' > ~/.config/nixpkgs/home.nix
|
||||||
|
- nix-shell . -A install
|
||||||
|
- mkdir public
|
||||||
|
- cp -r ~/.nix-profile/share/doc/home-manager/* public/
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
when: always
|
||||||
|
|
||||||
|
Deploy NUR:
|
||||||
|
stage: deploy
|
||||||
|
variables:
|
||||||
|
HM_BRANCH: $CI_COMMIT_REF_NAME
|
||||||
|
HM_COMMIT_SHA: $CI_COMMIT_SHA
|
||||||
|
trigger:
|
||||||
|
project: rycee/nur-expressions
|
||||||
|
branch: master
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH =~ /^release-/
|
||||||
|
when: always
|
||||||
1
CONTRIBUTING.adoc
Symbolic link
1
CONTRIBUTING.adoc
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
doc/contributing.adoc
|
||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2017 Robert Helgesson
|
Copyright (c) 2017-2020 Home Manager contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
275
README.md
275
README.md
@@ -3,89 +3,149 @@ Home Manager using Nix
|
|||||||
|
|
||||||
This project provides a basic system for managing a user environment
|
This project provides a basic system for managing a user environment
|
||||||
using the [Nix][] package manager together with the Nix libraries
|
using the [Nix][] package manager together with the Nix libraries
|
||||||
found in [Nixpkgs][]. Before attempting to use Home Manager please
|
found in [Nixpkgs][]. It allows declarative configuration of user
|
||||||
read the warning below.
|
specific (non global) packages and dotfiles.
|
||||||
|
|
||||||
|
Before attempting to use Home Manager please read the warning below.
|
||||||
|
|
||||||
|
For a more systematic overview of Home Manager and its available
|
||||||
|
options, please see the [Home Manager manual][manual].
|
||||||
|
|
||||||
Words of warning
|
Words of warning
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
This project is under development. I personally use it to manage
|
Unfortunately, it is quite possible to get difficult to understand
|
||||||
several user configurations but it may fail catastrophically for you.
|
errors when working with Home Manager, such as infinite loops with no
|
||||||
So beware!
|
clear source reference. You should therefore be comfortable using the
|
||||||
|
Nix language and the various tools in the Nix ecosystem. Reading
|
||||||
|
through the [Nix Pills][] document is a good way to familiarize
|
||||||
|
yourself with them.
|
||||||
|
|
||||||
|
If you are not very familiar with Nix but still want to use Home
|
||||||
|
Manager then you are strongly encouraged to start with a small and
|
||||||
|
very simple configuration and gradually make it more elaborate as you
|
||||||
|
learn.
|
||||||
|
|
||||||
In some cases Home Manager cannot detect whether it will overwrite a
|
In some cases Home Manager cannot detect whether it will overwrite a
|
||||||
previous manual configuration. For example, the Gnome Terminal module
|
previous manual configuration. For example, the Gnome Terminal module
|
||||||
will write to your dconf store and cannot tell whether a configuration
|
will write to your dconf store and cannot tell whether a configuration
|
||||||
that it is about to be overwrite was from a previous Home Manager
|
that it is about to be overwritten was from a previous Home Manager
|
||||||
generation or from manual configuration.
|
generation or from manual configuration.
|
||||||
|
|
||||||
Home Manager targets [NixOS][] version 17.03 (the current stable
|
Home Manager targets [NixOS][] unstable and NixOS version 21.05 (the
|
||||||
version), it may or may not work on other Linux distributions and
|
current stable version), it may or may not work on other Linux
|
||||||
NixOS versions.
|
distributions and NixOS versions.
|
||||||
|
|
||||||
Also, the `home-manager` tool does not explicitly support rollbacks at
|
Also, the `home-manager` tool does not explicitly support rollbacks at
|
||||||
the moment so if your home directory gets messed up you'll have to fix
|
the moment so if your home directory gets messed up you'll have to fix
|
||||||
it yourself (you can attempt to run the activation script for the
|
it yourself. See the [rollbacks](#rollbacks) section for instructions
|
||||||
desired generation).
|
on how to manually perform a rollback.
|
||||||
|
|
||||||
Now when your expectations have been built up and you are eager to try
|
Now when your expectations have been built up and you are eager to try
|
||||||
all this out you can go ahead and read the rest of this text.
|
all this out you can go ahead and read the rest of this text.
|
||||||
|
|
||||||
|
Contact
|
||||||
|
-------
|
||||||
|
|
||||||
|
You can chat with us on IRC in the channel [#home-manager][] on
|
||||||
|
[OFTC][].
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Currently the easiest way to install Home Manager is as follows:
|
Currently the easiest way to install Home Manager is as follows:
|
||||||
|
|
||||||
1. Make sure you have a working Nix installation. If you are not
|
1. Make sure you have a working Nix installation. Specifically, make
|
||||||
using NixOS then you may here have to run
|
sure that your user is able to build and install Nix packages. For
|
||||||
|
example, you should be able to successfully run a command like
|
||||||
|
`nix-instantiate '<nixpkgs>' -A hello` without having to switch to
|
||||||
|
the root user. For a multi-user install of Nix this means that
|
||||||
|
your user must be covered by the
|
||||||
|
[`allowed-users`][nixAllowedUsers] Nix option. On NixOS you can
|
||||||
|
control this option using the
|
||||||
|
[`nix.allowedUsers`][nixosAllowedUsers] system option.
|
||||||
|
|
||||||
```
|
Note that Nix 2.4 (`nixUnstable`) is not yet supported.
|
||||||
$ mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
|
|
||||||
|
2. Add the appropriate Home Manager channel. If you are following
|
||||||
|
Nixpkgs master or an unstable channel you can run
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||||
|
$ nix-channel --update
|
||||||
```
|
```
|
||||||
|
|
||||||
since Home Manager uses these directories to manage your profile
|
and if you follow a Nixpkgs version 21.05 channel you can run
|
||||||
generations. On NixOS these should already be available.
|
|
||||||
|
|
||||||
2. Clone the Home Manager repository into the `~/.config/nixpkgs`
|
```console
|
||||||
directory:
|
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||||
|
$ nix-channel --update
|
||||||
```
|
|
||||||
$ git clone https://github.com/rycee/home-manager ~/.config/nixpkgs/home-manager
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Add Home Manager to your user's Nixpkgs, for example by adding it
|
On NixOS you may need to log out and back in for the channel to
|
||||||
to the `packageOverrides` section in your
|
become available. On non-NixOS you may have to add
|
||||||
`~/.config/nixpkgs/config.nix` file:
|
|
||||||
|
|
||||||
```nix
|
```shell
|
||||||
{
|
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||||
packageOverrides = pkgs: rec {
|
|
||||||
home-manager = import ./home-manager { inherit pkgs; };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Install the `home-manager` package:
|
to your shell (see [nix#2033](https://github.com/NixOS/nix/issues/2033)).
|
||||||
|
|
||||||
|
3. Install Home Manager and create the first Home Manager generation:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nix-shell '<home-manager>' -A install
|
||||||
|
```
|
||||||
|
|
||||||
|
Once finished, Home Manager should be active and available in your
|
||||||
|
user environment.
|
||||||
|
|
||||||
|
3. If you do not plan on having Home Manager manage your shell
|
||||||
|
configuration then you must source the
|
||||||
|
|
||||||
```
|
```
|
||||||
$ nix-env -f '<nixpkgs>' -iA home-manager
|
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||||
installing ‘home-manager’
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
file in your shell configuration. Unfortunately, in this specific
|
||||||
|
case we currently only support POSIX.2-like shells such as
|
||||||
|
[Bash][] or [Z shell][].
|
||||||
|
|
||||||
|
For example, if you use Bash then add
|
||||||
|
|
||||||
|
```bash
|
||||||
|
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||||
|
```
|
||||||
|
|
||||||
|
or this when managing home configuration together with system
|
||||||
|
configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
. "/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh"
|
||||||
|
```
|
||||||
|
|
||||||
|
to your `~/.profile` file.
|
||||||
|
|
||||||
|
If instead of using channels you want to run Home Manager from a Git
|
||||||
|
checkout of the repository then you can use the
|
||||||
|
`programs.home-manager.path` option to specify the absolute path to
|
||||||
|
the repository.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
The `home-manager` package installs a tool that is conveniently called
|
Home Manager is typically managed through the `home-manager` tool.
|
||||||
`home-manager`. This tool can apply configurations to your home
|
This tool can, for example, apply configurations to your home
|
||||||
directory, list user packages installed by the tool, and list the
|
directory, list user packages installed by the tool, and list the
|
||||||
configuration generations.
|
configuration generations.
|
||||||
|
|
||||||
As an example, let us set up a very simple configuration that installs
|
As an example, let us expand the initial configuration file from the
|
||||||
the htop and fortune packages, installs Emacs with a few extra
|
installation above to install the htop and fortune packages, install
|
||||||
packages enabled, installs Firefox with Adobe Flash enabled, and
|
Emacs with a few extra packages enabled, install Firefox with
|
||||||
enables the user gpg-agent service.
|
smooth scrolling disabled, and enable the user gpg-agent service.
|
||||||
|
|
||||||
First create a file `~/.config/nixpkgs/home.nix` containing
|
To satisfy the above setup we should elaborate the
|
||||||
|
`~/.config/nixpkgs/home.nix` file as follows:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
@@ -106,7 +166,13 @@ First create a file `~/.config/nixpkgs/home.nix` containing
|
|||||||
|
|
||||||
programs.firefox = {
|
programs.firefox = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableAdobeFlash = true;
|
profiles = {
|
||||||
|
myprofile = {
|
||||||
|
settings = {
|
||||||
|
"general.smoothScroll" = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.gpg-agent = {
|
services.gpg-agent = {
|
||||||
@@ -114,28 +180,75 @@ First create a file `~/.config/nixpkgs/home.nix` containing
|
|||||||
defaultCacheTtl = 1800;
|
defaultCacheTtl = 1800;
|
||||||
enableSshSupport = true;
|
enableSshSupport = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
programs.home-manager = {
|
||||||
|
enable = true;
|
||||||
|
path = "…";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To activate this configuration you can then run
|
To activate this configuration you can then run
|
||||||
|
|
||||||
```
|
```console
|
||||||
$ home-manager switch
|
$ home-manager switch
|
||||||
```
|
```
|
||||||
|
|
||||||
or if you are not feeling so lucky,
|
or if you are not feeling so lucky,
|
||||||
|
|
||||||
```
|
```console
|
||||||
$ home-manager build
|
$ home-manager build
|
||||||
```
|
```
|
||||||
|
|
||||||
which will create a `result` link to a directory containing an
|
which will create a `result` link to a directory containing an
|
||||||
activation script and the generated home directory files.
|
activation script and the generated home directory files.
|
||||||
|
|
||||||
|
Documentation of available configuration options, including
|
||||||
|
descriptions and usage examples, is available in the [Home Manager
|
||||||
|
manual][configuration options] or offline by running
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ man home-configuration.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
Rollbacks
|
||||||
|
---------
|
||||||
|
|
||||||
|
While the `home-manager` tool does not explicitly support rollbacks at
|
||||||
|
the moment it is relatively easy to perform one manually. The steps to
|
||||||
|
do so are
|
||||||
|
|
||||||
|
1. Run `home-manager generations` to determine which generation you
|
||||||
|
wish to rollback to:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ home-manager generations
|
||||||
|
2018-01-04 11:56 : id 765 -> /nix/store/kahm1rxk77mnvd2l8pfvd4jkkffk5ijk-home-manager-generation
|
||||||
|
2018-01-03 10:29 : id 764 -> /nix/store/2wsmsliqr5yynqkdyjzb1y57pr5q2lsj-home-manager-generation
|
||||||
|
2018-01-01 12:21 : id 763 -> /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
|
||||||
|
2017-12-29 21:03 : id 762 -> /nix/store/6c0k1r03fxckql4vgqcn9ccb616ynb94-home-manager-generation
|
||||||
|
2017-12-25 18:51 : id 761 -> /nix/store/czc5y6vi1rvnkfv83cs3rn84jarcgsgh-home-manager-generation
|
||||||
|
…
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Copy the Nix store path of the generation you chose, e.g.,
|
||||||
|
|
||||||
|
/nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
|
||||||
|
|
||||||
|
for generation 763.
|
||||||
|
|
||||||
|
3. Run the `activate` script inside the copied store path:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation/activate
|
||||||
|
Starting home manager activation
|
||||||
|
…
|
||||||
|
```
|
||||||
|
|
||||||
Keeping your ~ safe from harm
|
Keeping your ~ safe from harm
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
To configure programs and services the Home Manager must write various
|
To configure programs and services Home Manager must write various
|
||||||
things to your home directory. To prevent overwriting any existing
|
things to your home directory. To prevent overwriting any existing
|
||||||
files when switching to a new generation, Home Manager will attempt to
|
files when switching to a new generation, Home Manager will attempt to
|
||||||
detect collisions between existing files and generated files. If any
|
detect collisions between existing files and generated files. If any
|
||||||
@@ -143,7 +256,7 @@ such collision is detected the activation will terminate before
|
|||||||
changing anything on your computer.
|
changing anything on your computer.
|
||||||
|
|
||||||
For example, suppose you have a wonderful, painstakingly created
|
For example, suppose you have a wonderful, painstakingly created
|
||||||
`~/.gitconfig` and add
|
`~/.config/git/config` and add
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
@@ -162,11 +275,11 @@ For example, suppose you have a wonderful, painstakingly created
|
|||||||
to your configuration. Attempting to switch to the generation will
|
to your configuration. Attempting to switch to the generation will
|
||||||
then result in
|
then result in
|
||||||
|
|
||||||
```
|
```console
|
||||||
$ home-manager switch
|
$ home-manager switch
|
||||||
…
|
…
|
||||||
Activating checkLinkTargets
|
Activating checkLinkTargets
|
||||||
Existing file '/home/jdoe/.gitconfig' is in the way
|
Existing file '/home/jdoe/.config/git/config' is in the way
|
||||||
Please move the above files and try again
|
Please move the above files and try again
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -196,7 +309,7 @@ in your system configuration and
|
|||||||
# …
|
# …
|
||||||
|
|
||||||
xsession.enable = true;
|
xsession.enable = true;
|
||||||
xsession.windowManager = "…";
|
xsession.windowManager.command = "…";
|
||||||
|
|
||||||
# …
|
# …
|
||||||
}
|
}
|
||||||
@@ -204,6 +317,70 @@ in your system configuration and
|
|||||||
|
|
||||||
in your Home Manager configuration.
|
in your Home Manager configuration.
|
||||||
|
|
||||||
|
Nix Flakes
|
||||||
|
----------
|
||||||
|
|
||||||
|
Home Manager includes a `flake.nix` file for compatibility with [Nix Flakes][]
|
||||||
|
for those that wish to use it as a module. A bare-minimum `flake.nix` would be
|
||||||
|
as follows:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
description = "NixOS configuration";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
home-manager.url = "github:nix-community/home-manager";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { home-manager, nixpkgs, ... }: {
|
||||||
|
nixosConfigurations = {
|
||||||
|
hostname = nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules = [
|
||||||
|
./configuration.nix
|
||||||
|
home-manager.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
home-manager.users.jdoe = import ./home.nix;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, the Home Manager library is exported by the flake under
|
||||||
|
`lib.hm`.
|
||||||
|
|
||||||
|
When using flakes, switch to new configurations as you do for the
|
||||||
|
whole system (e. g. `nixos-rebuild switch --flake <path>`) instead of
|
||||||
|
using the `home-manager` command line tool.
|
||||||
|
|
||||||
|
Releases
|
||||||
|
--------
|
||||||
|
|
||||||
|
Home Manager is developed against `nixpkgs-unstable` branch, which
|
||||||
|
often causes it to contain tweaks for changes/packages not yet
|
||||||
|
released in stable NixOS. To avoid breaking users' configurations,
|
||||||
|
Home Manager is released in branches corresponding to NixOS releases
|
||||||
|
(e.g. `release-21.05`). These branches get fixes, but usually not new
|
||||||
|
modules. If you need a module to be backported, then feel free to open
|
||||||
|
an issue.
|
||||||
|
|
||||||
|
[Bash]: https://www.gnu.org/software/bash/
|
||||||
[Nix]: https://nixos.org/nix/
|
[Nix]: https://nixos.org/nix/
|
||||||
[NixOS]: https://nixos.org/
|
[NixOS]: https://nixos.org/
|
||||||
[Nixpkgs]: https://nixos.org/nixpkgs/
|
[Nixpkgs]: https://nixos.org/nixpkgs/
|
||||||
|
[nixAllowedUsers]: https://nixos.org/nix/manual/#conf-allowed-users
|
||||||
|
[nixosAllowedUsers]: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers
|
||||||
|
[Z shell]: http://zsh.sourceforge.net/
|
||||||
|
[manual]: https://nix-community.github.io/home-manager/
|
||||||
|
[configuration options]: https://nix-community.github.io/home-manager/options.html
|
||||||
|
[#home-manager]: https://webchat.oftc.net/?channels=home-manager
|
||||||
|
[OFTC]: https://oftc.net/
|
||||||
|
[samueldr]: https://github.com/samueldr/
|
||||||
|
[Nix Pills]: https://nixos.org/nixos/nix-pills/
|
||||||
|
[Nix Flakes]: https://nixos.wiki/wiki/Flakes
|
||||||
|
|||||||
20
default.nix
20
default.nix
@@ -1,2 +1,18 @@
|
|||||||
# Simply defer to the home-manager script derivation.
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
import ./home-manager
|
|
||||||
|
rec {
|
||||||
|
docs = with import ./doc { inherit pkgs; }; {
|
||||||
|
html = manual.html;
|
||||||
|
manPages = manPages;
|
||||||
|
json = options.json;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager = pkgs.callPackage ./home-manager { path = toString ./.; };
|
||||||
|
|
||||||
|
install =
|
||||||
|
pkgs.callPackage ./home-manager/install.nix { inherit home-manager; };
|
||||||
|
|
||||||
|
nixos = import ./nixos;
|
||||||
|
|
||||||
|
path = ./.;
|
||||||
|
}
|
||||||
|
|||||||
258
doc/contributing.adoc
Normal file
258
doc/contributing.adoc
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
[[ch-contributing]]
|
||||||
|
== Contributing
|
||||||
|
|
||||||
|
:open-issues: https://github.com/nix-community/home-manager/issues
|
||||||
|
:new-issue: https://github.com/nix-community/home-manager/issues/new
|
||||||
|
:fork-a-repo: https://help.github.com/articles/fork-a-repo/
|
||||||
|
:create-a-pull-request: https://help.github.com/articles/creating-a-pull-request/
|
||||||
|
:seven-rules: https://chris.beams.io/posts/git-commit/#seven-rules
|
||||||
|
:news-nix: https://github.com/nix-community/home-manager/blob/master/modules/misc/news.nix
|
||||||
|
:nixfmt: https://github.com/serokell/nixfmt/
|
||||||
|
:example-commit-message: https://github.com/nix-community/home-manager/commit/69f8e47e9e74c8d3d060ca22e18246b7f7d988ef
|
||||||
|
|
||||||
|
Contributions to Home Manager are very welcome. To make the process as smooth as possible for both you and the Home Manager maintainers we provide some guidelines that we ask you to follow. See <<sec-contrib-getting-started>> for information on how to set up a suitable development environment and <<sec-guidelines>> for the actual guidelines.
|
||||||
|
|
||||||
|
This text is mainly directed at those who would like to make code contributions to Home Manager. If you just want to report a bug then first look among the already {open-issues}[open issues], if you find one matching yours then feel free to comment on it to add any additional information you may have. If no matching issue exists then go to the {new-issue}[new issue] page and write a description of your problem. Include as much information as you can, ideally also include relevant excerpts from your Home Manager configuration.
|
||||||
|
|
||||||
|
[[sec-contrib-getting-started]]
|
||||||
|
=== Getting started
|
||||||
|
|
||||||
|
If you have not previously forked Home Manager then you need to do that first. Have a look at GitHub's {fork-a-repo}[Fork a repo] for instructions on how to do this.
|
||||||
|
|
||||||
|
Once you have a fork of Home Manager you should create a branch starting at the most recent `master` branch. Give your branch a reasonably descriptive name. Commit your changes to this branch and when you are happy with the result and it fulfills <<sec-guidelines>> then push the branch to GitHub and {create-a-pull-request}[create a pull request].
|
||||||
|
|
||||||
|
Assuming your clone is at `$HOME/devel/home-manager` then you can make the `home-manager` command use it by either
|
||||||
|
|
||||||
|
1. overriding the default path by using the `-I` command line option:
|
||||||
|
+
|
||||||
|
[source,console]
|
||||||
|
$ home-manager -I home-manager=$HOME/devel/home-manager
|
||||||
|
+
|
||||||
|
or
|
||||||
|
|
||||||
|
2. changing the default path by ensuring your configuration includes
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
programs.home-manager.path = "$HOME/devel/home-manager";
|
||||||
|
----
|
||||||
|
+
|
||||||
|
and running `home-manager switch` to activate the change. Afterwards, `home-manager build` and `home-manager switch` will use your cloned repository.
|
||||||
|
|
||||||
|
The first option is good if you only temporarily want to use your clone.
|
||||||
|
|
||||||
|
[[sec-guidelines]]
|
||||||
|
=== Guidelines
|
||||||
|
:irc-home-manager: https://webchat.oftc.net/?channels=home-manager
|
||||||
|
:valuable-options: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md#valuable-options
|
||||||
|
:rfc-42: https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md
|
||||||
|
:assertions: https://nixos.org/manual/nixos/stable/index.html#sec-assertions
|
||||||
|
|
||||||
|
If your contribution satisfy the following rules then there is a good chance it will be merged without too much trouble. The rules are enforced by the Home Manager maintainers and to a lesser extent the Home Manager CI system.
|
||||||
|
|
||||||
|
If you are uncertain how these rules affect the change you would like to make then feel free to start a discussion in the {irc-home-manager}[#home-manager] IRC channel, ideally before you start developing.
|
||||||
|
|
||||||
|
[[sec-guidelines-back-compat]]
|
||||||
|
==== Maintain backward compatibility
|
||||||
|
|
||||||
|
Your contribution should not cause another user's existing configuration to break unless there is a very good reason and the change should be announced to the user through an {assertions}[assertion] or similar.
|
||||||
|
|
||||||
|
Remember that Home Manager is used in many different environments and you should consider how your change may effect others. For example,
|
||||||
|
|
||||||
|
- Does your change work for people that do not use NixOS? Consider other GNU/Linux distributions and macOS.
|
||||||
|
- Does your change work for people whose configuration is built on one system and deployed on another system?
|
||||||
|
|
||||||
|
[[sec-guidelines-forward-compat]]
|
||||||
|
==== Keep forward compatibility in mind
|
||||||
|
|
||||||
|
The master branch of Home Manager tracks the unstable channel of Nixpkgs, which may update package versions at any time. It is therefore important to consider how a package update may affect your code and try to reduce the risk of breakage.
|
||||||
|
|
||||||
|
The most effective way to reduce this risk is to follow the advice in <<sec-guidelines-valuable-options>>.
|
||||||
|
|
||||||
|
[[sec-guidelines-valuable-options]]
|
||||||
|
==== Add only valuable options
|
||||||
|
|
||||||
|
When creating a new module it is tempting to include every option supported by the software. This is _strongly_ discouraged. Providing many options increases maintenance burden and risk of breakage considerably. This is why only the most {valuable-options}[important software options] should be modeled explicitly. Less important options should be expressible through an `extraConfig` escape hatch.
|
||||||
|
|
||||||
|
A good rule of thumb for the first implementation of a module is to only add explicit options for those settings that absolutely must be set for the software to function correctly. It follows that a module for software that provides sensible default values for all settings would require no explicit options at all.
|
||||||
|
|
||||||
|
If the software uses a structured configuration format like a JSON, YAML, INI, TOML, or even a plain list of key/value pairs then consider using a `settings` option as described in {rfc-42}[Nix RFC 42].
|
||||||
|
|
||||||
|
[[sec-guidelines-add-tests]]
|
||||||
|
==== Add relevant tests
|
||||||
|
|
||||||
|
If at all possible, make sure to add new tests and expand existing tests so that your change will keep working in the future. See <<sec-tests>> for more information about the Home Manager test suite.
|
||||||
|
|
||||||
|
All contributed code _must_ pass the test suite.
|
||||||
|
|
||||||
|
[[sec-guidelines-module-maintainer]]
|
||||||
|
|
||||||
|
==== Add relevant documentation
|
||||||
|
:docbook: https://tdg.docbook.org/
|
||||||
|
:asciidoc: https://asciidoc.org/
|
||||||
|
:docbook-rocks: https://berbiche.github.io/docbook.rocks/
|
||||||
|
|
||||||
|
Many code changes require changing the documentation as well. Module options should be documented with DocBook. See {docbook-rocks}[DocBook rocks!] for a quick introduction and {docbook}[DocBook 5: The Definitive Guide] for in-depth information of DocBook. Home Manager is itself documented using a combination of DocBook and {asciidoc}[AsciiDoc]. All text is hosted in Home Manager's Git repository.
|
||||||
|
|
||||||
|
The HTML version of the manual containing both the module option descriptions and the documentation of Home Manager can be generated and opened by typing the following in a shell within a clone of the Home Manager Git repository:
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
$ nix-build -A docs.html
|
||||||
|
$ xdg-open ./result/share/doc/home-manager/index.html
|
||||||
|
|
||||||
|
When you have made changes to a module, it is a good idea to check that the man page version of the module options looks good:
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
$ nix-build -A docs.manPages
|
||||||
|
$ man ./result/share/man/man5/home-configuration.nix.5
|
||||||
|
|
||||||
|
==== Add yourself as a module maintainer
|
||||||
|
|
||||||
|
Every new module _must_ include a named maintainer using the `meta.maintainers` attribute. If you are a user of a module that currently lacks a maintainer then please consider adopting it.
|
||||||
|
|
||||||
|
If you are present in the NixOS maintainer list then you can use that entry. If you are not then you can add yourself to `modules/lib/maintainers.nix` in the Home Manager project.
|
||||||
|
|
||||||
|
Also add yourself to `.github/CODEOWNERS` as owner of the associated module files, including the test files. You will then be automatically added as a reviewer on any new pull request that touches your files.
|
||||||
|
|
||||||
|
Maintainers are encouraged to join the IRC channel and participate when they have opportunity.
|
||||||
|
|
||||||
|
[[sec-guidelines-code-style]]
|
||||||
|
==== Format your code
|
||||||
|
|
||||||
|
Make sure your code is formatted as described in <<sec-code-style>>. To maintain consistency throughout the project you are encouraged to browse through existing code and adopt its style also in new code.
|
||||||
|
|
||||||
|
[[sec-guidelines-commit-message-style]]
|
||||||
|
==== Format your commit messages
|
||||||
|
|
||||||
|
Similar to <<sec-guidelines-code-style>> we encourage a consistent commit message format as described in <<sec-commit-style>>.
|
||||||
|
|
||||||
|
[[sec-guidelines-news-style]]
|
||||||
|
==== Format your news entries
|
||||||
|
|
||||||
|
If your contribution includes a change that should be communicated to users of Home Manager then you can add a news entry. The entry must be formatted as described in <<sec-news>>.
|
||||||
|
|
||||||
|
When new modules are added a news entry should be included but you do not need to create this entry manually. The merging maintainer will create the entry for you. This is to reduce the risk of merge conflicts.
|
||||||
|
|
||||||
|
[[sec-guidelines-conditional-modules]]
|
||||||
|
==== Use conditional modules and news
|
||||||
|
|
||||||
|
Home Manager includes a number of modules that are only usable on some of the supported platforms. The most common example of platform specific modules are those that define systemd user services, which only works on Linux systems.
|
||||||
|
|
||||||
|
If you add a module that is platform specific then make sure to include a condition in the `loadModule` function call. This will make the module accessible only on systems where the condition evaluates to `true`.
|
||||||
|
|
||||||
|
Similarly, if you are adding a news entry then it should be shown only to users that may find it relevant, see <<sec-news>> for a description of conditional news.
|
||||||
|
|
||||||
|
[[sec-guidelines-licensing]]
|
||||||
|
==== Mind the license
|
||||||
|
|
||||||
|
The Home Manager project is covered by the MIT license and we can only accept contributions that fall under this license, or are licensed in a compatible way. When you contribute self written code and documentation it is assumed that you are doing so under the MIT license.
|
||||||
|
|
||||||
|
A potential gotcha with respect to licensing are option descriptions. Often it is convenient to copy from the upstream software documentation. When this is done it is important to verify that the license of the upstream documentation allows redistribution under the terms of the MIT license.
|
||||||
|
|
||||||
|
[[sec-commit-style]]
|
||||||
|
=== Commits
|
||||||
|
|
||||||
|
The commits in your pull request should be reasonably self-contained, that is, each commit should make sense in isolation. In particular, you will be asked to amend any commit that introduces syntax errors or similar problems even if they are fixed in a later commit.
|
||||||
|
|
||||||
|
The commit messages should follow the {seven-rules}[seven rules]. We also ask you to include the affected code component or module in the first line. That is, a commit message should follow the template
|
||||||
|
|
||||||
|
----
|
||||||
|
{component}: {description}
|
||||||
|
|
||||||
|
{long description}
|
||||||
|
----
|
||||||
|
|
||||||
|
where `{component}` refers to the code component (or module) your change affects, `{description}` is a very brief description of your change, and `{long description}` is an optional clarifying description. As a rare exception, if there is no clear component, or your change affects many components, then the `{component}` part is optional. See <<ex-commit-message>> for a commit message that fulfills these requirements.
|
||||||
|
|
||||||
|
[[ex-commit-message]]
|
||||||
|
.Compliant commit message
|
||||||
|
===============================================================================
|
||||||
|
The commit {example-commit-message}[69f8e47e9e74c8d3d060ca22e18246b7f7d988ef] contains the commit message
|
||||||
|
|
||||||
|
----
|
||||||
|
starship: allow running in Emacs if vterm is used
|
||||||
|
|
||||||
|
The vterm buffer is backed by libvterm and can handle Starship prompts
|
||||||
|
without issues.
|
||||||
|
----
|
||||||
|
|
||||||
|
which ticks all the boxes necessary to be accepted in Home Manager.
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Finally, when adding a new module, say `programs/foo.nix`, we use the fixed commit format `foo: add module`. You can, of course, still include a long description if you wish.
|
||||||
|
|
||||||
|
[[sec-code-style]]
|
||||||
|
=== Code Style
|
||||||
|
|
||||||
|
The code in Home Manager is formatted by the {nixfmt}[nixfmt] tool and the formatting is checked in the pull request tests. Run the `format` tool inside the project repository before submitting your pull request.
|
||||||
|
|
||||||
|
Keep lines at a reasonable width, ideally 80 characters or less. This also applies to string literals.
|
||||||
|
|
||||||
|
We prefer `lowerCamelCase` for variable and attribute names with the accepted exception of variables directly referencing packages in Nixpkgs which use a hyphenated style. For example, the Home Manager option `services.gpg-agent.enableSshSupport` references the `gpg-agent` package in Nixpkgs.
|
||||||
|
|
||||||
|
[[sec-news]]
|
||||||
|
=== News
|
||||||
|
|
||||||
|
Home Manager includes a system for presenting news to the user. When making a change you, therefore, have the option to also include an associated news entry. In general, a news entry should only be added for truly noteworthy news. For example, a bug fix or new option does generally not need a news entry.
|
||||||
|
|
||||||
|
If you do have a change worthy of a news entry then please add one in {news-nix}[`news.nix`] but you should follow some basic guidelines:
|
||||||
|
|
||||||
|
- The entry timestamp should be in ISO-8601 format having "+00:00" as time zone. For example, "2017-09-13T17:10:14+00:00". A suitable timestamp can be produced by the command
|
||||||
|
+
|
||||||
|
[source,console]
|
||||||
|
$ date --iso-8601=second --universal
|
||||||
|
|
||||||
|
- The entry condition should be as specific as possible. For example, if you are changing or deprecating a specific option then you could restrict the news to those users who actually use this option.
|
||||||
|
|
||||||
|
- Wrap the news message so that it will fit in the typical terminal, that is, at most 80 characters wide. Ideally a bit less.
|
||||||
|
|
||||||
|
- Unlike commit messages, news will be read without any connection to the Home Manager source code. It is therefore important to make the message understandable in isolation and to those who do not have knowledge of the Home Manager internals. To this end it should be written in more descriptive, prose like way.
|
||||||
|
|
||||||
|
- If you refer to an option then write its full attribute path. That is, instead of writing
|
||||||
|
+
|
||||||
|
----
|
||||||
|
The option 'foo' has been deprecated, please use 'bar' instead.
|
||||||
|
----
|
||||||
|
+
|
||||||
|
it should read
|
||||||
|
+
|
||||||
|
----
|
||||||
|
The option 'services.myservice.foo' has been deprecated, please
|
||||||
|
use 'services.myservice.bar' instead.
|
||||||
|
----
|
||||||
|
|
||||||
|
- A new module, say `foo.nix`, should always include a news entry that has a message along the lines of
|
||||||
|
+
|
||||||
|
----
|
||||||
|
A new module is available: 'services.foo'.
|
||||||
|
----
|
||||||
|
+
|
||||||
|
If the module is platform specific, e.g., a service module using systemd, then a condition like
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
condition = hostPlatform.isLinux;
|
||||||
|
+
|
||||||
|
should be added. If you contribute a module then you don't need to add this entry, the merger will create an entry for you.
|
||||||
|
|
||||||
|
[[sec-tests]]
|
||||||
|
=== Tests
|
||||||
|
|
||||||
|
Home Manager includes a basic test suite and it is highly recommended to include at least one test when adding a module. Tests are typically in the form of "golden tests" where, for example, a generated configuration file is compared to a known correct file.
|
||||||
|
|
||||||
|
It is relatively easy to create tests by modeling the existing tests, found in the `tests` project directory.
|
||||||
|
|
||||||
|
The full Home Manager test suite can be run by executing
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
$ nix-shell --pure tests -A run.all
|
||||||
|
|
||||||
|
in the project root. List all test cases through
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
$ nix-shell --pure tests -A list
|
||||||
|
|
||||||
|
and run an individual test, for example `alacritty-empty-settings`, through
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
$ nix-shell --pure tests -A run.alacritty-empty-settings
|
||||||
120
doc/default.nix
Normal file
120
doc/default.nix
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
{ pkgs
|
||||||
|
|
||||||
|
# Note, this should be "the standard library" + HM extensions.
|
||||||
|
, lib ? import ../modules/lib/stdlib-extended.nix pkgs.lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
nmdSrc = pkgs.fetchFromGitLab {
|
||||||
|
name = "nmd";
|
||||||
|
owner = "rycee";
|
||||||
|
repo = "nmd";
|
||||||
|
rev = "2398aa79ab12aa7aba14bc3b08a6efd38ebabdc5";
|
||||||
|
sha256 = "0yxb48afvccn8vvpkykzcr4q1rgv8jsijqncia7a5ffzshcrwrnh";
|
||||||
|
};
|
||||||
|
|
||||||
|
nmd = import nmdSrc { inherit lib pkgs; };
|
||||||
|
|
||||||
|
# Make sure the used package is scrubbed to avoid actually
|
||||||
|
# instantiating derivations.
|
||||||
|
scrubbedPkgsModule = {
|
||||||
|
imports = [{
|
||||||
|
_module.args = {
|
||||||
|
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
|
||||||
|
pkgs_i686 = lib.mkForce { };
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
buildModulesDocs = args:
|
||||||
|
nmd.buildModulesDocs ({
|
||||||
|
moduleRootPaths = [ ./.. ];
|
||||||
|
mkModuleUrl = path:
|
||||||
|
"https://github.com/nix-community/home-manager/blob/master/${path}#blob-path";
|
||||||
|
channelName = "home-manager";
|
||||||
|
} // args);
|
||||||
|
|
||||||
|
hmModulesDocs = buildModulesDocs {
|
||||||
|
modules = import ../modules/modules.nix {
|
||||||
|
inherit lib pkgs;
|
||||||
|
check = false;
|
||||||
|
} ++ [ scrubbedPkgsModule ];
|
||||||
|
docBook.id = "home-manager-options";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixosModuleDocs = buildModulesDocs {
|
||||||
|
modules = let
|
||||||
|
nixosModule = module: pkgs.path + "/nixos/modules" + module;
|
||||||
|
mockedNixos = with lib; {
|
||||||
|
options = {
|
||||||
|
environment.pathsToLink = mkSinkUndeclaredOptions { };
|
||||||
|
systemd.services = mkSinkUndeclaredOptions { };
|
||||||
|
users.users = mkSinkUndeclaredOptions { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in [
|
||||||
|
../nixos/default.nix
|
||||||
|
mockedNixos
|
||||||
|
(nixosModule "/misc/assertions.nix")
|
||||||
|
scrubbedPkgsModule
|
||||||
|
];
|
||||||
|
docBook = {
|
||||||
|
id = "nixos-options";
|
||||||
|
optionIdPrefix = "nixos-opt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixDarwinModuleDocs = buildModulesDocs {
|
||||||
|
modules = let
|
||||||
|
nixosModule = module: pkgs.path + "/nixos/modules" + module;
|
||||||
|
mockedNixDarwin = with lib; {
|
||||||
|
options = {
|
||||||
|
environment.pathsToLink = mkSinkUndeclaredOptions { };
|
||||||
|
system.activationScripts.postActivation.text =
|
||||||
|
mkSinkUndeclaredOptions { };
|
||||||
|
users.users = mkSinkUndeclaredOptions { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in [
|
||||||
|
../nix-darwin/default.nix
|
||||||
|
mockedNixDarwin
|
||||||
|
(nixosModule "/misc/assertions.nix")
|
||||||
|
scrubbedPkgsModule
|
||||||
|
];
|
||||||
|
docBook = {
|
||||||
|
id = "nix-darwin-options";
|
||||||
|
optionIdPrefix = "nix-darwin-opt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
docs = nmd.buildDocBookDocs {
|
||||||
|
pathName = "home-manager";
|
||||||
|
modulesDocs = [ hmModulesDocs nixDarwinModuleDocs nixosModuleDocs ];
|
||||||
|
documentsDirectory = ./.;
|
||||||
|
documentType = "book";
|
||||||
|
chunkToc = ''
|
||||||
|
<toc>
|
||||||
|
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-home-manager-manual"><?dbhtml filename="index.html"?>
|
||||||
|
<d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
|
||||||
|
<d:tocentry linkend="ch-nixos-options"><?dbhtml filename="nixos-options.html"?></d:tocentry>
|
||||||
|
<d:tocentry linkend="ch-nix-darwin-options"><?dbhtml filename="nix-darwin-options.html"?></d:tocentry>
|
||||||
|
<d:tocentry linkend="ch-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
||||||
|
<d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
|
||||||
|
</d:tocentry>
|
||||||
|
</toc>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
inherit nmdSrc;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
json = hmModulesDocs.json.override {
|
||||||
|
path = "share/doc/home-manager/options.json";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
manPages = docs.manPages;
|
||||||
|
|
||||||
|
manual = { inherit (docs) html htmlOpenTool; };
|
||||||
|
}
|
||||||
173
doc/faq.adoc
Normal file
173
doc/faq.adoc
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
[[ch-faq]]
|
||||||
|
== Frequently Asked Questions (FAQ)
|
||||||
|
|
||||||
|
=== Why is there a collision error when switching generation?
|
||||||
|
|
||||||
|
Home Manager currently installs packages into the user environment, precisely as if the packages were installed through `nix-env --install`. This means that you will get a collision error if your Home Manager configuration attempts to install a package that you already have installed manually, that is, packages that shows up when you run `nix-env --query`.
|
||||||
|
|
||||||
|
For example, imagine you have the `hello` package installed in your environment
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
$ nix-env --query
|
||||||
|
hello-2.10
|
||||||
|
----
|
||||||
|
|
||||||
|
and your Home Manager configuration contains
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home.packages = [ pkgs.hello ];
|
||||||
|
----
|
||||||
|
|
||||||
|
Then attempting to switch to this configuration will result in an error similar to
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
$ home-manager switch
|
||||||
|
these derivations will be built:
|
||||||
|
/nix/store/xg69wsnd1rp8xgs9qfsjal017nf0ldhm-home-manager-path.drv
|
||||||
|
[…]
|
||||||
|
Activating installPackages
|
||||||
|
replacing old ‘home-manager-path’
|
||||||
|
installing ‘home-manager-path’
|
||||||
|
building path(s) ‘/nix/store/b5c0asjz9f06l52l9812w6k39ifr49jj-user-environment’
|
||||||
|
Wide character in die at /nix/store/64jc9gd2rkbgdb4yjx3nrgc91bpjj5ky-buildenv.pl line 79.
|
||||||
|
collision between ‘/nix/store/fmwa4axzghz11cnln5absh31nbhs9lq1-home-manager-path/bin/hello’ and ‘/nix/store/c2wyl8b9p4afivpcz8jplc9kis8rj36d-hello-2.10/bin/hello’; use ‘nix-env --set-flag priority NUMBER PKGNAME’ to change the priority of one of the conflicting packages
|
||||||
|
builder for ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed with exit code 2
|
||||||
|
error: build of ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed
|
||||||
|
----
|
||||||
|
|
||||||
|
The solution is typically to uninstall the package from the environment using `nix-env --uninstall` and reattempt the Home Manager generation switch.
|
||||||
|
|
||||||
|
You could also opt to unistall _all_ of the packages from your profile with `nix-env --uninstall '*'`.
|
||||||
|
|
||||||
|
=== Why are the session variables not set?
|
||||||
|
|
||||||
|
Home Manager is only able to set session variables automatically if it manages your Bash or Z shell configuration. If you don't want to let Home Manager manage your shell then you will have to manually source the `~/.nix-profile/etc/profile.d/hm-session-vars.sh` file in an appropriate way. In Bash and Z shell this can be done by adding
|
||||||
|
|
||||||
|
[source,bash]
|
||||||
|
----
|
||||||
|
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||||
|
----
|
||||||
|
|
||||||
|
to your `.profile` and `.zshrc` files, respectively. The `hm-session-vars.sh` file should work in most Bourne-like shells.
|
||||||
|
|
||||||
|
=== How to set up a configuration for multiple users/machines?
|
||||||
|
:post-your-homenix: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/
|
||||||
|
|
||||||
|
A typical way to prepare a repository of configurations for multiple logins and machines is to prepare one "top-level" file for each unique combination.
|
||||||
|
|
||||||
|
For example, if you have two machines, called "kronos" and "rhea" on which you want to configure your user "jane" then you could create the files
|
||||||
|
|
||||||
|
- `kronos-jane.nix`,
|
||||||
|
- `rhea-jane.nix`, and
|
||||||
|
- `common.nix`
|
||||||
|
|
||||||
|
in your repository. On the kronos and rhea machines you can then make `~jane/.config/nixpkgs/home.nix` be a symbolic link to the corresponding file in your configuration repository.
|
||||||
|
|
||||||
|
The `kronos-jane.nix` and `rhea-jane.nix` files follow the format
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./common.nix ];
|
||||||
|
|
||||||
|
# Various options that are specific for this machine/user.
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
while the `common.nix` file contains configuration shared across the two logins. Of course, instead of just a single `common.nix` file you can have multiple ones, even one per program or service.
|
||||||
|
|
||||||
|
You can get some inspiration from the {post-your-homenix}[Post your home-manager home.nix file!] Reddit thread.
|
||||||
|
|
||||||
|
=== Why do I get an error message about `ca.desrt.dconf`?
|
||||||
|
|
||||||
|
You are most likely trying to configure the GTK or Gnome Terminal but the DBus session is not aware of the dconf service. The full error you might get is
|
||||||
|
|
||||||
|
----
|
||||||
|
error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt.dconf was not provided by any .service files
|
||||||
|
----
|
||||||
|
|
||||||
|
The solution on NixOS is to add
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
services.dbus.packages = with pkgs; [ gnome.dconf ];
|
||||||
|
|
||||||
|
to your system configuration.
|
||||||
|
|
||||||
|
=== How do I install packages from Nixpkgs unstable?
|
||||||
|
|
||||||
|
If you are using a stable version of Nixpkgs but would like to install some particular packages from Nixpkgs unstable – or some other channel – then you can import the unstable Nixpkgs and refer to its packages within your configuration. Something like
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgsUnstable.foo
|
||||||
|
];
|
||||||
|
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
should work provided you have a Nix channel called `nixpkgs-unstable`.
|
||||||
|
|
||||||
|
You can add the `nixpkgs-unstable` channel by running
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
# nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable
|
||||||
|
# nix-channel --update
|
||||||
|
----
|
||||||
|
|
||||||
|
Note, the package will not be affected by any package overrides, overlays, etc.
|
||||||
|
|
||||||
|
=== How do I override the package used by a module?
|
||||||
|
:nixpkgs-overlays: https://nixos.org/nixpkgs/manual/#chap-overlays
|
||||||
|
|
||||||
|
By default Home Manager will install the package provided by your chosen `nixpkgs` channel but occasionally you might end up needing to change this package. This can typically be done in two ways.
|
||||||
|
|
||||||
|
1. If the module provides a `package` option, such as `programs.beets.package`, then this is the recommended way to perform the override. For example,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
programs.beets.package = pkgs.beets.override { enableCheck = true; };
|
||||||
|
|
||||||
|
2. If no `package` option is available then you can typically override the relevant package using an {nixpkgs-overlays}[overlay].
|
||||||
|
+
|
||||||
|
For example, if you want to use the `programs.skim` module but use the `skim` package from Nixpkgs unstable, then a configuration like
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.skim.enable = true;
|
||||||
|
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(self: super: {
|
||||||
|
skim = pkgsUnstable.skim;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
# …
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
should work OK.
|
||||||
263
doc/installation.adoc
Normal file
263
doc/installation.adoc
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
[[ch-installation]]
|
||||||
|
== Installing Home Manager
|
||||||
|
|
||||||
|
:nix-darwin: https://github.com/LnL7/nix-darwin/
|
||||||
|
|
||||||
|
Home Manager can be used in three primary ways:
|
||||||
|
|
||||||
|
1. Using the standalone `home-manager` tool. For platforms other than
|
||||||
|
NixOS and Darwin, this is the only available choice. It is also
|
||||||
|
recommended for people on NixOS or Darwin that want to manage their
|
||||||
|
home directory independent of the system as a whole. See
|
||||||
|
<<sec-install-standalone>> for instructions on how to perform this
|
||||||
|
installation.
|
||||||
|
|
||||||
|
2. As a module within a NixOS system configuration. This allows the
|
||||||
|
user profiles to be built together with the system when running
|
||||||
|
`nixos-rebuild`. See <<sec-install-nixos-module>> for a description of
|
||||||
|
this setup.
|
||||||
|
|
||||||
|
3. As a module within a {nix-darwin}[nix-darwin] system configuration.
|
||||||
|
This allows the user profiles to be built together with the system
|
||||||
|
when running `darwin-rebuild`. See <<sec-install-nix-darwin-module>>
|
||||||
|
for a description of this setup.
|
||||||
|
|
||||||
|
[[sec-install-standalone]]
|
||||||
|
=== Standalone installation
|
||||||
|
|
||||||
|
:nix-allowed-users: https://nixos.org/nix/manual/#conf-allowed-users
|
||||||
|
:nixos-allowed-users: https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers
|
||||||
|
|
||||||
|
1. Make sure you have a working Nix installation. Specifically, make
|
||||||
|
sure that your user is able to build and install Nix packages. For
|
||||||
|
example, you should be able to successfully run a command like
|
||||||
|
`nix-instantiate '<nixpkgs>' -A hello` without having to switch to the
|
||||||
|
root user. For a multi-user install of Nix this means that your user
|
||||||
|
must be covered by the {nix-allowed-users}[`allowed-users`] Nix
|
||||||
|
option. On NixOS you can control this option using the
|
||||||
|
{nixos-allowed-users}[`nix.allowedUsers`] system option.
|
||||||
|
|
||||||
|
2. Add the Home Manager channel that you wish to follow. If you are
|
||||||
|
following Nixpkgs master or an unstable channel then this is done by
|
||||||
|
running
|
||||||
|
+
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||||
|
$ nix-channel --update
|
||||||
|
----
|
||||||
|
+
|
||||||
|
and if you follow a Nixpkgs version 21.05 channel, you can run
|
||||||
|
+
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||||
|
$ nix-channel --update
|
||||||
|
----
|
||||||
|
+
|
||||||
|
On NixOS you may need to log out and back in for the channel to become
|
||||||
|
available. On non-NixOS you may have to add
|
||||||
|
+
|
||||||
|
[source,bash]
|
||||||
|
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||||
|
+
|
||||||
|
to your shell (see
|
||||||
|
https://github.com/NixOS/nix/issues/2033[nix#2033]).
|
||||||
|
|
||||||
|
3. Run the Home Manager installation command and create the first Home
|
||||||
|
Manager generation:
|
||||||
|
+
|
||||||
|
[source,console]
|
||||||
|
$ nix-shell '<home-manager>' -A install
|
||||||
|
+
|
||||||
|
Once finished, Home Manager should be active and available in your
|
||||||
|
user environment.
|
||||||
|
|
||||||
|
4. If you do not plan on having Home Manager manage your shell
|
||||||
|
configuration then you must source the
|
||||||
|
+
|
||||||
|
[source,bash]
|
||||||
|
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||||
|
+
|
||||||
|
file in your shell configuration. Alternatively source
|
||||||
|
+
|
||||||
|
[source,bash]
|
||||||
|
/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh
|
||||||
|
+
|
||||||
|
when managing home configuration together with system configuration.
|
||||||
|
+
|
||||||
|
Unfortunately, we currently only support POSIX.2-like shells such as
|
||||||
|
https://www.gnu.org/software/bash/[Bash] or
|
||||||
|
http://zsh.sourceforge.net/[Z shell].
|
||||||
|
+
|
||||||
|
For example, if you use Bash then add
|
||||||
|
+
|
||||||
|
[source,bash]
|
||||||
|
----
|
||||||
|
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||||
|
----
|
||||||
|
+
|
||||||
|
to your `~/.profile` file.
|
||||||
|
|
||||||
|
If instead of using channels you want to run Home Manager from a Git
|
||||||
|
checkout of the repository then you can use the
|
||||||
|
<<opt-programs.home-manager.path>> option to specify the absolute path
|
||||||
|
to the repository.
|
||||||
|
|
||||||
|
[[sec-install-nixos-module]]
|
||||||
|
=== NixOS module
|
||||||
|
|
||||||
|
Home Manager provides a NixOS module that allows you to prepare user
|
||||||
|
environments directly from the system configuration file, which often
|
||||||
|
is more convenient than using the `home-manager` tool. It also opens
|
||||||
|
up additional possibilities, for example, to automatically configure
|
||||||
|
user environments in NixOS declarative containers or on systems
|
||||||
|
deployed through NixOps.
|
||||||
|
|
||||||
|
To make the NixOS module available for use you must `import` it into
|
||||||
|
your system configuration. This is most conveniently done by adding a
|
||||||
|
Home Manager channel. For example, if you are following Nixpkgs master
|
||||||
|
or an unstable channel, you can run
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||||
|
# nix-channel --update
|
||||||
|
----
|
||||||
|
|
||||||
|
and if you follow a Nixpkgs version 21.05 channel, you can run
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||||
|
# nix-channel --update
|
||||||
|
----
|
||||||
|
|
||||||
|
It is then possible to add
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
imports = [ <home-manager/nixos> ];
|
||||||
|
|
||||||
|
to your system `configuration.nix` file, which will introduce a new
|
||||||
|
NixOS option called `home-manager.users` whose type is an attribute
|
||||||
|
set that maps user names to Home Manager configurations.
|
||||||
|
|
||||||
|
For example, a NixOS configuration may include the lines
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
users.users.eve.isNormalUser = true;
|
||||||
|
home-manager.users.eve = { pkgs, ... }: {
|
||||||
|
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||||
|
programs.bash.enable = true;
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
and after a `nixos-rebuild switch` the user eve's environment should
|
||||||
|
include a basic Bash configuration and the packages atool and httpie.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
By default packages will be installed to `$HOME/.nix-profile` but they
|
||||||
|
can be installed to `/etc/profiles` if
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
|
||||||
|
is added to the system configuration. This is necessary if, for
|
||||||
|
example, you wish to use `nixos-rebuild build-vm`. This option may
|
||||||
|
become the default value in the future.
|
||||||
|
====
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
By default, Home Manager uses a private `pkgs` instance that is
|
||||||
|
configured via the `home-manager.users.<name>.nixpkgs` options. To
|
||||||
|
instead use the global `pkgs` that is configured via the system level
|
||||||
|
`nixpkgs` options, set
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
|
||||||
|
This saves an extra Nixpkgs evaluation, adds consistency, and removes
|
||||||
|
the dependency on `NIX_PATH`, which is otherwise used for importing
|
||||||
|
Nixpkgs.
|
||||||
|
====
|
||||||
|
|
||||||
|
[[sec-install-nix-darwin-module]]
|
||||||
|
=== nix-darwin module
|
||||||
|
|
||||||
|
Home Manager provides a module that allows you to prepare user
|
||||||
|
environments directly from the {nix-darwin}[nix-darwin] configuration
|
||||||
|
file, which often is more convenient than using the `home-manager`
|
||||||
|
tool.
|
||||||
|
|
||||||
|
To make the NixOS module available for use you must `import` it into
|
||||||
|
your system configuration. This is most conveniently done by adding a
|
||||||
|
Home Manager channel. For example, if you are following Nixpkgs master
|
||||||
|
or an unstable channel, you can run
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
# nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
||||||
|
# nix-channel --update
|
||||||
|
----
|
||||||
|
|
||||||
|
and if you follow a Nixpkgs version 21.05 channel, you can run
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
----
|
||||||
|
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz home-manager
|
||||||
|
# nix-channel --update
|
||||||
|
----
|
||||||
|
|
||||||
|
It is then possible to add
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
imports = [ <home-manager/nix-darwin> ];
|
||||||
|
|
||||||
|
to your nix-darwin `configuration.nix` file, which will introduce a
|
||||||
|
new NixOS option called `home-manager` whose type is an attribute set
|
||||||
|
that maps user names to Home Manager configurations.
|
||||||
|
|
||||||
|
For example, a nix-darwin configuration may include the lines
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home-manager.users.eve = { pkgs, ... }: {
|
||||||
|
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||||
|
programs.bash.enable = true;
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
and after a `darwin-rebuild switch` the user eve's environment
|
||||||
|
should include a basic Bash configuration and the packages atool and
|
||||||
|
httpie.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
By default user packages will not be ignored in favor of
|
||||||
|
`environment.systemPackages`, but they will be intalled to
|
||||||
|
`/etc/profiles/per-user/$USERNAME` if
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
|
||||||
|
is added to the nix-darwin configuration. This option may become the
|
||||||
|
default value in the future.
|
||||||
|
====
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
By default, Home Manager uses a private `pkgs` instance that is
|
||||||
|
configured via the `home-manager.users.<name>.nixpkgs` options. To
|
||||||
|
instead use the global `pkgs` that is configured via the system level
|
||||||
|
`nixpkgs` options, set
|
||||||
|
|
||||||
|
[source,nix]
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
|
||||||
|
This saves an extra Nixpkgs evaluation, adds consistency, and removes
|
||||||
|
the dependency on `NIX_PATH`, which is otherwise used for importing
|
||||||
|
Nixpkgs.
|
||||||
|
====
|
||||||
40
doc/man-configuration.xml
Normal file
40
doc/man-configuration.xml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle><filename>home-configuration.nix</filename></refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum>
|
||||||
|
<refmiscinfo class="source">Home Manager</refmiscinfo>
|
||||||
|
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||||
|
</refmeta>
|
||||||
|
<refnamediv>
|
||||||
|
<refname><filename>home-configuration.nix</filename></refname>
|
||||||
|
<refpurpose>Home Manager configuration specification</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
<refsection>
|
||||||
|
<title>Description</title>
|
||||||
|
<para>
|
||||||
|
The file <filename>~/.config/nixpkgs/home.nix</filename> contains the
|
||||||
|
declarative specification of your Home Manager configuration. The command
|
||||||
|
<command>home-manager</command> takes this file and realises the user
|
||||||
|
environment configuration specified therein.
|
||||||
|
</para>
|
||||||
|
</refsection>
|
||||||
|
<refsection>
|
||||||
|
<title>Options</title>
|
||||||
|
<para>
|
||||||
|
You can use the following options in
|
||||||
|
<filename>home-configuration.nix</filename>:
|
||||||
|
</para>
|
||||||
|
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||||
|
</refsection>
|
||||||
|
<refsection>
|
||||||
|
<title>See also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>home-manager</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum>
|
||||||
|
</citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsection>
|
||||||
|
</refentry>
|
||||||
587
doc/man-home-manager.xml
Normal file
587
doc/man-home-manager.xml
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle><command>home-manager</command>
|
||||||
|
</refentrytitle><manvolnum>1</manvolnum>
|
||||||
|
<refmiscinfo class="source">Home Manager</refmiscinfo>
|
||||||
|
</refmeta>
|
||||||
|
<refnamediv>
|
||||||
|
<refname><command>home-manager</command>
|
||||||
|
</refname><refpurpose>reconfigure a user environment</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>home-manager</command> <group choice="req">
|
||||||
|
<arg choice="plain">
|
||||||
|
build
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
instantiate
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
edit
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
expire-generations <replaceable>timestamp</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
generations
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
help
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
news
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
option <replaceable>option.name</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
packages
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
remove-generations <replaceable>ID …</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
switch
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
uninstall
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
<sbr />
|
||||||
|
<arg>
|
||||||
|
-A <replaceable>attrPath</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
-I <replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--flake <replaceable>flake-uri</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
-b <replaceable>ext</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
<group choice="req">
|
||||||
|
<arg choice="plain">
|
||||||
|
-f
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
--file
|
||||||
|
</arg>
|
||||||
|
</group> <replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
<group choice="req">
|
||||||
|
<arg choice="plain">
|
||||||
|
-h
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
--help
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
<group choice="req">
|
||||||
|
<arg choice="plain">
|
||||||
|
-n
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
--dry-run
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--option <replaceable>name</replaceable> <replaceable>value</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--cores <replaceable>number</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
<group choice="req">
|
||||||
|
<arg choice="plain">
|
||||||
|
-j
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
--max-jobs
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
<replaceable>number</replaceable>
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--debug
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--keep-failed
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--keep-going
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--show-trace
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
--(no-)substitute
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg>
|
||||||
|
<group choice="req">
|
||||||
|
<arg choice="plain">
|
||||||
|
-v
|
||||||
|
</arg>
|
||||||
|
|
||||||
|
<arg choice="plain">
|
||||||
|
--verbose
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
<refsection>
|
||||||
|
<title>Description</title>
|
||||||
|
<para>
|
||||||
|
This command updates the user environment so that it corresponds to the
|
||||||
|
configuration specified in <filename>~/.config/nixpkgs/home.nix</filename> or <filename>~/.config/nixpkgs/flake.nix</filename>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
All operations using this tool expects a sub-command that indicates the
|
||||||
|
operation to perform. It must be one of
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>build</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Build configuration into a <filename>result</filename> directory.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>instantiate</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Instantiate the configuration and print the resulting derivation.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>edit</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Open the home configuration using the editor indicated by
|
||||||
|
<envar>EDITOR</envar>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>expire-generations <replaceable>timestamp</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Remove generations older than <replaceable>timestamp</replaceable> where
|
||||||
|
<replaceable>timestamp</replaceable> is interpreted as in the
|
||||||
|
<option>-d</option> argument of the <citerefentry>
|
||||||
|
<refentrytitle>date</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry> tool. For example <literal>-30
|
||||||
|
days</literal> or <literal>2018-01-01</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>generations</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
List all home environment generations.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>help</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Print tool help.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>news</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Show news entries in a pager.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>option <replaceable>option.name</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Inspect the given option name in the home configuration, like <citerefentry>
|
||||||
|
<refentrytitle>nixos-option</refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>packages</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
List all packages installed in <varname>home-manager-path</varname>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>remove-generations <replaceable>ID …</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Remove indicated generations. Use the <option>generations</option>
|
||||||
|
sub-command to find suitable generation numbers.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>switch</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Build and activate the configuration.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>uninstall</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Remove Home Manager from the user environment. This will
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
remove all managed files from the home directory,
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
remove packages installed through Home Manager from the user profile,
|
||||||
|
and
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
optionally remove all Home Manager generations and make them
|
||||||
|
available for immediate garbage collection.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
</refsection>
|
||||||
|
<refsection>
|
||||||
|
<title>Options</title>
|
||||||
|
<para>
|
||||||
|
The tool accepts the options
|
||||||
|
</para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-A <replaceable>attrPath</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Optional attribute that selects a configuration expression in the
|
||||||
|
configuration file. That is, if <filename>home.nix</filename> contains
|
||||||
|
<programlisting language="nix">
|
||||||
|
{
|
||||||
|
joe-at-work = {pkgs, ...}: { home.packages = [ pkgs.fortune ]; };
|
||||||
|
joe-at-home = {pkgs, ...}: { home.packages = [ pkgs.cowsay ]; };
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
then the command <command>home-manager switch -A joe-at-work</command>
|
||||||
|
will activate the profile containing the fortune program.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-I <replaceable>path</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Add a path to the Nix expression search path. For example, to build a
|
||||||
|
Home Manager profile using a specific Nixpkgs run <command>home-manager
|
||||||
|
-I nixpkgs=/absolute/path/to/nixpkgs build</command>. By default
|
||||||
|
<literal><nixpkgs></literal> is used.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--flake <replaceable>flake-uri[#name]</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Build Home Manager configuration from the flake, which must contain the
|
||||||
|
output homeConfigurations.name. If no name is specified it will first try
|
||||||
|
username@hostname and then username.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-b <replaceable>extension</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Enable automatic resolution of collisions between unmanaged and managed
|
||||||
|
files. The name of the original file will be suffixed by the given
|
||||||
|
extension. For example,
|
||||||
|
<screen>
|
||||||
|
<prompt>$</prompt> <userinput>home-manager -b bck switch</userinput>
|
||||||
|
</screen>
|
||||||
|
will cause a colliding file <filename>~/.config/foo.conf</filename> to be
|
||||||
|
moved to <filename>~/.config/foo.conf.bck</filename>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-f <replaceable>path</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<term>
|
||||||
|
<option>--file <replaceable>path</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Indicates the path to the Home Manager configuration file. If not given,
|
||||||
|
<filename>~/.config/nixpkgs/home.nix</filename> is used.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-h</option>
|
||||||
|
</term>
|
||||||
|
<term>
|
||||||
|
<option>--help</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Prints usage information for the <command>home-manager</command> tool.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-n</option>
|
||||||
|
</term>
|
||||||
|
<term>
|
||||||
|
<option>--dry-run</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Perform a dry-run of the given operation, only prints what actions would
|
||||||
|
be taken.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--option <replaceable>name</replaceable> <replaceable>value</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--cores <replaceable>number</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-j <replaceable>number</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<term>
|
||||||
|
<option>--max-jobs <replaceable>number</replaceable></option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--debug</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--keep-failed</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--keep-going</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--show-trace</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--(no-)substitute</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Passed on to <citerefentry>
|
||||||
|
<refentrytitle>nix-build</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum> </citerefentry>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-v</option>
|
||||||
|
</term>
|
||||||
|
<term>
|
||||||
|
<option>--verbose</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Activates verbose output.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsection>
|
||||||
|
<refsection>
|
||||||
|
<title>Files</title>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<filename>~/.local/share/home-manager/news-read-ids</filename>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Identifiers of news items that have been shown. Can be deleted to reset
|
||||||
|
the read news indicator.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsection>
|
||||||
|
<refsection>
|
||||||
|
<title>Bugs</title>
|
||||||
|
<para>
|
||||||
|
Please report any bugs on the
|
||||||
|
<link
|
||||||
|
xlink:href="https://github.com/nix-community/home-manager/issues">project
|
||||||
|
issue tracker</link>.
|
||||||
|
</para>
|
||||||
|
</refsection>
|
||||||
|
<refsection>
|
||||||
|
<title>See also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>home-configuration.nix</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum> </citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsection>
|
||||||
|
</refentry>
|
||||||
12
doc/man-pages.xml
Normal file
12
doc/man-pages.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<reference xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
<title>Home Manager Reference Pages</title>
|
||||||
|
<info>
|
||||||
|
<author><personname>Home Manager contributors</personname></author>
|
||||||
|
<copyright><year>2017–2020</year><holder>Home Manager contributors</holder>
|
||||||
|
</copyright>
|
||||||
|
</info>
|
||||||
|
<xi:include href="man-configuration.xml" />
|
||||||
|
<xi:include href="man-home-manager.xml" />
|
||||||
|
</reference>
|
||||||
52
doc/manual.xml
Normal file
52
doc/manual.xml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<book xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="book-home-manager-manual">
|
||||||
|
<info>
|
||||||
|
<title>Home Manager Manual</title>
|
||||||
|
</info>
|
||||||
|
<preface>
|
||||||
|
<title>Preface</title>
|
||||||
|
<para>
|
||||||
|
This manual will eventually describes how to install, use, and extend Home
|
||||||
|
Manager.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If you encounter problems then please reach out on the IRC channel
|
||||||
|
<link xlink:href="https://webchat.oftc.net/?channels=home-manager">#home-manager</link>
|
||||||
|
hosted by <link xlink:href="https://oftc.net/">OFTC</link>.
|
||||||
|
If your problem is caused by a bug in Home Manager then it should
|
||||||
|
be reported on the
|
||||||
|
<link xlink:href="https://github.com/nix-community/home-manager/issues">Home Manager issue tracker</link>.
|
||||||
|
</para>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Commands prefixed with <literal>#</literal> have to be run as root, either
|
||||||
|
requiring to login as root user or temporarily switching to it using
|
||||||
|
<literal>sudo</literal> for example.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</preface>
|
||||||
|
<xi:include href="installation.xml" />
|
||||||
|
<xi:include href="writing-modules.xml" />
|
||||||
|
<xi:include href="contributing.xml" />
|
||||||
|
<xi:include href="faq.xml" />
|
||||||
|
<appendix xml:id="ch-options">
|
||||||
|
<title>Configuration Options</title>
|
||||||
|
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||||
|
</appendix>
|
||||||
|
<appendix xml:id="ch-nixos-options">
|
||||||
|
<title>NixOS Module Options</title>
|
||||||
|
<xi:include href="./nmd-result/nixos-options.xml" />
|
||||||
|
</appendix>
|
||||||
|
<appendix xml:id="ch-nix-darwin-options">
|
||||||
|
<title>nix-darwin Module Options</title>
|
||||||
|
<xi:include href="./nmd-result/nix-darwin-options.xml" />
|
||||||
|
</appendix>
|
||||||
|
<appendix xml:id="ch-tools">
|
||||||
|
<title>Tools</title>
|
||||||
|
<xi:include href="./man-home-manager.xml" />
|
||||||
|
</appendix>
|
||||||
|
<xi:include href="./release-notes/release-notes.xml" />
|
||||||
|
</book>
|
||||||
23
doc/release-notes/release-notes.adoc
Normal file
23
doc/release-notes/release-notes.adoc
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
[[ch-release-notes]]
|
||||||
|
[appendix]
|
||||||
|
== Release Notes
|
||||||
|
|
||||||
|
This section lists the release notes for stable versions of Home Manager and the current unstable version.
|
||||||
|
|
||||||
|
:leveloffset: 1
|
||||||
|
|
||||||
|
include::rl-2111.adoc[]
|
||||||
|
|
||||||
|
include::rl-2105.adoc[]
|
||||||
|
|
||||||
|
include::rl-2009.adoc[]
|
||||||
|
|
||||||
|
include::rl-2003.adoc[]
|
||||||
|
|
||||||
|
include::rl-1909.adoc[]
|
||||||
|
|
||||||
|
include::rl-1903.adoc[]
|
||||||
|
|
||||||
|
include::rl-1809.adoc[]
|
||||||
|
|
||||||
|
:leveloffset: 0
|
||||||
4
doc/release-notes/rl-1809.adoc
Normal file
4
doc/release-notes/rl-1809.adoc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[sec-release-18.09]]
|
||||||
|
== Release 18.09
|
||||||
|
|
||||||
|
The 18.09 release branch became the stable branch in September, 2018.
|
||||||
59
doc/release-notes/rl-1903.adoc
Normal file
59
doc/release-notes/rl-1903.adoc
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
[[sec-release-19.03]]
|
||||||
|
== Release 19.03
|
||||||
|
|
||||||
|
The 19.03 release branch became the stable branch in April, 2019.
|
||||||
|
|
||||||
|
[[sec-release-19.03-highlights]]
|
||||||
|
=== Highlights
|
||||||
|
:opt-home-file-source: opt-home.file._name_.source
|
||||||
|
|
||||||
|
This release has the following notable changes:
|
||||||
|
|
||||||
|
* The <<{opt-home-file-source}>> option now allows source files to be
|
||||||
|
hidden, that is, having a name starting with the `.` character. It
|
||||||
|
also allows the source file name to contain characters not typically
|
||||||
|
allowed for Nix store paths. For example, your configuration can now
|
||||||
|
contain things such as
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home.file."my file".source = ./. + "/file with spaces!";
|
||||||
|
----
|
||||||
|
|
||||||
|
* The type used for the systemd unit options under
|
||||||
|
<<opt-systemd.user.services>>, <<opt-systemd.user.sockets>>, etc. has
|
||||||
|
been changed to offer more robust merging of configurations. If you
|
||||||
|
don't override values within systemd units then you are not affected
|
||||||
|
by this change. Unfortunately, if you do override unit values you may
|
||||||
|
encounter errors.
|
||||||
|
+
|
||||||
|
In particular, if you get an error saying that a ``unique option'' is
|
||||||
|
``defined multiple times'' then you need to use the
|
||||||
|
https://nixos.org/nixos/manual/#sec-option-definitions-setting-priorities[`mkForce`]
|
||||||
|
function. For example,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
|
||||||
|
----
|
||||||
|
+
|
||||||
|
becomes
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
|
||||||
|
----
|
||||||
|
+
|
||||||
|
We had to make this change because the old merging was causing too
|
||||||
|
many confusing situations for people.
|
||||||
|
|
||||||
|
[[sec-release-19.03-state-version-changes]]
|
||||||
|
=== State Version Changes
|
||||||
|
|
||||||
|
The state version in this release includes the changes below. These
|
||||||
|
changes are only active if the <<opt-home.stateVersion>> option is set
|
||||||
|
to ``19.03'' or later.
|
||||||
|
|
||||||
|
* There is now an option <<opt-programs.beets.enable>> that defaults
|
||||||
|
to `false`. Before the module would be active if the
|
||||||
|
<<opt-programs.beets.settings>> option was non-empty.
|
||||||
31
doc/release-notes/rl-1909.adoc
Normal file
31
doc/release-notes/rl-1909.adoc
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
[[sec-release-19.09]]
|
||||||
|
== Release 19.09
|
||||||
|
|
||||||
|
The 19.09 release branch became the stable branch in October, 2019.
|
||||||
|
|
||||||
|
[[sec-release-19.09-highlights]]
|
||||||
|
=== Highlights
|
||||||
|
|
||||||
|
This release has the following notable changes:
|
||||||
|
|
||||||
|
* The `programs.firefox.enableGoogleTalk` and
|
||||||
|
`programs.firefox.enableIcedTea` options are now deprecated
|
||||||
|
and will only work if Firefox ESR 52.x is used.
|
||||||
|
|
||||||
|
* The `home-manager` tool now provides an `uninstall` sub-command that
|
||||||
|
can be used to uninstall Home Manager, if used in the standalone
|
||||||
|
mode. That is, not as a NixOS module.
|
||||||
|
|
||||||
|
[[sec-release-19.09-state-version-changes]]
|
||||||
|
=== State Version Changes
|
||||||
|
|
||||||
|
The state version in this release includes the changes below. These
|
||||||
|
changes are only active if the `home.stateVersion` option is set to
|
||||||
|
"19.09" or later.
|
||||||
|
|
||||||
|
* The <<opt-programs.firefox.package>> option now expects a wrapped
|
||||||
|
Firefox package and defaults to `pkgs.firefox`.
|
||||||
|
|
||||||
|
* The options <<opt-home.keyboard.layout>> and
|
||||||
|
<<opt-home.keyboard.variant>> now default to `null`, which indicates
|
||||||
|
that the system value should be used.
|
||||||
126
doc/release-notes/rl-2003.adoc
Normal file
126
doc/release-notes/rl-2003.adoc
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
[[sec-release-20.03]]
|
||||||
|
== Release 20.03
|
||||||
|
|
||||||
|
The 20.03 release branch became the stable branch in April, 2020.
|
||||||
|
|
||||||
|
[[sec-release-20.03-highlights]]
|
||||||
|
=== Highlights
|
||||||
|
|
||||||
|
This release has the following notable changes:
|
||||||
|
|
||||||
|
* Assigning a list to the <<opt-home.file>>, <<opt-xdg.configFile>>,
|
||||||
|
and <<opt-xdg.dataFile>> options is now deprecated and will produce a
|
||||||
|
warning message if used. Specifically, if your configuration currently
|
||||||
|
contains something like
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home.file = [
|
||||||
|
{
|
||||||
|
target = ".config/foo.txt";
|
||||||
|
text = "bar";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
----
|
||||||
|
+
|
||||||
|
then it should be updated to instead use the equivalent attribute set form
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home.file = {
|
||||||
|
".config/foo.txt".text = "bar";
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
Support for the list form will be removed in Home Manager version
|
||||||
|
20.09.
|
||||||
|
|
||||||
|
* The `lib` function attribute given to modules is now enriched with
|
||||||
|
an attribute `hm` containing extra library functions specific for Home
|
||||||
|
Manager. More specifically, `lib.hm` is now the same as `config.lib`
|
||||||
|
and should be the preferred choice since it is more robust.
|
||||||
|
+
|
||||||
|
Therefore, if your configuration makes use of, for example,
|
||||||
|
`config.lib.dag` to create activation script blocks, it is recommended
|
||||||
|
to change to `lib.hm.dag`.
|
||||||
|
+
|
||||||
|
Note, in the unlikely case that you are
|
||||||
|
+
|
||||||
|
** using Home Manager's NixOS or nix-darwin module,
|
||||||
|
** have made your own Home Manager module containing an top-level
|
||||||
|
option named `config` or `options`, and
|
||||||
|
** assign to this option in your system configuration inside a plain
|
||||||
|
attribute set, i.e., without a function argument,
|
||||||
|
|
||||||
|
+
|
||||||
|
then you must update your configuration to perform the option
|
||||||
|
assignment inside a `config` attribute. For example, instead of
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home-manager.users.jane = { config = "foo"; };
|
||||||
|
----
|
||||||
|
+
|
||||||
|
use
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
home-manager.users.jane = { config.config = "foo"; };
|
||||||
|
----
|
||||||
|
|
||||||
|
* The `services.compton` module has been deprecated and instead the
|
||||||
|
new module `services.picom` should be used. This is because Nixpkgs no
|
||||||
|
longer packages compton, and instead packages the (mostly) compatible
|
||||||
|
fork called picom.
|
||||||
|
|
||||||
|
* The list form of the <<opt-programs.ssh.matchBlocks>> option has
|
||||||
|
been deprecated and configurations requiring match blocks in a defined
|
||||||
|
order should switch to using DAG entries instead. For example, a
|
||||||
|
configuration
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.ssh.matchBlocks = [
|
||||||
|
{
|
||||||
|
host = "alpha.foo.com";
|
||||||
|
user = "jd";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
host = "*.foo.com";
|
||||||
|
user = "john.doe";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
----
|
||||||
|
+
|
||||||
|
can be expressed along the lines of
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.ssh.matchBlocks = {
|
||||||
|
"*.example.com" = {
|
||||||
|
user = "john.doe";
|
||||||
|
}
|
||||||
|
"alpha.example.com" = lib.hm.dag.entryBefore ["*.example.com"] {
|
||||||
|
user = "jd";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
----
|
||||||
|
+
|
||||||
|
Support for the list form will be removed in Home Manager version
|
||||||
|
20.09.
|
||||||
|
|
||||||
|
[[sec-release-20.03-state-version-changes]]
|
||||||
|
=== State Version Changes
|
||||||
|
|
||||||
|
The state version in this release includes the changes below. These
|
||||||
|
changes are only active if the `home.stateVersion` option is set to
|
||||||
|
"20.03" or later.
|
||||||
|
|
||||||
|
* The <<opt-programs.zsh.history.path>> option is no longer prepended
|
||||||
|
by `$HOME`, which allows specifying absolute paths, for example,
|
||||||
|
using the xdg module. Also, the default value is fixed to
|
||||||
|
`$HOME/.zsh_history` and `dotDir` path is not prepended to it
|
||||||
|
anymore.
|
||||||
|
* The newsboat module will now default in displaying `queries` before `urls` in
|
||||||
|
its main window. This makes sense in the case when one has a lot of URLs and
|
||||||
|
few queries.
|
||||||
96
doc/release-notes/rl-2009.adoc
Normal file
96
doc/release-notes/rl-2009.adoc
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
[[sec-release-20.09]]
|
||||||
|
== Release 20.09
|
||||||
|
|
||||||
|
The 20.09 release branch became the stable branch in late September, 2020.
|
||||||
|
|
||||||
|
[[sec-release-20.09-highlights]]
|
||||||
|
=== Highlights
|
||||||
|
|
||||||
|
This release has the following notable changes:
|
||||||
|
|
||||||
|
* Nothing has happened.
|
||||||
|
|
||||||
|
[[sec-release-20.09-state-version-changes]]
|
||||||
|
=== State Version Changes
|
||||||
|
|
||||||
|
The state version in this release includes the changes below. These
|
||||||
|
changes are only active if the `home.stateVersion` option is set to
|
||||||
|
"20.09" or later.
|
||||||
|
|
||||||
|
* The options <<opt-home.homeDirectory>> and <<opt-home.username>> no
|
||||||
|
longer have default values and must therefore be provided in your
|
||||||
|
configuration. Previously their values would default to the content of
|
||||||
|
the environment variables `HOME` and `USER`, respectively.
|
||||||
|
+
|
||||||
|
--
|
||||||
|
Further, the options <<opt-xdg.cacheHome>>, <<opt-xdg.configHome>>,
|
||||||
|
and <<opt-xdg.dataHome>> will no longer be affected by the
|
||||||
|
`XDG_CACHE_HOME`, `XDG_CONFIG_HOME`, and `XDG_DATA_HOME` environment
|
||||||
|
variables. They now unconditionally default to
|
||||||
|
|
||||||
|
- `"${config.home.homeDirectory}/.cache"`,
|
||||||
|
- `"${config.home.homeDirectory}/.config"`, and
|
||||||
|
- `"${config.home.homeDirectory}/.local/share"`.
|
||||||
|
|
||||||
|
If you choose to switch to state version 20.09 then you must set these
|
||||||
|
options if you use non-default XDG base directory paths.
|
||||||
|
|
||||||
|
The initial configuration generated by
|
||||||
|
|
||||||
|
[source,console]
|
||||||
|
$ nix-shell '<home-manager>' -A install
|
||||||
|
|
||||||
|
will automatically include these options, when necessary.
|
||||||
|
--
|
||||||
|
|
||||||
|
* Git's `smtpEncryption` option is now set to `tls` only if both <<opt-accounts.email.accounts.\_name_.smtp.tls.enable>> and <<opt-accounts.email.accounts.\_name_.smtp.tls.useStartTls>> are `true`. If only <<opt-accounts.email.accounts.\_name_.smtp.tls.enable>> is `true`, `ssl` is used instead.
|
||||||
|
|
||||||
|
* The `nixpkgs` module no longer references `<nixpkgs>`. Before it would do so when building the `pkgs` module argument. Starting with state version 20.09, the `pkgs` argument is instead built from the same Nixpkgs that was used to initialize the Home Manager modules. This is useful, for example, when using Home Manager within a Nix Flake. If you want to keep using `<nixpkgs>` with state version ≥ 20.09 then add
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
_module.args.pkgsPath = <nixpkgs>;
|
||||||
|
+
|
||||||
|
to your Home Manager configuration.
|
||||||
|
|
||||||
|
* The options `wayland.windowManager.sway.config.bars` and `opt-xsession.windowManager.i3.config.bars` have been changed so that most of the suboptions are now nullable and default to `null`. The default for these two options has been changed to manually set the old defaults for each suboption. The overall effect is that if the `bars` options is not set, then the default remains the same. On the other hand, something like:
|
||||||
|
+
|
||||||
|
--
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
bars = [ {
|
||||||
|
command = "waybar";
|
||||||
|
} ];
|
||||||
|
----
|
||||||
|
will now create the config:
|
||||||
|
....
|
||||||
|
bar {
|
||||||
|
swaybar_command waybar
|
||||||
|
}
|
||||||
|
....
|
||||||
|
instead of
|
||||||
|
....
|
||||||
|
bar {
|
||||||
|
|
||||||
|
font pango:monospace 8
|
||||||
|
mode dock
|
||||||
|
hidden_state hide
|
||||||
|
position bottom
|
||||||
|
status_command /nix/store/h7s6i9q1z5fxrlyyw5ls8vqxhf5bcs5a-i3status-2.13/bin/i3status
|
||||||
|
swaybar_command waybar
|
||||||
|
workspace_buttons yes
|
||||||
|
strip_workspace_numbers no
|
||||||
|
tray_output primary
|
||||||
|
colors {
|
||||||
|
background #000000
|
||||||
|
statusline #ffffff
|
||||||
|
separator #666666
|
||||||
|
focused_workspace #4c7899 #285577 #ffffff
|
||||||
|
active_workspace #333333 #5f676a #ffffff
|
||||||
|
inactive_workspace #333333 #222222 #888888
|
||||||
|
urgent_workspace #2f343a #900000 #ffffff
|
||||||
|
binding_mode #2f343a #900000 #ffffff
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
....
|
||||||
|
--
|
||||||
200
doc/release-notes/rl-2105.adoc
Normal file
200
doc/release-notes/rl-2105.adoc
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
[[sec-release-21.05]]
|
||||||
|
== Release 21.05
|
||||||
|
|
||||||
|
The 21.05 release branch became the stable branch in May, 2021.
|
||||||
|
|
||||||
|
[[sec-release-21.05-highlights]]
|
||||||
|
=== Highlights
|
||||||
|
|
||||||
|
This release has the following notable changes:
|
||||||
|
|
||||||
|
* The <<opt-programs.broot.verbs>> option is now a list rather than an
|
||||||
|
attribute set. To migrate, move the keys of the attrset into the list
|
||||||
|
items' `invocation` keys. For example,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.broot.verbs = {
|
||||||
|
"p" = { execution = ":parent"; };
|
||||||
|
};
|
||||||
|
----
|
||||||
|
+
|
||||||
|
becomes
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.broot.verbs = [
|
||||||
|
{
|
||||||
|
invocation = "p";
|
||||||
|
execution = ":parent";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
----
|
||||||
|
|
||||||
|
* The <<opt-programs.mpv.package>> option has been changed to allow custom
|
||||||
|
derivations. The following configuration is now possible:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.mpv.package = (pkgs.wrapMpv (pkgs.mpv-unwrapped.override {
|
||||||
|
vapoursynthSupport = true;
|
||||||
|
}) {
|
||||||
|
extraMakeWrapperArgs = [
|
||||||
|
"--prefix" "LD_LIBRARY_PATH" ":" "${pkgs.vapoursynth-mvtools}/lib/vapoursynth"
|
||||||
|
];
|
||||||
|
});
|
||||||
|
----
|
||||||
|
+
|
||||||
|
As a result of this change, <<opt-programs.mpv.package>> is no longer the
|
||||||
|
resulting derivation. Use the newly introduced `programs.mpv.finalPackage`
|
||||||
|
instead.
|
||||||
|
|
||||||
|
* The <<opt-programs.rofi.extraConfig>> option is now an attribute set rather
|
||||||
|
than a string. To migrate, move each line into the attribute set,
|
||||||
|
removing the `rofi.` prefix from the keys. For example,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.rofi.extraConfig = ''
|
||||||
|
rofi.show-icons: true
|
||||||
|
rofi.modi: drun,emoji,ssh
|
||||||
|
'';
|
||||||
|
----
|
||||||
|
+
|
||||||
|
becomes
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.rofi.extraConfig = {
|
||||||
|
show-icons = true;
|
||||||
|
modi = "drun,emoji,ssh";
|
||||||
|
};
|
||||||
|
----
|
||||||
|
+
|
||||||
|
* The <<opt-programs.rofi.theme>> option now supports defining a theme
|
||||||
|
using an attribute set, the following configuration is now possible:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.rofi.theme = let
|
||||||
|
# Necessary to avoid quoting non-string values
|
||||||
|
inherit (config.lib.formats.rasi) mkLiteral;
|
||||||
|
in {
|
||||||
|
"@import" = "~/.config/rofi/theme.rasi";
|
||||||
|
|
||||||
|
"*" = {
|
||||||
|
background-color = mkLiteral "#000000";
|
||||||
|
foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )";
|
||||||
|
border-color = mkLiteral "#FFFFFF";
|
||||||
|
width = 512;
|
||||||
|
};
|
||||||
|
|
||||||
|
"#textbox-prompt-colon" = {
|
||||||
|
expand = false;
|
||||||
|
str = ":";
|
||||||
|
margin = mkLiteral "0px 0.3em 0em 0em";
|
||||||
|
text-color = mkLiteral "@foreground-color";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
* The `services.redshift.extraOptions` and `services.gammastep.extraOptions`
|
||||||
|
options were removed in favor of <<opt-services.redshift.settings>> and
|
||||||
|
`services.gammastep.settings`, that are now an attribute set rather
|
||||||
|
than a string. They also support new features not available before, for
|
||||||
|
example:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
services.redshift = {
|
||||||
|
dawnTime = "6:00-7:45";
|
||||||
|
duskTime = "18:35-20:15";
|
||||||
|
settings = {
|
||||||
|
redshift = {
|
||||||
|
gamma = 0.8;
|
||||||
|
adjustment-method = "randr";
|
||||||
|
};
|
||||||
|
|
||||||
|
randr = {
|
||||||
|
screen = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
----
|
||||||
|
+
|
||||||
|
It is recommended to check either
|
||||||
|
https://github.com/jonls/redshift/blob/master/redshift.conf.sample[redshift.conf.sample] or
|
||||||
|
https://gitlab.com/chinstrap/gammastep/-/blob/master/gammastep.conf.sample[gammastep.conf.sample]
|
||||||
|
for the available additional options in each program.
|
||||||
|
|
||||||
|
* Specifying `programs.neomutt.binds.map` or `programs.neomutt.macros.map` as a
|
||||||
|
single string is now deprecated in favor of specfiying it as a list of
|
||||||
|
strings.
|
||||||
|
|
||||||
|
* The `programs.neovim.configure` is deprecated in favor of other `programs.neovim` options;
|
||||||
|
please use the other options at your disposal:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
configure.packages.*.opt -> programs.neovim.plugins = [ { plugin = ...; optional = true; }]
|
||||||
|
configure.packages.*.start -> programs.neovim.plugins = [ { plugin = ...; }]
|
||||||
|
configure.customRC -> programs.neovim.extraConfig
|
||||||
|
----
|
||||||
|
|
||||||
|
* Home Manager now respects the `NO_COLOR` environment variable as per
|
||||||
|
https://no-color.org/[].
|
||||||
|
|
||||||
|
* Qt module now supports <<opt-qt.style.name>> to specify a theme name and
|
||||||
|
<<opt-qt.style.package>> to specify a theme package. If you have set
|
||||||
|
<<opt-qt.platformTheme>> to `gnome`, a <<opt-qt.style.package>> compatible
|
||||||
|
with both Qt and Gtk is now required to be set. For instance:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
qt = {
|
||||||
|
platformTheme = "gnome";
|
||||||
|
style = {
|
||||||
|
name = "adwaita-dark";
|
||||||
|
package = pkgs.adwaita-qt;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
* The library type `fontType` now has a `size` attribute in addition to `name`. For example:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
font = {
|
||||||
|
name = "DejaVu Sans";
|
||||||
|
size = 8;
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
* The <<opt-programs.htop.settings>> option is introduced to replace individual
|
||||||
|
options in `programs.htop`. To migrate, set the htop options directly in
|
||||||
|
<<opt-programs.htop.settings>>. For example:
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
programs.htop = {
|
||||||
|
enabled = true;
|
||||||
|
settings = {
|
||||||
|
color_scheme = 5;
|
||||||
|
delay = 15;
|
||||||
|
highlight_base_name = 1;
|
||||||
|
highlight_megabytes = 1;
|
||||||
|
highlight_threads = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
[[sec-release-21.05-state-version-changes]]
|
||||||
|
=== State Version Changes
|
||||||
|
|
||||||
|
The state version in this release includes the changes below. These
|
||||||
|
changes are only active if the `home.stateVersion` option is set to
|
||||||
|
"21.05" or later.
|
||||||
|
|
||||||
|
* The `newsboat` module now stores generated configuration in
|
||||||
|
`$XDG_CONFIG_HOME/newsboat`.
|
||||||
43
doc/release-notes/rl-2111.adoc
Normal file
43
doc/release-notes/rl-2111.adoc
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
[[sec-release-21.11]]
|
||||||
|
== Release 21.11
|
||||||
|
|
||||||
|
This is the current unstable branch and the information in this
|
||||||
|
section is therefore not final.
|
||||||
|
|
||||||
|
[[sec-release-21.11-highlights]]
|
||||||
|
=== Highlights
|
||||||
|
|
||||||
|
This release has the following notable changes:
|
||||||
|
|
||||||
|
* All Home Manager modules are now loaded on all platforms. With this
|
||||||
|
change you will get a more descriptive error message if you attempt to
|
||||||
|
enable a module that is incompatible with the host platform.
|
||||||
|
+
|
||||||
|
Previously, modules that were platform specific would only be loaded
|
||||||
|
on that particular platform. For example, a module defining a
|
||||||
|
https://systemd.io/[systemd] service would only be loaded when the
|
||||||
|
host platform was Linux. This reduced evaluation times, simplified the
|
||||||
|
generated documentation, and made it impossible to accidentally use
|
||||||
|
modules that do not support the host platform.
|
||||||
|
+
|
||||||
|
While the above benefits are quite nice, avoiding module loads also
|
||||||
|
brings a few problems. For example, the
|
||||||
|
https://nix-community.github.io/home-manager/[public documentation]
|
||||||
|
will only show the options available for Linux hosts and the
|
||||||
|
documentation cannot make references to options within modules that
|
||||||
|
are unavailable on some hosts. Finally, users who wish to use the same
|
||||||
|
configuration file for different platforms cannot do so, even if the
|
||||||
|
platform incompatible options are unused.
|
||||||
|
+
|
||||||
|
Ultimately, the benefits of loading all modules won and the behavior
|
||||||
|
has now changed. For associated discussion see
|
||||||
|
https://github.com/nix-community/home-manager/issues/1906[issue #1906].
|
||||||
|
|
||||||
|
[[sec-release-21.11-state-version-changes]]
|
||||||
|
=== State Version Changes
|
||||||
|
|
||||||
|
The state version in this release includes the changes below. These
|
||||||
|
changes are only active if the `home.stateVersion` option is set to
|
||||||
|
"21.11" or later.
|
||||||
|
|
||||||
|
* Nothing has happened.
|
||||||
187
doc/writing-modules.adoc
Normal file
187
doc/writing-modules.adoc
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
[[ch-writing-modules]]
|
||||||
|
== Writing Home Manager Modules
|
||||||
|
:writing-nixos-modules: https://nixos.org/nixos/manual/index.html#sec-writing-modules
|
||||||
|
|
||||||
|
The module system in Home Manager is based entirely on the NixOS module system so we will here only highlight aspects that are specific for Home Manager. For information about the module system as such please refer to the {writing-nixos-modules}[Writing NixOS Modules] chapter of the NixOS manual.
|
||||||
|
|
||||||
|
[[sec-option-types]]
|
||||||
|
=== Option Types
|
||||||
|
:wikipedia-dag: https://en.wikipedia.org/w/index.php?title=Directed_acyclic_graph&oldid=939656095
|
||||||
|
:gvariant-description: https://developer.gnome.org/glib/stable/glib-GVariant.html#glib-GVariant.description
|
||||||
|
|
||||||
|
Overall the basic option types are the same in Home Manager as NixOS. A few Home Manager options, however, make use of custom types that are worth describing in more detail. These are the option types `dagOf` and `gvariant` that are used, for example, by <<opt-programs.ssh.matchBlocks>> and <<opt-dconf.settings>>.
|
||||||
|
|
||||||
|
`hm.types.dagOf`::
|
||||||
|
Options of this type have attribute sets as values where each member is a node in a {wikipedia-dag}[directed acyclic graph] (DAG). This allows the attribute set entries to express dependency relations among themselves. This can, for example, be used to control the order of match blocks in a OpenSSH client configuration or the order of activation script blocks in <<opt-home.activation>>.
|
||||||
|
+
|
||||||
|
A number of functions are provided to create DAG nodes. The functions are shown below with examples using an option `foo.bar` of type `hm.types.dagOf types.int`.
|
||||||
|
+
|
||||||
|
`hm.dag.entryAnywhere (value: T)`:::
|
||||||
|
Indicates that `value` can be placed anywhere within the DAG. This is also the default for plain attribute set entries, that is
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = {
|
||||||
|
a = hm.dag.entryAnywhere 0;
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
and
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = {
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
are equivalent.
|
||||||
|
+
|
||||||
|
`hm.dag.entryAfter (afters: list string) (value: T)`:::
|
||||||
|
Indicates that `value` must be placed _after_ each of the attribute names in the given list. For example
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = {
|
||||||
|
a = 0;
|
||||||
|
b = hm.dag.entryAfter [ "a" ] 1;
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
would place `b` after `a` in the graph.
|
||||||
|
+
|
||||||
|
`hm.dag.entryBefore (befores: list string) (value: T)`:::
|
||||||
|
Indicates that `value` must be placed _before_ each of the attribute names in the given list. For example
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = {
|
||||||
|
b = hm.dag.entryBefore [ "a" ] 1;
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
would place `b` before `a` in the graph.
|
||||||
|
+
|
||||||
|
`hm.dag.entryBetween (befores: list string) (afters: list string) (value: T)`:::
|
||||||
|
Indicates that `value` must be placed _before_ the attribute names in the first list and _after_ the attribute names in the second list. For example
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = {
|
||||||
|
a = 0;
|
||||||
|
c = hm.dag.entryBetween [ "b" ] [ "a" ] 2;
|
||||||
|
b = 1;
|
||||||
|
}
|
||||||
|
----
|
||||||
|
+
|
||||||
|
would place `c` before `b` and after `a` in the graph.
|
||||||
|
|
||||||
|
`hm.types.gvariant`::
|
||||||
|
This type is useful for options representing {gvariant-description}[GVariant] values. The type accepts all primitive GVariant types as well as arrays and tuples. Dictionaries are not currently supported.
|
||||||
|
+
|
||||||
|
To create a GVariant value you can use a number of provided functions. Examples assume an option `foo.bar` of type `hm.types.gvariant`.
|
||||||
|
+
|
||||||
|
`hm.gvariant.mkBoolean (v: bool)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `boolean` value. Note, Nix booleans are automatically coerced using this function. That is,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = hm.gvariant.mkBoolean true;
|
||||||
|
----
|
||||||
|
+
|
||||||
|
is equivalent to
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = true;
|
||||||
|
----
|
||||||
|
`hm.gvariant.mkString (v: string)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `string` value. Note, Nix strings are automatically coerced using this function. That is,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = hm.gvariant.mkString "a string";
|
||||||
|
----
|
||||||
|
+
|
||||||
|
is equivalent to
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = "a string";
|
||||||
|
----
|
||||||
|
`hm.gvariant.mkObjectpath (v: string)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `objectpath` value.
|
||||||
|
`hm.gvariant.mkUchar (v: string)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `uchar` value.
|
||||||
|
`hm.gvariant.mkInt16 (v: int)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `int16` value.
|
||||||
|
`hm.gvariant.mkUint16 (v: int)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `uint16` value.
|
||||||
|
`hm.gvariant.mkInt32 (v: int)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `int32` value. Note, Nix integers are automatically coerced using this function. That is,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = hm.gvariant.mkInt32 7;
|
||||||
|
----
|
||||||
|
+
|
||||||
|
is equivalent to
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = 7;
|
||||||
|
----
|
||||||
|
`hm.gvariant.mkUint32 (v: int)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `uint32` value.
|
||||||
|
`hm.gvariant.mkInt64 (v: int)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `int64` value.
|
||||||
|
`hm.gvariant.mkUint64 (v: int)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `uint64` value.
|
||||||
|
`hm.gvariant.mkDouble (v: double)`:::
|
||||||
|
Takes a Nix value `v` to a GVariant `double` value. Note, Nix floats are automatically coerced using this function. That is,
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = hm.gvariant.mkDouble 3.14;
|
||||||
|
----
|
||||||
|
+
|
||||||
|
is equivalent to
|
||||||
|
+
|
||||||
|
[source,nix]
|
||||||
|
----
|
||||||
|
foo.bar = 3.14;
|
||||||
|
----
|
||||||
|
+
|
||||||
|
`hm.gvariant.mkArray type elements`:::
|
||||||
|
Builds a GVariant array containing the given list of elements, where each element is a GVariant value of the given type. The `type` value can be constructed using
|
||||||
|
+
|
||||||
|
--
|
||||||
|
- `hm.gvariant.type.string`
|
||||||
|
- `hm.gvariant.type.boolean`
|
||||||
|
- `hm.gvariant.type.uchar`
|
||||||
|
- `hm.gvariant.type.int16`
|
||||||
|
- `hm.gvariant.type.uint16`
|
||||||
|
- `hm.gvariant.type.int32`
|
||||||
|
- `hm.gvariant.type.uint32`
|
||||||
|
- `hm.gvariant.type.int64`
|
||||||
|
- `hm.gvariant.type.uint64`
|
||||||
|
- `hm.gvariant.type.double`
|
||||||
|
- `hm.gvariant.type.arrayOf type`
|
||||||
|
- `hm.gvariant.type.maybeOf type`
|
||||||
|
- `hm.gvariant.type.tupleOf types`
|
||||||
|
--
|
||||||
|
+
|
||||||
|
where `type` and `types` are themselves a type and list of types, respectively.
|
||||||
|
+
|
||||||
|
`hm.gvariant.mkEmptyArray type`:::
|
||||||
|
An alias of `hm.gvariant.mkArray type []`.
|
||||||
|
+
|
||||||
|
`hm.gvariant.mkNothing type`:::
|
||||||
|
Builds a GVariant maybe value whose (non-existent) element is of the given type. The `type` value is constructed as described for the `mkArray` function above.
|
||||||
|
+
|
||||||
|
`hm.gvariant.mkJust element`:::
|
||||||
|
Builds a GVariant maybe value containing the given GVariant element.
|
||||||
|
+
|
||||||
|
`hm.gvariant.mkTuple elements`:::
|
||||||
|
Builds a GVariant tuple containing the given list of elements, where each element is a GVariant value.
|
||||||
46
flake.nix
Normal file
46
flake.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
description = "Home Manager for Nix";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }:
|
||||||
|
let
|
||||||
|
# List of systems supported by home-manager binary
|
||||||
|
supportedSystems = nixpkgs.lib.platforms.unix;
|
||||||
|
|
||||||
|
# Function to generate a set based on supported systems
|
||||||
|
forAllSystems = f:
|
||||||
|
nixpkgs.lib.genAttrs supportedSystems (system: f system);
|
||||||
|
|
||||||
|
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
|
||||||
|
in rec {
|
||||||
|
nixosModules.home-manager = import ./nixos;
|
||||||
|
nixosModule = self.nixosModules.home-manager;
|
||||||
|
|
||||||
|
darwinModules.home-manager = import ./nix-darwin;
|
||||||
|
darwinModule = self.darwinModules.home-manager;
|
||||||
|
|
||||||
|
packages = forAllSystems (system: {
|
||||||
|
home-manager = nixpkgsFor.${system}.callPackage ./home-manager { };
|
||||||
|
});
|
||||||
|
|
||||||
|
defaultPackage =
|
||||||
|
forAllSystems (system: self.packages.${system}.home-manager);
|
||||||
|
|
||||||
|
lib = {
|
||||||
|
hm = import ./modules/lib { lib = nixpkgs.lib; };
|
||||||
|
homeManagerConfiguration = { configuration, system, homeDirectory
|
||||||
|
, username, extraModules ? [ ], extraSpecialArgs ? { }
|
||||||
|
, pkgs ? builtins.getAttr system nixpkgs.outputs.legacyPackages
|
||||||
|
, check ? true, stateVersion ? "20.09" }@args:
|
||||||
|
assert nixpkgs.lib.versionAtLeast stateVersion "20.09";
|
||||||
|
|
||||||
|
import ./modules {
|
||||||
|
inherit pkgs check extraSpecialArgs;
|
||||||
|
configuration = { ... }: {
|
||||||
|
imports = [ configuration ] ++ extraModules;
|
||||||
|
home = { inherit homeDirectory stateVersion username; };
|
||||||
|
nixpkgs = { inherit (pkgs) config overlays; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
40
format
Executable file
40
format
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/05f0934825c2a0750d4888c4735f9420c906b388.tar.gz -i bash -p findutils nixfmt
|
||||||
|
|
||||||
|
CHECK_ARG=
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
-h)
|
||||||
|
echo "$0 [-c]"
|
||||||
|
;;
|
||||||
|
-c)
|
||||||
|
CHECK_ARG=-c
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# The first block of excludes are files where nixfmt does a poor job,
|
||||||
|
# IMHO. The second block of excludes are files touched by open pull
|
||||||
|
# requests and we want to avoid merge conflicts.
|
||||||
|
find . -name '*.nix' \
|
||||||
|
! -path ./modules/programs/irssi.nix \
|
||||||
|
\
|
||||||
|
! -path ./home-manager/home-manager.nix \
|
||||||
|
! -path ./modules/default.nix \
|
||||||
|
! -path ./modules/files.nix \
|
||||||
|
! -path ./modules/home-environment.nix \
|
||||||
|
! -path ./modules/lib/default.nix \
|
||||||
|
! -path ./modules/lib/file-type.nix \
|
||||||
|
! -path ./modules/manual.nix \
|
||||||
|
! -path ./modules/misc/news.nix \
|
||||||
|
! -path ./modules/programs/bash.nix \
|
||||||
|
! -path ./modules/programs/gpg.nix \
|
||||||
|
! -path ./modules/programs/ssh.nix \
|
||||||
|
! -path ./modules/programs/tmux.nix \
|
||||||
|
! -path ./modules/programs/zsh.nix \
|
||||||
|
! -path ./modules/services/gpg-agent.nix \
|
||||||
|
! -path ./modules/services/mpd.nix \
|
||||||
|
! -path ./nix-darwin/default.nix \
|
||||||
|
! -path ./tests/default.nix \
|
||||||
|
! -path ./tests/modules/home-environment/session-variables.nix \
|
||||||
|
! -path ./tests/modules/programs/gpg/override-defaults.nix \
|
||||||
|
-exec nixfmt $CHECK_ARG {} +
|
||||||
362
home-manager/completion.bash
Normal file
362
home-manager/completion.bash
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
#!/bin/env bash
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# « home-manager » command-line completion
|
||||||
|
#
|
||||||
|
# © 2019 "Sam Boosalis" <samboosalis@gmail.com>
|
||||||
|
#
|
||||||
|
# MIT License
|
||||||
|
#
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Contributing:
|
||||||
|
|
||||||
|
# Compatibility — Bash 3.
|
||||||
|
#
|
||||||
|
# OSX won't update Bash 3 (last updated circa 2009) to Bash 4,
|
||||||
|
# and we'd like this completion script to work on both Linux and Mac.
|
||||||
|
#
|
||||||
|
# For example, OSX Yosemite (released circa 2014) ships with Bash 3:
|
||||||
|
#
|
||||||
|
# $ echo $BASH_VERSION
|
||||||
|
# 3.2
|
||||||
|
#
|
||||||
|
# While Ubuntu LTS 14.04 (a.k.a. Trusty, also released circa 2016)
|
||||||
|
# ships with the latest version, Bash 4 (updated circa 2016):
|
||||||
|
#
|
||||||
|
# $ echo $BASH_VERSION
|
||||||
|
# 4.3
|
||||||
|
#
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
#
|
||||||
|
# (1) Invoke « shellcheck »
|
||||||
|
#
|
||||||
|
# * source: « https://github.com/koalaman/shellcheck »
|
||||||
|
# * run: « shellcheck ./share/bash-completion/completions/home-manager »
|
||||||
|
#
|
||||||
|
# (2) Interpret via Bash 3
|
||||||
|
#
|
||||||
|
# * run: « bash --noprofile --norc ./share/bash-completion/completions/home-manager »
|
||||||
|
#
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Examples:
|
||||||
|
|
||||||
|
# $ home-manager <TAB>
|
||||||
|
#
|
||||||
|
# -A
|
||||||
|
# -I
|
||||||
|
# -f
|
||||||
|
# --file
|
||||||
|
# -h
|
||||||
|
# --help
|
||||||
|
# -n
|
||||||
|
# --dry-run
|
||||||
|
# -v
|
||||||
|
# --verbose
|
||||||
|
# build
|
||||||
|
# edit
|
||||||
|
# expire-generations
|
||||||
|
# generations
|
||||||
|
# help
|
||||||
|
# news
|
||||||
|
# option
|
||||||
|
# packages
|
||||||
|
# remove-generations
|
||||||
|
# switch
|
||||||
|
# uninstall
|
||||||
|
|
||||||
|
# $ home-manager e<TAB>
|
||||||
|
#
|
||||||
|
# edit
|
||||||
|
# expire-generations
|
||||||
|
|
||||||
|
# $ home-manager remove-generations 20<TAB>
|
||||||
|
#
|
||||||
|
# 200
|
||||||
|
# 201
|
||||||
|
# 202
|
||||||
|
# 203
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Notes:
|
||||||
|
|
||||||
|
# « home-manager » Subcommands:
|
||||||
|
#
|
||||||
|
# help
|
||||||
|
# edit
|
||||||
|
# option
|
||||||
|
# build
|
||||||
|
# switch
|
||||||
|
# generations
|
||||||
|
# remove-generations
|
||||||
|
# expire-generations
|
||||||
|
# packages
|
||||||
|
# news
|
||||||
|
# uninstall
|
||||||
|
|
||||||
|
# « home-manager » Options:
|
||||||
|
#
|
||||||
|
# -b EXT
|
||||||
|
# -f FILE
|
||||||
|
# --file FILE
|
||||||
|
# -A ATTRIBUTE
|
||||||
|
# -I PATH
|
||||||
|
# -v
|
||||||
|
# --verbose
|
||||||
|
# -n
|
||||||
|
# --dry-run
|
||||||
|
# -h
|
||||||
|
# --help
|
||||||
|
|
||||||
|
# $ home-manager
|
||||||
|
#
|
||||||
|
# Usage: /home/sboo/.nix-profile/bin/home-manager [OPTION] COMMAND
|
||||||
|
#
|
||||||
|
# Options
|
||||||
|
#
|
||||||
|
# -f FILE The home configuration file.
|
||||||
|
# Default is '~/.config/nixpkgs/home.nix'.
|
||||||
|
# -A ATTRIBUTE Optional attribute that selects a configuration
|
||||||
|
# expression in the configuration file.
|
||||||
|
# -I PATH Add a path to the Nix expression search path.
|
||||||
|
# -b EXT Move existing files to new path rather than fail.
|
||||||
|
# -v Verbose output
|
||||||
|
# -n Do a dry run, only prints what actions would be taken
|
||||||
|
# -h Print this help
|
||||||
|
#
|
||||||
|
# Commands
|
||||||
|
#
|
||||||
|
# help Print this help
|
||||||
|
#
|
||||||
|
# edit Open the home configuration in $EDITOR
|
||||||
|
#
|
||||||
|
# option OPTION.NAME
|
||||||
|
# Inspect configuration option named OPTION.NAME.
|
||||||
|
#
|
||||||
|
# build Build configuration into result directory
|
||||||
|
#
|
||||||
|
# switch Build and activate configuration
|
||||||
|
#
|
||||||
|
# generations List all home environment generations
|
||||||
|
#
|
||||||
|
# remove-generations ID...
|
||||||
|
# Remove indicated generations. Use 'generations' command to
|
||||||
|
# find suitable generation numbers.
|
||||||
|
#
|
||||||
|
# expire-generations TIMESTAMP
|
||||||
|
# Remove generations older than TIMESTAMP where TIMESTAMP is
|
||||||
|
# interpreted as in the -d argument of the date tool. For
|
||||||
|
# example "-30 days" or "2018-01-01".
|
||||||
|
#
|
||||||
|
# packages List all packages installed in home-manager-path
|
||||||
|
#
|
||||||
|
# news Show news entries in a pager
|
||||||
|
#
|
||||||
|
# uninstall Remove Home Manager
|
||||||
|
#
|
||||||
|
##################################################
|
||||||
|
# Dependencies:
|
||||||
|
|
||||||
|
command -v home-manager >/dev/null
|
||||||
|
command -v grep >/dev/null
|
||||||
|
command -v sed >/dev/null
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Code:
|
||||||
|
|
||||||
|
_home-manager_list-generation-identifiers ()
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
home-manager generations | sed -n -e 's/^................ : id \([[:alnum:]]\+\) -> .*/\1/p'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# NOTES
|
||||||
|
#
|
||||||
|
# (1) the « sed -n -e 's/.../.../p' » invocation:
|
||||||
|
#
|
||||||
|
# * the « -e '...' » option takes a Sed Script.
|
||||||
|
# * the « -n » option only prints when « .../p » would print.
|
||||||
|
# * the « s/xxx/yyy/ » Sed Script substitutes « yyy » whenever « xxx » is matched.
|
||||||
|
#
|
||||||
|
# (2) the « '^................ : id \([[:alnum:]]\+\) -> .*' » regular expression:
|
||||||
|
#
|
||||||
|
# * matches « 199 », for example, in the line « 2019-03-13 15:26 : id 199 -> /nix/store/mv619y9pzgsx3kndq0q7fjfvbqqdy5k8-home-manager-generation »
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
#------------------------------------------------#
|
||||||
|
|
||||||
|
# shellcheck disable=SC2120
|
||||||
|
_home-manager_list-nix-attributes ()
|
||||||
|
|
||||||
|
{
|
||||||
|
local HomeFile
|
||||||
|
local HomeAttrsString
|
||||||
|
# local HomeAttrsArray
|
||||||
|
# local HomeAttr
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
HomeFile=$(readlink -f "$(_home-manager_get-default-home-file)")
|
||||||
|
else
|
||||||
|
HomeFile="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
HomeAttrsString=$(nix-instantiate --eval -E "let home = import ${HomeFile}; in (builtins.trace (builtins.toString (builtins.attrNames home)) null)" |& grep '^trace: ')
|
||||||
|
HomeAttrsString="${HomeAttrsString#trace: }"
|
||||||
|
|
||||||
|
echo "${HomeAttrsString}"
|
||||||
|
|
||||||
|
# IFS=" " read -ar HomeAttrsArray <<< "${HomeAttrsString}"
|
||||||
|
#
|
||||||
|
# local HomeAttr
|
||||||
|
# for HomeAttr in "${HomeAttrsArray[@]}"
|
||||||
|
# do
|
||||||
|
# echo "${HomeAttr}"
|
||||||
|
# done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# e.g.:
|
||||||
|
#
|
||||||
|
# $ nix-instantiate --eval -E 'let home = import /home/sboo/configuration/configs/nixpkgs/home-attrs.nix; in (builtins.trace (builtins.toString (builtins.attrNames home)) null)' 1>/dev/null
|
||||||
|
# trace: darwin linux
|
||||||
|
#
|
||||||
|
# $ _home-manager_list-nix-attributes
|
||||||
|
# linux darwin
|
||||||
|
#
|
||||||
|
|
||||||
|
#------------------------------------------------#
|
||||||
|
|
||||||
|
_home-manager_get-default-home-file ()
|
||||||
|
|
||||||
|
{
|
||||||
|
local HomeFileDefault
|
||||||
|
|
||||||
|
HomeFileDefault="$(_home-manager_xdg-get-config-home)/nixpkgs/home.nix"
|
||||||
|
|
||||||
|
echo "${HomeFileDefault}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# e.g.:
|
||||||
|
#
|
||||||
|
# $ _home-manager_get-default-home-file
|
||||||
|
# ~/.config/nixpkgs/home.nix
|
||||||
|
#
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# XDG-BaseDirs:
|
||||||
|
|
||||||
|
_home-manager_xdg-get-config-home () {
|
||||||
|
|
||||||
|
echo "${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#------------------------------------------------#
|
||||||
|
|
||||||
|
_home-manager_xdg-get-data-home () {
|
||||||
|
|
||||||
|
echo "${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------#
|
||||||
|
_home-manager_xdg-get-cache-home () {
|
||||||
|
|
||||||
|
echo "${XDG_CACHE_HOME:-$HOME/.cache}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# shellcheck disable=SC2207
|
||||||
|
_home-manager_completions ()
|
||||||
|
{
|
||||||
|
|
||||||
|
#--------------------------#
|
||||||
|
|
||||||
|
local Subcommands
|
||||||
|
Subcommands=( "help" "edit" "option" "build" "instantiate" "switch" "generations" "remove-generations" "expire-generations" "packages" "news" "uninstall" )
|
||||||
|
|
||||||
|
# ^ « home-manager »'s subcommands.
|
||||||
|
|
||||||
|
#--------------------------#
|
||||||
|
|
||||||
|
local Options
|
||||||
|
Options=( "-f" "--file" "-b" "-A" "-I" "-h" "--help" "-n" "--dry-run" "-v" "--verbose" \
|
||||||
|
"--cores" "--debug" "--keep-failed" "--keep-going" "-j" "--max-jobs" "--no-substitute" "--show-trace" "--substitute")
|
||||||
|
|
||||||
|
# ^ « home-manager »'s options.
|
||||||
|
|
||||||
|
#--------------------------#
|
||||||
|
|
||||||
|
local CurrentWord
|
||||||
|
CurrentWord="${COMP_WORDS[$COMP_CWORD]}"
|
||||||
|
|
||||||
|
# ^ the word currently being completed
|
||||||
|
|
||||||
|
local PreviousWord
|
||||||
|
if [ "$COMP_CWORD" -ge 1 ]
|
||||||
|
then
|
||||||
|
PreviousWord="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
else
|
||||||
|
PreviousWord=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ^ the word to the left of the current word.
|
||||||
|
#
|
||||||
|
# e.g. in « home-manager -v -f ./<TAB> »:
|
||||||
|
#
|
||||||
|
# PreviousWord="-f"
|
||||||
|
# CurrentWord="./"
|
||||||
|
|
||||||
|
#--------------------------#
|
||||||
|
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
|
case "$PreviousWord" in
|
||||||
|
|
||||||
|
"-f"|"--file")
|
||||||
|
|
||||||
|
COMPREPLY+=( $( compgen -A file -- "$CurrentWord") )
|
||||||
|
;;
|
||||||
|
|
||||||
|
"-I")
|
||||||
|
|
||||||
|
COMPREPLY+=( $( compgen -A directory -- "$CurrentWord") )
|
||||||
|
;;
|
||||||
|
|
||||||
|
"-A")
|
||||||
|
|
||||||
|
# shellcheck disable=SC2119
|
||||||
|
COMPREPLY+=( $( compgen -W "$(_home-manager_list-nix-attributes)" -- "$CurrentWord") )
|
||||||
|
;;
|
||||||
|
|
||||||
|
"remove-generations")
|
||||||
|
|
||||||
|
COMPREPLY+=( $( compgen -W "$(_home-manager_list-generation-identifiers)" -- "$CurrentWord" ) )
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
COMPREPLY+=( $( compgen -W "${Subcommands[*]}" -- "$CurrentWord" ) )
|
||||||
|
COMPREPLY+=( $( compgen -W "${Options[*]}" -- "$CurrentWord" ) )
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
#--------------------------#
|
||||||
|
}
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
complete -F _home-manager_completions -o default home-manager
|
||||||
|
|
||||||
|
#complete -W "help edit option build switch generations remove-generations expire-generations packages news" home-manager
|
||||||
62
home-manager/completion.fish
Normal file
62
home-manager/completion.fish
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/env fish
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
# « home-manager » command-line fish completion
|
||||||
|
#
|
||||||
|
# © 2021 "Ariel AxionL" <i at axionl dot me>
|
||||||
|
#
|
||||||
|
# MIT License
|
||||||
|
#
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
### Functions
|
||||||
|
function __home_manager_generations --description "Get all generations"
|
||||||
|
for i in (home-manager generations)
|
||||||
|
set -l split (string split " " $i)
|
||||||
|
set -l gen_id $split[5]
|
||||||
|
set -l gen_datetime $split[1..2]
|
||||||
|
set -l gen_hash (string match -r '\w{32}' $i)
|
||||||
|
echo $gen_id\t$gen_datetime $gen_hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
### SubCommands
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "help" -d "Print home-manager help"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "edit" -d "Open the home configuration in $EDITOR"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "option" -d "Inspect configuration option"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "build" -d "Build configuration into result directory"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "instantiate" -d "Instantiate the configuration and print the resulting derivation"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "switch" -d "Build and activate configuration"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "generations" -d "List all home environment generations"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "packages" -d "List all packages installed in home-manager-path"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "news" -d "Show news entries in a pager"
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -f -a "uninstall" -d "Remove Home Manager"
|
||||||
|
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -x -a "remove-generations" -d "Remove indicated generations"
|
||||||
|
complete -c home-manager -n "__fish_seen_subcommand_from remove-generations" -f -ka '(__home_manager_generations)'
|
||||||
|
|
||||||
|
complete -c home-manager -n "__fish_use_subcommand" -x -a "expire-generations" -d "Remove generations older than TIMESTAMP"
|
||||||
|
|
||||||
|
### Options
|
||||||
|
complete -c home-manager -F -s f -l "file" -d "The home configuration file"
|
||||||
|
complete -c home-manager -x -s A -d "Select an expression in the configuration file"
|
||||||
|
complete -c home-manager -F -s I -d "Add a path to the Nix expression search path"
|
||||||
|
complete -c home-manager -F -l "flake" -d "Use home-manager configuration at specified flake-uri"
|
||||||
|
complete -c home-manager -F -s b -d "Move existing files to new path rather than fail"
|
||||||
|
complete -c home-manager -f -s v -l "verbose" -d "Verbose output"
|
||||||
|
complete -c home-manager -f -s n -l "dry-run" -d "Do a dry run, only prints what actions would be taken"
|
||||||
|
complete -c home-manager -f -s h -l "help" -d "Print this help"
|
||||||
|
|
||||||
|
complete -c home-manager -x -l "arg" -d "Override inputs passed to home-manager.nix"
|
||||||
|
complete -c home-manager -x -l "argstr" -d "Like --arg but the value is a string"
|
||||||
|
complete -c home-manager -x -l "cores" -d "Threads per job (e.g. -j argument to make)"
|
||||||
|
complete -c home-manager -x -l "debug"
|
||||||
|
complete -c home-manager -f -l "keep-failed" -d "Keep temporary directory used by failed builds"
|
||||||
|
complete -c home-manager -f -l "keep-going" -d "Keep going in case of failed builds"
|
||||||
|
complete -c home-manager -x -s j -l "max-jobs" -d "Max number of build jobs in parallel"
|
||||||
|
complete -c home-manager -x -l "option" -d "Set Nix configuration option"
|
||||||
|
complete -c home-manager -f -l "show-trace" -d "Print stack trace of evaluation errors"
|
||||||
|
complete -c home-manager -f -l "substitute"
|
||||||
|
complete -c home-manager -f -l "no-substitute"
|
||||||
59
home-manager/completion.zsh
Normal file
59
home-manager/completion.zsh
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#compdef home-manager
|
||||||
|
|
||||||
|
local state ret=1
|
||||||
|
|
||||||
|
_arguments \
|
||||||
|
'-A[attribute]:ATTRIBUTE:()' \
|
||||||
|
'-I[search path]:PATH:_files -/' \
|
||||||
|
'-b[backup files]:EXT:()' \
|
||||||
|
'--cores[cores]:NUM:()' \
|
||||||
|
'--debug[debug]' \
|
||||||
|
'--keep-failed[keep failed]' \
|
||||||
|
'--keep-going[keep going]' \
|
||||||
|
'(-h --help)'{--help,-h}'[help]' \
|
||||||
|
'(-v --verbose)'{--verbose,-v}'[verbose]' \
|
||||||
|
'(-n --dry-run)'{--dry-run,-n}'[dry run]' \
|
||||||
|
'(-f --file)'{--file,-f}'[configuration file]:FILE:_files' \
|
||||||
|
'(-j --max-jobs)'{--max-jobs,-j}'[max jobs]:NUM:()' \
|
||||||
|
'--option[option]:NAME VALUE:()' \
|
||||||
|
'--show-trace[show trace]' \
|
||||||
|
'1: :->cmds' \
|
||||||
|
'*:: :->args' && ret=0
|
||||||
|
|
||||||
|
case "$state" in
|
||||||
|
cmds)
|
||||||
|
_values 'command' \
|
||||||
|
'help[help]' \
|
||||||
|
'edit[edit]' \
|
||||||
|
'option[inspect option]' \
|
||||||
|
'build[build]' \
|
||||||
|
'switch[switch]' \
|
||||||
|
'generations[list generations]' \
|
||||||
|
'remove-generations[remove generations]' \
|
||||||
|
'expire-generations[expire generations]' \
|
||||||
|
'packages[managed packages]' \
|
||||||
|
'news[read the news]' \
|
||||||
|
'uninstall[uninstall]' && ret=0
|
||||||
|
;;
|
||||||
|
args)
|
||||||
|
case $line[1] in
|
||||||
|
remove-generations)
|
||||||
|
_values 'generations' \
|
||||||
|
$(home-manager generations | cut -d ' ' -f 5) && ret=0
|
||||||
|
;;
|
||||||
|
build|switch)
|
||||||
|
_arguments \
|
||||||
|
'--cores[cores]:NUM:()' \
|
||||||
|
'--debug[debug]' \
|
||||||
|
'--keep-failed[keep failed]' \
|
||||||
|
'--keep-going[keep going]' \
|
||||||
|
'--max-jobs[max jobs]:NUM:()' \
|
||||||
|
'--no-substitute[no substitute]' \
|
||||||
|
'--option[option]:NAME VALUE:()' \
|
||||||
|
'--show-trace[show trace]' \
|
||||||
|
'--substitute[substitute]'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
esac
|
||||||
|
|
||||||
|
return ret
|
||||||
@@ -1,41 +1,44 @@
|
|||||||
{ pkgs, modulesPath ? "$HOME/.config/nixpkgs/home-manager/modules" }:
|
{ runCommand, lib, bash, callPackage, coreutils, findutils, gnused, less
|
||||||
|
# used for pkgs.path for nixos-option
|
||||||
|
, pkgs
|
||||||
|
|
||||||
|
# Extra path to Home Manager. If set then this path will be tried
|
||||||
|
# before `$HOME/.config/nixpkgs/home-manager` and
|
||||||
|
# `$HOME/.nixpkgs/home-manager`.
|
||||||
|
, path ? null }:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
homeManagerExpr = pkgs.writeText "home-manager.nix" ''
|
pathStr = if path == null then "" else path;
|
||||||
{ pkgs ? import <nixpkgs> {}, confPath }:
|
|
||||||
|
|
||||||
let
|
nixos-option = pkgs.nixos-option or (callPackage
|
||||||
env = import <home-manager> {
|
(pkgs.path + "/nixos/modules/installer/tools/nixos-option") { });
|
||||||
configuration = import confPath;
|
|
||||||
pkgs = pkgs;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit (env) activation-script;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
in runCommand "home-manager" {
|
||||||
|
preferLocalBuild = true;
|
||||||
pkgs.stdenv.mkDerivation {
|
allowSubstitutes = false;
|
||||||
name = "home-manager";
|
meta = with lib; {
|
||||||
|
|
||||||
phases = [ "installPhase" ];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
install -v -D -m755 ${./home-manager} $out/bin/home-manager
|
|
||||||
|
|
||||||
substituteInPlace $out/bin/home-manager \
|
|
||||||
--subst-var-by bash "${pkgs.bash}" \
|
|
||||||
--subst-var-by coreutils "${pkgs.coreutils}" \
|
|
||||||
--subst-var-by MODULES_PATH '${modulesPath}' \
|
|
||||||
--subst-var-by HOME_MANAGER_EXPR_PATH "${homeManagerExpr}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with pkgs.stdenv.lib; {
|
|
||||||
description = "A user environment configurator";
|
description = "A user environment configurator";
|
||||||
maintainers = [ maintainers.rycee ];
|
maintainers = [ maintainers.rycee ];
|
||||||
platforms = platforms.linux;
|
platforms = platforms.unix;
|
||||||
|
license = licenses.mit;
|
||||||
};
|
};
|
||||||
}
|
} ''
|
||||||
|
install -v -D -m755 ${./home-manager} $out/bin/home-manager
|
||||||
|
|
||||||
|
substituteInPlace $out/bin/home-manager \
|
||||||
|
--subst-var-by bash "${bash}" \
|
||||||
|
--subst-var-by coreutils "${coreutils}" \
|
||||||
|
--subst-var-by findutils "${findutils}" \
|
||||||
|
--subst-var-by gnused "${gnused}" \
|
||||||
|
--subst-var-by less "${less}" \
|
||||||
|
--subst-var-by nixos-option "${nixos-option}" \
|
||||||
|
--subst-var-by HOME_MANAGER_PATH '${pathStr}'
|
||||||
|
|
||||||
|
install -D -m755 ${./completion.bash} \
|
||||||
|
$out/share/bash-completion/completions/home-manager
|
||||||
|
install -D -m755 ${./completion.zsh} \
|
||||||
|
$out/share/zsh/site-functions/_home-manager
|
||||||
|
install -D -m755 ${./completion.fish} \
|
||||||
|
$out/share/fish/vendor_completions.d/home-manager.fish
|
||||||
|
''
|
||||||
|
|||||||
@@ -1,12 +1,37 @@
|
|||||||
#!@bash@/bin/bash
|
#!@bash@/bin/bash
|
||||||
|
|
||||||
# This code explicitly requires GNU Core Utilities and we therefore
|
# Prepare to use tools from Nixpkgs.
|
||||||
# need to ensure they are prioritized over any other similarly named
|
PATH=@coreutils@/bin:@findutils@/bin:@gnused@/bin:@less@/bin:@nixos-option@/bin${PATH:+:}$PATH
|
||||||
# tools on the system.
|
|
||||||
PATH=@coreutils@/bin:$PATH
|
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
function errorEcho() {
|
||||||
|
# shellcheck disable=2048,2086
|
||||||
|
echo $* >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVerboseAndDryRun() {
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
export VERBOSE_ARG="--verbose"
|
||||||
|
else
|
||||||
|
export VERBOSE_ARG=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v DRY_RUN ]] ; then
|
||||||
|
export DRY_RUN_CMD=echo
|
||||||
|
else
|
||||||
|
export DRY_RUN_CMD=""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWorkDir() {
|
||||||
|
if [[ ! -v WORK_DIR ]]; then
|
||||||
|
WORK_DIR="$(mktemp --tmpdir -d home-manager-build.XXXXXXXXXX)"
|
||||||
|
# shellcheck disable=2064
|
||||||
|
trap "rm -r '$WORK_DIR'" EXIT
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Attempts to set the HOME_MANAGER_CONFIG global variable.
|
# Attempts to set the HOME_MANAGER_CONFIG global variable.
|
||||||
#
|
#
|
||||||
# If no configuration file can be found then this function will print
|
# If no configuration file can be found then this function will print
|
||||||
@@ -14,7 +39,7 @@ set -euo pipefail
|
|||||||
function setConfigFile() {
|
function setConfigFile() {
|
||||||
if [[ -v HOME_MANAGER_CONFIG ]] ; then
|
if [[ -v HOME_MANAGER_CONFIG ]] ; then
|
||||||
if [[ ! -e "$HOME_MANAGER_CONFIG" ]] ; then
|
if [[ ! -e "$HOME_MANAGER_CONFIG" ]] ; then
|
||||||
echo "No configure file found at $HOME_MANAGER_CONFIG"
|
errorEcho "No configuration file found at $HOME_MANAGER_CONFIG"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -22,155 +47,615 @@ function setConfigFile() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local defaultConfFile="${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
|
||||||
local confFile
|
local confFile
|
||||||
for confFile in "$HOME/.config/nixpkgs/home.nix" \
|
for confFile in "$defaultConfFile" \
|
||||||
"$HOME/.nixpkgs/home.nix" ; do
|
"$HOME/.nixpkgs/home.nix" ; do
|
||||||
if [[ -e "$confFile" ]] ; then
|
if [[ -e "$confFile" ]] ; then
|
||||||
HOME_MANAGER_CONFIG="$confFile"
|
HOME_MANAGER_CONFIG="$(realpath "$confFile")"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "No configuration file found. " \
|
errorEcho "No configuration file found." \
|
||||||
"Please create one at ~/.config/nixpkgs/home.nix"
|
"Please create one at $defaultConfFile"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function setHomeManagerModulesPath() {
|
function setHomeManagerNixPath() {
|
||||||
local modulesPath
|
local path
|
||||||
for modulesPath in "@MODULES_PATH@" \
|
for path in "@HOME_MANAGER_PATH@" \
|
||||||
"$HOME/.nixpkgs/home-manager/modules" ; do
|
"${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home-manager" \
|
||||||
if [[ -e "$modulesPath" ]] ; then
|
"$HOME/.nixpkgs/home-manager" ; do
|
||||||
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=$modulesPath"
|
if [[ -e "$path" || "$path" =~ ^https?:// ]] ; then
|
||||||
|
export NIX_PATH="home-manager=$path${NIX_PATH:+:}$NIX_PATH"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function doBuild() {
|
function setFlakeAttribute() {
|
||||||
if [[ -z "$1" ]]; then
|
local configFlake="${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/flake.nix"
|
||||||
echo "Need to provide generation output path."
|
if [[ -z $FLAKE_ARG && ! -v HOME_MANAGER_CONFIG && -e "$configFlake" ]]; then
|
||||||
exit 1
|
FLAKE_ARG="$(dirname "$(readlink -f "$configFlake")")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -e "$1" ]]; then
|
if [[ -n "$FLAKE_ARG" ]]; then
|
||||||
echo "The output path $1 already exists."
|
local flake="${FLAKE_ARG%#*}"
|
||||||
|
case $FLAKE_ARG in
|
||||||
|
*#*)
|
||||||
|
local name="${FLAKE_ARG#*#}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
local name="$USER@$(hostname)"
|
||||||
|
if [ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$name\"")" = "false" ]; then
|
||||||
|
name="$USER"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$name\""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function doInspectOption() {
|
||||||
|
setFlakeAttribute
|
||||||
|
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||||
|
errorEcho "Can't inspect options of a flake configuration"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
setConfigFile
|
setConfigFile
|
||||||
setHomeManagerModulesPath
|
setHomeManagerNixPath
|
||||||
|
|
||||||
output="$(realpath "$1")"
|
local extraArgs=("$@")
|
||||||
|
|
||||||
if [[ $? -ne 0 ]]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=@MODULES_PATH@"
|
|
||||||
|
|
||||||
local extraArgs
|
|
||||||
extraArgs=""
|
|
||||||
|
|
||||||
for p in "${EXTRA_NIX_PATH[@]}"; do
|
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||||
extraArgs="$extraArgs -I $p"
|
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -v VERBOSE ]]; then
|
if [[ -v VERBOSE ]]; then
|
||||||
extraArgs="$extraArgs --show-trace"
|
extraArgs=("${extraArgs[@]}" "--show-trace")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
nix-build $extraArgs \
|
local HOME_MANAGER_CONFIG_NIX HOME_MANAGER_CONFIG_ATTRIBUTE_NIX
|
||||||
"@HOME_MANAGER_EXPR_PATH@" \
|
HOME_MANAGER_CONFIG_NIX=${HOME_MANAGER_CONFIG//'\'/'\\'}
|
||||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
HOME_MANAGER_CONFIG_NIX=${HOME_MANAGER_CONFIG_NIX//'"'/'\"'}
|
||||||
-A activation-script \
|
HOME_MANAGER_CONFIG_NIX=${HOME_MANAGER_CONFIG_NIX//$'\n'/$'\\n'}
|
||||||
-o "$output"
|
HOME_MANAGER_CONFIG_ATTRIBUTE_NIX=${HOME_MANAGER_CONFIG_ATTRIBUTE//'\'/'\\'}
|
||||||
|
HOME_MANAGER_CONFIG_ATTRIBUTE_NIX=${HOME_MANAGER_CONFIG_ATTRIBUTE_NIX//'"'/'\"'}
|
||||||
|
HOME_MANAGER_CONFIG_ATTRIBUTE_NIX=${HOME_MANAGER_CONFIG_ATTRIBUTE_NIX//$'\n'/$'\\n'}
|
||||||
|
local modulesExpr
|
||||||
|
modulesExpr="let confPath = \"${HOME_MANAGER_CONFIG_NIX}\"; "
|
||||||
|
modulesExpr+="confAttr = \"${HOME_MANAGER_CONFIG_ATTRIBUTE_NIX}\"; in "
|
||||||
|
modulesExpr+="(import <home-manager/modules> {"
|
||||||
|
modulesExpr+=" configuration = if confAttr == \"\" then confPath else (import confPath).\${confAttr};"
|
||||||
|
modulesExpr+=" pkgs = import <nixpkgs> {}; check = true; })"
|
||||||
|
|
||||||
|
nixos-option \
|
||||||
|
--options_expr "$modulesExpr.options" \
|
||||||
|
--config_expr "$modulesExpr.config" \
|
||||||
|
"${extraArgs[@]}" \
|
||||||
|
"${PASSTHROUGH_OPTS[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function doInstantiate() {
|
||||||
|
setFlakeAttribute
|
||||||
|
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||||
|
errorEcho "Can't instantiate a flake configuration"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
setConfigFile
|
||||||
|
setHomeManagerNixPath
|
||||||
|
|
||||||
|
local extraArgs=()
|
||||||
|
|
||||||
|
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||||
|
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
extraArgs=("${extraArgs[@]}" "--show-trace")
|
||||||
|
fi
|
||||||
|
|
||||||
|
nix-instantiate \
|
||||||
|
"<home-manager/home-manager/home-manager.nix>" \
|
||||||
|
"${extraArgs[@]}" \
|
||||||
|
"${PASSTHROUGH_OPTS[@]}" \
|
||||||
|
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||||
|
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||||
|
}
|
||||||
|
|
||||||
|
function doBuildAttr() {
|
||||||
|
setConfigFile
|
||||||
|
setHomeManagerNixPath
|
||||||
|
|
||||||
|
local extraArgs=("$@")
|
||||||
|
|
||||||
|
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||||
|
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
extraArgs=("${extraArgs[@]}" "--show-trace")
|
||||||
|
fi
|
||||||
|
|
||||||
|
nix-build \
|
||||||
|
"<home-manager/home-manager/home-manager.nix>" \
|
||||||
|
"${extraArgs[@]}" \
|
||||||
|
"${PASSTHROUGH_OPTS[@]}" \
|
||||||
|
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||||
|
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Presents news to the user. Takes as argument the path to a "news
|
||||||
|
# info" file as generated by `buildNews`.
|
||||||
|
function presentNews() {
|
||||||
|
local infoFile="$1"
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$infoFile"
|
||||||
|
|
||||||
|
# shellcheck disable=2154
|
||||||
|
if [[ $newsNumUnread -eq 0 ]]; then
|
||||||
|
return
|
||||||
|
elif [[ "$newsDisplay" == "silent" ]]; then
|
||||||
|
return
|
||||||
|
elif [[ "$newsDisplay" == "notify" ]]; then
|
||||||
|
local msg
|
||||||
|
if [[ $newsNumUnread -eq 1 ]]; then
|
||||||
|
msg="There is an unread and relevant news item.\n"
|
||||||
|
msg+="Read it by running the command '$(basename "$0") news'."
|
||||||
|
else
|
||||||
|
msg="There are $newsNumUnread unread and relevant news items.\n"
|
||||||
|
msg+="Read them by running the command '$(basename "$0") news'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Not actually an error but here stdout is reserved for
|
||||||
|
# nix-build output.
|
||||||
|
errorEcho
|
||||||
|
errorEcho -e "$msg"
|
||||||
|
errorEcho
|
||||||
|
|
||||||
|
if [[ -v DISPLAY ]] && type -P notify-send > /dev/null; then
|
||||||
|
notify-send "Home Manager" "$msg"
|
||||||
|
fi
|
||||||
|
elif [[ "$newsDisplay" == "show" ]]; then
|
||||||
|
doShowNews --unread
|
||||||
|
else
|
||||||
|
errorEcho "Unknown 'news.display' setting '$newsDisplay'."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function doEdit() {
|
||||||
|
if [[ ! -v EDITOR || -z $EDITOR ]]; then
|
||||||
|
errorEcho "Please set the \$EDITOR environment variable"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
setConfigFile
|
||||||
|
|
||||||
|
# Don't quote $EDITOR in order to support values including options, e.g.,
|
||||||
|
# "code --wait".
|
||||||
|
#
|
||||||
|
# shellcheck disable=2086
|
||||||
|
exec $EDITOR "$HOME_MANAGER_CONFIG"
|
||||||
|
}
|
||||||
|
|
||||||
|
function doBuild() {
|
||||||
|
if [[ ! -w . ]]; then
|
||||||
|
errorEcho "Cannot run build in read-only directory";
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
setFlakeAttribute
|
||||||
|
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||||
|
local exitCode=0
|
||||||
|
nix build \
|
||||||
|
"${PASSTHROUGH_OPTS[@]}" \
|
||||||
|
${DRY_RUN+--dry-run} \
|
||||||
|
"$FLAKE_CONFIG_URI.activationPackage" \
|
||||||
|
|| exitCode=1
|
||||||
|
return $exitCode
|
||||||
|
fi
|
||||||
|
|
||||||
|
setWorkDir
|
||||||
|
|
||||||
|
local newsInfo
|
||||||
|
newsInfo=$(buildNews)
|
||||||
|
|
||||||
|
local exitCode
|
||||||
|
|
||||||
|
doBuildAttr --attr activationPackage \
|
||||||
|
&& exitCode=0 || exitCode=1
|
||||||
|
|
||||||
|
presentNews "$newsInfo"
|
||||||
|
|
||||||
|
return $exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSwitch() {
|
function doSwitch() {
|
||||||
local wrkdir
|
setFlakeAttribute
|
||||||
wrkdir="$(mktemp -d)"
|
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||||
|
local exitCode=0
|
||||||
if doBuild "$wrkdir/generation" ; then
|
nix run \
|
||||||
"$wrkdir/generation/activate"
|
"${PASSTHROUGH_OPTS[@]}" \
|
||||||
|
"$FLAKE_CONFIG_URI.activationPackage" \
|
||||||
|
|| exitCode=1
|
||||||
|
return $exitCode
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -r "$wrkdir"
|
setWorkDir
|
||||||
|
|
||||||
|
local newsInfo
|
||||||
|
newsInfo=$(buildNews)
|
||||||
|
|
||||||
|
local generation
|
||||||
|
local exitCode=0
|
||||||
|
|
||||||
|
# Build the generation and run the activate script. Note, we
|
||||||
|
# specify an output link so that it is treated as a GC root. This
|
||||||
|
# prevents an unfortunately timed GC from removing the generation
|
||||||
|
# before activation completes.
|
||||||
|
generation="$WORK_DIR/generation"
|
||||||
|
|
||||||
|
doBuildAttr \
|
||||||
|
--out-link "$generation" \
|
||||||
|
--attr activationPackage \
|
||||||
|
&& "$generation/activate" || exitCode=1
|
||||||
|
|
||||||
|
presentNews "$newsInfo"
|
||||||
|
|
||||||
|
return $exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
function doListGens() {
|
function doListGens() {
|
||||||
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
|
# Whether to colorize the generations output.
|
||||||
ls --color=yes -gG --sort time home-manager-*-link \
|
local color="never"
|
||||||
| cut -d' ' -f 4-
|
if [[ ! -v NO_COLOR && -t 1 ]]; then
|
||||||
|
color="always"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd "$NIX_STATE_DIR/profiles/per-user/$USER" > /dev/null
|
||||||
|
# shellcheck disable=2012
|
||||||
|
ls --color=$color -gG --time-style=long-iso --sort time home-manager-*-link \
|
||||||
|
| cut -d' ' -f 4- \
|
||||||
|
| sed -E 's/home-manager-([[:digit:]]*)-link/: id \1/'
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Removes linked generations. Takes as arguments identifiers of
|
||||||
|
# generations to remove.
|
||||||
|
function doRmGenerations() {
|
||||||
|
setVerboseAndDryRun
|
||||||
|
|
||||||
|
pushd "$NIX_STATE_DIR/profiles/per-user/$USER" > /dev/null
|
||||||
|
|
||||||
|
for generationId in "$@"; do
|
||||||
|
local linkName="home-manager-$generationId-link"
|
||||||
|
|
||||||
|
if [[ ! -e $linkName ]]; then
|
||||||
|
errorEcho "No generation with ID $generationId"
|
||||||
|
elif [[ $linkName == $(readlink home-manager) ]]; then
|
||||||
|
errorEcho "Cannot remove the current generation $generationId"
|
||||||
|
else
|
||||||
|
echo Removing generation $generationId
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG $linkName
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function doRmAllGenerations() {
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG \
|
||||||
|
"$NIX_STATE_DIR/profiles/per-user/$USER/home-manager"*
|
||||||
|
}
|
||||||
|
|
||||||
|
function doExpireGenerations() {
|
||||||
|
local profileDir="$NIX_STATE_DIR/profiles/per-user/$USER"
|
||||||
|
|
||||||
|
local generations
|
||||||
|
generations="$( \
|
||||||
|
find "$profileDir" -name 'home-manager-*-link' -not -newermt "$1" \
|
||||||
|
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
|
||||||
|
)"
|
||||||
|
|
||||||
|
if [[ -n $generations ]]; then
|
||||||
|
# shellcheck disable=2086
|
||||||
|
doRmGenerations $generations
|
||||||
|
elif [[ -v VERBOSE ]]; then
|
||||||
|
echo "No generations to expire"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function doListPackages() {
|
function doListPackages() {
|
||||||
local outPath
|
local outPath
|
||||||
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
|
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
|
||||||
if [[ -n "$outPath" ]] ; then
|
if [[ -n "$outPath" ]] ; then
|
||||||
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
||||||
else
|
else
|
||||||
echo "No home-manager packages seem to be installed."
|
errorEcho "No home-manager packages seem to be installed."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function newsReadIdsFile() {
|
||||||
|
local dataDir="${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
||||||
|
local path="$dataDir/news-read-ids"
|
||||||
|
|
||||||
|
# If the path doesn't exist then we should create it, otherwise
|
||||||
|
# Nix will error out when we attempt to use builtins.readFile.
|
||||||
|
if [[ ! -f "$path" ]]; then
|
||||||
|
mkdir -p "$dataDir"
|
||||||
|
touch "$path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Builds news meta information to be sourced into this script.
|
||||||
|
#
|
||||||
|
# Note, we suppress build output to remove unnecessary verbosity. We
|
||||||
|
# put the output in the work directory to avoid the risk of an
|
||||||
|
# unfortunately timed GC removing it.
|
||||||
|
function buildNews() {
|
||||||
|
local output
|
||||||
|
output="$WORK_DIR/news-info.sh"
|
||||||
|
|
||||||
|
doBuildAttr \
|
||||||
|
--out-link "$output" \
|
||||||
|
--no-build-output \
|
||||||
|
--quiet \
|
||||||
|
--arg check false \
|
||||||
|
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||||
|
--attr newsInfo \
|
||||||
|
> /dev/null
|
||||||
|
|
||||||
|
echo "$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
function doShowNews() {
|
||||||
|
setWorkDir
|
||||||
|
|
||||||
|
local infoFile
|
||||||
|
infoFile=$(buildNews) || return 1
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$infoFile"
|
||||||
|
|
||||||
|
# shellcheck disable=2154
|
||||||
|
case $1 in
|
||||||
|
--all)
|
||||||
|
${PAGER:-less} "$newsFileAll"
|
||||||
|
;;
|
||||||
|
--unread)
|
||||||
|
${PAGER:-less} "$newsFileUnread"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
errorEcho "Unknown argument $1"
|
||||||
|
return 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
# shellcheck disable=2154
|
||||||
|
if [[ -s "$newsUnreadIdsFile" ]]; then
|
||||||
|
local newsReadIdsFile
|
||||||
|
newsReadIdsFile="$(newsReadIdsFile)"
|
||||||
|
cat "$newsUnreadIdsFile" >> "$newsReadIdsFile"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function doUninstall() {
|
||||||
|
setVerboseAndDryRun
|
||||||
|
|
||||||
|
echo "This will remove Home Manager from your system."
|
||||||
|
|
||||||
|
if [[ -v DRY_RUN ]]; then
|
||||||
|
echo "This is a dry run, nothing will actually be uninstalled."
|
||||||
|
fi
|
||||||
|
|
||||||
|
local confirmation
|
||||||
|
read -r -n 1 -p "Really uninstall Home Manager? [y/n] " confirmation
|
||||||
|
echo
|
||||||
|
|
||||||
|
case $confirmation in
|
||||||
|
y|Y)
|
||||||
|
echo "Switching to empty Home Manager configuration..."
|
||||||
|
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
|
||||||
|
echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG"
|
||||||
|
doSwitch
|
||||||
|
$DRY_RUN_CMD nix-env -e home-manager-path || true
|
||||||
|
rm "$HOME_MANAGER_CONFIG"
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
|
||||||
|
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG \
|
||||||
|
"$NIX_STATE_DIR/gcroots/per-user/$USER/current-home"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Yay!"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local deleteProfiles
|
||||||
|
read -r -n 1 \
|
||||||
|
-p 'Remove all Home Manager generations? [y/n] ' \
|
||||||
|
deleteProfiles
|
||||||
|
echo
|
||||||
|
|
||||||
|
case $deleteProfiles in
|
||||||
|
y|Y)
|
||||||
|
doRmAllGenerations
|
||||||
|
echo "All generations are now eligible for garbage collection."
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Leaving generations but they may still be garbage collected."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Home Manager is uninstalled but your home.nix is left untouched."
|
||||||
|
}
|
||||||
|
|
||||||
function doHelp() {
|
function doHelp() {
|
||||||
echo "Usage: $0 [OPTION] COMMAND"
|
echo "Usage: $0 [OPTION] COMMAND"
|
||||||
echo
|
echo
|
||||||
echo "Options"
|
echo "Options"
|
||||||
echo
|
echo
|
||||||
echo " -f FILE The home configuration file."
|
echo " -f FILE The home configuration file."
|
||||||
echo " Default is '~/.config/nixpkgs/home.nix'."
|
echo " Default is '~/.config/nixpkgs/home.nix'."
|
||||||
echo " -I PATH Add a path to the Nix expression search path."
|
echo " -A ATTRIBUTE Optional attribute that selects a configuration"
|
||||||
echo " -v Verbose output"
|
echo " expression in the configuration file."
|
||||||
echo " -n Do a dry run, only prints what actions would be taken"
|
echo " -I PATH Add a path to the Nix expression search path."
|
||||||
echo " -h Print this help"
|
echo " --flake flake-uri Use home-manager configuration at flake-uri"
|
||||||
|
echo " -b EXT Move existing files to new path rather than fail."
|
||||||
|
echo " -v Verbose output"
|
||||||
|
echo " -n Do a dry run, only prints what actions would be taken"
|
||||||
|
echo " -h Print this help"
|
||||||
|
echo
|
||||||
|
echo "Options passed on to nix-build(1)"
|
||||||
|
echo
|
||||||
|
echo " --arg(str) NAME VALUE Override inputs passed to home-manager.nix"
|
||||||
|
echo " --cores NUM"
|
||||||
|
echo " --debug"
|
||||||
|
echo " --keep-failed"
|
||||||
|
echo " --keep-going"
|
||||||
|
echo " -j, --max-jobs NUM"
|
||||||
|
echo " --option NAME VALUE"
|
||||||
|
echo " --show-trace"
|
||||||
|
echo " --(no-)substitute"
|
||||||
echo
|
echo
|
||||||
echo "Commands"
|
echo "Commands"
|
||||||
|
echo
|
||||||
echo " help Print this help"
|
echo " help Print this help"
|
||||||
|
echo
|
||||||
|
echo " edit Open the home configuration in \$EDITOR"
|
||||||
|
echo
|
||||||
|
echo " option OPTION.NAME"
|
||||||
|
echo " Inspect configuration option named OPTION.NAME."
|
||||||
|
echo
|
||||||
echo " build Build configuration into result directory"
|
echo " build Build configuration into result directory"
|
||||||
|
echo
|
||||||
|
echo " instantiate Instantiate the configuration and print the resulting derivation"
|
||||||
|
echo
|
||||||
echo " switch Build and activate configuration"
|
echo " switch Build and activate configuration"
|
||||||
|
echo
|
||||||
echo " generations List all home environment generations"
|
echo " generations List all home environment generations"
|
||||||
|
echo
|
||||||
|
echo " remove-generations ID..."
|
||||||
|
echo " Remove indicated generations. Use 'generations' command to"
|
||||||
|
echo " find suitable generation numbers."
|
||||||
|
echo
|
||||||
|
echo " expire-generations TIMESTAMP"
|
||||||
|
echo " Remove generations older than TIMESTAMP where TIMESTAMP is"
|
||||||
|
echo " interpreted as in the -d argument of the date tool. For"
|
||||||
|
echo " example \"-30 days\" or \"2018-01-01\"."
|
||||||
|
echo
|
||||||
echo " packages List all packages installed in home-manager-path"
|
echo " packages List all packages installed in home-manager-path"
|
||||||
|
echo
|
||||||
|
echo " news Show news entries in a pager"
|
||||||
|
echo
|
||||||
|
echo " uninstall Remove Home Manager"
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTRA_NIX_PATH=()
|
readonly NIX_STATE_DIR="${NIX_STATE_DIR:-/nix/var/nix}"
|
||||||
|
|
||||||
while getopts f:I:vnh opt; do
|
EXTRA_NIX_PATH=()
|
||||||
|
HOME_MANAGER_CONFIG_ATTRIBUTE=""
|
||||||
|
PASSTHROUGH_OPTS=()
|
||||||
|
COMMAND=""
|
||||||
|
COMMAND_ARGS=()
|
||||||
|
FLAKE_ARG=""
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
opt="$1"
|
||||||
|
shift
|
||||||
case $opt in
|
case $opt in
|
||||||
f)
|
build|instantiate|option|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
|
||||||
HOME_MANAGER_CONFIG="$OPTARG"
|
COMMAND="$opt"
|
||||||
;;
|
;;
|
||||||
I)
|
-A)
|
||||||
EXTRA_NIX_PATH+=("$OPTARG")
|
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
v)
|
-I)
|
||||||
export VERBOSE=1
|
EXTRA_NIX_PATH+=("$1")
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
n)
|
-b)
|
||||||
export DRY_RUN=1
|
export HOME_MANAGER_BACKUP_EXT="$1"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
h)
|
-f|--file)
|
||||||
|
HOME_MANAGER_CONFIG="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--flake)
|
||||||
|
FLAKE_ARG="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt")
|
||||||
|
;;
|
||||||
|
--update-input)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--override-input)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
doHelp
|
doHelp
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
-n|--dry-run)
|
||||||
|
export DRY_RUN=1
|
||||||
|
;;
|
||||||
|
--option|--arg|--argstr)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-j|--max-jobs|--cores)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--debug|--keep-failed|--keep-going|--show-trace\
|
||||||
|
|--substitute|--no-substitute)
|
||||||
|
PASSTHROUGH_OPTS+=("$opt")
|
||||||
|
;;
|
||||||
|
-v|--verbose)
|
||||||
|
export VERBOSE=1
|
||||||
|
;;
|
||||||
|
--version)
|
||||||
|
echo 21.11
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown option -$OPTARG" >&2
|
case $COMMAND in
|
||||||
doHelp >&2
|
expire-generations|remove-generations|option)
|
||||||
exit 1
|
COMMAND_ARGS+=("$opt")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
errorEcho "$0: unknown option '$opt'"
|
||||||
|
errorEcho "Run '$0 --help' for usage help"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Get rid of the options.
|
if [[ -z $COMMAND ]]; then
|
||||||
shift "$((OPTIND-1))"
|
doHelp >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
cmd="$*"
|
case $COMMAND in
|
||||||
|
edit)
|
||||||
case "$cmd" in
|
doEdit
|
||||||
|
;;
|
||||||
build)
|
build)
|
||||||
doBuild "result"
|
doBuild
|
||||||
|
;;
|
||||||
|
instantiate)
|
||||||
|
doInstantiate
|
||||||
;;
|
;;
|
||||||
switch)
|
switch)
|
||||||
doSwitch
|
doSwitch
|
||||||
@@ -178,14 +663,34 @@ case "$cmd" in
|
|||||||
generations)
|
generations)
|
||||||
doListGens
|
doListGens
|
||||||
;;
|
;;
|
||||||
|
remove-generations)
|
||||||
|
doRmGenerations "${COMMAND_ARGS[@]}"
|
||||||
|
;;
|
||||||
|
expire-generations)
|
||||||
|
if [[ ${#COMMAND_ARGS[@]} != 1 ]]; then
|
||||||
|
errorEcho "expire-generations expects one argument, got ${#COMMAND_ARGS[@]}."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
doExpireGenerations "${COMMAND_ARGS[@]}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
option)
|
||||||
|
doInspectOption "${COMMAND_ARGS[@]}"
|
||||||
|
;;
|
||||||
packages)
|
packages)
|
||||||
doListPackages
|
doListPackages
|
||||||
;;
|
;;
|
||||||
help|--help)
|
news)
|
||||||
|
doShowNews --all
|
||||||
|
;;
|
||||||
|
uninstall)
|
||||||
|
doUninstall
|
||||||
|
;;
|
||||||
|
help)
|
||||||
doHelp
|
doHelp
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown command: $cmd"
|
errorEcho "Unknown command: $COMMAND"
|
||||||
doHelp >&2
|
doHelp >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
|||||||
88
home-manager/home-manager.nix
Normal file
88
home-manager/home-manager.nix
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
{ pkgs ? import <nixpkgs> {}
|
||||||
|
, confPath
|
||||||
|
, confAttr ? null
|
||||||
|
, check ? true
|
||||||
|
, newsReadIdsFile ? null
|
||||||
|
}:
|
||||||
|
|
||||||
|
with pkgs.lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
env = import ../modules {
|
||||||
|
configuration =
|
||||||
|
if confAttr == "" || confAttr == null
|
||||||
|
then confPath
|
||||||
|
else (import confPath).${confAttr};
|
||||||
|
pkgs = pkgs;
|
||||||
|
check = check;
|
||||||
|
};
|
||||||
|
|
||||||
|
newsReadIds =
|
||||||
|
if newsReadIdsFile == null
|
||||||
|
then {}
|
||||||
|
else
|
||||||
|
let
|
||||||
|
ids = splitString "\n" (fileContents newsReadIdsFile);
|
||||||
|
in
|
||||||
|
builtins.listToAttrs (map (id: { name = id; value = null; }) ids);
|
||||||
|
|
||||||
|
newsIsRead = entry: builtins.hasAttr entry.id newsReadIds;
|
||||||
|
|
||||||
|
newsFiltered =
|
||||||
|
let
|
||||||
|
pred = entry: entry.condition && ! newsIsRead entry;
|
||||||
|
in
|
||||||
|
filter pred env.newsEntries;
|
||||||
|
|
||||||
|
newsNumUnread = length newsFiltered;
|
||||||
|
|
||||||
|
newsFileUnread = pkgs.writeText "news-unread.txt" (
|
||||||
|
concatMapStringsSep "\n\n" (entry:
|
||||||
|
let
|
||||||
|
time = replaceStrings ["T"] [" "] (removeSuffix "+00:00" entry.time);
|
||||||
|
in
|
||||||
|
''
|
||||||
|
* ${time}
|
||||||
|
|
||||||
|
${replaceStrings ["\n"] ["\n "] entry.message}
|
||||||
|
''
|
||||||
|
) newsFiltered
|
||||||
|
);
|
||||||
|
|
||||||
|
newsFileAll = pkgs.writeText "news-all.txt" (
|
||||||
|
concatMapStringsSep "\n\n" (entry:
|
||||||
|
let
|
||||||
|
flag = if newsIsRead entry then "read" else "unread";
|
||||||
|
time = replaceStrings ["T"] [" "] (removeSuffix "+00:00" entry.time);
|
||||||
|
in
|
||||||
|
''
|
||||||
|
* ${time} [${flag}]
|
||||||
|
|
||||||
|
${replaceStrings ["\n"] ["\n "] entry.message}
|
||||||
|
''
|
||||||
|
) env.newsEntries
|
||||||
|
);
|
||||||
|
|
||||||
|
# File where each line corresponds to an unread news entry
|
||||||
|
# identifier. If non-empty then the file ends in "\n".
|
||||||
|
newsUnreadIdsFile = pkgs.writeText "news-unread-ids" (
|
||||||
|
let
|
||||||
|
text = concatMapStringsSep "\n" (entry: entry.id) newsFiltered;
|
||||||
|
in
|
||||||
|
text + optionalString (text != "") "\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
newsInfo = pkgs.writeText "news-info.sh" ''
|
||||||
|
local newsNumUnread=${toString newsNumUnread}
|
||||||
|
local newsDisplay="${env.newsDisplay}"
|
||||||
|
local newsFileAll="${newsFileAll}"
|
||||||
|
local newsFileUnread="${newsFileUnread}"
|
||||||
|
local newsUnreadIdsFile="${newsUnreadIdsFile}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit (env) activationPackage;
|
||||||
|
inherit newsInfo;
|
||||||
|
}
|
||||||
84
home-manager/install.nix
Normal file
84
home-manager/install.nix
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{ home-manager, runCommand }:
|
||||||
|
|
||||||
|
runCommand "home-manager-install" {
|
||||||
|
propagatedBuildInputs = [ home-manager ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
shellHookOnly = true;
|
||||||
|
shellHook = ''
|
||||||
|
confFile="''${XDG_CONFIG_HOME:-$HOME/.config}/nixpkgs/home.nix"
|
||||||
|
|
||||||
|
if [[ ! -e $confFile ]]; then
|
||||||
|
echo
|
||||||
|
echo "Creating initial Home Manager configuration..."
|
||||||
|
|
||||||
|
nl=$'\n'
|
||||||
|
xdgVars=""
|
||||||
|
if [[ -v XDG_CACHE_HOME && $XDG_CACHE_HOME != "$HOME/.cache" ]]; then
|
||||||
|
xdgVars="$xdgVars xdg.cacheHome = \"$XDG_CACHE_HOME\";$nl"
|
||||||
|
fi
|
||||||
|
if [[ -v XDG_CONFIG_HOME && $XDG_CONFIG_HOME != "$HOME/.config" ]]; then
|
||||||
|
xdgVars="$xdgVars xdg.configHome = \"$XDG_CONFIG_HOME\";$nl"
|
||||||
|
fi
|
||||||
|
if [[ -v XDG_DATA_HOME && $XDG_DATA_HOME != "$HOME/.local/share" ]]; then
|
||||||
|
xdgVars="$xdgVars xdg.dataHome = \"$XDG_DATA_HOME\";$nl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$confFile")"
|
||||||
|
cat > $confFile <<EOF
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Let Home Manager install and manage itself.
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
|
||||||
|
# Home Manager needs a bit of information about you and the
|
||||||
|
# paths it should manage.
|
||||||
|
home.username = "$USER";
|
||||||
|
home.homeDirectory = "$HOME";
|
||||||
|
$xdgVars
|
||||||
|
# This value determines the Home Manager release that your
|
||||||
|
# configuration is compatible with. This helps avoid breakage
|
||||||
|
# when a new Home Manager release introduces backwards
|
||||||
|
# incompatible changes.
|
||||||
|
#
|
||||||
|
# You can update Home Manager without changing this value. See
|
||||||
|
# the Home Manager release notes for a list of state version
|
||||||
|
# changes in each release.
|
||||||
|
home.stateVersion = "21.11";
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Creating initial Home Manager generation..."
|
||||||
|
echo
|
||||||
|
|
||||||
|
if home-manager switch; then
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
All done! The home-manager tool should now be installed and you
|
||||||
|
can edit
|
||||||
|
|
||||||
|
$confFile
|
||||||
|
|
||||||
|
to configure Home Manager. Run 'man home-configuration.nix' to
|
||||||
|
see all available options.
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
Uh oh, the installation failed! Please create an issue at
|
||||||
|
|
||||||
|
https://github.com/nix-community/home-manager/issues
|
||||||
|
|
||||||
|
if the error seems to be the fault of Home Manager.
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
} ''
|
||||||
|
echo This derivation is not buildable, instead run it using nix-shell.
|
||||||
|
exit 1
|
||||||
|
''
|
||||||
399
modules/accounts/email.nix
Normal file
399
modules/accounts/email.nix
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.accounts.email;
|
||||||
|
|
||||||
|
gpgModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
key = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The key to use as listed in <command>gpg --list-keys</command>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
signByDefault = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Sign messages by default.";
|
||||||
|
};
|
||||||
|
|
||||||
|
encryptByDefault = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Encrypt outgoing messages by default.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
signatureModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
text = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
example = ''
|
||||||
|
--
|
||||||
|
Luke Skywalker
|
||||||
|
May the force be with you.
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Signature content.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
showSignature = mkOption {
|
||||||
|
type = types.enum [ "append" "attach" "none" ];
|
||||||
|
default = "none";
|
||||||
|
description = "Method to communicate the signature.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tlsModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to enable TLS/SSL.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
useStartTls = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to use STARTTLS.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
certificatesFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = config.accounts.email.certificatesFile;
|
||||||
|
defaultText = "config.accounts.email.certificatesFile";
|
||||||
|
description = ''
|
||||||
|
Path to file containing certificate authorities that should
|
||||||
|
be used to validate the connection authenticity. If
|
||||||
|
<literal>null</literal> then the system default is used.
|
||||||
|
Note, if set then the system default may still be accepted.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
imapModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "imap.example.org";
|
||||||
|
description = ''
|
||||||
|
Hostname of IMAP server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.nullOr types.port;
|
||||||
|
default = null;
|
||||||
|
example = 993;
|
||||||
|
description = ''
|
||||||
|
The port on which the IMAP server listens. If
|
||||||
|
<literal>null</literal> then the default port is used.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tls = mkOption {
|
||||||
|
type = tlsModule;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Configuration for secure connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
smtpModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "smtp.example.org";
|
||||||
|
description = ''
|
||||||
|
Hostname of SMTP server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.nullOr types.port;
|
||||||
|
default = null;
|
||||||
|
example = 465;
|
||||||
|
description = ''
|
||||||
|
The port on which the SMTP server listens. If
|
||||||
|
<literal>null</literal> then the default port is used.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tls = mkOption {
|
||||||
|
type = tlsModule;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Configuration for secure connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
maildirModule = types.submodule ({ config, ... }: {
|
||||||
|
options = {
|
||||||
|
path = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Path to maildir directory where mail for this account is
|
||||||
|
stored. This is relative to the base maildir path.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
absPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
default = "${cfg.maildirBasePath}/${config.path}";
|
||||||
|
description = ''
|
||||||
|
A convenience option whose value is the absolute path of
|
||||||
|
this maildir.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
mailAccountOpts = { name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
readOnly = true;
|
||||||
|
description = ''
|
||||||
|
Unique identifier of the account. This is set to the
|
||||||
|
attribute name of the account configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
primary = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether this is the primary account. Only one account may be
|
||||||
|
set as primary.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
flavor = mkOption {
|
||||||
|
type = types.enum [ "plain" "gmail.com" "runbox.com" ];
|
||||||
|
default = "plain";
|
||||||
|
description = ''
|
||||||
|
Some email providers have peculiar behavior that require
|
||||||
|
special treatment. This option is therefore intended to
|
||||||
|
indicate the nature of the provider.
|
||||||
|
</para><para>
|
||||||
|
When this indicates a specific provider then, for example,
|
||||||
|
the IMAP and SMTP server configuration may be set
|
||||||
|
automatically.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
address = mkOption {
|
||||||
|
type = types.strMatching ".*@.*";
|
||||||
|
example = "jane.doe@example.org";
|
||||||
|
description = "The email address of this account.";
|
||||||
|
};
|
||||||
|
|
||||||
|
aliases = mkOption {
|
||||||
|
type = types.listOf (types.strMatching ".*@.*");
|
||||||
|
default = [ ];
|
||||||
|
example = [ "webmaster@example.org" "admin@example.org" ];
|
||||||
|
description = "Alternative email addresses of this account.";
|
||||||
|
};
|
||||||
|
|
||||||
|
realName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "Jane Doe";
|
||||||
|
description = "Name displayed when sending mails.";
|
||||||
|
};
|
||||||
|
|
||||||
|
userName = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The server username of this account. This will be used as
|
||||||
|
the SMTP and IMAP user name.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordCommand = mkOption {
|
||||||
|
type = types.nullOr (types.either types.str (types.listOf types.str));
|
||||||
|
default = null;
|
||||||
|
apply = p: if isString p then splitString " " p else p;
|
||||||
|
example = "secret-tool lookup email me@example.org";
|
||||||
|
description = ''
|
||||||
|
A command, which when run writes the account password on
|
||||||
|
standard output.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
folders = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = {
|
||||||
|
inbox = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Inbox";
|
||||||
|
description = ''
|
||||||
|
Relative path of the inbox mail.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sent = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = "Sent";
|
||||||
|
description = ''
|
||||||
|
Relative path of the sent mail folder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
drafts = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Drafts";
|
||||||
|
description = ''
|
||||||
|
Relative path of the drafts mail folder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
trash = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Trash";
|
||||||
|
description = ''
|
||||||
|
Relative path of the deleted mail folder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Standard email folders.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
imap = mkOption {
|
||||||
|
type = types.nullOr imapModule;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The IMAP configuration to use for this account.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
signature = mkOption {
|
||||||
|
type = signatureModule;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Signature configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
gpg = mkOption {
|
||||||
|
type = types.nullOr gpgModule;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
GPG configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
smtp = mkOption {
|
||||||
|
type = types.nullOr smtpModule;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The SMTP configuration to use for this account.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
maildir = mkOption {
|
||||||
|
type = types.nullOr maildirModule;
|
||||||
|
defaultText = { path = "\${name}"; };
|
||||||
|
description = ''
|
||||||
|
Maildir configuration for this account.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
{
|
||||||
|
name = name;
|
||||||
|
maildir = mkOptionDefault { path = "${name}"; };
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf (config.flavor == "gmail.com") {
|
||||||
|
userName = mkDefault config.address;
|
||||||
|
|
||||||
|
imap = {
|
||||||
|
host = "imap.gmail.com";
|
||||||
|
port = 993;
|
||||||
|
};
|
||||||
|
|
||||||
|
smtp = {
|
||||||
|
host = "smtp.gmail.com";
|
||||||
|
port = if config.smtp.tls.useStartTls then 587 else 465;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (config.flavor == "runbox.com") {
|
||||||
|
imap = { host = "mail.runbox.com"; };
|
||||||
|
|
||||||
|
smtp = { host = "mail.runbox.com"; };
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.accounts.email = {
|
||||||
|
certificatesFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/etc/ssl/certs/ca-certificates.crt";
|
||||||
|
description = ''
|
||||||
|
Path to default file containing certificate authorities that
|
||||||
|
should be used to validate the connection authenticity. This
|
||||||
|
path may be overridden on a per-account basis.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
maildirBasePath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "${config.home.homeDirectory}/Maildir";
|
||||||
|
defaultText = "$HOME/Maildir";
|
||||||
|
apply = p:
|
||||||
|
if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}";
|
||||||
|
description = ''
|
||||||
|
The base directory for account maildir directories. May be a
|
||||||
|
relative path, in which case it is relative the home
|
||||||
|
directory.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule mailAccountOpts);
|
||||||
|
default = { };
|
||||||
|
description = "List of email accounts.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.accounts != { }) {
|
||||||
|
assertions = [
|
||||||
|
(let
|
||||||
|
primaries =
|
||||||
|
catAttrs "name" (filter (a: a.primary) (attrValues cfg.accounts));
|
||||||
|
in {
|
||||||
|
assertion = length primaries == 1;
|
||||||
|
message = "Must have exactly one primary mail account but found "
|
||||||
|
+ toString (length primaries) + optionalString (length primaries > 1)
|
||||||
|
(", namely " + concatStringsSep ", " primaries);
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
46
modules/config/i18n.nix
Normal file
46
modules/config/i18n.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# The glibc package in Nixpkgs is patched to make it possible to specify
|
||||||
|
# an alternative path for the locale archive through a special environment
|
||||||
|
# variable. This would allow different versions of glibc to coexist on the
|
||||||
|
# same system because each version of glibc could look up different paths
|
||||||
|
# for its locale archive should the archive format ever change in
|
||||||
|
# incompatible ways.
|
||||||
|
#
|
||||||
|
# See also:
|
||||||
|
# - localedef(1)
|
||||||
|
# - https://nixos.org/manual/nixpkgs/stable/#locales
|
||||||
|
# - https://github.com/NixOS/nixpkgs/issues/38991
|
||||||
|
#
|
||||||
|
# Note, the name of the said environment variable gets updated with each
|
||||||
|
# breaking release of the glibcLocales package. Periodically check the link
|
||||||
|
# below for changes:
|
||||||
|
# https://github.com/NixOS/nixpkgs/blob/nixpkgs-unstable/pkgs/development/libraries/glibc/nix-locale-archive.patch
|
||||||
|
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
inherit (pkgs.glibcLocales) version;
|
||||||
|
|
||||||
|
archivePath = "${pkgs.glibcLocales}/lib/locale/locale-archive";
|
||||||
|
|
||||||
|
# lookup the version of glibcLocales and set the appropriate environment vars
|
||||||
|
localeVars = if versionAtLeast version "2.27" then {
|
||||||
|
LOCALE_ARCHIVE_2_27 = archivePath;
|
||||||
|
} else if versionAtLeast version "2.11" then {
|
||||||
|
LOCALE_ARCHIVE_2_11 = archivePath;
|
||||||
|
} else
|
||||||
|
{ };
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ midchildan ];
|
||||||
|
|
||||||
|
config = mkIf pkgs.hostPlatform.isLinux {
|
||||||
|
# For shell sessions.
|
||||||
|
home.sessionVariables = localeVars;
|
||||||
|
|
||||||
|
# For desktop apps.
|
||||||
|
systemd.user.sessionVariables = localeVars;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,46 +1,17 @@
|
|||||||
{ configuration
|
{ configuration
|
||||||
, pkgs
|
, pkgs
|
||||||
, lib ? pkgs.stdenv.lib
|
, lib ? pkgs.lib
|
||||||
|
|
||||||
|
# Whether to check that each option has a matching declaration.
|
||||||
|
, check ? true
|
||||||
|
# Extra arguments passed to specialArgs.
|
||||||
|
, extraSpecialArgs ? { }
|
||||||
}:
|
}:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
modules = [
|
|
||||||
./home-environment.nix
|
|
||||||
./manual.nix
|
|
||||||
./misc/gtk.nix
|
|
||||||
./misc/pam.nix
|
|
||||||
./programs/bash.nix
|
|
||||||
./programs/beets.nix
|
|
||||||
./programs/eclipse.nix
|
|
||||||
./programs/emacs.nix
|
|
||||||
./programs/firefox.nix
|
|
||||||
./programs/git.nix
|
|
||||||
./programs/gnome-terminal.nix
|
|
||||||
./programs/info.nix
|
|
||||||
./programs/lesspipe.nix
|
|
||||||
./programs/ssh.nix
|
|
||||||
./programs/texlive.nix
|
|
||||||
./services/dunst.nix
|
|
||||||
./services/gnome-keyring.nix
|
|
||||||
./services/gpg-agent.nix
|
|
||||||
./services/keepassx.nix
|
|
||||||
./services/network-manager-applet.nix
|
|
||||||
./services/random-background.nix
|
|
||||||
./services/redshift.nix
|
|
||||||
./services/taffybar.nix
|
|
||||||
./services/tahoe-lafs.nix
|
|
||||||
./services/udiskie.nix
|
|
||||||
./services/xscreensaver.nix
|
|
||||||
./systemd.nix
|
|
||||||
./xresources.nix
|
|
||||||
./xsession.nix
|
|
||||||
<nixpkgs/nixos/modules/misc/assertions.nix>
|
|
||||||
<nixpkgs/nixos/modules/misc/meta.nix>
|
|
||||||
];
|
|
||||||
|
|
||||||
collectFailed = cfg:
|
collectFailed = cfg:
|
||||||
map (x: x.message) (filter (x: !x.assertion) cfg.assertions);
|
map (x: x.message) (filter (x: !x.assertion) cfg.assertions);
|
||||||
|
|
||||||
@@ -50,23 +21,28 @@ let
|
|||||||
in
|
in
|
||||||
fold f res res.config.warnings;
|
fold f res res.config.warnings;
|
||||||
|
|
||||||
pkgsModule = {
|
extendedLib = import ./lib/stdlib-extended.nix pkgs.lib;
|
||||||
config._module.args.pkgs = lib.mkForce pkgs;
|
|
||||||
config._module.args.baseModules = modules;
|
hmModules =
|
||||||
|
import ./modules.nix {
|
||||||
|
inherit check pkgs;
|
||||||
|
lib = extendedLib;
|
||||||
|
};
|
||||||
|
|
||||||
|
rawModule = extendedLib.evalModules {
|
||||||
|
modules = [ configuration ] ++ hmModules;
|
||||||
|
specialArgs = {
|
||||||
|
modulesPath = builtins.toString ./.;
|
||||||
|
} // extraSpecialArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = showWarnings (
|
module = showWarnings (
|
||||||
let
|
let
|
||||||
mod = lib.evalModules {
|
failed = collectFailed rawModule.config;
|
||||||
modules = [ configuration ] ++ modules ++ [ pkgsModule ];
|
|
||||||
};
|
|
||||||
|
|
||||||
failed = collectFailed mod.config;
|
|
||||||
|
|
||||||
failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed);
|
failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed);
|
||||||
in
|
in
|
||||||
if failed == []
|
if failed == []
|
||||||
then mod
|
then rawModule
|
||||||
else throw "\nFailed assertions:\n${failedStr}"
|
else throw "\nFailed assertions:\n${failedStr}"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -75,6 +51,14 @@ in
|
|||||||
{
|
{
|
||||||
inherit (module) options config;
|
inherit (module) options config;
|
||||||
|
|
||||||
|
activationPackage = module.config.home.activationPackage;
|
||||||
|
|
||||||
|
# For backwards compatibility. Please use activationPackage instead.
|
||||||
activation-script = module.config.home.activationPackage;
|
activation-script = module.config.home.activationPackage;
|
||||||
home-path = module.config.home.path;
|
|
||||||
|
newsDisplay = rawModule.config.news.display;
|
||||||
|
newsEntries =
|
||||||
|
sort (a: b: a.time > b.time) (
|
||||||
|
filter (a: a.condition) rawModule.config.news.entries
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
402
modules/files.nix
Normal file
402
modules/files.nix
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.home.file;
|
||||||
|
|
||||||
|
homeDirectory = config.home.homeDirectory;
|
||||||
|
|
||||||
|
fileType = (import lib/file-type.nix {
|
||||||
|
inherit homeDirectory lib pkgs;
|
||||||
|
}).fileType;
|
||||||
|
|
||||||
|
sourceStorePath = file:
|
||||||
|
let
|
||||||
|
sourcePath = toString file.source;
|
||||||
|
sourceName = config.lib.strings.storeFileName (baseNameOf sourcePath);
|
||||||
|
in
|
||||||
|
if builtins.hasContext sourcePath
|
||||||
|
then file.source
|
||||||
|
else builtins.path { path = file.source; name = sourceName; };
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
home.file = mkOption {
|
||||||
|
description = "Attribute set of files to link into the user home.";
|
||||||
|
default = {};
|
||||||
|
type = fileType "<envar>HOME</envar>" homeDirectory;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-files = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
internal = true;
|
||||||
|
description = "Package to contain all home files";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
assertions = [(
|
||||||
|
let
|
||||||
|
dups =
|
||||||
|
attrNames
|
||||||
|
(filterAttrs (n: v: v > 1)
|
||||||
|
(foldAttrs (acc: v: acc + v) 0
|
||||||
|
(mapAttrsToList (n: v: { ${v.target} = 1; }) cfg)));
|
||||||
|
dupsStr = concatStringsSep ", " dups;
|
||||||
|
in {
|
||||||
|
assertion = dups == [];
|
||||||
|
message = ''
|
||||||
|
Conflicting managed target files: ${dupsStr}
|
||||||
|
|
||||||
|
This may happen, for example, if you have a configuration similar to
|
||||||
|
|
||||||
|
home.file = {
|
||||||
|
conflict1 = { source = ./foo.nix; target = "baz"; };
|
||||||
|
conflict2 = { source = ./bar.nix; target = "baz"; };
|
||||||
|
}'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
lib.file.mkOutOfStoreSymlink = path:
|
||||||
|
let
|
||||||
|
pathStr = toString path;
|
||||||
|
name = hm.strings.storeFileName (baseNameOf pathStr);
|
||||||
|
in
|
||||||
|
pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out'';
|
||||||
|
|
||||||
|
# This verifies that the links we are about to create will not
|
||||||
|
# overwrite an existing file.
|
||||||
|
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
|
||||||
|
let
|
||||||
|
# Paths that should be forcibly overwritten by Home Manager.
|
||||||
|
# Caveat emptor!
|
||||||
|
forcedPaths =
|
||||||
|
concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'')
|
||||||
|
(mapAttrsToList (n: v: v.target)
|
||||||
|
(filterAttrs (n: v: v.force) cfg));
|
||||||
|
|
||||||
|
check = pkgs.writeText "check" ''
|
||||||
|
. ${./lib-bash/color-echo.sh}
|
||||||
|
|
||||||
|
# A symbolic link whose target path matches this pattern will be
|
||||||
|
# considered part of a Home Manager generation.
|
||||||
|
homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*"
|
||||||
|
|
||||||
|
forcedPaths=(${forcedPaths})
|
||||||
|
|
||||||
|
newGenFiles="$1"
|
||||||
|
shift
|
||||||
|
for sourcePath in "$@" ; do
|
||||||
|
relativePath="''${sourcePath#$newGenFiles/}"
|
||||||
|
targetPath="$HOME/$relativePath"
|
||||||
|
|
||||||
|
forced=""
|
||||||
|
for forcedPath in "''${forcedPaths[@]}"; do
|
||||||
|
if [[ $targetPath == $forcedPath* ]]; then
|
||||||
|
forced="yeah"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n $forced ]]; then
|
||||||
|
$VERBOSE_ECHO "Skipping collision check for $targetPath"
|
||||||
|
elif [[ -e "$targetPath" \
|
||||||
|
&& ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||||
|
if [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||||
|
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||||
|
if [[ -e "$backup" ]]; then
|
||||||
|
errorEcho "Existing file '$backup' would be clobbered by backing up '$targetPath'"
|
||||||
|
collision=1
|
||||||
|
else
|
||||||
|
warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be moved to '$backup'"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
errorEcho "Existing file '$targetPath' is in the way of '$sourcePath'"
|
||||||
|
collision=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -v collision ]] ; then
|
||||||
|
errorEcho "Please move the above files and try again or use -b <ext> to move automatically."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
''
|
||||||
|
function checkNewGenCollision() {
|
||||||
|
local newGenFiles
|
||||||
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
|
find "$newGenFiles" \( -type f -or -type l \) \
|
||||||
|
-exec bash ${check} "$newGenFiles" {} +
|
||||||
|
}
|
||||||
|
|
||||||
|
checkNewGenCollision || exit 1
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
# This activation script will
|
||||||
|
#
|
||||||
|
# 1. Remove files from the old generation that are not in the new
|
||||||
|
# generation.
|
||||||
|
#
|
||||||
|
# 2. Switch over the Home Manager gcroot and current profile
|
||||||
|
# links.
|
||||||
|
#
|
||||||
|
# 3. Symlink files from the new generation into $HOME.
|
||||||
|
#
|
||||||
|
# This order is needed to ensure that we always know which links
|
||||||
|
# belong to which generation. Specifically, if we're moving from
|
||||||
|
# generation A to generation B having sets of home file links FA
|
||||||
|
# and FB, respectively then cleaning before linking produces state
|
||||||
|
# transitions similar to
|
||||||
|
#
|
||||||
|
# FA → FA ∩ FB → (FA ∩ FB) ∪ FB = FB
|
||||||
|
#
|
||||||
|
# and a failure during the intermediate state FA ∩ FB will not
|
||||||
|
# result in lost links because this set of links are in both the
|
||||||
|
# source and target generation.
|
||||||
|
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
|
||||||
|
let
|
||||||
|
link = pkgs.writeShellScript "link" ''
|
||||||
|
rootPath="$1"
|
||||||
|
newGenFiles="$2"
|
||||||
|
shift 2
|
||||||
|
for sourcePath in "$@" ; do
|
||||||
|
relativePath="''${sourcePath#$newGenFiles/}"
|
||||||
|
targetPath="$rootPath/$relativePath"
|
||||||
|
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||||
|
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||||
|
$DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
|
||||||
|
fi
|
||||||
|
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
|
||||||
|
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath"
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
cleanup = pkgs.writeShellScript "cleanup" ''
|
||||||
|
. ${./lib-bash/color-echo.sh}
|
||||||
|
|
||||||
|
# A symbolic link whose target path matches this pattern will be
|
||||||
|
# considered part of a Home Manager generation.
|
||||||
|
homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*"
|
||||||
|
|
||||||
|
rootPath="$1"
|
||||||
|
newGenFiles="$2"
|
||||||
|
shift 2
|
||||||
|
for relativePath in "$@" ; do
|
||||||
|
targetPath="$rootPath/$relativePath"
|
||||||
|
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
||||||
|
$VERBOSE_ECHO "Checking $targetPath: exists"
|
||||||
|
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||||
|
warnEcho "Path '$targetPath' does not link into a Home Manager generation. Skipping delete."
|
||||||
|
else
|
||||||
|
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
|
||||||
|
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath"
|
||||||
|
|
||||||
|
# Recursively delete empty parent directories.
|
||||||
|
targetDir="$(dirname "$relativePath")"
|
||||||
|
if [[ "$targetDir" != "." ]] ; then
|
||||||
|
# TODO
|
||||||
|
# pushd "$HOME" > /dev/null
|
||||||
|
|
||||||
|
# Call rmdir with a relative path excluding $HOME.
|
||||||
|
# Otherwise, it might try to delete $HOME and exit
|
||||||
|
# with a permission error.
|
||||||
|
$DRY_RUN_CMD rmdir $VERBOSE_ARG \
|
||||||
|
-p --ignore-fail-on-non-empty \
|
||||||
|
"$targetDir"
|
||||||
|
|
||||||
|
# popd > /dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
''
|
||||||
|
function linkNewGen() {
|
||||||
|
echo "Creating home file links"
|
||||||
|
|
||||||
|
local rootPath=
|
||||||
|
if [[ $newGenLayoutVersion -eq 0 ]] ; then
|
||||||
|
rootPath="$HOME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local newGenFiles
|
||||||
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
|
find "$newGenFiles" \( -type f -or -type l \) \
|
||||||
|
-exec bash ${link} "$rootPath" "$newGenFiles" {} +
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanOldGen() {
|
||||||
|
if [[ ! -v oldGenPath ]] ; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cleaning up orphan links"
|
||||||
|
|
||||||
|
local newGenFiles oldGenFiles
|
||||||
|
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||||
|
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
||||||
|
|
||||||
|
# When transitioning from layout 0 to 1 we need to prefix all old
|
||||||
|
# paths with the home directory. Conversely, if we ever go from
|
||||||
|
# layout 1 to 0 we need to "subtract" the home directory from the
|
||||||
|
# old generation path, this is done by appending an "antiprefix" to
|
||||||
|
# the layout 1 paths.
|
||||||
|
local prefix= antiprefix=
|
||||||
|
if [[ $oldGenLayoutVersion -eq 0 && $newGenLayoutVersion -ge 1 ]] ; then
|
||||||
|
prefix="''${HOME#/}/"
|
||||||
|
elif [[ $oldGenLayoutVersion -ge 1 && $newGenLayoutVersion -eq 0 ]] ; then
|
||||||
|
antiprefix="/$HOME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local rootPath=
|
||||||
|
if [[ $newGenLayoutVersion -eq 0 ]] ; then
|
||||||
|
rootPath="$HOME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$VERBOSE_ECHO "Orphan link cleanup uses prefix=$prefix antiprefix=$antiprefix rootPath=$rootPath"
|
||||||
|
|
||||||
|
# Apply the cleanup script on each leaf in the old generation. The
|
||||||
|
# find command below will print the relative path of the entry.
|
||||||
|
find "$oldGenFiles$antiprefix" '(' -type f -or -type l ')' -printf "$prefix%P\0" \
|
||||||
|
| xargs -0 bash ${cleanup} "$rootPath" "$newGenFiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanOldGen
|
||||||
|
|
||||||
|
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||||
|
echo "Creating profile generation $newGenNum"
|
||||||
|
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||||
|
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
|
||||||
|
else
|
||||||
|
echo "No change so reusing latest profile generation $oldGenNum"
|
||||||
|
fi
|
||||||
|
|
||||||
|
linkNewGen
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
|
||||||
|
let
|
||||||
|
homeDirArg = escapeShellArg homeDirectory;
|
||||||
|
in ''
|
||||||
|
function _cmp() {
|
||||||
|
if [[ -d $1 && -d $2 ]]; then
|
||||||
|
diff -rq "$1" "$2" &> /dev/null
|
||||||
|
else
|
||||||
|
cmp --quiet "$1" "$2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
declare -A changedFiles
|
||||||
|
'' + concatMapStrings (v:
|
||||||
|
let
|
||||||
|
sourceArg = escapeShellArg (sourceStorePath v);
|
||||||
|
targetArg = escapeShellArg v.target;
|
||||||
|
in ''
|
||||||
|
_cmp ${sourceArg} ${homeDirArg}/${targetArg} \
|
||||||
|
&& changedFiles[${targetArg}]=0 \
|
||||||
|
|| changedFiles[${targetArg}]=1
|
||||||
|
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||||
|
+ ''
|
||||||
|
unset -f _cmp
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
|
||||||
|
concatMapStrings (v: ''
|
||||||
|
if [[ ''${changedFiles[${escapeShellArg v.target}]} -eq 1 ]]; then
|
||||||
|
${v.onChange}
|
||||||
|
fi
|
||||||
|
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||||
|
);
|
||||||
|
|
||||||
|
# Symlink directories and files that have the right execute bit.
|
||||||
|
# Copy files that need their execute bit changed.
|
||||||
|
home-files = pkgs.runCommandLocal
|
||||||
|
"home-manager-files"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
||||||
|
}
|
||||||
|
(''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
# Needed in case /nix is a symbolic link.
|
||||||
|
realOut="$(realpath -m "$out")"
|
||||||
|
|
||||||
|
function insertFile() {
|
||||||
|
local source="$1"
|
||||||
|
local relTarget="$2"
|
||||||
|
local executable="$3"
|
||||||
|
local recursive="$4"
|
||||||
|
|
||||||
|
# If the target already exists then we have a collision. Note, this
|
||||||
|
# should not happen due to the assertion found in the 'files' module.
|
||||||
|
# We therefore simply log the conflict and otherwise ignore it, mainly
|
||||||
|
# to make the `files-target-config` test work as expected.
|
||||||
|
if [[ -e "$realOut/$relTarget" ]]; then
|
||||||
|
echo "File conflict for file '$relTarget'" >&2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Figure out the real absolute path to the target.
|
||||||
|
local target
|
||||||
|
target="$(realpath -m "$realOut/$relTarget")"
|
||||||
|
|
||||||
|
# Target path must be within $HOME.
|
||||||
|
if [[ ! $target == $realOut* ]] ; then
|
||||||
|
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$target")"
|
||||||
|
if [[ -d $source ]]; then
|
||||||
|
if [[ $recursive ]]; then
|
||||||
|
mkdir -p "$target"
|
||||||
|
lndir -silent "$source" "$target"
|
||||||
|
else
|
||||||
|
ln -s "$source" "$target"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
[[ -x $source ]] && isExecutable=1 || isExecutable=""
|
||||||
|
|
||||||
|
# Link the file into the home file directory if possible,
|
||||||
|
# i.e., if the executable bit of the source is the same we
|
||||||
|
# expect for the target. Otherwise, we copy the file and
|
||||||
|
# set the executable bit to the expected value.
|
||||||
|
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||||
|
ln -s "$source" "$target"
|
||||||
|
else
|
||||||
|
cp "$source" "$target"
|
||||||
|
|
||||||
|
if [[ $executable == inherit ]]; then
|
||||||
|
# Don't change file mode if it should match the source.
|
||||||
|
:
|
||||||
|
elif [[ $executable ]]; then
|
||||||
|
chmod +x "$target"
|
||||||
|
else
|
||||||
|
chmod -x "$target"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
'' + concatStrings (
|
||||||
|
mapAttrsToList (n: v: ''
|
||||||
|
insertFile ${
|
||||||
|
escapeShellArgs [
|
||||||
|
(sourceStorePath v)
|
||||||
|
v.target
|
||||||
|
(if v.executable == null
|
||||||
|
then "inherit"
|
||||||
|
else toString v.executable)
|
||||||
|
(toString v.recursive)
|
||||||
|
]}
|
||||||
|
'') cfg
|
||||||
|
));
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
with import ./lib/dag.nix;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@@ -17,11 +16,35 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
address = mkOption {
|
ctype = mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The language to use for addresses.
|
Character classification category.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
numeric = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for numerical values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
time = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for formatting times.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
collate = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for collation (alphabetical ordering).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,6 +56,14 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
messages = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for messages, application UI languages, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
paper = mkOption {
|
paper = mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
@@ -41,29 +72,62 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
time = mkOption {
|
name = mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The language to use for formatting times.
|
The language to use for personal names.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
address = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for addresses.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
telephone = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for telephone numbers.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
measurement = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
The language to use for measurement values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
keyboardSubModule = types.submodule {
|
keyboardSubModule = types.submodule {
|
||||||
options = {
|
options = {
|
||||||
layout = mkOption {
|
layout = mkOption {
|
||||||
type = types.str;
|
type = with types; nullOr str;
|
||||||
default = "us";
|
default =
|
||||||
|
if versionAtLeast config.home.stateVersion "19.09"
|
||||||
|
then null
|
||||||
|
else "us";
|
||||||
|
defaultText = literalExample "null";
|
||||||
description = ''
|
description = ''
|
||||||
Keyboard layout.
|
Keyboard layout. If <literal>null</literal>, then the system
|
||||||
|
configuration will be used.
|
||||||
|
</para><para>
|
||||||
|
This defaults to <literal>null</literal> for state
|
||||||
|
version ≥ 19.09 and <literal>"us"</literal> otherwise.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
model = mkOption {
|
model = mkOption {
|
||||||
type = types.str;
|
type = with types; nullOr str;
|
||||||
default = "pc104";
|
default = null;
|
||||||
example = "presario";
|
example = "presario";
|
||||||
description = ''
|
description = ''
|
||||||
Keyboard model.
|
Keyboard model.
|
||||||
@@ -80,11 +144,19 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
variant = mkOption {
|
variant = mkOption {
|
||||||
type = types.str;
|
type = with types; nullOr str;
|
||||||
default = "";
|
default =
|
||||||
|
if versionAtLeast config.home.stateVersion "19.09"
|
||||||
|
then null
|
||||||
|
else "";
|
||||||
|
defaultText = literalExample "null";
|
||||||
example = "colemak";
|
example = "colemak";
|
||||||
description = ''
|
description = ''
|
||||||
X keyboard variant.
|
X keyboard variant. If <literal>null</literal>, then the
|
||||||
|
system configuration will be used.
|
||||||
|
</para><para>
|
||||||
|
This defaults to <literal>null</literal> for state
|
||||||
|
version ≥ 19.09 and <literal>""</literal> otherwise.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -93,53 +165,51 @@ let
|
|||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "home" "sessionVariableSetter" ] ''
|
||||||
|
Session variables are now always set through the shell. This is
|
||||||
|
done automatically if the shell configuration is managed by Home
|
||||||
|
Manager. If not, then you must source the
|
||||||
|
|
||||||
|
~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||||
|
|
||||||
|
file yourself.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
home.file = mkOption {
|
home.username = mkOption {
|
||||||
description = "Attribute set of files to link into the user home.";
|
type = types.str;
|
||||||
default = {};
|
defaultText = literalExample ''
|
||||||
type = types.loaOf (types.submodule (
|
"$USER" for state version < 20.09,
|
||||||
{ name, config, ... }: {
|
undefined for state version ≥ 20.09
|
||||||
options = {
|
'';
|
||||||
target = mkOption {
|
example = "jane.doe";
|
||||||
type = types.str;
|
description = "The user's username.";
|
||||||
description = ''
|
};
|
||||||
Path to target file relative to <envar>HOME</envar>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
text = mkOption {
|
home.homeDirectory = mkOption {
|
||||||
default = null;
|
type = types.path;
|
||||||
type = types.nullOr types.lines;
|
defaultText = literalExample ''
|
||||||
description = "Text of the file.";
|
"$HOME" for state version < 20.09,
|
||||||
};
|
undefined for state version ≥ 20.09
|
||||||
|
'';
|
||||||
|
apply = toString;
|
||||||
|
example = "/home/jane.doe";
|
||||||
|
description = "The user's home directory. Must be an absolute path.";
|
||||||
|
};
|
||||||
|
|
||||||
source = mkOption {
|
home.profileDirectory = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
description = ''
|
defaultText = "~/.nix-profile";
|
||||||
Path of the source file. The file name must not start
|
internal = true;
|
||||||
with a period since Nix will not allow such names in
|
readOnly = true;
|
||||||
the Nix store.
|
description = ''
|
||||||
</para><para>
|
The profile directory where Home Manager generations are
|
||||||
This may refer to a directory.
|
installed.
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
|
|
||||||
mode = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "444";
|
|
||||||
description = "The permissions to apply to the file.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
target = mkDefault name;
|
|
||||||
source = mkIf (config.text != null) (
|
|
||||||
let name' = "user-etc-" + baseNameOf name;
|
|
||||||
in mkDefault (pkgs.writeText name' config.text)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
home.language = mkOption {
|
home.language = mkOption {
|
||||||
@@ -149,9 +219,12 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
home.keyboard = mkOption {
|
home.keyboard = mkOption {
|
||||||
type = keyboardSubModule;
|
type = types.nullOr keyboardSubModule;
|
||||||
default = {};
|
default = {};
|
||||||
description = "Keyboard configuration.";
|
description = ''
|
||||||
|
Keyboard configuration. Set to <literal>null</literal> to
|
||||||
|
disable Home Manager keyboard management.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
home.sessionVariables = mkOption {
|
home.sessionVariables = mkOption {
|
||||||
@@ -160,22 +233,55 @@ in
|
|||||||
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
||||||
description = ''
|
description = ''
|
||||||
Environment variables to always set at login.
|
Environment variables to always set at login.
|
||||||
|
</para><para>
|
||||||
|
The values may refer to other environment variables using
|
||||||
|
POSIX.2 style variable references. For example, a variable
|
||||||
|
<varname>parameter</varname> may be referenced as
|
||||||
|
<code>$parameter</code> or <code>''${parameter}</code>. A
|
||||||
|
default value <literal>foo</literal> may be given as per
|
||||||
|
<code>''${parameter:-foo}</code> and, similarly, an alternate
|
||||||
|
value <literal>bar</literal> can be given as per
|
||||||
|
<code>''${parameter:+bar}</code>.
|
||||||
|
</para><para>
|
||||||
|
Note, these variables may be set in any order so no session
|
||||||
|
variable may have a runtime dependency on another session
|
||||||
|
variable. In particular code like
|
||||||
|
<programlisting language="nix">
|
||||||
|
home.sessionVariables = {
|
||||||
|
FOO = "Hello";
|
||||||
|
BAR = "$FOO World!";
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
may not work as expected. If you need to reference another
|
||||||
|
session variable, then do so inside Nix instead. The above
|
||||||
|
example then becomes
|
||||||
|
<programlisting language="nix">
|
||||||
|
home.sessionVariables = {
|
||||||
|
FOO = "Hello";
|
||||||
|
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
home.sessionVariableSetter = mkOption {
|
home.sessionPath = mkOption {
|
||||||
default = "bash";
|
type = with types; listOf str;
|
||||||
type = types.enum [ "pam" "bash" ];
|
default = [ ];
|
||||||
example = "pam";
|
example = [
|
||||||
|
".git/safe/../../bin"
|
||||||
|
"\${xdg.configHome}/emacs/bin"
|
||||||
|
"~/.local/bin"
|
||||||
|
];
|
||||||
|
description = "Extra directories to add to <envar>PATH</envar>.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.sessionVariablesExtra = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
internal = true;
|
||||||
description = ''
|
description = ''
|
||||||
Identifies the module that should set the session variables.
|
Extra configuration to add to the
|
||||||
</para><para>
|
<filename>hm-session-vars.sh</filename> file.
|
||||||
If "bash" is set then <varname>config.bash.enable</varname>
|
|
||||||
must also be enabled.
|
|
||||||
</para><para>
|
|
||||||
If "pam" is set then PAM must be used to set the system
|
|
||||||
environment. Also mind that typical environment variables
|
|
||||||
might not be set by the time PAM starts up.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -185,23 +291,79 @@ in
|
|||||||
description = "The set of packages to appear in the user environment.";
|
description = "The set of packages to appear in the user environment.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
home.extraOutputsToInstall = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "doc" "info" "devdoc" ];
|
||||||
|
description = ''
|
||||||
|
List of additional package outputs of the packages
|
||||||
|
<varname>home.packages</varname> that should be installed into
|
||||||
|
the user environment.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
home.path = mkOption {
|
home.path = mkOption {
|
||||||
internal = true;
|
internal = true;
|
||||||
description = "The derivation installing the user packages.";
|
description = "The derivation installing the user packages.";
|
||||||
};
|
};
|
||||||
|
|
||||||
home.activation = mkOption {
|
home.emptyActivationPath = mkOption {
|
||||||
internal = true;
|
internal = true;
|
||||||
default = {};
|
default = false;
|
||||||
type = types.attrs;
|
type = types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Activation scripts for the home environment.
|
Whether the activation script should start with an empty
|
||||||
|
<envar>PATH</envar> variable. When <literal>false</literal>
|
||||||
|
then the user's <envar>PATH</envar> will be used.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.activation = mkOption {
|
||||||
|
type = hm.types.dagOf types.str;
|
||||||
|
default = {};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||||
|
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
|
||||||
|
''${builtins.toPath ./link-me-directly} $HOME
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
The activation scripts blocks to run when activating a Home
|
||||||
|
Manager generation. Any entry here should be idempotent,
|
||||||
|
meaning running twice or more times produces the same result
|
||||||
|
as running it once.
|
||||||
|
|
||||||
</para><para>
|
</para><para>
|
||||||
Any script should respect the <varname>DRY_RUN</varname>
|
|
||||||
variable, if it is set then no actual action should be taken.
|
If the script block produces any observable side effect, such
|
||||||
|
as writing or deleting files, then it
|
||||||
|
<emphasis>must</emphasis> be placed after the special
|
||||||
|
<literal>writeBoundary</literal> script block. Prior to the
|
||||||
|
write boundary one can place script blocks that verifies, but
|
||||||
|
does not modify, the state of the system and exits if an
|
||||||
|
unexpected state is found. For example, the
|
||||||
|
<literal>checkLinkTargets</literal> script block checks for
|
||||||
|
collisions between non-managed files and files defined in
|
||||||
|
<varname><link linkend="opt-home.file">home.file</link></varname>.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
A script block should respect the <varname>DRY_RUN</varname>
|
||||||
|
variable, if it is set then the actions taken by the script
|
||||||
|
should be logged to standard out and not actually performed.
|
||||||
The variable <varname>DRY_RUN_CMD</varname> is set to
|
The variable <varname>DRY_RUN_CMD</varname> is set to
|
||||||
<code>echo</code> if dry run is enabled. Thus, many cases you
|
<command>echo</command> if dry run is enabled.
|
||||||
can use the idiom <code>$DRY_RUN_CMD rm -rf /</code>.
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
A script block should also respect the
|
||||||
|
<varname>VERBOSE</varname> variable, and if set print
|
||||||
|
information on standard out that may be useful for debugging
|
||||||
|
any issue that may arise. The variable
|
||||||
|
<varname>VERBOSE_ARG</varname> is set to
|
||||||
|
<option>--verbose</option> if verbose output is enabled.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -210,164 +372,205 @@ in
|
|||||||
type = types.package;
|
type = types.package;
|
||||||
description = "The package containing the complete activation script.";
|
description = "The package containing the complete activation script.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
home.extraActivationPath = mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [ ];
|
||||||
|
description = ''
|
||||||
|
Extra packages to add to <envar>PATH</envar> within the activation
|
||||||
|
script.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.extraBuilderCommands = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Extra commands to run in the Home Manager generation builder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.extraProfileCommands = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Extra commands to run in the Home Manager profile builder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.enableNixpkgsReleaseCheck = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Determines whether to check for release version mismatch between Home
|
||||||
|
Manager and Nixpkgs. Using mismatched versions is likely to cause errors
|
||||||
|
and unexpected behavior. It is therefore highly recommended to use a
|
||||||
|
release of Home Manager than corresponds with your chosen release of
|
||||||
|
Nixpkgs.
|
||||||
|
</para><para>
|
||||||
|
When this option is enabled and a mismatch is detected then a warning
|
||||||
|
will be printed when the user configuration is being built.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
assertions = [
|
assertions = [
|
||||||
(let
|
{
|
||||||
badFiles =
|
assertion = config.home.username != "";
|
||||||
filter (f: hasPrefix "." (baseNameOf f))
|
message = "Username could not be determined";
|
||||||
(map (v: toString v.source)
|
}
|
||||||
(attrValues cfg.file));
|
{
|
||||||
badFilesStr = toString badFiles;
|
assertion = config.home.homeDirectory != "";
|
||||||
in
|
message = "Home directory could not be determined";
|
||||||
{
|
}
|
||||||
assertion = badFiles == [];
|
|
||||||
message = "Source file names must not start with '.': ${badFilesStr}";
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
warnings =
|
||||||
|
let
|
||||||
|
hmRelease = fileContents ../.release;
|
||||||
|
nixpkgsRelease = pkgs.lib.trivial.release;
|
||||||
|
releaseMismatch =
|
||||||
|
config.home.enableNixpkgsReleaseCheck
|
||||||
|
&& hmRelease != nixpkgsRelease;
|
||||||
|
in
|
||||||
|
optional releaseMismatch ''
|
||||||
|
You are using
|
||||||
|
|
||||||
|
Home Manager version ${hmRelease} and
|
||||||
|
Nixpkgs version ${nixpkgsRelease}.
|
||||||
|
|
||||||
|
Using mismatched versions is likely to cause errors and unexpected
|
||||||
|
behavior. It is therefore highly recommended to use a release of Home
|
||||||
|
Manager than corresponds with your chosen release of Nixpkgs.
|
||||||
|
|
||||||
|
If you insist then you can disable this warning by adding
|
||||||
|
|
||||||
|
home.enableNixpkgsReleaseCheck = false;
|
||||||
|
|
||||||
|
to your configuration.
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.username =
|
||||||
|
mkIf (versionOlder config.home.stateVersion "20.09")
|
||||||
|
(mkDefault (builtins.getEnv "USER"));
|
||||||
|
home.homeDirectory =
|
||||||
|
mkIf (versionOlder config.home.stateVersion "20.09")
|
||||||
|
(mkDefault (builtins.getEnv "HOME"));
|
||||||
|
|
||||||
|
home.profileDirectory =
|
||||||
|
if config.submoduleSupport.enable
|
||||||
|
&& config.submoduleSupport.externalPackageInstall
|
||||||
|
then "/etc/profiles/per-user/${cfg.username}"
|
||||||
|
else cfg.homeDirectory + "/.nix-profile";
|
||||||
|
|
||||||
home.sessionVariables =
|
home.sessionVariables =
|
||||||
let
|
let
|
||||||
maybeSet = name: value:
|
maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
||||||
listToAttrs (optional (value != null) { inherit name value; });
|
|
||||||
in
|
in
|
||||||
(maybeSet "LANG" cfg.language.base)
|
(maybeSet "LANG" cfg.language.base)
|
||||||
//
|
//
|
||||||
(maybeSet "LC_ADDRESS" cfg.language.address)
|
(maybeSet "LC_CTYPE" cfg.language.ctype)
|
||||||
|
//
|
||||||
|
(maybeSet "LC_NUMERIC" cfg.language.numeric)
|
||||||
|
//
|
||||||
|
(maybeSet "LC_TIME" cfg.language.time)
|
||||||
|
//
|
||||||
|
(maybeSet "LC_COLLATE" cfg.language.collate)
|
||||||
//
|
//
|
||||||
(maybeSet "LC_MONETARY" cfg.language.monetary)
|
(maybeSet "LC_MONETARY" cfg.language.monetary)
|
||||||
//
|
//
|
||||||
|
(maybeSet "LC_MESSAGES" cfg.language.messages)
|
||||||
|
//
|
||||||
(maybeSet "LC_PAPER" cfg.language.paper)
|
(maybeSet "LC_PAPER" cfg.language.paper)
|
||||||
//
|
//
|
||||||
(maybeSet "LC_TIME" cfg.language.time);
|
(maybeSet "LC_NAME" cfg.language.name)
|
||||||
|
//
|
||||||
|
(maybeSet "LC_ADDRESS" cfg.language.address)
|
||||||
|
//
|
||||||
|
(maybeSet "LC_TELEPHONE" cfg.language.telephone)
|
||||||
|
//
|
||||||
|
(maybeSet "LC_MEASUREMENT" cfg.language.measurement);
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
# Provide a file holding all session variables.
|
||||||
|
(
|
||||||
|
pkgs.writeTextFile {
|
||||||
|
name = "hm-session-vars.sh";
|
||||||
|
destination = "/etc/profile.d/hm-session-vars.sh";
|
||||||
|
text = ''
|
||||||
|
# Only source this once.
|
||||||
|
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi
|
||||||
|
export __HM_SESS_VARS_SOURCED=1
|
||||||
|
|
||||||
|
${config.lib.shell.exportAll cfg.sessionVariables}
|
||||||
|
'' + lib.optionalString (cfg.sessionPath != [ ]) ''
|
||||||
|
export PATH="$PATH''${PATH:+:}${concatStringsSep ":" cfg.sessionPath}"
|
||||||
|
'' + cfg.sessionVariablesExtra;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
# A dummy entry acting as a boundary between the activation
|
# A dummy entry acting as a boundary between the activation
|
||||||
# script's "check" and the "write" phases.
|
# script's "check" and the "write" phases.
|
||||||
home.activation.writeBoundary = dagEntryAnywhere "";
|
home.activation.writeBoundary = hm.dag.entryAnywhere "";
|
||||||
|
|
||||||
# This verifies that the links we are about to create will not
|
# Install packages to the user environment.
|
||||||
# overwrite an existing file.
|
#
|
||||||
home.activation.checkLinkTargets = dagEntryBefore ["writeBoundary"] (
|
# Note, sometimes our target may not allow modification of the Nix
|
||||||
let
|
# store and then we cannot rely on `nix-env -i`. This is the case,
|
||||||
pattern = "-home-manager-files/";
|
# for example, if we are running as a NixOS module and building a
|
||||||
check = pkgs.writeText "check" ''
|
# virtual machine. Then we must instead rely on an external
|
||||||
. ${./lib-bash/color-echo.sh}
|
# mechanism for installing packages, which in NixOS is provided by
|
||||||
|
# the `users.users.<name?>.packages` option. The activation
|
||||||
|
# command is still needed since some modules need to run their
|
||||||
|
# activation commands after the packages are guaranteed to be
|
||||||
|
# installed.
|
||||||
|
#
|
||||||
|
# In case the user has moved from a user-install of Home Manager
|
||||||
|
# to a submodule managed one we attempt to uninstall the
|
||||||
|
# `home-manager-path` package if it is installed.
|
||||||
|
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
|
||||||
|
if config.submoduleSupport.externalPackageInstall
|
||||||
|
then
|
||||||
|
''
|
||||||
|
if nix-env -q | grep '^home-manager-path$'; then
|
||||||
|
$DRY_RUN_CMD nix-env -e home-manager-path
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
else
|
||||||
|
''
|
||||||
|
if ! $DRY_RUN_CMD nix-env -i ${cfg.path} ; then
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
newGenFiles="$1"
|
Oops, nix-env failed to install your new Home Manager profile!
|
||||||
shift
|
|
||||||
for sourcePath in "$@" ; do
|
|
||||||
relativePath="''${sourcePath#$newGenFiles/}"
|
|
||||||
targetPath="$HOME/$relativePath"
|
|
||||||
if [[ -e "$targetPath" \
|
|
||||||
&& ! "$(readlink -e "$targetPath")" =~ "${pattern}" ]] ; then
|
|
||||||
errorEcho "Existing file '$targetPath' is in the way"
|
|
||||||
collision=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -v collision ]] ; then
|
Perhaps there is a conflict with a package that was installed using
|
||||||
errorEcho "Please move the above files and try again"
|
'nix-env -i'? Try running
|
||||||
|
|
||||||
|
nix-env -q
|
||||||
|
|
||||||
|
and if there is a conflicting package you can remove it with
|
||||||
|
|
||||||
|
nix-env -e {package name}
|
||||||
|
|
||||||
|
Then try activating your Home Manager configuration again.
|
||||||
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
'';
|
|
||||||
in
|
|
||||||
''
|
|
||||||
function checkNewGenCollision() {
|
|
||||||
local newGenFiles
|
|
||||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
|
||||||
find "$newGenFiles" -type f -print0 -or -type l -print0 \
|
|
||||||
| xargs -0 bash ${check} "$newGenFiles"
|
|
||||||
}
|
|
||||||
|
|
||||||
checkNewGenCollision || exit 1
|
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
home.activation.linkGeneration = dagEntryAfter ["writeBoundary"] (
|
|
||||||
let
|
|
||||||
pattern = "-home-manager-files/";
|
|
||||||
|
|
||||||
link = pkgs.writeText "link" ''
|
|
||||||
newGenFiles="$1"
|
|
||||||
shift
|
|
||||||
for sourcePath in "$@" ; do
|
|
||||||
relativePath="''${sourcePath#$newGenFiles/}"
|
|
||||||
targetPath="$HOME/$relativePath"
|
|
||||||
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
|
|
||||||
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath"
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
|
|
||||||
cleanup = pkgs.writeText "cleanup" ''
|
|
||||||
. ${./lib-bash/color-echo.sh}
|
|
||||||
|
|
||||||
newGenFiles="$1"
|
|
||||||
oldGenFiles="$2"
|
|
||||||
shift 2
|
|
||||||
for sourcePath in "$@" ; do
|
|
||||||
relativePath="''${sourcePath#$oldGenFiles/}"
|
|
||||||
targetPath="$HOME/$relativePath"
|
|
||||||
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
|
||||||
$VERBOSE_ECHO "Checking $targetPath exists"
|
|
||||||
elif [[ ! "$(readlink -e "$targetPath")" =~ "${pattern}" ]] ; then
|
|
||||||
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
|
|
||||||
else
|
|
||||||
echo "Checking $targetPath gone (deleting)"
|
|
||||||
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath"
|
|
||||||
$DRY_RUN_CMD rmdir --ignore-fail-on-non-empty \
|
|
||||||
$VERBOSE_ARG -p "$(dirname "$targetPath")"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
''
|
|
||||||
function linkNewGen() {
|
|
||||||
local newGenFiles
|
|
||||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
|
||||||
find "$newGenFiles" -type f -print0 -or -type l -print0 \
|
|
||||||
| xargs -0 bash ${link} "$newGenFiles"
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanOldGen() {
|
|
||||||
if [[ ! -v oldGenPath ]] ; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Cleaning up orphan links from $HOME"
|
|
||||||
|
|
||||||
local newGenFiles oldGenFiles
|
|
||||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
|
||||||
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
|
||||||
find "$oldGenFiles" -type f -print0 -or -type l -print0 \
|
|
||||||
| xargs -0 bash ${cleanup} "$newGenFiles" "$oldGenFiles"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
|
||||||
echo "Creating profile generation $newGenNum"
|
|
||||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath"
|
|
||||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenProfilePath" "$genProfilePath"
|
|
||||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
|
|
||||||
else
|
|
||||||
echo "No change so reusing latest profile generation $oldGenNum"
|
|
||||||
fi
|
|
||||||
|
|
||||||
linkNewGen
|
|
||||||
cleanOldGen
|
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
home.activation.installPackages = dagEntryAfter ["writeBoundary"] ''
|
|
||||||
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
|
||||||
'';
|
|
||||||
|
|
||||||
home.activationPackage =
|
home.activationPackage =
|
||||||
let
|
let
|
||||||
mkCmd = res: ''
|
mkCmd = res: ''
|
||||||
noteEcho Activating ${res.name}
|
noteEcho Activating ${res.name}
|
||||||
${res.data}
|
${res.data}
|
||||||
'';
|
'';
|
||||||
sortedCommands = dagTopoSort cfg.activation;
|
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||||
activationCmds =
|
activationCmds =
|
||||||
if sortedCommands ? result then
|
if sortedCommands ? result then
|
||||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||||
@@ -375,16 +578,28 @@ in
|
|||||||
abort ("Dependency cycle in activation script: "
|
abort ("Dependency cycle in activation script: "
|
||||||
+ builtins.toJSON sortedCommands);
|
+ builtins.toJSON sortedCommands);
|
||||||
|
|
||||||
sf = pkgs.writeText "activation-script" ''
|
# Programs that always should be available on the activation
|
||||||
#!${pkgs.stdenv.shell}
|
# script's PATH.
|
||||||
|
activationBinPaths = lib.makeBinPath (
|
||||||
|
[
|
||||||
|
pkgs.bash
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.diffutils # For `cmp` and `diff`.
|
||||||
|
pkgs.findutils
|
||||||
|
pkgs.gnugrep
|
||||||
|
pkgs.gnused
|
||||||
|
pkgs.ncurses # For `tput`.
|
||||||
|
] ++ config.home.extraActivationPath
|
||||||
|
)
|
||||||
|
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||||
|
|
||||||
|
activationScript = pkgs.writeShellScript "activation-script" ''
|
||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# This code explicitly requires GNU Core Utilities and Bash.
|
cd $HOME
|
||||||
# We therefore need to ensure they are prioritized over any
|
|
||||||
# other similarly named tools on the system.
|
export PATH="${activationBinPaths}"
|
||||||
export PATH="${pkgs.coreutils}/bin:${pkgs.bash}/bin:$PATH"
|
|
||||||
|
|
||||||
. ${./lib-bash/color-echo.sh}
|
. ${./lib-bash/color-echo.sh}
|
||||||
|
|
||||||
@@ -392,47 +607,44 @@ in
|
|||||||
|
|
||||||
${activationCmds}
|
${activationCmds}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
home-files = pkgs.stdenv.mkDerivation {
|
|
||||||
name = "home-manager-files";
|
|
||||||
|
|
||||||
phases = [ "installPhase" ];
|
|
||||||
|
|
||||||
installPhase =
|
|
||||||
"mkdir -p $out\n" +
|
|
||||||
concatStringsSep "\n" (
|
|
||||||
mapAttrsToList (n: v:
|
|
||||||
''
|
|
||||||
if [ -d "${v.source}" ]; then
|
|
||||||
mkdir -pv "$(dirname "$out/${v.target}")"
|
|
||||||
ln -sv "${v.source}" "$out/${v.target}"
|
|
||||||
else
|
|
||||||
install -D -m${v.mode} "${v.source}" "$out/${v.target}"
|
|
||||||
fi
|
|
||||||
''
|
|
||||||
) cfg.file
|
|
||||||
);
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
pkgs.stdenv.mkDerivation {
|
pkgs.runCommand
|
||||||
name = "home-manager-generation";
|
"home-manager-generation"
|
||||||
|
{
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
}
|
||||||
|
''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
phases = [ "installPhase" ];
|
cp ${activationScript} $out/activate
|
||||||
|
|
||||||
installPhase = ''
|
mkdir $out/bin
|
||||||
install -D -m755 ${sf} $out/activate
|
ln -s $out/activate $out/bin/home-manager-generation
|
||||||
|
|
||||||
|
# The generation directory layout version.
|
||||||
|
#
|
||||||
|
# - Version 0 (also implied when file is missing) means
|
||||||
|
# "legacy layout".
|
||||||
|
# - Version 1 adds full home file paths.
|
||||||
|
echo 0 > $out/version
|
||||||
|
|
||||||
substituteInPlace $out/activate \
|
substituteInPlace $out/activate \
|
||||||
--subst-var-by GENERATION_DIR $out
|
--subst-var-by GENERATION_DIR $out
|
||||||
|
|
||||||
ln -s ${home-files} $out/home-files
|
ln -s ${config.home-files} $out/home-files
|
||||||
|
ln -s ${cfg.path} $out/home-path
|
||||||
|
|
||||||
|
${cfg.extraBuilderCommands}
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
|
|
||||||
home.path = pkgs.buildEnv {
|
home.path = pkgs.buildEnv {
|
||||||
name = "home-manager-path";
|
name = "home-manager-path";
|
||||||
|
|
||||||
paths = cfg.packages;
|
paths = cfg.packages;
|
||||||
|
inherit (cfg) extraOutputsToInstall;
|
||||||
|
|
||||||
|
postBuild = cfg.extraProfileCommands;
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "Environment of packages installed through home-manager";
|
description = "Environment of packages installed through home-manager";
|
||||||
|
|||||||
106
modules/i18n/input-method/default.nix
Normal file
106
modules/i18n/input-method/default.nix
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.i18n.inputMethod;
|
||||||
|
|
||||||
|
gtk2Cache = pkgs.runCommandLocal "gtk2-immodule.cache" {
|
||||||
|
buildInputs = [ pkgs.gtk2 cfg.package ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/etc/gtk-2.0/
|
||||||
|
GTK_PATH=${cfg.package}/lib/gtk-2.0/ \
|
||||||
|
gtk-query-immodules-2.0 > $out/etc/gtk-2.0/immodules.cache
|
||||||
|
'';
|
||||||
|
|
||||||
|
gtk3Cache = pkgs.runCommandLocal "gtk3-immodule.cache" {
|
||||||
|
buildInputs = [ pkgs.gtk3 cfg.package ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/etc/gtk-3.0/
|
||||||
|
GTK_PATH=${cfg.package}/lib/gtk-3.0/ \
|
||||||
|
gtk-query-immodules-3.0 > $out/etc/gtk-3.0/immodules.cache
|
||||||
|
'';
|
||||||
|
|
||||||
|
in {
|
||||||
|
imports =
|
||||||
|
[ ./fcitx.nix ./fcitx5.nix ./hime.nix ./kime.nix ./nabi.nix ./uim.nix ];
|
||||||
|
|
||||||
|
options.i18n = {
|
||||||
|
inputMethod = {
|
||||||
|
enabled = mkOption {
|
||||||
|
type = types.nullOr
|
||||||
|
(types.enum [ "fcitx" "fcitx5" "nabi" "uim" "hime" "kime" ]);
|
||||||
|
default = null;
|
||||||
|
example = "fcitx";
|
||||||
|
description = ''
|
||||||
|
Select the enabled input method. Input methods is a software to input
|
||||||
|
symbols that are not available on standard input devices.
|
||||||
|
</para><para>
|
||||||
|
Input methods are specially used to input Chinese, Japanese and Korean
|
||||||
|
characters.
|
||||||
|
</para><para>
|
||||||
|
Currently the following input methods are available in Home Manager:
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>fcitx</literal></term>
|
||||||
|
<listitem><para>
|
||||||
|
A customizable lightweight input method
|
||||||
|
extra input engines can be added using
|
||||||
|
<literal>i18n.inputMethod.fcitx.engines</literal>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>fcitx5</literal></term>
|
||||||
|
<listitem><para>
|
||||||
|
The next generation of fcitx,
|
||||||
|
addons (including engines, dictionaries, skins) can be added using
|
||||||
|
<literal>i18n.inputMethod.fcitx5.addons</literal>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>nabi</literal></term>
|
||||||
|
<listitem><para>
|
||||||
|
A Korean input method based on XIM. Nabi doesn't support Qt 5.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>uim</literal></term>
|
||||||
|
<listitem><para>
|
||||||
|
The universal input method, is a library with a XIM bridge.
|
||||||
|
uim mainly support Chinese, Japanese and Korean.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>hime</literal></term>
|
||||||
|
<listitem><para>An extremely easy-to-use input method framework.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>kime</literal></term>
|
||||||
|
<listitem><para>A Korean IME.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The input method method package.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.enabled != null) {
|
||||||
|
assertions = [
|
||||||
|
(hm.assertions.assertPlatform "i18n.inputMethod" pkgs platforms.linux)
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages = [ cfg.package gtk2Cache gtk3Cache ];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib; [ hm.maintainers.kranzes ];
|
||||||
|
}
|
||||||
50
modules/i18n/input-method/fcitx.nix
Normal file
50
modules/i18n/input-method/fcitx.nix
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.i18n.inputMethod.fcitx;
|
||||||
|
fcitxPackage = pkgs.fcitx.override { plugins = cfg.engines; };
|
||||||
|
fcitxEngine = types.package // {
|
||||||
|
name = "fcitx-engine";
|
||||||
|
check = x:
|
||||||
|
types.package.check x && attrByPath [ "meta" "isFcitxEngine" ] false x;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
i18n.inputMethod.fcitx = {
|
||||||
|
engines = mkOption {
|
||||||
|
type = with types; listOf fcitxEngine;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample "with pkgs.fcitx-engines; [ mozc hangul ]";
|
||||||
|
description = let
|
||||||
|
enginesDrv = filterAttrs (const isDerivation) pkgs.fcitx-engines;
|
||||||
|
engines = concatStringsSep ", "
|
||||||
|
(map (name: "<literal>${name}</literal>") (attrNames enginesDrv));
|
||||||
|
in "Enabled Fcitx engines. Available engines are: ${engines}.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (config.i18n.inputMethod.enabled == "fcitx") {
|
||||||
|
i18n.inputMethod.package = fcitxPackage;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
GTK_IM_MODULE = "fcitx";
|
||||||
|
QT_IM_MODULE = "fcitx";
|
||||||
|
XMODIFIERS = "@im=fcitx";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.fcitx-daemon = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Fcitx input method editor";
|
||||||
|
PartOf = [ "graphical-session.desktop" ];
|
||||||
|
};
|
||||||
|
Service.ExecStart = "${fcitxPackage}/bin/fcitx";
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
42
modules/i18n/input-method/fcitx5.nix
Normal file
42
modules/i18n/input-method/fcitx5.nix
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
im = config.i18n.inputMethod;
|
||||||
|
cfg = im.fcitx5;
|
||||||
|
fcitx5Package = pkgs.fcitx5-with-addons.override { inherit (cfg) addons; };
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
i18n.inputMethod.fcitx5 = {
|
||||||
|
addons = mkOption {
|
||||||
|
type = with types; listOf package;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample "with pkgs; [ fcitx5-rime ]";
|
||||||
|
description = ''
|
||||||
|
Enabled Fcitx5 addons.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (im.enabled == "fcitx5") {
|
||||||
|
i18n.inputMethod.package = fcitx5Package;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
GTK_IM_MODULE = "fcitx";
|
||||||
|
QT_IM_MODULE = "fcitx";
|
||||||
|
XMODIFIERS = "@im=fcitx";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.fcitx5-daemon = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Fcitx5 input method editor";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service.ExecStart = "${fcitx5Package}/bin/fcitx5";
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
23
modules/i18n/input-method/hime.nix
Normal file
23
modules/i18n/input-method/hime.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib; {
|
||||||
|
config = mkIf (config.i18n.inputMethod.enabled == "hime") {
|
||||||
|
i18n.inputMethod.package = pkgs.hime;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
GTK_IM_MODULE = "hime";
|
||||||
|
QT_IM_MODULE = "hime";
|
||||||
|
XMODIFIERS = "@im=hime";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.hime-daemon = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Hime input method editor";
|
||||||
|
PartOf = [ "graphical-session.desktop" ];
|
||||||
|
};
|
||||||
|
Service.ExecStart = "${pkgs.hime}/bin/hime";
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
58
modules/i18n/input-method/kime.nix
Normal file
58
modules/i18n/input-method/kime.nix
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{ config, pkgs, lib, generators, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.i18n.inputMethod.kime;
|
||||||
|
yamlFormat = pkgs.formats.yaml { };
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
i18n.inputMethod.kime = {
|
||||||
|
config = mkOption {
|
||||||
|
type = yamlFormat.type;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
daemon = {
|
||||||
|
modules = ["Xim" "Indicator"];
|
||||||
|
};
|
||||||
|
|
||||||
|
indicator = {
|
||||||
|
icon_color = "White";
|
||||||
|
};
|
||||||
|
|
||||||
|
engine = {
|
||||||
|
hangul = {
|
||||||
|
layout = "dubeolsik";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
kime configuration. Refer to
|
||||||
|
<link xlink:href="https://github.com/Riey/kime/blob/develop/docs/CONFIGURATION.md"/>
|
||||||
|
for details on supported values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (config.i18n.inputMethod.enabled == "kime") {
|
||||||
|
i18n.inputMethod.package = pkgs.kime;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
GTK_IM_MODULE = "kime";
|
||||||
|
QT_IM_MODULE = "kime";
|
||||||
|
XMODIFIERS = "@im=kime";
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."kime/config.yaml".text =
|
||||||
|
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.config);
|
||||||
|
|
||||||
|
systemd.user.services.kime-daemon = {
|
||||||
|
Unit = { Description = "Kime input method editor"; };
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
Service.ExecStart = "${pkgs.kime}/bin/kime";
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
23
modules/i18n/input-method/nabi.nix
Normal file
23
modules/i18n/input-method/nabi.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib; {
|
||||||
|
config = mkIf (config.i18n.inputMethod.enabled == "nabi") {
|
||||||
|
i18n.inputMethod.package = pkgs.nabi;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
GTK_IM_MODULE = "nabi";
|
||||||
|
QT_IM_MODULE = "nabi";
|
||||||
|
XMODIFIERS = "@im=nabi";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.nabi-daemon = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Nabi input method editor";
|
||||||
|
PartOf = [ "graphical-session.desktop" ];
|
||||||
|
};
|
||||||
|
Service.ExecStart = "${pkgs.nabi}/bin/nabi";
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
45
modules/i18n/input-method/uim.nix
Normal file
45
modules/i18n/input-method/uim.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let cfg = config.i18n.inputMethod.uim;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
i18n.inputMethod.uim = {
|
||||||
|
toolbar = mkOption {
|
||||||
|
type = types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt4" ];
|
||||||
|
default = "gtk";
|
||||||
|
example = "gtk-systray";
|
||||||
|
description = ''
|
||||||
|
Selected UIM toolbar.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (config.i18n.inputMethod.enabled == "uim") {
|
||||||
|
i18n.inputMethod.package = pkgs.uim;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
GTK_IM_MODULE = "uim";
|
||||||
|
QT_IM_MODULE = "uim";
|
||||||
|
XMODIFIERS = "@im=uim";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.uim-daemon = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Uim input method editor";
|
||||||
|
PartOf = [ "graphical-session.desktop" ];
|
||||||
|
};
|
||||||
|
Service.ExecStart = toString
|
||||||
|
(pkgs.writeShellScript "start-uim-xim-and-uim-toolbar" ''
|
||||||
|
${pkgs.uim}/bin/uim-xim &
|
||||||
|
${pkgs.uim}/bin/uim-toolbar-${cfg.toolbar}
|
||||||
|
'');
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,35 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
function setupVars() {
|
function setupVars() {
|
||||||
local profilesPath="/nix/var/nix/profiles/per-user/$USER"
|
local nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
|
||||||
local gcPath="/nix/var/nix/gcroots/per-user/$USER"
|
local profilesPath="$nixStateDir/profiles/per-user/$USER"
|
||||||
|
local gcPath="$nixStateDir/gcroots/per-user/$USER"
|
||||||
|
|
||||||
|
declare -gr genProfilePath="$profilesPath/home-manager"
|
||||||
|
declare -gr newGenPath="@GENERATION_DIR@";
|
||||||
|
declare -gr newGenGcPath="$gcPath/current-home"
|
||||||
|
|
||||||
|
declare -g newGenLayoutVersion
|
||||||
|
if [[ -f $newGenPath/version ]]; then
|
||||||
|
newGenLayoutVersion=$(< "$newGenPath/version")
|
||||||
|
else
|
||||||
|
newGenLayoutVersion=0
|
||||||
|
fi
|
||||||
|
readonly newGenLayoutVersion
|
||||||
|
|
||||||
local greatestGenNum
|
local greatestGenNum
|
||||||
|
|
||||||
greatestGenNum=$( \
|
greatestGenNum=$( \
|
||||||
find "$profilesPath" -name 'home-manager-*-link' \
|
nix-env --list-generations --profile "$genProfilePath" \
|
||||||
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
|
| tail -1 \
|
||||||
| sort -rn \
|
| sed -E 's/ *([[:digit:]]+) .*/\1/')
|
||||||
| head -1)
|
|
||||||
|
|
||||||
if [[ -n "$greatestGenNum" ]] ; then
|
if [[ -n $greatestGenNum ]] ; then
|
||||||
oldGenNum=$greatestGenNum
|
oldGenNum=$greatestGenNum
|
||||||
newGenNum=$((oldGenNum + 1))
|
newGenNum=$((oldGenNum + 1))
|
||||||
else
|
else
|
||||||
newGenNum=1
|
newGenNum=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -e "$gcPath/current-home" ]] ; then
|
if [[ -e $profilesPath/home-manager ]] ; then
|
||||||
oldGenPath="$(readlink -e "$gcPath/current-home")"
|
declare -g oldGenPath oldGenLayoutVersion
|
||||||
|
oldGenPath="$(readlink -e "$profilesPath/home-manager")"
|
||||||
|
if [[ -f $oldGenPath/version ]]; then
|
||||||
|
oldGenLayoutVersion=$(< "$oldGenPath/version")
|
||||||
|
else
|
||||||
|
oldGenLayoutVersion=0
|
||||||
|
fi
|
||||||
|
readonly oldGenPath oldGenLayoutVersion
|
||||||
fi
|
fi
|
||||||
|
|
||||||
genProfilePath="$profilesPath/home-manager"
|
$VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath"
|
||||||
newGenPath="@GENERATION_DIR@";
|
if [[ -v oldGenNum && ! -v oldGenPath
|
||||||
newGenProfilePath="$profilesPath/home-manager-$newGenNum-link"
|
|| ! -v oldGenNum && -v oldGenPath ]]; then
|
||||||
newGenGcPath="$gcPath/current-home"
|
errorEcho "Invalid profile number and current profile values! These"
|
||||||
|
errorEcho "must be either both empty or both set but are now set to"
|
||||||
|
errorEcho " '${oldGenNum:-}' and '${oldGenPath:-}'"
|
||||||
|
errorEcho "If you don't mind losing previous profile generations then"
|
||||||
|
errorEcho "the easiest solution is probably to run"
|
||||||
|
errorEcho " rm $profilesPath/home-manager*"
|
||||||
|
errorEcho " rm $gcPath/current-home"
|
||||||
|
errorEcho "and trying home-manager switch again. Good luck!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
setupVars
|
|
||||||
|
|
||||||
echo "Starting home manager activation"
|
|
||||||
|
|
||||||
if [[ -v VERBOSE ]]; then
|
if [[ -v VERBOSE ]]; then
|
||||||
export VERBOSE_ECHO=echo
|
export VERBOSE_ECHO=echo
|
||||||
export VERBOSE_ARG="--verbose"
|
export VERBOSE_ARG="--verbose"
|
||||||
@@ -38,14 +64,28 @@ else
|
|||||||
export VERBOSE_ARG=""
|
export VERBOSE_ARG=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Starting home manager activation"
|
||||||
|
|
||||||
|
# Verify that we can connect to the Nix store and/or daemon. This will
|
||||||
|
# also create the necessary directories in profiles and gcroots.
|
||||||
|
$VERBOSE_ECHO "Sanity checking Nix"
|
||||||
|
nix-build --expr '{}' --no-out-link
|
||||||
|
|
||||||
|
setupVars
|
||||||
|
|
||||||
if [[ -v DRY_RUN ]] ; then
|
if [[ -v DRY_RUN ]] ; then
|
||||||
$VERBOSE_ECHO "This is a dry run"
|
echo "This is a dry run"
|
||||||
export DRY_RUN_CMD=echo
|
export DRY_RUN_CMD=echo
|
||||||
else
|
else
|
||||||
$VERBOSE_ECHO "This is a live run"
|
$VERBOSE_ECHO "This is a live run"
|
||||||
export DRY_RUN_CMD=""
|
export DRY_RUN_CMD=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
echo -n "Using Nix version: "
|
||||||
|
nix-env --version
|
||||||
|
fi
|
||||||
|
|
||||||
$VERBOSE_ECHO "Activation variables:"
|
$VERBOSE_ECHO "Activation variables:"
|
||||||
if [[ -v oldGenNum ]] ; then
|
if [[ -v oldGenNum ]] ; then
|
||||||
$VERBOSE_ECHO " oldGenNum=$oldGenNum"
|
$VERBOSE_ECHO " oldGenNum=$oldGenNum"
|
||||||
@@ -56,6 +96,5 @@ else
|
|||||||
fi
|
fi
|
||||||
$VERBOSE_ECHO " newGenPath=$newGenPath"
|
$VERBOSE_ECHO " newGenPath=$newGenPath"
|
||||||
$VERBOSE_ECHO " newGenNum=$newGenNum"
|
$VERBOSE_ECHO " newGenNum=$newGenNum"
|
||||||
$VERBOSE_ECHO " newGenProfilePath=$newGenProfilePath"
|
|
||||||
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
|
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
|
||||||
$VERBOSE_ECHO " genProfilePath=$genProfilePath"
|
$VERBOSE_ECHO " genProfilePath=$genProfilePath"
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# The check for terminal output and color support is heavily inspired
|
# The check for terminal output and color support is heavily inspired
|
||||||
# by https://unix.stackexchange.com/a/10065.
|
# by https://unix.stackexchange.com/a/10065.
|
||||||
|
#
|
||||||
|
# Allow opt out by respecting the `NO_COLOR` environment variable.
|
||||||
|
|
||||||
function setupColors() {
|
function setupColors() {
|
||||||
normalColor=""
|
normalColor=""
|
||||||
@@ -7,8 +9,8 @@ function setupColors() {
|
|||||||
warnColor=""
|
warnColor=""
|
||||||
noteColor=""
|
noteColor=""
|
||||||
|
|
||||||
# Check if stdout is a terminal.
|
# Enable colors for terminals, and allow opting out.
|
||||||
if [[ -t 1 ]]; then
|
if [[ ! -v NO_COLOR && -t 1 ]]; then
|
||||||
# See if it supports colors.
|
# See if it supports colors.
|
||||||
local ncolors
|
local ncolors
|
||||||
ncolors=$(tput colors)
|
ncolors=$(tput colors)
|
||||||
|
|||||||
14
modules/lib/assertions.nix
Normal file
14
modules/lib/assertions.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
{
|
||||||
|
assertPlatform = module: pkgs: platforms: {
|
||||||
|
assertion = lib.elem pkgs.stdenv.hostPlatform.system platforms;
|
||||||
|
message = let
|
||||||
|
platformsStr = lib.concatStringsSep "\n"
|
||||||
|
(map (p: " - ${p}") (lib.sort (a: b: a < b) platforms));
|
||||||
|
in ''
|
||||||
|
The module ${module} does not support your platform. It only supports
|
||||||
|
|
||||||
|
${platformsStr}'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,19 +7,17 @@
|
|||||||
# - the addition of the function `dagEntryBefore` indicating a
|
# - the addition of the function `dagEntryBefore` indicating a
|
||||||
# "wanted by" relationship.
|
# "wanted by" relationship.
|
||||||
|
|
||||||
with import <nixpkgs/lib/strings.nix>;
|
{ lib }:
|
||||||
with import <nixpkgs/lib/attrsets.nix>;
|
|
||||||
with import <nixpkgs/lib/lists.nix>;
|
with lib;
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
emptyDag = {};
|
emptyDag = { };
|
||||||
|
|
||||||
isDag = dag:
|
isDag = dag:
|
||||||
let
|
let isEntry = e: (e ? data) && (e ? after) && (e ? before);
|
||||||
isEntry = e: (e ? data) && (e ? after) && (e ? before);
|
in builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
|
||||||
in
|
|
||||||
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
|
|
||||||
|
|
||||||
# Takes an attribute set containing entries built by
|
# Takes an attribute set containing entries built by
|
||||||
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
|
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
|
||||||
@@ -80,22 +78,19 @@ rec {
|
|||||||
dagTopoSort = dag:
|
dagTopoSort = dag:
|
||||||
let
|
let
|
||||||
dagBefore = dag: name:
|
dagBefore = dag: name:
|
||||||
mapAttrsToList (n: v: n) (
|
mapAttrsToList (n: v: n)
|
||||||
filterAttrs (n: v: any (a: a == name) v.before) dag
|
(filterAttrs (n: v: any (a: a == name) v.before) dag);
|
||||||
);
|
normalizedDag = mapAttrs (n: v: {
|
||||||
normalizedDag =
|
name = n;
|
||||||
mapAttrs (n: v: {
|
data = v.data;
|
||||||
name = n;
|
after = v.after ++ dagBefore dag n;
|
||||||
data = v.data;
|
}) dag;
|
||||||
after = v.after ++ dagBefore dag n;
|
|
||||||
}) dag;
|
|
||||||
before = a: b: any (c: a.name == c) b.after;
|
before = a: b: any (c: a.name == c) b.after;
|
||||||
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
|
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
|
||||||
in
|
in if sorted ? result then {
|
||||||
if sorted ? result then
|
result = map (v: { inherit (v) name data; }) sorted.result;
|
||||||
{ result = map (v: { inherit (v) name data; }) sorted.result; }
|
} else
|
||||||
else
|
sorted;
|
||||||
sorted;
|
|
||||||
|
|
||||||
# Applies a function to each element of the given DAG.
|
# Applies a function to each element of the given DAG.
|
||||||
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
|
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
|
||||||
@@ -103,22 +98,20 @@ rec {
|
|||||||
# Create a DAG entry with no particular dependency information.
|
# Create a DAG entry with no particular dependency information.
|
||||||
dagEntryAnywhere = data: {
|
dagEntryAnywhere = data: {
|
||||||
inherit data;
|
inherit data;
|
||||||
before = [];
|
before = [ ];
|
||||||
after = [];
|
after = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
dagEntryBetween = before: after: data: {
|
dagEntryBetween = before: after: data: { inherit data before after; };
|
||||||
inherit data before after;
|
|
||||||
};
|
|
||||||
|
|
||||||
dagEntryAfter = after: data: {
|
dagEntryAfter = after: data: {
|
||||||
inherit data after;
|
inherit data after;
|
||||||
before = [];
|
before = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
dagEntryBefore = before: data: {
|
dagEntryBefore = before: data: {
|
||||||
inherit data before;
|
inherit data before;
|
||||||
after = [];
|
after = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
28
modules/lib/default.nix
Normal file
28
modules/lib/default.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
dag =
|
||||||
|
let
|
||||||
|
d = import ./dag.nix { inherit lib; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
empty = d.emptyDag;
|
||||||
|
isDag = d.isDag;
|
||||||
|
topoSort = d.dagTopoSort;
|
||||||
|
map = d.dagMap;
|
||||||
|
entryAnywhere = d.dagEntryAnywhere;
|
||||||
|
entryBetween = d.dagEntryBetween;
|
||||||
|
entryAfter = d.dagEntryAfter;
|
||||||
|
entryBefore = d.dagEntryBefore;
|
||||||
|
};
|
||||||
|
|
||||||
|
assertions = import ./assertions.nix { inherit lib; };
|
||||||
|
|
||||||
|
gvariant = import ./gvariant.nix { inherit lib; };
|
||||||
|
maintainers = import ./maintainers.nix;
|
||||||
|
strings = import ./strings.nix { inherit lib; };
|
||||||
|
types = import ./types.nix { inherit dag gvariant lib; };
|
||||||
|
|
||||||
|
shell = import ./shell.nix { inherit lib; };
|
||||||
|
zsh = import ./zsh.nix { inherit lib; };
|
||||||
|
}
|
||||||
115
modules/lib/file-type.nix
Normal file
115
modules/lib/file-type.nix
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{ homeDirectory, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
# Constructs a type suitable for a `home.file` like option. The
|
||||||
|
# target path may be either absolute or relative, in which case it
|
||||||
|
# is relative the `basePath` argument (which itself must be an
|
||||||
|
# absolute path).
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# - basePathDesc docbook compatible description of the base path
|
||||||
|
# - basePath the file base path
|
||||||
|
fileType = basePathDesc: basePath: types.attrsOf (types.submodule (
|
||||||
|
{ name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
target = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
apply = p:
|
||||||
|
let
|
||||||
|
absPath = if hasPrefix "/" p then p else "${basePath}/${p}";
|
||||||
|
in
|
||||||
|
removePrefix (homeDirectory + "/") absPath;
|
||||||
|
defaultText = literalExample "<name>";
|
||||||
|
description = ''
|
||||||
|
Path to target file relative to ${basePathDesc}.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
text = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.lines;
|
||||||
|
description = ''
|
||||||
|
Text of the file. If this option is null then
|
||||||
|
<link linkend="opt-home.file._name_.source">home.file.<name?>.source</link>
|
||||||
|
must be set.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
source = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Path of the source file or directory. If
|
||||||
|
<link linkend="opt-home.file._name_.text">home.file.<name?>.text</link>
|
||||||
|
is non-null then this option will automatically point to a file
|
||||||
|
containing that text.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
executable = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Set the execute bit. If <literal>null</literal>, defaults to the mode
|
||||||
|
of the <varname>source</varname> file or to <literal>false</literal>
|
||||||
|
for files created through the <varname>text</varname> option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
recursive = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
If the file source is a directory, then this option
|
||||||
|
determines whether the directory should be recursively
|
||||||
|
linked to the target location. This option has no effect
|
||||||
|
if the source is a file.
|
||||||
|
</para><para>
|
||||||
|
If <literal>false</literal> (the default) then the target
|
||||||
|
will be a symbolic link to the source directory. If
|
||||||
|
<literal>true</literal> then the target will be a
|
||||||
|
directory structure matching the source's but whose leafs
|
||||||
|
are symbolic links to the files of the source directory.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
onChange = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Shell commands to run when file has changed between
|
||||||
|
generations. The script will be run
|
||||||
|
<emphasis>after</emphasis> the new files have been linked
|
||||||
|
into place.
|
||||||
|
</para><para>
|
||||||
|
Note, this code is always run when <literal>recursive</literal> is
|
||||||
|
enabled.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
force = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
visible = false;
|
||||||
|
description = ''
|
||||||
|
Whether the target path should be unconditionally replaced
|
||||||
|
by the managed file source. Warning, this will silently
|
||||||
|
delete the target regardless of whether it is a file or
|
||||||
|
link.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
target = mkDefault name;
|
||||||
|
source = mkIf (config.text != null) (
|
||||||
|
mkDefault (pkgs.writeTextFile {
|
||||||
|
inherit (config) executable text;
|
||||||
|
name = hm.strings.storeFileName name;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/* Functions that generate widespread file
|
|
||||||
* formats from nix data structures.
|
|
||||||
*
|
|
||||||
* They all follow a similar interface:
|
|
||||||
* generator { config-attrs } data
|
|
||||||
*
|
|
||||||
* Tests can be found in ./tests.nix
|
|
||||||
* Documentation in the manual, #sec-generators
|
|
||||||
*/
|
|
||||||
with import <nixpkgs/lib/trivial.nix>;
|
|
||||||
let
|
|
||||||
libStr = import <nixpkgs/lib/strings.nix>;
|
|
||||||
libAttr = import <nixpkgs/lib/attrsets.nix>;
|
|
||||||
|
|
||||||
flipMapAttrs = flip libAttr.mapAttrs;
|
|
||||||
in
|
|
||||||
|
|
||||||
rec {
|
|
||||||
|
|
||||||
/* Generate a line of key k and value v, separated by
|
|
||||||
* character sep. If sep appears in k, it is escaped.
|
|
||||||
* Helper for synaxes with different separators.
|
|
||||||
*
|
|
||||||
* mkKeyValueDefault ":" "f:oo" "bar"
|
|
||||||
* > "f\:oo:bar"
|
|
||||||
*/
|
|
||||||
mkKeyValueDefault = sep: k: v:
|
|
||||||
"${libStr.escape [sep] k}${sep}${toString v}";
|
|
||||||
|
|
||||||
|
|
||||||
/* Generate a key-value-style config file from an attrset.
|
|
||||||
*
|
|
||||||
* mkKeyValue is the same as in toINI.
|
|
||||||
*/
|
|
||||||
toKeyValue = {
|
|
||||||
mkKeyValue ? mkKeyValueDefault "="
|
|
||||||
}: attrs:
|
|
||||||
let mkLine = k: v: mkKeyValue k v + "\n";
|
|
||||||
in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
|
|
||||||
|
|
||||||
|
|
||||||
/* Generate an INI-style config file from an
|
|
||||||
* attrset of sections to an attrset of key-value pairs.
|
|
||||||
*
|
|
||||||
* generators.toINI {} {
|
|
||||||
* foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
|
|
||||||
* baz = { "also, integers" = 42; };
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*> [baz]
|
|
||||||
*> also, integers=42
|
|
||||||
*>
|
|
||||||
*> [foo]
|
|
||||||
*> ciao=bar
|
|
||||||
*> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
|
|
||||||
*
|
|
||||||
* The mk* configuration attributes can generically change
|
|
||||||
* the way sections and key-value strings are generated.
|
|
||||||
*
|
|
||||||
* For more examples see the test cases in ./tests.nix.
|
|
||||||
*/
|
|
||||||
toINI = {
|
|
||||||
# apply transformations (e.g. escapes) to section names
|
|
||||||
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
|
|
||||||
# format a setting line from key and value
|
|
||||||
mkKeyValue ? mkKeyValueDefault "="
|
|
||||||
}: attrsOfAttrs:
|
|
||||||
let
|
|
||||||
# map function to string for each key val
|
|
||||||
mapAttrsToStringsSep = sep: mapFn: attrs:
|
|
||||||
libStr.concatStringsSep sep
|
|
||||||
(libAttr.mapAttrsToList mapFn attrs);
|
|
||||||
mkSection = sectName: sectValues: ''
|
|
||||||
[${mkSectionName sectName}]
|
|
||||||
'' + toKeyValue { inherit mkKeyValue; } sectValues;
|
|
||||||
in
|
|
||||||
# map input to ini sections
|
|
||||||
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
|
|
||||||
|
|
||||||
|
|
||||||
/* Generates JSON from an arbitrary (non-function) value.
|
|
||||||
* For more information see the documentation of the builtin.
|
|
||||||
*/
|
|
||||||
toJSON = {}: builtins.toJSON;
|
|
||||||
|
|
||||||
|
|
||||||
/* YAML has been a strict superset of JSON since 1.2, so we
|
|
||||||
* use toJSON. Before it only had a few differences referring
|
|
||||||
* to implicit typing rules, so it should work with older
|
|
||||||
* parsers as well.
|
|
||||||
*/
|
|
||||||
toYAML = {}@args: toJSON args;
|
|
||||||
}
|
|
||||||
156
modules/lib/gvariant.nix
Normal file
156
modules/lib/gvariant.nix
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# A partial and basic implementation of GVariant formatted strings.
|
||||||
|
#
|
||||||
|
# Note, this API is not considered fully stable and it might therefore
|
||||||
|
# change in backwards incompatible ways without prior notice.
|
||||||
|
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
mkPrimitive = t: v: {
|
||||||
|
_type = "gvariant";
|
||||||
|
type = t;
|
||||||
|
value = v;
|
||||||
|
__toString = self: "@${self.type} ${toString self.value}";
|
||||||
|
};
|
||||||
|
|
||||||
|
type = {
|
||||||
|
arrayOf = t: "a${t}";
|
||||||
|
maybeOf = t: "m${t}";
|
||||||
|
tupleOf = ts: "(${concatStrings ts})";
|
||||||
|
string = "s";
|
||||||
|
boolean = "b";
|
||||||
|
uchar = "y";
|
||||||
|
int16 = "n";
|
||||||
|
uint16 = "q";
|
||||||
|
int32 = "i";
|
||||||
|
uint32 = "u";
|
||||||
|
int64 = "x";
|
||||||
|
uint64 = "t";
|
||||||
|
double = "d";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Returns the GVariant type of a given Nix value. If no type can be
|
||||||
|
# found for the value then the empty string is returned.
|
||||||
|
typeOf = v:
|
||||||
|
with type;
|
||||||
|
if builtins.isBool v then
|
||||||
|
boolean
|
||||||
|
else if builtins.isInt v then
|
||||||
|
int32
|
||||||
|
else if builtins.isFloat v then
|
||||||
|
double
|
||||||
|
else if builtins.isString v then
|
||||||
|
string
|
||||||
|
else if builtins.isList v then
|
||||||
|
let elemType = elemTypeOf v;
|
||||||
|
in if elemType == "" then "" else arrayOf elemType
|
||||||
|
else if builtins.isAttrs v && v ? type then
|
||||||
|
v.type
|
||||||
|
else
|
||||||
|
"";
|
||||||
|
|
||||||
|
elemTypeOf = vs:
|
||||||
|
if builtins.isList vs then
|
||||||
|
if vs == [ ] then "" else typeOf (head vs)
|
||||||
|
else
|
||||||
|
"";
|
||||||
|
|
||||||
|
mkMaybe = elemType: elem:
|
||||||
|
mkPrimitive (type.maybeOf elemType) elem // {
|
||||||
|
__toString = self:
|
||||||
|
if self.value == null then
|
||||||
|
"@${self.type} nothing"
|
||||||
|
else
|
||||||
|
"just ${toString self.value}";
|
||||||
|
};
|
||||||
|
|
||||||
|
in rec {
|
||||||
|
|
||||||
|
inherit type typeOf;
|
||||||
|
|
||||||
|
isArray = hasPrefix "a";
|
||||||
|
isMaybe = hasPrefix "m";
|
||||||
|
isTuple = hasPrefix "(";
|
||||||
|
|
||||||
|
# Returns the GVariant value that most closely matches the given Nix
|
||||||
|
# value. If no GVariant value can be found then `null` is returned.
|
||||||
|
#
|
||||||
|
# No support for dictionaries, maybe types, or variants.
|
||||||
|
mkValue = v:
|
||||||
|
if builtins.isBool v then
|
||||||
|
mkBoolean v
|
||||||
|
else if builtins.isInt v then
|
||||||
|
mkInt32 v
|
||||||
|
else if builtins.isFloat v then
|
||||||
|
mkDouble v
|
||||||
|
else if builtins.isString v then
|
||||||
|
mkString v
|
||||||
|
else if builtins.isList v then
|
||||||
|
if v == [ ] then mkArray type.string [ ] else mkArray (elemTypeOf v) v
|
||||||
|
else if builtins.isAttrs v && (v._type or "") == "gvariant" then
|
||||||
|
v
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
|
mkArray = elemType: elems:
|
||||||
|
mkPrimitive (type.arrayOf elemType) (map mkValue elems) // {
|
||||||
|
__toString = self:
|
||||||
|
"@${self.type} [${concatMapStringsSep "," toString self.value}]";
|
||||||
|
};
|
||||||
|
|
||||||
|
mkEmptyArray = elemType: mkArray elemType [ ];
|
||||||
|
|
||||||
|
mkNothing = elemType: mkMaybe elemType null;
|
||||||
|
|
||||||
|
mkJust = elem: let gvarElem = mkValue elem; in mkMaybe gvarElem.type gvarElem;
|
||||||
|
|
||||||
|
mkTuple = elems:
|
||||||
|
let
|
||||||
|
gvarElems = map mkValue elems;
|
||||||
|
tupleType = type.tupleOf (map (e: e.type) gvarElems);
|
||||||
|
in mkPrimitive tupleType gvarElems // {
|
||||||
|
__toString = self:
|
||||||
|
"@${self.type} (${concatMapStringsSep "," toString self.value})";
|
||||||
|
};
|
||||||
|
|
||||||
|
mkBoolean = v:
|
||||||
|
mkPrimitive type.boolean v // {
|
||||||
|
__toString = self: if self.value then "true" else "false";
|
||||||
|
};
|
||||||
|
|
||||||
|
mkString = v:
|
||||||
|
mkPrimitive type.string v // {
|
||||||
|
__toString = self: "'${escape [ "'" "\\" ] self.value}'";
|
||||||
|
};
|
||||||
|
|
||||||
|
mkObjectpath = v:
|
||||||
|
mkPrimitive type.string v // {
|
||||||
|
__toString = self: "objectpath '${escape [ "'" ] self.value}'";
|
||||||
|
};
|
||||||
|
|
||||||
|
mkUchar = mkPrimitive type.uchar;
|
||||||
|
|
||||||
|
mkInt16 = mkPrimitive type.int16;
|
||||||
|
|
||||||
|
mkUint16 = mkPrimitive type.uint16;
|
||||||
|
|
||||||
|
mkInt32 = v:
|
||||||
|
mkPrimitive type.int32 v // {
|
||||||
|
__toString = self: toString self.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkUint32 = mkPrimitive type.uint32;
|
||||||
|
|
||||||
|
mkInt64 = mkPrimitive type.int64;
|
||||||
|
|
||||||
|
mkUint64 = mkPrimitive type.uint64;
|
||||||
|
|
||||||
|
mkDouble = v:
|
||||||
|
mkPrimitive type.double v // {
|
||||||
|
__toString = self: toString self.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
124
modules/lib/maintainers.nix
Normal file
124
modules/lib/maintainers.nix
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
# Home Manager maintainers.
|
||||||
|
#
|
||||||
|
# This attribute set contains Home Manager module maintainers that do
|
||||||
|
# not have an entry in the Nixpkgs maintainer list [1]. Entries here
|
||||||
|
# are expected to be follow the same format as described in [1].
|
||||||
|
#
|
||||||
|
# [1] https://github.com/NixOS/nixpkgs/blob/fca0d6e093c82b31103dc0dacc48da2a9b06e24b/maintainers/maintainer-list.nix#LC1
|
||||||
|
|
||||||
|
{
|
||||||
|
justinlovinger = {
|
||||||
|
name = "Justin Lovinger";
|
||||||
|
email = "git@justinlovinger.com";
|
||||||
|
github = "JustinLovinger";
|
||||||
|
githubId = 7183441;
|
||||||
|
};
|
||||||
|
owm111 = {
|
||||||
|
email = "7798336+owm111@users.noreply.github.com";
|
||||||
|
name = "Owen McGrath";
|
||||||
|
github = "owm111";
|
||||||
|
githubId = 7798336;
|
||||||
|
};
|
||||||
|
cwyc = {
|
||||||
|
email = "cwyc@users.noreply.github.com";
|
||||||
|
name = "cwyc";
|
||||||
|
github = "cwyc";
|
||||||
|
githubId = 16950437;
|
||||||
|
};
|
||||||
|
chisui = {
|
||||||
|
name = "Philipp Dargel";
|
||||||
|
email = "chisui@users.noreply.github.com";
|
||||||
|
github = "chisui";
|
||||||
|
githubId = 4526429;
|
||||||
|
};
|
||||||
|
olmokramer = {
|
||||||
|
name = "Olmo Kramer";
|
||||||
|
email = "olmokramer@users.noreply.github.com";
|
||||||
|
github = "olmokramer";
|
||||||
|
githubId = 3612514;
|
||||||
|
};
|
||||||
|
kalhauge = {
|
||||||
|
name = "Christian Gram Kalhauge";
|
||||||
|
email = "kalhauge@users.noreply.github.com";
|
||||||
|
github = "kalhauge";
|
||||||
|
githubId = 1182166;
|
||||||
|
};
|
||||||
|
kamadorueda = {
|
||||||
|
name = "Kevin Amado";
|
||||||
|
email = "kamadorueda@gmail.com";
|
||||||
|
github = "kamadorueda";
|
||||||
|
githubId = 47480384;
|
||||||
|
keys = [{
|
||||||
|
longkeyid = "rsa4096/0x04D0CEAF916A9A40";
|
||||||
|
fingerprint = "2BE3 BAFD 793E A349 ED1F F00F 04D0 CEAF 916A 9A40";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
kubukoz = {
|
||||||
|
name = "Jakub Kozłowski";
|
||||||
|
email = "kubukoz@users.noreply.github.com";
|
||||||
|
github = "kubukoz";
|
||||||
|
githubId = 894884;
|
||||||
|
};
|
||||||
|
matrss = {
|
||||||
|
name = "Matthias Riße";
|
||||||
|
email = "matrss@users.noreply.github.com";
|
||||||
|
github = "matrss";
|
||||||
|
githubId = 9308656;
|
||||||
|
};
|
||||||
|
seylerius = {
|
||||||
|
email = "sable@seyleri.us";
|
||||||
|
name = "Sable Seyler";
|
||||||
|
github = "seylerius";
|
||||||
|
githubId = 1145981;
|
||||||
|
keys = [{
|
||||||
|
logkeyid = "rsa4096/0x68BF2EAE6D91CAFF";
|
||||||
|
fingerprint = "F0E0 0311 126A CD72 4392 25E6 68BF 2EAE 6D91 CAFF";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
thiagokokada = {
|
||||||
|
email = "thiagokokada@gmail.com";
|
||||||
|
name = "Thiago Kenji Okada";
|
||||||
|
github = "thiagokokada";
|
||||||
|
githubId = 844343;
|
||||||
|
};
|
||||||
|
fendse = {
|
||||||
|
email = "46252070+Fendse@users.noreply.github.com";
|
||||||
|
github = "Fendse";
|
||||||
|
githubId = 46252070;
|
||||||
|
name = "Sara Johnsson";
|
||||||
|
};
|
||||||
|
msfjarvis = {
|
||||||
|
email = "me@msfjarvis.dev";
|
||||||
|
github = "msfjarvis";
|
||||||
|
githubId = "13348378";
|
||||||
|
name = "Harsh Shandilya";
|
||||||
|
keys = [{
|
||||||
|
longkeyid = "rsa4096/0xB7843F823355E9B9";
|
||||||
|
fingerprint = "8F87 050B 0F9C B841 1515 7399 B784 3F82 3355 E9B9";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
ambroisie = {
|
||||||
|
email = "bruno.home-manager@belanyi.fr";
|
||||||
|
github = "ambroisie";
|
||||||
|
githubId = 12465195;
|
||||||
|
name = "Bruno BELANYI";
|
||||||
|
};
|
||||||
|
malvo = {
|
||||||
|
email = "malte@malvo.org";
|
||||||
|
github = "malte-v";
|
||||||
|
githubId = 34393802;
|
||||||
|
name = "Malte Voos";
|
||||||
|
};
|
||||||
|
kranzes = {
|
||||||
|
email = "personal@ilanjoselevich.com";
|
||||||
|
github = "Kranzes";
|
||||||
|
githubId = 56614642;
|
||||||
|
name = "Ilan Joselevich";
|
||||||
|
};
|
||||||
|
mager = {
|
||||||
|
email = "andreas@mager.eu";
|
||||||
|
github = "AndreasMager";
|
||||||
|
githubId = 5646732;
|
||||||
|
name = "Andreas Mager";
|
||||||
|
};
|
||||||
|
}
|
||||||
11
modules/lib/shell.nix
Normal file
11
modules/lib/shell.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# Produces a Bourne shell like variable export statement.
|
||||||
|
export = n: v: ''export ${n}="${toString v}"'';
|
||||||
|
|
||||||
|
# Given an attribute set containing shell variable names and their
|
||||||
|
# assignment, this function produces a string containing an export
|
||||||
|
# statement for each set entry.
|
||||||
|
exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars);
|
||||||
|
}
|
||||||
7
modules/lib/stdlib-extended.nix
Normal file
7
modules/lib/stdlib-extended.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Just a convenience function that returns the given Nixpkgs standard
|
||||||
|
# library extended with the HM library.
|
||||||
|
|
||||||
|
nixpkgsLib:
|
||||||
|
|
||||||
|
let mkHmLib = import ./.;
|
||||||
|
in nixpkgsLib.extend (self: super: { hm = mkHmLib { lib = super; }; })
|
||||||
22
modules/lib/strings.nix
Normal file
22
modules/lib/strings.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
# Figures out a valid Nix store name for the given path.
|
||||||
|
storeFileName = path:
|
||||||
|
let
|
||||||
|
# All characters that are considered safe. Note "-" is not
|
||||||
|
# included to avoid "-" followed by digit being interpreted as a
|
||||||
|
# version.
|
||||||
|
safeChars = [ "+" "." "_" "?" "=" ] ++ lowerChars ++ upperChars
|
||||||
|
++ stringToCharacters "0123456789";
|
||||||
|
|
||||||
|
empties = l: genList (x: "") (length l);
|
||||||
|
|
||||||
|
unsafeInName =
|
||||||
|
stringToCharacters (replaceStrings safeChars (empties safeChars) path);
|
||||||
|
|
||||||
|
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
|
||||||
|
in "hm_" + safeName;
|
||||||
|
}
|
||||||
99
modules/lib/types-dag.nix
Normal file
99
modules/lib/types-dag.nix
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
{ dag, lib }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
|
||||||
|
|
||||||
|
dagContentType = elemType:
|
||||||
|
types.submodule ({ name, ... }: {
|
||||||
|
options = {
|
||||||
|
data = mkOption { type = elemType; };
|
||||||
|
after = mkOption { type = with types; uniq (listOf str); };
|
||||||
|
before = mkOption { type = with types; uniq (listOf str); };
|
||||||
|
};
|
||||||
|
config = mkIf (elemType.name == "submodule") {
|
||||||
|
data._module.args.dagName = name;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
in rec {
|
||||||
|
# A directed acyclic graph of some inner type.
|
||||||
|
#
|
||||||
|
# Note, if the element type is a submodule then the `name` argument
|
||||||
|
# will always be set to the string "data" since it picks up the
|
||||||
|
# internal structure of the DAG values. To give access to the
|
||||||
|
# "actual" attribute name a new submodule argument is provided with
|
||||||
|
# the name `dagName`.
|
||||||
|
dagOf = elemType:
|
||||||
|
let
|
||||||
|
convertAllToDags = let
|
||||||
|
maybeConvert = n: v: if isDagEntry v then v else dag.entryAnywhere v;
|
||||||
|
in map (def: def // { value = mapAttrs maybeConvert def.value; });
|
||||||
|
|
||||||
|
attrEquivalent = types.attrsOf (dagContentType elemType);
|
||||||
|
in mkOptionType rec {
|
||||||
|
name = "dagOf";
|
||||||
|
description = "DAG of ${elemType.description}s";
|
||||||
|
check = isAttrs;
|
||||||
|
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
|
||||||
|
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
|
||||||
|
getSubModules = elemType.getSubModules;
|
||||||
|
substSubModules = m: dagOf (elemType.substSubModules m);
|
||||||
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
|
};
|
||||||
|
|
||||||
|
# A directed acyclic graph of some inner type OR a list of that
|
||||||
|
# inner type. This is a temporary hack for use by the
|
||||||
|
# `programs.ssh.matchBlocks` and is only guaranteed to be vaguely
|
||||||
|
# correct!
|
||||||
|
#
|
||||||
|
# In particular, adding a dependency on one of the "unnamed-N-M"
|
||||||
|
# entries generated by a list value is almost guaranteed to destroy
|
||||||
|
# the list's order.
|
||||||
|
#
|
||||||
|
# This function will be removed in version 20.09.
|
||||||
|
listOrDagOf = elemType:
|
||||||
|
let
|
||||||
|
paddedIndexStr = list: i:
|
||||||
|
let padWidth = stringLength (toString (length list));
|
||||||
|
in fixedWidthNumber padWidth i;
|
||||||
|
|
||||||
|
convertAll = loc: defs:
|
||||||
|
let
|
||||||
|
convertListValue = namePrefix: def:
|
||||||
|
let
|
||||||
|
vs = def.value;
|
||||||
|
pad = paddedIndexStr vs;
|
||||||
|
makeEntry = i: v: nameValuePair "${namePrefix}.${pad i}" v;
|
||||||
|
warning = ''
|
||||||
|
In file ${def.file}
|
||||||
|
a list is being assigned to the option '${
|
||||||
|
concatStringsSep "." loc
|
||||||
|
}'.
|
||||||
|
This will soon be an error due to the list form being deprecated.
|
||||||
|
Please use the attribute set form instead with DAG functions to
|
||||||
|
express the desired order of entries.
|
||||||
|
'';
|
||||||
|
in warn warning (listToAttrs (imap1 makeEntry vs));
|
||||||
|
|
||||||
|
convertValue = i: def:
|
||||||
|
if isList def.value then
|
||||||
|
convertListValue "unnamed-${paddedIndexStr defs i}" def
|
||||||
|
else
|
||||||
|
def.value;
|
||||||
|
in imap1 (i: def: def // { value = convertValue i def; }) defs;
|
||||||
|
|
||||||
|
dagType = dagOf elemType;
|
||||||
|
in mkOptionType rec {
|
||||||
|
name = "listOrDagOf";
|
||||||
|
description = "list or DAG of ${elemType.description}s";
|
||||||
|
check = x: isList x || dagType.check x;
|
||||||
|
merge = loc: defs: dagType.merge loc (convertAll loc defs);
|
||||||
|
getSubOptions = dagType.getSubOptions;
|
||||||
|
getSubModules = dagType.getSubModules;
|
||||||
|
substSubModules = m: listOrDagOf (elemType.substSubModules m);
|
||||||
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
|
};
|
||||||
|
}
|
||||||
99
modules/lib/types.nix
Normal file
99
modules/lib/types.nix
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
{ lib, dag ? import ./dag.nix { inherit lib; }
|
||||||
|
, gvariant ? import ./gvariant.nix { inherit lib; } }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
typesDag = import ./types-dag.nix { inherit dag lib; };
|
||||||
|
|
||||||
|
# Needed since the type is called gvariant and its merge attribute
|
||||||
|
# must refer back to the type.
|
||||||
|
gvar = gvariant;
|
||||||
|
|
||||||
|
in rec {
|
||||||
|
|
||||||
|
inherit (typesDag) dagOf listOrDagOf;
|
||||||
|
|
||||||
|
selectorFunction = mkOptionType {
|
||||||
|
name = "selectorFunction";
|
||||||
|
description = "Function that takes an attribute set and returns a list"
|
||||||
|
+ " containing a selection of the values of the input set";
|
||||||
|
check = isFunction;
|
||||||
|
merge = _loc: defs: as: concatMap (select: select as) (getValues defs);
|
||||||
|
};
|
||||||
|
|
||||||
|
overlayFunction = mkOptionType {
|
||||||
|
name = "overlayFunction";
|
||||||
|
description = "An overlay function, takes self and super and returns"
|
||||||
|
+ " an attribute set overriding the desired attributes.";
|
||||||
|
check = isFunction;
|
||||||
|
merge = _loc: defs: self: super:
|
||||||
|
foldl' (res: def: mergeAttrs res (def.value self super)) { } defs;
|
||||||
|
};
|
||||||
|
|
||||||
|
fontType = types.submodule {
|
||||||
|
options = {
|
||||||
|
package = mkOption {
|
||||||
|
type = types.nullOr types.package;
|
||||||
|
default = null;
|
||||||
|
example = literalExample "pkgs.dejavu_fonts";
|
||||||
|
description = ''
|
||||||
|
Package providing the font. This package will be installed
|
||||||
|
to your profile. If <literal>null</literal> then the font
|
||||||
|
is assumed to already be available in your profile.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "DejaVu Sans";
|
||||||
|
description = ''
|
||||||
|
The family name of the font within the package.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
size = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
example = "8";
|
||||||
|
description = ''
|
||||||
|
The size of the font.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gvariant = mkOptionType rec {
|
||||||
|
name = "gvariant";
|
||||||
|
description = "GVariant value";
|
||||||
|
check = v: gvar.mkValue v != null;
|
||||||
|
merge = loc: defs:
|
||||||
|
let
|
||||||
|
vdefs = map (d: d // { value = gvar.mkValue d.value; }) defs;
|
||||||
|
vals = map (d: d.value) vdefs;
|
||||||
|
defTypes = map (x: x.type) vals;
|
||||||
|
sameOrNull = x: y: if x == y then y else null;
|
||||||
|
# A bit naive to just check the first entry…
|
||||||
|
sharedDefType = foldl' sameOrNull (head defTypes) defTypes;
|
||||||
|
allChecked = all (x: check x) vals;
|
||||||
|
in if sharedDefType == null then
|
||||||
|
throw ("Cannot merge definitions of `${showOption loc}' with"
|
||||||
|
+ " mismatched GVariant types given in"
|
||||||
|
+ " ${showFiles (getFiles defs)}.")
|
||||||
|
else if gvar.isArray sharedDefType && allChecked then
|
||||||
|
(types.listOf gvariant).merge loc
|
||||||
|
(map (d: d // { value = d.value.value; }) vdefs)
|
||||||
|
else if gvar.isTuple sharedDefType && allChecked then
|
||||||
|
mergeOneOption loc defs
|
||||||
|
else if gvar.isMaybe sharedDefType && allChecked then
|
||||||
|
mergeOneOption loc defs
|
||||||
|
else if gvar.type.string == sharedDefType && allChecked then
|
||||||
|
types.str.merge loc defs
|
||||||
|
else if gvar.type.double == sharedDefType && allChecked then
|
||||||
|
types.float.merge loc defs
|
||||||
|
else
|
||||||
|
mergeDefaultOption loc defs;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
30
modules/lib/zsh.nix
Normal file
30
modules/lib/zsh.nix
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
# Produces a Zsh shell like value
|
||||||
|
toZshValue = v:
|
||||||
|
if builtins.isBool v then
|
||||||
|
if v then "true" else "false"
|
||||||
|
else if builtins.isString v then
|
||||||
|
''"${v}"''
|
||||||
|
else if builtins.isList v then
|
||||||
|
"(${lib.concatStringsSep " " (map toZshValue v)})"
|
||||||
|
else
|
||||||
|
''"${toString v}"'';
|
||||||
|
|
||||||
|
# Produces a Zsh shell like definition statement
|
||||||
|
define = n: v: "${n}=${toZshValue v}";
|
||||||
|
|
||||||
|
# Given an attribute set containing shell variable names and their
|
||||||
|
# assignments, this function produces a string containing a definition
|
||||||
|
# statement for each set entry.
|
||||||
|
defineAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList define vars);
|
||||||
|
|
||||||
|
# Produces a Zsh shell like export statement
|
||||||
|
export = n: v: "export ${define n v}";
|
||||||
|
|
||||||
|
# Given an attribute set containing shell variable names and their
|
||||||
|
# assignments, this function produces a string containing an export
|
||||||
|
# statement for each set entry.
|
||||||
|
exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars);
|
||||||
|
}
|
||||||
@@ -1,49 +1,27 @@
|
|||||||
{ config, lib, pkgs, baseModules, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
/* For the purpose of generating docs, evaluate options with each derivation
|
cfg = config.manual;
|
||||||
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
|
|
||||||
It isn't perfect, but it seems to cover a vast majority of use cases.
|
|
||||||
Caveat: even if the package is reached by a different means,
|
|
||||||
the path above will be shown and not e.g. `${config.services.foo.package}`. */
|
|
||||||
nixosManual = import <nixpkgs/nixos/doc/manual> {
|
|
||||||
inherit pkgs config;
|
|
||||||
version = "0.1";
|
|
||||||
revision = "release-0.1";
|
|
||||||
options =
|
|
||||||
let
|
|
||||||
scrubbedEval = evalModules {
|
|
||||||
modules = [ { nixpkgs.system = pkgs.stdenv.system; } ] ++ baseModules;
|
|
||||||
args = (config._module.args) // { modules = [ ]; };
|
|
||||||
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
|
|
||||||
};
|
|
||||||
scrubDerivations = namePrefix: pkgSet: mapAttrs
|
|
||||||
(name: value:
|
|
||||||
let wholeName = "${namePrefix}.${name}"; in
|
|
||||||
if isAttrs value then
|
|
||||||
scrubDerivations wholeName value
|
|
||||||
// (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
|
|
||||||
else value
|
|
||||||
)
|
|
||||||
pkgSet;
|
|
||||||
in scrubbedEval.options;
|
|
||||||
};
|
|
||||||
|
|
||||||
homeEnvironmentManPages = pkgs.runCommand "home-environment-manpages" {
|
docs = import ../doc { inherit lib pkgs; };
|
||||||
allowedReferences = [ "out" ];
|
|
||||||
} ''
|
|
||||||
install -v -D -m444 \
|
|
||||||
${nixosManual.manpages}/share/man/man5/configuration.nix.5 \
|
|
||||||
$out/share/man/man5/home-configuration.nix.5
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
manual.html.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to install the HTML manual. This also installs the
|
||||||
|
<command>home-manager-help</command> tool, which opens a local
|
||||||
|
copy of the Home Manager manual in the system web browser.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
manual.manpages.enable = mkOption {
|
manual.manpages.enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@@ -57,12 +35,34 @@ in
|
|||||||
Thanks!
|
Thanks!
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
manual.json.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
Whether to install a JSON formatted list of all Home Manager
|
||||||
|
options. This can be located at
|
||||||
|
<filename><profile directory>/share/doc/home-manager/options.json</filename>,
|
||||||
|
and may be used for navigating definitions, auto-completing,
|
||||||
|
and other miscellaneous tasks.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf config.manual.manpages.enable {
|
config = {
|
||||||
# To fix error during manpage build.
|
home.packages = mkMerge [
|
||||||
meta.doc = builtins.toFile "nothingness" "<para></para>";
|
(mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ])
|
||||||
|
(mkIf cfg.manpages.enable [ docs.manPages ])
|
||||||
|
(mkIf cfg.json.enable [ docs.options.json ])
|
||||||
|
];
|
||||||
|
|
||||||
home.packages = [ homeEnvironmentManPages ];
|
# Whether a dependency on nmd should be introduced.
|
||||||
|
home.extraBuilderCommands =
|
||||||
|
mkIf (cfg.html.enable || cfg.manpages.enable || cfg.json.enable) ''
|
||||||
|
mkdir $out/lib
|
||||||
|
ln -s ${docs.nmdSrc} $out/lib/nmd
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
70
modules/misc/dconf.nix
Normal file
70
modules/misc/dconf.nix
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.dconf;
|
||||||
|
|
||||||
|
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
|
||||||
|
|
||||||
|
mkIniKeyValue = key: value: "${key}=${toString (hm.gvariant.mkValue value)}";
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.gnidorah maintainers.rycee ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
dconf = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
visible = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable dconf settings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = with types; attrsOf (attrsOf hm.types.gvariant);
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"org/gnome/calculator" = {
|
||||||
|
button-mode = "programming";
|
||||||
|
show-thousands = true;
|
||||||
|
base = 10;
|
||||||
|
word-size = 64;
|
||||||
|
window-position = lib.hm.gvariant.mkTuple [100 100];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Settings to write to the dconf configuration system.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.enable && cfg.settings != { }) {
|
||||||
|
# Make sure the dconf directory exists.
|
||||||
|
xdg.configFile."dconf/.keep".source = builtins.toFile "keep" "";
|
||||||
|
|
||||||
|
home.activation.dconfSettings = hm.dag.entryAfter [ "installPackages" ]
|
||||||
|
(let iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
|
||||||
|
in ''
|
||||||
|
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
|
||||||
|
DCONF_DBUS_RUN_SESSION=""
|
||||||
|
else
|
||||||
|
DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v DRY_RUN ]]; then
|
||||||
|
echo $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / "<" ${iniFile}
|
||||||
|
else
|
||||||
|
$DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset DCONF_DBUS_RUN_SESSION
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
}
|
||||||
26
modules/misc/debug.nix
Normal file
26
modules/misc/debug.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options.home = {
|
||||||
|
enableDebugInfo = mkEnableOption "" // {
|
||||||
|
description = ''
|
||||||
|
Some Nix-packages provide debug symbols for
|
||||||
|
<command>gdb</command> in the <literal>debug</literal>-output.
|
||||||
|
This option ensures that those are automatically fetched from
|
||||||
|
the binary cache if available and <command>gdb</command> is
|
||||||
|
configured to find those symbols.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.home.enableDebugInfo {
|
||||||
|
home.extraOutputsToInstall = [ "debug" ];
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
NIX_DEBUG_INFO_DIRS =
|
||||||
|
"$NIX_DEBUG_INFO_DIRS\${NIX_DEBUG_INFO_DIRS:+:}${config.home.profileDirectory}/lib/debug";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
105
modules/misc/fontconfig.nix
Normal file
105
modules/misc/fontconfig.nix
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.fonts.fontconfig;
|
||||||
|
|
||||||
|
profileDirectory = config.home.profileDirectory;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
|
||||||
|
"fonts"
|
||||||
|
"fontconfig"
|
||||||
|
"enable"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
fonts.fontconfig = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable fontconfig configuration. This will, for
|
||||||
|
example, allow fontconfig to discover fonts and
|
||||||
|
configurations installed through
|
||||||
|
<varname>home.packages</varname> and
|
||||||
|
<command>nix-env</command>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# Create two dummy files in /lib/fontconfig to make sure that
|
||||||
|
# buildEnv creates a real directory path. These files are removed
|
||||||
|
# in home.extraProfileCommands below so the packages will not
|
||||||
|
# become "runtime" dependencies.
|
||||||
|
home.packages = [
|
||||||
|
(pkgs.writeTextFile {
|
||||||
|
name = "hm-dummy1";
|
||||||
|
destination = "/lib/fontconfig/hm-dummy1";
|
||||||
|
text = "dummy";
|
||||||
|
})
|
||||||
|
|
||||||
|
(pkgs.writeTextFile {
|
||||||
|
name = "hm-dummy2";
|
||||||
|
destination = "/lib/fontconfig/hm-dummy2";
|
||||||
|
text = "dummy";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
home.extraProfileCommands = ''
|
||||||
|
if [[ -d $out/lib/X11/fonts || -d $out/share/fonts ]]; then
|
||||||
|
export FONTCONFIG_FILE="$(pwd)/fonts.conf"
|
||||||
|
|
||||||
|
cat > $FONTCONFIG_FILE << EOF
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||||
|
<fontconfig>
|
||||||
|
<dir>$out/lib/X11/fonts</dir>
|
||||||
|
<dir>$out/share/fonts</dir>
|
||||||
|
<cachedir>$out/lib/fontconfig/cache</cachedir>
|
||||||
|
</fontconfig>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
${getBin pkgs.fontconfig}/bin/fc-cache -f
|
||||||
|
rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG
|
||||||
|
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig/cache
|
||||||
|
|
||||||
|
rm "$FONTCONFIG_FILE"
|
||||||
|
unset FONTCONFIG_FILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove hacky dummy files.
|
||||||
|
rm $out/lib/fontconfig/hm-dummy?
|
||||||
|
rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.configFile = {
|
||||||
|
"fontconfig/conf.d/10-hm-fonts.conf".text = ''
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
|
||||||
|
<!-- Generated by Home Manager. -->
|
||||||
|
|
||||||
|
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||||
|
<fontconfig>
|
||||||
|
<include ignore_missing="yes">${config.home.path}/etc/fonts/conf.d</include>
|
||||||
|
<include ignore_missing="yes">${config.home.path}/etc/fonts/fonts.conf</include>
|
||||||
|
|
||||||
|
<dir>${config.home.path}/lib/X11/fonts</dir>
|
||||||
|
<dir>${config.home.path}/share/fonts</dir>
|
||||||
|
<dir>${profileDirectory}/lib/X11/fonts</dir>
|
||||||
|
<dir>${profileDirectory}/share/fonts</dir>
|
||||||
|
|
||||||
|
<cachedir>${config.home.path}/lib/fontconfig/cache</cachedir>
|
||||||
|
</fontconfig>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -8,124 +8,179 @@ let
|
|||||||
cfg2 = config.gtk.gtk2;
|
cfg2 = config.gtk.gtk2;
|
||||||
cfg3 = config.gtk.gtk3;
|
cfg3 = config.gtk.gtk3;
|
||||||
|
|
||||||
toGtk3Ini = (import ../lib/generators.nix).toINI {
|
toGtk3Ini = generators.toINI {
|
||||||
mkKeyValue = key: value:
|
mkKeyValue = key: value:
|
||||||
let
|
let
|
||||||
value' =
|
value' = if isBool value then
|
||||||
if isBool value then (if value then "true" else "false")
|
(if value then "true" else "false")
|
||||||
else toString value;
|
else
|
||||||
in
|
toString value;
|
||||||
"${key}=${value'}";
|
in "${key}=${value'}";
|
||||||
};
|
};
|
||||||
|
|
||||||
formatGtk2Option = n: v:
|
formatGtk2Option = n: v:
|
||||||
let
|
let
|
||||||
v' =
|
v' = if isBool v then
|
||||||
if isBool v then (if v then "true" else "false")
|
(if v then "true" else "false")
|
||||||
else if isString v then "\"${v}\""
|
else if isString v then
|
||||||
else toString v;
|
''"${v}"''
|
||||||
in
|
else
|
||||||
"${n} = ${v'}";
|
toString v;
|
||||||
|
in "${n} = ${v'}";
|
||||||
|
|
||||||
in
|
themeType = types.submodule {
|
||||||
|
options = {
|
||||||
|
package = mkOption {
|
||||||
|
type = types.nullOr types.package;
|
||||||
|
default = null;
|
||||||
|
example = literalExample "pkgs.gnome.gnome_themes_standard";
|
||||||
|
description = ''
|
||||||
|
Package providing the theme. This package will be installed
|
||||||
|
to your profile. If <literal>null</literal> then the theme
|
||||||
|
is assumed to already be available in your profile.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "Adwaita";
|
||||||
|
description = "The name of the theme within the package.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "gtk" "gtk3" "waylandSupport" ] ''
|
||||||
|
This options is not longer needed and can be removed.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
{
|
|
||||||
options = {
|
options = {
|
||||||
gtk = {
|
gtk = {
|
||||||
enable = mkEnableOption "GTK 2/3 configuration";
|
enable = mkEnableOption "GTK 2/3 configuration";
|
||||||
|
|
||||||
fontName = mkOption {
|
font = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr hm.types.fontType;
|
||||||
default = null;
|
default = null;
|
||||||
example = "DejaVu Sans 8";
|
|
||||||
description = ''
|
description = ''
|
||||||
The font to use in GTK+ 2/3 applications.
|
The font to use in GTK+ 2/3 applications.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
themeName = mkOption {
|
iconTheme = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr themeType;
|
||||||
default = null;
|
default = null;
|
||||||
example = "Vertex-Dark";
|
description = "The icon theme to use.";
|
||||||
description = "The name of the GTK+2/3 theme to use.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
iconThemeName = mkOption {
|
theme = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr themeType;
|
||||||
default = null;
|
default = null;
|
||||||
example = "Tango";
|
description = "The GTK+2/3 theme to use.";
|
||||||
description = "The name of the icon theme to use.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gtk2 = mkOption {
|
gtk2 = {
|
||||||
description = "Options specific to GTK+ 2";
|
extraConfig = mkOption {
|
||||||
default = {};
|
type = types.lines;
|
||||||
type = types.submodule {
|
default = "";
|
||||||
options = {
|
example = "gtk-can-change-accels = 1";
|
||||||
extraConfig = mkOption {
|
description = ''
|
||||||
type = types.lines;
|
Extra configuration lines to add verbatim to
|
||||||
default = "";
|
<filename>~/.gtkrc-2.0</filename>.
|
||||||
example = "gtk-can-change-accels = 1";
|
'';
|
||||||
description = ''
|
};
|
||||||
Extra configuration lines to add verbatim to
|
|
||||||
<filename>~/.gtkrc-2.0</filename>.
|
configLocation = mkOption {
|
||||||
'';
|
type = types.path;
|
||||||
};
|
default = "${config.home.homeDirectory}/.gtkrc-2.0";
|
||||||
};
|
defaultText =
|
||||||
|
literalExample ''"''${config.home.homeDirectory}/.gtkrc-2.0"'';
|
||||||
|
example =
|
||||||
|
literalExample ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"'';
|
||||||
|
description = ''
|
||||||
|
The location to put the GTK configuration file.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
gtk3 = mkOption {
|
gtk3 = {
|
||||||
description = "Options specific to GTK+ 3";
|
bookmarks = mkOption {
|
||||||
default = {};
|
type = types.listOf types.str;
|
||||||
type = types.submodule {
|
default = [ ];
|
||||||
options = {
|
example = [ "file:///home/jane/Documents" ];
|
||||||
extraConfig = mkOption {
|
description = "Bookmarks in the sidebar of the GTK file browser";
|
||||||
type = types.attrs;
|
};
|
||||||
default = {};
|
|
||||||
example = { gtk-cursor-blink = false; gtk-recent-files-limit = 20; };
|
|
||||||
description = ''
|
|
||||||
Extra configuration options to add to
|
|
||||||
<filename>~/.config/gtk-3.0/settings.ini</filename>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraCss = mkOption {
|
extraConfig = mkOption {
|
||||||
type = types.lines;
|
type = with types; attrsOf (either bool (either int str));
|
||||||
default = "";
|
default = { };
|
||||||
description = ''
|
example = {
|
||||||
Extra configuration lines to add verbatim to
|
gtk-cursor-blink = false;
|
||||||
<filename>~/.config/gtk-3.0/gtk.css</filename>.
|
gtk-recent-files-limit = 20;
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
description = ''
|
||||||
|
Extra configuration options to add to
|
||||||
|
<filename>~/.config/gtk-3.0/settings.ini</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraCss = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Extra configuration lines to add verbatim to
|
||||||
|
<filename>~/.config/gtk-3.0/gtk.css</filename>.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable (let
|
||||||
let
|
ini = optionalAttrs (cfg.font != null) {
|
||||||
ini =
|
gtk-font-name = let
|
||||||
optionalAttrs (cfg.fontName != null)
|
fontSize =
|
||||||
{ gtk-font-name = cfg.fontName; }
|
optionalString (cfg.font.size != null) " ${toString cfg.font.size}";
|
||||||
//
|
in "${cfg.font.name}" + fontSize;
|
||||||
optionalAttrs (cfg.themeName != null)
|
} // optionalAttrs (cfg.theme != null) { gtk-theme-name = cfg.theme.name; }
|
||||||
{ gtk-theme-name = cfg.themeName; }
|
// optionalAttrs (cfg.iconTheme != null) {
|
||||||
//
|
gtk-icon-theme-name = cfg.iconTheme.name;
|
||||||
optionalAttrs (cfg.iconThemeName != null)
|
};
|
||||||
{ gtk-icon-theme-name = cfg.iconThemeName; };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.file.".gtkrc-2.0".text =
|
|
||||||
concatStringsSep "\n" (
|
|
||||||
mapAttrsToList formatGtk2Option ini
|
|
||||||
) + "\n" + cfg2.extraConfig;
|
|
||||||
|
|
||||||
home.file.".config/gtk-3.0/settings.ini".text =
|
dconfIni = optionalAttrs (cfg.font != null) {
|
||||||
toGtk3Ini { Settings = ini // cfg3.extraConfig; };
|
font-name = let
|
||||||
|
fontSize =
|
||||||
|
optionalString (cfg.font.size != null) " ${toString cfg.font.size}";
|
||||||
|
in "${cfg.font.name}" + fontSize;
|
||||||
|
} // optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; }
|
||||||
|
// optionalAttrs (cfg.iconTheme != null) {
|
||||||
|
icon-theme = cfg.iconTheme.name;
|
||||||
|
};
|
||||||
|
|
||||||
home.file.".config/gtk-3.0/gtk.css".text = cfg3.extraCss;
|
optionalPackage = opt:
|
||||||
}
|
optional (opt != null && opt.package != null) opt.package;
|
||||||
);
|
in {
|
||||||
|
home.packages = optionalPackage cfg.font ++ optionalPackage cfg.theme
|
||||||
|
++ optionalPackage cfg.iconTheme;
|
||||||
|
|
||||||
|
home.file.${cfg2.configLocation}.text =
|
||||||
|
concatStringsSep "\n" (mapAttrsToList formatGtk2Option ini) + "\n"
|
||||||
|
+ cfg2.extraConfig;
|
||||||
|
|
||||||
|
home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation;
|
||||||
|
|
||||||
|
xdg.configFile."gtk-3.0/settings.ini".text =
|
||||||
|
toGtk3Ini { Settings = ini // cfg3.extraConfig; };
|
||||||
|
|
||||||
|
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
|
||||||
|
|
||||||
|
xdg.configFile."gtk-3.0/bookmarks" = mkIf (cfg3.bookmarks != [ ]) {
|
||||||
|
text = concatStringsSep "\n" cfg3.bookmarks;
|
||||||
|
};
|
||||||
|
|
||||||
|
dconf.settings."org/gnome/desktop/interface" = dconfIni;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
14
modules/misc/lib.nix
Normal file
14
modules/misc/lib.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
lib = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
This option allows modules to define helper functions,
|
||||||
|
constants, etc.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
2154
modules/misc/news.nix
Normal file
2154
modules/misc/news.nix
Normal file
File diff suppressed because it is too large
Load Diff
139
modules/misc/nixpkgs.nix
Normal file
139
modules/misc/nixpkgs.nix
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
# Adapted from Nixpkgs.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, pkgsPath, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
isConfig = x: builtins.isAttrs x || builtins.isFunction x;
|
||||||
|
|
||||||
|
optCall = f: x: if builtins.isFunction f then f x else f;
|
||||||
|
|
||||||
|
mergeConfig = lhs_: rhs_:
|
||||||
|
let
|
||||||
|
lhs = optCall lhs_ { inherit pkgs; };
|
||||||
|
rhs = optCall rhs_ { inherit pkgs; };
|
||||||
|
in lhs // rhs // optionalAttrs (lhs ? packageOverrides) {
|
||||||
|
packageOverrides = pkgs:
|
||||||
|
optCall lhs.packageOverrides pkgs
|
||||||
|
// optCall (attrByPath [ "packageOverrides" ] ({ }) rhs) pkgs;
|
||||||
|
} // optionalAttrs (lhs ? perlPackageOverrides) {
|
||||||
|
perlPackageOverrides = pkgs:
|
||||||
|
optCall lhs.perlPackageOverrides pkgs
|
||||||
|
// optCall (attrByPath [ "perlPackageOverrides" ] ({ }) rhs) pkgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
configType = mkOptionType {
|
||||||
|
name = "nixpkgs-config";
|
||||||
|
description = "nixpkgs config";
|
||||||
|
check = x:
|
||||||
|
let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
|
||||||
|
in traceXIfNot isConfig;
|
||||||
|
merge = args: fold (def: mergeConfig def.value) { };
|
||||||
|
};
|
||||||
|
|
||||||
|
overlayType = mkOptionType {
|
||||||
|
name = "nixpkgs-overlay";
|
||||||
|
description = "nixpkgs overlay";
|
||||||
|
check = builtins.isFunction;
|
||||||
|
merge = lib.mergeOneOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
_pkgs = import pkgsPath (filterAttrs (n: v: v != null) config.nixpkgs);
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.nixpkgs = {
|
||||||
|
config = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = { allowBroken = true; };
|
||||||
|
type = types.nullOr configType;
|
||||||
|
description = ''
|
||||||
|
The configuration of the Nix Packages collection. (For
|
||||||
|
details, see the Nixpkgs documentation.) It allows you to set
|
||||||
|
package configuration options.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
If <literal>null</literal>, then configuration is taken from
|
||||||
|
the fallback location, for example,
|
||||||
|
<filename>~/.config/nixpkgs/config.nix</filename>.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
Note, this option will not apply outside your Home Manager
|
||||||
|
configuration like when installing manually through
|
||||||
|
<command>nix-env</command>. If you want to apply it both
|
||||||
|
inside and outside Home Manager you can put it in a separate
|
||||||
|
file and include something like
|
||||||
|
|
||||||
|
<programlisting language="nix">
|
||||||
|
nixpkgs.config = import ./nixpkgs-config.nix;
|
||||||
|
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
in your Home Manager configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
overlays = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = literalExample ''
|
||||||
|
[ (self: super: {
|
||||||
|
openssh = super.openssh.override {
|
||||||
|
hpnSupport = true;
|
||||||
|
withKerberos = true;
|
||||||
|
kerberos = self.libkrb5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
) ]
|
||||||
|
'';
|
||||||
|
type = types.nullOr (types.listOf overlayType);
|
||||||
|
description = ''
|
||||||
|
List of overlays to use with the Nix Packages collection. (For
|
||||||
|
details, see the Nixpkgs documentation.) It allows you to
|
||||||
|
override packages globally. This is a function that takes as
|
||||||
|
an argument the <emphasis>original</emphasis> Nixpkgs. The
|
||||||
|
first argument should be used for finding dependencies, and
|
||||||
|
the second should be used for overriding recipes.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
If <literal>null</literal>, then the overlays are taken from
|
||||||
|
the fallback location, for example,
|
||||||
|
<filename>~/.config/nixpkgs/overlays</filename>.
|
||||||
|
|
||||||
|
</para><para>
|
||||||
|
|
||||||
|
Like <varname>nixpkgs.config</varname> this option only
|
||||||
|
applies within the Home Manager configuration. See
|
||||||
|
<varname>nixpkgs.config</varname> for a suggested setup that
|
||||||
|
works both internally and externally.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "i686-linux";
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Specifies the Nix platform type for which the user environment
|
||||||
|
should be built. If unset, it defaults to the platform type of
|
||||||
|
your host system. Specifying this option is useful when doing
|
||||||
|
distributed multi-platform deployment, or when building
|
||||||
|
virtual machines.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
_module.args = {
|
||||||
|
pkgs = mkOverride modules.defaultPriority _pkgs;
|
||||||
|
pkgs_i686 =
|
||||||
|
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 then
|
||||||
|
_pkgs.pkgsi686Linux
|
||||||
|
else
|
||||||
|
{ };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
35
modules/misc/numlock.nix
Normal file
35
modules/misc/numlock.nix
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xsession.numlock;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.evanjs ];
|
||||||
|
|
||||||
|
options = { xsession.numlock.enable = mkEnableOption "Num Lock"; };
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
(hm.assertions.assertPlatform "xsession.numlock" pkgs platforms.linux)
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.user.services.numlockx = {
|
||||||
|
Unit = {
|
||||||
|
Description = "NumLockX";
|
||||||
|
After = [ "graphical-session-pre.target" ];
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = "${pkgs.numlockx}/bin/numlockx";
|
||||||
|
};
|
||||||
|
|
||||||
|
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,17 +4,32 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
homeCfg = config.home;
|
vars = config.pam.sessionVariables;
|
||||||
|
|
||||||
in
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
{
|
options = {
|
||||||
options = {};
|
pam.sessionVariables = mkOption {
|
||||||
|
default = { };
|
||||||
|
type = types.attrs;
|
||||||
|
example = { EDITOR = "vim"; };
|
||||||
|
description = ''
|
||||||
|
Environment variables that will be set for the PAM session.
|
||||||
|
The variable values must be as described in
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>pam_env.conf</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum>
|
||||||
|
</citerefentry>.
|
||||||
|
</para><para>
|
||||||
|
Note, this option will become deprecated in the future and its use is
|
||||||
|
therefore discouraged.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = mkIf (homeCfg.sessionVariableSetter == "pam") {
|
config = mkIf (vars != { }) {
|
||||||
home.file.".pam_environment".text =
|
home.file.".pam_environment".text = concatStringsSep "\n"
|
||||||
concatStringsSep "\n" (
|
(mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') vars) + "\n";
|
||||||
mapAttrsToList (n: v: "${n} OVERRIDE=${v}") homeCfg.sessionVariables
|
|
||||||
) + "\n";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
121
modules/misc/qt.nix
Normal file
121
modules/misc/qt.nix
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.qt;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkChangedOptionModule [ "qt" "useGtkTheme" ] [ "qt" "platformTheme" ]
|
||||||
|
(config:
|
||||||
|
if getAttrFromPath [ "qt" "useGtkTheme" ] config then "gtk" else null))
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
qt = {
|
||||||
|
enable = mkEnableOption "Qt 4 and 5 configuration";
|
||||||
|
|
||||||
|
platformTheme = mkOption {
|
||||||
|
type = types.nullOr (types.enum [ "gtk" "gnome" ]);
|
||||||
|
default = null;
|
||||||
|
example = "gnome";
|
||||||
|
relatedPackages =
|
||||||
|
[ "qgnomeplatform" [ "libsForQt5" "qtstyleplugins" ] ];
|
||||||
|
description = ''
|
||||||
|
Selects the platform theme to use for Qt applications.</para>
|
||||||
|
<para>The options are
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>gtk</literal></term>
|
||||||
|
<listitem><para>Use GTK theme with
|
||||||
|
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>gnome</literal></term>
|
||||||
|
<listitem><para>Use GNOME theme with
|
||||||
|
<link xlink:href="https://github.com/FedoraQt/QGnomePlatform">qgnomeplatform</link>
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
style = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "adwaita-dark";
|
||||||
|
relatedPackages = [ "adwaita-qt" [ "libsForQt5" "qtstyleplugins" ] ];
|
||||||
|
description = ''
|
||||||
|
Selects the style to use for Qt5 applications.</para>
|
||||||
|
<para>The options are
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>adwaita</literal></term>
|
||||||
|
<term><literal>adwaita-dark</literal></term>
|
||||||
|
<listitem><para>Use Adwaita Qt style with
|
||||||
|
<link xlink:href="https://github.com/FedoraQt/adwaita-qt">adwaita</link>
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>cleanlooks</literal></term>
|
||||||
|
<term><literal>gtk2</literal></term>
|
||||||
|
<term><literal>motif</literal></term>
|
||||||
|
<term><literal>plastique</literal></term>
|
||||||
|
<listitem><para>Use styles from
|
||||||
|
<link xlink:href="https://github.com/qt/qtstyleplugins">qtstyleplugins</link>
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.nullOr types.package;
|
||||||
|
default = null;
|
||||||
|
example = literalExample "pkgs.adwaita-qt";
|
||||||
|
description = "Theme package to be used in Qt5 applications.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.enable && cfg.platformTheme != null) {
|
||||||
|
assertions = [{
|
||||||
|
assertion = (cfg.platformTheme == "gnome")
|
||||||
|
-> ((cfg.style.name != null) && (cfg.style.package != null));
|
||||||
|
message = ''
|
||||||
|
`qt.platformTheme` "gnome" must have `qt.style` set to a theme that
|
||||||
|
supports both Qt and Gtk, for example "adwaita" or "adwaita-dark".
|
||||||
|
'';
|
||||||
|
}];
|
||||||
|
|
||||||
|
# Necessary because home.sessionVariables is of types.attrs
|
||||||
|
home.sessionVariables = (filterAttrs (n: v: v != null) {
|
||||||
|
QT_QPA_PLATFORMTHEME =
|
||||||
|
if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
|
||||||
|
QT_STYLE_OVERRIDE = cfg.style.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
home.packages = if cfg.platformTheme == "gnome" then
|
||||||
|
[ pkgs.qgnomeplatform ]
|
||||||
|
++ lib.optionals (cfg.style.package != null) [ cfg.style.package ]
|
||||||
|
else
|
||||||
|
[ pkgs.libsForQt5.qtstyleplugins ];
|
||||||
|
|
||||||
|
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ]
|
||||||
|
++ lib.optionals (cfg.style != null) [ "QT_STYLE_OVERRIDE" ];
|
||||||
|
|
||||||
|
# Enable GTK+ style for Qt4 in either case.
|
||||||
|
# It doesn’t support the platform theme packages.
|
||||||
|
home.activation.useGtkThemeInQt4 = hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
$DRY_RUN_CMD ${pkgs.crudini}/bin/crudini $VERBOSE_ARG \
|
||||||
|
--set "${config.xdg.configHome}/Trolltech.conf" Qt style GTK+
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
32
modules/misc/submodule-support.nix
Normal file
32
modules/misc/submodule-support.nix
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
options.submoduleSupport = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Whether the Home Manager module system is used as a submodule
|
||||||
|
in, for example, NixOS or nix-darwin.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
externalPackageInstall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Whether the packages of <option>home.packages</option> are
|
||||||
|
installed separately from the Home Manager activation script.
|
||||||
|
In NixOS, for example, this may be accomplished by installing
|
||||||
|
the packages through
|
||||||
|
<option>users.users.‹name?›.packages</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
54
modules/misc/tmpfiles.nix
Normal file
54
modules/misc/tmpfiles.nix
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.systemd.user.tmpfiles;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ maintainers.dawidsowa ];
|
||||||
|
|
||||||
|
options.systemd.user.tmpfiles.rules = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "L /home/user/Documents - - - - /mnt/data/Documents" ];
|
||||||
|
description = ''
|
||||||
|
Rules for creating and cleaning up temporary files
|
||||||
|
automatically. See
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>tmpfiles.d</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum>
|
||||||
|
</citerefentry>
|
||||||
|
for the exact format.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.rules != [ ]) {
|
||||||
|
assertions = [
|
||||||
|
(hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs
|
||||||
|
platforms.linux)
|
||||||
|
];
|
||||||
|
|
||||||
|
xdg = {
|
||||||
|
dataFile."user-tmpfiles.d/home-manager.conf" = {
|
||||||
|
text = ''
|
||||||
|
# This file is created automatically and should not be modified.
|
||||||
|
# Please change the option ‘systemd.user.tmpfiles.rules’ instead.
|
||||||
|
${concatStringsSep "\n" cfg.rules}
|
||||||
|
'';
|
||||||
|
onChange = "${pkgs.systemd}/bin/systemd-tmpfiles --user --create";
|
||||||
|
};
|
||||||
|
configFile = {
|
||||||
|
"systemd/user/basic.target.wants/systemd-tmpfiles-setup.service".source =
|
||||||
|
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
|
||||||
|
"systemd/user/systemd-tmpfiles-setup.service".source =
|
||||||
|
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
|
||||||
|
"systemd/user/timers.target.wants/systemd-tmpfiles-clean.timer".source =
|
||||||
|
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.timer";
|
||||||
|
"systemd/user/systemd-tmpfiles-clean.service".source =
|
||||||
|
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
33
modules/misc/version.nix
Normal file
33
modules/misc/version.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
home.stateVersion = mkOption {
|
||||||
|
type = types.enum [
|
||||||
|
"18.09"
|
||||||
|
"19.03"
|
||||||
|
"19.09"
|
||||||
|
"20.03"
|
||||||
|
"20.09"
|
||||||
|
"21.03"
|
||||||
|
"21.05"
|
||||||
|
"21.11"
|
||||||
|
];
|
||||||
|
default = "18.09";
|
||||||
|
description = ''
|
||||||
|
It is occasionally necessary for Home Manager to change
|
||||||
|
configuration defaults in a way that is incompatible with
|
||||||
|
stateful data. This could, for example, include switching the
|
||||||
|
default data format or location of a file.
|
||||||
|
</para><para>
|
||||||
|
The <emphasis>state version</emphasis> indicates which default
|
||||||
|
settings are in effect and will therefore help avoid breaking
|
||||||
|
program configurations. Switching to a higher state version
|
||||||
|
typically requires performing some manual steps, such as data
|
||||||
|
conversion or moving files.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
51
modules/misc/vte.nix
Normal file
51
modules/misc/vte.nix
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
|
||||||
|
options.programs = let
|
||||||
|
description = ''
|
||||||
|
Whether to enable integration with terminals using the VTE
|
||||||
|
library. This will let the terminal track the current working
|
||||||
|
directory.
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
bash.enableVteIntegration = mkEnableOption "" // { inherit description; };
|
||||||
|
|
||||||
|
zsh.enableVteIntegration = mkEnableOption "" // { inherit description; };
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf config.programs.bash.enableVteIntegration {
|
||||||
|
# Unfortunately we have to do a little dance here to fix two
|
||||||
|
# problems with the upstream vte.sh file:
|
||||||
|
#
|
||||||
|
# - It does `PROMPT_COMMAND="__vte_prompt_command"` which
|
||||||
|
# clobbers any previously assigned prompt command.
|
||||||
|
#
|
||||||
|
# - Its `__vte_prompt_command` function runs commands that will
|
||||||
|
# overwrite the exit status of the command the user ran.
|
||||||
|
programs.bash.initExtra = ''
|
||||||
|
__HM_PROMPT_COMMAND="''${PROMPT_COMMAND:+''${PROMPT_COMMAND%;};}__hm_vte_prompt_command"
|
||||||
|
. ${pkgs.vte}/etc/profile.d/vte.sh
|
||||||
|
if [[ $(type -t __vte_prompt_command) = function ]]; then
|
||||||
|
__hm_vte_prompt_command() {
|
||||||
|
local old_exit_status=$?
|
||||||
|
__vte_prompt_command
|
||||||
|
return $old_exit_status
|
||||||
|
}
|
||||||
|
PROMPT_COMMAND="$__HM_PROMPT_COMMAND"
|
||||||
|
fi
|
||||||
|
unset __HM_PROMPT_COMMAND
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf config.programs.zsh.enableVteIntegration {
|
||||||
|
programs.zsh.initExtra = ''
|
||||||
|
. ${pkgs.vte}/etc/profile.d/vte.sh
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
183
modules/misc/xdg-desktop-entries.nix
Normal file
183
modules/misc/xdg-desktop-entries.nix
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
desktopEntry = {
|
||||||
|
options = {
|
||||||
|
# Since this module uses the nixpkgs/pkgs/build-support/make-desktopitem function,
|
||||||
|
# our options and defaults follow its parameters, with the following exceptions:
|
||||||
|
|
||||||
|
# `desktopName` on makeDesktopItem is controlled by `name`.
|
||||||
|
# This is what we'd commonly consider the name of the application.
|
||||||
|
# `name` on makeDesktopItem is controlled by this module's key in the attrset.
|
||||||
|
# This is the file's filename excluding ".desktop".
|
||||||
|
|
||||||
|
# `extraEntries` on makeDesktopItem is controlled by `extraConfig`,
|
||||||
|
# and `extraDesktopEntries` by `settings`,
|
||||||
|
# to match what's commonly used by other home manager modules.
|
||||||
|
|
||||||
|
# `startupNotify` on makeDesktopItem asks for "true" or "false" strings,
|
||||||
|
# for usability's sake we ask for a boolean.
|
||||||
|
|
||||||
|
# `mimeType` and `categories` on makeDesktopItem ask for a string in the format "one;two;three;",
|
||||||
|
# for the same reason we ask for a list of strings.
|
||||||
|
|
||||||
|
# Descriptions are taken from the desktop entry spec:
|
||||||
|
# https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys
|
||||||
|
|
||||||
|
type = mkOption {
|
||||||
|
description = "The type of the desktop entry.";
|
||||||
|
default = "Application";
|
||||||
|
type = types.enum [ "Application" "Link" "Directory" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
exec = mkOption {
|
||||||
|
description = "Program to execute, possibly with arguments.";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
icon = mkOption {
|
||||||
|
description = "Icon to display in file manager, menus, etc.";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
comment = mkOption {
|
||||||
|
description = "Tooltip for the entry.";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
terminal = mkOption {
|
||||||
|
description = "Whether the program runs in a terminal window.";
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
description = "Specific name of the application.";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
genericName = mkOption {
|
||||||
|
description = "Generic name of the application.";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
mimeType = mkOption {
|
||||||
|
description = "The MIME type(s) supported by this application.";
|
||||||
|
type = types.nullOr (types.listOf types.str);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
categories = mkOption {
|
||||||
|
description =
|
||||||
|
"Categories in which the entry should be shown in a menu.";
|
||||||
|
type = types.nullOr (types.listOf types.str);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
startupNotify = mkOption {
|
||||||
|
description = ''
|
||||||
|
If true, it is KNOWN that the application will send a "remove"
|
||||||
|
message when started with the <literal>DESKTOP_STARTUP_ID</literal>
|
||||||
|
environment variable set. If false, it is KNOWN that the application
|
||||||
|
does not work with startup notification at all.'';
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
description = ''
|
||||||
|
Extra configuration. Will be appended to the end of the file and
|
||||||
|
may thus contain extra sections.
|
||||||
|
'';
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.attrsOf types.string;
|
||||||
|
description = ''
|
||||||
|
Extra key-value pairs to add to the <literal>[Desktop Entry]</literal> section.
|
||||||
|
This may override other values.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
Keywords = "calc;math";
|
||||||
|
DBusActivatable = "false";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
fileValidation = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Whether to validate the generated desktop file.";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#formatting helpers
|
||||||
|
ifNotNull = a: a': if a == null then null else a';
|
||||||
|
stringBool = bool: if bool then "true" else "false";
|
||||||
|
semicolonList = list:
|
||||||
|
(concatStringsSep ";" list) + ";"; # requires trailing semicolon
|
||||||
|
|
||||||
|
#passes config options to makeDesktopItem in expected format
|
||||||
|
makeFile = name: config:
|
||||||
|
pkgs.makeDesktopItem {
|
||||||
|
name = name;
|
||||||
|
type = config.type;
|
||||||
|
exec = config.exec;
|
||||||
|
icon = config.icon;
|
||||||
|
comment = config.comment;
|
||||||
|
terminal = config.terminal;
|
||||||
|
desktopName = config.name;
|
||||||
|
genericName = config.genericName;
|
||||||
|
mimeType = ifNotNull config.mimeType (semicolonList config.mimeType);
|
||||||
|
categories =
|
||||||
|
ifNotNull config.categories (semicolonList config.categories);
|
||||||
|
startupNotify =
|
||||||
|
ifNotNull config.startupNotify (stringBool config.startupNotify);
|
||||||
|
extraEntries = config.extraConfig;
|
||||||
|
extraDesktopEntries = config.settings;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ cwyc ];
|
||||||
|
|
||||||
|
options.xdg.desktopEntries = mkOption {
|
||||||
|
description = ''
|
||||||
|
Desktop Entries allow applications to be shown in your desktop environment's app launcher. </para><para>
|
||||||
|
You can define entries for programs without entries or override existing entries. </para><para>
|
||||||
|
See <link xlink:href="https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys" /> for more information on options.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
type = types.attrsOf (types.submodule desktopEntry);
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
firefox = {
|
||||||
|
name = "Firefox";
|
||||||
|
genericName = "Web Browser";
|
||||||
|
exec = "firefox %U";
|
||||||
|
terminal = false;
|
||||||
|
categories = [ "Application" "Network" "WebBrowser" ];
|
||||||
|
mimeType = [ "text/html" "text/xml" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (config.xdg.desktopEntries != { }) {
|
||||||
|
assertions = [
|
||||||
|
(hm.assertions.assertPlatform "xdg.desktopEntries" pkgs platforms.linux)
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages = (map hiPrio # we need hiPrio to override existing entries
|
||||||
|
(attrsets.mapAttrsToList makeFile config.xdg.desktopEntries));
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
91
modules/misc/xdg-mime-apps.nix
Normal file
91
modules/misc/xdg-mime-apps.nix
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg.mimeApps;
|
||||||
|
|
||||||
|
strListOrSingleton = with types;
|
||||||
|
coercedTo (either (listOf str) str) toList (listOf str);
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ pacien ];
|
||||||
|
|
||||||
|
options.xdg.mimeApps = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to manage <filename>$XDG_CONFIG_HOME/mimeapps.list</filename>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The generated file is read-only.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# descriptions from
|
||||||
|
# https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-1.0.1.html
|
||||||
|
|
||||||
|
associations.added = mkOption {
|
||||||
|
type = types.attrsOf strListOrSingleton;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"mimetype1" = [ "foo1.desktop" "foo2.desktop" "foo3.desktop" ];
|
||||||
|
"mimetype2" = "foo4.desktop";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Defines additional associations of applications with
|
||||||
|
mimetypes, as if the .desktop file was listing this mimetype
|
||||||
|
in the first place.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
associations.removed = mkOption {
|
||||||
|
type = types.attrsOf strListOrSingleton;
|
||||||
|
default = { };
|
||||||
|
example = { "mimetype1" = "foo5.desktop"; };
|
||||||
|
description = ''
|
||||||
|
Removes associations of applications with mimetypes, as if the
|
||||||
|
.desktop file was <emphasis>not</emphasis> listing this
|
||||||
|
mimetype in the first place.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultApplications = mkOption {
|
||||||
|
type = types.attrsOf strListOrSingleton;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"mimetype1" = [ "default1.desktop" "default2.desktop" ];
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
The default application to be used for a given mimetype. This
|
||||||
|
is, for instance, the one that will be started when
|
||||||
|
double-clicking on a file in a file manager. If the
|
||||||
|
application is no longer installed, the next application in
|
||||||
|
the list is attempted, and so on.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions =
|
||||||
|
[ (hm.assertions.assertPlatform "xdg.mimeApps" pkgs platforms.linux) ];
|
||||||
|
|
||||||
|
# Deprecated but still used by some applications.
|
||||||
|
xdg.dataFile."applications/mimeapps.list".source =
|
||||||
|
config.xdg.configFile."mimeapps.list".source;
|
||||||
|
|
||||||
|
xdg.configFile."mimeapps.list".text =
|
||||||
|
let joinValues = mapAttrs (n: concatStringsSep ";");
|
||||||
|
in generators.toINI { } {
|
||||||
|
"Added Associations" = joinValues cfg.associations.added;
|
||||||
|
"Removed Associations" = joinValues cfg.associations.removed;
|
||||||
|
"Default Applications" = joinValues cfg.defaultApplications;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
60
modules/misc/xdg-mime.nix
Normal file
60
modules/misc/xdg-mime.nix
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg.mime;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
xdg.mime.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = pkgs.hostPlatform.isLinux;
|
||||||
|
defaultText =
|
||||||
|
literalExample "true if host platform is Linux, false otherwise";
|
||||||
|
description = ''
|
||||||
|
Whether to install programs and files to support the
|
||||||
|
XDG Shared MIME-info specification and XDG MIME Applications
|
||||||
|
specification at
|
||||||
|
<link xlink:href="https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html"/>
|
||||||
|
and
|
||||||
|
<link xlink:href="https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html"/>,
|
||||||
|
respectively.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.xdg.mime.enable {
|
||||||
|
assertions =
|
||||||
|
[ (hm.assertions.assertPlatform "xdg.mime" pkgs platforms.linux) ];
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
# Explicitly install package to provide basic mime types.
|
||||||
|
pkgs.shared-mime-info
|
||||||
|
|
||||||
|
# Make sure the target directories will be real directories.
|
||||||
|
(pkgs.runCommandLocal "dummy-xdg-mime-dirs1" { } ''
|
||||||
|
mkdir -p $out/share/{applications,mime/packages}
|
||||||
|
'')
|
||||||
|
(pkgs.runCommandLocal "dummy-xdg-mime-dirs2" { } ''
|
||||||
|
mkdir -p $out/share/{applications,mime/packages}
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
home.extraProfileCommands = ''
|
||||||
|
if [[ -w $out/share/mime && -w $out/share/mime/packages && -d $out/share/mime/packages ]]; then
|
||||||
|
XDG_DATA_DIRS=$out/share \
|
||||||
|
PKGSYSTEM_ENABLE_FSYNC=0 \
|
||||||
|
${pkgs.buildPackages.shared-mime-info}/bin/update-mime-database \
|
||||||
|
-V $out/share/mime > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -w $out/share/applications ]]; then
|
||||||
|
${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database \
|
||||||
|
$out/share/applications
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
61
modules/misc/xdg-system-dirs.nix
Normal file
61
modules/misc/xdg-system-dirs.nix
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg.systemDirs;
|
||||||
|
|
||||||
|
configDirs = concatStringsSep ":" cfg.config;
|
||||||
|
|
||||||
|
dataDirs = concatStringsSep ":" cfg.data;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ tadfisher ];
|
||||||
|
|
||||||
|
options.xdg.systemDirs = {
|
||||||
|
config = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample ''[ "/etc/xdg" ]'';
|
||||||
|
description = ''
|
||||||
|
Directory names to add to <envar>XDG_CONFIG_DIRS</envar>
|
||||||
|
in the user session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
data = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = literalExample ''[ "/usr/share" "/usr/local/share" ]'';
|
||||||
|
description = ''
|
||||||
|
Directory names to add to <envar>XDG_DATA_DIRS</envar>
|
||||||
|
in the user session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf (cfg.config != [ ] || cfg.data != [ ]) {
|
||||||
|
assertions = [
|
||||||
|
(hm.assertions.assertPlatform "xdg.systemDirs" pkgs platforms.linux)
|
||||||
|
];
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (cfg.config != [ ]) {
|
||||||
|
home.sessionVariables.XDG_CONFIG_DIRS =
|
||||||
|
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||||
|
|
||||||
|
systemd.user.sessionVariables.XDG_CONFIG_DIRS =
|
||||||
|
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (cfg.data != [ ]) {
|
||||||
|
home.sessionVariables.XDG_DATA_DIRS =
|
||||||
|
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||||
|
|
||||||
|
systemd.user.sessionVariables.XDG_DATA_DIRS =
|
||||||
|
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
124
modules/misc/xdg-user-dirs.nix
Normal file
124
modules/misc/xdg-user-dirs.nix
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg.userDirs;
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ pacien ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [
|
||||||
|
"xdg"
|
||||||
|
"userDirs"
|
||||||
|
"publicShare"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
options.xdg.userDirs = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to manage <filename>$XDG_CONFIG_HOME/user-dirs.dirs</filename>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The generated file is read-only.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Well-known directory list from
|
||||||
|
# https://gitlab.freedesktop.org/xdg/xdg-user-dirs/blob/master/man/user-dirs.dirs.xml
|
||||||
|
|
||||||
|
desktop = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Desktop";
|
||||||
|
description = "The Desktop directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
documents = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Documents";
|
||||||
|
description = "The Documents directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
download = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Downloads";
|
||||||
|
description = "The Downloads directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
music = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Music";
|
||||||
|
description = "The Music directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
pictures = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Pictures";
|
||||||
|
description = "The Pictures directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
publicShare = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Public";
|
||||||
|
description = "The Public share directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
templates = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Templates";
|
||||||
|
description = "The Templates directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
videos = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "$HOME/Videos";
|
||||||
|
description = "The Videos directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = { };
|
||||||
|
example = { XDG_MISC_DIR = "$HOME/Misc"; };
|
||||||
|
description = "Other user directories.";
|
||||||
|
};
|
||||||
|
|
||||||
|
createDirectories =
|
||||||
|
mkEnableOption "automatic creation of the XDG user directories";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
directories = {
|
||||||
|
XDG_DESKTOP_DIR = cfg.desktop;
|
||||||
|
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||||
|
XDG_DOWNLOAD_DIR = cfg.download;
|
||||||
|
XDG_MUSIC_DIR = cfg.music;
|
||||||
|
XDG_PICTURES_DIR = cfg.pictures;
|
||||||
|
XDG_PUBLICSHARE_DIR = cfg.publicShare;
|
||||||
|
XDG_TEMPLATES_DIR = cfg.templates;
|
||||||
|
XDG_VIDEOS_DIR = cfg.videos;
|
||||||
|
} // cfg.extraConfig;
|
||||||
|
in mkIf cfg.enable {
|
||||||
|
assertions =
|
||||||
|
[ (hm.assertions.assertPlatform "xdg.userDirs" pkgs platforms.linux) ];
|
||||||
|
|
||||||
|
xdg.configFile."user-dirs.dirs".text = let
|
||||||
|
# For some reason, these need to be wrapped with quotes to be valid.
|
||||||
|
wrapped = mapAttrs (_: value: ''"${value}"'') directories;
|
||||||
|
in generators.toKeyValue { } wrapped;
|
||||||
|
|
||||||
|
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||||||
|
|
||||||
|
home.activation = mkIf cfg.createDirectories {
|
||||||
|
createXdgUserDirectories = let
|
||||||
|
directoriesList = attrValues directories;
|
||||||
|
mkdir = (dir: ''$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "${dir}"'');
|
||||||
|
in lib.hm.dag.entryAfter [ "writeBoundary" ]
|
||||||
|
(strings.concatMapStringsSep "\n" mkdir directoriesList);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
108
modules/misc/xdg.nix
Normal file
108
modules/misc/xdg.nix
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
{ options, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.xdg;
|
||||||
|
|
||||||
|
fileType = (import ../lib/file-type.nix {
|
||||||
|
inherit (config.home) homeDirectory;
|
||||||
|
inherit lib pkgs;
|
||||||
|
}).fileType;
|
||||||
|
|
||||||
|
defaultCacheHome = "${config.home.homeDirectory}/.cache";
|
||||||
|
defaultConfigHome = "${config.home.homeDirectory}/.config";
|
||||||
|
defaultDataHome = "${config.home.homeDirectory}/.local/share";
|
||||||
|
|
||||||
|
getXdgDir = name: fallback:
|
||||||
|
let value = builtins.getEnv name;
|
||||||
|
in if value != "" then value else fallback;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.xdg = {
|
||||||
|
enable = mkEnableOption "management of XDG base directories";
|
||||||
|
|
||||||
|
cacheHome = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
defaultText = "~/.cache";
|
||||||
|
description = ''
|
||||||
|
Absolute path to directory holding application caches.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = mkOption {
|
||||||
|
type = fileType "<varname>xdg.configHome</varname>" cfg.configHome;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Attribute set of files to link into the user's XDG
|
||||||
|
configuration home.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configHome = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
defaultText = "~/.config";
|
||||||
|
description = ''
|
||||||
|
Absolute path to directory holding application configurations.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataFile = mkOption {
|
||||||
|
type = fileType "<varname>xdg.dataHome</varname>" cfg.dataHome;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Attribute set of files to link into the user's XDG
|
||||||
|
data home.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataHome = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
defaultText = "~/.local/share";
|
||||||
|
description = ''
|
||||||
|
Absolute path to directory holding application data.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf cfg.enable {
|
||||||
|
xdg.cacheHome = mkDefault defaultCacheHome;
|
||||||
|
xdg.configHome = mkDefault defaultConfigHome;
|
||||||
|
xdg.dataHome = mkDefault defaultDataHome;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
XDG_CACHE_HOME = cfg.cacheHome;
|
||||||
|
XDG_CONFIG_HOME = cfg.configHome;
|
||||||
|
XDG_DATA_HOME = cfg.dataHome;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
# Legacy non-deterministic setup.
|
||||||
|
(mkIf (!cfg.enable && versionOlder config.home.stateVersion "20.09") {
|
||||||
|
xdg.cacheHome = getXdgDir "XDG_CACHE_HOME" defaultCacheHome;
|
||||||
|
xdg.configHome = getXdgDir "XDG_CONFIG_HOME" defaultConfigHome;
|
||||||
|
xdg.dataHome = getXdgDir "XDG_DATA_HOME" defaultDataHome;
|
||||||
|
})
|
||||||
|
|
||||||
|
# "Modern" deterministic setup.
|
||||||
|
(mkIf (!cfg.enable && versionAtLeast config.home.stateVersion "20.09") {
|
||||||
|
xdg.cacheHome = mkDefault defaultCacheHome;
|
||||||
|
xdg.configHome = mkDefault defaultConfigHome;
|
||||||
|
xdg.dataHome = mkDefault defaultDataHome;
|
||||||
|
})
|
||||||
|
|
||||||
|
{
|
||||||
|
home.file = mkMerge [
|
||||||
|
(mapAttrs'
|
||||||
|
(name: file: nameValuePair "${config.xdg.configHome}/${name}" file)
|
||||||
|
cfg.configFile)
|
||||||
|
(mapAttrs'
|
||||||
|
(name: file: nameValuePair "${config.xdg.dataHome}/${name}" file)
|
||||||
|
cfg.dataFile)
|
||||||
|
{ "${config.xdg.cacheHome}/.keep".text = ""; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
254
modules/modules.nix
Normal file
254
modules/modules.nix
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
{ pkgs
|
||||||
|
|
||||||
|
# Note, this should be "the standard library" + HM extensions.
|
||||||
|
, lib
|
||||||
|
|
||||||
|
# Whether to enable module type checking.
|
||||||
|
, check ? true
|
||||||
|
|
||||||
|
# If disabled, the pkgs attribute passed to this function is used instead.
|
||||||
|
, useNixpkgsModule ? true }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
modules = [
|
||||||
|
./accounts/email.nix
|
||||||
|
./config/i18n.nix
|
||||||
|
./files.nix
|
||||||
|
./home-environment.nix
|
||||||
|
./i18n/input-method/default.nix
|
||||||
|
./manual.nix
|
||||||
|
./misc/dconf.nix
|
||||||
|
./misc/debug.nix
|
||||||
|
./misc/fontconfig.nix
|
||||||
|
./misc/gtk.nix
|
||||||
|
./misc/lib.nix
|
||||||
|
./misc/news.nix
|
||||||
|
./misc/numlock.nix
|
||||||
|
./misc/pam.nix
|
||||||
|
./misc/qt.nix
|
||||||
|
./misc/submodule-support.nix
|
||||||
|
./misc/tmpfiles.nix
|
||||||
|
./misc/version.nix
|
||||||
|
./misc/vte.nix
|
||||||
|
./misc/xdg-desktop-entries.nix
|
||||||
|
./misc/xdg-mime-apps.nix
|
||||||
|
./misc/xdg-mime.nix
|
||||||
|
./misc/xdg-system-dirs.nix
|
||||||
|
./misc/xdg-user-dirs.nix
|
||||||
|
./misc/xdg.nix
|
||||||
|
./programs/abook.nix
|
||||||
|
./programs/afew.nix
|
||||||
|
./programs/alacritty.nix
|
||||||
|
./programs/alot.nix
|
||||||
|
./programs/aria2.nix
|
||||||
|
./programs/astroid.nix
|
||||||
|
./programs/autojump.nix
|
||||||
|
./programs/autorandr.nix
|
||||||
|
./programs/bash.nix
|
||||||
|
./programs/bat.nix
|
||||||
|
./programs/beets.nix
|
||||||
|
./programs/broot.nix
|
||||||
|
./programs/browserpass.nix
|
||||||
|
./programs/chromium.nix
|
||||||
|
./programs/command-not-found/command-not-found.nix
|
||||||
|
./programs/dircolors.nix
|
||||||
|
./programs/direnv.nix
|
||||||
|
./programs/eclipse.nix
|
||||||
|
./programs/emacs.nix
|
||||||
|
./programs/exa.nix
|
||||||
|
./programs/feh.nix
|
||||||
|
./programs/firefox.nix
|
||||||
|
./programs/fish.nix
|
||||||
|
./programs/foot.nix
|
||||||
|
./programs/fzf.nix
|
||||||
|
./programs/getmail.nix
|
||||||
|
./programs/gh.nix
|
||||||
|
./programs/git.nix
|
||||||
|
./programs/gnome-terminal.nix
|
||||||
|
./programs/go.nix
|
||||||
|
./programs/gpg.nix
|
||||||
|
./programs/himalaya.nix
|
||||||
|
./programs/home-manager.nix
|
||||||
|
./programs/htop.nix
|
||||||
|
./programs/i3status-rust.nix
|
||||||
|
./programs/i3status.nix
|
||||||
|
./programs/info.nix
|
||||||
|
./programs/irssi.nix
|
||||||
|
./programs/jq.nix
|
||||||
|
./programs/kakoune.nix
|
||||||
|
./programs/keychain.nix
|
||||||
|
./programs/kitty.nix
|
||||||
|
./programs/lazygit.nix
|
||||||
|
./programs/lesspipe.nix
|
||||||
|
./programs/lf.nix
|
||||||
|
./programs/lieer.nix
|
||||||
|
./programs/lsd.nix
|
||||||
|
./programs/man.nix
|
||||||
|
./programs/mangohud.nix
|
||||||
|
./programs/matplotlib.nix
|
||||||
|
./programs/mbsync.nix
|
||||||
|
./programs/mcfly.nix
|
||||||
|
./programs/mercurial.nix
|
||||||
|
./programs/mpv.nix
|
||||||
|
./programs/msmtp.nix
|
||||||
|
./programs/mu.nix
|
||||||
|
./programs/ncmpcpp.nix
|
||||||
|
./programs/ncspot.nix
|
||||||
|
./programs/ne.nix
|
||||||
|
./programs/neomutt.nix
|
||||||
|
./programs/neovim.nix
|
||||||
|
./programs/newsboat.nix
|
||||||
|
./programs/nix-index.nix
|
||||||
|
./programs/noti.nix
|
||||||
|
./programs/notmuch.nix
|
||||||
|
./programs/nushell.nix
|
||||||
|
./programs/obs-studio.nix
|
||||||
|
./programs/octant.nix
|
||||||
|
./programs/offlineimap.nix
|
||||||
|
./programs/opam.nix
|
||||||
|
./programs/password-store.nix
|
||||||
|
./programs/pazi.nix
|
||||||
|
./programs/pet.nix
|
||||||
|
./programs/pidgin.nix
|
||||||
|
./programs/piston-cli.nix
|
||||||
|
./programs/powerline-go.nix
|
||||||
|
./programs/qutebrowser.nix
|
||||||
|
./programs/rbw.nix
|
||||||
|
./programs/readline.nix
|
||||||
|
./programs/rofi-pass.nix
|
||||||
|
./programs/rofi.nix
|
||||||
|
./programs/rtorrent.nix
|
||||||
|
./programs/sbt.nix
|
||||||
|
./programs/scmpuff.nix
|
||||||
|
./programs/senpai.nix
|
||||||
|
./programs/skim.nix
|
||||||
|
./programs/sm64ex.nix
|
||||||
|
./programs/ssh.nix
|
||||||
|
./programs/starship.nix
|
||||||
|
./programs/taskwarrior.nix
|
||||||
|
./programs/terminator.nix
|
||||||
|
./programs/termite.nix
|
||||||
|
./programs/texlive.nix
|
||||||
|
./programs/tmux.nix
|
||||||
|
./programs/topgrade.nix
|
||||||
|
./programs/urxvt.nix
|
||||||
|
./programs/vim.nix
|
||||||
|
./programs/vscode.nix
|
||||||
|
./programs/vscode/haskell.nix
|
||||||
|
./programs/waybar.nix
|
||||||
|
./programs/xmobar.nix
|
||||||
|
./programs/z-lua.nix
|
||||||
|
./programs/zathura.nix
|
||||||
|
./programs/zoxide.nix
|
||||||
|
./programs/zplug.nix
|
||||||
|
./programs/zsh.nix
|
||||||
|
./programs/zsh/prezto.nix
|
||||||
|
./services/barrier.nix
|
||||||
|
./services/blueman-applet.nix
|
||||||
|
./services/caffeine.nix
|
||||||
|
./services/cbatticon.nix
|
||||||
|
./services/clipmenu.nix
|
||||||
|
./services/compton.nix
|
||||||
|
./services/devilspie2.nix
|
||||||
|
./services/dropbox.nix
|
||||||
|
./services/dunst.nix
|
||||||
|
./services/dwm-status.nix
|
||||||
|
./services/emacs.nix
|
||||||
|
./services/etesync-dav.nix
|
||||||
|
./services/flameshot.nix
|
||||||
|
./services/fluidsynth.nix
|
||||||
|
./services/getmail.nix
|
||||||
|
./services/gnome-keyring.nix
|
||||||
|
./services/gpg-agent.nix
|
||||||
|
./services/grobi.nix
|
||||||
|
./services/hound.nix
|
||||||
|
./services/imapnotify.nix
|
||||||
|
./services/kanshi.nix
|
||||||
|
./services/kbfs.nix
|
||||||
|
./services/kdeconnect.nix
|
||||||
|
./services/keepassx.nix
|
||||||
|
./services/keybase.nix
|
||||||
|
./services/keynav.nix
|
||||||
|
./services/lieer.nix
|
||||||
|
./services/lorri.nix
|
||||||
|
./services/mako.nix
|
||||||
|
./services/mbsync.nix
|
||||||
|
./services/mpd.nix
|
||||||
|
./services/mpdris2.nix
|
||||||
|
./services/mpris-proxy.nix
|
||||||
|
./services/muchsync.nix
|
||||||
|
./services/network-manager-applet.nix
|
||||||
|
./services/nextcloud-client.nix
|
||||||
|
./services/owncloud-client.nix
|
||||||
|
./services/pantalaimon.nix
|
||||||
|
./services/parcellite.nix
|
||||||
|
./services/pass-secret-service.nix
|
||||||
|
./services/password-store-sync.nix
|
||||||
|
./services/pasystray.nix
|
||||||
|
./services/pbgopy.nix
|
||||||
|
./services/picom.nix
|
||||||
|
./services/plan9port.nix
|
||||||
|
./services/playerctld.nix
|
||||||
|
./services/polybar.nix
|
||||||
|
./services/poweralertd.nix
|
||||||
|
./services/pulseeffects.nix
|
||||||
|
./services/random-background.nix
|
||||||
|
./services/redshift-gammastep/gammastep.nix
|
||||||
|
./services/redshift-gammastep/redshift.nix
|
||||||
|
./services/rsibreak.nix
|
||||||
|
./services/screen-locker.nix
|
||||||
|
./services/spotifyd.nix
|
||||||
|
./services/stalonetray.nix
|
||||||
|
./services/status-notifier-watcher.nix
|
||||||
|
./services/sxhkd.nix
|
||||||
|
./services/syncthing.nix
|
||||||
|
./services/taffybar.nix
|
||||||
|
./services/trayer.nix
|
||||||
|
./services/tahoe-lafs.nix
|
||||||
|
./services/taskwarrior-sync.nix
|
||||||
|
./services/udiskie.nix
|
||||||
|
./services/unclutter.nix
|
||||||
|
./services/unison.nix
|
||||||
|
./services/volnoti.nix
|
||||||
|
./services/window-managers/awesome.nix
|
||||||
|
./services/window-managers/bspwm/default.nix
|
||||||
|
./services/window-managers/i3-sway/i3.nix
|
||||||
|
./services/window-managers/i3-sway/sway.nix
|
||||||
|
./services/window-managers/xmonad.nix
|
||||||
|
./services/wlsunset.nix
|
||||||
|
./services/xcape.nix
|
||||||
|
./services/xembed-sni-proxy.nix
|
||||||
|
./services/xidlehook.nix
|
||||||
|
./services/xscreensaver.nix
|
||||||
|
./services/xsettingsd.nix
|
||||||
|
./services/xsuspender.nix
|
||||||
|
./systemd.nix
|
||||||
|
./targets/darwin
|
||||||
|
./targets/generic-linux.nix
|
||||||
|
./xcursor.nix
|
||||||
|
./xresources.nix
|
||||||
|
./xsession.nix
|
||||||
|
(pkgs.path + "/nixos/modules/misc/assertions.nix")
|
||||||
|
(pkgs.path + "/nixos/modules/misc/meta.nix")
|
||||||
|
] ++ optional useNixpkgsModule ./misc/nixpkgs.nix;
|
||||||
|
|
||||||
|
pkgsModule = { config, ... }: {
|
||||||
|
config = {
|
||||||
|
_module.args.baseModules = modules;
|
||||||
|
_module.args.pkgsPath = lib.mkDefault
|
||||||
|
(if versionAtLeast config.home.stateVersion "20.09" then
|
||||||
|
pkgs.path
|
||||||
|
else
|
||||||
|
<nixpkgs>);
|
||||||
|
_module.args.pkgs = lib.mkDefault pkgs;
|
||||||
|
_module.check = check;
|
||||||
|
lib = lib.hm;
|
||||||
|
} // optionalAttrs useNixpkgsModule {
|
||||||
|
nixpkgs.system = mkDefault pkgs.system;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in modules ++ [ pkgsModule ]
|
||||||
44
modules/programs/abook.nix
Normal file
44
modules/programs/abook.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.abook;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.programs.abook = {
|
||||||
|
enable = mkEnableOption "Abook";
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
example = ''
|
||||||
|
field pager = Pager
|
||||||
|
view CONTACT = name, email
|
||||||
|
set autosave=true
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Extra lines added to <filename>$HOME/.config/abook/abookrc</filename>.
|
||||||
|
Available configuration options are described in the abook repository:
|
||||||
|
<link xlink:href="https://sourceforge.net/p/abook/git/ci/master/tree/sample.abookrc" />.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions =
|
||||||
|
[ (hm.assertions.assertPlatform "programs.abook" pkgs platforms.linux) ];
|
||||||
|
|
||||||
|
home.packages = [ pkgs.abook ];
|
||||||
|
|
||||||
|
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
||||||
|
text = ''
|
||||||
|
# Generated by Home Manager.
|
||||||
|
# See http://abook.sourceforge.net/
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
50
modules/programs/afew.nix
Normal file
50
modules/programs/afew.nix
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.afew;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.programs.afew = {
|
||||||
|
enable = mkEnableOption "the afew initial tagging script for Notmuch";
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = ''
|
||||||
|
[SpamFilter]
|
||||||
|
[KillThreadsFilter]
|
||||||
|
[ListMailsFilter]
|
||||||
|
[ArchiveSentMailsFilter]
|
||||||
|
[InboxFilter]
|
||||||
|
'';
|
||||||
|
example = ''
|
||||||
|
[SpamFilter]
|
||||||
|
|
||||||
|
[Filter.0]
|
||||||
|
query = from:pointyheaded@boss.com
|
||||||
|
tags = -new;+boss
|
||||||
|
message = Message from above
|
||||||
|
|
||||||
|
[InboxFilter]
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Extra lines added to afew configuration file. Available
|
||||||
|
configuration options are described in the afew manual:
|
||||||
|
<link xlink:href="https://afew.readthedocs.io/en/latest/configuration.html" />.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.afew ];
|
||||||
|
|
||||||
|
xdg.configFile."afew/config".text = ''
|
||||||
|
# Generated by Home Manager.
|
||||||
|
# See https://afew.readthedocs.io/
|
||||||
|
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
63
modules/programs/alacritty.nix
Normal file
63
modules/programs/alacritty.nix
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.alacritty;
|
||||||
|
yamlFormat = pkgs.formats.yaml { };
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
programs.alacritty = {
|
||||||
|
enable = mkEnableOption "Alacritty";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.alacritty;
|
||||||
|
defaultText = literalExample "pkgs.alacritty";
|
||||||
|
description = "The Alacritty package to install.";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = yamlFormat.type;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
window.dimensions = {
|
||||||
|
lines = 3;
|
||||||
|
columns = 200;
|
||||||
|
};
|
||||||
|
key_bindings = [
|
||||||
|
{
|
||||||
|
key = "K";
|
||||||
|
mods = "Control";
|
||||||
|
chars = "\\x0c";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Configuration written to
|
||||||
|
<filename>~/.config/alacritty/alacritty.yml</filename>. See
|
||||||
|
<link xlink:href="https://github.com/jwilm/alacritty/blob/master/alacritty.yml"/>
|
||||||
|
for the default configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
|
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) {
|
||||||
|
# TODO: Replace by the generate function but need to figure out how to
|
||||||
|
# handle the escaping first.
|
||||||
|
#
|
||||||
|
# source = yamlFormat.generate "alacritty.yml" cfg.settings;
|
||||||
|
|
||||||
|
text =
|
||||||
|
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
58
modules/programs/alot-accounts.nix
Normal file
58
modules/programs/alot-accounts.nix
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
pkgs:
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options.alot = {
|
||||||
|
sendMailCommand = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
Command to send a mail. If msmtp is enabled for the account,
|
||||||
|
then this is set to
|
||||||
|
<command>msmtpq --read-envelope-from --read-recipients</command>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
contactCompletion = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = {
|
||||||
|
type = "shellcommand";
|
||||||
|
command =
|
||||||
|
"'${pkgs.notmuch}/bin/notmuch address --format=json --output=recipients date:6M..'";
|
||||||
|
regexp = "'\\[?{" + ''
|
||||||
|
"name": "(?P<name>.*)", "address": "(?P<email>.+)", "name-addr": ".*"''
|
||||||
|
+ "}[,\\]]?'";
|
||||||
|
shellcommand_external_filtering = "False";
|
||||||
|
};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
type = "shellcommand";
|
||||||
|
command = "abook --mutt-query";
|
||||||
|
regexp = "'^(?P<email>[^@]+@[^\t]+)\t+(?P<name>[^\t]+)'";
|
||||||
|
ignorecase = "True";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Contact completion configuration as expected per alot.
|
||||||
|
See <link xlink:href="http://alot.readthedocs.io/en/latest/configuration/contacts_completion.html">alot's wiki</link> for
|
||||||
|
explanation about possible values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Extra settings to add to this Alot account configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.notmuch.enable {
|
||||||
|
alot.sendMailCommand = mkOptionDefault (if config.msmtp.enable then
|
||||||
|
"msmtpq --read-envelope-from --read-recipients"
|
||||||
|
else
|
||||||
|
null);
|
||||||
|
};
|
||||||
|
}
|
||||||
240
modules/programs/alot.nix
Normal file
240
modules/programs/alot.nix
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
# alot config loader is sensitive to leading space !
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.alot;
|
||||||
|
|
||||||
|
enabledAccounts =
|
||||||
|
filter (a: a.notmuch.enable) (attrValues config.accounts.email.accounts);
|
||||||
|
|
||||||
|
# sorted: primary first
|
||||||
|
alotAccounts = sort (a: b: !(a.primary -> b.primary)) enabledAccounts;
|
||||||
|
|
||||||
|
boolStr = v: if v then "True" else "False";
|
||||||
|
|
||||||
|
mkKeyValue = key: value:
|
||||||
|
let value' = if isBool value then boolStr value else toString value;
|
||||||
|
in "${key} = ${value'}";
|
||||||
|
|
||||||
|
mk2ndLevelSectionName = name: "[" + name + "]";
|
||||||
|
|
||||||
|
tagSubmodule = types.submodule {
|
||||||
|
options = {
|
||||||
|
translated = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
Fixed string representation for this tag. The tag can be
|
||||||
|
hidden from view, if the key translated is set to
|
||||||
|
<literal>""</literal>, the empty string.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
translation = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
A pair of strings that define a regular substitution to
|
||||||
|
compute the string representation on the fly using
|
||||||
|
<literal>re.sub</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
normal = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "'','', 'white','light red', 'white','#d66'";
|
||||||
|
description = ''
|
||||||
|
How to display the tag when unfocused.
|
||||||
|
See <link xlink:href="https://alot.readthedocs.io/en/latest/configuration/theming.html#tagstring-formatting"/>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
focus = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "How to display the tag when focused.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
accountStr = account:
|
||||||
|
with account;
|
||||||
|
concatStringsSep "\n" ([ "[[${name}]]" ]
|
||||||
|
++ mapAttrsToList (n: v: n + "=" + v) ({
|
||||||
|
address = address;
|
||||||
|
realname = realName;
|
||||||
|
sendmail_command =
|
||||||
|
optionalString (alot.sendMailCommand != null) alot.sendMailCommand;
|
||||||
|
sent_box = "maildir" + "://" + maildir.absPath + "/" + folders.sent;
|
||||||
|
draft_box = "maildir" + "://" + maildir.absPath + "/" + folders.drafts;
|
||||||
|
} // optionalAttrs (aliases != [ ]) {
|
||||||
|
aliases = concatStringsSep "," aliases;
|
||||||
|
} // optionalAttrs (gpg != null) {
|
||||||
|
gpg_key = gpg.key;
|
||||||
|
encrypt_by_default = if gpg.encryptByDefault then "all" else "none";
|
||||||
|
sign_by_default = boolStr gpg.signByDefault;
|
||||||
|
} // optionalAttrs (signature.showSignature != "none") {
|
||||||
|
signature = pkgs.writeText "signature.txt" signature.text;
|
||||||
|
signature_as_attachment = boolStr (signature.showSignature == "attach");
|
||||||
|
}) ++ [ alot.extraConfig ] ++ [ "[[[abook]]]" ]
|
||||||
|
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion);
|
||||||
|
|
||||||
|
configFile = let
|
||||||
|
bindingsToStr = attrSet:
|
||||||
|
concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${v}") attrSet);
|
||||||
|
in ''
|
||||||
|
# Generated by Home Manager.
|
||||||
|
# See http://alot.readthedocs.io/en/latest/configuration/config_options.html
|
||||||
|
|
||||||
|
${generators.toKeyValue { inherit mkKeyValue; } cfg.settings}
|
||||||
|
${cfg.extraConfig}
|
||||||
|
[tags]
|
||||||
|
'' + (let
|
||||||
|
submoduleToAttrs = m:
|
||||||
|
filterAttrs (name: v: name != "_module" && v != null) m;
|
||||||
|
in generators.toINI { mkSectionName = mk2ndLevelSectionName; }
|
||||||
|
(mapAttrs (name: x: submoduleToAttrs x) cfg.tags)) + ''
|
||||||
|
[bindings]
|
||||||
|
${bindingsToStr cfg.bindings.global}
|
||||||
|
|
||||||
|
[[bufferlist]]
|
||||||
|
${bindingsToStr cfg.bindings.bufferlist}
|
||||||
|
[[search]]
|
||||||
|
${bindingsToStr cfg.bindings.search}
|
||||||
|
[[envelope]]
|
||||||
|
${bindingsToStr cfg.bindings.envelope}
|
||||||
|
[[taglist]]
|
||||||
|
${bindingsToStr cfg.bindings.taglist}
|
||||||
|
[[thread]]
|
||||||
|
${bindingsToStr cfg.bindings.thread}
|
||||||
|
|
||||||
|
[accounts]
|
||||||
|
|
||||||
|
${concatStringsSep "\n\n" (map accountStr alotAccounts)}
|
||||||
|
'';
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
programs.alot = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
Whether to enable the Alot mail user agent. Alot uses the
|
||||||
|
Notmuch email system and will therefore be automatically
|
||||||
|
enabled for each email account that is managed by Notmuch.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hooks = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Content of the hooks file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
bindings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = {
|
||||||
|
global = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Global keybindings.";
|
||||||
|
};
|
||||||
|
|
||||||
|
bufferlist = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Bufferlist mode keybindings.";
|
||||||
|
};
|
||||||
|
|
||||||
|
search = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Search mode keybindings.";
|
||||||
|
};
|
||||||
|
|
||||||
|
envelope = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Envelope mode keybindings.";
|
||||||
|
};
|
||||||
|
|
||||||
|
taglist = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Taglist mode keybindings.";
|
||||||
|
};
|
||||||
|
|
||||||
|
thread = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Thread mode keybindings.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Keybindings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tags = mkOption {
|
||||||
|
type = types.attrsOf tagSubmodule;
|
||||||
|
default = { };
|
||||||
|
description = "How to display the tags.";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = with types;
|
||||||
|
let primitive = either (either (either str int) bool) float;
|
||||||
|
in attrsOf primitive;
|
||||||
|
default = {
|
||||||
|
initial_command = "search tag:inbox AND NOT tag:killed";
|
||||||
|
auto_remove_unread = true;
|
||||||
|
handle_mouse = true;
|
||||||
|
prefer_plaintext = true;
|
||||||
|
};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
auto_remove_unread = true;
|
||||||
|
ask_subject = false;
|
||||||
|
thread_indent_replies = 2;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Configuration options added to alot configuration file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Extra lines added to alot configuration file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts.email.accounts = mkOption {
|
||||||
|
type = with types; attrsOf (submodule (import ./alot-accounts.nix pkgs));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.alot ];
|
||||||
|
|
||||||
|
xdg.configFile."alot/config".text = configFile;
|
||||||
|
|
||||||
|
xdg.configFile."alot/hooks.py" = mkIf (cfg.hooks != "") {
|
||||||
|
text = ''
|
||||||
|
# Generated by Home Manager.
|
||||||
|
'' + cfg.hooks;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
61
modules/programs/aria2.nix
Normal file
61
modules/programs/aria2.nix
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.aria2;
|
||||||
|
|
||||||
|
formatLine = n: v:
|
||||||
|
let
|
||||||
|
formatValue = v:
|
||||||
|
if builtins.isBool v then
|
||||||
|
(if v then "true" else "false")
|
||||||
|
else
|
||||||
|
toString v;
|
||||||
|
in "${n}=${formatValue v}";
|
||||||
|
in {
|
||||||
|
meta.maintainers = [ hm.maintainers.justinlovinger ];
|
||||||
|
|
||||||
|
options.programs.aria2 = {
|
||||||
|
enable = mkEnableOption "aria2";
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = with types; attrsOf (oneOf [ bool float int str ]);
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Options to add to <filename>aria2.conf</filename> file.
|
||||||
|
See
|
||||||
|
<citerefentry>
|
||||||
|
<refentrytitle>aria2c</refentrytitle>
|
||||||
|
<manvolnum>1</manvolnum>
|
||||||
|
</citerefentry>
|
||||||
|
for options.
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
listen-port = 60000;
|
||||||
|
dht-listen-port = 60000;
|
||||||
|
seed-ratio = 1.0;
|
||||||
|
max-upload-limit = "50K";
|
||||||
|
ftp-pasv = true;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Extra lines added to <filename>aria2.conf</filename> file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.aria2 ];
|
||||||
|
|
||||||
|
xdg.configFile."aria2/aria2.conf".text = concatStringsSep "\n" ([ ]
|
||||||
|
++ mapAttrsToList formatLine cfg.settings
|
||||||
|
++ optional (cfg.extraConfig != "") cfg.extraConfig);
|
||||||
|
};
|
||||||
|
}
|
||||||
32
modules/programs/astroid-accounts.nix
Normal file
32
modules/programs/astroid-accounts.nix
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options.astroid = {
|
||||||
|
enable = mkEnableOption "Astroid";
|
||||||
|
|
||||||
|
sendMailCommand = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Command to send a mail. If msmtp is enabled for the account,
|
||||||
|
then this is set to
|
||||||
|
<command>msmtpq --read-envelope-from --read-recipients</command>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.attrsOf types.anything;
|
||||||
|
default = { };
|
||||||
|
example = { select_query = ""; };
|
||||||
|
description = ''
|
||||||
|
Extra settings to add to this astroid account configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.notmuch.enable {
|
||||||
|
astroid.sendMailCommand = mkIf config.msmtp.enable
|
||||||
|
(mkOptionDefault "msmtpq --read-envelope-from --read-recipients");
|
||||||
|
};
|
||||||
|
}
|
||||||
113
modules/programs/astroid-config-template.json
Normal file
113
modules/programs/astroid-config-template.json
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"astroid": {
|
||||||
|
"config": {
|
||||||
|
"version": "11"
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"dryrun_sending": "false"
|
||||||
|
},
|
||||||
|
"hints": {
|
||||||
|
"level": "0"
|
||||||
|
},
|
||||||
|
"log": {
|
||||||
|
"syslog": "false",
|
||||||
|
"stdout": "true",
|
||||||
|
"level": "info"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"startup": {
|
||||||
|
"queries": {
|
||||||
|
"inbox": "tag:inbox"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terminal": {
|
||||||
|
"height": "10",
|
||||||
|
"font_description": "default"
|
||||||
|
},
|
||||||
|
"thread_index": {
|
||||||
|
"page_jump_rows": "6",
|
||||||
|
"sort_order": "newest",
|
||||||
|
"cell": {
|
||||||
|
"font_description": "default",
|
||||||
|
"line_spacing": "2",
|
||||||
|
"date_length": "10",
|
||||||
|
"message_count_length": "4",
|
||||||
|
"authors_length": "20",
|
||||||
|
"subject_color": "#807d74",
|
||||||
|
"subject_color_selected": "#000000",
|
||||||
|
"background_color_selected": "",
|
||||||
|
"background_color_marked": "#fff584",
|
||||||
|
"background_color_marked_selected": "#bcb559",
|
||||||
|
"tags_length": "80",
|
||||||
|
"tags_upper_color": "#e5e5e5",
|
||||||
|
"tags_lower_color": "#333333",
|
||||||
|
"tags_alpha": "0.5",
|
||||||
|
"hidden_tags": "attachment,flagged,unread"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"time": {
|
||||||
|
"clock_format": "local",
|
||||||
|
"same_year": "%b %-e",
|
||||||
|
"diff_year": "%x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"charset": "utf-8",
|
||||||
|
"save_draft_on_force_quit": "true",
|
||||||
|
"attachment_words": "attach",
|
||||||
|
"attachment_directory": "~",
|
||||||
|
"markdown_processor": "marked"
|
||||||
|
},
|
||||||
|
"mail": {
|
||||||
|
"reply": {
|
||||||
|
"quote_line": "Excerpts from %1's message of %2:",
|
||||||
|
"mailinglist_reply_to_sender": "true"
|
||||||
|
},
|
||||||
|
"forward": {
|
||||||
|
"quote_line": "Forwarding %1's message of %2:",
|
||||||
|
"disposition": "inline"
|
||||||
|
},
|
||||||
|
"sent_tags": "sent",
|
||||||
|
"message_id_fqdn": "",
|
||||||
|
"message_id_user": "",
|
||||||
|
"user_agent": "default",
|
||||||
|
"send_delay": "2",
|
||||||
|
"close_on_success": "false",
|
||||||
|
"format_flowed": "false"
|
||||||
|
},
|
||||||
|
"poll": {
|
||||||
|
"interval": "60",
|
||||||
|
"always_full_refresh": "false"
|
||||||
|
},
|
||||||
|
"attachment": {
|
||||||
|
"external_open_cmd": "xdg-open"
|
||||||
|
},
|
||||||
|
"thread_view": {
|
||||||
|
"open_html_part_external": "false",
|
||||||
|
"preferred_type": "plain",
|
||||||
|
"preferred_html_only": "false",
|
||||||
|
"allow_remote_when_encrypted": "false",
|
||||||
|
"open_external_link": "xdg-open",
|
||||||
|
"default_save_directory": "~",
|
||||||
|
"indent_messages": "false",
|
||||||
|
"gravatar": {
|
||||||
|
"enable": "true"
|
||||||
|
},
|
||||||
|
"mark_unread_delay": "0.5",
|
||||||
|
"expand_flagged": "true"
|
||||||
|
},
|
||||||
|
"crypto": {
|
||||||
|
"gpg": {
|
||||||
|
"path": "gpg2",
|
||||||
|
"always_trust": "true",
|
||||||
|
"enabled": "true"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"saved_searches": {
|
||||||
|
"show_on_startup": "false",
|
||||||
|
"save_history": "true",
|
||||||
|
"history_lines_to_show": "15",
|
||||||
|
"history_lines": "1000"
|
||||||
|
}
|
||||||
|
}
|
||||||
127
modules/programs/astroid.nix
Normal file
127
modules/programs/astroid.nix
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
with builtins;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.programs.astroid;
|
||||||
|
|
||||||
|
jsonFormat = pkgs.formats.json { };
|
||||||
|
|
||||||
|
astroidAccounts =
|
||||||
|
filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts;
|
||||||
|
|
||||||
|
boolOpt = b: if b then "true" else "false";
|
||||||
|
|
||||||
|
accountAttr = account:
|
||||||
|
with account;
|
||||||
|
{
|
||||||
|
email = address;
|
||||||
|
name = realName;
|
||||||
|
sendmail = astroid.sendMailCommand;
|
||||||
|
additional_sent_tags = "";
|
||||||
|
default = boolOpt primary;
|
||||||
|
save_drafts_to = "${maildir.absPath}/${folders.drafts}";
|
||||||
|
save_sent = "true";
|
||||||
|
save_sent_to = "${maildir.absPath}/${folders.sent}";
|
||||||
|
select_query = "";
|
||||||
|
} // optionalAttrs (signature.showSignature != "none") {
|
||||||
|
signature_attach = boolOpt (signature.showSignature == "attach");
|
||||||
|
signature_default_on = boolOpt (signature.showSignature != "none");
|
||||||
|
signature_file = pkgs.writeText "signature.txt" signature.text;
|
||||||
|
signature_file_markdown = "false";
|
||||||
|
signature_separate = "true"; # prepends '--\n' to the signature
|
||||||
|
} // optionalAttrs (gpg != null) {
|
||||||
|
always_gpg_sign = boolOpt gpg.signByDefault;
|
||||||
|
gpgkey = gpg.key;
|
||||||
|
} // astroid.extraConfig;
|
||||||
|
|
||||||
|
# See https://github.com/astroidmail/astroid/wiki/Configuration-Reference
|
||||||
|
finalConfig = let
|
||||||
|
template = fromJSON (readFile ./astroid-config-template.json);
|
||||||
|
astroidConfig = foldl' recursiveUpdate template [
|
||||||
|
{
|
||||||
|
astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc";
|
||||||
|
accounts = mapAttrs (n: accountAttr) astroidAccounts;
|
||||||
|
crypto.gpg.path = "${pkgs.gnupg}/bin/gpg";
|
||||||
|
}
|
||||||
|
cfg.extraConfig
|
||||||
|
cfg.externalEditor
|
||||||
|
];
|
||||||
|
in astroidConfig;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
programs.astroid = {
|
||||||
|
enable = mkEnableOption "Astroid";
|
||||||
|
|
||||||
|
pollScript = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
example = "mbsync gmail";
|
||||||
|
description = ''
|
||||||
|
Script to run to fetch/update mails.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
externalEditor = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
# Converts it into JSON that can be merged into the configuration.
|
||||||
|
apply = cmd:
|
||||||
|
optionalAttrs (cmd != null) {
|
||||||
|
editor = {
|
||||||
|
"external_editor" = "true";
|
||||||
|
"cmd" = cmd;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
example =
|
||||||
|
"nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
|
||||||
|
description = ''
|
||||||
|
You can use <code>%1</code>, <code>%2</code>, and
|
||||||
|
<code>%3</code> to refer respectively to:
|
||||||
|
<orderedlist numeration="arabic">
|
||||||
|
<listitem><para>file name</para></listitem>
|
||||||
|
<listitem><para>server name</para></listitem>
|
||||||
|
<listitem><para>socket ID</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
See <link xlink:href='https://github.com/astroidmail/astroid/wiki/Customizing-editor' />.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = jsonFormat.type;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
poll.interval = 0;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
JSON config that will override the default Astroid configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts.email.accounts = mkOption {
|
||||||
|
type = with types; attrsOf (submodule (import ./astroid-accounts.nix));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.astroid ];
|
||||||
|
|
||||||
|
xdg.configFile."astroid/config".source =
|
||||||
|
jsonFormat.generate "astroid-config" finalConfig;
|
||||||
|
|
||||||
|
xdg.configFile."astroid/poll.sh" = {
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
# Generated by Home Manager
|
||||||
|
|
||||||
|
${cfg.pollScript}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user