mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-11 17:39:37 +08:00
Compare commits
528 Commits
release-18
...
release-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6f96b6aa3 | ||
|
|
4a8d628054 | ||
|
|
318bc0754e | ||
|
|
3a8e036f4a | ||
|
|
d8fdbbdf03 | ||
|
|
12620f7fd4 | ||
|
|
1710db409d | ||
|
|
ab911f44e6 | ||
|
|
3797004203 | ||
|
|
96fcf3b017 | ||
|
|
db21f23943 | ||
|
|
b49ababba0 | ||
|
|
7c0774ba0e | ||
|
|
cc69c3115f | ||
|
|
9fea5ac54f | ||
|
|
22d03f20fb | ||
|
|
c91b2f4556 | ||
|
|
25ddbf4824 | ||
|
|
a378bccd60 | ||
|
|
98fa8f63b8 | ||
|
|
9b5133529e | ||
|
|
2dd4c20f49 | ||
|
|
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 |
163
.github/CODEOWNERS
vendored
Normal file
163
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
* @rycee
|
||||
|
||||
/modules/home-environment.nix @rycee
|
||||
|
||||
/modules/misc/dconf.nix @gnidorah @rycee
|
||||
|
||||
/modules/misc/fontconfig.nix @rycee
|
||||
/tests/modules/misc/fontconfig @rycee
|
||||
|
||||
/modules/misc/gtk.nix @rycee
|
||||
|
||||
/modules/misc/news.nix @rycee
|
||||
|
||||
/modules/misc/pam.nix @rycee
|
||||
/tests/modules/misc/pam @rycee
|
||||
|
||||
/modules/misc/qt.nix @rycee
|
||||
|
||||
/modules/misc/submodule-support.nix @rycee
|
||||
|
||||
/modules/misc/xdg-mime-apps.nix @pacien
|
||||
|
||||
/modules/misc/xdg-user-dirs.nix @pacien
|
||||
|
||||
/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/firefox.nix @rycee
|
||||
|
||||
/modules/programs/git.nix @rycee
|
||||
|
||||
/modules/programs/gnome-terminal.nix @rycee
|
||||
|
||||
/modules/programs/go.nix @rvolosatovs
|
||||
|
||||
/modules/programs/home-manager.nix @rycee
|
||||
|
||||
/modules/programs/keychain.nix @marsam
|
||||
|
||||
/modules/programs/lesspipe.nix @rycee
|
||||
|
||||
/modules/programs/lieer.nix @tadfisher
|
||||
|
||||
/modules/programs/lsd.nix @marsam
|
||||
|
||||
/modules/programs/matplotlib.nix @rprospero
|
||||
|
||||
/modules/programs/mpv.nix @tadeokondrak
|
||||
|
||||
/modules/programs/noti.nix @marsam
|
||||
|
||||
/modules/programs/obs-studio.nix @adisbladis
|
||||
|
||||
/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/rtorrent.nix @marsam
|
||||
|
||||
/modules/programs/ssh.nix @rycee
|
||||
|
||||
/modules/programs/starship.nix @marsam
|
||||
|
||||
/modules/programs/texlive.nix @rycee
|
||||
|
||||
/modules/programs/z-lua.nix @marsam
|
||||
|
||||
/modules/programs/zathura.nix @rprospero
|
||||
|
||||
/modules/services/cbatticon.nix @pmiddend
|
||||
|
||||
/modules/services/dunst.nix @rycee
|
||||
|
||||
/modules/services/flameshot.nix @moredhel
|
||||
|
||||
/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/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/muchsync.nix @pacien
|
||||
|
||||
/modules/services/network-manager-applet.nix @rycee
|
||||
|
||||
/modules/services/parcellite.nix @gleber
|
||||
|
||||
/modules/services/password-store-sync.nix @pacien
|
||||
|
||||
/modules/services/pasystray.nix @pltanton
|
||||
|
||||
/modules/services/random-background.nix @rycee
|
||||
|
||||
/modules/services/redshift.nix @rycee
|
||||
|
||||
/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/udiskie.nix @rycee
|
||||
|
||||
/modules/services/unison.nix @pacien
|
||||
|
||||
/modules/services/xcape.nix @nickhu
|
||||
|
||||
/modules/services/xembed-sni-proxy.nix @rycee
|
||||
|
||||
/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
|
||||
34
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
34
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<!--
|
||||
|
||||
Please fill the description and checklist to the best of your
|
||||
ability.
|
||||
|
||||
-->
|
||||
|
||||
### Description
|
||||
|
||||
|
||||
|
||||
### Checklist
|
||||
|
||||
- [ ] Code formatted with `./format`.
|
||||
|
||||
- [ ] Code tested through `nix-shell --pure tests -A run.all`.
|
||||
|
||||
- [ ] Test cases updated/added. See [example](https://github.com/rycee/home-manager/commit/f3fbb50b68df20da47f9b0def5607857fcc0d021#diff-b61a6d542f9036550ba9c401c80f00ef).
|
||||
|
||||
- [ ] Commit messages are formatted like
|
||||
|
||||
```
|
||||
{component}: {description}
|
||||
|
||||
{long description}
|
||||
```
|
||||
|
||||
See [CONTRIBUTING](https://github.com/rycee/home-manager/blob/master/CONTRIBUTING.md#commits) for more information and [recent commit messages](https://github.com/rycee/home-manager/commits/master) for examples.
|
||||
|
||||
- If this PR adds a new module
|
||||
|
||||
- [ ] Added myself as module maintainer. See [example](https://github.com/rycee/home-manager/blob/068ff76a10e95820f886ac46957edcff4e44621d/modules/programs/lesspipe.nix#L6).
|
||||
|
||||
- [ ] Added myself and the module files to `.github/CODEOWNERS`.
|
||||
@@ -1,6 +1,23 @@
|
||||
image: nixos/nix:latest
|
||||
|
||||
variables:
|
||||
# Pinned 2020-01-01.
|
||||
NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/b0bbacb52134a7e731e549f4c0a7a2a39ca6b481.tar.gz"
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
Run tests:
|
||||
stage: test
|
||||
script:
|
||||
- nix-shell 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
|
||||
@@ -10,5 +27,18 @@ pages:
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- master
|
||||
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
|
||||
|
||||
@@ -4,10 +4,7 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
before_script:
|
||||
- mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
|
||||
- mkdir -p ~/.config/nixpkgs
|
||||
- echo "{}" > ~/.config/nixpkgs/home.nix
|
||||
|
||||
script:
|
||||
nix-shell . -A install
|
||||
- ./format -c
|
||||
- nix-shell . -A install
|
||||
- nix-shell --pure --max-jobs 10 tests -A run.all
|
||||
|
||||
@@ -91,12 +91,15 @@ In addition to the above commit message guidelines, try to follow the
|
||||
|
||||
### Style guidelines ###
|
||||
|
||||
The code in Home Manager should follow the [Nixpkgs syntax
|
||||
guidelines][]. Note, 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.
|
||||
The code in Home Manager is formatted by the [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.
|
||||
|
||||
Note, 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.
|
||||
|
||||
### News ###
|
||||
|
||||
@@ -139,15 +142,48 @@ If you do have a change worthy of a news entry then please add one in
|
||||
> use 'services.myservice.bar' instead.
|
||||
|
||||
- A new module, say `foo.nix`, should always include a news entry
|
||||
(without any condition) that has a message along the lines of
|
||||
that has a message along the lines of
|
||||
|
||||
> A new service is available: 'services.foo'.
|
||||
> A new module is available: 'services.foo'.
|
||||
|
||||
or
|
||||
If the module is platform specific, e.g., a service module using
|
||||
systemd, then a condition like
|
||||
|
||||
> A new program configuration is available: 'program.foo'.
|
||||
```
|
||||
condition = hostPlatform.isLinux;
|
||||
```
|
||||
|
||||
depending on the type of module.
|
||||
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.
|
||||
|
||||
### 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
|
||||
|
||||
```console
|
||||
$ nix-shell --pure tests -A run.all
|
||||
```
|
||||
|
||||
in the project root. List all test cases through
|
||||
|
||||
```console
|
||||
$ nix-shell --pure tests -A list
|
||||
```
|
||||
|
||||
and run an individual test, for example `alacritty-empty-settings`,
|
||||
through
|
||||
|
||||
```console
|
||||
$ nix-shell --pure tests -A run.alacritty-empty-settings
|
||||
```
|
||||
|
||||
[open issues]: https://github.com/rycee/home-manager/issues
|
||||
[new issue]: https://github.com/rycee/home-manager/issues/new
|
||||
@@ -155,4 +191,4 @@ If you do have a change worthy of a news entry then please add one in
|
||||
[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/rycee/home-manager/blob/master/modules/misc/news.nix
|
||||
[Nixpkgs syntax guidelines]: https://nixos.org/nixpkgs/manual/#sec-syntax
|
||||
[nixfmt]: https://github.com/serokell/nixfmt/
|
||||
|
||||
92
FAQ.md
92
FAQ.md
@@ -104,3 +104,95 @@ You can get some inspiration from the [Post your home-manager home.nix
|
||||
file!][1] Reddit thread.
|
||||
|
||||
[1]: https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/
|
||||
|
||||
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
|
||||
|
||||
services.dbus.packages = with pkgs; [ gnome3.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 then you can import the
|
||||
unstable Nixpkgs and refer to its packages within your configuration.
|
||||
Something like
|
||||
|
||||
```nix
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
home.packages = [
|
||||
pkgsUnstable.foo
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
```
|
||||
|
||||
should work provided you have a Nix channel called `nixpkgs-unstable`.
|
||||
Note, the package will not be affected by any package overrides,
|
||||
overlays, etc.
|
||||
|
||||
How do I override the package used by a module?
|
||||
-----------------------------------------------
|
||||
|
||||
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,
|
||||
|
||||
```
|
||||
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 [overlay][nixpkgs-overlays].
|
||||
|
||||
For example, if you want to use the `programs.skim` module but use
|
||||
the `skim` package from Nixpkgs unstable, then a configuration like
|
||||
|
||||
```nix
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
programs.skim.enable = true;
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
skim = pkgsUnstable.skim;
|
||||
})
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
```
|
||||
|
||||
should work OK.
|
||||
|
||||
[nixpkgs-overlays]: https://nixos.org/nixpkgs/manual/#chap-overlays
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2018 Robert Helgesson
|
||||
Copyright (c) 2017-2020 Robert Helgesson and Home Manager contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
119
README.md
119
README.md
@@ -6,6 +6,9 @@ using the [Nix][] package manager together with the Nix libraries
|
||||
found in [Nixpkgs][]. 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
|
||||
----------------
|
||||
|
||||
@@ -19,7 +22,7 @@ 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
|
||||
generation or from manual configuration.
|
||||
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 18.03 (the
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 20.03 (the
|
||||
current stable version), it may or may not work on other Linux
|
||||
distributions and NixOS versions.
|
||||
|
||||
@@ -31,73 +34,72 @@ on how to manually perform a rollback.
|
||||
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.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
You can chat with us on IRC in the channel [#home-manager][] on
|
||||
[freenode][]. The [channel logs][] are hosted courtesy of
|
||||
[samueldr][].
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Currently the easiest way to install Home Manager is as follows:
|
||||
|
||||
1. Make sure you have a working Nix installation. If you are not
|
||||
using NixOS then you may here have to run
|
||||
|
||||
```console
|
||||
$ mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
|
||||
```
|
||||
|
||||
since Home Manager uses these directories to manage your profile
|
||||
generations. On NixOS these should already be available.
|
||||
|
||||
Also 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`. 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
|
||||
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
|
||||
[`allowed-users`][nixAllowedUsers] Nix option. On NixOS you can
|
||||
control this option using the
|
||||
[`nix.allowedUsers`][nixosAllowedUsers] system option.
|
||||
|
||||
2. Assign a temporary variable holding the URL to the appropriate
|
||||
archive. Typically this is
|
||||
2. Add the appropriate Home Manager channel. Typically this is
|
||||
|
||||
```console
|
||||
$ HM_PATH=https://github.com/rycee/home-manager/archive/master.tar.gz
|
||||
$ nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
if you are following Nixpkgs master or an unstable channel and
|
||||
|
||||
```console
|
||||
$ HM_PATH=https://github.com/rycee/home-manager/archive/release-18.03.tar.gz
|
||||
$ nix-channel --add https://github.com/rycee/home-manager/archive/release-20.03.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
if you follow a Nixpkgs version 18.03 channel.
|
||||
if you follow a Nixpkgs version 20.03 channel.
|
||||
|
||||
3. Create an initial Home Manager configuration file:
|
||||
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
|
||||
|
||||
```shell
|
||||
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||
```
|
||||
|
||||
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
|
||||
$ cat > ~/.config/nixpkgs/home.nix <<EOF
|
||||
{
|
||||
programs.home-manager.enable = true;
|
||||
programs.home-manager.path = $HM_PATH;
|
||||
}
|
||||
EOF
|
||||
$ nix-shell '<home-manager>' -A install
|
||||
```
|
||||
|
||||
4. Install Home Manager and create the first Home Manager generation:
|
||||
Once finished, Home Manager should be active and available in your
|
||||
user environment.
|
||||
|
||||
```console
|
||||
$ nix-shell $HM_PATH -A install
|
||||
```
|
||||
|
||||
Home Manager should now be active and available in your user
|
||||
environment.
|
||||
|
||||
5. If you do not plan on having Home Manager manage your shell
|
||||
3. If you do not plan on having Home Manager manage your shell
|
||||
configuration then you must source the
|
||||
|
||||
```
|
||||
"$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
```
|
||||
|
||||
file in your shell configuration. Unfortunately, we currently only
|
||||
support POSIX.2-like shells such as [Bash][] or [Z shell][].
|
||||
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
|
||||
|
||||
@@ -107,11 +109,10 @@ Currently the easiest way to install Home Manager is as follows:
|
||||
|
||||
to your `~/.profile` file.
|
||||
|
||||
Note, because the `HM_PATH` variable above points to the live Home
|
||||
Manager repository you will automatically get updates whenever you
|
||||
build a new generation. If you dislike automatic updates then perform
|
||||
a Git clone of the desired branch and instead do the above steps with
|
||||
`HM_PATH` set to the _absolute path_ of your clone.
|
||||
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
|
||||
-----
|
||||
@@ -148,7 +149,13 @@ To satisfy the above setup we should elaborate the
|
||||
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
enableIcedTea = true;
|
||||
profiles = {
|
||||
myprofile = {
|
||||
settings = {
|
||||
"general.smoothScroll" = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.gpg-agent = {
|
||||
@@ -232,7 +239,7 @@ such collision is detected the activation will terminate before
|
||||
changing anything on your computer.
|
||||
|
||||
For example, suppose you have a wonderful, painstakingly created
|
||||
`~/.gitconfig` and add
|
||||
`~/.config/git/config` and add
|
||||
|
||||
```nix
|
||||
{
|
||||
@@ -293,6 +300,17 @@ in your system configuration and
|
||||
|
||||
in your Home Manager configuration.
|
||||
|
||||
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-20.03`). 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/
|
||||
[NixOS]: https://nixos.org/
|
||||
@@ -300,4 +318,9 @@ in your Home Manager configuration.
|
||||
[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://rycee.gitlab.io/home-manager/
|
||||
[configuration options]: https://rycee.gitlab.io/home-manager/options.html
|
||||
[#home-manager]: https://webchat.freenode.net/?url=irc%3A%2F%2Firc.freenode.net%2Fhome-manager
|
||||
[freenode]: https://freenode.net/
|
||||
[channel logs]: https://logs.nix.samueldr.com/home-manager/
|
||||
[samueldr]: https://github.com/samueldr/
|
||||
|
||||
12
default.nix
12
default.nix
@@ -1,14 +1,10 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
rec {
|
||||
home-manager = import ./home-manager {
|
||||
inherit pkgs;
|
||||
path = toString ./.;
|
||||
};
|
||||
home-manager = pkgs.callPackage ./home-manager { path = toString ./.; };
|
||||
|
||||
install = import ./home-manager/install.nix {
|
||||
inherit home-manager pkgs;
|
||||
};
|
||||
install =
|
||||
pkgs.callPackage ./home-manager/install.nix { inherit home-manager; };
|
||||
|
||||
nixos = import ./nixos;
|
||||
}
|
||||
|
||||
361
doc/default.nix
361
doc/default.nix
@@ -1,327 +1,68 @@
|
||||
{ pkgs, options, config, version, revision, extraSources ? [] }:
|
||||
|
||||
with pkgs;
|
||||
{
|
||||
# Note, this should be "the standard library" + HM extensions.
|
||||
lib, pkgs }:
|
||||
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Remove invisible and internal options.
|
||||
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
||||
nmdSrc = pkgs.fetchFromGitLab {
|
||||
name = "nmd";
|
||||
owner = "rycee";
|
||||
repo = "nmd";
|
||||
rev = "49567e3ff2824ac8ba457f439f384eafc1eb4547";
|
||||
sha256 = "0x2lwcryvmnr128r497bzrawi4x1yyxb4riicppdaib95iwn8jck";
|
||||
};
|
||||
|
||||
# Replace functions by the string <function>
|
||||
substFunction = x:
|
||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||
else if builtins.isList x then map substFunction x
|
||||
else if lib.isFunction x then "<function>"
|
||||
else x;
|
||||
nmd = import nmdSrc { inherit lib pkgs; };
|
||||
|
||||
# Generate DocBook documentation for a list of packages. This is
|
||||
# what `relatedPackages` option of `mkOption` from
|
||||
# ../../../lib/options.nix influences.
|
||||
#
|
||||
# Each element of `relatedPackages` can be either
|
||||
# - a string: that will be interpreted as an attribute name from `pkgs`,
|
||||
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
||||
# - an attrset: that can specify `name`, `path`, `package`, `comment`
|
||||
# (either of `name`, `path` is required, the rest are optional).
|
||||
genRelatedPackages = packages:
|
||||
let
|
||||
unpack = p: if lib.isString p then { name = p; }
|
||||
else if lib.isList p then { path = p; }
|
||||
else p;
|
||||
describe = args:
|
||||
let
|
||||
name = args.name or (lib.concatStringsSep "." args.path);
|
||||
path = args.path or [ args.name ];
|
||||
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
|
||||
in "<listitem>"
|
||||
+ "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
|
||||
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
|
||||
+ ": ${package.meta.description or "???"}.</para>"
|
||||
+ lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
|
||||
# Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
|
||||
+ lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
|
||||
+ "</listitem>";
|
||||
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
|
||||
# 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 { };
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
|
||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||
declarations = map stripAnyPrefixes opt.declarations;
|
||||
}
|
||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
||||
// lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
|
||||
hmModulesDocs = nmd.buildModulesDocs {
|
||||
modules = import ../modules/modules.nix {
|
||||
inherit lib pkgs;
|
||||
check = false;
|
||||
} ++ [ scrubbedPkgsModule ];
|
||||
moduleRootPaths = [ ./.. ];
|
||||
mkModuleUrl = path:
|
||||
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
|
||||
channelName = "home-manager";
|
||||
docBook.id = "home-manager-options";
|
||||
};
|
||||
|
||||
# We need to strip references to /nix/store/* from options,
|
||||
# including any `extraSources` if some modules came from elsewhere,
|
||||
# or else the build will fail.
|
||||
#
|
||||
# E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
|
||||
# you'd need to include `extraSources = [ pkgs.customModules ]`
|
||||
prefixesToStrip = map (p: "${toString p}/") ([ ./.. ] ++ extraSources);
|
||||
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
|
||||
|
||||
# Custom "less" that pushes up all the things ending in ".enable*"
|
||||
# and ".package*"
|
||||
optionLess = a: b:
|
||||
let
|
||||
ise = lib.hasPrefix "enable";
|
||||
isp = lib.hasPrefix "package";
|
||||
cmp = lib.splitByAndCompare ise lib.compare
|
||||
(lib.splitByAndCompare isp lib.compare lib.compare);
|
||||
in lib.compareLists cmp a.loc b.loc < 0;
|
||||
|
||||
# Customly sort option list for the man page.
|
||||
optionsList = lib.sort optionLess optionsListDesc;
|
||||
|
||||
# Convert the list of options into an XML file.
|
||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
|
||||
|
||||
optionsDocBook = runCommand "options-db.xml"
|
||||
{
|
||||
nativeBuildInputs = [ buildPackages.libxslt.bin ];
|
||||
}
|
||||
''
|
||||
optionsXML=${optionsXML}
|
||||
xsltproc \
|
||||
--stringparam program 'home-manager' \
|
||||
--stringparam revision '${revision}' \
|
||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
||||
'';
|
||||
|
||||
sources = lib.sourceFilesBySuffices ./. [".xml"];
|
||||
|
||||
modulesDoc = builtins.toFile "modules.xml" ''
|
||||
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules">
|
||||
${(lib.concatMapStrings (path: ''
|
||||
<xi:include href="${path}" />
|
||||
'') (lib.catAttrs "value" config.meta.doc))}
|
||||
</section>
|
||||
'';
|
||||
|
||||
generatedSources = runCommand "generated-docbook" {} ''
|
||||
mkdir $out
|
||||
ln -s ${modulesDoc} $out/modules.xml
|
||||
ln -s ${optionsDocBook} $out/options-db.xml
|
||||
printf "%s" "${version}" > $out/version
|
||||
'';
|
||||
|
||||
copySources =
|
||||
''
|
||||
cp -prd $sources/* . # */
|
||||
ln -s ${generatedSources} ./generated
|
||||
chmod -R u+w .
|
||||
'';
|
||||
|
||||
toc = builtins.toFile "toc.xml"
|
||||
''
|
||||
<toc role="chunk-toc">
|
||||
docs = nmd.buildDocBookDocs {
|
||||
pathName = "home-manager";
|
||||
modulesDocs = [ hmModulesDocs ];
|
||||
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-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
||||
<d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
|
||||
</d:tocentry>
|
||||
</toc>
|
||||
'';
|
||||
};
|
||||
|
||||
manualXsltprocOptions = toString [
|
||||
"--param section.autolabel 1"
|
||||
"--param section.label.includes.component.label 1"
|
||||
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
|
||||
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
|
||||
"--param xref.with.number.and.title 1"
|
||||
"--param toc.section.depth 3"
|
||||
"--stringparam admon.style ''"
|
||||
"--stringparam callout.graphics.extension .svg"
|
||||
"--stringparam current.docid manual"
|
||||
"--param chunk.section.depth 0"
|
||||
"--param chunk.first.sections 1"
|
||||
"--param use.id.as.filename 1"
|
||||
"--stringparam generate.toc 'book toc appendix toc'"
|
||||
"--stringparam chunk.toc ${toc}"
|
||||
];
|
||||
in {
|
||||
inherit nmdSrc;
|
||||
|
||||
manual-combined = runCommand "home-manager-manual-combined"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The Home Manager manual as plain docbook XML";
|
||||
}
|
||||
''
|
||||
${copySources}
|
||||
options = {
|
||||
json = hmModulesDocs.json.override {
|
||||
path = "share/doc/home-manager/options.json";
|
||||
};
|
||||
};
|
||||
|
||||
xmllint --xinclude --output ./manual-combined.xml ./manual.xml
|
||||
xmllint --xinclude --noxincludenode \
|
||||
--output ./man-pages-combined.xml ./man-pages.xml
|
||||
|
||||
# outputs the context of an xmllint error output
|
||||
# LEN lines around the failing line are printed
|
||||
function context {
|
||||
# length of context
|
||||
local LEN=6
|
||||
# lines to print before error line
|
||||
local BEFORE=4
|
||||
|
||||
# xmllint output lines are:
|
||||
# file.xml:1234: there was an error on line 1234
|
||||
while IFS=':' read -r file line rest; do
|
||||
echo
|
||||
if [[ -n "$rest" ]]; then
|
||||
echo "$file:$line:$rest"
|
||||
local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1))
|
||||
# number lines & filter context
|
||||
nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p"
|
||||
else
|
||||
if [[ -n "$line" ]]; then
|
||||
echo "$file:$line"
|
||||
else
|
||||
echo "$file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function lintrng {
|
||||
xmllint --debug --noout --nonet \
|
||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||
"$1" \
|
||||
2>&1 | context 1>&2
|
||||
# ^ redirect assumes xmllint doesn’t print to stdout
|
||||
}
|
||||
|
||||
lintrng manual-combined.xml
|
||||
lintrng man-pages-combined.xml
|
||||
|
||||
mkdir $out
|
||||
cp manual-combined.xml $out/
|
||||
cp man-pages-combined.xml $out/
|
||||
'';
|
||||
|
||||
olinkDB = runCommand "manual-olinkdb"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
}
|
||||
''
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam collect.xref.targets only \
|
||||
--stringparam targets.filename "$out/manual.db" \
|
||||
--nonet \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
cat > "$out/olinkdb.xml" <<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE targetset SYSTEM
|
||||
"file://${docbook5_xsl}/xml/xsl/docbook/common/targetdatabase.dtd" [
|
||||
<!ENTITY manualtargets SYSTEM "file://$out/manual.db">
|
||||
]>
|
||||
<targetset>
|
||||
<targetsetinfo>
|
||||
Allows for cross-referencing olinks between the manpages
|
||||
and manual.
|
||||
</targetsetinfo>
|
||||
|
||||
<document targetdoc="manual">&manualtargets;</document>
|
||||
</targetset>
|
||||
EOF
|
||||
'';
|
||||
|
||||
in rec {
|
||||
inherit generatedSources;
|
||||
|
||||
# The Home Manager options in JSON format.
|
||||
optionsJSON = runCommand "options-json"
|
||||
{ meta.description = "List of Home Manager options in JSON format";
|
||||
}
|
||||
''
|
||||
# Export list of options in different format.
|
||||
dst=$out/share/doc/home-manager
|
||||
mkdir -p $dst
|
||||
|
||||
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
|
||||
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
|
||||
} $dst/options.json
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
|
||||
# Generate the Home Manager manual.
|
||||
manual = runCommand "home-manager-manual"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The Home Manager manual in HTML format";
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
# Generate the HTML manual.
|
||||
dst=$out/share/doc/home-manager
|
||||
mkdir -p $dst
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--nonet --output $dst/ \
|
||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
mkdir -p $dst/images/callouts
|
||||
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
|
||||
|
||||
cp ${./style.css} $dst/style.css
|
||||
cp ${./overrides.css} $dst/overrides.css
|
||||
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
|
||||
echo "doc manual $dst" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
|
||||
|
||||
manualEpub = runCommand "home-manager-manual-epub"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2.bin libxslt.bin zip ];
|
||||
}
|
||||
''
|
||||
# Generate the epub manual.
|
||||
dst=$out/share/doc/home-manager
|
||||
|
||||
xsltproc \
|
||||
${manualXsltprocOptions} \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
--nonet --xinclude --output $dst/epub/ \
|
||||
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
|
||||
${manual-combined}/manual-combined.xml
|
||||
|
||||
mkdir -p $dst/epub/OEBPS/images/callouts
|
||||
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
|
||||
echo "application/epub+zip" > mimetype
|
||||
manual="$dst/home-manager-manual.epub"
|
||||
zip -0Xq "$manual" mimetype
|
||||
cd $dst/epub && zip -Xr9D "$manual" *
|
||||
|
||||
rm -rf $dst/epub
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
|
||||
|
||||
# Generate the Home Manager manpages.
|
||||
manpages = runCommand "home-manager-manpages"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
# Generate manpages.
|
||||
mkdir -p $out/share/man
|
||||
xsltproc --nonet \
|
||||
--param man.output.in.separate.dir 1 \
|
||||
--param man.output.base.dir "'$out/share/man/'" \
|
||||
--param man.endnotes.are.numbered 0 \
|
||||
--param man.break.after.slash 1 \
|
||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
||||
${manual-combined}/man-pages-combined.xml
|
||||
'';
|
||||
manPages = docs.manPages;
|
||||
|
||||
manual = { inherit (docs) html htmlOpenTool; };
|
||||
}
|
||||
|
||||
317
doc/installation.xml
Normal file
317
doc/installation.xml
Normal file
@@ -0,0 +1,317 @@
|
||||
<chapter 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="ch-installation">
|
||||
<title>Installing Home Manager</title>
|
||||
<para>
|
||||
Home Manager can be used in three primary ways:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Using the standalone <command>home-manager</command> 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
|
||||
<xref linkend="sec-install-standalone"/> for instructions on how to
|
||||
perform this installation.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
As a module within a NixOS system configuration. This allows the user
|
||||
profiles to be built together with the system when running
|
||||
<command>nixos-rebuild</command>. See
|
||||
<xref linkend="sec-install-nixos-module"/> for a description of this
|
||||
setup.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
As a module within a
|
||||
<link xlink:href="https://github.com/LnL7/nix-darwin/">nix-darwin</link>
|
||||
system configuration. This allows the user profiles to be built together
|
||||
with the system when running <command>darwin-rebuild</command>. See
|
||||
<xref linkend="sec-install-nix-darwin-module"/> for a description of this
|
||||
setup.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<section xml:id="sec-install-standalone">
|
||||
<title>Standalone installation</title>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
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 <literal>nix-instantiate '<nixpkgs>' -A hello</literal>
|
||||
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
|
||||
<link xlink:href="https://nixos.org/nix/manual/#conf-allowed-users"><literal>allowed-users</literal></link>
|
||||
Nix option. On NixOS you can control this option using the
|
||||
<link xlink:href="https://nixos.org/nixos/manual/options.html#opt-nix.allowedUsers"><literal>nix.allowedUsers</literal></link>
|
||||
system option.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Add the Home Manager channel that you wish to follow. This is done by
|
||||
running
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager</userinput>
|
||||
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
if you are following Nixpkgs master or an unstable channel and
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-20.03.tar.gz home-manager</userinput>
|
||||
<prompt>$</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
if you follow a Nixpkgs version 20.03 channel.
|
||||
</para>
|
||||
<para>
|
||||
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
|
||||
<programlisting language="bash">
|
||||
export NIX_PATH=$HOME/.nix-defexpr/channels${NIX_PATH:+:}$NIX_PATH
|
||||
</programlisting>
|
||||
to your shell (see
|
||||
<link xlink:href="https://github.com/NixOS/nix/issues/2033">nix#2033</link>).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Run the Home Manager installation command and create the first Home
|
||||
Manager generation:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>nix-shell '<home-manager>' -A install</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
Once finished, Home Manager should be active and available in your user
|
||||
environment.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you do not plan on having Home Manager manage your shell configuration
|
||||
then you must source the
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
|
||||
</programlisting>
|
||||
<para>
|
||||
file in your shell configuration. Unfortunately, we currently only support
|
||||
POSIX.2-like shells such as
|
||||
<link xlink:href="https://www.gnu.org/software/bash/">Bash</link> or
|
||||
<link xlink:href="http://zsh.sourceforge.net/">Z shell</link>.
|
||||
</para>
|
||||
<para>
|
||||
For example, if you use Bash then add
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
|
||||
</programlisting>
|
||||
<para>
|
||||
to your <literal>~/.profile</literal> file.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
If instead of using channels you want to run Home Manager from a Git
|
||||
checkout of the repository then you can use the
|
||||
<literal>programs.home-manager.path</literal> option to specify the absolute
|
||||
path to the repository.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="sec-install-nixos-module">
|
||||
<title>NixOS module</title>
|
||||
|
||||
<para>
|
||||
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 <command>home-manager</command> tool. It also
|
||||
opens up additional possibilities, for example, to automatically configure
|
||||
user environments in NixOS declarative containers or on systems deployed
|
||||
through NixOps.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To make the NixOS module available for use you must <option>import</option>
|
||||
it into your system configuration. This is most conveniently done by adding
|
||||
a Home Manager channel, for example
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager</userinput>
|
||||
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
if you are following Nixpkgs master or an unstable channel and
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-20.03.tar.gz home-manager</userinput>
|
||||
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
if you follow a Nixpkgs version 20.03 channel.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is then possible to add
|
||||
</para>
|
||||
|
||||
<programlisting language="nix">
|
||||
imports = [ <home-manager/nixos> ];
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
to your system <filename>configuration.nix</filename> file, which will
|
||||
introduce a new NixOS option called <option>home-manager.users</option>
|
||||
whose type is an attribute set that maps user names to Home Manager
|
||||
configurations.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, a NixOS configuration may include the lines
|
||||
</para>
|
||||
|
||||
<programlisting language="nix">
|
||||
users.users.eve.isNormalUser = true;
|
||||
home-manager.users.eve = { pkgs, ... }: {
|
||||
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||
programs.bash.enable = true;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
and after a <command>nixos-rebuild switch</command> the user eve's
|
||||
environment should include a basic Bash configuration and the packages atool
|
||||
and httpie.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
By default packages will be installed to
|
||||
<filename>$HOME/.nix-profile</filename> but they can be installed to
|
||||
<filename>/etc/profiles</filename> if
|
||||
</para>
|
||||
<programlisting language="nix">
|
||||
home-manager.useUserPackages = true;
|
||||
</programlisting>
|
||||
<para>
|
||||
is added to the system configuration. This is necessary if, for example,
|
||||
you wish to use <command>nixos-rebuild build-vm</command>. This option may
|
||||
become the default value in the future.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
By default, Home Manager uses a private <literal>pkgs</literal> instance
|
||||
that is configured via the <option>home-manager.users.<name>.nixpkgs</option> options.
|
||||
To instead use the global <literal>pkgs</literal> that is configured via
|
||||
the system level <option>nixpkgs</option> options, set
|
||||
</para>
|
||||
<programlisting language="nix">
|
||||
home-manager.useGlobalPkgs = true;
|
||||
</programlisting>
|
||||
<para>
|
||||
This saves an extra Nixpkgs evaluation, adds consistency, and removes the
|
||||
dependency on <envar>NIX_PATH</envar>, which is otherwise used for
|
||||
importing Nixpkgs.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
<section xml:id="sec-install-nix-darwin-module">
|
||||
<title>nix-darwin module</title>
|
||||
|
||||
<para>
|
||||
Home Manager provides a module that allows you to prepare user
|
||||
environments directly from the nix-darwin configuration file, which often is
|
||||
more convenient than using the <command>home-manager</command> tool.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To make the NixOS module available for use you must <option>import</option>
|
||||
it into your system configuration. This is most conveniently done by adding
|
||||
a Home Manager channel, for example
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager</userinput>
|
||||
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
if you are following Nixpkgs master or an unstable channel and
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>#</prompt> <userinput>nix-channel --add https://github.com/rycee/home-manager/archive/release-20.03.tar.gz home-manager</userinput>
|
||||
<prompt>#</prompt> <userinput>nix-channel --update</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
if you follow a Nixpkgs version 20.03 channel.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is then possible to add
|
||||
</para>
|
||||
|
||||
<programlisting language="nix">
|
||||
imports = [ <home-manager/nix-darwin> ];
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
to your nix-darwin <filename>configuration.nix</filename> file, which will
|
||||
introduce a new NixOS option called <option>home-manager</option> whose type
|
||||
is an attribute set that maps user names to Home Manager configurations.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, a nix-darwin configuration may include the lines
|
||||
</para>
|
||||
|
||||
<programlisting language="nix">
|
||||
home-manager.users.eve = { pkgs, ... }: {
|
||||
home.packages = [ pkgs.atool pkgs.httpie ];
|
||||
programs.bash.enable = true;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
and after a <command>darwin-rebuild --switch</command> the user eve's
|
||||
environment should include a basic Bash configuration and the packages atool
|
||||
and httpie.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
By default user packages will not be ignored in favor of
|
||||
<option>environment.systemPackages</option>, but they will be intalled to
|
||||
<option>/etc/profiles/per-user/$USERNAME</option> if
|
||||
</para>
|
||||
|
||||
<programlisting language="nix">
|
||||
home-manager.useUserPackages = true;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
is added to the nix-darwin configuration. This option may become the default
|
||||
value in the future.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -7,28 +7,34 @@
|
||||
<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.
|
||||
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="./generated/options-db.xml" xpointer="configuration-variable-list" />
|
||||
<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>
|
||||
|
||||
@@ -2,61 +2,526 @@
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<refmeta>
|
||||
<refentrytitle><command>home-manager</command></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
<refentrytitle><command>home-manager</command>
|
||||
</refentrytitle><manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Home Manager</refmiscinfo>
|
||||
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname><command>home-manager</command></refname>
|
||||
<refpurpose>reconfigure a user environment</refpurpose>
|
||||
<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'><option>help</option></arg>
|
||||
<arg choice='plain'><option>build</option></arg>
|
||||
<arg choice='plain'><option>switch</option></arg>
|
||||
<arg choice='plain'><option>generations</option></arg>
|
||||
<arg choice='plain'><option>remove-generations</option></arg>
|
||||
<arg choice='plain'><option>packages</option></arg>
|
||||
<arg choice='plain'><option>news</option></arg>
|
||||
<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">
|
||||
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>
|
||||
-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>
|
||||
--max-jobs <replaceable>number</replaceable>
|
||||
</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>.
|
||||
This command updates the user environment so that it corresponds to the
|
||||
configuration specified in <filename>~/.config/nixpkgs/home.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>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>Files</title>
|
||||
<title>Options</title>
|
||||
<para>
|
||||
The tool accepts the options
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>~/.local/share/home-manager/news-read-ids</filename></term>
|
||||
<term>
|
||||
<option>-A <replaceable>attrPath</replaceable></option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Identifiers of news items that have been shown. Can be deleted
|
||||
to reset the read news indicator.
|
||||
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>-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>--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>--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
|
||||
Please report any bugs on the
|
||||
<link
|
||||
xlink:href="https://github.com/rycee/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>
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<title>Home Manager Reference Pages</title>
|
||||
<info>
|
||||
<author>
|
||||
<personname>Home Manager contributors</personname>
|
||||
<contrib>Author</contrib>
|
||||
</author>
|
||||
<copyright>
|
||||
<year>2017-2018</year><holder>Home Manager contributors</holder>
|
||||
<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" />
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
<preface>
|
||||
<title>Preface</title>
|
||||
<para>
|
||||
This manual will eventually describes how to install, use, and
|
||||
extend Home Manager.
|
||||
This manual will eventually describes how to install, use, and extend Home
|
||||
Manager.
|
||||
</para>
|
||||
<para>
|
||||
If you encounter problems or bugs then please report them on the
|
||||
<link xlink:href="https://github.com/rycee/home-manager/issues">Home Manager issue tracker</link>.
|
||||
<link xlink:href="https://github.com/rycee/home-manager/issues">Home Manager
|
||||
issue tracker</link>.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
@@ -24,8 +25,15 @@
|
||||
</para>
|
||||
</note>
|
||||
</preface>
|
||||
<xi:include href="installation.xml" />
|
||||
<xi:include href="writing-modules.xml" />
|
||||
<appendix xml:id="ch-options">
|
||||
<title>Configuration Options</title>
|
||||
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
|
||||
<xi:include href="./nmd-result/home-manager-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>
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:str="http://exslt.org/strings"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
extension-element-prefixes="str"
|
||||
>
|
||||
|
||||
<xsl:output method='xml' encoding="UTF-8" />
|
||||
|
||||
<xsl:param name="revision" />
|
||||
<xsl:param name="program" />
|
||||
|
||||
|
||||
<xsl:template match="/expr/list">
|
||||
<appendix>
|
||||
<title>Configuration Options</title>
|
||||
<variablelist xml:id="configuration-variable-list">
|
||||
<xsl:for-each select="attrs">
|
||||
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
||||
<varlistentry>
|
||||
<term xlink:href="#{$id}">
|
||||
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
||||
<option>
|
||||
<xsl:value-of select="attr[@name = 'name']/string/@value" />
|
||||
</option>
|
||||
</term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>
|
||||
<xsl:value-of disable-output-escaping="yes"
|
||||
select="attr[@name = 'description']/string/@value" />
|
||||
</para>
|
||||
|
||||
<xsl:if test="attr[@name = 'type']">
|
||||
<para>
|
||||
<emphasis>Type:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="attr[@name = 'type']/string/@value"/>
|
||||
<xsl:if test="attr[@name = 'readOnly']/bool/@value = 'true'">
|
||||
<xsl:text> </xsl:text>
|
||||
<emphasis>(read only)</emphasis>
|
||||
</xsl:if>
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="attr[@name = 'default']">
|
||||
<para>
|
||||
<emphasis>Default:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:apply-templates select="attr[@name = 'default']" mode="top" />
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="attr[@name = 'example']">
|
||||
<para>
|
||||
<emphasis>Example:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:choose>
|
||||
<xsl:when test="attr[@name = 'example']/attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
||||
<programlisting><xsl:value-of select="attr[@name = 'example']/attrs/attr[@name = 'text']/string/@value" /></programlisting>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates select="attr[@name = 'example']" mode="top" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="attr[@name = 'relatedPackages']">
|
||||
<para>
|
||||
<emphasis>Related packages:</emphasis>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of disable-output-escaping="yes"
|
||||
select="attr[@name = 'relatedPackages']/string/@value" />
|
||||
</para>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
|
||||
<para>
|
||||
<emphasis>Declared by:</emphasis>
|
||||
</para>
|
||||
<xsl:apply-templates select="attr[@name = 'declarations']" />
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="count(attr[@name = 'definitions']/list/*) != 0">
|
||||
<para>
|
||||
<emphasis>Defined by:</emphasis>
|
||||
</para>
|
||||
<xsl:apply-templates select="attr[@name = 'definitions']" />
|
||||
</xsl:if>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</xsl:for-each>
|
||||
|
||||
</variablelist>
|
||||
</appendix>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="*" mode="top">
|
||||
<xsl:choose>
|
||||
<xsl:when test="string[contains(@value, '
')]">
|
||||
<programlisting>
|
||||
<xsl:text>''
|
||||
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "''${")' /><xsl:text>''</xsl:text></programlisting>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<literal><xsl:apply-templates /></literal>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="null">
|
||||
<xsl:text>null</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="string">
|
||||
<xsl:choose>
|
||||
<xsl:when test="(contains(@value, '"') or contains(@value, '\')) and not(contains(@value, '
'))">
|
||||
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "''${")' /><xsl:text>''</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>"</xsl:text><xsl:value-of select="str:replace(str:replace(str:replace(str:replace(@value, '\', '\\'), '"', '\"'), '
', '\n'), '$', '\$')" /><xsl:text>"</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="int">
|
||||
<xsl:value-of select="@value" />
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="bool[@value = 'true']">
|
||||
<xsl:text>true</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="bool[@value = 'false']">
|
||||
<xsl:text>false</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="list">
|
||||
[
|
||||
<xsl:for-each select="*">
|
||||
<xsl:apply-templates select="." />
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
]
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
||||
<xsl:value-of select="attr[@name = 'text']/string/@value" />
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="attrs">
|
||||
{
|
||||
<xsl:for-each select="attr">
|
||||
<xsl:value-of select="@name" />
|
||||
<xsl:text> = </xsl:text>
|
||||
<xsl:apply-templates select="*" /><xsl:text>; </xsl:text>
|
||||
</xsl:for-each>
|
||||
}
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="derivation">
|
||||
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
|
||||
<simplelist>
|
||||
<xsl:for-each select="list/string">
|
||||
<member><filename>
|
||||
<!-- Hyperlink the filename either to the NixOS Subversion
|
||||
repository (if it’s a module and we have a revision number),
|
||||
or to the local filesystem. -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="not(starts-with(@value, '/'))">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$program = 'home-manager'">
|
||||
<xsl:attribute name="xlink:href">https://github.com/rycee/home-manager/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/>#blob-path</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:when test="$revision = 'local'">
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/master/<xsl:value-of select="@value"/></xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/></xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:when test="$revision != 'local' and $program = 'nixops' and contains(@value, '/nix/')">
|
||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xlink:href">file://<xsl:value-of select="@value"/></xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<!-- Print the filename and make it user-friendly by replacing the
|
||||
/nix/store/<hash> prefix by the default location of nixos
|
||||
sources. -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$program = 'home-manager'">
|
||||
<home-manager/<xsl:value-of select="@value"/>>
|
||||
</xsl:when>
|
||||
<xsl:when test="not(starts-with(@value, '/'))">
|
||||
<nixpkgs/<xsl:value-of select="@value"/>>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains(@value, 'nixops') and contains(@value, '/nix/')">
|
||||
<nixops/<xsl:value-of select="substring-after(@value, '/nix/')"/>>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="@value" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</filename></member>
|
||||
</xsl:for-each>
|
||||
</simplelist>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="function">
|
||||
<xsl:text>λ</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
</xsl:stylesheet>
|
||||
@@ -1,9 +0,0 @@
|
||||
.docbook .xref img[src^=images\/callouts\/],
|
||||
.screen img,
|
||||
.programlisting img {
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.calloutlist img {
|
||||
width: 1.5em;
|
||||
}
|
||||
17
doc/release-notes/release-notes.adoc
Normal file
17
doc/release-notes/release-notes.adoc
Normal file
@@ -0,0 +1,17 @@
|
||||
[[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-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.
|
||||
271
doc/style.css
271
doc/style.css
@@ -1,271 +0,0 @@
|
||||
/* Copied from http://bakefile.sourceforge.net/, which appears
|
||||
licensed under the GNU GPL. */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Basic headers and text:
|
||||
***************************************************************************/
|
||||
|
||||
body
|
||||
{
|
||||
font-family: "Nimbus Sans L", sans-serif;
|
||||
background: white;
|
||||
margin: 2em 1em 2em 1em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4
|
||||
{
|
||||
color: #005aa0;
|
||||
}
|
||||
|
||||
h1 /* title */
|
||||
{
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
h2 /* chapters, appendices, subtitle */
|
||||
{
|
||||
font-size: 180%;
|
||||
}
|
||||
|
||||
/* Extra space between chapters, appendices. */
|
||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
||||
{
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.section > div.titlepage h2 /* sections */
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
h3 /* subsections */
|
||||
{
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.simplesect h2
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.appendix h3
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
|
||||
{
|
||||
margin-top: 1.4em;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.refsection h3
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Examples:
|
||||
***************************************************************************/
|
||||
|
||||
div.example
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 6px 6px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
background: #f4f4f8;
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
div.example p.title
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.example pre
|
||||
{
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Screen dumps:
|
||||
***************************************************************************/
|
||||
|
||||
pre.screen, pre.programlisting
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
|
||||
background: #f4f4f8;
|
||||
font-family: monospace;
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
div.example pre.programlisting
|
||||
{
|
||||
border: 0px;
|
||||
padding: 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Notes, warnings etc:
|
||||
***************************************************************************/
|
||||
|
||||
.note, .warning
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0.3em 0.3em 0.3em 0.3em;
|
||||
background: #fffff5;
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
div.note, div.warning
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.note h3, div.warning h3
|
||||
{
|
||||
color: red;
|
||||
font-size: 100%;
|
||||
padding-right: 0.5em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note p, div.warning p
|
||||
{
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
div.note h3 + p, div.warning h3 + p
|
||||
{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note h3
|
||||
{
|
||||
color: blue;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
div.navfooter *
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Links colors and highlighting:
|
||||
***************************************************************************/
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
a:link { color: #0048b3; }
|
||||
a:visited { color: #002a6a; }
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Table of contents:
|
||||
***************************************************************************/
|
||||
|
||||
div.toc
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.toc dl
|
||||
{
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Special elements:
|
||||
***************************************************************************/
|
||||
|
||||
tt, code
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
.term
|
||||
{
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
div.variablelist dd p, div.glosslist dd p
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.variablelist dd, div.glosslist dd
|
||||
{
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
div.glosslist dt
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.varname
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
span.command strong
|
||||
{
|
||||
font-weight: normal;
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
div.calloutlist table
|
||||
{
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border-collapse: collapse;
|
||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
||||
}
|
||||
|
||||
table.simplelist
|
||||
{
|
||||
text-align: left;
|
||||
color: #005aa0;
|
||||
border: 0;
|
||||
padding: 5px;
|
||||
background: #fffff5;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
box-shadow: none;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.navheader table, div.navfooter table {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
div.affiliation
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
180
doc/writing-modules.adoc
Normal file
180
doc/writing-modules.adoc
Normal file
@@ -0,0 +1,180 @@
|
||||
[[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.tupleOf types`
|
||||
--
|
||||
+
|
||||
where `type` and `types` are themselve a type and list of types, respectively.
|
||||
+
|
||||
`hm.gvariant.mkEmptyArray type`:::
|
||||
An alias of `hm.gvariant.mkArray type []`.
|
||||
+
|
||||
`hm.gvariant.mkTuple elements`:::
|
||||
Builds a GVariant tuple containing the given list of elements, where each element is a GVariant value.
|
||||
65
format
Executable file
65
format
Executable file
@@ -0,0 +1,65 @@
|
||||
#! /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/default.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/dconf.nix \
|
||||
! -path ./modules/misc/gtk.nix \
|
||||
! -path ./modules/misc/news.nix \
|
||||
! -path ./modules/misc/nixpkgs.nix \
|
||||
! -path ./modules/misc/xdg.nix \
|
||||
! -path ./modules/modules.nix \
|
||||
! -path ./modules/programs/afew.nix \
|
||||
! -path ./modules/programs/alot.nix \
|
||||
! -path ./modules/programs/bash.nix \
|
||||
! -path ./modules/programs/emacs.nix \
|
||||
! -path ./modules/programs/firefox.nix \
|
||||
! -path ./modules/programs/gpg.nix \
|
||||
! -path ./modules/programs/lesspipe.nix \
|
||||
! -path ./modules/programs/neovim.nix \
|
||||
! -path ./modules/programs/ssh.nix \
|
||||
! -path ./modules/programs/tmux.nix \
|
||||
! -path ./modules/programs/vscode.nix \
|
||||
! -path ./modules/programs/zsh.nix \
|
||||
! -path ./modules/services/gpg-agent.nix \
|
||||
! -path ./modules/services/kbfs.nix \
|
||||
! -path ./modules/services/keybase.nix \
|
||||
! -path ./modules/services/mpd.nix \
|
||||
! -path ./modules/services/sxhkd.nix \
|
||||
! -path ./modules/services/window-managers/i3.nix \
|
||||
! -path ./modules/systemd.nix \
|
||||
! -path ./nix-darwin/default.nix \
|
||||
! -path ./tests/default.nix \
|
||||
! -path ./tests/modules/home-environment/default.nix \
|
||||
! -path ./tests/modules/home-environment/session-variables.nix \
|
||||
! -path ./tests/modules/programs/gpg/override-defaults.nix \
|
||||
! -path ./tests/modules/programs/tmux/default.nix \
|
||||
! -path ./tests/modules/programs/zsh/session-variables.nix \
|
||||
! -path ./tests/modules/services/sxhkd/service.nix \
|
||||
! -path ./tests/modules/systemd/default.nix \
|
||||
! -path ./tests/modules/systemd/services.nix \
|
||||
! -path ./tests/modules/systemd/session-variables.nix \
|
||||
-exec nixfmt $CHECK_ARG {} +
|
||||
356
home-manager/completion.bash
Normal file
356
home-manager/completion.bash
Normal file
@@ -0,0 +1,356 @@
|
||||
#!/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
|
||||
# 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
|
||||
# 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
|
||||
#
|
||||
# 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" "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" "--show-trace" )
|
||||
|
||||
# ^ « 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 build switch generations remove-generations expire-generations packages news" home-manager
|
||||
@@ -1,4 +1,4 @@
|
||||
{ pkgs
|
||||
{ runCommand, lib, bash, coreutils, findutils, gnused, less
|
||||
|
||||
# Extra path to Home Manager. If set then this path will be tried
|
||||
# before `$HOME/.config/nixpkgs/home-manager` and
|
||||
@@ -12,25 +12,29 @@ let
|
||||
|
||||
in
|
||||
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager";
|
||||
|
||||
buildCommand = ''
|
||||
install -v -D -m755 ${./home-manager} $out/bin/home-manager
|
||||
runCommand
|
||||
"home-manager"
|
||||
{
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
meta = with lib; {
|
||||
description = "A user environment configurator";
|
||||
maintainers = [ maintainers.rycee ];
|
||||
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 "${pkgs.bash}" \
|
||||
--subst-var-by coreutils "${pkgs.coreutils}" \
|
||||
--subst-var-by findutils "${pkgs.findutils}" \
|
||||
--subst-var-by gnused "${pkgs.gnused}" \
|
||||
--subst-var-by less "${pkgs.less}" \
|
||||
--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 HOME_MANAGER_PATH '${pathStr}'
|
||||
'';
|
||||
|
||||
meta = with pkgs.stdenv.lib; {
|
||||
description = "A user environment configurator";
|
||||
maintainers = [ maintainers.rycee ];
|
||||
platforms = platforms.unix;
|
||||
license = licenses.mit;
|
||||
};
|
||||
}
|
||||
install -D -m755 ${./completion.bash} \
|
||||
$out/share/bash-completion/completions/home-manager
|
||||
''
|
||||
|
||||
@@ -10,6 +10,20 @@ function errorEcho() {
|
||||
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)"
|
||||
@@ -60,34 +74,48 @@ function setHomeManagerNixPath() {
|
||||
done
|
||||
}
|
||||
|
||||
function doInstantiate() {
|
||||
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="$*"
|
||||
local extraArgs=("$@")
|
||||
|
||||
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||
extraArgs="$extraArgs -I $p"
|
||||
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||
done
|
||||
|
||||
if [[ -v VERBOSE ]]; then
|
||||
extraArgs="$extraArgs --show-trace"
|
||||
extraArgs=("${extraArgs[@]}" "--show-trace")
|
||||
fi
|
||||
|
||||
# shellcheck disable=2086
|
||||
if [[ -v USE_NIX2_COMMAND ]]; then
|
||||
nix build \
|
||||
-f "<home-manager/home-manager/home-manager.nix>" \
|
||||
$extraArgs \
|
||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||
else
|
||||
nix-build \
|
||||
"<home-manager/home-manager/home-manager.nix>" \
|
||||
$extraArgs \
|
||||
--argstr confPath "$HOME_MANAGER_CONFIG" \
|
||||
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE"
|
||||
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
|
||||
@@ -129,6 +157,17 @@ function presentNews() {
|
||||
fi
|
||||
}
|
||||
|
||||
function doEdit() {
|
||||
if [[ ! -v EDITOR || -z $EDITOR ]]; then
|
||||
errorEcho "Please set the \$EDITOR environment variable"
|
||||
return 1
|
||||
fi
|
||||
|
||||
setConfigFile
|
||||
|
||||
exec "$EDITOR" "$HOME_MANAGER_CONFIG"
|
||||
}
|
||||
|
||||
function doBuild() {
|
||||
if [[ ! -w . ]]; then
|
||||
errorEcho "Cannot run build in read-only directory";
|
||||
@@ -142,13 +181,8 @@ function doBuild() {
|
||||
|
||||
local exitCode
|
||||
|
||||
if [[ -v USE_NIX2_COMMAND ]]; then
|
||||
doBuildAttr activationPackage \
|
||||
&& exitCode=0 || exitCode=1
|
||||
else
|
||||
doBuildAttr --attr activationPackage \
|
||||
&& exitCode=0 || exitCode=1
|
||||
fi
|
||||
doBuildAttr --attr activationPackage \
|
||||
&& exitCode=0 || exitCode=1
|
||||
|
||||
presentNews "$newsInfo"
|
||||
|
||||
@@ -170,17 +204,10 @@ function doSwitch() {
|
||||
# before activation completes.
|
||||
generation="$WORK_DIR/generation"
|
||||
|
||||
if [[ -v USE_NIX2_COMMAND ]]; then
|
||||
doBuildAttr \
|
||||
--out-link "$generation" \
|
||||
activationPackage \
|
||||
&& "$generation/activate" || exitCode=1
|
||||
else
|
||||
doBuildAttr \
|
||||
--out-link "$generation" \
|
||||
--attr activationPackage \
|
||||
&& "$generation/activate" || exitCode=1
|
||||
fi
|
||||
doBuildAttr \
|
||||
--out-link "$generation" \
|
||||
--attr activationPackage \
|
||||
&& "$generation/activate" || exitCode=1
|
||||
|
||||
presentNews "$newsInfo"
|
||||
|
||||
@@ -205,17 +232,7 @@ function doListGens() {
|
||||
# Removes linked generations. Takes as arguments identifiers of
|
||||
# generations to remove.
|
||||
function doRmGenerations() {
|
||||
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
|
||||
setVerboseAndDryRun
|
||||
|
||||
pushd "/nix/var/nix/profiles/per-user/$USER" > /dev/null
|
||||
|
||||
@@ -235,6 +252,11 @@ function doRmGenerations() {
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function doRmAllGenerations() {
|
||||
$DRY_RUN_CMD rm $VERBOSE_ARG \
|
||||
"/nix/var/nix/profiles/per-user/$USER/home-manager"*
|
||||
}
|
||||
|
||||
function doExpireGenerations() {
|
||||
local profileDir="/nix/var/nix/profiles/per-user/$USER"
|
||||
|
||||
@@ -285,23 +307,14 @@ function buildNews() {
|
||||
local output
|
||||
output="$WORK_DIR/news-info.sh"
|
||||
|
||||
if [[ -v USE_NIX2_COMMAND ]]; then
|
||||
doBuildAttr \
|
||||
--out-link "$output" \
|
||||
--quiet \
|
||||
--arg check false \
|
||||
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||
newsInfo
|
||||
else
|
||||
doBuildAttr \
|
||||
--out-link "$output" \
|
||||
--no-build-output \
|
||||
--quiet \
|
||||
--arg check false \
|
||||
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||
--attr newsInfo \
|
||||
> /dev/null
|
||||
fi
|
||||
doBuildAttr \
|
||||
--out-link "$output" \
|
||||
--no-build-output \
|
||||
--quiet \
|
||||
--arg check false \
|
||||
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||
--attr newsInfo \
|
||||
> /dev/null
|
||||
|
||||
echo "$output"
|
||||
}
|
||||
@@ -336,6 +349,56 @@ function doShowNews() {
|
||||
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
|
||||
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/var/nix/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() {
|
||||
echo "Usage: $0 [OPTION] COMMAND"
|
||||
echo
|
||||
@@ -346,16 +409,31 @@ function doHelp() {
|
||||
echo " -A ATTRIBUTE Optional attribute that selects a configuration"
|
||||
echo " expression in the configuration file."
|
||||
echo " -I PATH Add a path to the Nix expression search path."
|
||||
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 " --cores NUM"
|
||||
echo " --keep-failed"
|
||||
echo " --keep-going"
|
||||
echo " --max-jobs NUM"
|
||||
echo " --option NAME VALUE"
|
||||
echo " --show-trace"
|
||||
echo " --(no-)substitute"
|
||||
echo
|
||||
echo "Commands"
|
||||
echo
|
||||
echo " help Print this help"
|
||||
echo
|
||||
echo " edit Open the home configuration in \$EDITOR"
|
||||
echo
|
||||
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
|
||||
echo " generations List all home environment generations"
|
||||
@@ -372,67 +450,91 @@ function doHelp() {
|
||||
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=()
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE=""
|
||||
PASSTHROUGH_OPTS=()
|
||||
COMMAND=""
|
||||
COMMAND_ARGS=()
|
||||
|
||||
# As a special case, if the user has given --help anywhere on the
|
||||
# command line then print help and exit.
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == "--help" ]]; then
|
||||
doHelp
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
while getopts 2f:I:A:vnh opt; do
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$1"
|
||||
shift
|
||||
case $opt in
|
||||
2)
|
||||
USE_NIX2_COMMAND=1
|
||||
build|instantiate|edit|expire-generations|generations|help|news|packages|remove-generations|switch|uninstall)
|
||||
COMMAND="$opt"
|
||||
;;
|
||||
f)
|
||||
HOME_MANAGER_CONFIG="$OPTARG"
|
||||
-A)
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE="$1"
|
||||
shift
|
||||
;;
|
||||
I)
|
||||
EXTRA_NIX_PATH+=("$OPTARG")
|
||||
-I)
|
||||
EXTRA_NIX_PATH+=("$1")
|
||||
shift
|
||||
;;
|
||||
A)
|
||||
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
|
||||
-b)
|
||||
export HOME_MANAGER_BACKUP_EXT="$1"
|
||||
shift
|
||||
;;
|
||||
v)
|
||||
export VERBOSE=1
|
||||
-f|--file)
|
||||
HOME_MANAGER_CONFIG="$1"
|
||||
shift
|
||||
;;
|
||||
n)
|
||||
export DRY_RUN=1
|
||||
;;
|
||||
h)
|
||||
-h|--help)
|
||||
doHelp
|
||||
exit 0
|
||||
;;
|
||||
-n|--dry-run)
|
||||
export DRY_RUN=1
|
||||
;;
|
||||
--option)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1" "$2")
|
||||
shift 2
|
||||
;;
|
||||
--max-jobs|--cores)
|
||||
PASSTHROUGH_OPTS+=("$opt" "$1")
|
||||
shift
|
||||
;;
|
||||
--keep-failed|--keep-going|--show-trace\
|
||||
|--substitute|--no-substitute)
|
||||
PASSTHROUGH_OPTS+=("$opt")
|
||||
;;
|
||||
-v|--verbose)
|
||||
export VERBOSE=1
|
||||
;;
|
||||
*)
|
||||
errorEcho "Unknown option -$OPTARG"
|
||||
doHelp >&2
|
||||
exit 1
|
||||
case $COMMAND in
|
||||
expire-generations|remove-generations)
|
||||
COMMAND_ARGS+=("$opt")
|
||||
;;
|
||||
*)
|
||||
errorEcho "$0: unknown option '$opt'"
|
||||
errorEcho "Run '$0 --help' for usage help"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get rid of the options.
|
||||
shift "$((OPTIND-1))"
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
if [[ -z $COMMAND ]]; then
|
||||
doHelp >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd="$1"
|
||||
shift 1
|
||||
|
||||
case "$cmd" in
|
||||
case $COMMAND in
|
||||
edit)
|
||||
doEdit
|
||||
;;
|
||||
build)
|
||||
doBuild
|
||||
;;
|
||||
instantiate)
|
||||
doInstantiate
|
||||
;;
|
||||
switch)
|
||||
doSwitch
|
||||
;;
|
||||
@@ -440,10 +542,15 @@ case "$cmd" in
|
||||
doListGens
|
||||
;;
|
||||
remove-generations)
|
||||
doRmGenerations "$@"
|
||||
doRmGenerations "${COMMAND_ARGS[@]}"
|
||||
;;
|
||||
expire-generations)
|
||||
doExpireGenerations "$@"
|
||||
if [[ ${#COMMAND_ARGS[@]} != 1 ]]; then
|
||||
errorEcho "expire-generations expects one argument, got ${#COMMAND_ARGS[@]}."
|
||||
exit 1
|
||||
else
|
||||
doExpireGenerations "${COMMAND_ARGS[@]}"
|
||||
fi
|
||||
;;
|
||||
packages)
|
||||
doListPackages
|
||||
@@ -451,11 +558,14 @@ case "$cmd" in
|
||||
news)
|
||||
doShowNews --all
|
||||
;;
|
||||
help|--help)
|
||||
uninstall)
|
||||
doUninstall
|
||||
;;
|
||||
help)
|
||||
doHelp
|
||||
;;
|
||||
*)
|
||||
errorEcho "Unknown command: $cmd"
|
||||
errorEcho "Unknown command: $COMMAND"
|
||||
doHelp >&2
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -9,7 +9,7 @@ with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
env = import <home-manager/modules> {
|
||||
env = import ../modules {
|
||||
configuration =
|
||||
if confAttr == ""
|
||||
then confPath
|
||||
|
||||
@@ -1,39 +1,67 @@
|
||||
{ home-manager, pkgs }:
|
||||
{ home-manager, runCommand }:
|
||||
|
||||
pkgs.runCommand
|
||||
"home-manager-install"
|
||||
{
|
||||
propagatedBuildInputs = [ home-manager ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
shellHook = ''
|
||||
echo
|
||||
echo "Creating initial Home Manager generation..."
|
||||
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..."
|
||||
|
||||
if home-manager switch; then
|
||||
cat <<EOF
|
||||
mkdir -p "$(dirname "$confFile")"
|
||||
cat > $confFile <<EOF
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
All done! The home-manager tool should now be installed and you
|
||||
can edit
|
||||
{
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
''${XDG_CONFIG_HOME:-~/.config}/nixpkgs/home.nix
|
||||
# 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 = "20.03";
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
to configure Home Manager. Run 'man home-configuration.nix' to
|
||||
see all available options.
|
||||
EOF
|
||||
exit 0
|
||||
else
|
||||
cat <<EOF
|
||||
echo
|
||||
echo "Creating initial Home Manager generation..."
|
||||
echo
|
||||
|
||||
Uh oh, the installation failed! Please create an issue at
|
||||
if home-manager switch; then
|
||||
cat <<EOF
|
||||
|
||||
https://github.com/rycee/home-manager/issues
|
||||
All done! The home-manager tool should now be installed and you
|
||||
can edit
|
||||
|
||||
if the error seems to be the fault of Home Manager.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
}
|
||||
""
|
||||
$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/rycee/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
|
||||
''
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ config, lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@@ -95,7 +95,7 @@ let
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
type = types.nullOr types.port;
|
||||
default = null;
|
||||
example = 993;
|
||||
description = ''
|
||||
@@ -106,7 +106,7 @@ let
|
||||
|
||||
tls = mkOption {
|
||||
type = tlsModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for secure connections.
|
||||
'';
|
||||
@@ -125,7 +125,7 @@ let
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
type = types.nullOr types.port;
|
||||
default = null;
|
||||
example = 465;
|
||||
description = ''
|
||||
@@ -136,7 +136,7 @@ let
|
||||
|
||||
tls = mkOption {
|
||||
type = tlsModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for secure connections.
|
||||
'';
|
||||
@@ -207,6 +207,13 @@ let
|
||||
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";
|
||||
@@ -269,7 +276,7 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Standard email folders.
|
||||
'';
|
||||
@@ -285,7 +292,7 @@ let
|
||||
|
||||
signature = mkOption {
|
||||
type = signatureModule;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Signature configuration.
|
||||
'';
|
||||
@@ -325,9 +332,7 @@ let
|
||||
(mkIf (config.flavor == "gmail.com") {
|
||||
userName = mkDefault config.address;
|
||||
|
||||
imap = {
|
||||
host = "imap.gmail.com";
|
||||
};
|
||||
imap = { host = "imap.gmail.com"; };
|
||||
|
||||
smtp = {
|
||||
host = "smtp.gmail.com";
|
||||
@@ -336,20 +341,14 @@ let
|
||||
})
|
||||
|
||||
(mkIf (config.flavor == "runbox.com") {
|
||||
imap = {
|
||||
host = "mail.runbox.com";
|
||||
};
|
||||
imap = { host = "mail.runbox.com"; };
|
||||
|
||||
smtp = {
|
||||
host = "mail.runbox.com";
|
||||
};
|
||||
smtp = { host = "mail.runbox.com"; };
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options.accounts.email = {
|
||||
certificatesFile = mkOption {
|
||||
type = types.path;
|
||||
@@ -366,9 +365,7 @@ in
|
||||
default = "${config.home.homeDirectory}/Maildir";
|
||||
defaultText = "$HOME/Maildir";
|
||||
apply = p:
|
||||
if hasPrefix "/" p
|
||||
then p
|
||||
else "${config.home.homeDirectory}/${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
|
||||
@@ -377,38 +374,35 @@ in
|
||||
};
|
||||
|
||||
accounts = mkOption {
|
||||
type = types.attrsOf (types.submodule [
|
||||
type = types.attrsOf (types.submodule ([
|
||||
mailAccountOpts
|
||||
(import ../programs/alot-accounts.nix)
|
||||
(import ../programs/alot-accounts.nix pkgs)
|
||||
(import ../programs/astroid-accounts.nix)
|
||||
(import ../programs/getmail-accounts.nix)
|
||||
(import ../programs/lieer-accounts.nix)
|
||||
(import ../programs/mbsync-accounts.nix)
|
||||
(import ../programs/msmtp-accounts.nix)
|
||||
(import ../programs/neomutt-accounts.nix)
|
||||
(import ../programs/notmuch-accounts.nix)
|
||||
(import ../programs/offlineimap-accounts.nix)
|
||||
]);
|
||||
default = {};
|
||||
] ++ optionals pkgs.stdenv.hostPlatform.isLinux
|
||||
[ (import ../services/lieer-accounts.nix) ]));
|
||||
default = { };
|
||||
description = "List of email accounts.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.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);
|
||||
}
|
||||
)
|
||||
(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);
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,10 +19,19 @@ let
|
||||
in
|
||||
fold f res res.config.warnings;
|
||||
|
||||
rawModule = lib.evalModules {
|
||||
modules =
|
||||
[ configuration ]
|
||||
++ (import ./modules.nix { inherit check lib pkgs; });
|
||||
extendedLib = import ./lib/stdlib-extended.nix pkgs.lib;
|
||||
|
||||
hmModules =
|
||||
import ./modules.nix {
|
||||
inherit check pkgs;
|
||||
lib = extendedLib;
|
||||
};
|
||||
|
||||
rawModule = extendedLib.evalModules {
|
||||
modules = [ configuration ] ++ hmModules;
|
||||
specialArgs = {
|
||||
modulesPath = builtins.toString ./.;
|
||||
};
|
||||
};
|
||||
|
||||
module = showWarnings (
|
||||
|
||||
@@ -6,17 +6,20 @@ let
|
||||
|
||||
cfg = config.home.file;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
homeDirectory = config.home.homeDirectory;
|
||||
|
||||
fileType = (import lib/file-type.nix {
|
||||
inherit homeDirectory lib pkgs;
|
||||
}).fileType;
|
||||
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*";
|
||||
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
|
||||
|
||||
@@ -36,41 +39,61 @@ in
|
||||
};
|
||||
|
||||
config = {
|
||||
assertions = [
|
||||
(let
|
||||
badFiles =
|
||||
filter (f: hasPrefix "." (baseNameOf f))
|
||||
(map (v: toString v.source)
|
||||
(attrValues cfg));
|
||||
badFilesStr = toString badFiles;
|
||||
in
|
||||
{
|
||||
assertion = badFiles == [];
|
||||
message = "Source file names must not start with '.': ${badFilesStr}";
|
||||
})
|
||||
];
|
||||
|
||||
# This verifies that the links we are about to create will not
|
||||
# overwrite an existing file.
|
||||
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
|
||||
home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] (
|
||||
let
|
||||
# Paths that should be forcibly overwritten by Home Manager.
|
||||
# Caveat emptor!
|
||||
forcedPaths =
|
||||
concatMapStringsSep " " (p: ''"$HOME/${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 "${builtins.storeDir}")/*-home-manager-files/*"
|
||||
|
||||
forcedPaths=(${forcedPaths})
|
||||
|
||||
newGenFiles="$1"
|
||||
shift
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" \
|
||||
&& ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
|
||||
errorEcho "Existing file '$targetPath' is in the way"
|
||||
collision=1
|
||||
|
||||
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, will be moved to '$backup'"
|
||||
fi
|
||||
else
|
||||
errorEcho "Existing file '$targetPath' is in the way"
|
||||
collision=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -v collision ]] ; then
|
||||
errorEcho "Please move the above files and try again"
|
||||
errorEcho "Please move the above files and try again or use -b <ext> to move automatically."
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
@@ -79,8 +102,8 @@ 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"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${check} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
checkNewGenCollision || exit 1
|
||||
@@ -108,7 +131,7 @@ in
|
||||
# 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 = dag.entryAfter ["writeBoundary"] (
|
||||
home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] (
|
||||
let
|
||||
link = pkgs.writeText "link" ''
|
||||
newGenFiles="$1"
|
||||
@@ -116,6 +139,10 @@ in
|
||||
for sourcePath in "$@" ; do
|
||||
relativePath="''${sourcePath#$newGenFiles/}"
|
||||
targetPath="$HOME/$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
|
||||
@@ -124,13 +151,17 @@ in
|
||||
cleanup = pkgs.writeText "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 "${builtins.storeDir}")/*-home-manager-files/*"
|
||||
|
||||
newGenFiles="$1"
|
||||
shift 1
|
||||
for relativePath in "$@" ; do
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$newGenFiles/$relativePath" ]] ; then
|
||||
$VERBOSE_ECHO "Checking $targetPath: exists"
|
||||
elif [[ ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
|
||||
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
|
||||
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
|
||||
else
|
||||
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
|
||||
@@ -160,8 +191,8 @@ in
|
||||
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" -type f -print0 -or -type l -print0 \
|
||||
| xargs -0 bash ${link} "$newGenFiles"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${link} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
function cleanOldGen() {
|
||||
@@ -186,8 +217,7 @@ in
|
||||
|
||||
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 $(basename "$newGenProfilePath") "$genProfilePath"
|
||||
$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"
|
||||
@@ -197,17 +227,17 @@ in
|
||||
''
|
||||
);
|
||||
|
||||
home.activation.checkFilesChanged = dag.entryBefore ["linkGeneration"] (
|
||||
home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] (
|
||||
''
|
||||
declare -A changedFiles
|
||||
'' + concatMapStrings (v: ''
|
||||
cmp --quiet "${v.source}" "${config.home.homeDirectory}/${v.target}" \
|
||||
cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \
|
||||
&& changedFiles["${v.target}"]=0 \
|
||||
|| changedFiles["${v.target}"]=1
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
);
|
||||
|
||||
home.activation.onFilesChange = dag.entryAfter ["linkGeneration"] (
|
||||
home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] (
|
||||
concatMapStrings (v: ''
|
||||
if [[ ${"$\{changedFiles"}["${v.target}"]} -eq 1 ]]; then
|
||||
${v.onChange}
|
||||
@@ -215,19 +245,21 @@ in
|
||||
'') (filter (v: v.onChange != "") (attrValues cfg))
|
||||
);
|
||||
|
||||
home-files = pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager-files";
|
||||
|
||||
nativeBuildInputs = [ pkgs.xlibs.lndir ];
|
||||
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
|
||||
# Symlink directories and files that have the right execute bit.
|
||||
# Copy files that need their execute bit changed.
|
||||
buildCommand = ''
|
||||
# Symlink directories and files that have the right execute bit.
|
||||
# Copy files that need their execute bit changed.
|
||||
home-files = pkgs.runCommand
|
||||
"home-manager-files"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.xlibs.lndir ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
(''
|
||||
mkdir -p $out
|
||||
|
||||
# Needed in case /nix is a symbolic link.
|
||||
realOut="$(realpath -m "$out")"
|
||||
|
||||
function insertFile() {
|
||||
local source="$1"
|
||||
local relTarget="$2"
|
||||
@@ -236,10 +268,10 @@ in
|
||||
|
||||
# Figure out the real absolute path to the target.
|
||||
local target
|
||||
target="$(realpath -m "$out/$relTarget")"
|
||||
target="$(realpath -m "$realOut/$relTarget")"
|
||||
|
||||
# Target path must be within $HOME.
|
||||
if [[ ! $target == $out* ]] ; then
|
||||
if [[ ! $target == $realOut* ]] ; then
|
||||
echo "Error installing file '$relTarget' outside \$HOME" >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -277,14 +309,13 @@ in
|
||||
}
|
||||
'' + concatStrings (
|
||||
mapAttrsToList (n: v: ''
|
||||
insertFile "${v.source}" \
|
||||
insertFile "${sourceStorePath v}" \
|
||||
"${v.target}" \
|
||||
"${if v.executable == null
|
||||
then "inherit"
|
||||
else builtins.toString v.executable}" \
|
||||
"${builtins.toString v.recursive}"
|
||||
'') cfg
|
||||
);
|
||||
};
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ let
|
||||
|
||||
cfg = config.home;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
languageSubModule = types.submodule {
|
||||
options = {
|
||||
base = mkOption {
|
||||
@@ -55,16 +53,24 @@ let
|
||||
keyboardSubModule = types.submodule {
|
||||
options = {
|
||||
layout = mkOption {
|
||||
type = types.str;
|
||||
default = "us";
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "us";
|
||||
defaultText = literalExample "null";
|
||||
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 {
|
||||
type = types.str;
|
||||
default = "pc104";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "presario";
|
||||
description = ''
|
||||
Keyboard model.
|
||||
@@ -81,11 +87,19 @@ let
|
||||
};
|
||||
|
||||
variant = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
type = with types; nullOr str;
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then null
|
||||
else "";
|
||||
defaultText = literalExample "null";
|
||||
example = "colemak";
|
||||
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.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -139,9 +153,12 @@ in
|
||||
};
|
||||
|
||||
home.keyboard = mkOption {
|
||||
type = keyboardSubModule;
|
||||
type = types.nullOr keyboardSubModule;
|
||||
default = {};
|
||||
description = "Keyboard configuration.";
|
||||
description = ''
|
||||
Keyboard configuration. Set to <literal>null</literal> to
|
||||
disable Home Manager keyboard management.
|
||||
'';
|
||||
};
|
||||
|
||||
home.sessionVariables = mkOption {
|
||||
@@ -163,24 +180,34 @@ in
|
||||
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>
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "$FOO World!";
|
||||
};
|
||||
<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>
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
<programlisting language="nix">
|
||||
home.sessionVariables = {
|
||||
FOO = "Hello";
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
|
||||
home.sessionVariablesExtra = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = ''
|
||||
Extra configuration to add to the
|
||||
<filename>hm-session-vars.sh</filename> file.
|
||||
'';
|
||||
};
|
||||
|
||||
home.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
@@ -209,23 +236,57 @@ in
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether the activation script should start with an empty
|
||||
<envvar>PATH</envvar> variable. When <literal>false</literal>
|
||||
then the user's <envvar>PATH</envvar> will be used.
|
||||
<envar>PATH</envar> variable. When <literal>false</literal>
|
||||
then the user's <envar>PATH</envar> will be used.
|
||||
'';
|
||||
};
|
||||
|
||||
home.activation = mkOption {
|
||||
internal = true;
|
||||
type = hm.types.dagOf types.str;
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
example = literalExample ''
|
||||
{
|
||||
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
||||
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
|
||||
''${builtins.toPath ./link-me-directly} $HOME
|
||||
''';
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Activation scripts for the home environment.
|
||||
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>
|
||||
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
|
||||
<code>echo</code> if dry run is enabled. Thus, many cases you
|
||||
can use the idiom <code>$DRY_RUN_CMD rm -rf /</code>.
|
||||
<command>echo</command> if dry run is enabled.
|
||||
|
||||
</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.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -269,7 +330,11 @@ in
|
||||
home.username = mkDefault (builtins.getEnv "USER");
|
||||
home.homeDirectory = mkDefault (builtins.getEnv "HOME");
|
||||
|
||||
home.profileDirectory = cfg.homeDirectory + "/.nix-profile";
|
||||
home.profileDirectory =
|
||||
if config.submoduleSupport.enable
|
||||
&& config.submoduleSupport.externalPackageInstall
|
||||
then config.home.path
|
||||
else cfg.homeDirectory + "/.nix-profile";
|
||||
|
||||
home.sessionVariables =
|
||||
let
|
||||
@@ -297,19 +362,43 @@ in
|
||||
export __HM_SESS_VARS_SOURCED=1
|
||||
|
||||
${config.lib.shell.exportAll cfg.sessionVariables}
|
||||
'';
|
||||
'' + cfg.sessionVariablesExtra;
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
# A dummy entry acting as a boundary between the activation
|
||||
# script's "check" and the "write" phases.
|
||||
home.activation.writeBoundary = dag.entryAnywhere "";
|
||||
home.activation.writeBoundary = hm.dag.entryAnywhere "";
|
||||
|
||||
# Install packages to the user environment.
|
||||
home.activation.installPackages = dag.entryAfter ["writeBoundary"] ''
|
||||
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
||||
'';
|
||||
#
|
||||
# Note, sometimes our target may not allow modification of the Nix
|
||||
# store and then we cannot rely on `nix-env -i`. This is the case,
|
||||
# for example, if we are running as a NixOS module and building a
|
||||
# virtual machine. Then we must instead rely on an external
|
||||
# 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
|
||||
''
|
||||
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
||||
''
|
||||
);
|
||||
|
||||
home.activationPackage =
|
||||
let
|
||||
@@ -317,7 +406,7 @@ in
|
||||
noteEcho Activating ${res.name}
|
||||
${res.data}
|
||||
'';
|
||||
sortedCommands = dag.topoSort cfg.activation;
|
||||
sortedCommands = hm.dag.topoSort cfg.activation;
|
||||
activationCmds =
|
||||
if sortedCommands ? result then
|
||||
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
||||
@@ -339,7 +428,7 @@ in
|
||||
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
||||
|
||||
activationScript = pkgs.writeScript "activation-script" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
@@ -355,13 +444,13 @@ in
|
||||
${activationCmds}
|
||||
'';
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager-generation";
|
||||
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
|
||||
buildCommand = ''
|
||||
pkgs.runCommand
|
||||
"home-manager-generation"
|
||||
{
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
''
|
||||
mkdir -p $out
|
||||
|
||||
cp ${activationScript} $out/activate
|
||||
@@ -374,7 +463,6 @@ in
|
||||
|
||||
${cfg.extraBuilderCommands}
|
||||
'';
|
||||
};
|
||||
|
||||
home.path = pkgs.buildEnv {
|
||||
name = "home-manager-path";
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
function setupVars() {
|
||||
local profilesPath="/nix/var/nix/profiles/per-user/$USER"
|
||||
local gcPath="/nix/var/nix/gcroots/per-user/$USER"
|
||||
local greatestGenNum
|
||||
|
||||
genProfilePath="$profilesPath/home-manager"
|
||||
newGenPath="@GENERATION_DIR@";
|
||||
newGenGcPath="$gcPath/current-home"
|
||||
|
||||
local greatestGenNum
|
||||
greatestGenNum=$( \
|
||||
find "$profilesPath" -name 'home-manager-*-link' \
|
||||
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
|
||||
| sort -rn \
|
||||
| head -1)
|
||||
nix-env --list-generations --profile "$genProfilePath" \
|
||||
| tail -1 \
|
||||
| sed -E 's/ *([[:digit:]]+) .*/\1/')
|
||||
|
||||
if [[ -n $greatestGenNum ]] ; then
|
||||
oldGenNum=$greatestGenNum
|
||||
@@ -18,15 +21,15 @@ function setupVars() {
|
||||
newGenNum=1
|
||||
fi
|
||||
|
||||
if [[ -e $gcPath/current-home ]] ; then
|
||||
oldGenPath="$(readlink -e "$gcPath/current-home")"
|
||||
if [[ -e $profilesPath/home-manager ]] ; then
|
||||
oldGenPath="$(readlink -e "$profilesPath/home-manager")"
|
||||
fi
|
||||
|
||||
$VERBOSE_ECHO "Sanity checking oldGenNum and oldGenPath"
|
||||
if [[ -v oldGenNum && ! -v oldGenPath
|
||||
|| ! -v oldGenNum && -v oldGenPath ]]; then
|
||||
errorEcho "Invalid profile number and GC root values! These must be"
|
||||
errorEcho "either both empty or both set but are now set to"
|
||||
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"
|
||||
@@ -35,12 +38,6 @@ function setupVars() {
|
||||
errorEcho "and trying home-manager switch again. Good luck!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
genProfilePath="$profilesPath/home-manager"
|
||||
newGenPath="@GENERATION_DIR@";
|
||||
newGenProfilePath="$profilesPath/home-manager-$newGenNum-link"
|
||||
newGenGcPath="$gcPath/current-home"
|
||||
}
|
||||
|
||||
if [[ -v VERBOSE ]]; then
|
||||
@@ -53,6 +50,11 @@ 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
|
||||
@@ -78,6 +80,5 @@ else
|
||||
fi
|
||||
$VERBOSE_ECHO " newGenPath=$newGenPath"
|
||||
$VERBOSE_ECHO " newGenNum=$newGenNum"
|
||||
$VERBOSE_ECHO " newGenProfilePath=$newGenProfilePath"
|
||||
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
|
||||
$VERBOSE_ECHO " genProfilePath=$genProfilePath"
|
||||
|
||||
@@ -13,13 +13,11 @@ with lib;
|
||||
|
||||
rec {
|
||||
|
||||
emptyDag = {};
|
||||
emptyDag = { };
|
||||
|
||||
isDag = dag:
|
||||
let
|
||||
isEntry = e: (e ? data) && (e ? after) && (e ? before);
|
||||
in
|
||||
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
|
||||
let isEntry = e: (e ? data) && (e ? after) && (e ? before);
|
||||
in builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
|
||||
|
||||
# Takes an attribute set containing entries built by
|
||||
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
|
||||
@@ -80,22 +78,19 @@ rec {
|
||||
dagTopoSort = dag:
|
||||
let
|
||||
dagBefore = dag: name:
|
||||
mapAttrsToList (n: v: n) (
|
||||
filterAttrs (n: v: any (a: a == name) v.before) dag
|
||||
);
|
||||
normalizedDag =
|
||||
mapAttrs (n: v: {
|
||||
name = n;
|
||||
data = v.data;
|
||||
after = v.after ++ dagBefore dag n;
|
||||
}) dag;
|
||||
mapAttrsToList (n: v: n)
|
||||
(filterAttrs (n: v: any (a: a == name) v.before) dag);
|
||||
normalizedDag = mapAttrs (n: v: {
|
||||
name = n;
|
||||
data = v.data;
|
||||
after = v.after ++ dagBefore dag n;
|
||||
}) dag;
|
||||
before = a: b: any (c: a.name == c) b.after;
|
||||
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
|
||||
in
|
||||
if sorted ? result then
|
||||
{ result = map (v: { inherit (v) name data; }) sorted.result; }
|
||||
else
|
||||
sorted;
|
||||
in if sorted ? result then {
|
||||
result = map (v: { inherit (v) name data; }) sorted.result;
|
||||
} else
|
||||
sorted;
|
||||
|
||||
# Applies a function to each element of the given 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.
|
||||
dagEntryAnywhere = data: {
|
||||
inherit data;
|
||||
before = [];
|
||||
after = [];
|
||||
before = [ ];
|
||||
after = [ ];
|
||||
};
|
||||
|
||||
dagEntryBetween = before: after: data: {
|
||||
inherit data before after;
|
||||
};
|
||||
dagEntryBetween = before: after: data: { inherit data before after; };
|
||||
|
||||
dagEntryAfter = after: data: {
|
||||
inherit data after;
|
||||
before = [];
|
||||
before = [ ];
|
||||
};
|
||||
|
||||
dagEntryBefore = before: data: {
|
||||
inherit data before;
|
||||
after = [];
|
||||
after = [ ];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib }:
|
||||
|
||||
{
|
||||
rec {
|
||||
dag =
|
||||
let
|
||||
d = import ./dag.nix { inherit lib; };
|
||||
@@ -16,5 +16,11 @@
|
||||
entryBefore = d.dagEntryBefore;
|
||||
};
|
||||
|
||||
gvariant = import ./gvariant.nix { inherit lib; };
|
||||
|
||||
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; };
|
||||
}
|
||||
|
||||
@@ -2,32 +2,6 @@
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
# 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
|
||||
"home_file_" + safeName;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
# Constructs a type suitable for a `home.file` like option. The
|
||||
# target path may be either absolute or relative, in which case it
|
||||
@@ -106,6 +80,18 @@ in
|
||||
into place.
|
||||
'';
|
||||
};
|
||||
|
||||
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 = {
|
||||
@@ -113,7 +99,7 @@ in
|
||||
source = mkIf (config.text != null) (
|
||||
mkDefault (pkgs.writeTextFile {
|
||||
inherit (config) executable text;
|
||||
name = storeFileName name;
|
||||
name = hm.strings.storeFileName name;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
141
modules/lib/gvariant.nix
Normal file
141
modules/lib/gvariant.nix
Normal file
@@ -0,0 +1,141 @@
|
||||
# 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}";
|
||||
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
|
||||
"";
|
||||
|
||||
in rec {
|
||||
|
||||
inherit type typeOf;
|
||||
|
||||
isArray = hasPrefix "a";
|
||||
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 [ ];
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
rec {
|
||||
# Produces a Bourne shell like variable export statement.
|
||||
export = n: v: "export ${n}=\"${toString v}\"";
|
||||
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
|
||||
|
||||
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; };
|
||||
};
|
||||
}
|
||||
88
modules/lib/types.nix
Normal file
88
modules/lib/types.nix
Normal file
@@ -0,0 +1,88 @@
|
||||
{ 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 8";
|
||||
description = ''
|
||||
The family name and size of the font within the package.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
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.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,4 +1,4 @@
|
||||
{ config, lib, pkgs, baseModules, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
@@ -6,55 +6,7 @@ let
|
||||
|
||||
cfg = config.manual;
|
||||
|
||||
/* For the purpose of generating docs, evaluate options with each derivation
|
||||
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}`. */
|
||||
homeManagerManual = import ../doc {
|
||||
inherit pkgs config;
|
||||
version = "0.1";
|
||||
revision = "master";
|
||||
options =
|
||||
let
|
||||
scrubbedEval = evalModules {
|
||||
modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ 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;
|
||||
};
|
||||
|
||||
manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";
|
||||
|
||||
helpScript = pkgs.writeScriptBin "home-manager-help" ''
|
||||
#!${pkgs.bash}/bin/bash -e
|
||||
|
||||
if [ -z "$BROWSER" ]; then
|
||||
for candidate in xdg-open open w3m; do
|
||||
BROWSER="$(type -P $candidate || true)"
|
||||
if [ -x "$BROWSER" ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$BROWSER" ]; then
|
||||
echo "$0: unable to start a web browser; please set \$BROWSER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec "$BROWSER" ${manualHtmlRoot}
|
||||
'';
|
||||
docs = import ../doc { inherit lib pkgs; };
|
||||
|
||||
in
|
||||
|
||||
@@ -83,19 +35,34 @@ in
|
||||
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 = {
|
||||
home.packages = mkMerge [
|
||||
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
|
||||
|
||||
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
|
||||
(mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ])
|
||||
(mkIf cfg.manpages.enable [ docs.manPages ])
|
||||
(mkIf cfg.json.enable [ docs.options.json ])
|
||||
];
|
||||
|
||||
# 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
|
||||
'';
|
||||
};
|
||||
|
||||
# To fix error during manpage build.
|
||||
meta = {
|
||||
maintainers = [ maintainers.rycee ];
|
||||
doc = builtins.toFile "nothingness" "";
|
||||
};
|
||||
}
|
||||
|
||||
73
modules/misc/dconf.nix
Normal file
73
modules/misc/dconf.nix
Normal file
@@ -0,0 +1,73 @@
|
||||
{ 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 != {}) {
|
||||
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.gnome3.dconf}/bin/dconf load / "<" ${iniFile}
|
||||
else
|
||||
$DCONF_DBUS_RUN_SESSION ${pkgs.gnome3.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";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -6,36 +6,100 @@ let
|
||||
|
||||
cfg = config.fonts.fontconfig;
|
||||
|
||||
in
|
||||
profileDirectory = config.home.profileDirectory;
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
|
||||
"fonts"
|
||||
"fontconfig"
|
||||
"enable"
|
||||
])
|
||||
];
|
||||
|
||||
options = {
|
||||
fonts.fontconfig = {
|
||||
enableProfileFonts = mkOption {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Configure fontconfig to discover fonts installed through
|
||||
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>.
|
||||
</para><para>
|
||||
Note, this is only necessary on non-NixOS systems.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enableProfileFonts {
|
||||
xdg.configFile."fontconfig/conf.d/10-nix-profile-fonts.conf".text = ''
|
||||
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>${config.home.profileDirectory}/lib/X11/fonts</dir>
|
||||
<dir>${config.home.profileDirectory}/share/fonts</dir>
|
||||
<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,8 +8,6 @@ let
|
||||
cfg2 = config.gtk.gtk2;
|
||||
cfg3 = config.gtk.gtk3;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
toGtk3Ini = generators.toINI {
|
||||
mkKeyValue = key: value:
|
||||
let
|
||||
@@ -29,39 +27,6 @@ let
|
||||
in
|
||||
"${n} = ${v'}";
|
||||
|
||||
toDconfIni = generators.toINI {
|
||||
mkKeyValue = key: value:
|
||||
let
|
||||
tweakVal = v:
|
||||
if isString v then "'${v}'"
|
||||
else toString v;
|
||||
in
|
||||
"${key}=${tweakVal value}";
|
||||
};
|
||||
|
||||
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 8";
|
||||
description = ''
|
||||
The family name and size of the font within the package.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
themeType = types.submodule {
|
||||
options = {
|
||||
package = mkOption {
|
||||
@@ -88,12 +53,18 @@ in
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["gtk" "gtk3" "waylandSupport"] ''
|
||||
This options is not longer needed and can be removed.
|
||||
'')
|
||||
];
|
||||
|
||||
options = {
|
||||
gtk = {
|
||||
enable = mkEnableOption "GTK 2/3 configuration";
|
||||
|
||||
font = mkOption {
|
||||
type = types.nullOr fontType;
|
||||
type = types.nullOr hm.types.fontType;
|
||||
default = null;
|
||||
description = ''
|
||||
The font to use in GTK+ 2/3 applications.
|
||||
@@ -112,63 +83,43 @@ in
|
||||
description = "The GTK+2/3 theme to use.";
|
||||
};
|
||||
|
||||
gtk2 = mkOption {
|
||||
description = "Options specific to GTK+ 2";
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "gtk-can-change-accels = 1";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.gtkrc-2.0</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
gtk2 = {
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "gtk-can-change-accels = 1";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.gtkrc-2.0</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
gtk3 = mkOption {
|
||||
description = "Options specific to GTK+ 3";
|
||||
default = {};
|
||||
type = types.submodule {
|
||||
options = {
|
||||
extraConfig = mkOption {
|
||||
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>.
|
||||
'';
|
||||
};
|
||||
gtk3 = {
|
||||
bookmarks = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "file:///home/jane/Documents" ];
|
||||
description = "Bookmarks in the sidebar of the GTK file browser";
|
||||
};
|
||||
|
||||
extraCss = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.config/gtk-3.0/gtk.css</filename>.
|
||||
'';
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
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>.
|
||||
'';
|
||||
};
|
||||
|
||||
waylandSupport = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Support GSettings provider (dconf) in addition to
|
||||
GtkSettings (INI file). This is needed for Wayland.
|
||||
</para><para>
|
||||
Note, on NixOS the following line must be in the
|
||||
system configuration:
|
||||
<programlisting>
|
||||
services.dbus.packages = [ pkgs.gnome3.dconf ];
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
};
|
||||
extraCss = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add verbatim to
|
||||
<filename>~/.config/gtk-3.0/gtk.css</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -200,7 +151,6 @@ in
|
||||
optional (opt != null && opt.package != null) opt.package;
|
||||
in
|
||||
{
|
||||
|
||||
home.packages =
|
||||
optionalPackage cfg.font
|
||||
++ optionalPackage cfg.theme
|
||||
@@ -216,22 +166,11 @@ in
|
||||
|
||||
xdg.configFile."gtk-3.0/gtk.css".text = cfg3.extraCss;
|
||||
|
||||
home.activation = mkIf cfg3.waylandSupport {
|
||||
gtk3 = dag.entryAfter ["installPackages"] (
|
||||
let
|
||||
iniText = toDconfIni { "/" = dconfIni; };
|
||||
iniFile = pkgs.writeText "gtk3.ini" iniText;
|
||||
dconfPath = "/org/gnome/desktop/interface/";
|
||||
in
|
||||
''
|
||||
if [[ -v DRY_RUN ]]; then
|
||||
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile}
|
||||
else
|
||||
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile}
|
||||
fi
|
||||
''
|
||||
);
|
||||
xdg.configFile."gtk-3.0/bookmarks" = mkIf (cfg3.bookmarks != []) {
|
||||
text = concatStringsSep "\n" cfg3.bookmarks;
|
||||
};
|
||||
|
||||
dconf.settings."org/gnome/desktop/interface" = dconfIni;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
options = {
|
||||
lib = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.attrs;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
This option allows modules to define helper functions,
|
||||
constants, etc.
|
||||
|
||||
@@ -6,6 +6,8 @@ let
|
||||
|
||||
cfg = config.news;
|
||||
|
||||
hostPlatform = pkgs.stdenv.hostPlatform;
|
||||
|
||||
entryModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
id = mkOption {
|
||||
@@ -734,7 +736,7 @@ in
|
||||
|
||||
{
|
||||
time = "2018-08-19T20:46:09+00:00";
|
||||
condition = pkgs.stdenv.isLinux;
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new modules is available: 'programs.chromium'.
|
||||
'';
|
||||
@@ -871,6 +873,614 @@ in
|
||||
A new module is available: 'services.nextcloud-client'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2018-11-25T22:55:12+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.vscode'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2018-12-04T21:54:38+00:00";
|
||||
condition = config.programs.beets.settings != {};
|
||||
message = ''
|
||||
A new option 'programs.beets.enable' has been added.
|
||||
Starting with state version 19.03 this option defaults to
|
||||
false. For earlier versions it defaults to true if
|
||||
'programs.beets.settings' is non-empty.
|
||||
|
||||
It is recommended to explicitly add
|
||||
|
||||
programs.beets.enable = true;
|
||||
|
||||
to your configuration.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2018-12-12T21:02:05+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.jq'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2018-12-24T16:26:16+00:00";
|
||||
message = ''
|
||||
A new module is available: 'dconf'.
|
||||
|
||||
Note, on NixOS you may need to add
|
||||
|
||||
services.dbus.packages = with pkgs; [ gnome3.dconf ];
|
||||
|
||||
to the system configuration for this module to work as
|
||||
expected. In particular if you get the error message
|
||||
|
||||
The name ca.desrt.dconf was not provided by any .service files
|
||||
|
||||
when activating your Home Manager configuration.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2018-12-28T12:32:30+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.opam'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-01-18T00:21:56+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.matplotlib'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-01-26T13:20:37+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.xembed-sni-proxy'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-01-28T23:36:10+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.irssi'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-02-09T14:09:58+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.emacs'.
|
||||
|
||||
This module provides a user service that runs the Emacs
|
||||
configured in
|
||||
|
||||
programs.emacs
|
||||
|
||||
as an Emacs daemon.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-02-16T20:33:56+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
When using Home Manager as a NixOS submodule it is now
|
||||
possible to install packages using the NixOS
|
||||
|
||||
users.users.<name?>.packages
|
||||
|
||||
option. This is enabled by adding
|
||||
|
||||
home-manager.useUserPackages = true;
|
||||
|
||||
to your NixOS system configuration. This mode of operation
|
||||
is necessary if you want to use 'nixos-rebuild build-vm'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-02-17T21:11:24+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.keychain'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-02-24T00:32:23+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new service is available: 'services.mpdris2'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-03-19T22:56:20+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.bat'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-03-19T23:07:34+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.lsd'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-04-09T20:10:22+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.xcape'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-04-11T22:50:10+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
The type used for the systemd unit options under
|
||||
|
||||
systemd.user.services, 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 due to this change.
|
||||
|
||||
In particular, if you get an error saying that a "unique option" is
|
||||
"defined multiple times" then you need to use 'lib.mkForce'. For
|
||||
example,
|
||||
|
||||
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
|
||||
|
||||
becomes
|
||||
|
||||
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. Apologies for potentially
|
||||
breaking your configuration!
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-04-14T15:35:16+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.skim'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-04-22T12:43:20+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.alacritty'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-04-26T22:53:48+00:00";
|
||||
condition = config.programs.vscode.enable;
|
||||
message = ''
|
||||
A new module is available: 'programs.vscode.haskell'.
|
||||
|
||||
Enable to add Haskell IDE Engine and syntax highlighting
|
||||
support to your VSCode.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-05-04T23:56:39+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.rsibreak'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-05-07T20:49:29+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.mpv'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-05-30T17:49:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.xsuspender'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-06-03T21:47:10+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.gpg'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-06-09T12:19:18+00:00";
|
||||
message = ''
|
||||
Collisions between unmanaged and managed files can now be
|
||||
automatically resolved by moving the target file to a new
|
||||
path instead of failing the switch operation. To enable
|
||||
this, use the new '-b' command line argument. For example,
|
||||
|
||||
home-manager -b bck switch
|
||||
|
||||
where 'bck' is the suffix to give the moved file. In this
|
||||
case a colliding file 'foo.conf' will be moved to
|
||||
'foo.conf.bck'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-06-19T17:49:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: `services.getmail`.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-07-02T09:27:56+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.broot'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-07-17T19:30:29+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.taskwarrior-sync'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-07-17T20:05:29+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.kakoune'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-08T11:49:35+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.hound'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-17T12:24:58+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.muchsync'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-18T14:22:41+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.dwm-status'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-08-28T10:18:07+00:00";
|
||||
condition = config.programs.vim.enable;
|
||||
message = ''
|
||||
The 'programs.vim.plugins' option now accepts packages.
|
||||
Specifying them as strings is deprecated.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-09-17T19:33:49+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.sxhkd'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-09-26T21:05:24+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.starship'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-09-26T21:47:13+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.rtorrent'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-04T20:56:29+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.pazi'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-05T21:54:04+00:00";
|
||||
condition = config.programs.zsh.enable;
|
||||
message = ''
|
||||
The 'programs.zsh.history.path' option behavior and the
|
||||
default value has changed for state version 20.03 and above.
|
||||
|
||||
Specifically, '$HOME' will no longer be prepended to the
|
||||
option value, which allows specifying absolute paths (e.g.
|
||||
using the xdg module). Also, the default value is fixed to
|
||||
'$HOME/.zsh_history' and 'dotDir' path is not prepended to
|
||||
it anymore.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-17T18:47:40+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.lorri'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-24T17:46:57+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.spotifyd'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-29T21:18:48+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.password-store'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-29T21:18:48+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.password-store-sync'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-11-29T22:46:49+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.unison'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-12-01T22:10:23+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'xdg.mime'.
|
||||
|
||||
If enabled, which it is by default, this module will create
|
||||
the XDG mime database and desktop file database caches from
|
||||
programs installed via Home Manager.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2019-12-08T19:48:26+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.readline'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-01-11T11:49:51+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.cbatticon'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-01-26T12:42:33+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'xsession.windowManager.bspwm'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-01-26T12:49:40+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.grobi'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-01-26T19:37:57+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.neomutt'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-02-23T10:19:48+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.kitty'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-02-26T21:20:55+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'wayland.windowManager.sway'
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-04T18:55:03+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'programs.abook'
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-07T11:43:26+00:00";
|
||||
condition = config.programs.fish.enable;
|
||||
message = ''
|
||||
The option 'programs.fish.functions' has been reworked in
|
||||
order to support all available flags, such as
|
||||
'--description', '--on-event', and more.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-07T13:11:43+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
The NixOS module has a new option: 'home-manager.useGlobalPkgs'.
|
||||
|
||||
This enables using the system configuration's 'pkgs'
|
||||
argument in Home Manager.
|
||||
|
||||
To learn more, see the installation section of the manual
|
||||
|
||||
https://rycee.gitlab.io/home-manager/#sec-install-nixos-module
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-07T14:12:50+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.lieer'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-07T14:12:50+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.lieer'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-15T16:55:28+00:00";
|
||||
condition = config.programs.firefox.enable;
|
||||
message = ''
|
||||
In anticipation of Firefox dropping support for extension
|
||||
sideloading[1], we now install extensions directly to
|
||||
Firefox profiles managed through Home Manager's
|
||||
|
||||
'programs.firefox.profiles'
|
||||
|
||||
option.
|
||||
|
||||
Unfortunately this will most likely trigger an "Existing
|
||||
file is in the way" error when activating your configuration
|
||||
since Firefox keeps a copy of the add-on in the location
|
||||
Home Manager wants to overwrite. If this is the case, remove
|
||||
the listed '.xpi' files and try again.
|
||||
|
||||
This change also means that extensions installed through
|
||||
Home Manager may disappear from unmanaged profiles in future
|
||||
Firefox releases.
|
||||
|
||||
[1] https://blog.mozilla.org/addons/2019/10/31/firefox-to-discontinue-sideloaded-extensions/
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-17T21:56:26+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.keynav'.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-03-24T22:17:20+00:00";
|
||||
condition = config.services.compton.enable;
|
||||
message = ''
|
||||
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 'services.compton' and 'services.picom' modules have a
|
||||
few differences:
|
||||
|
||||
- 'services.picom' has a new 'experimentalBackends'
|
||||
option.
|
||||
|
||||
- 'vSync' is now a boolean value on 'services.picom', as
|
||||
opposed to the string in 'services.compton'.
|
||||
|
||||
Migrating to the new picom service is simple - just change
|
||||
all references to 'services.compton' to 'services.picom',
|
||||
and adhere to the above changes.
|
||||
|
||||
The deprecated 'services.compton' will eventually be removed
|
||||
in the future. Please update your configurations to use
|
||||
'services.picom' as soon as possible.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-04-08T09:33:05+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'targets.genericLinux'.
|
||||
|
||||
When enabled, this module will configure various settings
|
||||
and environment variables to make Home Manager and programs
|
||||
installed through Nix work better on GNU/Linux distributions
|
||||
other than NixOS.
|
||||
|
||||
It should not be enabled if your Home Manager configuration
|
||||
is deployed on a NixOS host.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-04-08T11:51:15+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.qutebrowser'
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-04-09T09:19:38+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'services.mako'
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2020-05-12T20:09:54+00:00";
|
||||
message = ''
|
||||
A new module is available: 'programs.dircolors'
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,10 +80,9 @@ in
|
||||
inside and outside Home Manager you can put it in a separate
|
||||
file and include something like
|
||||
|
||||
<programlisting>
|
||||
<programlisting language="nix">
|
||||
nixpkgs.config = import ./nixpkgs-config.nix;
|
||||
xdg.configFile."nixpkgs/config.nix".source =
|
||||
./nixpkgs-config.nix;
|
||||
xdg.configFile."nixpkgs/config.nix".source = ./nixpkgs-config.nix;
|
||||
</programlisting>
|
||||
|
||||
in your Home Manager configuration.
|
||||
@@ -143,8 +142,11 @@ in
|
||||
|
||||
config = {
|
||||
_module.args = {
|
||||
pkgs = _pkgs;
|
||||
pkgs_i686 = if _pkgs.stdenv.isLinux then _pkgs.pkgsi686Linux else {};
|
||||
pkgs = mkOverride modules.defaultPriority _pkgs;
|
||||
pkgs_i686 =
|
||||
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86
|
||||
then _pkgs.pkgsi686Linux
|
||||
else { };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
29
modules/misc/numlock.nix
Normal file
29
modules/misc/numlock.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xsession.numlock;
|
||||
|
||||
in {
|
||||
options = { xsession.numlock.enable = mkEnableOption "Num Lock"; };
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
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" ]; };
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -6,14 +6,12 @@ let
|
||||
|
||||
vars = config.pam.sessionVariables;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
pam.sessionVariables = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = types.attrs;
|
||||
example = { EDITOR = "vim"; };
|
||||
description = ''
|
||||
@@ -27,10 +25,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (vars != {}) {
|
||||
home.file.".pam_environment".text =
|
||||
concatStringsSep "\n" (
|
||||
mapAttrsToList (n: v: "${n} OVERRIDE=${toString v}") vars
|
||||
) + "\n";
|
||||
config = mkIf (vars != { }) {
|
||||
home.file.".pam_environment".text = concatStringsSep "\n"
|
||||
(mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') vars) + "\n";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,37 +5,64 @@ with lib;
|
||||
let
|
||||
|
||||
cfg = config.qt;
|
||||
dag = config.lib.dag;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
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";
|
||||
|
||||
useGtkTheme = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
platformTheme = mkOption {
|
||||
type = types.nullOr (types.enum [ "gtk" "gnome" ]);
|
||||
default = null;
|
||||
example = "gnome";
|
||||
relatedPackages =
|
||||
[ "qgnomeplatform" [ "libsForQt5" "qtstyleplugins" ] ];
|
||||
description = ''
|
||||
Whether Qt 4 and 5 should be set up to use the GTK theme
|
||||
settings.
|
||||
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>
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable && cfg.useGtkTheme) {
|
||||
home.sessionVariables.QT_QPA_PLATFORMTHEME = "gtk2";
|
||||
home.packages = [ pkgs.libsForQt5.qtstyleplugins ];
|
||||
xsession.profileExtra =
|
||||
"systemctl --user import-environment QT_QPA_PLATFORMTHEME";
|
||||
config = mkIf (cfg.enable && cfg.platformTheme != null) {
|
||||
home.sessionVariables.QT_QPA_PLATFORMTHEME =
|
||||
if cfg.platformTheme == "gnome" then "gnome" else "gtk2";
|
||||
|
||||
home.activation.useGtkThemeInQt4 = dag.entryAfter ["writeBoundary"] ''
|
||||
home.packages = if cfg.platformTheme == "gnome" then
|
||||
[ pkgs.qgnomeplatform ]
|
||||
else
|
||||
[ pkgs.libsForQt5.qtstyleplugins ];
|
||||
|
||||
xsession.importedVariables = [ "QT_QPA_PLATFORMTHEME" ];
|
||||
|
||||
# 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 $HOME/.config/Trolltech.conf Qt style GTK+
|
||||
--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>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -5,7 +5,7 @@ with lib;
|
||||
{
|
||||
options = {
|
||||
home.stateVersion = mkOption {
|
||||
type = types.enum [ "18.09" "19.03" ];
|
||||
type = types.enum [ "18.09" "19.03" "19.09" "20.03" "20.09" ];
|
||||
default = "18.09";
|
||||
description = ''
|
||||
It is occasionally necessary for Home Manager to change
|
||||
|
||||
88
modules/misc/xdg-mime-apps.nix
Normal file
88
modules/misc/xdg-mime-apps.nix
Normal file
@@ -0,0 +1,88 @@
|
||||
{ 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 {
|
||||
# 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;
|
||||
};
|
||||
};
|
||||
}
|
||||
47
modules/misc/xdg-mime.nix
Normal file
47
modules/misc/xdg-mime.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.mime;
|
||||
|
||||
in {
|
||||
options = {
|
||||
xdg.mime.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
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 {
|
||||
home.packages = [
|
||||
# Explicitly install package to provide basic mime types.
|
||||
pkgs.shared-mime-info
|
||||
];
|
||||
|
||||
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
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
110
modules/misc/xdg-user-dirs.nix
Normal file
110
modules/misc/xdg-user-dirs.nix
Normal file
@@ -0,0 +1,110 @@
|
||||
{ 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.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
xdg.configFile."user-dirs.dirs".text = let
|
||||
options = {
|
||||
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;
|
||||
|
||||
# For some reason, these need to be wrapped with quotes to be valid.
|
||||
wrapped = mapAttrs (_: value: ''"${value}"'') options;
|
||||
in generators.toKeyValue { } wrapped;
|
||||
|
||||
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||||
};
|
||||
}
|
||||
@@ -92,10 +92,13 @@ in
|
||||
})
|
||||
|
||||
{
|
||||
home.file = mkMerge [ cfg.configFile cfg.dataFile ];
|
||||
home.activation.xdgCreateCache = dag.entryAfter [ "writeBoundary" ] ''
|
||||
$DRY_RUN_CMD mkdir $VERBOSE_ARG -m0700 -p "${config.xdg.cacheHome}"
|
||||
'';
|
||||
home.file = mkMerge [
|
||||
cfg.configFile
|
||||
cfg.dataFile
|
||||
{
|
||||
"${config.xdg.cacheHome}/.keep".text = "";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,129 +1,195 @@
|
||||
{ pkgs
|
||||
|
||||
# Note, this should be "the standard library" + HM extensions.
|
||||
, lib
|
||||
|
||||
# Whether to enable module type checking.
|
||||
, check ? true
|
||||
|
||||
# Whether these modules are inside a NixOS submodule.
|
||||
, nixosSubmodule ? false
|
||||
# If disabled, the pkgs attribute passed to this function is used instead.
|
||||
, useNixpkgsModule ? true
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
modules = [
|
||||
./accounts/email.nix
|
||||
./files.nix
|
||||
./home-environment.nix
|
||||
./manual.nix
|
||||
./misc/fontconfig.nix
|
||||
./misc/gtk.nix
|
||||
./misc/lib.nix
|
||||
./misc/news.nix
|
||||
./misc/nixpkgs.nix
|
||||
./misc/pam.nix
|
||||
./misc/qt.nix
|
||||
./misc/version.nix
|
||||
./misc/xdg.nix
|
||||
./programs/afew.nix
|
||||
./programs/alot.nix
|
||||
./programs/astroid.nix
|
||||
./programs/autorandr.nix
|
||||
./programs/bash.nix
|
||||
./programs/beets.nix
|
||||
./programs/browserpass.nix
|
||||
./programs/command-not-found/command-not-found.nix
|
||||
./programs/direnv.nix
|
||||
./programs/eclipse.nix
|
||||
./programs/emacs.nix
|
||||
./programs/feh.nix
|
||||
./programs/firefox.nix
|
||||
./programs/fish.nix
|
||||
./programs/fzf.nix
|
||||
./programs/git.nix
|
||||
./programs/gnome-terminal.nix
|
||||
./programs/go.nix
|
||||
./programs/home-manager.nix
|
||||
./programs/htop.nix
|
||||
./programs/info.nix
|
||||
./programs/lesspipe.nix
|
||||
./programs/man.nix
|
||||
./programs/mbsync.nix
|
||||
./programs/mercurial.nix
|
||||
./programs/msmtp.nix
|
||||
./programs/neovim.nix
|
||||
./programs/newsboat.nix
|
||||
./programs/noti.nix
|
||||
./programs/notmuch.nix
|
||||
./programs/obs-studio.nix
|
||||
./programs/offlineimap.nix
|
||||
./programs/pidgin.nix
|
||||
./programs/rofi.nix
|
||||
./programs/ssh.nix
|
||||
./programs/taskwarrior.nix
|
||||
./programs/termite.nix
|
||||
./programs/texlive.nix
|
||||
./programs/tmux.nix
|
||||
./programs/urxvt.nix
|
||||
./programs/vim.nix
|
||||
./programs/zathura.nix
|
||||
./programs/zsh.nix
|
||||
./services/blueman-applet.nix
|
||||
./services/compton.nix
|
||||
./services/dunst.nix
|
||||
./services/flameshot.nix
|
||||
./services/gnome-keyring.nix
|
||||
./services/gpg-agent.nix
|
||||
./services/kbfs.nix
|
||||
./services/kdeconnect.nix
|
||||
./services/keepassx.nix
|
||||
./services/keybase.nix
|
||||
./services/mbsync.nix
|
||||
./services/mpd.nix
|
||||
./services/network-manager-applet.nix
|
||||
./services/nextcloud-client.nix
|
||||
./services/owncloud-client.nix
|
||||
./services/parcellite.nix
|
||||
./services/pasystray.nix
|
||||
./services/polybar.nix
|
||||
./services/random-background.nix
|
||||
./services/redshift.nix
|
||||
./services/screen-locker.nix
|
||||
./services/stalonetray.nix
|
||||
./services/status-notifier-watcher.nix
|
||||
./services/syncthing.nix
|
||||
./services/taffybar.nix
|
||||
./services/tahoe-lafs.nix
|
||||
./services/udiskie.nix
|
||||
./services/unclutter.nix
|
||||
./services/window-managers/awesome.nix
|
||||
./services/window-managers/i3.nix
|
||||
./services/window-managers/xmonad.nix
|
||||
./services/xscreensaver.nix
|
||||
./systemd.nix
|
||||
./xcursor.nix
|
||||
./xresources.nix
|
||||
./xsession.nix
|
||||
<nixpkgs/nixos/modules/misc/assertions.nix>
|
||||
<nixpkgs/nixos/modules/misc/meta.nix>
|
||||
]
|
||||
++
|
||||
optional pkgs.stdenv.isLinux ./programs/chromium.nix;
|
||||
hostPlatform = pkgs.stdenv.hostPlatform;
|
||||
|
||||
loadModule = file: { condition ? true }: {
|
||||
inherit file condition;
|
||||
};
|
||||
|
||||
allModules = [
|
||||
(loadModule ./accounts/email.nix { })
|
||||
(loadModule ./files.nix { })
|
||||
(loadModule ./home-environment.nix { })
|
||||
(loadModule ./manual.nix { })
|
||||
(loadModule ./misc/dconf.nix { })
|
||||
(loadModule ./misc/debug.nix { })
|
||||
(loadModule ./misc/fontconfig.nix { })
|
||||
(loadModule ./misc/gtk.nix { })
|
||||
(loadModule ./misc/lib.nix { })
|
||||
(loadModule ./misc/news.nix { })
|
||||
(loadModule ./misc/nixpkgs.nix { condition = useNixpkgsModule; })
|
||||
(loadModule ./misc/numlock.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/pam.nix { })
|
||||
(loadModule ./misc/qt.nix { })
|
||||
(loadModule ./misc/submodule-support.nix { })
|
||||
(loadModule ./misc/version.nix { })
|
||||
(loadModule ./misc/xdg-mime.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg-mime-apps.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg-user-dirs.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./misc/xdg.nix { })
|
||||
(loadModule ./programs/abook.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/afew.nix { })
|
||||
(loadModule ./programs/alacritty.nix { })
|
||||
(loadModule ./programs/alot.nix { })
|
||||
(loadModule ./programs/astroid.nix { })
|
||||
(loadModule ./programs/autorandr.nix { })
|
||||
(loadModule ./programs/bash.nix { })
|
||||
(loadModule ./programs/bat.nix { })
|
||||
(loadModule ./programs/beets.nix { })
|
||||
(loadModule ./programs/broot.nix { })
|
||||
(loadModule ./programs/browserpass.nix { })
|
||||
(loadModule ./programs/chromium.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/command-not-found/command-not-found.nix { })
|
||||
(loadModule ./programs/dircolors.nix { })
|
||||
(loadModule ./programs/direnv.nix { })
|
||||
(loadModule ./programs/eclipse.nix { })
|
||||
(loadModule ./programs/emacs.nix { })
|
||||
(loadModule ./programs/feh.nix { })
|
||||
(loadModule ./programs/firefox.nix { })
|
||||
(loadModule ./programs/fish.nix { })
|
||||
(loadModule ./programs/fzf.nix { })
|
||||
(loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./programs/git.nix { })
|
||||
(loadModule ./programs/gnome-terminal.nix { })
|
||||
(loadModule ./programs/go.nix { })
|
||||
(loadModule ./programs/gpg.nix { })
|
||||
(loadModule ./programs/home-manager.nix { })
|
||||
(loadModule ./programs/htop.nix { })
|
||||
(loadModule ./programs/info.nix { })
|
||||
(loadModule ./programs/irssi.nix { })
|
||||
(loadModule ./programs/lieer.nix { })
|
||||
(loadModule ./programs/jq.nix { })
|
||||
(loadModule ./programs/kakoune.nix { })
|
||||
(loadModule ./programs/keychain.nix { })
|
||||
(loadModule ./programs/kitty.nix { })
|
||||
(loadModule ./programs/lesspipe.nix { })
|
||||
(loadModule ./programs/lsd.nix { })
|
||||
(loadModule ./programs/man.nix { })
|
||||
(loadModule ./programs/matplotlib.nix { })
|
||||
(loadModule ./programs/mbsync.nix { })
|
||||
(loadModule ./programs/mercurial.nix { })
|
||||
(loadModule ./programs/mpv.nix { })
|
||||
(loadModule ./programs/msmtp.nix { })
|
||||
(loadModule ./programs/neomutt.nix { })
|
||||
(loadModule ./programs/neovim.nix { })
|
||||
(loadModule ./programs/newsboat.nix { })
|
||||
(loadModule ./programs/noti.nix { })
|
||||
(loadModule ./programs/notmuch.nix { })
|
||||
(loadModule ./programs/obs-studio.nix { })
|
||||
(loadModule ./programs/offlineimap.nix { })
|
||||
(loadModule ./programs/opam.nix { })
|
||||
(loadModule ./programs/password-store.nix { })
|
||||
(loadModule ./programs/pazi.nix { })
|
||||
(loadModule ./programs/pidgin.nix { })
|
||||
(loadModule ./programs/qutebrowser.nix { })
|
||||
(loadModule ./programs/readline.nix { })
|
||||
(loadModule ./programs/rofi.nix { })
|
||||
(loadModule ./programs/rtorrent.nix { })
|
||||
(loadModule ./programs/skim.nix { })
|
||||
(loadModule ./programs/starship.nix { })
|
||||
(loadModule ./programs/ssh.nix { })
|
||||
(loadModule ./programs/taskwarrior.nix { })
|
||||
(loadModule ./programs/termite.nix { })
|
||||
(loadModule ./programs/texlive.nix { })
|
||||
(loadModule ./programs/tmux.nix { })
|
||||
(loadModule ./programs/urxvt.nix { })
|
||||
(loadModule ./programs/vim.nix { })
|
||||
(loadModule ./programs/vscode.nix { })
|
||||
(loadModule ./programs/vscode/haskell.nix { })
|
||||
(loadModule ./programs/z-lua.nix { })
|
||||
(loadModule ./programs/zathura.nix { })
|
||||
(loadModule ./programs/zsh.nix { })
|
||||
(loadModule ./services/blueman-applet.nix { })
|
||||
(loadModule ./services/cbatticon.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/compton.nix { })
|
||||
(loadModule ./services/dunst.nix { })
|
||||
(loadModule ./services/dwm-status.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/emacs.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/flameshot.nix { })
|
||||
(loadModule ./services/getmail.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/gnome-keyring.nix { })
|
||||
(loadModule ./services/gpg-agent.nix { })
|
||||
(loadModule ./services/grobi.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/hound.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/imapnotify.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/kbfs.nix { })
|
||||
(loadModule ./services/kdeconnect.nix { })
|
||||
(loadModule ./services/keepassx.nix { })
|
||||
(loadModule ./services/keybase.nix { })
|
||||
(loadModule ./services/keynav.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/lieer.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/lorri.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/mako.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/mbsync.nix { })
|
||||
(loadModule ./services/mpd.nix { })
|
||||
(loadModule ./services/mpdris2.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/muchsync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/network-manager-applet.nix { })
|
||||
(loadModule ./services/nextcloud-client.nix { })
|
||||
(loadModule ./services/owncloud-client.nix { })
|
||||
(loadModule ./services/parcellite.nix { })
|
||||
(loadModule ./services/password-store-sync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/pasystray.nix { })
|
||||
(loadModule ./services/picom.nix { })
|
||||
(loadModule ./services/polybar.nix { })
|
||||
(loadModule ./services/random-background.nix { })
|
||||
(loadModule ./services/redshift.nix { })
|
||||
(loadModule ./services/rsibreak.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/screen-locker.nix { })
|
||||
(loadModule ./services/stalonetray.nix { })
|
||||
(loadModule ./services/status-notifier-watcher.nix { })
|
||||
(loadModule ./services/spotifyd.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/sxhkd.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/syncthing.nix { })
|
||||
(loadModule ./services/taffybar.nix { })
|
||||
(loadModule ./services/tahoe-lafs.nix { })
|
||||
(loadModule ./services/taskwarrior-sync.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/udiskie.nix { })
|
||||
(loadModule ./services/unclutter.nix { })
|
||||
(loadModule ./services/unison.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/window-managers/awesome.nix { })
|
||||
(loadModule ./services/window-managers/bspwm/default.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/window-managers/i3-sway/i3.nix { })
|
||||
(loadModule ./services/window-managers/i3-sway/sway.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/window-managers/xmonad.nix { })
|
||||
(loadModule ./services/xcape.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/xembed-sni-proxy.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./services/xscreensaver.nix { })
|
||||
(loadModule ./services/xsuspender.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./systemd.nix { })
|
||||
(loadModule ./targets/generic-linux.nix { condition = hostPlatform.isLinux; })
|
||||
(loadModule ./xcursor.nix { })
|
||||
(loadModule ./xresources.nix { })
|
||||
(loadModule ./xsession.nix { })
|
||||
(loadModule (pkgs.path + "/nixos/modules/misc/assertions.nix") { })
|
||||
(loadModule (pkgs.path + "/nixos/modules/misc/meta.nix") { })
|
||||
];
|
||||
|
||||
modules = map (getAttr "file") (filter (getAttr "condition") allModules);
|
||||
|
||||
pkgsModule = {
|
||||
options.nixosSubmodule = mkOption {
|
||||
type = types.bool;
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
config = {
|
||||
_module.args.baseModules = modules;
|
||||
_module.args.pkgs = lib.mkDefault pkgs;
|
||||
_module.check = check;
|
||||
lib = lib.hm;
|
||||
} // optionalAttrs useNixpkgsModule {
|
||||
nixpkgs.system = mkDefault pkgs.system;
|
||||
};
|
||||
|
||||
config._module.args.baseModules = modules;
|
||||
config._module.args.pkgs = lib.mkDefault pkgs;
|
||||
config._module.check = check;
|
||||
config.lib = import ./lib { inherit lib; };
|
||||
config.nixosSubmodule = nixosSubmodule;
|
||||
config.nixpkgs.system = mkDefault pkgs.system;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
40
modules/programs/abook.nix
Normal file
40
modules/programs/abook.nix
Normal file
@@ -0,0 +1,40 @@
|
||||
{ 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 {
|
||||
home.packages = [ pkgs.abook ];
|
||||
xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") {
|
||||
text = ''
|
||||
# Generated by Home Manager.
|
||||
# See http://abook.sourceforge.net/
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
52
modules/programs/alacritty.nix
Normal file
52
modules/programs/alacritty.nix
Normal file
@@ -0,0 +1,52 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.alacritty;
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.alacritty = {
|
||||
enable = mkEnableOption "Alacritty";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
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 = [ pkgs.alacritty ];
|
||||
|
||||
xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) {
|
||||
text =
|
||||
replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pkgs:
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
@@ -13,6 +14,32 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
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 = "";
|
||||
@@ -23,10 +50,9 @@ with lib;
|
||||
};
|
||||
|
||||
config = mkIf config.notmuch.enable {
|
||||
alot.sendMailCommand = mkOptionDefault (
|
||||
if config.msmtp.enable
|
||||
then "msmtpq --read-envelope-from --read-recipients"
|
||||
else null
|
||||
);
|
||||
alot.sendMailCommand = mkOptionDefault (if config.msmtp.enable then
|
||||
"msmtpq --read-envelope-from --read-recipients"
|
||||
else
|
||||
null);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ let
|
||||
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;
|
||||
@@ -33,9 +38,10 @@ let
|
||||
boolStr (signature.showSignature == "attach");
|
||||
}
|
||||
)
|
||||
)
|
||||
+ "\n"
|
||||
+ alot.extraConfig;
|
||||
++ [ alot.extraConfig ]
|
||||
++ [ "[[[abook]]]" ]
|
||||
++ mapAttrsToList (n: v: n + "=" + v) alot.contactCompletion
|
||||
);
|
||||
|
||||
configFile =
|
||||
let
|
||||
|
||||
@@ -17,7 +17,7 @@ with lib;
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
default = { };
|
||||
example = { select_query = ""; };
|
||||
description = ''
|
||||
Extra settings to add to this astroid account configuration.
|
||||
@@ -26,8 +26,7 @@ with lib;
|
||||
};
|
||||
|
||||
config = mkIf config.notmuch.enable {
|
||||
astroid.sendMailCommand = mkIf config.msmtp.enable (
|
||||
mkOptionDefault "msmtpq --read-envelope-from --read-recipients"
|
||||
);
|
||||
astroid.sendMailCommand = mkIf config.msmtp.enable
|
||||
(mkOptionDefault "msmtpq --read-envelope-from --read-recipients");
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,35 +8,32 @@ let
|
||||
cfg = config.programs.astroid;
|
||||
|
||||
astroidAccounts =
|
||||
filterAttrs
|
||||
(n: v: v.astroid.enable)
|
||||
config.accounts.email.accounts;
|
||||
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 = folders.drafts;
|
||||
save_sent = "true";
|
||||
save_sent_to = 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;
|
||||
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
|
||||
configFile = mailAccounts:
|
||||
@@ -51,12 +48,9 @@ let
|
||||
cfg.extraConfig
|
||||
cfg.externalEditor
|
||||
];
|
||||
in
|
||||
builtins.toJSON astroidConfig;
|
||||
in builtins.toJSON astroidConfig;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options = {
|
||||
programs.astroid = {
|
||||
enable = mkEnableOption "Astroid";
|
||||
@@ -81,7 +75,8 @@ in
|
||||
"cmd" = cmd;
|
||||
};
|
||||
};
|
||||
example = "nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1";
|
||||
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:
|
||||
@@ -96,7 +91,7 @@ in
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
default = { };
|
||||
example = { poll.interval = 0; };
|
||||
description = ''
|
||||
JSON config that will override the default Astroid configuration.
|
||||
@@ -106,26 +101,15 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.programs.notmuch.maildir.synchronizeFlags;
|
||||
message = "The astroid module requires"
|
||||
+ " 'programs.notmuch.maildir.synchronizeFlags = true'.";
|
||||
}
|
||||
];
|
||||
home.packages = [ pkgs.astroid ];
|
||||
|
||||
home.packages = [ pkgs.astroid ];
|
||||
|
||||
xdg.configFile."astroid/config".source =
|
||||
pkgs.runCommand "out.json"
|
||||
{
|
||||
json = configFile astroidAccounts;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
''
|
||||
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
|
||||
'';
|
||||
xdg.configFile."astroid/config".source = pkgs.runCommand "out.json" {
|
||||
json = configFile astroidAccounts;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
} ''
|
||||
echo -n "$json" | ${pkgs.jq}/bin/jq . > $out
|
||||
'';
|
||||
|
||||
xdg.configFile."astroid/poll.sh" = {
|
||||
executable = true;
|
||||
|
||||
@@ -6,27 +6,43 @@ let
|
||||
|
||||
cfg = config.programs.autorandr;
|
||||
|
||||
matrixOf = n: m: elemType:
|
||||
mkOptionType rec {
|
||||
name = "matrixOf";
|
||||
description =
|
||||
"${toString n}×${toString m} matrix of ${elemType.description}s";
|
||||
check = xss:
|
||||
let listOfSize = l: xs: isList xs && length xs == l;
|
||||
in listOfSize n xss
|
||||
&& all (xs: listOfSize m xs && all elemType.check xs) xss;
|
||||
merge = mergeOneOption;
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "*" "*" ]);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
|
||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||
};
|
||||
|
||||
profileModule = types.submodule {
|
||||
options = {
|
||||
fingerprint = mkOption {
|
||||
type = types.attrsOf types.string;
|
||||
type = types.attrsOf types.str;
|
||||
description = ''
|
||||
Output name to EDID mapping.
|
||||
Use <code>autorandr --fingerprint</code> to get current setup values.
|
||||
'';
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.attrsOf configModule;
|
||||
description = "Per output profile configuration.";
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
|
||||
hooks = mkOption {
|
||||
type = profileHooksModule;
|
||||
description = "Profile hook scripts.";
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -46,39 +62,113 @@ let
|
||||
};
|
||||
|
||||
position = mkOption {
|
||||
type = types.string;
|
||||
type = types.str;
|
||||
description = "Output position";
|
||||
default = "";
|
||||
example = "5760x0";
|
||||
};
|
||||
|
||||
mode = mkOption {
|
||||
type = types.string;
|
||||
type = types.str;
|
||||
description = "Output resolution.";
|
||||
default = "";
|
||||
example = "3840x2160";
|
||||
};
|
||||
|
||||
rate = mkOption {
|
||||
type = types.string;
|
||||
type = types.str;
|
||||
description = "Output framerate.";
|
||||
default = "";
|
||||
example = "60.00";
|
||||
};
|
||||
|
||||
gamma = mkOption {
|
||||
type = types.string;
|
||||
type = types.str;
|
||||
description = "Output gamma configuration.";
|
||||
default = "";
|
||||
example = "1.0:0.909:0.833";
|
||||
};
|
||||
|
||||
rotate = mkOption {
|
||||
type = types.nullOr (types.enum ["normal" "left" "right" "inverted"]);
|
||||
type = types.nullOr (types.enum [ "normal" "left" "right" "inverted" ]);
|
||||
description = "Output rotate configuration.";
|
||||
default = null;
|
||||
example = "left";
|
||||
};
|
||||
|
||||
transform = mkOption {
|
||||
type = types.nullOr (matrixOf 3 3 types.float);
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
[
|
||||
[ 0.6 0.0 0.0 ]
|
||||
[ 0.0 0.6 0.0 ]
|
||||
[ 0.0 0.0 1.0 ]
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Refer to
|
||||
<citerefentry>
|
||||
<refentrytitle>xrandr</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
for the documentation of the transform matrix.
|
||||
'';
|
||||
};
|
||||
|
||||
dpi = mkOption {
|
||||
type = types.nullOr types.ints.positive;
|
||||
description = "Output DPI configuration.";
|
||||
default = null;
|
||||
example = 96;
|
||||
};
|
||||
|
||||
scale = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
method = mkOption {
|
||||
type = types.enum [ "factor" "pixel" ];
|
||||
description = "Output scaling method.";
|
||||
default = "factor";
|
||||
example = "pixel";
|
||||
};
|
||||
|
||||
x = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Horizontal scaling factor/pixels.";
|
||||
};
|
||||
|
||||
y = mkOption {
|
||||
type = types.either types.float types.ints.positive;
|
||||
description = "Vertical scaling factor/pixels.";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
Output scale configuration.
|
||||
</para><para>
|
||||
Either configure by pixels or a scaling factor. When using pixel method the
|
||||
<citerefentry>
|
||||
<refentrytitle>xrandr</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
option
|
||||
<parameter class="command">--scale-from</parameter>
|
||||
will be used; when using factor method the option
|
||||
<parameter class="command">--scale</parameter>
|
||||
will be used.
|
||||
</para><para>
|
||||
This option is a shortcut version of the transform option and they are mutually
|
||||
exclusive.
|
||||
'';
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
{
|
||||
x = 1.25;
|
||||
y = 1.25;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -89,19 +179,21 @@ let
|
||||
postswitch = mkOption {
|
||||
type = types.attrsOf hookType;
|
||||
description = "Postswitch hook executed after mode switch.";
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
|
||||
preswitch = mkOption {
|
||||
type = types.attrsOf hookType;
|
||||
description = "Preswitch hook executed before mode switch.";
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
|
||||
predetect = mkOption {
|
||||
type = types.attrsOf hookType;
|
||||
description = "Predetect hook executed before autorandr attempts to run xrandr.";
|
||||
default = {};
|
||||
description = ''
|
||||
Predetect hook executed before autorandr attempts to run xrandr.
|
||||
'';
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -122,42 +214,56 @@ let
|
||||
|
||||
predetect = mkOption {
|
||||
type = hookType;
|
||||
description = "Predetect hook executed before autorandr attempts to run xrandr.";
|
||||
description = ''
|
||||
Predetect hook executed before autorandr attempts to run xrandr.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hookToFile = folder: name: hook:
|
||||
nameValuePair
|
||||
"autorandr/${folder}/${name}"
|
||||
{ source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook"; };
|
||||
profileToFiles = name: profile: with profile; mkMerge ([
|
||||
{
|
||||
"autorandr/${name}/setup".text = concatStringsSep "\n" (mapAttrsToList fingerprintToString fingerprint);
|
||||
"autorandr/${name}/config".text = concatStringsSep "\n" (mapAttrsToList configToString profile.config);
|
||||
}
|
||||
(mkIf (hooks.postswitch != "") (listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
|
||||
(mkIf (hooks.preswitch != "") (listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
|
||||
(mkIf (hooks.predetect != "") (listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
|
||||
]);
|
||||
nameValuePair "autorandr/${folder}/${name}" {
|
||||
source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook";
|
||||
};
|
||||
profileToFiles = name: profile:
|
||||
with profile;
|
||||
mkMerge ([
|
||||
{
|
||||
"autorandr/${name}/setup".text = concatStringsSep "\n"
|
||||
(mapAttrsToList fingerprintToString fingerprint);
|
||||
"autorandr/${name}/config".text =
|
||||
concatStringsSep "\n" (mapAttrsToList configToString profile.config);
|
||||
}
|
||||
(mkIf (hooks.postswitch != "")
|
||||
(listToAttrs [ (hookToFile name "postswitch" hooks.postswitch) ]))
|
||||
(mkIf (hooks.preswitch != "")
|
||||
(listToAttrs [ (hookToFile name "preswitch" hooks.preswitch) ]))
|
||||
(mkIf (hooks.predetect != "")
|
||||
(listToAttrs [ (hookToFile name "predetect" hooks.predetect) ]))
|
||||
]);
|
||||
fingerprintToString = name: edid: "${name} ${edid}";
|
||||
configToString = name: config: if config.enable then ''
|
||||
output ${name}
|
||||
${optionalString (config.position != "") "pos ${config.position}"}
|
||||
${optionalString config.primary "primary"}
|
||||
${optionalString (config.gamma != "") "gamma ${config.gamma}"}
|
||||
${optionalString (config.mode != "") "mode ${config.mode}"}
|
||||
${optionalString (config.rate != "") "rate ${config.rate}"}
|
||||
${optionalString (config.rotate != null) "rotate ${config.rotate}"}
|
||||
'' else ''
|
||||
output ${name}
|
||||
off
|
||||
'';
|
||||
configToString = name: config:
|
||||
if config.enable then ''
|
||||
output ${name}
|
||||
${optionalString (config.position != "") "pos ${config.position}"}
|
||||
${optionalString config.primary "primary"}
|
||||
${optionalString (config.dpi != null) "dpi ${toString config.dpi}"}
|
||||
${optionalString (config.gamma != "") "gamma ${config.gamma}"}
|
||||
${optionalString (config.mode != "") "mode ${config.mode}"}
|
||||
${optionalString (config.rate != "") "rate ${config.rate}"}
|
||||
${optionalString (config.rotate != null) "rotate ${config.rotate}"}
|
||||
${optionalString (config.scale != null)
|
||||
((if config.scale.method == "factor" then "scale" else "scale-from")
|
||||
+ " ${toString config.scale.x}x${toString config.scale.y}")}
|
||||
${optionalString (config.transform != null) ("transform "
|
||||
+ concatMapStringsSep "," toString (flatten config.transform))}
|
||||
'' else ''
|
||||
output ${name}
|
||||
off
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options = {
|
||||
programs.autorandr = {
|
||||
enable = mkEnableOption "Autorandr";
|
||||
@@ -165,39 +271,39 @@ in
|
||||
hooks = mkOption {
|
||||
type = globalHooksModule;
|
||||
description = "Global hook scripts";
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
postswitch = {
|
||||
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
|
||||
"change-background" = readFile ./change-background.sh;
|
||||
"change-dpi" = '''
|
||||
case "$AUTORANDR_CURRENT_PROFILE" in
|
||||
default)
|
||||
DPI=120
|
||||
;;
|
||||
home)
|
||||
DPI=192
|
||||
;;
|
||||
work)
|
||||
DPI=144
|
||||
;;
|
||||
*)
|
||||
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
|
||||
exit 1
|
||||
esac
|
||||
{
|
||||
postswitch = {
|
||||
"notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
|
||||
"change-background" = readFile ./change-background.sh;
|
||||
"change-dpi" = '''
|
||||
case "$AUTORANDR_CURRENT_PROFILE" in
|
||||
default)
|
||||
DPI=120
|
||||
;;
|
||||
home)
|
||||
DPI=192
|
||||
;;
|
||||
work)
|
||||
DPI=144
|
||||
;;
|
||||
*)
|
||||
echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
|
||||
'''
|
||||
};
|
||||
}
|
||||
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
|
||||
'''
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
profiles = mkOption {
|
||||
type = types.attrsOf profileModule;
|
||||
description = "Autorandr profiles specification.";
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"work" = {
|
||||
@@ -226,11 +332,21 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = flatten (mapAttrsToList (profile:
|
||||
{ config, ... }:
|
||||
mapAttrsToList (output: opts: {
|
||||
assertion = opts.scale == null || opts.transform == null;
|
||||
message = ''
|
||||
Cannot use the profile output options 'scale' and 'transform' simultaneously.
|
||||
Check configuration for: programs.autorandr.profiles.${profile}.config.${output}
|
||||
'';
|
||||
}) config) cfg.profiles);
|
||||
|
||||
home.packages = [ pkgs.autorandr ];
|
||||
xdg.configFile = mkMerge ([
|
||||
(mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)
|
||||
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
|
||||
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
|
||||
(mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
|
||||
(mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
|
||||
(mkMerge (mapAttrsToList profileToFiles cfg.profiles))
|
||||
]);
|
||||
};
|
||||
|
||||
@@ -81,12 +81,17 @@ in
|
||||
|
||||
shellAliases = mkOption {
|
||||
default = {};
|
||||
example = { ll = "ls -l"; ".." = "cd .."; };
|
||||
type = types.attrsOf types.str;
|
||||
example = literalExample ''
|
||||
{
|
||||
ll = "ls -l";
|
||||
".." = "cd ..";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
An attribute set that maps aliases (the top level attribute names in
|
||||
this option) to command strings or directly to build outputs.
|
||||
'';
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
enableAutojump = mkOption {
|
||||
@@ -123,6 +128,15 @@ in
|
||||
interactive shell.
|
||||
'';
|
||||
};
|
||||
|
||||
logoutExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Extra commands that should be run when logging out of an
|
||||
interactive shell.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -195,6 +209,14 @@ in
|
||||
${cfg.bashrcExtra}
|
||||
'';
|
||||
|
||||
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
|
||||
text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
${cfg.logoutExtra}
|
||||
'';
|
||||
};
|
||||
|
||||
home.packages =
|
||||
optional (cfg.enableAutojump) pkgs.autojump;
|
||||
}
|
||||
|
||||
58
modules/programs/bat.nix
Normal file
58
modules/programs/bat.nix
Normal file
@@ -0,0 +1,58 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.bat;
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.marsam ];
|
||||
|
||||
options.programs.bat = {
|
||||
enable = mkEnableOption "bat, a cat clone with wings";
|
||||
|
||||
config = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = {
|
||||
theme = "TwoDark";
|
||||
pager = "less -FR";
|
||||
};
|
||||
description = ''
|
||||
Bat configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
themes = mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
dracula = builtins.readFile (pkgs.fetchFromGitHub {
|
||||
owner = "dracula";
|
||||
repo = "sublime"; # Bat uses sublime syntax for its themes
|
||||
rev = "26c57ec282abcaa76e57e055f38432bd827ac34e";
|
||||
sha256 = "019hfl4zbn4vm4154hh3bwk6hm7bdxbr1hdww83nabxwjn99ndhv";
|
||||
} + "/Dracula.tmTheme");
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Additional themes to provide.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.bat ];
|
||||
|
||||
xdg.configFile = mkMerge ([{
|
||||
"bat/config" = mkIf (cfg.config != { }) {
|
||||
text = concatStringsSep "\n"
|
||||
(mapAttrsToList (n: v: ''--${n}="${v}"'') cfg.config);
|
||||
};
|
||||
}] ++ flip mapAttrsToList cfg.themes
|
||||
(name: body: { "bat/themes/${name}.tmTheme" = { text = body; }; }));
|
||||
};
|
||||
}
|
||||
@@ -6,16 +6,41 @@ let
|
||||
|
||||
cfg = config.programs.beets;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
programs.beets = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = if versionAtLeast config.home.stateVersion "19.03" then
|
||||
false
|
||||
else
|
||||
cfg.settings != { };
|
||||
defaultText = "false";
|
||||
description = ''
|
||||
Whether to enable the beets music library manager. This
|
||||
defaults to <literal>false</literal> for state
|
||||
version ≥ 19.03. For earlier versions beets is enabled if
|
||||
<option>programs.beets.settings</option> is non-empty.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.beets;
|
||||
defaultText = literalExample "pkgs.beets";
|
||||
example =
|
||||
literalExample "(pkgs.beets.override { enableCheck = true; })";
|
||||
description = ''
|
||||
The <literal>beets</literal> package to use.
|
||||
Can be used to specify extensions.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/beets/config.yaml</filename>
|
||||
@@ -24,10 +49,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.settings != {}) {
|
||||
home.packages = [ pkgs.beets ];
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile."beets/config.yaml".text =
|
||||
builtins.toJSON config.programs.beets.settings;
|
||||
builtins.toJSON config.programs.beets.settings;
|
||||
};
|
||||
}
|
||||
|
||||
256
modules/programs/broot.nix
Normal file
256
modules/programs/broot.nix
Normal file
@@ -0,0 +1,256 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.broot;
|
||||
|
||||
configFile = config:
|
||||
pkgs.runCommand "conf.toml" {
|
||||
buildInputs = [ pkgs.remarshal ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
} ''
|
||||
remarshal -if json -of toml \
|
||||
< ${pkgs.writeText "verbs.json" (builtins.toJSON config)} \
|
||||
> $out
|
||||
'';
|
||||
|
||||
brootConf = {
|
||||
verbs =
|
||||
mapAttrsToList (name: value: value // { invocation = name; }) cfg.verbs;
|
||||
skin = cfg.skin;
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.aheaume ];
|
||||
|
||||
options.programs.broot = {
|
||||
enable = mkEnableOption "Broot, a better way to navigate directories";
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
verbs = mkOption {
|
||||
type = with types; attrsOf (attrsOf (either bool str));
|
||||
default = {
|
||||
"p" = { execution = ":parent"; };
|
||||
"edit" = {
|
||||
shortcut = "e";
|
||||
execution = "$EDITOR {file}";
|
||||
};
|
||||
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
|
||||
"view" = { execution = "less {file}"; };
|
||||
};
|
||||
example = literalExample ''
|
||||
{
|
||||
"p" = { execution = ":parent"; };
|
||||
"edit" = { shortcut = "e"; execution = "$EDITOR {file}" ; };
|
||||
"create {subpath}" = { execution = "$EDITOR {directory}/{subpath}"; };
|
||||
"view" = { execution = "less {file}"; };
|
||||
"blop {name}\\.{type}" = {
|
||||
execution = "/bin/mkdir {parent}/{type} && /usr/bin/nvim {parent}/{type}/{name}.{type}";
|
||||
from_shell = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Define new verbs. The attribute name indicates how the verb is
|
||||
called by the user, with placeholders for arguments.
|
||||
</para><para>
|
||||
The possible attributes are:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>execution</literal> (mandatory)</term>
|
||||
<listitem><para>how the verb is executed</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>shortcut</literal> (optional)</term>
|
||||
<listitem><para>an alternate way to call the verb (without
|
||||
the arguments part)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>leave_broot</literal> (optional)</term>
|
||||
<listitem><para>whether to quit broot on execution
|
||||
(default: <literal>true</literal>)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>from_shell</literal> (optional)</term>
|
||||
<listitem><para>whether the verb must be executed from the
|
||||
parent shell (default:
|
||||
<literal>false</literal>)</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
};
|
||||
|
||||
skin = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
status_normal_fg = "grayscale(18)";
|
||||
status_normal_bg = "grayscale(3)";
|
||||
status_error_fg = "red";
|
||||
status_error_bg = "yellow";
|
||||
tree_fg = "red";
|
||||
selected_line_bg = "grayscale(7)";
|
||||
permissions_fg = "grayscale(12)";
|
||||
size_bar_full_bg = "red";
|
||||
size_bar_void_bg = "black";
|
||||
directory_fg = "lightyellow";
|
||||
input_fg = "cyan";
|
||||
flag_value_fg = "lightyellow";
|
||||
table_border_fg = "red";
|
||||
code_fg = "lightyellow";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Color configuration.
|
||||
</para><para>
|
||||
Complete list of keys (expected to change before the v1 of broot):
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>char_match</literal></para></listitem>
|
||||
<listitem><para><literal>code</literal></para></listitem>
|
||||
<listitem><para><literal>directory</literal></para></listitem>
|
||||
<listitem><para><literal>exe</literal></para></listitem>
|
||||
<listitem><para><literal>file</literal></para></listitem>
|
||||
<listitem><para><literal>file_error</literal></para></listitem>
|
||||
<listitem><para><literal>flag_label</literal></para></listitem>
|
||||
<listitem><para><literal>flag_value</literal></para></listitem>
|
||||
<listitem><para><literal>input</literal></para></listitem>
|
||||
<listitem><para><literal>link</literal></para></listitem>
|
||||
<listitem><para><literal>permissions</literal></para></listitem>
|
||||
<listitem><para><literal>selected_line</literal></para></listitem>
|
||||
<listitem><para><literal>size_bar_full</literal></para></listitem>
|
||||
<listitem><para><literal>size_bar_void</literal></para></listitem>
|
||||
<listitem><para><literal>size_text</literal></para></listitem>
|
||||
<listitem><para><literal>spinner</literal></para></listitem>
|
||||
<listitem><para><literal>status_error</literal></para></listitem>
|
||||
<listitem><para><literal>status_normal</literal></para></listitem>
|
||||
<listitem><para><literal>table_border</literal></para></listitem>
|
||||
<listitem><para><literal>tree</literal></para></listitem>
|
||||
<listitem><para><literal>unlisted</literal></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>
|
||||
Add <literal>_fg</literal> for a foreground color and
|
||||
<literal>_bg</literal> for a background colors.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.broot ];
|
||||
|
||||
xdg.configFile."broot/conf.toml".source = configFile brootConf;
|
||||
|
||||
# Dummy file to prevent broot from trying to reinstall itself
|
||||
xdg.configFile."broot/launcher/installed".text = "";
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br {
|
||||
f=$(mktemp)
|
||||
(
|
||||
set +e
|
||||
broot --outcmd "$f" "$@"
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
rm -f "$f"
|
||||
exit "$code"
|
||||
fi
|
||||
)
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
return "$code"
|
||||
fi
|
||||
d=$(cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
}
|
||||
'');
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br {
|
||||
f=$(mktemp)
|
||||
(
|
||||
set +e
|
||||
broot --outcmd "$f" "$@"
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
rm -f "$f"
|
||||
exit "$code"
|
||||
fi
|
||||
)
|
||||
code=$?
|
||||
if [ "$code" != 0 ]; then
|
||||
return "$code"
|
||||
fi
|
||||
d=$(cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
}
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
# This script was automatically generated by the broot function
|
||||
# More information can be found in https://github.com/Canop/broot
|
||||
# This function starts broot and executes the command
|
||||
# it produces, if any.
|
||||
# It's needed because some shell commands, like `cd`,
|
||||
# have no useful effect if executed in a subshell.
|
||||
function br
|
||||
set f (mktemp)
|
||||
broot --outcmd $f $argv
|
||||
if test $status -ne 0
|
||||
rm -f "$f"
|
||||
return "$code"
|
||||
end
|
||||
set d (cat "$f")
|
||||
rm -f "$f"
|
||||
eval "$d"
|
||||
end
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -2,13 +2,7 @@
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
browsers = [
|
||||
"chrome"
|
||||
"chromium"
|
||||
"firefox"
|
||||
"vivaldi"
|
||||
];
|
||||
let browsers = [ "chrome" "chromium" "firefox" "vivaldi" ];
|
||||
in {
|
||||
options = {
|
||||
programs.browserpass = {
|
||||
@@ -24,57 +18,59 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf config.programs.browserpass.enable {
|
||||
home.file = builtins.concatLists (with pkgs.stdenv; map (x:
|
||||
home.file = foldl' (a: b: a // b) { } (concatMap (x:
|
||||
with pkgs.stdenv;
|
||||
if x == "chrome" then
|
||||
let dir = if isDarwin
|
||||
then "Library/Application Support/Google/Chrome/NativeMessagingHosts"
|
||||
else ".config/google-chrome/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
}
|
||||
]
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Google/Chrome/NativeMessagingHosts"
|
||||
else
|
||||
".config/google-chrome/NativeMessagingHosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}]
|
||||
else if x == "chromium" then
|
||||
let dir = if isDarwin
|
||||
then "Library/Application Support/Chromium/NativeMessagingHosts"
|
||||
else ".config/chromium/NativeMessagingHosts";
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Chromium/NativeMessagingHosts"
|
||||
else
|
||||
".config/chromium/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}
|
||||
]
|
||||
else if x == "firefox" then
|
||||
[ {
|
||||
target = (if isDarwin
|
||||
then "Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else ".mozilla/native-messaging-hosts")
|
||||
+ "/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/lib/mozilla/native-messaging-hosts/com.dannyvankooten.browserpass.json";
|
||||
} ]
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/firefox/com.github.browserpass.native.json";
|
||||
}]
|
||||
else if x == "vivaldi" then
|
||||
let dir = if isDarwin
|
||||
then "Library/Application Support/Vivaldi/NativeMessagingHosts"
|
||||
else ".config/vivaldi/NativeMessagingHosts";
|
||||
in [
|
||||
{
|
||||
target = "${dir}/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-host.json";
|
||||
}
|
||||
{
|
||||
target = "${dir}/../policies/managed/com.dannyvankooten.browserpass.json";
|
||||
source = "${pkgs.browserpass}/etc/chrome-policy.json";
|
||||
}
|
||||
]
|
||||
else throw "unknown browser ${x}") config.programs.browserpass.browsers);
|
||||
let
|
||||
dir = if isDarwin then
|
||||
"Library/Application Support/Vivaldi/NativeMessagingHosts"
|
||||
else
|
||||
".config/vivaldi/NativeMessagingHosts";
|
||||
in [{
|
||||
"${dir}/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json";
|
||||
"${dir}/../policies/managed/com.github.browserpass.native.json".source =
|
||||
"${pkgs.browserpass}/lib/browserpass/policies/chromium/com.github.browserpass.native.json";
|
||||
}]
|
||||
else
|
||||
throw "unknown browser ${x}") config.programs.browserpass.browsers);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,46 +5,44 @@ with lib;
|
||||
let
|
||||
|
||||
browserModule = defaultPkg: name: visible:
|
||||
let
|
||||
browser = (builtins.parseDrvName defaultPkg.name).name;
|
||||
in
|
||||
{
|
||||
enable = mkOption {
|
||||
inherit visible;
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether to enable ${name}.";
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
inherit visible;
|
||||
type = types.package;
|
||||
default = defaultPkg;
|
||||
defaultText = "pkgs.${browser}";
|
||||
description = "The ${name} package to use.";
|
||||
};
|
||||
|
||||
extensions = mkOption {
|
||||
inherit visible;
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = literalExample ''
|
||||
[
|
||||
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
|
||||
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
|
||||
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
|
||||
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of ${name} extensions to install.
|
||||
To find the extension ID, check its URL on the
|
||||
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
|
||||
'';
|
||||
};
|
||||
let browser = (builtins.parseDrvName defaultPkg.name).name;
|
||||
in {
|
||||
enable = mkOption {
|
||||
inherit visible;
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether to enable ${name}.";
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
inherit visible;
|
||||
type = types.package;
|
||||
default = defaultPkg;
|
||||
defaultText = literalExample "pkgs.${browser}";
|
||||
description = "The ${name} package to use.";
|
||||
};
|
||||
|
||||
extensions = mkOption {
|
||||
inherit visible;
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = literalExample ''
|
||||
[
|
||||
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
|
||||
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
|
||||
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
|
||||
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of ${name} extensions to install.
|
||||
To find the extension ID, check its URL on the
|
||||
<link xlink:href="https://chrome.google.com/webstore/category/extensions">Chrome Web Store</link>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
browserConfig = cfg:
|
||||
let
|
||||
|
||||
@@ -57,31 +55,32 @@ let
|
||||
google-chrome-dev = "Google/Chrome Dev";
|
||||
};
|
||||
|
||||
configDir = if pkgs.stdenv.isDarwin
|
||||
then "Library/Application Support/${getAttr browser darwinDirs}"
|
||||
else "${config.xdg.configHome}/${browser}";
|
||||
configDir = if pkgs.stdenv.isDarwin then
|
||||
"Library/Application Support/${getAttr browser darwinDirs}"
|
||||
else
|
||||
"${config.xdg.configHome}/${browser}";
|
||||
|
||||
extensionJson = ext: {
|
||||
target = "${configDir}/External Extensions/${ext}.json";
|
||||
text = builtins.toJSON {
|
||||
external_update_url = "https://clients2.google.com/service/update2/crx";
|
||||
name = "${configDir}/External Extensions/${ext}.json";
|
||||
value.text = builtins.toJSON {
|
||||
external_update_url =
|
||||
"https://clients2.google.com/service/update2/crx";
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
home.file = map extensionJson cfg.extensions;
|
||||
};
|
||||
in mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
home.file = listToAttrs (map extensionJson cfg.extensions);
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options.programs = {
|
||||
chromium = browserModule pkgs.chromium "Chromium" true;
|
||||
google-chrome = browserModule pkgs.google-chrome "Google Chrome" false;
|
||||
google-chrome-beta = browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
|
||||
google-chrome-dev = browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
|
||||
google-chrome-beta =
|
||||
browserModule pkgs.google-chrome-beta "Google Chrome Beta" false;
|
||||
google-chrome-dev =
|
||||
browserModule pkgs.google-chrome-dev "Google Chrome Dev" false;
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
|
||||
@@ -13,8 +13,11 @@ let
|
||||
isExecutable = true;
|
||||
inherit (pkgs) perl;
|
||||
inherit (cfg) dbPath;
|
||||
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
|
||||
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
|
||||
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [
|
||||
pkgs.perlPackages.DBI
|
||||
pkgs.perlPackages.DBDSQLite
|
||||
pkgs.perlPackages.StringShellQuote
|
||||
]);
|
||||
};
|
||||
|
||||
shInit = commandNotFoundHandlerName: ''
|
||||
@@ -31,14 +34,13 @@ let
|
||||
}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options.programs.command-not-found = {
|
||||
enable = mkEnableOption "command-not-found hook for interactive shell";
|
||||
|
||||
dbPath = mkOption {
|
||||
default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ;
|
||||
default =
|
||||
"/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite";
|
||||
description = ''
|
||||
Absolute path to <filename>programs.sqlite</filename>. By
|
||||
default this file will be provided by your channel
|
||||
|
||||
223
modules/programs/dircolors.nix
Normal file
223
modules/programs/dircolors.nix
Normal file
@@ -0,0 +1,223 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.dircolors;
|
||||
|
||||
formatLine = n: v: "${n} ${toString v}";
|
||||
in {
|
||||
meta.maintainers = [ hm.maintainers.justinlovinger ];
|
||||
|
||||
options.programs.dircolors = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to manage <filename>.dir_colors</filename>
|
||||
and set <code>LS_COLORS</code>.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
default = { };
|
||||
description = ''
|
||||
Options to add to <filename>.dir_colors</filename> file.
|
||||
See <command>dircolors --print-database</command>
|
||||
for options.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
OTHER_WRITABLE = "30;46";
|
||||
".sh" = "01;32";
|
||||
".csh" = "01;32";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra lines added to <filename>.dir_colors</filename> file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Add default settings from `dircolors --print-database`.
|
||||
programs.dircolors.settings = {
|
||||
RESET = mkDefault "0";
|
||||
DIR = mkDefault "01;34";
|
||||
LINK = mkDefault "01;36";
|
||||
MULTIHARDLINK = mkDefault "00";
|
||||
FIFO = mkDefault "40;33";
|
||||
SOCK = mkDefault "01;35";
|
||||
DOOR = mkDefault "01;35";
|
||||
BLK = mkDefault "40;33;01";
|
||||
CHR = mkDefault "40;33;01";
|
||||
ORPHAN = mkDefault "40;31;01";
|
||||
MISSING = mkDefault "00";
|
||||
SETUID = mkDefault "37;41";
|
||||
SETGID = mkDefault "30;43";
|
||||
CAPABILITY = mkDefault "30;41";
|
||||
STICKY_OTHER_WRITABLE = mkDefault "30;42";
|
||||
OTHER_WRITABLE = mkDefault "34;42";
|
||||
STICKY = mkDefault "37;44";
|
||||
EXEC = mkDefault "01;32";
|
||||
".tar" = mkDefault "01;31";
|
||||
".tgz" = mkDefault "01;31";
|
||||
".arc" = mkDefault "01;31";
|
||||
".arj" = mkDefault "01;31";
|
||||
".taz" = mkDefault "01;31";
|
||||
".lha" = mkDefault "01;31";
|
||||
".lz4" = mkDefault "01;31";
|
||||
".lzh" = mkDefault "01;31";
|
||||
".lzma" = mkDefault "01;31";
|
||||
".tlz" = mkDefault "01;31";
|
||||
".txz" = mkDefault "01;31";
|
||||
".tzo" = mkDefault "01;31";
|
||||
".t7z" = mkDefault "01;31";
|
||||
".zip" = mkDefault "01;31";
|
||||
".z" = mkDefault "01;31";
|
||||
".dz" = mkDefault "01;31";
|
||||
".gz" = mkDefault "01;31";
|
||||
".lrz" = mkDefault "01;31";
|
||||
".lz" = mkDefault "01;31";
|
||||
".lzo" = mkDefault "01;31";
|
||||
".xz" = mkDefault "01;31";
|
||||
".zst" = mkDefault "01;31";
|
||||
".tzst" = mkDefault "01;31";
|
||||
".bz2" = mkDefault "01;31";
|
||||
".bz" = mkDefault "01;31";
|
||||
".tbz" = mkDefault "01;31";
|
||||
".tbz2" = mkDefault "01;31";
|
||||
".tz" = mkDefault "01;31";
|
||||
".deb" = mkDefault "01;31";
|
||||
".rpm" = mkDefault "01;31";
|
||||
".jar" = mkDefault "01;31";
|
||||
".war" = mkDefault "01;31";
|
||||
".ear" = mkDefault "01;31";
|
||||
".sar" = mkDefault "01;31";
|
||||
".rar" = mkDefault "01;31";
|
||||
".alz" = mkDefault "01;31";
|
||||
".ace" = mkDefault "01;31";
|
||||
".zoo" = mkDefault "01;31";
|
||||
".cpio" = mkDefault "01;31";
|
||||
".7z" = mkDefault "01;31";
|
||||
".rz" = mkDefault "01;31";
|
||||
".cab" = mkDefault "01;31";
|
||||
".wim" = mkDefault "01;31";
|
||||
".swm" = mkDefault "01;31";
|
||||
".dwm" = mkDefault "01;31";
|
||||
".esd" = mkDefault "01;31";
|
||||
".jpg" = mkDefault "01;35";
|
||||
".jpeg" = mkDefault "01;35";
|
||||
".mjpg" = mkDefault "01;35";
|
||||
".mjpeg" = mkDefault "01;35";
|
||||
".gif" = mkDefault "01;35";
|
||||
".bmp" = mkDefault "01;35";
|
||||
".pbm" = mkDefault "01;35";
|
||||
".pgm" = mkDefault "01;35";
|
||||
".ppm" = mkDefault "01;35";
|
||||
".tga" = mkDefault "01;35";
|
||||
".xbm" = mkDefault "01;35";
|
||||
".xpm" = mkDefault "01;35";
|
||||
".tif" = mkDefault "01;35";
|
||||
".tiff" = mkDefault "01;35";
|
||||
".png" = mkDefault "01;35";
|
||||
".svg" = mkDefault "01;35";
|
||||
".svgz" = mkDefault "01;35";
|
||||
".mng" = mkDefault "01;35";
|
||||
".pcx" = mkDefault "01;35";
|
||||
".mov" = mkDefault "01;35";
|
||||
".mpg" = mkDefault "01;35";
|
||||
".mpeg" = mkDefault "01;35";
|
||||
".m2v" = mkDefault "01;35";
|
||||
".mkv" = mkDefault "01;35";
|
||||
".webm" = mkDefault "01;35";
|
||||
".ogm" = mkDefault "01;35";
|
||||
".mp4" = mkDefault "01;35";
|
||||
".m4v" = mkDefault "01;35";
|
||||
".mp4v" = mkDefault "01;35";
|
||||
".vob" = mkDefault "01;35";
|
||||
".qt" = mkDefault "01;35";
|
||||
".nuv" = mkDefault "01;35";
|
||||
".wmv" = mkDefault "01;35";
|
||||
".asf" = mkDefault "01;35";
|
||||
".rm" = mkDefault "01;35";
|
||||
".rmvb" = mkDefault "01;35";
|
||||
".flc" = mkDefault "01;35";
|
||||
".avi" = mkDefault "01;35";
|
||||
".fli" = mkDefault "01;35";
|
||||
".flv" = mkDefault "01;35";
|
||||
".gl" = mkDefault "01;35";
|
||||
".dl" = mkDefault "01;35";
|
||||
".xcf" = mkDefault "01;35";
|
||||
".xwd" = mkDefault "01;35";
|
||||
".yuv" = mkDefault "01;35";
|
||||
".cgm" = mkDefault "01;35";
|
||||
".emf" = mkDefault "01;35";
|
||||
".ogv" = mkDefault "01;35";
|
||||
".ogx" = mkDefault "01;35";
|
||||
".aac" = mkDefault "00;36";
|
||||
".au" = mkDefault "00;36";
|
||||
".flac" = mkDefault "00;36";
|
||||
".m4a" = mkDefault "00;36";
|
||||
".mid" = mkDefault "00;36";
|
||||
".midi" = mkDefault "00;36";
|
||||
".mka" = mkDefault "00;36";
|
||||
".mp3" = mkDefault "00;36";
|
||||
".mpc" = mkDefault "00;36";
|
||||
".ogg" = mkDefault "00;36";
|
||||
".ra" = mkDefault "00;36";
|
||||
".wav" = mkDefault "00;36";
|
||||
".oga" = mkDefault "00;36";
|
||||
".opus" = mkDefault "00;36";
|
||||
".spx" = mkDefault "00;36";
|
||||
".xspf" = mkDefault "00;36";
|
||||
};
|
||||
|
||||
home.file.".dir_colors".text = concatStringsSep "\n" ([ ]
|
||||
++ optional (cfg.extraConfig != "") cfg.extraConfig
|
||||
++ mapAttrsToList formatLine cfg.settings) + "\n";
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
eval (${pkgs.coreutils}/bin/dircolors -c ~/.dir_colors)
|
||||
'';
|
||||
|
||||
# Set `LS_COLORS` before Oh My Zsh and `initExtra`.
|
||||
programs.zsh.initExtraBeforeCompInit = mkIf cfg.enableZshIntegration ''
|
||||
eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors)
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -6,21 +6,17 @@ let
|
||||
|
||||
cfg = config.programs.direnv;
|
||||
configFile = config:
|
||||
pkgs.runCommand "config.toml"
|
||||
{
|
||||
buildInputs = [ pkgs.remarshal ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
''
|
||||
remarshal -if json -of toml \
|
||||
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
|
||||
> $out
|
||||
'';
|
||||
pkgs.runCommand "config.toml" {
|
||||
buildInputs = [ pkgs.remarshal ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
} ''
|
||||
remarshal -if json -of toml \
|
||||
< ${pkgs.writeText "config.json" (builtins.toJSON config)} \
|
||||
> $out
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options.programs.direnv = {
|
||||
@@ -28,7 +24,7 @@ in
|
||||
|
||||
config = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/direnv/config.toml</filename>.
|
||||
@@ -74,27 +70,31 @@ in
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableNixDirenvIntegration = mkEnableOption ''
|
||||
<link
|
||||
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
|
||||
a fast, persistent use_nix implementation for direnv'';
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.direnv ];
|
||||
|
||||
xdg.configFile."direnv/config.toml" = mkIf (cfg.config != {}) {
|
||||
source = configFile cfg.config;
|
||||
};
|
||||
xdg.configFile."direnv/config.toml" =
|
||||
mkIf (cfg.config != { }) { source = configFile cfg.config; };
|
||||
|
||||
xdg.configFile."direnv/direnvrc" = mkIf (cfg.stdlib != "") {
|
||||
text = cfg.stdlib;
|
||||
};
|
||||
xdg.configFile."direnv/direnvrc" = let
|
||||
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
|
||||
++ optional cfg.enableNixDirenvIntegration
|
||||
"source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc");
|
||||
in mkIf (text != "") { inherit text; };
|
||||
|
||||
programs.bash.initExtra =
|
||||
mkIf cfg.enableBashIntegration (
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
|
||||
''
|
||||
);
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
||||
# Using mkAfter to make it more likely to appear after other
|
||||
# manipulations of the prompt.
|
||||
mkAfter ''
|
||||
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
|
||||
'');
|
||||
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${pkgs.direnv}/bin/direnv hook zsh)"
|
||||
|
||||
@@ -6,9 +6,7 @@ let
|
||||
|
||||
cfg = config.programs.eclipse;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
@@ -27,13 +25,13 @@ in
|
||||
|
||||
jvmArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
description = "JVM arguments to use for the Eclipse process.";
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
default = [ ];
|
||||
description = "Plugins that should be added to Eclipse.";
|
||||
};
|
||||
};
|
||||
@@ -43,10 +41,8 @@ in
|
||||
home.packages = [
|
||||
(pkgs.eclipses.eclipseWithPlugins {
|
||||
eclipse = pkgs.eclipses.eclipse-platform;
|
||||
jvmArgs =
|
||||
cfg.jvmArgs
|
||||
++ optional cfg.enableLombok
|
||||
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
|
||||
jvmArgs = cfg.jvmArgs ++ optional cfg.enableLombok
|
||||
"-javaagent:${pkgs.lombok}/share/java/lombok.jar";
|
||||
plugins = cfg.plugins;
|
||||
})
|
||||
];
|
||||
|
||||
@@ -6,8 +6,13 @@ let
|
||||
|
||||
cfg = config.programs.emacs;
|
||||
|
||||
# Copied from all-packages.nix.
|
||||
emacsPackages = pkgs.emacsPackagesNgGen cfg.package;
|
||||
# Copied from all-packages.nix, with modifications to support
|
||||
# overrides.
|
||||
emacsPackages =
|
||||
let
|
||||
epkgs = pkgs.emacsPackagesGen cfg.package;
|
||||
in
|
||||
epkgs.overrideScope' cfg.overrides;
|
||||
emacsWithPackages = emacsPackages.emacsWithPackages;
|
||||
|
||||
in
|
||||
@@ -22,30 +27,51 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.emacs;
|
||||
defaultText = "pkgs.emacs";
|
||||
defaultText = literalExample "pkgs.emacs";
|
||||
example = literalExample "pkgs.emacs25-nox";
|
||||
description = "The Emacs package to use.";
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
default = self: [];
|
||||
type = hm.types.selectorFunction;
|
||||
defaultText = "epkgs: []";
|
||||
example = literalExample "epkgs: [ epkgs.emms epkgs.magit ]";
|
||||
description = "Extra packages available to Emacs.";
|
||||
description = ''
|
||||
Extra packages available to Emacs. To get a list of
|
||||
available packages run:
|
||||
<command>nix-env -f '<nixpkgs>' -qaP -A emacsPackages</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
overrides = mkOption {
|
||||
default = self: super: {};
|
||||
type = hm.types.overlayFunction;
|
||||
defaultText = "self: super: {}";
|
||||
example = literalExample ''
|
||||
self: super: rec {
|
||||
haskell-mode = self.melpaPackages.haskell-mode;
|
||||
# ...
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
Allows overriding packages within the Emacs package set.
|
||||
'';
|
||||
};
|
||||
|
||||
finalPackage = mkOption {
|
||||
type = types.package;
|
||||
internal = true;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
description = "The Emacs package including any extra packages.";
|
||||
description = ''
|
||||
The Emacs package including any overrides and extra packages.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.finalPackage ];
|
||||
|
||||
programs.emacs.finalPackage = emacsWithPackages cfg.extraPackages;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,20 +7,37 @@ let
|
||||
cfg = config.programs.feh;
|
||||
|
||||
disableBinding = func: key: func;
|
||||
enableBinding = func: key: "${func} ${key}";
|
||||
enableBinding = func: key: "${func} ${toString key}";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options.programs.feh = {
|
||||
enable = mkEnableOption "feh - a fast and light image viewer";
|
||||
|
||||
keybindings = mkOption {
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
example = { zoom_in = "plus"; zoom_out = "minus"; };
|
||||
buttons = mkOption {
|
||||
default = { };
|
||||
type = with types; attrsOf (nullOr (either str int));
|
||||
example = {
|
||||
zoom_in = 4;
|
||||
zoom_out = "C-4";
|
||||
};
|
||||
description = ''
|
||||
Set keybindings.
|
||||
Override feh's default mouse button mapping. If you want to disable an
|
||||
action, set its value to null.
|
||||
See <link xlink:href="https://man.finalrewind.org/1/feh/#x425554544f4e53"/> for
|
||||
default bindings and available commands.
|
||||
'';
|
||||
};
|
||||
|
||||
keybindings = mkOption {
|
||||
default = { };
|
||||
type = types.attrsOf (types.nullOr types.str);
|
||||
example = {
|
||||
zoom_in = "plus";
|
||||
zoom_out = "minus";
|
||||
};
|
||||
description = ''
|
||||
Override feh's default keybindings. If you want to disable a keybinding
|
||||
set its value to null.
|
||||
See <link xlink:href="https://man.finalrewind.org/1/feh/#x4b455953"/> for
|
||||
default bindings and available commands.
|
||||
'';
|
||||
@@ -28,14 +45,26 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [{
|
||||
assertion = ((filterAttrs (n: v: v == "") cfg.keybindings) == { });
|
||||
message =
|
||||
"To disable a keybinding, use `null` instead of an empty string.";
|
||||
}];
|
||||
|
||||
home.packages = [ pkgs.feh ];
|
||||
|
||||
xdg.configFile."feh/keys".text = ''
|
||||
# Disable default keybindings
|
||||
${concatStringsSep "\n" (mapAttrsToList disableBinding cfg.keybindings)}
|
||||
xdg.configFile."feh/buttons".text = ''
|
||||
${concatStringsSep "\n" (mapAttrsToList disableBinding
|
||||
(filterAttrs (n: v: v == null) cfg.buttons))}
|
||||
${concatStringsSep "\n" (mapAttrsToList enableBinding
|
||||
(filterAttrs (n: v: v != null) cfg.buttons))}
|
||||
'';
|
||||
|
||||
# Enable new keybindings
|
||||
${concatStringsSep "\n" (mapAttrsToList enableBinding cfg.keybindings)}
|
||||
xdg.configFile."feh/keys".text = ''
|
||||
${concatStringsSep "\n" (mapAttrsToList disableBinding
|
||||
(filterAttrs (n: v: v == null) cfg.keybindings))}
|
||||
${concatStringsSep "\n" (mapAttrsToList enableBinding
|
||||
(filterAttrs (n: v: v != null) cfg.keybindings))}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,22 +4,205 @@ with lib;
|
||||
|
||||
let
|
||||
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
cfg = config.programs.firefox;
|
||||
|
||||
mozillaConfigPath =
|
||||
if isDarwin
|
||||
then "Library/Application Support/Mozilla"
|
||||
else ".mozilla";
|
||||
|
||||
firefoxConfigPath =
|
||||
if isDarwin
|
||||
then "Library/Application Support/Firefox"
|
||||
else "${mozillaConfigPath}/firefox";
|
||||
|
||||
profilesPath =
|
||||
if isDarwin
|
||||
then "${firefoxConfigPath}/Profiles"
|
||||
else firefoxConfigPath;
|
||||
|
||||
# The extensions path shared by all profiles; will not be supported
|
||||
# by future Firefox versions.
|
||||
extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
|
||||
|
||||
extensionsEnvPkg = pkgs.buildEnv {
|
||||
name = "hm-firefox-extensions";
|
||||
paths = cfg.extensions;
|
||||
};
|
||||
|
||||
profiles =
|
||||
flip mapAttrs' cfg.profiles (_: profile:
|
||||
nameValuePair "Profile${toString profile.id}" {
|
||||
Name = profile.name;
|
||||
Path =
|
||||
if isDarwin
|
||||
then "Profiles/${profile.path}"
|
||||
else profile.path;
|
||||
IsRelative = 1;
|
||||
Default = if profile.isDefault then 1 else 0;
|
||||
}
|
||||
) // {
|
||||
General = {
|
||||
StartWithLastProfile = 1;
|
||||
};
|
||||
};
|
||||
|
||||
profilesIni = generators.toINI {} profiles;
|
||||
|
||||
mkUserJs = prefs: extraPrefs: ''
|
||||
// Generated by Home Manager.
|
||||
|
||||
${concatStrings (mapAttrsToList (name: value: ''
|
||||
user_pref("${name}", ${builtins.toJSON value});
|
||||
'') prefs)}
|
||||
|
||||
${extraPrefs}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["programs" "firefox" "enableGoogleTalk"]
|
||||
"Support for this option has been removed.")
|
||||
(mkRemovedOptionModule ["programs" "firefox" "enableIcedTea"]
|
||||
"Support for this option has been removed.")
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.firefox = {
|
||||
enable = mkEnableOption "Firefox";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.firefox-unwrapped;
|
||||
defaultText = "pkgs.firefox-unwrapped";
|
||||
description = "The unwrapped Firefox package to use.";
|
||||
default =
|
||||
if versionAtLeast config.home.stateVersion "19.09"
|
||||
then pkgs.firefox
|
||||
else pkgs.firefox-unwrapped;
|
||||
defaultText = literalExample "pkgs.firefox";
|
||||
description = ''
|
||||
The Firefox package to use. If state version ≥ 19.09 then
|
||||
this should be a wrapped Firefox package. For earlier state
|
||||
versions it should be an unwrapped Firefox package.
|
||||
'';
|
||||
};
|
||||
|
||||
extensions = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
example = literalExample ''
|
||||
with pkgs.nur.repos.rycee.firefox-addons; [
|
||||
https-everywhere
|
||||
privacy-badger
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
List of Firefox add-on packages to install. Some
|
||||
pre-packaged add-ons are accessible from NUR,
|
||||
<link xlink:href="https://github.com/nix-community/NUR"/>.
|
||||
Once you have NUR installed run
|
||||
|
||||
<screen language="console">
|
||||
<prompt>$</prompt> <userinput>nix-env -f '<nixpkgs>' -qaP -A nur.repos.rycee.firefox-addons</userinput>
|
||||
</screen>
|
||||
|
||||
to list the available Firefox add-ons.
|
||||
</para><para>
|
||||
Note that it is necessary to manually enable these
|
||||
extensions inside Firefox after the first installation.
|
||||
'';
|
||||
};
|
||||
|
||||
profiles = mkOption {
|
||||
type = types.attrsOf (types.submodule ({config, name, ...}: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Profile name.";
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
Profile ID. This should be set to a unique number per profile.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (either bool (either int str));
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
"browser.startup.homepage" = "https://nixos.org";
|
||||
"browser.search.region" = "GB";
|
||||
"browser.search.isUS" = false;
|
||||
"distribution.searchplugins.defaultLocale" = "en-GB";
|
||||
"general.useragent.locale" = "en-GB";
|
||||
"browser.bookmarks.showMobileBookmarks" = true;
|
||||
}
|
||||
'';
|
||||
description = "Attribute set of Firefox preferences.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra preferences to add to <filename>user.js</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
userChrome = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Custom Firefox user chrome CSS.";
|
||||
example = ''
|
||||
/* Hide tab bar in FF Quantum */
|
||||
@-moz-document url("chrome://browser/content/browser.xul") {
|
||||
#TabsToolbar {
|
||||
visibility: collapse !important;
|
||||
margin-bottom: 21px !important;
|
||||
}
|
||||
|
||||
#sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"] #sidebar-header {
|
||||
visibility: collapse !important;
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
userContent = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Custom Firefox user content CSS.";
|
||||
example = ''
|
||||
/* Hide scrollbar in FF Quantum */
|
||||
*{scrollbar-width:none !important}
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "Profile path.";
|
||||
};
|
||||
|
||||
isDefault = mkOption {
|
||||
type = types.bool;
|
||||
default = config.id == 0;
|
||||
defaultText = "true if profile ID is 0";
|
||||
description = "Whether this is a default profile.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = {};
|
||||
description = "Attribute set of Firefox profiles.";
|
||||
};
|
||||
|
||||
enableAdobeFlash = mkOption {
|
||||
@@ -27,38 +210,100 @@ in
|
||||
default = false;
|
||||
description = "Whether to enable the unfree Adobe Flash plugin.";
|
||||
};
|
||||
|
||||
enableGoogleTalk = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the unfree Google Talk plugin.";
|
||||
};
|
||||
|
||||
enableIcedTea = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the Java applet plugin.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(
|
||||
let
|
||||
defaults =
|
||||
catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles));
|
||||
in {
|
||||
assertion = cfg.profiles == {} || length defaults == 1;
|
||||
message =
|
||||
"Must have exactly one default Firefox profile but found "
|
||||
+ toString (length defaults)
|
||||
+ optionalString (length defaults > 1)
|
||||
(", namely " + concatStringsSep ", " defaults);
|
||||
}
|
||||
)
|
||||
|
||||
(
|
||||
let
|
||||
duplicates =
|
||||
filterAttrs (_: v: length v != 1)
|
||||
(zipAttrs
|
||||
(mapAttrsToList (n: v: { "${toString v.id}" = n; })
|
||||
(cfg.profiles)));
|
||||
|
||||
mkMsg = n: v: " - ID ${n} is used by ${concatStringsSep ", " v}";
|
||||
in {
|
||||
assertion = duplicates == {};
|
||||
message =
|
||||
"Must not have Firefox profiles with duplicate IDs but\n"
|
||||
+ concatStringsSep "\n" (mapAttrsToList mkMsg duplicates);
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
home.packages =
|
||||
let
|
||||
# The configuration expected by the Firefox wrapper.
|
||||
fcfg = {
|
||||
enableAdobeFlash = cfg.enableAdobeFlash;
|
||||
};
|
||||
|
||||
# A bit of hackery to force a config into the wrapper.
|
||||
browserName = cfg.package.browserName
|
||||
or (builtins.parseDrvName cfg.package.name).name;
|
||||
|
||||
fcfg = setAttrByPath [browserName] {
|
||||
enableAdobeFlash = cfg.enableAdobeFlash;
|
||||
enableGoogleTalkPlugin = cfg.enableGoogleTalk;
|
||||
icedtea = cfg.enableIcedTea;
|
||||
# The configuration expected by the Firefox wrapper builder.
|
||||
bcfg = setAttrByPath [browserName] fcfg;
|
||||
|
||||
package =
|
||||
if isDarwin then
|
||||
cfg.package
|
||||
else if versionAtLeast config.home.stateVersion "19.09" then
|
||||
cfg.package.override { cfg = fcfg; }
|
||||
else
|
||||
(pkgs.wrapFirefox.override { config = bcfg; }) cfg.package { };
|
||||
in
|
||||
[ package ];
|
||||
|
||||
home.file = mkMerge (
|
||||
[{
|
||||
"${mozillaConfigPath}/${extensionPath}" = mkIf (cfg.extensions != []) {
|
||||
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
wrapper = pkgs.wrapFirefox.override {
|
||||
config = fcfg;
|
||||
"${firefoxConfigPath}/profiles.ini" = mkIf (cfg.profiles != {}) {
|
||||
text = profilesIni;
|
||||
};
|
||||
in
|
||||
[ (wrapper cfg.package { }) ];
|
||||
}]
|
||||
++ flip mapAttrsToList cfg.profiles (_: profile: {
|
||||
"${profilesPath}/${profile.path}/chrome/userChrome.css" =
|
||||
mkIf (profile.userChrome != "") {
|
||||
text = profile.userChrome;
|
||||
};
|
||||
|
||||
"${profilesPath}/${profile.path}/chrome/userContent.css" =
|
||||
mkIf (profile.userContent != "") {
|
||||
text = profile.userContent;
|
||||
};
|
||||
|
||||
"${profilesPath}/${profile.path}/user.js" =
|
||||
mkIf (profile.settings != {} || profile.extraConfig != "") {
|
||||
text = mkUserJs profile.settings profile.extraConfig;
|
||||
};
|
||||
|
||||
"${profilesPath}/${profile.path}/extensions" = mkIf (cfg.extensions != []) {
|
||||
source = "${extensionsEnvPkg}/share/mozilla/${extensionPath}";
|
||||
recursive = true;
|
||||
force = true;
|
||||
};
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,114 +6,453 @@ let
|
||||
|
||||
cfg = config.programs.fish;
|
||||
|
||||
abbrsStr = concatStringsSep "\n" (
|
||||
mapAttrsToList (k: v: "abbr --add ${k} '${v}'") cfg.shellAbbrs
|
||||
);
|
||||
|
||||
aliasesStr = concatStringsSep "\n" (
|
||||
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.fish = {
|
||||
enable = mkEnableOption "fish friendly interactive shell";
|
||||
|
||||
shellAliases = mkOption {
|
||||
default = {};
|
||||
pluginModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Set of aliases for fish shell. See
|
||||
<option>environment.shellAliases</option> for an option
|
||||
format description.
|
||||
Path to the plugin folder.
|
||||
</para><para>
|
||||
Relevant pieces will be added to the fish function path and
|
||||
the completion path. The <filename>init.fish</filename> and
|
||||
<filename>key_binding.fish</filename> files are sourced if
|
||||
they exist.
|
||||
'';
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
shellAbbrs = mkOption {
|
||||
default = {};
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Set of abbreviations for fish shell.
|
||||
The name of the plugin.
|
||||
'';
|
||||
type = types.attrs;
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
shellInit = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during fish shell initialisation.
|
||||
'';
|
||||
functionModule = types.submodule {
|
||||
options = {
|
||||
body = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
The function body.
|
||||
'';
|
||||
};
|
||||
|
||||
loginShellInit = mkOption {
|
||||
default = "";
|
||||
argumentNames = mkOption {
|
||||
type = with types; nullOr (either str (listOf str));
|
||||
default = null;
|
||||
description = ''
|
||||
Shell script code called during fish login shell initialisation.
|
||||
Assigns the value of successive command line arguments to the names
|
||||
given.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
interactiveShellInit = mkOption {
|
||||
default = "";
|
||||
description = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Shell script code called during interactive fish shell initialisation.
|
||||
A description of what the function does, suitable as a completion
|
||||
description.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
promptInit = mkOption {
|
||||
default = "";
|
||||
wraps = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Shell script code used to initialise fish prompt.
|
||||
Causes the function to inherit completions from the given wrapped
|
||||
command.
|
||||
'';
|
||||
};
|
||||
|
||||
onEvent = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Tells fish to run this function when the specified named event is
|
||||
emitted. Fish internally generates named events e.g. when showing the
|
||||
prompt.
|
||||
'';
|
||||
};
|
||||
|
||||
onVariable = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Tells fish to run this function when the specified variable changes
|
||||
value.
|
||||
'';
|
||||
};
|
||||
|
||||
onJobExit = mkOption {
|
||||
type = with types; nullOr (either str int);
|
||||
default = null;
|
||||
description = ''
|
||||
Tells fish to run this function when the job with the specified group
|
||||
ID exits. Instead of a PID, the stringer <literal>caller</literal> can
|
||||
be specified. This is only legal when in a command substitution, and
|
||||
will result in the handler being triggered by the exit of the job
|
||||
which created this command substitution.
|
||||
'';
|
||||
};
|
||||
|
||||
onProcessExit = mkOption {
|
||||
type = with types; nullOr (either str int);
|
||||
default = null;
|
||||
example = "$fish_pid";
|
||||
description = ''
|
||||
Tells fish to run this function when the fish child process with the
|
||||
specified process ID exits. Instead of a PID, for backwards
|
||||
compatibility, <literal>%self</literal> can be specified as an alias
|
||||
for <literal>$fish_pid</literal>, and the function will be run when
|
||||
the current fish instance exits.
|
||||
'';
|
||||
};
|
||||
|
||||
onSignal = mkOption {
|
||||
type = with types; nullOr (either str int);
|
||||
default = null;
|
||||
example = [ "SIGHUP" "HUP" 1 ];
|
||||
description = ''
|
||||
Tells fish to run this function when the specified signal is
|
||||
delievered. The signal can be a signal number or signal name.
|
||||
'';
|
||||
};
|
||||
|
||||
noScopeShadowing = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Allows the function to access the variables of calling functions.
|
||||
'';
|
||||
};
|
||||
|
||||
inheritVariable = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Snapshots the value of the specified variable and defines a local
|
||||
variable with that same name and value when the function is defined.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.fish ];
|
||||
abbrsStr = concatStringsSep "\n"
|
||||
(mapAttrsToList (k: v: "abbr --add --global -- ${k} ${escapeShellArg v}")
|
||||
cfg.shellAbbrs);
|
||||
|
||||
xdg.configFile."fish/config.fish".text = ''
|
||||
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.
|
||||
# if we haven't sourced the general config, do it
|
||||
if not set -q __fish_general_config_sourced
|
||||
set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
|
||||
fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null
|
||||
set -e fish_function_path[1]
|
||||
aliasesStr = concatStringsSep "\n"
|
||||
(mapAttrsToList (k: v: "alias ${k} ${escapeShellArg v}") cfg.shellAliases);
|
||||
|
||||
${cfg.shellInit}
|
||||
# and leave a note so we don't source this config section again from
|
||||
# this very shell (children will source the general config anew)
|
||||
set -g __fish_general_config_sourced 1
|
||||
end
|
||||
# if we haven't sourced the login config, do it
|
||||
status --is-login; and not set -q __fish_login_config_sourced
|
||||
and begin
|
||||
in {
|
||||
options = {
|
||||
programs.fish = {
|
||||
enable = mkEnableOption "fish, the friendly interactive shell";
|
||||
|
||||
${cfg.loginShellInit}
|
||||
# and leave a note so we don't source this config section again from
|
||||
# this very shell (children will source the general config anew)
|
||||
set -g __fish_login_config_sourced 1
|
||||
end
|
||||
# if we haven't sourced the interactive config, do it
|
||||
status --is-interactive; and not set -q __fish_interactive_config_sourced
|
||||
and begin
|
||||
# Abbrs
|
||||
${abbrsStr}
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.fish;
|
||||
defaultText = literalExample "pkgs.fish";
|
||||
description = ''
|
||||
The fish package to install. May be used to change the version.
|
||||
'';
|
||||
};
|
||||
|
||||
# Aliases
|
||||
${aliasesStr}
|
||||
shellAliases = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
ll = "ls -l";
|
||||
".." = "cd ..";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
An attribute set that maps aliases (the top level attribute names
|
||||
in this option) to command strings or directly to build outputs.
|
||||
'';
|
||||
};
|
||||
|
||||
shellAbbrs = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
default = { };
|
||||
example = {
|
||||
l = "less";
|
||||
gco = "git checkout";
|
||||
};
|
||||
description = ''
|
||||
An attribute set that maps aliases (the top level attribute names
|
||||
in this option) to abbreviations. Abbreviations are expanded with
|
||||
the longer phrase after they are entered.
|
||||
'';
|
||||
};
|
||||
|
||||
shellInit = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during fish shell
|
||||
initialisation.
|
||||
'';
|
||||
};
|
||||
|
||||
loginShellInit = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during fish login shell
|
||||
initialisation.
|
||||
'';
|
||||
};
|
||||
|
||||
interactiveShellInit = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code called during interactive fish shell
|
||||
initialisation.
|
||||
'';
|
||||
};
|
||||
|
||||
promptInit = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Shell script code used to initialise fish prompt.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
programs.fish.plugins = mkOption {
|
||||
type = types.listOf pluginModule;
|
||||
default = [ ];
|
||||
example = literalExample ''
|
||||
[
|
||||
{
|
||||
name = "z";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "jethrokuan";
|
||||
repo = "z";
|
||||
rev = "ddeb28a7b6a1f0ec6dae40c636e5ca4908ad160a";
|
||||
sha256 = "0c5i7sdrsp0q3vbziqzdyqn4fmp235ax4mn4zslrswvn8g3fvdyh";
|
||||
};
|
||||
}
|
||||
|
||||
# oh-my-fish plugins are stored in their own repositories, which
|
||||
# makes them simple to import into home-manager.
|
||||
{
|
||||
name = "fasd";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "oh-my-fish";
|
||||
repo = "plugin-fasd";
|
||||
rev = "38a5b6b6011106092009549e52249c6d6f501fba";
|
||||
sha256 = "06v37hqy5yrv5a6ssd1p3cjd9y3hnp19d3ab7dag56fs1qmgyhbs";
|
||||
};
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
The plugins to source in
|
||||
<filename>conf.d/99plugins.fish</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
programs.fish.functions = mkOption {
|
||||
type = with types; attrsOf (either lines functionModule);
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
__fish_command_not_found_handler = {
|
||||
body = "__fish_default_command_not_found_handler $argv[1]";
|
||||
onEvent = "fish_command_not_found";
|
||||
};
|
||||
|
||||
gitignore = "curl -sL https://www.gitignore.io/api/$argv";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Basic functions to add to fish. For more information see
|
||||
<link xlink:href="https://fishshell.com/docs/current/cmds/function.html"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
${cfg.promptInit}
|
||||
${cfg.interactiveShellInit}
|
||||
# and leave a note so we don't source this config section again from
|
||||
# this very shell (children will source the general config anew,
|
||||
# allowing configuration changes in, e.g, aliases, to propagate)
|
||||
set -g __fish_interactive_config_sourced 1
|
||||
end
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.dataFile."fish/home-manager_generated_completions".source = let
|
||||
# paths later in the list will overwrite those already linked
|
||||
destructiveSymlinkJoin = args_@{ name, paths, preferLocalBuild ? true
|
||||
, allowSubstitutes ? false, postBuild ? "", ... }:
|
||||
let
|
||||
args = removeAttrs args_ [ "name" "postBuild" ] // {
|
||||
# pass the defaults
|
||||
inherit preferLocalBuild allowSubstitutes;
|
||||
};
|
||||
in pkgs.runCommand name args ''
|
||||
mkdir -p $out
|
||||
for i in $paths; do
|
||||
if [ -z "$(find $i -prune -empty)" ]; then
|
||||
cp -srf $i/* $out
|
||||
fi
|
||||
done
|
||||
${postBuild}
|
||||
'';
|
||||
|
||||
generateCompletions = package:
|
||||
pkgs.runCommand "${package.name}-fish-completions" {
|
||||
src = package;
|
||||
nativeBuildInputs = [ pkgs.python2 ];
|
||||
buildInputs = [ cfg.package ];
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
} ''
|
||||
mkdir -p $out
|
||||
if [ -d $src/share/man ]; then
|
||||
find $src/share/man -type f \
|
||||
| xargs python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out \
|
||||
> /dev/null
|
||||
fi
|
||||
'';
|
||||
in destructiveSymlinkJoin {
|
||||
name = "${config.home.username}-fish-completions";
|
||||
paths =
|
||||
let cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
|
||||
in map generateCompletions (sort cmp config.home.packages);
|
||||
};
|
||||
|
||||
programs.fish.interactiveShellInit = ''
|
||||
# add completions generated by Home Manager to $fish_complete_path
|
||||
begin
|
||||
set -l joined (string join " " $fish_complete_path)
|
||||
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
|
||||
set -l post_joined (string replace $prev_joined "" $joined)
|
||||
set -l prev (string split " " (string trim $prev_joined))
|
||||
set -l post (string split " " (string trim $post_joined))
|
||||
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
|
||||
end
|
||||
'';
|
||||
|
||||
xdg.configFile."fish/config.fish".text = ''
|
||||
# ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated
|
||||
# automatically by home-manager.
|
||||
|
||||
# if we haven't sourced the general config, do it
|
||||
if not set -q __fish_general_config_sourced
|
||||
|
||||
set -p fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions
|
||||
fenv source ${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh > /dev/null
|
||||
set -e fish_function_path[1]
|
||||
|
||||
${cfg.shellInit}
|
||||
# and leave a note so we don't source this config section again from
|
||||
# this very shell (children will source the general config anew)
|
||||
set -g __fish_general_config_sourced 1
|
||||
|
||||
end
|
||||
|
||||
# if we haven't sourced the login config, do it
|
||||
status --is-login; and not set -q __fish_login_config_sourced
|
||||
and begin
|
||||
|
||||
# Login shell initialisation
|
||||
${cfg.loginShellInit}
|
||||
|
||||
# and leave a note so we don't source this config section again from
|
||||
# this very shell (children will source the general config anew)
|
||||
set -g __fish_login_config_sourced 1
|
||||
|
||||
end
|
||||
|
||||
# if we haven't sourced the interactive config, do it
|
||||
status --is-interactive; and not set -q __fish_interactive_config_sourced
|
||||
and begin
|
||||
|
||||
# Abbreviations
|
||||
${abbrsStr}
|
||||
|
||||
# Aliases
|
||||
${aliasesStr}
|
||||
|
||||
# Prompt initialisation
|
||||
${cfg.promptInit}
|
||||
|
||||
# Interactive shell intialisation
|
||||
${cfg.interactiveShellInit}
|
||||
|
||||
# and leave a note so we don't source this config section again from
|
||||
# this very shell (children will source the general config anew,
|
||||
# allowing configuration changes in, e.g, aliases, to propagate)
|
||||
set -g __fish_interactive_config_sourced 1
|
||||
|
||||
end
|
||||
'';
|
||||
}
|
||||
{
|
||||
xdg.configFile = mapAttrs' (name: def: {
|
||||
name = "fish/functions/${name}.fish";
|
||||
value = {
|
||||
text = let
|
||||
modifierStr = n: v: optional (v != null) ''--${n}="${toString v}"'';
|
||||
modifierStrs = n: v: optional (v != null) "--${n}=${toString v}";
|
||||
modifierBool = n: v: optional (v != null && v) "--${n}";
|
||||
|
||||
mods = with def;
|
||||
modifierStr "description" description ++ modifierStr "wraps" wraps
|
||||
++ modifierStr "on-event" onEvent
|
||||
++ modifierStr "on-variable" onVariable
|
||||
++ modifierStr "on-job-exit" onJobExit
|
||||
++ modifierStr "on-process-exit" onProcessExit
|
||||
++ modifierStr "on-signal" onSignal
|
||||
++ modifierBool "no-scope-shadowing" noScopeShadowing
|
||||
++ modifierStr "inherit-variable" inheritVariable
|
||||
++ modifierStrs "argument-names" argumentNames;
|
||||
|
||||
modifiers = if isAttrs def then " ${toString mods}" else "";
|
||||
body = if isAttrs def then def.body else def;
|
||||
in ''
|
||||
function ${name}${modifiers}
|
||||
${body}
|
||||
end
|
||||
'';
|
||||
};
|
||||
}) cfg.functions;
|
||||
}
|
||||
|
||||
# Each plugin gets a corresponding conf.d/plugin-NAME.fish file to load
|
||||
# in the paths and any initialization scripts.
|
||||
(mkIf (length cfg.plugins > 0) {
|
||||
xdg.configFile = mkMerge ((map (plugin: {
|
||||
"fish/conf.d/plugin-${plugin.name}.fish".text = ''
|
||||
# Plugin ${plugin.name}
|
||||
set -l plugin_dir ${plugin.src}
|
||||
|
||||
# Set paths to import plugin components
|
||||
if test -d $plugin_dir/functions
|
||||
set fish_function_path $fish_function_path[1] $plugin_dir/functions $fish_function_path[2..-1]
|
||||
end
|
||||
|
||||
if test -d $plugin_dir/completions
|
||||
set fish_complete_path $fish_complete_path[1] $plugin_dir/completions $fish_complete_path[2..-1]
|
||||
end
|
||||
|
||||
# Source initialization code if it exists.
|
||||
if test -d $plugin_dir/conf.d
|
||||
source $plugin_dir/conf.d/*.fish
|
||||
end
|
||||
|
||||
if test -f $plugin_dir/key_bindings.fish
|
||||
source $plugin_dir/key_bindings.fish
|
||||
end
|
||||
|
||||
if test -f $plugin_dir/init.fish
|
||||
source $plugin_dir/init.fish
|
||||
end
|
||||
'';
|
||||
}) cfg.plugins));
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ let
|
||||
|
||||
cfg = config.programs.fzf;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options.programs.fzf = {
|
||||
enable = mkEnableOption "fzf - a command-line fuzzy finder";
|
||||
|
||||
@@ -24,7 +22,7 @@ in
|
||||
|
||||
defaultOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "--height 40%" "--border" ];
|
||||
description = ''
|
||||
Extra command line options given to fzf by default.
|
||||
@@ -43,7 +41,7 @@ in
|
||||
|
||||
fileWidgetOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "--preview 'head {}'" ];
|
||||
description = ''
|
||||
Command line options for the CTRL-T keybinding.
|
||||
@@ -53,7 +51,7 @@ in
|
||||
changeDirWidgetCommand = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "fd --type d" ;
|
||||
example = "fd --type d";
|
||||
description = ''
|
||||
The command that gets executed as the source for fzf for the
|
||||
ALT-C keybinding.
|
||||
@@ -62,7 +60,7 @@ in
|
||||
|
||||
changeDirWidgetOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "--preview 'tree -C {} | head -200'" ];
|
||||
description = ''
|
||||
Command line options for the ALT-C keybinding.
|
||||
@@ -80,7 +78,7 @@ in
|
||||
|
||||
historyWidgetOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "--sort" "--exact" ];
|
||||
description = ''
|
||||
Command line options for the CTRL-R keybinding.
|
||||
@@ -102,24 +100,30 @@ in
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.fzf ];
|
||||
|
||||
home.sessionVariables =
|
||||
mapAttrs (n: v: toString v) (
|
||||
filterAttrs (n: v: v != [] && v != null) {
|
||||
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
|
||||
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
|
||||
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
|
||||
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
|
||||
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
|
||||
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
|
||||
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
|
||||
FZF_DEFAULT_OPTS = cfg.defaultOptions;
|
||||
}
|
||||
);
|
||||
home.sessionVariables = mapAttrs (n: v: toString v)
|
||||
(filterAttrs (n: v: v != [ ] && v != null) {
|
||||
FZF_ALT_C_COMMAND = cfg.changeDirWidgetCommand;
|
||||
FZF_ALT_C_OPTS = cfg.changeDirWidgetOptions;
|
||||
FZF_CTRL_R_COMMAND = cfg.historyWidgetCommand;
|
||||
FZF_CTRL_R_OPTS = cfg.historyWidgetOptions;
|
||||
FZF_CTRL_T_COMMAND = cfg.fileWidgetCommand;
|
||||
FZF_CTRL_T_OPTS = cfg.fileWidgetOptions;
|
||||
FZF_DEFAULT_COMMAND = cfg.defaultCommand;
|
||||
FZF_DEFAULT_OPTS = cfg.defaultOptions;
|
||||
});
|
||||
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
@@ -134,5 +138,9 @@ in
|
||||
. ${pkgs.fzf}/share/fzf/key-bindings.zsh
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
|
||||
source ${pkgs.fzf}/share/fzf/key-bindings.fish && fzf_key_bindings
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
49
modules/programs/getmail-accounts.nix
Normal file
49
modules/programs/getmail-accounts.nix
Normal file
@@ -0,0 +1,49 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.getmail = {
|
||||
enable = mkEnableOption "the getmail mail retriever for this account";
|
||||
|
||||
destinationCommand = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "\${pkgs.maildrop}/bin/maildrop";
|
||||
description = ''
|
||||
Specify a command delivering the incoming mail to your maildir.
|
||||
'';
|
||||
};
|
||||
|
||||
mailboxes = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = [ ];
|
||||
example = [ "INBOX" "INBOX.spam" ];
|
||||
description = ''
|
||||
A non-empty list of mailboxes. To download all mail you can
|
||||
use the <literal>ALL</literal> mailbox.
|
||||
'';
|
||||
};
|
||||
|
||||
delete = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable if you want to delete read messages from the server. Most
|
||||
users should either enable <literal>delete</literal> or disable
|
||||
<literal>readAll</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
readAll = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable if you want to fetch all, even the read messages from the
|
||||
server. Most users should either enable <literal>delete</literal> or
|
||||
disable <literal>readAll</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
57
modules/programs/getmail.nix
Normal file
57
modules/programs/getmail.nix
Normal file
@@ -0,0 +1,57 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
accounts =
|
||||
filter (a: a.getmail.enable) (attrValues config.accounts.email.accounts);
|
||||
|
||||
renderAccountConfig = account:
|
||||
with account;
|
||||
let
|
||||
passCmd = concatMapStringsSep ", " (x: "'${x}'") passwordCommand;
|
||||
renderedMailboxes =
|
||||
concatMapStringsSep ", " (x: "'${x}'") getmail.mailboxes;
|
||||
retrieverType = if imap.tls.enable then
|
||||
"SimpleIMAPSSLRetriever"
|
||||
else
|
||||
"SimpleIMAPRetriever";
|
||||
destination = if getmail.destinationCommand != null then {
|
||||
destinationType = "MDA_external";
|
||||
destinationPath = getmail.destinationCommand;
|
||||
} else {
|
||||
destinationType = "Maildir";
|
||||
destinationPath = "${maildir.absPath}/";
|
||||
};
|
||||
renderGetmailBoolean = v: if v then "true" else "false";
|
||||
in ''
|
||||
# Generated by Home-Manager.
|
||||
[retriever]
|
||||
type = ${retrieverType}
|
||||
server = ${imap.host}
|
||||
${optionalString (imap.port != null) "port = ${toString imap.port}"}
|
||||
username = ${userName}
|
||||
password_command = (${passCmd})
|
||||
mailboxes = ( ${renderedMailboxes} )
|
||||
|
||||
[destination]
|
||||
type = ${destination.destinationType}
|
||||
path = ${destination.destinationPath}
|
||||
|
||||
[options]
|
||||
delete = ${renderGetmailBoolean getmail.delete}
|
||||
read_all = ${renderGetmailBoolean getmail.readAll}
|
||||
'';
|
||||
getmailEnabled = length (filter (a: a.getmail.enable) accounts) > 0;
|
||||
# Watch out! This is used by the getmail.service too!
|
||||
renderConfigFilepath = a:
|
||||
".getmail/getmail${if a.primary then "rc" else a.name}";
|
||||
|
||||
in {
|
||||
config = mkIf getmailEnabled {
|
||||
home.file = foldl' (a: b: a // b) { }
|
||||
(map (a: { "${renderConfigFilepath a}".text = renderAccountConfig a; })
|
||||
accounts);
|
||||
};
|
||||
}
|
||||
@@ -6,6 +6,58 @@ let
|
||||
|
||||
cfg = config.programs.git;
|
||||
|
||||
# create [section "subsection"] keys from "section.subsection" attrset names
|
||||
mkSectionName = name:
|
||||
let
|
||||
containsQuote = strings.hasInfix ''"'' name;
|
||||
sections = splitString "." name;
|
||||
section = head sections;
|
||||
subsections = tail sections;
|
||||
subsection = concatStringsSep "." subsections;
|
||||
in if containsQuote || subsections == [ ] then
|
||||
name
|
||||
else
|
||||
''${section} "${subsection}"'';
|
||||
|
||||
mkValueString = v:
|
||||
let
|
||||
escapedV = ''
|
||||
"${
|
||||
replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v
|
||||
}"'';
|
||||
in generators.mkValueStringDefault { } (if isString v then escapedV else v);
|
||||
|
||||
# generation for multiple ini values
|
||||
mkKeyValue = k: v:
|
||||
let
|
||||
mkKeyValue =
|
||||
generators.mkKeyValueDefault { inherit mkValueString; } " = " k;
|
||||
in concatStringsSep "\n" (map (kv: " " + mkKeyValue kv) (toList v));
|
||||
|
||||
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
|
||||
gitFlattenAttrs = let
|
||||
recurse = path: value:
|
||||
if isAttrs value then
|
||||
mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
|
||||
else if length path > 1 then {
|
||||
${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
|
||||
} else {
|
||||
${head path} = value;
|
||||
};
|
||||
in attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
|
||||
|
||||
gitToIni = attrs:
|
||||
let toIni = generators.toINI { inherit mkKeyValue mkSectionName; };
|
||||
in toIni (gitFlattenAttrs attrs);
|
||||
|
||||
gitIniType = with types;
|
||||
let
|
||||
primitiveType = either str (either bool int);
|
||||
multipleType = either primitiveType (listOf primitiveType);
|
||||
sectionType = attrsOf multipleType;
|
||||
supersectionType = attrsOf (either multipleType sectionType);
|
||||
in attrsOf supersectionType;
|
||||
|
||||
signModule = types.submodule {
|
||||
options = {
|
||||
key = mkOption {
|
||||
@@ -28,7 +80,7 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
includeModule = types.submodule {
|
||||
includeModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
condition = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
@@ -44,15 +96,24 @@ let
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
type = with types; either str path;
|
||||
description = "Path of the configuration file to include.";
|
||||
};
|
||||
|
||||
contents = mkOption {
|
||||
type = types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration to include. If empty then a path must be given.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
config.path = mkIf (config.contents != { })
|
||||
(mkDefault (pkgs.writeText "contents" (gitToIni config.contents)));
|
||||
});
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
@@ -62,23 +123,29 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.git;
|
||||
defaultText = "pkgs.git";
|
||||
description = "Git package to install.";
|
||||
defaultText = literalExample "pkgs.git";
|
||||
description = ''
|
||||
Git package to install. Use <varname>pkgs.gitAndTools.gitFull</varname>
|
||||
to gain access to <command>git send-email</command> for instance.
|
||||
'';
|
||||
};
|
||||
|
||||
userName = mkOption {
|
||||
type = types.str;
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Default user name to use.";
|
||||
};
|
||||
|
||||
userEmail = mkOption {
|
||||
type = types.str;
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Default user email to use.";
|
||||
};
|
||||
|
||||
aliases = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = { co = "checkout"; };
|
||||
description = "Git aliases to define.";
|
||||
};
|
||||
|
||||
@@ -89,26 +156,40 @@ in
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.either types.attrs types.lines;
|
||||
default = {};
|
||||
description = "Additional configuration to add.";
|
||||
type = types.either types.lines gitIniType;
|
||||
default = { };
|
||||
example = {
|
||||
core = { whitespace = "trailing-space,space-before-tab"; };
|
||||
url."ssh://git@host".insteadOf = "otherhost";
|
||||
};
|
||||
description = ''
|
||||
Additional configuration to add. The use of string values is
|
||||
deprecated and will be removed in the future.
|
||||
'';
|
||||
};
|
||||
|
||||
iniContent = mkOption {
|
||||
type = types.attrsOf types.attrs;
|
||||
type = gitIniType;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
ignores = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = [ "*~" "*.swp" ];
|
||||
description = "List of paths that should be globally ignored.";
|
||||
};
|
||||
|
||||
attributes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "*.pdf diff=pdf" ];
|
||||
description = "List of defining attributes set globally.";
|
||||
};
|
||||
|
||||
includes = mkOption {
|
||||
type = types.listOf includeModule;
|
||||
default = [];
|
||||
default = [ ];
|
||||
example = literalExample ''
|
||||
[
|
||||
{ path = "~/path/to/config.inc"; }
|
||||
@@ -120,57 +201,113 @@ in
|
||||
'';
|
||||
description = "List of configuration files to include.";
|
||||
};
|
||||
|
||||
lfs = {
|
||||
enable = mkEnableOption "Git Large File Storage";
|
||||
|
||||
skipSmudge = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Skip automatic downloading of objects on clone or pull.
|
||||
This requires a manual <command>git lfs pull</command>
|
||||
every time a new commit is checked out on your repository.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
programs.git.iniContent.user = {
|
||||
name = cfg.userName;
|
||||
email = cfg.userEmail;
|
||||
programs.git.iniContent.user = {
|
||||
name = mkIf (cfg.userName != null) cfg.userName;
|
||||
email = mkIf (cfg.userEmail != null) cfg.userEmail;
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"git/config".text = gitToIni cfg.iniContent;
|
||||
|
||||
"git/ignore" = mkIf (cfg.ignores != [ ]) {
|
||||
text = concatStringsSep "\n" cfg.ignores + "\n";
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"git/config".text = generators.toINI {} cfg.iniContent;
|
||||
"git/attributes" = mkIf (cfg.attributes != [ ]) {
|
||||
text = concatStringsSep "\n" cfg.attributes + "\n";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
"git/ignore" = mkIf (cfg.ignores != []) {
|
||||
text = concatStringsSep "\n" cfg.ignores + "\n";
|
||||
{
|
||||
programs.git.iniContent = let
|
||||
hasSmtp = name: account: account.smtp != null;
|
||||
|
||||
genIdentity = name: account:
|
||||
with account;
|
||||
nameValuePair "sendemail.${name}" ({
|
||||
smtpEncryption = if smtp.tls.enable then "tls" else "";
|
||||
smtpServer = smtp.host;
|
||||
smtpUser = userName;
|
||||
from = address;
|
||||
} // optionalAttrs (smtp.port != null) {
|
||||
smtpServerPort = smtp.port;
|
||||
});
|
||||
in mapAttrs' genIdentity
|
||||
(filterAttrs hasSmtp config.accounts.email.accounts);
|
||||
}
|
||||
|
||||
(mkIf (cfg.signing != null) {
|
||||
programs.git.iniContent = {
|
||||
user.signingKey = cfg.signing.key;
|
||||
commit.gpgSign = cfg.signing.signByDefault;
|
||||
gpg.program = cfg.signing.gpgPath;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.aliases != { }) { programs.git.iniContent.alias = cfg.aliases; })
|
||||
|
||||
(mkIf (lib.isAttrs cfg.extraConfig) {
|
||||
programs.git.iniContent = cfg.extraConfig;
|
||||
})
|
||||
|
||||
(mkIf (lib.isString cfg.extraConfig) {
|
||||
warnings = [''
|
||||
Using programs.git.extraConfig as a string option is
|
||||
deprecated and will be removed in the future. Please
|
||||
change to using it as an attribute set instead.
|
||||
''];
|
||||
|
||||
xdg.configFile."git/config".text = cfg.extraConfig;
|
||||
})
|
||||
|
||||
(mkIf (cfg.includes != [ ]) {
|
||||
xdg.configFile."git/config".text = let
|
||||
include = i:
|
||||
with i;
|
||||
if condition != null then {
|
||||
includeIf.${condition}.path = "${path}";
|
||||
} else {
|
||||
include.path = "${path}";
|
||||
};
|
||||
in mkAfter
|
||||
(concatStringsSep "\n" (map gitToIni (map include cfg.includes)));
|
||||
})
|
||||
|
||||
(mkIf cfg.lfs.enable {
|
||||
home.packages = [ pkgs.git-lfs ];
|
||||
|
||||
programs.git.iniContent.filter.lfs =
|
||||
let skipArg = optional cfg.lfs.skipSmudge "--skip";
|
||||
in {
|
||||
clean = "git-lfs clean -- %f";
|
||||
process =
|
||||
concatStringsSep " " ([ "git-lfs" "filter-process" ] ++ skipArg);
|
||||
required = true;
|
||||
smudge = concatStringsSep " "
|
||||
([ "git-lfs" "smudge" ] ++ skipArg ++ [ "--" "%f" ]);
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf (cfg.signing != null) {
|
||||
programs.git.iniContent = {
|
||||
user.signingKey = cfg.signing.key;
|
||||
commit.gpgSign = cfg.signing.signByDefault;
|
||||
gpg.program = cfg.signing.gpgPath;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.aliases != {}) {
|
||||
programs.git.iniContent.alias = cfg.aliases;
|
||||
})
|
||||
|
||||
(mkIf (lib.isAttrs cfg.extraConfig) {
|
||||
programs.git.iniContent = cfg.extraConfig;
|
||||
})
|
||||
|
||||
(mkIf (lib.isString cfg.extraConfig) {
|
||||
xdg.configFile."git/config".text = cfg.extraConfig;
|
||||
})
|
||||
|
||||
(mkIf (cfg.includes != []) {
|
||||
xdg.configFile."git/config".text = mkAfter
|
||||
(concatMapStringsSep "\n"
|
||||
(i: with i; ''
|
||||
[${if (condition == null) then "include" else "includeIf \"${condition}\""}]
|
||||
path = ${path}
|
||||
'')
|
||||
cfg.includes);
|
||||
})
|
||||
]
|
||||
);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -6,103 +6,129 @@ let
|
||||
|
||||
cfg = config.programs.gnome-terminal;
|
||||
|
||||
dag = config.lib.dag;
|
||||
vteInitStr = ''
|
||||
# gnome-terminal: Show current directory in the terminal window title.
|
||||
. ${pkgs.gnome3.vte}/etc/profile.d/vte.sh
|
||||
'';
|
||||
|
||||
profileColorsSubModule = types.submodule (
|
||||
{ ... }: {
|
||||
options = {
|
||||
foregroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
};
|
||||
|
||||
backgroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The background color.";
|
||||
};
|
||||
|
||||
boldColor = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = "The bold color, null to use same as foreground.";
|
||||
};
|
||||
|
||||
palette = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "The terminal palette.";
|
||||
};
|
||||
backForeSubModule = types.submodule ({ ... }: {
|
||||
options = {
|
||||
foreground = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
profileSubModule = types.submodule (
|
||||
{ name, config, ... }: {
|
||||
options = {
|
||||
default = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether this should be the default profile.";
|
||||
};
|
||||
|
||||
visibleName = mkOption {
|
||||
type = types.str;
|
||||
description = "The profile name.";
|
||||
};
|
||||
|
||||
colors = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr profileColorsSubModule;
|
||||
description = "The terminal colors, null to use system default.";
|
||||
};
|
||||
|
||||
cursorShape = mkOption {
|
||||
default = "block";
|
||||
type = types.enum [ "block" "ibeam" "underline" ];
|
||||
description = "The cursor shape.";
|
||||
};
|
||||
|
||||
font = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = "The font name, null to use system default.";
|
||||
};
|
||||
|
||||
scrollOnOutput = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether to scroll when output is written.";
|
||||
};
|
||||
|
||||
showScrollbar = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether the scroll bar should be visible.";
|
||||
};
|
||||
|
||||
scrollbackLines = mkOption {
|
||||
default = 10000;
|
||||
type = types.nullOr types.int;
|
||||
description =
|
||||
''
|
||||
The number of scrollback lines to keep, null for infinite.
|
||||
'';
|
||||
};
|
||||
background = mkOption {
|
||||
type = types.str;
|
||||
description = "The background color.";
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
|
||||
profileColorsSubModule = types.submodule ({ ... }: {
|
||||
options = {
|
||||
foregroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
};
|
||||
|
||||
mkIniKeyValue = key: value:
|
||||
let
|
||||
tweakVal = v:
|
||||
if isString v then "'${v}'"
|
||||
else if isList v then "[" + concatStringsSep "," (map tweakVal v) + "]"
|
||||
else if isBool v && v then "true"
|
||||
else if isBool v && !v then "false"
|
||||
else toString v;
|
||||
in
|
||||
"${key}=${tweakVal value}";
|
||||
backgroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The background color.";
|
||||
};
|
||||
|
||||
boldColor = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = "The bold color, null to use same as foreground.";
|
||||
};
|
||||
|
||||
palette = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "The terminal palette.";
|
||||
};
|
||||
|
||||
cursor = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr backForeSubModule;
|
||||
description = "The color for the terminal cursor.";
|
||||
};
|
||||
|
||||
highlight = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr backForeSubModule;
|
||||
description = "The colors for the terminal’s highlighted area.";
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
profileSubModule = types.submodule ({ name, config, ... }: {
|
||||
options = {
|
||||
default = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether this should be the default profile.";
|
||||
};
|
||||
|
||||
visibleName = mkOption {
|
||||
type = types.str;
|
||||
description = "The profile name.";
|
||||
};
|
||||
|
||||
colors = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr profileColorsSubModule;
|
||||
description = "The terminal colors, null to use system default.";
|
||||
};
|
||||
|
||||
cursorBlinkMode = mkOption {
|
||||
default = "system";
|
||||
type = types.enum [ "system" "on" "off" ];
|
||||
description = "The cursor blink mode.";
|
||||
};
|
||||
|
||||
cursorShape = mkOption {
|
||||
default = "block";
|
||||
type = types.enum [ "block" "ibeam" "underline" ];
|
||||
description = "The cursor shape.";
|
||||
};
|
||||
|
||||
font = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = "The font name, null to use system default.";
|
||||
};
|
||||
|
||||
allowBold = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.bool;
|
||||
description = ''
|
||||
If <literal>true</literal>, allow applications in the
|
||||
terminal to make text boldface.
|
||||
'';
|
||||
};
|
||||
|
||||
scrollOnOutput = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether to scroll when output is written.";
|
||||
};
|
||||
|
||||
showScrollbar = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether the scroll bar should be visible.";
|
||||
};
|
||||
|
||||
scrollbackLines = mkOption {
|
||||
default = 10000;
|
||||
type = types.nullOr types.int;
|
||||
description = ''
|
||||
The number of scrollback lines to keep, null for infinite.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
buildProfileSet = pcfg:
|
||||
{
|
||||
@@ -110,54 +136,42 @@ let
|
||||
scrollbar-policy = if pcfg.showScrollbar then "always" else "never";
|
||||
scrollback-lines = pcfg.scrollbackLines;
|
||||
cursor-shape = pcfg.cursorShape;
|
||||
}
|
||||
// (
|
||||
if (pcfg.font == null)
|
||||
then { use-system-font = true; }
|
||||
else { use-system-font = false; font = pcfg.font; }
|
||||
) // (
|
||||
if (pcfg.colors == null)
|
||||
then { use-theme-colors = true; }
|
||||
else (
|
||||
{
|
||||
use-theme-colors = false;
|
||||
foreground-color = pcfg.colors.foregroundColor;
|
||||
background-color = pcfg.colors.backgroundColor;
|
||||
palette = pcfg.colors.palette;
|
||||
}
|
||||
// (
|
||||
if (pcfg.colors.boldColor == null)
|
||||
then { bold-color-same-as-fg = true; }
|
||||
else {
|
||||
bold-color-same-as-fg = false;
|
||||
bold-color = pcfg.colors.boldColor;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
cursor-blink-mode = pcfg.cursorBlinkMode;
|
||||
} // (if (pcfg.font == null) then {
|
||||
use-system-font = true;
|
||||
} else {
|
||||
use-system-font = false;
|
||||
font = pcfg.font;
|
||||
}) // (if (pcfg.colors == null) then {
|
||||
use-theme-colors = true;
|
||||
} else
|
||||
({
|
||||
use-theme-colors = false;
|
||||
foreground-color = pcfg.colors.foregroundColor;
|
||||
background-color = pcfg.colors.backgroundColor;
|
||||
palette = pcfg.colors.palette;
|
||||
} // optionalAttrs (pcfg.allowBold != null) {
|
||||
allow-bold = pcfg.allowBold;
|
||||
} // (if (pcfg.colors.boldColor == null) then {
|
||||
bold-color-same-as-fg = true;
|
||||
} else {
|
||||
bold-color-same-as-fg = false;
|
||||
bold-color = pcfg.colors.boldColor;
|
||||
}) // (if (pcfg.colors.cursor != null) then {
|
||||
cursor-colors-set = true;
|
||||
cursor-foreground-color = pcfg.colors.cursor.foreground;
|
||||
cursor-background-color = pcfg.colors.cursor.background;
|
||||
} else {
|
||||
cursor-colors-set = false;
|
||||
}) // (if (pcfg.colors.highlight != null) then {
|
||||
highlight-colors-set = true;
|
||||
highlight-foreground-color = pcfg.colors.highlight.foreground;
|
||||
highlight-background-color = pcfg.colors.highlight.background;
|
||||
} else {
|
||||
highlight-colors-set = false;
|
||||
})));
|
||||
|
||||
buildIniSet = cfg:
|
||||
{
|
||||
"/" = {
|
||||
default-show-menubar = cfg.showMenubar;
|
||||
schema-version = 3;
|
||||
};
|
||||
}
|
||||
//
|
||||
{
|
||||
"profiles:" = {
|
||||
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
|
||||
list = attrNames cfg.profile;
|
||||
};
|
||||
}
|
||||
//
|
||||
mapAttrs' (name: value:
|
||||
nameValuePair ("profiles:/:${name}") (buildProfileSet value)
|
||||
) cfg.profile;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
@@ -170,8 +184,14 @@ in
|
||||
description = "Whether to show the menubar by default";
|
||||
};
|
||||
|
||||
themeVariant = mkOption {
|
||||
default = "default";
|
||||
type = types.enum [ "default" "light" "dark" "system" ];
|
||||
description = "The theme variation to request";
|
||||
};
|
||||
|
||||
profile = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = types.attrsOf profileSubModule;
|
||||
description = "A set of Gnome Terminal profiles.";
|
||||
};
|
||||
@@ -181,20 +201,23 @@ in
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.gnome3.gnome_terminal ];
|
||||
|
||||
# The dconf service needs to be installed and prepared.
|
||||
home.activation.gnomeTerminal = dag.entryAfter ["installPackages"] (
|
||||
let
|
||||
iniText = toDconfIni (buildIniSet cfg);
|
||||
iniFile = pkgs.writeText "gnome-terminal.ini" iniText;
|
||||
dconfPath = "/org/gnome/terminal/legacy/";
|
||||
in
|
||||
''
|
||||
if [[ -v DRY_RUN ]]; then
|
||||
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile}
|
||||
else
|
||||
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile}
|
||||
fi
|
||||
''
|
||||
);
|
||||
dconf.settings = let dconfPath = "org/gnome/terminal/legacy";
|
||||
in {
|
||||
"${dconfPath}" = {
|
||||
default-show-menubar = cfg.showMenubar;
|
||||
theme-variant = cfg.themeVariant;
|
||||
schema-version = 3;
|
||||
};
|
||||
|
||||
"${dconfPath}/profiles:" = {
|
||||
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
|
||||
list = attrNames cfg.profile;
|
||||
};
|
||||
} // mapAttrs'
|
||||
(n: v: nameValuePair ("${dconfPath}/profiles:/:${n}") (buildProfileSet v))
|
||||
cfg.profile;
|
||||
|
||||
programs.bash.initExtra = mkBefore vteInitStr;
|
||||
programs.zsh.initExtra = vteInitStr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ let
|
||||
|
||||
cfg = config.programs.go;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rvolosatovs ];
|
||||
|
||||
options = {
|
||||
@@ -18,13 +16,13 @@ in
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.go;
|
||||
defaultText = "pkgs.go";
|
||||
defaultText = literalExample "pkgs.go";
|
||||
description = "The Go package to use.";
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
type = with types; attrsOf path;
|
||||
default = {};
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
"golang.org/x/text" = builtins.fetchGit "https://go.googlesource.com/text";
|
||||
@@ -38,7 +36,24 @@ in
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "go";
|
||||
description = "GOPATH relative to HOME";
|
||||
description = ''
|
||||
Primary <envar>GOPATH</envar> relative to
|
||||
<envar>HOME</envar>. It will be exported first and therefore
|
||||
used by default by the Go tooling.
|
||||
'';
|
||||
};
|
||||
|
||||
extraGoPaths = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "extraGoPath1" "extraGoPath2" ];
|
||||
description = let goPathOpt = "programs.go.goPath";
|
||||
in ''
|
||||
Extra <envar>GOPATH</envar>s relative to <envar>HOME</envar> appended
|
||||
after
|
||||
<varname><link linkend="opt-${goPathOpt}">${goPathOpt}</link></varname>,
|
||||
if that option is set.
|
||||
'';
|
||||
};
|
||||
|
||||
goBin = mkOption {
|
||||
@@ -47,6 +62,18 @@ in
|
||||
example = ".local/bin.go";
|
||||
description = "GOBIN relative to HOME";
|
||||
};
|
||||
|
||||
goPrivate = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
example = [ "*.corp.example.com" "rsc.io/private" ];
|
||||
description = ''
|
||||
The <envar>GOPRIVATE</envar> environment variable controls
|
||||
which modules the go command considers to be private (not
|
||||
available publicly) and should therefore not use the proxy
|
||||
or checksum database.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -54,22 +81,25 @@ in
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.file =
|
||||
let
|
||||
goPath = if cfg.goPath != null then cfg.goPath else "go";
|
||||
|
||||
mkSrc = n: v: {
|
||||
target = "${goPath}/src/${n}";
|
||||
source = v;
|
||||
};
|
||||
in
|
||||
mapAttrsToList mkSrc cfg.packages;
|
||||
home.file = let
|
||||
goPath = if cfg.goPath != null then cfg.goPath else "go";
|
||||
mkSrc = n: v: { "${goPath}/src/${n}".source = v; };
|
||||
in foldl' (a: b: a // b) { } (mapAttrsToList mkSrc cfg.packages);
|
||||
}
|
||||
|
||||
(mkIf (cfg.goPath != null) {
|
||||
home.sessionVariables.GOPATH = builtins.toPath "${config.home.homeDirectory}/${cfg.goPath}";
|
||||
home.sessionVariables.GOPATH = concatStringsSep ":" (map builtins.toPath
|
||||
(map (path: "${config.home.homeDirectory}/${path}")
|
||||
([ cfg.goPath ] ++ cfg.extraGoPaths)));
|
||||
})
|
||||
|
||||
(mkIf (cfg.goBin != null) {
|
||||
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
|
||||
home.sessionVariables.GOBIN =
|
||||
builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
|
||||
})
|
||||
|
||||
(mkIf (cfg.goPrivate != [ ]) {
|
||||
home.sessionVariables.GOPRIVATE = concatStringsSep "," cfg.goPrivate;
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
61
modules/programs/gpg.nix
Normal file
61
modules/programs/gpg.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.gpg;
|
||||
|
||||
cfgText =
|
||||
concatStringsSep "\n"
|
||||
(attrValues
|
||||
(mapAttrs (key: value:
|
||||
if isString value
|
||||
then "${key} ${value}"
|
||||
else optionalString value key)
|
||||
cfg.settings));
|
||||
|
||||
in {
|
||||
options.programs.gpg = {
|
||||
enable = mkEnableOption "GnuPG";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf (types.either types.str types.bool);
|
||||
example = {
|
||||
no-comments = false;
|
||||
s2k-cipher-algo = "AES128";
|
||||
};
|
||||
description = ''
|
||||
GnuPG configuration options. Available options are described
|
||||
in the gpg manpage:
|
||||
<link xlink:href="https://gnupg.org/documentation/manpage.html"/>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.gpg.settings = {
|
||||
personal-cipher-preferences = mkDefault "AES256 AES192 AES";
|
||||
personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256";
|
||||
personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed";
|
||||
default-preference-list = mkDefault "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
|
||||
cert-digest-algo = mkDefault "SHA512";
|
||||
s2k-digest-algo = mkDefault "SHA512";
|
||||
s2k-cipher-algo = mkDefault "AES256";
|
||||
charset = mkDefault "utf-8";
|
||||
fixed-list-mode = mkDefault true;
|
||||
no-comments = mkDefault true;
|
||||
no-emit-version = mkDefault true;
|
||||
keyid-format = mkDefault "0xlong";
|
||||
list-options = mkDefault "show-uid-validity";
|
||||
verify-options = mkDefault "show-uid-validity";
|
||||
with-fingerprint = mkDefault true;
|
||||
require-cross-certification = mkDefault true;
|
||||
no-symkey-cache = mkDefault true;
|
||||
use-agent = mkDefault true;
|
||||
};
|
||||
|
||||
home.packages = [ pkgs.gnupg ];
|
||||
|
||||
home.file.".gnupg/gpg.conf".text = cfgText;
|
||||
};
|
||||
}
|
||||
@@ -8,9 +8,7 @@ let
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
meta.maintainers = [ maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
@@ -32,12 +30,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable && !config.nixosSubmodule) {
|
||||
home.packages = [
|
||||
(import ../../home-manager {
|
||||
inherit pkgs;
|
||||
inherit (cfg) path;
|
||||
})
|
||||
];
|
||||
config = mkIf (cfg.enable && !config.submoduleSupport.enable) {
|
||||
home.packages =
|
||||
[ (pkgs.callPackage ../../home-manager { inherit (cfg) path; }) ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.htop;
|
||||
|
||||
list = xs: concatMapStrings (x: "${toString x} ") xs;
|
||||
@@ -81,16 +82,15 @@ let
|
||||
RightCPUs2 = 1;
|
||||
Blank = 2;
|
||||
CPU = 1;
|
||||
"CPU(1)"= 1;
|
||||
"CPU(1)" = 1;
|
||||
"CPU(2)" = 1;
|
||||
"CPU(3)" = 1;
|
||||
"CPU(4)" = 1;
|
||||
};
|
||||
|
||||
singleMeterType = types.coercedTo
|
||||
(types.enum (attrNames meters))
|
||||
(m: { kind = m; mode = meters.${m}; })
|
||||
(types.submodule {
|
||||
singleMeterType = let
|
||||
meterEnum = types.enum (attrNames meters);
|
||||
meterSubmodule = types.submodule {
|
||||
options = {
|
||||
kind = mkOption {
|
||||
type = types.enum (attrNames meters);
|
||||
@@ -101,10 +101,15 @@ let
|
||||
mode = mkOption {
|
||||
type = types.enum [ 1 2 3 4 ];
|
||||
example = 2;
|
||||
description = "Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
|
||||
description =
|
||||
"Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
in types.coercedTo meterEnum (m: {
|
||||
kind = m;
|
||||
mode = meters.${m};
|
||||
}) meterSubmodule;
|
||||
|
||||
meterType = types.submodule {
|
||||
options = {
|
||||
@@ -115,7 +120,10 @@ let
|
||||
"Memory"
|
||||
"LeftCPUs2"
|
||||
"RightCPUs2"
|
||||
{ kind = "CPU"; mode = 3; }
|
||||
{
|
||||
kind = "CPU";
|
||||
mode = 3;
|
||||
}
|
||||
];
|
||||
type = types.listOf singleMeterType;
|
||||
};
|
||||
@@ -123,7 +131,10 @@ let
|
||||
description = "Meters shown in the right header.";
|
||||
default = [ "Tasks" "LoadAverage" "Uptime" ];
|
||||
example = [
|
||||
{ kind = "Clock"; mode = 4; }
|
||||
{
|
||||
kind = "Clock";
|
||||
mode = 4;
|
||||
}
|
||||
"Uptime"
|
||||
"Tasks"
|
||||
];
|
||||
@@ -131,15 +142,37 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
in {
|
||||
options.programs.htop = {
|
||||
enable = mkEnableOption "htop";
|
||||
|
||||
fields = mkOption {
|
||||
type = types.listOf (types.enum (attrNames fields));
|
||||
default = [ "PID" "USER" "PRIORITY" "NICE" "M_SIZE" "M_RESIDENT" "M_SHARE" "STATE" "PERCENT_CPU" "PERCENT_MEM" "TIME" "COMM" ];
|
||||
example = [ "PID" "USER" "PRIORITY" "PERCENT_CPU" "M_RESIDENT" "PERCENT_MEM" "TIME" "COMM" ];
|
||||
default = [
|
||||
"PID"
|
||||
"USER"
|
||||
"PRIORITY"
|
||||
"NICE"
|
||||
"M_SIZE"
|
||||
"M_RESIDENT"
|
||||
"M_SHARE"
|
||||
"STATE"
|
||||
"PERCENT_CPU"
|
||||
"PERCENT_MEM"
|
||||
"TIME"
|
||||
"COMM"
|
||||
];
|
||||
example = [
|
||||
"PID"
|
||||
"USER"
|
||||
"PRIORITY"
|
||||
"PERCENT_CPU"
|
||||
"M_RESIDENT"
|
||||
"PERCENT_MEM"
|
||||
"TIME"
|
||||
"COMM"
|
||||
];
|
||||
description = "Active fields shown in the table.";
|
||||
};
|
||||
|
||||
@@ -209,7 +242,7 @@ in
|
||||
default = true;
|
||||
description = "Display threads in a different color.";
|
||||
};
|
||||
|
||||
|
||||
treeView = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -225,7 +258,8 @@ in
|
||||
detailedCpuTime = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
|
||||
description =
|
||||
"Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
|
||||
};
|
||||
|
||||
cpuCountFromZero = mkOption {
|
||||
@@ -272,14 +306,23 @@ in
|
||||
"CPU"
|
||||
"LeftCPUs2"
|
||||
"RightCPUs2"
|
||||
{ kind = "CPU"; mode = 3; }
|
||||
{
|
||||
kind = "CPU";
|
||||
mode = 3;
|
||||
}
|
||||
];
|
||||
right = [
|
||||
{ kind = "Clock"; mode = 4; }
|
||||
{
|
||||
kind = "Clock";
|
||||
mode = 4;
|
||||
}
|
||||
"Uptime"
|
||||
"Tasks"
|
||||
"LoadAverage"
|
||||
{ kind = "Battery"; mode = 1; }
|
||||
{
|
||||
kind = "Battery";
|
||||
mode = 1;
|
||||
}
|
||||
];
|
||||
};
|
||||
type = meterType;
|
||||
|
||||
@@ -26,8 +26,6 @@ let
|
||||
|
||||
cfg = config.programs.info;
|
||||
|
||||
dag = config.lib.dag;
|
||||
|
||||
# Indexes info files found in this location
|
||||
homeInfoPath = "${config.home.profileDirectory}/share/info";
|
||||
|
||||
@@ -36,9 +34,7 @@ let
|
||||
# from this package in the activation script.
|
||||
infoPkg = pkgs.texinfoInteractive;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
in {
|
||||
options = {
|
||||
programs.info = {
|
||||
enable = mkEnableOption "GNU Info";
|
||||
@@ -57,19 +53,20 @@ in
|
||||
home.sessionVariables.INFOPATH =
|
||||
"${cfg.homeInfoDirLocation}\${INFOPATH:+:}\${INFOPATH}";
|
||||
|
||||
home.activation.createHomeInfoDir = dag.entryAfter ["installPackages"] ''
|
||||
oPATH=$PATH
|
||||
export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH"
|
||||
$DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}"
|
||||
$DRY_RUN_CMD rm -f "${cfg.homeInfoDirLocation}/dir"
|
||||
if [[ -d "${homeInfoPath}" ]]; then
|
||||
find -L "${homeInfoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
|
||||
-exec $DRY_RUN_CMD ${infoPkg}/bin/install-info '{}' \
|
||||
"${cfg.homeInfoDirLocation}/dir" \;
|
||||
fi
|
||||
export PATH="$oPATH"
|
||||
unset oPATH
|
||||
'';
|
||||
home.activation.createHomeInfoDir =
|
||||
hm.dag.entryAfter [ "installPackages" ] ''
|
||||
oPATH=$PATH
|
||||
export PATH="${lib.makeBinPath [ pkgs.gzip ]}''${PATH:+:}$PATH"
|
||||
$DRY_RUN_CMD mkdir -p "${cfg.homeInfoDirLocation}"
|
||||
$DRY_RUN_CMD rm -f "${cfg.homeInfoDirLocation}/dir"
|
||||
if [[ -d "${homeInfoPath}" ]]; then
|
||||
find -L "${homeInfoPath}" \( -name '*.info' -o -name '*.info.gz' \) \
|
||||
-exec $DRY_RUN_CMD ${infoPkg}/bin/install-info '{}' \
|
||||
"${cfg.homeInfoDirLocation}/dir" \;
|
||||
fi
|
||||
export PATH="$oPATH"
|
||||
unset oPATH
|
||||
'';
|
||||
|
||||
home.packages = [ infoPkg ];
|
||||
|
||||
|
||||
211
modules/programs/irssi.nix
Normal file
211
modules/programs/irssi.nix
Normal file
@@ -0,0 +1,211 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.irssi;
|
||||
|
||||
boolStr = b: if b then "yes" else "no";
|
||||
quoteStr = s: escape ["\""] s;
|
||||
|
||||
assignFormat = set:
|
||||
concatStringsSep "\n"
|
||||
(mapAttrsToList (k: v: " ${k} = \"${quoteStr v}\";") set);
|
||||
|
||||
chatnetString =
|
||||
concatStringsSep "\n"
|
||||
(flip mapAttrsToList cfg.networks
|
||||
(k: v: ''
|
||||
${k} = {
|
||||
type = "${v.type}";
|
||||
nick = "${quoteStr v.nick}";
|
||||
autosendcmd = "${concatMapStringsSep ";" quoteStr v.autoCommands}";
|
||||
};
|
||||
''));
|
||||
|
||||
serversString =
|
||||
concatStringsSep ",\n"
|
||||
(flip mapAttrsToList cfg.networks
|
||||
(k: v: ''
|
||||
{
|
||||
chatnet = "${k}";
|
||||
address = "${v.server.address}";
|
||||
port = "${toString v.server.port}";
|
||||
use_ssl = "${boolStr v.server.ssl.enable}";
|
||||
ssl_verify = "${boolStr v.server.ssl.verify}";
|
||||
autoconnect = "${boolStr v.server.autoConnect}";
|
||||
}
|
||||
''));
|
||||
|
||||
channelString =
|
||||
concatStringsSep ",\n"
|
||||
(flip mapAttrsToList cfg.networks
|
||||
(k: v:
|
||||
concatStringsSep ",\n"
|
||||
(flip mapAttrsToList v.channels
|
||||
(c: cv: ''
|
||||
{
|
||||
chatnet = "${k}";
|
||||
name = "${c}";
|
||||
autojoin = "${boolStr cv.autoJoin}";
|
||||
}
|
||||
''))));
|
||||
|
||||
channelType = types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
visible = false;
|
||||
default = null;
|
||||
description = "Name of the channel.";
|
||||
};
|
||||
|
||||
autoJoin = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to join this channel on connect.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networkType = types.submodule ({ name, ...}: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
visible = false;
|
||||
default = name;
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
nick = mkOption {
|
||||
type = types.str;
|
||||
description = "Nickname in that network.";
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.str;
|
||||
description = "Type of the network.";
|
||||
default = "IRC";
|
||||
};
|
||||
|
||||
autoCommands = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "List of commands to execute on connect.";
|
||||
};
|
||||
|
||||
server = {
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
description = "Address of the chat server.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 6667;
|
||||
description = "Port of the chat server.";
|
||||
};
|
||||
|
||||
ssl = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether SSL should be used.";
|
||||
};
|
||||
|
||||
verify = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether the SSL certificate should be verified.";
|
||||
};
|
||||
};
|
||||
|
||||
autoConnect = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether Irssi connects to the server on launch.";
|
||||
};
|
||||
};
|
||||
|
||||
channels = mkOption {
|
||||
description = "Channels for the given network.";
|
||||
type = types.attrsOf channelType;
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
programs.irssi = {
|
||||
enable = mkEnableOption "the Irssi chat client";
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
description = "These lines are appended to the Irssi configuration.";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
aliases = mkOption {
|
||||
default = {};
|
||||
example = { J = "join"; BYE = "quit";};
|
||||
description = "An attribute set that maps aliases to commands.";
|
||||
type = types.attrsOf types.str;
|
||||
};
|
||||
|
||||
networks = mkOption {
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
freenode = {
|
||||
nick = "hmuser";
|
||||
server = {
|
||||
address = "chat.freenode.net";
|
||||
port = 6697;
|
||||
autoConnect = true;
|
||||
};
|
||||
channels = {
|
||||
nixos.autoJoin = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = "An attribute set of chat networks.";
|
||||
type = types.attrsOf networkType;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.irssi ];
|
||||
|
||||
home.file.".irssi/config".text = ''
|
||||
settings = {
|
||||
core = {
|
||||
settings_autosave = "no";
|
||||
};
|
||||
};
|
||||
|
||||
aliases = {
|
||||
${assignFormat cfg.aliases}
|
||||
};
|
||||
|
||||
chatnets = {
|
||||
${chatnetString}
|
||||
};
|
||||
|
||||
servers = (
|
||||
${serversString}
|
||||
);
|
||||
|
||||
channels = (
|
||||
${channelString}
|
||||
);
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
}
|
||||
76
modules/programs/jq.nix
Normal file
76
modules/programs/jq.nix
Normal file
@@ -0,0 +1,76 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.jq;
|
||||
|
||||
colorType = mkOption {
|
||||
type = types.str;
|
||||
description = "ANSI color definition";
|
||||
example = "1;31";
|
||||
visible = false;
|
||||
};
|
||||
|
||||
colorsType = types.submodule {
|
||||
options = {
|
||||
null = colorType;
|
||||
false = colorType;
|
||||
true = colorType;
|
||||
numbers = colorType;
|
||||
strings = colorType;
|
||||
arrays = colorType;
|
||||
objects = colorType;
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.jq = {
|
||||
enable = mkEnableOption "the jq command-line JSON processor";
|
||||
|
||||
colors = mkOption {
|
||||
description = ''
|
||||
The colors used in colored JSON output.</para>
|
||||
|
||||
<para>See <link xlink:href="https://stedolan.github.io/jq/manual/#Colors"/>.
|
||||
'';
|
||||
|
||||
example = literalExample ''
|
||||
{
|
||||
null = "1;30";
|
||||
false = "0;31";
|
||||
true = "0;32";
|
||||
numbers = "0;36";
|
||||
strings = "0;33";
|
||||
arrays = "1;35";
|
||||
objects = "1;37";
|
||||
}
|
||||
'';
|
||||
|
||||
default = {
|
||||
null = "1;30";
|
||||
false = "0;39";
|
||||
true = "0;39";
|
||||
numbers = "0;39";
|
||||
strings = "0;32";
|
||||
arrays = "1;39";
|
||||
objects = "1;39";
|
||||
};
|
||||
|
||||
type = colorsType;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.jq ];
|
||||
|
||||
home.sessionVariables = let c = cfg.colors;
|
||||
in {
|
||||
JQ_COLORS =
|
||||
"${c.null}:${c.false}:${c.true}:${c.numbers}:${c.strings}:${c.arrays}:${c.objects}";
|
||||
};
|
||||
};
|
||||
}
|
||||
627
modules/programs/kakoune.nix
Normal file
627
modules/programs/kakoune.nix
Normal file
@@ -0,0 +1,627 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.kakoune;
|
||||
|
||||
hook = types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.enum [
|
||||
"NormalBegin"
|
||||
"NormalIdle"
|
||||
"NormalEnd"
|
||||
"NormalKey"
|
||||
"InsertBegin"
|
||||
"InsertIdle"
|
||||
"InsertEnd"
|
||||
"InsertKey"
|
||||
"InsertChar"
|
||||
"InsertDelete"
|
||||
"InsertMove"
|
||||
"WinCreate"
|
||||
"WinClose"
|
||||
"WinResize"
|
||||
"WinDisplay"
|
||||
"WinSetOption"
|
||||
"BufSetOption"
|
||||
"BufNewFile"
|
||||
"BufOpenFile"
|
||||
"BufCreate"
|
||||
"BufWritePre"
|
||||
"BufWritePost"
|
||||
"BufReload"
|
||||
"BufClose"
|
||||
"BufOpenFifo"
|
||||
"BufReadFifo"
|
||||
"BufCloseFifo"
|
||||
"RuntimeError"
|
||||
"ModeChange"
|
||||
"PromptIdle"
|
||||
"GlobalSetOption"
|
||||
"KakBegin"
|
||||
"KakEnd"
|
||||
"FocusIn"
|
||||
"FocusOut"
|
||||
"RawKey"
|
||||
"InsertCompletionShow"
|
||||
"InsertCompletionHide"
|
||||
"InsertCompletionSelect"
|
||||
"ModuleLoaded"
|
||||
];
|
||||
example = "SetOption";
|
||||
description = ''
|
||||
The name of the hook. For a description, see
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc#default-hooks"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
once = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Remove the hook after running it once.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Add the hook to the named group.
|
||||
'';
|
||||
};
|
||||
|
||||
option = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "filetype=latex";
|
||||
description = ''
|
||||
Additional option to pass to the hook.
|
||||
'';
|
||||
};
|
||||
|
||||
commands = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = "set-option window indentwidth 2";
|
||||
description = ''
|
||||
Commands to run when the hook is activated.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
keyMapping = types.submodule {
|
||||
options = {
|
||||
mode = mkOption {
|
||||
type = types.enum [
|
||||
"insert"
|
||||
"normal"
|
||||
"prompt"
|
||||
"menu"
|
||||
"user"
|
||||
"goto"
|
||||
"view"
|
||||
"object"
|
||||
];
|
||||
example = "user";
|
||||
description = ''
|
||||
The mode in which the mapping takes effect.
|
||||
'';
|
||||
};
|
||||
|
||||
docstring = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Optional documentation text to display in info boxes.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
example = "<a-x>";
|
||||
description = ''
|
||||
The key to be mapped. See
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc#mappable-keys"/>
|
||||
for possible values.
|
||||
'';
|
||||
};
|
||||
|
||||
effect = mkOption {
|
||||
type = types.str;
|
||||
example = ":wq<ret>";
|
||||
description = ''
|
||||
The sequence of keys to be mapped.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configModule = types.submodule {
|
||||
options = {
|
||||
colorScheme = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Set the color scheme. To see available schemes, enter
|
||||
<command>colorscheme</command> at the kakoune prompt.
|
||||
'';
|
||||
};
|
||||
|
||||
tabStop = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
The width of a tab in spaces. The kakoune default is
|
||||
<literal>6</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
indentWidth = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
The width of an indentation in spaces.
|
||||
The kakoune default is <literal>4</literal>.
|
||||
If <literal>0</literal>, a tab will be used instead.
|
||||
'';
|
||||
};
|
||||
|
||||
incrementalSearch = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Execute a search as it is being typed.
|
||||
'';
|
||||
};
|
||||
|
||||
alignWithTabs = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use tabs for the align command.
|
||||
'';
|
||||
};
|
||||
|
||||
autoInfo = mkOption {
|
||||
type = types.nullOr
|
||||
(types.listOf (types.enum [ "command" "onkey" "normal" ]));
|
||||
default = null;
|
||||
example = [ "command" "normal" ];
|
||||
description = ''
|
||||
Contexts in which to display automatic information box.
|
||||
The kakoune default is <literal>[ "command" "onkey" ]</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
autoComplete = mkOption {
|
||||
type = types.nullOr (types.listOf (types.enum [ "insert" "prompt" ]));
|
||||
default = null;
|
||||
description = ''
|
||||
Modes in which to display possible completions.
|
||||
The kakoune default is <literal>[ "insert" "prompt" ]</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
autoReload = mkOption {
|
||||
type = types.nullOr (types.enum [ "yes" "no" "ask" ]);
|
||||
default = null;
|
||||
description = ''
|
||||
Reload buffers when an external modification is detected.
|
||||
The kakoune default is <literal>"ask"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
scrollOff = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
lines = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
The number of lines to keep visible around the cursor.
|
||||
'';
|
||||
};
|
||||
|
||||
columns = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
The number of columns to keep visible around the cursor.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
How many lines and columns to keep visible around the cursor.
|
||||
'';
|
||||
};
|
||||
|
||||
ui = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
setTitle = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Change the title of the terminal emulator.
|
||||
'';
|
||||
};
|
||||
|
||||
statusLine = mkOption {
|
||||
type = types.enum [ "top" "bottom" ];
|
||||
default = "bottom";
|
||||
description = ''
|
||||
Where to display the status line.
|
||||
'';
|
||||
};
|
||||
|
||||
assistant = mkOption {
|
||||
type = types.enum [ "clippy" "cat" "dilbert" "none" ];
|
||||
default = "clippy";
|
||||
description = ''
|
||||
The assistant displayed in info boxes.
|
||||
'';
|
||||
};
|
||||
|
||||
enableMouse = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable mouse support.
|
||||
'';
|
||||
};
|
||||
|
||||
changeColors = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Change color palette.
|
||||
'';
|
||||
};
|
||||
|
||||
wheelDownButton = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Button to send for wheel down events.
|
||||
'';
|
||||
};
|
||||
|
||||
wheelUpButton = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Button to send for wheel up events.
|
||||
'';
|
||||
};
|
||||
|
||||
shiftFunctionKeys = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
Amount by which shifted function keys are offset. That
|
||||
is, if the terminal sends F13 for Shift-F1, this
|
||||
should be <literal>12</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
useBuiltinKeyParser = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Bypass ncurses key parser and use an internal one.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the ncurses interface.
|
||||
'';
|
||||
};
|
||||
|
||||
showMatching = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Highlight the matching char of the character under the
|
||||
selections' cursor using the <literal>MatchingChar</literal>
|
||||
face.
|
||||
'';
|
||||
};
|
||||
|
||||
wrapLines = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "the wrap lines highlighter";
|
||||
|
||||
word = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Wrap at word boundaries instead of codepoint boundaries.
|
||||
'';
|
||||
};
|
||||
|
||||
indent = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Preserve line indentation when wrapping.
|
||||
'';
|
||||
};
|
||||
|
||||
maxWidth = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
description = ''
|
||||
Wrap text at maxWidth, even if the window is wider.
|
||||
'';
|
||||
};
|
||||
|
||||
marker = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "⏎";
|
||||
description = ''
|
||||
Prefix wrapped lines with marker text.
|
||||
If not <literal>null</literal>,
|
||||
the marker text will be displayed in the indentation if possible.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the wrap lines highlighter.
|
||||
'';
|
||||
};
|
||||
|
||||
numberLines = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "the number lines highlighter";
|
||||
|
||||
relative = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Show line numbers relative to the main cursor line.
|
||||
'';
|
||||
};
|
||||
|
||||
highlightCursor = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Highlight the cursor line with a separate face.
|
||||
'';
|
||||
};
|
||||
|
||||
separator = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
String that separates the line number column from the
|
||||
buffer contents. The kakoune default is
|
||||
<literal>"|"</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the number lines highlighter.
|
||||
'';
|
||||
};
|
||||
|
||||
showWhitespace = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "the show whitespace highlighter";
|
||||
|
||||
lineFeed = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for line feeds.
|
||||
The kakoune default is <literal>"¬"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
space = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for spaces.
|
||||
The kakoune default is <literal>"·"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
nonBreakingSpace = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for non-breaking spaces.
|
||||
The kakoune default is <literal>"⍽"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
tab = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to display for tabs.
|
||||
The kakoune default is <literal>"→"</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
tabStop = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The character to append to tabs to reach the width of a tabstop.
|
||||
The kakoune default is <literal>" "</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = ''
|
||||
Settings for the show whitespaces highlighter.
|
||||
'';
|
||||
};
|
||||
|
||||
keyMappings = mkOption {
|
||||
type = types.listOf keyMapping;
|
||||
default = [ ];
|
||||
description = ''
|
||||
User-defined key mappings. For documentation, see
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
hooks = mkOption {
|
||||
type = types.listOf hook;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Global hooks. For documentation, see
|
||||
<link xlink:href="https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc"/>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configFile = let
|
||||
wrapOptions = with cfg.config.wrapLines;
|
||||
concatStrings [
|
||||
"${optionalString word " -word"}"
|
||||
"${optionalString indent " -indent"}"
|
||||
"${optionalString (marker != null) " -marker ${marker}"}"
|
||||
"${optionalString (maxWidth != null) " -width ${toString maxWidth}"}"
|
||||
];
|
||||
|
||||
numberLinesOptions = with cfg.config.numberLines;
|
||||
concatStrings [
|
||||
"${optionalString relative " -relative "}"
|
||||
"${optionalString highlightCursor " -hlcursor"}"
|
||||
"${optionalString (separator != null) " -separator ${separator}"}"
|
||||
];
|
||||
|
||||
showWhitespaceOptions = with cfg.config.showWhitespace;
|
||||
concatStrings [
|
||||
(optionalString (tab != null) " -tab ${tab}")
|
||||
(optionalString (tabStop != null) " -tabpad ${tabStop}")
|
||||
(optionalString (space != null) " -spc ${space}")
|
||||
(optionalString (nonBreakingSpace != null) " -nbsp ${nonBreakingSpace}")
|
||||
(optionalString (lineFeed != null) " -lf ${lineFeed}")
|
||||
];
|
||||
|
||||
uiOptions = with cfg.config.ui;
|
||||
concatStringsSep " " [
|
||||
"ncurses_set_title=${if setTitle then "true" else "false"}"
|
||||
"ncurses_status_on_top=${
|
||||
if (statusLine == "top") then "true" else "false"
|
||||
}"
|
||||
"ncurses_assistant=${assistant}"
|
||||
"ncurses_enable_mouse=${if enableMouse then "true" else "false"}"
|
||||
"ncurses_change_colors=${if changeColors then "true" else "false"}"
|
||||
"${optionalString (wheelDownButton != null)
|
||||
"ncurses_wheel_down_button=${wheelDownButton}"}"
|
||||
"${optionalString (wheelUpButton != null)
|
||||
"ncurses_wheel_up_button=${wheelUpButton}"}"
|
||||
"${optionalString (shiftFunctionKeys != null)
|
||||
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
|
||||
"ncurses_builtin_key_parser=${
|
||||
if useBuiltinKeyParser then "true" else "false"
|
||||
}"
|
||||
];
|
||||
|
||||
keyMappingString = km:
|
||||
concatStringsSep " " [
|
||||
"map global"
|
||||
"${km.mode} ${km.key} '${km.effect}'"
|
||||
"${optionalString (km.docstring != null)
|
||||
"-docstring '${km.docstring}'"}"
|
||||
];
|
||||
|
||||
hookString = h:
|
||||
concatStringsSep " " [
|
||||
"hook"
|
||||
"${optionalString (h.group != null) "-group ${group}"}"
|
||||
"${optionalString (h.once) "-once"}"
|
||||
"global"
|
||||
"${h.name}"
|
||||
"${optionalString (h.option != null) h.option}"
|
||||
"%{ ${h.commands} }"
|
||||
];
|
||||
|
||||
cfgStr = with cfg.config;
|
||||
concatStringsSep "\n" ([ "# Generated by home-manager" ]
|
||||
++ optional (colorScheme != null) "colorscheme ${colorScheme}"
|
||||
++ optional (tabStop != null)
|
||||
"set-option global tabstop ${toString tabStop}"
|
||||
++ optional (indentWidth != null)
|
||||
"set-option global indentwidth ${toString indentWidth}"
|
||||
++ optional (!incrementalSearch) "set-option global incsearch false"
|
||||
++ optional (alignWithTabs) "set-option global aligntab true"
|
||||
++ optional (autoInfo != null)
|
||||
"set-option global autoinfo ${concatStringsSep "|" autoInfo}"
|
||||
++ optional (autoComplete != null)
|
||||
"set-option global autocomplete ${concatStringsSep "|" autoComplete}"
|
||||
++ optional (autoReload != null)
|
||||
"set-option global autoreload ${autoReload}"
|
||||
++ optional (wrapLines != null && wrapLines.enable)
|
||||
"add-highlighter global/ wrap${wrapOptions}"
|
||||
++ optional (numberLines != null && numberLines.enable)
|
||||
"add-highlighter global/ number-lines${numberLinesOptions}"
|
||||
++ optional showMatching "add-highlighter global/ show-matching"
|
||||
++ optional (showWhitespace != null && showWhitespace.enable)
|
||||
"add-highlighter global/ show-whitespaces${showWhitespaceOptions}"
|
||||
++ optional (scrollOff != null)
|
||||
"set-option global scrolloff ${toString scrollOff.lines},${
|
||||
toString scrollOff.columns
|
||||
}"
|
||||
|
||||
++ [ "# UI options" ]
|
||||
++ optional (ui != null) "set-option global ui_options ${uiOptions}"
|
||||
|
||||
++ [ "# Key mappings" ] ++ map keyMappingString keyMappings
|
||||
|
||||
++ [ "# Hooks" ] ++ map hookString hooks);
|
||||
in pkgs.writeText "kakrc"
|
||||
(optionalString (cfg.config != null) cfgStr + "\n" + cfg.extraConfig);
|
||||
|
||||
in {
|
||||
options = {
|
||||
programs.kakoune = {
|
||||
enable = mkEnableOption "the kakoune text editor";
|
||||
|
||||
config = mkOption {
|
||||
type = types.nullOr configModule;
|
||||
default = { };
|
||||
description = "kakoune configuration options.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration lines to add to
|
||||
<filename>~/.config/kak/kakrc</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.kakoune ];
|
||||
xdg.configFile."kak/kakrc".source = configFile;
|
||||
};
|
||||
}
|
||||
115
modules/programs/keychain.nix
Normal file
115
modules/programs/keychain.nix
Normal file
@@ -0,0 +1,115 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.keychain;
|
||||
|
||||
flags = cfg.extraFlags ++ optional (cfg.agents != [ ])
|
||||
"--agents ${concatStringsSep "," cfg.agents}"
|
||||
++ optional (cfg.inheritType != null) "--inherit ${cfg.inheritType}";
|
||||
|
||||
shellCommand =
|
||||
"${cfg.package}/bin/keychain --eval ${concatStringsSep " " flags} ${
|
||||
concatStringsSep " " cfg.keys
|
||||
}";
|
||||
|
||||
in {
|
||||
meta.maintainers = [ maintainers.marsam ];
|
||||
|
||||
options.programs.keychain = {
|
||||
enable = mkEnableOption "keychain";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.keychain;
|
||||
defaultText = literalExample "pkgs.keychain";
|
||||
description = ''
|
||||
Keychain package to install.
|
||||
'';
|
||||
};
|
||||
|
||||
keys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "id_rsa" ];
|
||||
description = ''
|
||||
Keys to add to keychain.
|
||||
'';
|
||||
};
|
||||
|
||||
agents = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Agents to add.
|
||||
'';
|
||||
};
|
||||
|
||||
inheritType = mkOption {
|
||||
type =
|
||||
types.nullOr (types.enum [ "local" "any" "local-once" "any-once" ]);
|
||||
default = null;
|
||||
description = ''
|
||||
Inherit type to attempt from agent variables from the environment.
|
||||
'';
|
||||
};
|
||||
|
||||
extraFlags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "--quiet" ];
|
||||
description = ''
|
||||
Extra flags to pass to keychain.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Bash integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableFishIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Fish integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableZshIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable Zsh integration.
|
||||
'';
|
||||
};
|
||||
|
||||
enableXsessionIntegration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
visible = pkgs.stdenv.hostPlatform.isLinux;
|
||||
description = ''
|
||||
Whether to run keychain from your <filename>~/.xsession</filename>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration ''
|
||||
eval "$(${shellCommand})"
|
||||
'';
|
||||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
eval (${shellCommand})
|
||||
'';
|
||||
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${shellCommand})"
|
||||
'';
|
||||
xsession.initExtra = mkIf cfg.enableXsessionIntegration ''
|
||||
eval "$(${shellCommand})"
|
||||
'';
|
||||
};
|
||||
}
|
||||
91
modules/programs/kitty.nix
Normal file
91
modules/programs/kitty.nix
Normal file
@@ -0,0 +1,91 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.kitty;
|
||||
|
||||
eitherStrBoolInt = with types; either str (either bool int);
|
||||
|
||||
optionalPackage = opt:
|
||||
optional (opt != null && opt.package != null) opt.package;
|
||||
|
||||
toKittyConfig = generators.toKeyValue {
|
||||
mkKeyValue = key: value:
|
||||
let
|
||||
value' = if isBool value then
|
||||
(if value then "yes" else "no")
|
||||
else
|
||||
toString value;
|
||||
in "${key} ${value'}";
|
||||
};
|
||||
|
||||
toKittyKeybindings = generators.toKeyValue {
|
||||
mkKeyValue = key: command: "map ${key} ${command}";
|
||||
};
|
||||
|
||||
in {
|
||||
options.programs.kitty = {
|
||||
enable = mkEnableOption "Kitty terminal emulator";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf eitherStrBoolInt;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
scrollback_lines = 10000;
|
||||
enable_audio_bell = false;
|
||||
update_check_interval = 0;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to
|
||||
<filename>~/.config/kitty/kitty.conf</filename>. See
|
||||
<link xlink:href="https://sw.kovidgoyal.net/kitty/conf.html" />
|
||||
for the documentation.
|
||||
'';
|
||||
};
|
||||
|
||||
font = mkOption {
|
||||
type = types.nullOr hm.types.fontType;
|
||||
default = null;
|
||||
description = "The font to use.";
|
||||
};
|
||||
|
||||
keybindings = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Mapping of keybindings to actions.";
|
||||
example = literalExample ''
|
||||
{
|
||||
"ctrl+c" = "copy_or_interrupt";
|
||||
"ctrl+f>2" = "set_font_size 20";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Additional configuration to add.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ pkgs.kitty ] ++ optionalPackage cfg.font;
|
||||
|
||||
xdg.configFile."kitty/kitty.conf".text = ''
|
||||
# Generated by Home Manager.
|
||||
# See https://sw.kovidgoyal.net/kitty/conf.html
|
||||
|
||||
${optionalString (cfg.font != null) "font_family ${cfg.font.name}"}
|
||||
|
||||
${toKittyConfig cfg.settings}
|
||||
|
||||
${toKittyKeybindings cfg.keybindings}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
}
|
||||
69
modules/programs/lieer-accounts.nix
Normal file
69
modules/programs/lieer-accounts.nix
Normal file
@@ -0,0 +1,69 @@
|
||||
{ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.lieer = {
|
||||
enable = mkEnableOption "lieer Gmail synchronization for notmuch";
|
||||
|
||||
timeout = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
description = ''
|
||||
HTTP timeout in seconds. 0 means forever or system timeout.
|
||||
'';
|
||||
};
|
||||
|
||||
replaceSlashWithDot = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Replace '/' with '.' in Gmail labels.
|
||||
'';
|
||||
};
|
||||
|
||||
dropNonExistingLabels = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Allow missing labels on the Gmail side to be dropped.
|
||||
'';
|
||||
};
|
||||
|
||||
ignoreTagsLocal = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Set custom tags to ignore when syncing from local to
|
||||
remote (after translations).
|
||||
'';
|
||||
};
|
||||
|
||||
ignoreTagsRemote = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"CATEGORY_FORUMS"
|
||||
"CATEGORY_PROMOTIONS"
|
||||
"CATEGORY_UPDATES"
|
||||
"CATEGORY_SOCIAL"
|
||||
"CATEGORY_PERSONAL"
|
||||
];
|
||||
description = ''
|
||||
Set custom tags to ignore when syncing from remote to
|
||||
local (before translations).
|
||||
'';
|
||||
};
|
||||
|
||||
notmuchSetupWarning = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Warn if Notmuch is not also enabled for this account.
|
||||
</para><para>
|
||||
This can safely be disabled if <command>notmuch init</command>
|
||||
has been used to configure this account outside of Home
|
||||
Manager.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user