Compare commits
961 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd2c3d5902 | |||
| 06f45bb7b9 | |||
| 864d42397e | |||
| f43f5b14d5 | |||
| ebf9a48677 | |||
| b382999a70 | |||
| d7738efed2 | |||
| 88358607f2 | |||
| bf3f364f89 | |||
| 3247e4a8e6 | |||
| 54c2240be6 | |||
| 2b8d059ecc | |||
| 52d04c1cb1 | |||
| 5ed77b764f | |||
| 7c91ffb251 | |||
| f12e5a4293 | |||
| fb9f757519 | |||
| 606b1d3412 | |||
| 4d0741c841 | |||
| efcee11839 | |||
| 310ac5c3e7 | |||
| 5a56d4808c | |||
| 9385c5dba5 | |||
| ab414236ce | |||
| b997697aed | |||
| d59061e526 | |||
| 2c8d0f629c | |||
| 2072da67a5 | |||
| 77bd038f32 | |||
| b4015c2189 | |||
| 69a64b209a | |||
| c7c771804a | |||
| f933146a42 | |||
| d20760cd61 | |||
| 5811a41aca | |||
| b7845ef85e | |||
| 996a27965f | |||
| d3ddf34267 | |||
| f141b49dc3 | |||
| 9914644189 | |||
| 7d56db3e47 | |||
| dbc5fcbd01 | |||
| b8e580ee5a | |||
| fa5b1b2752 | |||
| eb75f1fa49 | |||
| 8542fef152 | |||
| 4cf92e7199 | |||
| 4d24c74c16 | |||
| 1a7e4d52aa | |||
| fcde4b8e83 | |||
| 3c5f0751f5 | |||
| f4ee1a0685 | |||
| a6499f3cb9 | |||
| 8deb3f809b | |||
| bff316ab7e | |||
| 985beb8bd4 | |||
| 629ef6e451 | |||
| fa492e0b26 | |||
| 9f0570d367 | |||
| bbe0f29435 | |||
| b047c064d6 | |||
| 3b346c4dd9 | |||
| ed1b4775eb | |||
| 0286a84f23 | |||
| c31525e667 | |||
| b50c59d60e | |||
| 7a229f6e79 | |||
| 2cbf8df0fa | |||
| 533fcb6144 | |||
| f0217c68f5 | |||
| e2f9c59cb6 | |||
| 5a57d97d36 | |||
| 3a470f1b1f | |||
| 37fff317ef | |||
| 1ead059695 | |||
| 9a61f3c889 | |||
| f800d96673 | |||
| 64205a79fd | |||
| 2ec9eed885 | |||
| 9a71920fd4 | |||
| 0a9dee2aee | |||
| f6b34b042f | |||
| 6d1bdd2b40 | |||
| 010f3ece90 | |||
| 5f8f5c79d5 | |||
| 2390ece70b | |||
| 36f5367a5d | |||
| a73ebc7726 | |||
| c19184a6be | |||
| 1a3b02a062 | |||
| 996b1dd077 | |||
| 0c60bc495f | |||
| 96ee6f2c01 | |||
| 517949b78f | |||
| cb43947e32 | |||
| f1c79bbb70 | |||
| 5fe647c0d3 | |||
| a321d2c803 | |||
| e5fa57c660 | |||
| e5b0545dfd | |||
| ef1fb417ad | |||
| b75e9d6abe | |||
| 05028b84d4 | |||
| b6e51e1950 | |||
| 9626986524 | |||
| 279b1b69eb | |||
| 88092aba5b | |||
| 4c00a430d6 | |||
| 4d23a5eb19 | |||
| 9c07aa1113 | |||
| 34ca7615b4 | |||
| fd4f1f9086 | |||
| fe6caebe2e | |||
| 0da119a5e8 | |||
| a2af4728f3 | |||
| ae238d401d | |||
| 7cbff9ef3b | |||
| fa5aaf4f97 | |||
| 45c6d0f604 | |||
| 47225fffbc | |||
| d022fc3fa9 | |||
| f034011f96 | |||
| a5bb4a471a | |||
| 2b781b030c | |||
| 32e0131620 | |||
| 339e1ddb76 | |||
| 2db93b7b01 | |||
| 7fcafe3d04 | |||
| 28ea82df03 | |||
| 18a40b49e3 | |||
| 140b84df2b | |||
| 9b3a431942 | |||
| e7d5ad707f | |||
| fb55262f39 | |||
| 6c80d9907b | |||
| a541754381 | |||
| e88f42182f | |||
| 6dacc92ba3 | |||
| 36ac1b51da | |||
| f4c39598ec | |||
| f765fcd633 | |||
| 54c797396c | |||
| 036d5c7fba | |||
| af225f2271 | |||
| 1126e8c6a7 | |||
| 3f505194b5 | |||
| 819463aa20 | |||
| 7e674669d3 | |||
| fa6dd68818 | |||
| 6367c91f7a | |||
| 3f9d23dbad | |||
| aa95ad60b7 | |||
| f91d4a26fc | |||
| 5c92c0e0ac | |||
| 0695229e9d | |||
| d8901e3169 | |||
| 544ec79aff | |||
| c70f9de97c | |||
| 45a149f05a | |||
| f3b233330b | |||
| 9a09854c59 | |||
| b8f61f2946 | |||
| b0f259253b | |||
| 22066db41b | |||
| a2814f326c | |||
| ad861dcc59 | |||
| 3eec2a1837 | |||
| 40ff86d6d7 | |||
| e6aa017562 | |||
| 266a190b19 | |||
| 0504d0503b | |||
| 63d686ad3a | |||
| 3302f44178 | |||
| b231111d93 | |||
| dce701146c | |||
| 62ce9eb8cb | |||
| 6b183a0220 | |||
| 90cd503219 | |||
| a0e00c5453 | |||
| 27f1d54a79 | |||
| 05682dbac9 | |||
| b9b9a55ede | |||
| b75195d339 | |||
| 7f72a0612b | |||
| d1cdddc9ca | |||
| c02590c07a | |||
| 8646c1a4ff | |||
| 0b8a50b6d9 | |||
| 66276562b9 | |||
| b9a206054a | |||
| 7cc94146b8 | |||
| 0645a593e6 | |||
| ecc335b07e | |||
| ec5ef05983 | |||
| fd438f74c6 | |||
| 7e36360550 | |||
| 86bdd6539c | |||
| 9a2fa01711 | |||
| 3992de319c | |||
| be6e0a9882 | |||
| 15eb7f5a0f | |||
| 501b2397d8 | |||
| 2c08b2f1fa | |||
| d8aeb36b27 | |||
| aa3c26d907 | |||
| f0e0b18c5f | |||
| 55139cd4fe | |||
| 533758d5da | |||
| 62505e4488 | |||
| 1d8452f232 | |||
| e4eb232d8f | |||
| 360c218344 | |||
| e3b0eca505 | |||
| 8d69b2907f | |||
| d869e7d5ce | |||
| 4345509218 | |||
| a6587cfd79 | |||
| b1fac0dce5 | |||
| f47f24cf34 | |||
| 05caa0c33a | |||
| 40921d4199 | |||
| 9843ea9db5 | |||
| f51242ae08 | |||
| 4f1c138a01 | |||
| f7dd9cd6e2 | |||
| c90317a84b | |||
| 7f1d365f0b | |||
| 9d67e03f97 | |||
| d559655e26 | |||
| 03d822da3f | |||
| 02e040d294 | |||
| cba3212896 | |||
| 68e5d860d8 | |||
| a76daab3ce | |||
| 489f82f24b | |||
| 94aec4440e | |||
| 9cbffaf841 | |||
| 3f2049ab02 | |||
| 95bdf1d091 | |||
| fe73f73adb | |||
| 0148834e15 | |||
| 4ca27063e2 | |||
| f3f74cfd70 | |||
| 4d53f559b1 | |||
| cf2c1a4437 | |||
| 29afd7f670 | |||
| 16b75e90b6 | |||
| 11bbedcde7 | |||
| 1ec9c22fd0 | |||
| c4a28eb062 | |||
| 8c8a9105e4 | |||
| 04a689c5d1 | |||
| 36b44128a0 | |||
| 6fe2d2f002 | |||
| 9b96ff35d6 | |||
| 471661239f | |||
| 00b4997a74 | |||
| 1d2bdc1beb | |||
| ca5388740f | |||
| 1812510e0d | |||
| 161fd0db6a | |||
| f166761af7 | |||
| 228a7099d0 | |||
| 8c9a212e64 | |||
| 343ebacdcf | |||
| b6f46da403 | |||
| 2f58484b4c | |||
| 7da2c3dd93 | |||
| 95fc029194 | |||
| 40be9f8a55 | |||
| e42fda1d43 | |||
| 70f5b26fd2 | |||
| 3b796515d4 | |||
| e809caa9fd | |||
| 919527d6fc | |||
| 31ac4f1439 | |||
| 1581992b8d | |||
| abac10ac49 | |||
| 06d7e9f7d5 | |||
| c3ba586954 | |||
| 4eb5af38e3 | |||
| e629ece0eb | |||
| b774bb99c8 | |||
| 49e3b91e7e | |||
| 0cac1559b8 | |||
| 8ad6be56a5 | |||
| 2d08fd3cb7 | |||
| ede2763756 | |||
| 474bd8ebf4 | |||
| d66c4316aa | |||
| 7d9abf1a01 | |||
| e9eb3d44a4 | |||
| b492ffa227 | |||
| cba58c7478 | |||
| 3676862097 | |||
| a45c63b744 | |||
| dfd3fb3ed3 | |||
| f90b4d064f | |||
| f571b1d02f | |||
| 966e889643 | |||
| 30740c73c9 | |||
| 516894b870 | |||
| a8b98bc03e | |||
| b979df91fd | |||
| 0e0ac0237c | |||
| 5f4f663e8b | |||
| 36c56b7d8d | |||
| b82353b513 | |||
| f9a650f352 | |||
| 707192cf81 | |||
| cabdfd8cb7 | |||
| b79cc2faf4 | |||
| 72bd225ca2 | |||
| daa883caf8 | |||
| 292809783d | |||
| d5ef998239 | |||
| 3f7c023251 | |||
| d8268599d8 | |||
| aaef949c99 | |||
| 9ffdbfe068 | |||
| 9424045430 | |||
| 3d93e1b565 | |||
| 1e260e4d17 | |||
| 04aff6d8d8 | |||
| 086c7ad27b | |||
| bb46ed1263 | |||
| e82b5e0770 | |||
| 55efe14c41 | |||
| 0a5f4dacba | |||
| 0667011531 | |||
| 8af056a3ea | |||
| 76883edf0b | |||
| a9c2031aee | |||
| 538dc8954b | |||
| 09c73d9f5e | |||
| f65ecdd821 | |||
| eaa31be821 | |||
| 57a3af6e40 | |||
| 3d8417b4a2 | |||
| 2e0863ae6d | |||
| b0c1301367 | |||
| f68fe49720 | |||
| 59d9601f49 | |||
| 4f2e1e050c | |||
| 98aba2f6da | |||
| 1dbd81e2fa | |||
| 04c2901b5e | |||
| a3b9c43c44 | |||
| b0a6886b31 | |||
| 4873d63ff7 | |||
| 37529429bf | |||
| 906fd006b0 | |||
| 65a07315f2 | |||
| 04dedc9fa9 | |||
| cbfe78f179 | |||
| c9102ead4f | |||
| 26e5a3d12e | |||
| bed0d1acdc | |||
| a2dbd51b2e | |||
| 6f8b0f02fd | |||
| 6c18d36d48 | |||
| cd2e2509bd | |||
| fc6f064a51 | |||
| 5809155f4b | |||
| 3cdb3bb181 | |||
| 18ac49f165 | |||
| 4a76601970 | |||
| bfb970a6d7 | |||
| 8ba3c2713f | |||
| 166a4d0369 | |||
| df7c007de3 | |||
| 7807f789cf | |||
| ed822139ec | |||
| c5b855765e | |||
| e3ba141695 | |||
| 709f56a0c2 | |||
| dbac1b8bd7 | |||
| e2295f350b | |||
| 1efb20f534 | |||
| 23582c25a1 | |||
| 578a845e60 | |||
| 1443cc06de | |||
| eb91c223ff | |||
| 0347b877c4 | |||
| e1981c2e91 | |||
| dd2edb3216 | |||
| a8d6d2e29e | |||
| 0cfc6140b6 | |||
| 6a14d05f5b | |||
| 03007f48bf | |||
| b8f5458ba1 | |||
| aac30d1313 | |||
| 5163067773 | |||
| 57fdf25c46 | |||
| 1f43d47695 | |||
| 7da7eadff5 | |||
| 077203b375 | |||
| 6b978b074d | |||
| af8315a657 | |||
| 6442377d1c | |||
| b81b285d92 | |||
| d393fa707f | |||
| 62c14b3c84 | |||
| 29e9e4cecd | |||
| 2cdb0afe48 | |||
| 19d6cdf416 | |||
| 973c4d27d0 | |||
| 248cf2e86f | |||
| 148da9eecf | |||
| 0ceb810133 | |||
| 137e11e81f | |||
| 8c71e7aade | |||
| 03a14c40fe | |||
| 95b976c171 | |||
| de5b30e92a | |||
| 9a937013d8 | |||
| 1962a582c2 | |||
| 271fad0288 | |||
| 3c1df26fc9 | |||
| c205079d46 | |||
| 49dd2c1b2f | |||
| 669404d2c3 | |||
| e6008a35ad | |||
| 00cab89857 | |||
| 53e6c6d872 | |||
| bbe6ac0fcd | |||
| 54cd7bdcdb | |||
| 735f803c66 | |||
| 378319e4bf | |||
| 15727ea482 | |||
| 3b548b581c | |||
| d2a1bb18eb | |||
| e29f62f228 | |||
| 0013c9d01e | |||
| 07a45af96b | |||
| 3a1eaa589d | |||
| fe599a2143 | |||
| 9915343370 | |||
| b3c91a0e7a | |||
| 1d6ffd7785 | |||
| 647f56d213 | |||
| 210aa544fc | |||
| 5e83259bcb | |||
| 0a2aae246a | |||
| 30881f356a | |||
| 3aaaeb49ca | |||
| 55e12cddaf | |||
| ac4f625768 | |||
| 2d44bc6006 | |||
| 03c1d14ed9 | |||
| 73a746cebd | |||
| 1e9dc4df4b | |||
| 7dd55a5de9 | |||
| e61116140d | |||
| b75b79057b | |||
| 1f08d10ac7 | |||
| b2cf885637 | |||
| 44eb487df9 | |||
| 006bf56fd7 | |||
| 73e3707570 | |||
| 82cfa4c6f7 | |||
| 27dd5ebb13 | |||
| a589feee7b | |||
| a9459e7606 | |||
| ad86ed60dc | |||
| 2a42da46ad | |||
| 1817f41423 | |||
| 217057612c | |||
| a1b5572eea | |||
| cddd8101c7 | |||
| d6f6154a22 | |||
| 8ac24e4f13 | |||
| e4abf62ec3 | |||
| 05aa451895 | |||
| c49a96ae29 | |||
| ac3c05545f | |||
| b12af73ff6 | |||
| 45b52845f7 | |||
| 434b3bfe81 | |||
| 6c1cd365a0 | |||
| b1d9bbc26e | |||
| 76b0b1c68d | |||
| 6dca4d1492 | |||
| a237c108d1 | |||
| 9832a955e4 | |||
| c90bb514d0 | |||
| 932e1a236c | |||
| e70f7269f4 | |||
| a07dfbe36a | |||
| d57e3ff61b | |||
| 6f38faef79 | |||
| 50d9301e13 | |||
| 58b02a6b16 | |||
| 29511fa574 | |||
| 809a68fa27 | |||
| 2ac43c8a33 | |||
| 802e9e6e39 | |||
| 625691084a | |||
| 38e7a45bb8 | |||
| dbe62811c7 | |||
| 8d83ded0fb | |||
| 74cec7dd8e | |||
| b2f75a37dc | |||
| a04a058077 | |||
| 7d03e63bdd | |||
| 1cf34add85 | |||
| 20b6aa07af | |||
| ab5a68ce9d | |||
| da729c1ade | |||
| f899d59da9 | |||
| ca8f0dc166 | |||
| 393338a23d | |||
| 5ca251646a | |||
| 75ef84913f | |||
| b92537e264 | |||
| e3a17925f2 | |||
| c170e251ac | |||
| ec1747707b | |||
| 56f2abc737 | |||
| cb6f46aea8 | |||
| dfab5ddacc | |||
| 0e2faec44f | |||
| 88671c40e7 | |||
| 9f59301a0e | |||
| d13a353921 | |||
| 989989ecc6 | |||
| 0a66a3b0a3 | |||
| be036118ca | |||
| 601fcafd31 | |||
| 087d38487c | |||
| b0e481a1f1 | |||
| 1ca7607814 | |||
| 59ea29a7ab | |||
| 486a3b343c | |||
| 3b7772712e | |||
| 37b34beca4 | |||
| ef60e7bf91 | |||
| 05bfd2df13 | |||
| 9d00eb39f9 | |||
| 30a9619f2c | |||
| da2ab6f86b | |||
| 7c61a58808 | |||
| 67c62534e8 | |||
| 26dc7bb149 | |||
| a1120fd930 | |||
| 13c72a8256 | |||
| 0322de2622 | |||
| d9be6f9213 | |||
| b977203d15 | |||
| db4e3b5fdd | |||
| a1f4764526 | |||
| 0996ec71e9 | |||
| 2e8d068070 | |||
| ee606e5518 | |||
| 440eb287ed | |||
| ee9828151c | |||
| 0b6bafb39c | |||
| df570294b4 | |||
| 5e0c7e90ff | |||
| ada780afc8 | |||
| d624ab4323 | |||
| f2dfb10c1b | |||
| f10666ff7c | |||
| a378fa3d60 | |||
| dfefa53e6b | |||
| 09a6af9d36 | |||
| 1172968a93 | |||
| 6d2ba3f0c1 | |||
| 262988949c | |||
| f5a745f37e | |||
| 02b6079198 | |||
| c645d31dd3 | |||
| 32a6789f44 | |||
| f173808e10 | |||
| 7ba80d4458 | |||
| e63a1a92e8 | |||
| 90cb0f987b | |||
| bfd05251f2 | |||
| 13b70df944 | |||
| a0c6965438 | |||
| e36daaa48c | |||
| ca239579d5 | |||
| d34d2adb42 | |||
| cc80f0e885 | |||
| 737603403a | |||
| 05a94aae60 | |||
| b02b7c0af8 | |||
| 24cd473387 | |||
| f6630bc6e0 | |||
| 417e6658dc | |||
| f626371732 | |||
| d318e35a93 | |||
| 7ddac56e17 | |||
| b060b69114 | |||
| 12f3032d8d | |||
| bbd300422b | |||
| b2d19ee218 | |||
| f5c1148c94 | |||
| f682523804 | |||
| b635efba09 | |||
| bd474f798e | |||
| 1575e50fea | |||
| ae851875a9 | |||
| 24630c5e5d | |||
| ae35522d11 | |||
| 6634eb7cb0 | |||
| d0568b9f19 | |||
| 803992635f | |||
| 9dbf2293ce | |||
| bc9b29f62b | |||
| 7347bcb842 | |||
| cc9dfa7940 | |||
| 0db7703857 | |||
| c8e84fbc36 | |||
| d3553ae104 | |||
| 9c5a1b12ef | |||
| d282a3b0b6 | |||
| 62487cc5ca | |||
| f81c62dc0a | |||
| f02f673012 | |||
| 0be942efe2 | |||
| 9f91849707 | |||
| 1cdf80adff | |||
| 8be00a52c8 | |||
| eb5c35d670 | |||
| d00d8cd43b | |||
| b4ea5aa354 | |||
| 8a9af081fc | |||
| ef86bc96f6 | |||
| 289888aa50 | |||
| 5b1b79a760 | |||
| c60388668c | |||
| 9c3e4bea8d | |||
| 2f6d1aa482 | |||
| c5267e7932 | |||
| 08baea2e22 | |||
| 356ed4bfdc | |||
| 3799aa0c90 | |||
| 28779f60ea | |||
| d0a9bdd002 | |||
| 0ee541c9e4 | |||
| e1baf45441 | |||
| e6c1b945f3 | |||
| 0efb7dfba1 | |||
| 4760e508be | |||
| 682346a66a | |||
| 0fac56f612 | |||
| 270d43251f | |||
| c3cf8138f8 | |||
| 7ccccfc84c | |||
| e39b79c508 | |||
| 664506b6cb | |||
| a946ff7cce | |||
| 99819c1df5 | |||
| c515ea9807 | |||
| 7ce3e9a391 | |||
| f61271a323 | |||
| 4a988dbce7 | |||
| 79a866a287 | |||
| bd53ef65ec | |||
| 804bf99e74 | |||
| 6e7fa3e223 | |||
| 508a45d801 | |||
| 7c9cb5156f | |||
| 08d8c4cbc5 | |||
| 7dc0adee72 | |||
| d61b27bcb5 | |||
| 0030a41a8f | |||
| 66fa46afb6 | |||
| 26da19ba38 | |||
| 81a4104973 | |||
| 6b55dfca46 | |||
| b3676ccbe6 | |||
| 71af10ff3b | |||
| a99adf065d | |||
| 2485f24fcc | |||
| 777d915cd2 | |||
| 5df740ca6e | |||
| dd27f9eaeb | |||
| d370d96f47 | |||
| 1e98f591f5 | |||
| 5e2bec4ac5 | |||
| 0c30883e22 | |||
| c9a42f1a13 | |||
| a9c123d9d4 | |||
| e4c9e863cf | |||
| 2970073d5e | |||
| 8bef422482 | |||
| 6247cecf0b | |||
| 721e74845a | |||
| 349ff8b5a1 | |||
| 4cf9b16faf | |||
| 8fc95549bf | |||
| f2dbaba802 | |||
| 538c81ca47 | |||
| 32161dd090 | |||
| a310ab4d4a | |||
| bc290e371b | |||
| b407453836 | |||
| 6ff9c397c8 | |||
| 033d50c738 | |||
| 7dc223a77e | |||
| c472654934 | |||
| 189a3a4689 | |||
| 1f0040a9dd | |||
| 5d8615cdb0 | |||
| 2f96ab5464 | |||
| c8bd133e49 | |||
| 5778d72dd4 | |||
| 01285af535 | |||
| e1cd93d6d1 | |||
| 714c45f5f9 | |||
| 87df015862 | |||
| c09091fa25 | |||
| 8b4a0a7055 | |||
| 78319f4ef6 | |||
| f66e73c5a6 | |||
| cf9d5acd95 | |||
| 98fed47741 | |||
| ed57391eb0 | |||
| fc4a44c023 | |||
| c158f17c63 | |||
| e61bd9ae14 | |||
| 4f6b899643 | |||
| 5d2cf3e5dd | |||
| befddfe476 | |||
| 204cb03922 | |||
| eebbb9f5e6 | |||
| ad76bb3451 | |||
| 0564357a9c | |||
| b44672d16c | |||
| 1164bebee4 | |||
| 29129215a5 | |||
| bc08dc1949 | |||
| 6e825eef7f | |||
| 6ae4d4ba80 | |||
| c34911ba26 | |||
| 82819ff091 | |||
| 12ef055135 | |||
| 5beb15c165 | |||
| cf6584ea71 | |||
| 3bbe86cb55 | |||
| 18c6e79d0c | |||
| 6fbefd0a67 | |||
| d502490bf6 | |||
| 3f6b5b321a | |||
| 2d06846467 | |||
| baac168826 | |||
| 78e5053ae5 | |||
| 25ac706450 | |||
| edff2bdc6c | |||
| 337f67109e | |||
| 450389400a | |||
| f52d604d42 | |||
| d12e3b979a | |||
| 7b482f8cfa | |||
| de1bc12b1b | |||
| a6fb453c9e | |||
| 32429619ab | |||
| cc6e5ea071 | |||
| ba29d32d80 | |||
| 0f08976902 | |||
| b3ac7784ca | |||
| b271e43df4 | |||
| 3dff682ceb | |||
| 8d05c3a204 | |||
| 887825d254 | |||
| 8061e07a00 | |||
| fa1cf24af5 | |||
| 1ab318b6db | |||
| 59493d03fa | |||
| c06504032c | |||
| cf80c7549e | |||
| e6b7e24a36 | |||
| 1b5a415d7a | |||
| 95d9cd0a27 | |||
| cca05de49b | |||
| fa9f23751c | |||
| cf33721ec1 | |||
| 52c72bd45d | |||
| c6e736d64b | |||
| c90d1c0208 | |||
| 5ed0ece058 | |||
| 8684376b98 | |||
| 03cee6582f | |||
| 86291af053 | |||
| 54bb672d9e | |||
| f34bf79884 | |||
| db9ebd5ffd | |||
| 64e384c18a | |||
| 1e325739b1 | |||
| 2bf5d295d4 | |||
| 040d8a210c | |||
| df63bce926 | |||
| b5707d8457 | |||
| cd4ed3679c | |||
| 55b6aadf00 | |||
| 849ecfd6b7 | |||
| ca60e962f0 | |||
| 7bf52e7a75 | |||
| 872caa0407 | |||
| 580a08841f | |||
| ff6442e588 | |||
| 271846703f | |||
| 298affd460 | |||
| d718c8084a | |||
| 39d35091d6 | |||
| cf9b184c9f | |||
| 4abe5d7b8d | |||
| 54ebad9151 | |||
| 3234d0db2e | |||
| c9b5a1d39b | |||
| fc8d43982b | |||
| c4a47b9e53 | |||
| 34182f3e45 | |||
| 87de22fec4 | |||
| 787010ac34 | |||
| 874a1ab939 | |||
| 95df12c59e | |||
| 25c0938a64 | |||
| 5731b52d3c | |||
| c7d88c1f57 | |||
| 678016e391 | |||
| e14d6f8405 | |||
| 588cbabbc2 | |||
| 7cc49c29f1 | |||
| 21b3d4ad37 | |||
| b6629a38a1 | |||
| a88afaaab3 | |||
| 2acda6e977 | |||
| d1dd9bfdd6 | |||
| 027d819860 | |||
| 7e02cc8566 | |||
| bacc1bf9cd | |||
| 6e7815ce22 | |||
| 0193f84847 | |||
| bb2c967981 | |||
| 8d24a094bf | |||
| cb0dc30c7e | |||
| 190d409992 | |||
| acd7f8308c | |||
| 4af3fa88dd | |||
| e90d2eca1e | |||
| 462f671a76 | |||
| 5d2371dda4 | |||
| 379032a40b | |||
| 65b5146dcb | |||
| 4c53b59e89 | |||
| 9bd5cac675 | |||
| 2e65d0aa03 | |||
| afc74dcf68 | |||
| e7e3d0040a | |||
| 14c174890e | |||
| dd472488b6 | |||
| ec4d00509e | |||
| aa0c789b6e | |||
| 016115faa5 | |||
| f6ade7c612 | |||
| 0bfd154437 | |||
| 9a752121ba | |||
| 3ea707245b | |||
| e31ae3f553 | |||
| c38db38207 | |||
| 6b364e19de | |||
| dae0504f5c | |||
| d53ed4ef7e | |||
| 530f8498a1 | |||
| ef3c903582 | |||
| 8314b91324 | |||
| ccd4752d04 | |||
| 1bfeeacf2f | |||
| bfac95b71e | |||
| b91508af5f | |||
| e51486a796 | |||
| 897af2712f | |||
| ed5b4d121c | |||
| 45a7973553 | |||
| a5f0922ba7 | |||
| 792a7e7bfc | |||
| 8f512eb0bd | |||
| 4936c0c46e | |||
| fe54e220e4 | |||
| 0c5b01b5f0 | |||
| 0024dff048 | |||
| 7c42d4d950 | |||
| dc0fc97cb9 | |||
| 86114a4db1 | |||
| 24ef3ed105 | |||
| be437c3417 | |||
| e2e75407c9 | |||
| b99f77e0de | |||
| 909409ff29 | |||
| 408d7dfd95 | |||
| de1d6fbf4c | |||
| e499f0ee37 | |||
| 0e194466d4 | |||
| 5da21ce346 | |||
| 0b4e365ce9 | |||
| 2ebbe3ae09 | |||
| 2a8a0d1c62 | |||
| a42c8f0aeb | |||
| f083f74825 | |||
| 4e0774e5d8 | |||
| 6582721050 | |||
| 609c9e53ff | |||
| 3a141b62df | |||
| 2865241acd | |||
| c6834707f0 | |||
| ef16db0bcd | |||
| b3b2136579 | |||
| dc2d5f1c6a | |||
| c935031234 | |||
| 0a16aa1b32 | |||
| ec485779ce | |||
| 1a474ec960 | |||
| e6b57d9d11 | |||
| 11fb1932ac | |||
| c224f9c773 | |||
| 86f3503245 | |||
| 7d99fab205 | |||
| d38bc4ff38 | |||
| d04f4109f2 | |||
| 0d53bea851 | |||
| dd2040568d | |||
| 89d8acd8eb | |||
| 3f24fa464d | |||
| 5b99c2ceca | |||
| df8a7e68e1 | |||
| 058031ad29 | |||
| a622057fb4 | |||
| 20ce65210b | |||
| 203edbffea | |||
| 226a3a2596 | |||
| 4f79b64f11 | |||
| 443d15e03b | |||
| 35b2b3f8be | |||
| f4428b9b23 | |||
| 814c29f72b | |||
| 5fd4a788df | |||
| 7f5cc5be23 | |||
| 3d93f5e624 | |||
| 967b408e41 | |||
| a81cfaf9fe | |||
| f971ec030d | |||
| ab11958597 | |||
| 6707783d0a | |||
| 9ec7a76e02 | |||
| 5a6bfc9e60 | |||
| be5f2338f6 | |||
| a880b9b20d | |||
| fedcf1bafd | |||
| c694c81215 | |||
| 5503e7bac0 | |||
| 7c7591e167 | |||
| d86aae96ff | |||
| ab1ecc49ed | |||
| 2baeb2e284 | |||
| 2c3df9ba1e | |||
| 4511f834af | |||
| 89653cabe4 | |||
| 4959da0b7e |
@@ -0,0 +1,3 @@
|
|||||||
|
# https://github.com/github-linguist/linguist/blob/master/docs/overrides.md
|
||||||
|
|
||||||
|
home/linux/desktop/i3/conf/polybar/** linguist-vendored
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
patreon: ryan4yin
|
||||||
|
custom: ['https://buymeacoffee.com/ryan4yin', 'https://afdian.net/a/ryan4yin']
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
name: Nix Flake Check
|
||||||
|
|
||||||
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
checks:
|
||||||
|
name: Check expressions
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# - name: Checkout repository
|
||||||
|
# uses: actions/checkout@v4
|
||||||
|
# - name: Install nix
|
||||||
|
# uses: cachix/install-nix-action@v24
|
||||||
|
# with:
|
||||||
|
# install_url: https://nixos.org/nix/install
|
||||||
|
# extra_nix_config: |
|
||||||
|
# access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
|
# experimental-features = nix-command flakes
|
||||||
|
|
||||||
|
- name: Run Nix Flake Check
|
||||||
|
run: |
|
||||||
|
echo 'TODO: nix flake check'
|
||||||
|
# nix flake check
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
name: Mirror this repo to Gitee
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
push: {}
|
||||||
|
jobs:
|
||||||
|
mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Mirror repo to Gitee
|
||||||
|
id: mirror-to-gitee
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
INPUT_SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY_GITEE_MIRROR }}
|
||||||
|
INPUT_TARGET_REPO_URL: git@gitee.com:ryan_yin/nix-config.git
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "$INPUT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
export GIT_SSH_COMMAND="ssh -v -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no"
|
||||||
|
git remote add mirror "$INPUT_TARGET_REPO_URL"
|
||||||
|
git push --tags --force --prune mirror "refs/remotes/origin/*:refs/heads/*"
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
result
|
||||||
|
result/
|
||||||
|
.direnv/
|
||||||
|
.DS_Store
|
||||||
|
.pre-commit-config.yaml
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
# just is a command runner, Justfile is very similar to Makefile, but simpler.
|
||||||
|
|
||||||
|
# use nushell for shell commands
|
||||||
|
set shell := ["nu", "-c"]
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Nix commands related to the local machine
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
i3 mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
nixos-switch ai-i3 {{mode}}
|
||||||
|
|
||||||
|
hypr mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
nixos-switch ai-hyprland {{mode}}
|
||||||
|
|
||||||
|
|
||||||
|
s-i3 mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
nixos-switch shoukei-i3 {{mode}}
|
||||||
|
|
||||||
|
|
||||||
|
s-hypr mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
nixos-switch shoukei-hyprland {{mode}}
|
||||||
|
|
||||||
|
|
||||||
|
up:
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
# Update specific input
|
||||||
|
# Usage: just upp nixpkgs
|
||||||
|
upp input:
|
||||||
|
nix flake lock --update-input {{input}}
|
||||||
|
|
||||||
|
history:
|
||||||
|
nix profile history --profile /nix/var/nix/profiles/system
|
||||||
|
|
||||||
|
repl:
|
||||||
|
nix repl -f flake:nixpkgs
|
||||||
|
|
||||||
|
clean:
|
||||||
|
# remove all generations older than 7 days
|
||||||
|
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
||||||
|
|
||||||
|
gc:
|
||||||
|
# garbage collect all unused nix store entries
|
||||||
|
sudo nix store gc --debug
|
||||||
|
sudo nix-collect-garbage --delete-old
|
||||||
|
|
||||||
|
gitgc:
|
||||||
|
git reflog expire --expire-unreachable=now --all
|
||||||
|
git gc --prune=now
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Darwin related commands, harmonica is my macbook pro's hostname
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
darwin-set-proxy:
|
||||||
|
sudo python3 scripts/darwin_set_proxy.py
|
||||||
|
sleep 1sec
|
||||||
|
|
||||||
|
darwin-rollback:
|
||||||
|
use utils.nu *; \
|
||||||
|
darwin-rollback
|
||||||
|
|
||||||
|
ha mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
darwin-build "harmonica" {{mode}}; \
|
||||||
|
darwin-switch "harmonica" {{mode}}
|
||||||
|
|
||||||
|
fe mode="default": darwin-set-proxy
|
||||||
|
use utils.nu *; \
|
||||||
|
darwin-build "fern" {{mode}}; \
|
||||||
|
darwin-switch "fern" {{mode}}
|
||||||
|
|
||||||
|
yabai-reload:
|
||||||
|
launchctl kickstart -k "gui/502/org.nixos.yabai";
|
||||||
|
launchctl kickstart -k "gui/502/org.nixos.skhd";
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Homelab - NixOS servers running on bare metal
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
virt:
|
||||||
|
colmena apply --on '@virt-*' --verbose --show-trace
|
||||||
|
|
||||||
|
shoryu:
|
||||||
|
colmena apply --on '@shoryu' --verbose --show-trace
|
||||||
|
|
||||||
|
shushou:
|
||||||
|
colmena apply --on '@shushou' --verbose --show-trace
|
||||||
|
|
||||||
|
youko:
|
||||||
|
colmena apply --on '@youko' --verbose --show-trace
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Homelab - Virtual Machines running on Kubevirt
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
lab:
|
||||||
|
colmena apply --on '@homelab-*' --verbose --show-trace
|
||||||
|
|
||||||
|
aqua:
|
||||||
|
colmena apply --on '@aqua' --verbose --show-trace
|
||||||
|
# some config changes require a restart of the dae service
|
||||||
|
ssh root@aquamarine "sudo systemctl stop dae; sleep 1; sudo systemctl start dae"
|
||||||
|
|
||||||
|
ruby:
|
||||||
|
colmena apply --on '@ruby' --verbose --show-trace
|
||||||
|
|
||||||
|
kana:
|
||||||
|
colmena apply --on '@kana' --verbose --show-trace
|
||||||
|
|
||||||
|
tailscale:
|
||||||
|
colmena apply --on '@tailscale-gw' --verbose --show-trace
|
||||||
|
|
||||||
|
# pve-aqua:
|
||||||
|
# nom build .#aquamarine
|
||||||
|
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-aquamarine.vma.zst
|
||||||
|
#
|
||||||
|
# pve-ruby:
|
||||||
|
# nom build .#ruby
|
||||||
|
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-ruby.vma.zst
|
||||||
|
#
|
||||||
|
# pve-kana:
|
||||||
|
# nom build .#kana
|
||||||
|
# rsync -avz --progress --copy-links result root@gtr5:/var/lib/vz/dump/vzdump-qemu-kana.vma.zst
|
||||||
|
#
|
||||||
|
# pve-tsgw:
|
||||||
|
# nom build .#tailscale-gw
|
||||||
|
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-tailscale-gw.vma.zst
|
||||||
|
#
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Kubernetes related commands
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
k3s:
|
||||||
|
colmena apply --on '@k3s-*' --verbose --show-trace
|
||||||
|
|
||||||
|
master:
|
||||||
|
colmena apply --on '@k3s-prod-1-master-*' --verbose --show-trace
|
||||||
|
|
||||||
|
worker:
|
||||||
|
colmena apply --on '@k3s-prod-1-worker-*' --verbose --show-trace
|
||||||
|
|
||||||
|
# pve-k8s:
|
||||||
|
# nom build .#k3s-prod-1-master-1
|
||||||
|
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-k3s-prod-1-master-1.vma.zst
|
||||||
|
#
|
||||||
|
# nom build .#k3s-prod-1-master-2
|
||||||
|
# rsync -avz --progress --copy-links result root@gtr5:/var/lib/vz/dump/vzdump-qemu-k3s-prod-1-master-2.vma.zst
|
||||||
|
#
|
||||||
|
# nom build .#k3s-prod-1-master-3
|
||||||
|
# rsync -avz --progress --copy-links result root@s500plus:/var/lib/vz/dump/vzdump-qemu-k3s-prod-1-master-3.vma.zst
|
||||||
|
#
|
||||||
|
# nom build .#k3s-prod-1-worker-1
|
||||||
|
# rsync -avz --progress --copy-links result root@gtr5:/var/lib/vz/dump/vzdump-qemu-k3s-prod-1-worker-1.vma.zst
|
||||||
|
#
|
||||||
|
# nom build .#k3s-prod-1-worker-2
|
||||||
|
# rsync -avz --progress --copy-links result root@s500plus:/var/lib/vz/dump/vzdump-qemu-k3s-prod-1-worker-2.vma.zst
|
||||||
|
#
|
||||||
|
# nom build .#k3s-prod-1-worker-3
|
||||||
|
# rsync -avz --progress --copy-links result root@s500plus:/var/lib/vz/dump/vzdump-qemu-k3s-prod-1-worker-3.vma.zst
|
||||||
|
#
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# RISC-V related commands
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
riscv:
|
||||||
|
colmena apply --on '@riscv' --verbose --show-trace
|
||||||
|
|
||||||
|
nozomi:
|
||||||
|
colmena apply --on '@nozomi' --verbose --show-trace
|
||||||
|
|
||||||
|
yukina:
|
||||||
|
colmena apply --on '@yukina' --verbose --show-trace
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Aarch64 related commands
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
aarch:
|
||||||
|
colmena apply --on '@aarch' --verbose --show-trace
|
||||||
|
|
||||||
|
suzu:
|
||||||
|
colmena apply --on '@suzu' --build-on-target --verbose --show-trace
|
||||||
|
|
||||||
|
suzu-local mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
nixos-switch suzu {{mode}}
|
||||||
|
|
||||||
|
rakushun:
|
||||||
|
colmena apply --on '@rakushun' --build-on-target --verbose --show-trace
|
||||||
|
|
||||||
|
rakushun-local mode="default":
|
||||||
|
use utils.nu *; \
|
||||||
|
nixos-switch rakushun {{mode}}
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Misc, other useful commands
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
# format the nix files in this repo
|
||||||
|
nix fmt
|
||||||
|
|
||||||
|
path:
|
||||||
|
$env.PATH | split row ":"
|
||||||
|
|
||||||
|
nvim-test:
|
||||||
|
rm -rf $"($env.HOME)/.config/astronvim/lua/user"
|
||||||
|
rsync -avz --copy-links --chmod=D2755,F744 home/base/desktop/editors/neovim/astronvim_user/ $"($env.HOME)/.config/astronvim/lua/user"
|
||||||
|
|
||||||
|
nvim-clean:
|
||||||
|
rm -rf $"($env.HOME)/.config/astronvim/lua/user"
|
||||||
|
|
||||||
|
# =================================================
|
||||||
|
# Emacs related commands
|
||||||
|
# =================================================
|
||||||
|
|
||||||
|
emacs-plist-path := "~/Library/LaunchAgents/org.nix-community.home.emacs.plist"
|
||||||
|
|
||||||
|
reload-emacs-cmd := if os() == "macos" {
|
||||||
|
"launchctl unload " + emacs-plist-path
|
||||||
|
+ "\n"
|
||||||
|
+ "launchctl load " + emacs-plist-path
|
||||||
|
+ "\n"
|
||||||
|
+ "tail -f ~/Library/Logs/emacs-daemon.stderr.log"
|
||||||
|
} else {
|
||||||
|
"systemctl --user restart emacs.service"
|
||||||
|
+ "\n"
|
||||||
|
+ "systemctl --user status emacs.service"
|
||||||
|
}
|
||||||
|
|
||||||
|
emacs-test:
|
||||||
|
rm -rf $"($env.HOME)/.config/doom"
|
||||||
|
rsync -avz --copy-links --chmod=D2755,F744 home/base/desktop/editors/emacs/doom/ $"($env.HOME)/.config/doom"
|
||||||
|
doom clean
|
||||||
|
doom sync
|
||||||
|
|
||||||
|
emacs-clean:
|
||||||
|
rm -rf $"($env.HOME)/.config/doom/"
|
||||||
|
|
||||||
|
emacs-purge:
|
||||||
|
doom purge
|
||||||
|
doom clean
|
||||||
|
doom sync
|
||||||
|
|
||||||
|
emacs-reload:
|
||||||
|
doom sync
|
||||||
|
{{reload-emacs-cmd}}
|
||||||
|
|
||||||
|
|
||||||
|
# =================================================
|
||||||
|
#
|
||||||
|
# Kubernetes related commands
|
||||||
|
#
|
||||||
|
# =================================================
|
||||||
|
|
||||||
|
|
||||||
|
del-failed:
|
||||||
|
kubectl delete pod --all-namespaces --field-selector="status.phase==Failed"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Ryan Yin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
deploy:
|
|
||||||
sudo nixos-rebuild switch --flake .
|
|
||||||
|
|
||||||
debug:
|
|
||||||
sudo nixos-rebuild switch --flake . --show-trace --verbose
|
|
||||||
|
|
||||||
update:
|
|
||||||
nix flake update
|
|
||||||
|
|
||||||
history:
|
|
||||||
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
|
|
||||||
|
|
||||||
gc:
|
|
||||||
sudo nix-collect-garbage --delete-older-than 14d
|
|
||||||
|
|
||||||
@@ -1,69 +1,236 @@
|
|||||||
# Nix Configuration
|
<h2 align="center">:snowflake: Ryan4Yin's Nix Config :snowflake:</h2>
|
||||||
|
|
||||||
This repository is home to the nix code that builds my systems.
|
<p align="center">
|
||||||
|
<img src="https://raw.githubusercontent.com/catppuccin/catppuccin/main/assets/palette/macchiato.png" width="400" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/ryan4yin/nix-config/stargazers">
|
||||||
|
<img alt="Stargazers" src="https://img.shields.io/github/stars/ryan4yin/nix-config?style=for-the-badge&logo=starship&color=C9CBFF&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||||
|
<a href="https://nixos.org/">
|
||||||
|
<img src="https://img.shields.io/badge/NixOS-23.11-informational.svg?style=for-the-badge&logo=nixos&color=F2CDCD&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||||
|
<a href="https://github.com/ryan4yin/nixos-and-flakes-book">
|
||||||
|
<img src="https://img.shields.io/static/v1?label=Nix Flakes&message=learning&style=for-the-badge&logo=nixos&color=DDB6F2&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
## Screenshots
|
> My configuration is becoming more and more complex, and it may be difficult for beginners to read it.
|
||||||
|
> If you are new to NixOS and want to know how I use NixOS, I would recommend you to take a look at the [ryan4yin/nix-config/releases](https://github.com/ryan4yin/nix-config/releases) first, **checkout to some simpler older versions**, which will be much easier to understand.
|
||||||
|
|
||||||

|
This repository is home to the nix code that builds my systems:
|
||||||
|
|
||||||
## TODO
|
1. NixOS Desktops: NixOS with home-manager, i3, hyprland, agenix, etc.
|
||||||
|
2. macOS Desktops: nix-darwin with home-manager, share the same home-manager configuration with NixOS Desktops.
|
||||||
|
3. NixOS Servers: virtual machines running on Proxmox, with various services, such as kubernetes, homepage, prometheus, grafana, etc.
|
||||||
|
|
||||||
- enable disk encryption to enhance data security
|
See [./hosts](./hosts) for details of each host.
|
||||||
- make fcitx5-rime work in vscode/chrome on wayland
|
|
||||||
|
|
||||||
## Why Nix?
|
## Why NixOS & Flakes?
|
||||||
|
|
||||||
Nix allows for easy to manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works forever. If someone else shares their configuration, anyone can make use of it.
|
Nix allows for easy-to-manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works (almost) forever. If someone else shares their configuration, anyone else can just use it (if you really understand what you're copying/refering now).
|
||||||
|
|
||||||
Want to know Nix in details? Looking for a beginner-friendly tutorial? Check out [NixOS & Nix Flakes - A Guide for Beginners](https://thiscute.world/en/posts/nixos-and-flake-basics/)!
|
As for Flakes, refer to [Introduction to Flakes - NixOS & Nix Flakes Book](https://nixos-and-flakes.thiscute.world/nixos-with-flakes/introduction-to-flakes)
|
||||||
|
|
||||||
|
**Want to know NixOS & Flaks in detail? Looking for a beginner-friendly tutorial or best practices? You don't have to go through the pain I've experienced again! Check out my [NixOS & Nix Flakes Book - 🛠️ ❤️ An unofficial & opinionated :book: for beginners](https://github.com/ryan4yin/nixos-and-flakes-book)!**
|
||||||
|
|
||||||
|
> If you're using macOS, check out [ryan4yin/nix-darwin-kickstarter](https://github.com/ryan4yin/nix-darwin-kickstarter) for a quick start.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
| | NixOS(Wayland) | NixOS(Xorg) |
|
||||||
|
| --------------------------- | :---------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Window Manager** | [Hyprland][Hyprland] | [i3][i3] |
|
||||||
|
| **Terminal Emulator** | [Zellij][Zellij] + [Kitty][Kitty] | [Zellij][Zellij] + [Kitty][Kitty] |
|
||||||
|
| **Bar** | [Waybar][Waybar] | [polybar][polybar] |
|
||||||
|
| **Application Launcher** | [anyrun][anyrun] | [rofi][rofi] |
|
||||||
|
| **Notification Daemon** | [Mako][Mako] | [Dunst][Dunst] |
|
||||||
|
| **Display Manager** | [GDM][GDM] | [GDM][GDM] |
|
||||||
|
| **Color Scheme** | [Catppuccin][Catppuccin] | [Catppuccin][Catppuccin] |
|
||||||
|
| **network management tool** | [NetworkManager][NetworkManager] | [NetworkManager][NetworkManager] |
|
||||||
|
| **Input method framework** | [Fcitx5][Fcitx5] | [Fcitx5][Fcitx5] |
|
||||||
|
| **System resource monitor** | [Btop][Btop] | [Btop][Btop] |
|
||||||
|
| **File Manager** | [Yazi][Yazi] + [thunar][thunar] | [Yazi][Yazi] + [thunar][thunar] |
|
||||||
|
| **Shell** | [Nushell][Nushell] + [Starship][Starship] | [Nushell][Nushell] + [Starship][Starship] |
|
||||||
|
| **Music Player** | [mpd][mpd], [ncmpcpp][ncmpcpp], [mpc][mpc], [Netease-cloud-music-gtk][netease-cloud-music-gtk] | [Netease-cloud-music-gtk][netease-cloud-music-gtk] |
|
||||||
|
| **Media Player** | [mpv][mpv] | [mpv][mpv] |
|
||||||
|
| **Text Editor** | [Neovim][Neovim] + [DoomEmacs][DoomEmacs] | [Neovim][Neovim] + [DoomEmacs][DoomEmacs] |
|
||||||
|
| **Fonts** | [Nerd fonts][Nerd fonts] | [Nerd fonts][Nerd fonts] |
|
||||||
|
| **Image Viewer** | [imv][imv] | [imv][imv] |
|
||||||
|
| **Screenshot Software** | [flameshot][flameshot] + [grim][grim] | [flameshot][flameshot] |
|
||||||
|
| **Screen Recording** | [OBS][OBS] | [OBS][OBS] |
|
||||||
|
| **Filesystem & Encryption** | tmpfs on `/`, [Btrfs][Btrfs] subvolumes on a [LUKS][LUKS] crypted partition for persistent, unlock via passphrase | tmpfs on `/`, [Btrfs][Btrfs] subvolumes on a [LUKS][LUKS] crypted partition for persistent, unlock via passphrase |
|
||||||
|
| **Secure Boot** | [lanzaboote][lanzaboote] | [lanzaboote][lanzaboote] |
|
||||||
|
|
||||||
|
Wallpapers: https://github.com/ryan4yin/wallpapers
|
||||||
|
|
||||||
|
## Hyprland + AstroNvim + DoomEmacs
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## I3 + AstroNvim
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## Neovim
|
||||||
|
|
||||||
|
See [./home/base/desktop/editors/neovim/](./home/base/desktop/editors/neovim/) for details.
|
||||||
|
|
||||||
|
## Emacs
|
||||||
|
|
||||||
|
See [./home/base/desktop/editors/emacs/](./home/base/desktop/editors/emacs/) for details.
|
||||||
|
|
||||||
|
## Secrets Management
|
||||||
|
|
||||||
|
See [./secrets](./secrets) for details.
|
||||||
|
|
||||||
## How to Deploy this Flake?
|
## How to Deploy this Flake?
|
||||||
|
|
||||||
>Note: you should NOT deploy this flake directly on your machine, it contains my hardware information and personal information which is not suitable for you. You may use this repo as a reference to build your own configuration.
|
> :red_circle: **IMPORTANT**: **You should NOT deploy this flake directly on your machine :exclamation: It will not succeed.**
|
||||||
|
> This flake contains my hardware configuration(such as [hardware-configuration.nix](hosts/idols-ai/hardware-configuration.nix), [cifs-mount.nix](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols_ai/cifs-mount.nix), [Nvidia Support](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols-ai/default.nix#L77-L91), etc.) which is not suitable for your hardwares,
|
||||||
|
> and requires my private secrets repository [ryan4yin/nix-secrets](https://github.com/ryan4yin/nix-config/tree/main/secrets) to deploy.
|
||||||
|
> You may use this repo as a reference to build your own configuration.
|
||||||
|
|
||||||
After installed NixOS with `nix-command` & `flake` enabled, you can deploy this flake with the following command:
|
For NixOS:
|
||||||
|
|
||||||
|
> To deploy this flake from NixOS's official ISO image(purest installation method), please refer to [./nixos-installer/](./nixos-installer/)
|
||||||
|
|
||||||
|
> Need to restart the machine when switching between `wayland` and `xorg`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# deploy my test configuration
|
# deploy one of the configuration based on the hostname
|
||||||
sudo nixos-rebuild switch --flake .#nixos-test
|
sudo nixos-rebuild switch --flake .#ai_i3
|
||||||
|
# sudo nixos-rebuild switch --flake .#ai-hyprland
|
||||||
|
|
||||||
|
# deploy via `just`(a command runner with similar syntax to make) & Justfile
|
||||||
|
just i3 # deploy my pc with i3 window manager
|
||||||
|
# just hypr # deploy my pc with hyprland compositor
|
||||||
|
|
||||||
# deploy my PC's configuration
|
# or we can deploy with details
|
||||||
sudo nixos-rebuild switch --flake .#msi-rtx4090
|
just i3 debug
|
||||||
|
# just hypr-debug
|
||||||
# or just deploy with hostname
|
|
||||||
sudo nixos-rebuild switch
|
|
||||||
|
|
||||||
# we can also deploy using make, which is defined in Makefile
|
|
||||||
make deploy
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Install Apps from Flatpak
|
For macOS:
|
||||||
|
|
||||||
We can install apps from flathub, which has a lot of apps that are not supported well in nixpkgs.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Add the Flathub repository
|
# If you are deploying for the first time,
|
||||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
# 1. install nix & homebrew manually.
|
||||||
|
# 2. prepare the deployment environment with essential packages available
|
||||||
|
nix-shell -p just nushell
|
||||||
|
# 3. comment home-manager's code in lib/macosSystem.nix to speed up the first deplyment.
|
||||||
|
# 4. comment out the proxy settings in scripts/darwin_set_proxy.py if the proxy is not ready yet.
|
||||||
|
|
||||||
# install apps from flathub
|
# 4. deploy harmonica's configuration(macOS Intel)
|
||||||
flatpak install netease-cloud-music-gtk
|
just ha
|
||||||
|
|
||||||
# or you can search apps from flathub
|
# deploy fern's configuration(Apple Silicon)
|
||||||
flatpak search <keyword>
|
just fe
|
||||||
# search on website is also supported: https://flathub.org/
|
|
||||||
|
# deploy with details
|
||||||
|
just ha debug
|
||||||
|
# just fe debug
|
||||||
```
|
```
|
||||||
|
|
||||||
## Other Interesting Dotfiles
|
> [What y'all will need when Nix drives you to drink.](https://www.youtube.com/watch?v=Eni9PPPPBpg) (copy from hlissner's dotfiles, it really matches my feelings when I first started using NixOS...)
|
||||||
|
|
||||||
Other configurations from where I learned and copied:
|
## How to create & managage VM from this flake?
|
||||||
|
|
||||||
- [notwidow/hyprland](https://github.com/notwidow/hyprland): hyprland configuration
|
use `aquamarine` as an example, we can create a virtual machine with the following command:
|
||||||
- [notusknot/dotfiles-nix](https://github.com/notusknot/dotfiles-nix)
|
|
||||||
- [xddxdd/nixos-config](https://github.com/xddxdd/nixos-config)
|
```shell
|
||||||
- [bobbbay/dotfiles](https://github.com/bobbbay/dotfiles)
|
# 1. generate a proxmox vma image file
|
||||||
- [gytis-ivaskevicius/nixfiles](https://github.com/gytis-ivaskevicius/nixfiles)
|
nom build .#aquamarine # `nom`(nix-output-monitor) can be replaced by the standard command `nix`
|
||||||
- [fufexan/dotfiles](https://github.com/fufexan/dotfiles)
|
|
||||||
- [davidtwco/veritas](https://github.com/davidtwco/veritas)
|
# 2. upload the genereated image to proxmox server's backup directory `/var/lib/vz/dump`
|
||||||
- [NixOS-CN/NixOS-CN-telegram](https://github.com/NixOS-CN/NixOS-CN-telegram)
|
# please replace the vma file name with the one you generated in step 1.
|
||||||
|
rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-aquamarine.vma.zst
|
||||||
|
|
||||||
|
# 3. the image we uploaded will be listed in proxmox web ui's this page: [storage 'local'] -> [backups], we can restore a vm from it via the web ui now.
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the virtual machine `aquamarine` is created, we can deploy updates to it with the following commands:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 1. add the ssh key to ssh-agent
|
||||||
|
ssh-add /etc/agenix/ssh-key-romantic
|
||||||
|
|
||||||
|
# 2. deploy the configuration to all the remote host with tag `@dist-build`
|
||||||
|
# using the ssh key we added in step 1
|
||||||
|
colmena apply --on '@dist-build' --show-trace
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're not familiar with remote deployment, please read this tutorial first: [Remote Deployment - NixOS & Flakes Book](https://nixos-and-flakes.thiscute.world/best-practices/remote-deployment)
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
Other dotfiles that inspired me:
|
||||||
|
|
||||||
|
- Nix Flakes
|
||||||
|
- [NixOS-CN/NixOS-CN-telegram](https://github.com/NixOS-CN/NixOS-CN-telegram)
|
||||||
|
- [notusknot/dotfiles-nix](https://github.com/notusknot/dotfiles-nix)
|
||||||
|
- [xddxdd/nixos-config](https://github.com/xddxdd/nixos-config)
|
||||||
|
- [bobbbay/dotfiles](https://github.com/bobbbay/dotfiles)
|
||||||
|
- [gytis-ivaskevicius/nixfiles](https://github.com/gytis-ivaskevicius/nixfiles)
|
||||||
|
- [davidtwco/veritas](https://github.com/davidtwco/veritas)
|
||||||
|
- [gvolpe/nix-config](https://github.com/gvolpe/nix-config)
|
||||||
|
- [Ruixi-rebirth/flakes](https://github.com/Ruixi-rebirth/flakes)
|
||||||
|
- [fufexan/dotfiles](https://github.com/fufexan/dotfiles): gtk theme, xdg, git, media, anyrun, etc.
|
||||||
|
- [nix-community/srvos](https://github.com/nix-community/srvos): a collection of opinionated and sharable NixOS configurations for servers
|
||||||
|
- Modularized NixOS Configuration
|
||||||
|
- [hlissner/dotfiles](https://github.com/hlissner/dotfiles)
|
||||||
|
- [viperML/dotfiles](https://github.com/viperML/dotfiles)
|
||||||
|
- Hyprland(wayland)
|
||||||
|
- [notwidow/hyprland](https://github.com/notwidow/hyprland): This is where I start my hyprland journey.
|
||||||
|
- [HeinzDev/Hyprland-dotfiles](https://github.com/HeinzDev/Hyprland-dotfiles): Refer to the waybar configuration here.
|
||||||
|
- [linuxmobile/kaku](https://github.com/linuxmobile/kaku)
|
||||||
|
- I3 Window Manager
|
||||||
|
- [endeavouros-i3wm-setup](https://github.com/endeavouros-team/endeavouros-i3wm-setup): I started using i3 here, and my i3 configuration is also based on it, but made a lot of changes.
|
||||||
|
- [denisse-dev/dotfiles](https://github.com/denisse-dev/dotfiles)
|
||||||
|
- Neovim/AstroNvim
|
||||||
|
- [maxbrunet/dotfiles](https://github.com/maxbrunet/dotfiles): astronvim with nix flakes.
|
||||||
|
- Misc
|
||||||
|
- [1amSimp1e/dots](https://github.com/1amSimp1e/dots)
|
||||||
|
|
||||||
|
[Hyprland]: https://github.com/hyprwm/Hyprland
|
||||||
|
[i3]: https://github.com/i3/i3
|
||||||
|
[Kitty]: https://github.com/kovidgoyal/kitty
|
||||||
|
[Nushell]: https://github.com/nushell/nushell
|
||||||
|
[Starship]: https://github.com/starship/starship
|
||||||
|
[Waybar]: https://github.com/Alexays/Waybar
|
||||||
|
[polybar]: https://github.com/polybar/polybar
|
||||||
|
[rofi]: https://github.com/davatorium/rofi
|
||||||
|
[anyrun]: https://github.com/Kirottu/anyrun
|
||||||
|
[Dunst]: https://github.com/dunst-project/dunst
|
||||||
|
[Fcitx5]: https://github.com/fcitx/fcitx5
|
||||||
|
[Btop]: https://github.com/aristocratos/btop
|
||||||
|
[mpv]: https://github.com/mpv-player/mpv
|
||||||
|
[Zellij]: https://github.com/zellij-org/zellij
|
||||||
|
[Neovim]: https://github.com/neovim/neovim
|
||||||
|
[AstroNvim]: https://github.com/AstroNvim/AstroNvim
|
||||||
|
[DoomEmacs]: https://github.com/doomemacs/doomemacs
|
||||||
|
[flameshot]: https://github.com/flameshot-org/flameshot
|
||||||
|
[grim]: https://github.com/emersion/grim
|
||||||
|
[flameshot]: https://github.com/flameshot-org/flameshot
|
||||||
|
[imv]: https://sr.ht/~exec64/imv/
|
||||||
|
[OBS]: https://obsproject.com
|
||||||
|
[Mako]: https://github.com/emersion/mako
|
||||||
|
[Nerd fonts]: https://github.com/ryanoasis/nerd-fonts
|
||||||
|
[catppuccin]: https://github.com/catppuccin/catppuccin
|
||||||
|
[mpd]: https://github.com/MusicPlayerDaemon/MPD
|
||||||
|
[ncmpcpp]: https://github.com/ncmpcpp/ncmpcpp
|
||||||
|
[mpc]: https://github.com/MusicPlayerDaemon/mpc
|
||||||
|
[Netease-cloud-music-gtk]: https://github.com/gmg137/netease-cloud-music-gtk
|
||||||
|
[NetworkManager]: https://wiki.gnome.org/Projects/NetworkManager
|
||||||
|
[wl-clipboard]: https://github.com/bugaevc/wl-clipboard
|
||||||
|
[GDM]: https://wiki.archlinux.org/title/GDM
|
||||||
|
[thunar]: https://gitlab.xfce.org/xfce/thunar
|
||||||
|
[Yazi]: https://github.com/sxyazi/yazi
|
||||||
|
[Catppuccin]: https://github.com/catppuccin/catppuccin
|
||||||
|
[Btrfs]: https://btrfs.readthedocs.io
|
||||||
|
[LUKS]: https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system
|
||||||
|
[lanzaboote]: https://github.com/nix-community/lanzaboote
|
||||||
|
|||||||
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 249 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 450 KiB |
|
After Width: | Height: | Size: 320 KiB |
|
After Width: | Height: | Size: 359 KiB |
|
After Width: | Height: | Size: 382 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 243 KiB |
|
After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 841 KiB |
|
After Width: | Height: | Size: 362 KiB |
|
After Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 336 KiB |
@@ -1,115 +1,166 @@
|
|||||||
{
|
{
|
||||||
description = "NixOS configuration of Ryan Yin";
|
description = "Ryan Yin's nix configuration for both NixOS & macOS";
|
||||||
|
|
||||||
# flake 为了确保够纯,它不依赖系统自身的 /etc/nix/nix.conf,而是在 flake.nix 中通过 nixConfig 设置
|
##################################################################################################################
|
||||||
# 但是为了确保安全性,flake 默认仅允许直接设置少数 nixConfig 参数,其他参数都需要在执行 nix 命令时指定 `--accept-flake-config`,否则会被忽略
|
#
|
||||||
# <https://nixos.org/manual/nix/stable/command-ref/conf-file.html>
|
# Want to know Nix in details? Looking for a beginner-friendly tutorial?
|
||||||
# 如果有些包国内镜像下载不到,它仍然会走国外,这时候就得靠旁路由来解决了。
|
# Check out https://github.com/ryan4yin/nixos-and-flakes-book !
|
||||||
# 临时修改默认网关为旁路由: sudo ip route add default via 192.168.5.201
|
#
|
||||||
# sudo ip route del default via 192.168.5.201
|
##################################################################################################################
|
||||||
|
|
||||||
|
outputs = inputs: import ./outputs inputs;
|
||||||
|
|
||||||
|
# the nixConfig here only affects the flake itself, not the system configuration!
|
||||||
|
# for more information, see:
|
||||||
|
# https://nixos-and-flakes.thiscute.world/nixos-with-flakes/add-custom-cache-servers
|
||||||
nixConfig = {
|
nixConfig = {
|
||||||
experimental-features = [ "nix-command" "flakes" ];
|
# substituers will be appended to the default substituters when fetching packages
|
||||||
substituters = [
|
|
||||||
# replace official cache with a mirror located in China
|
|
||||||
"https://mirrors.bfsu.edu.cn/nix-channels/store"
|
|
||||||
"https://cache.nixos.org/"
|
|
||||||
];
|
|
||||||
|
|
||||||
# nix community's cache server
|
|
||||||
extra-substituters = [
|
extra-substituters = [
|
||||||
"https://nix-community.cachix.org"
|
"https://anyrun.cachix.org"
|
||||||
"https://nixpkgs-wayland.cachix.org"
|
"https://hyprland.cachix.org"
|
||||||
"https://xddxdd.cachix.org"
|
"https://nix-gaming.cachix.org"
|
||||||
|
# "https://nixpkgs-wayland.cachix.org"
|
||||||
];
|
];
|
||||||
extra-trusted-public-keys = [
|
extra-trusted-public-keys = [
|
||||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
"anyrun.cachix.org-1:pqBobmOjI7nKlsUMV25u9QHa9btJK65/C8vnO3p346s="
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||||
"nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
|
"nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
|
||||||
"xddxdd.cachix.org-1:ay1HJyNDYmlSwj5NXQG065C8LfoqqKaTNCyzeixGjf8="
|
# "nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# 这是 flake.nix 的标准格式,inputs 是 flake 的依赖,outputs 是 flake 的输出
|
# This is the standard format for flake.nix. `inputs` are the dependencies of the flake,
|
||||||
# inputs 中的每一项都被拉取、构建后,被作为参数传递给 outputs 函数
|
# Each item in `inputs` will be passed as a parameter to the `outputs` function after being pulled and built.
|
||||||
inputs = {
|
inputs = {
|
||||||
# flake inputs 有很多种引用方式,应用最广泛的是 github 的引用方式
|
# There are many ways to reference flake inputs. The most widely used is github:owner/name/reference,
|
||||||
|
# which represents the GitHub repository URL + branch/commit-id/tag.
|
||||||
|
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; # 使用 nixos-unstable 分支 for nix flakes
|
# Official NixOS package source, using nixos's unstable branch by default
|
||||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-22.11"; # unstable branch may be broken sometimes, use stable branch when necessary
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
# nix users repository
|
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||||
# used to install some packages not in nixpkgs
|
|
||||||
# e.g. wechat-uos/qqmusic/dingtalk
|
|
||||||
nur.url = github:nix-community/NUR;
|
|
||||||
|
|
||||||
home-manager.url = "github:nix-community/home-manager";
|
# for macos
|
||||||
# follows 是 inputs 中的继承语法
|
nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-23.11-darwin";
|
||||||
# 这里使 home-manager 的 nixpkgs 这个 inputs 与当前 flake 的 inputs.nixpkgs 保持一致,避免依赖的 nixpkgs 版本不一致导致问题
|
nix-darwin = {
|
||||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
url = "github:lnl7/nix-darwin";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs-darwin";
|
||||||
# modern window compositor
|
|
||||||
hyprland.url = "github:hyprwm/Hyprland/v0.25.0";
|
|
||||||
# community wayland nixpkgs
|
|
||||||
nixpkgs-wayland.url = "github:nix-community/nixpkgs-wayland";
|
|
||||||
|
|
||||||
# use devenv to manage my development environment
|
|
||||||
devenv.url = "github:cachix/devenv/v0.6.2";
|
|
||||||
|
|
||||||
# secrets management, lock with git commit at 2023/5/15
|
|
||||||
agenix.url = "github:ryantm/agenix/db5637d10f797bb251b94ef9040b237f4702cde3";
|
|
||||||
};
|
|
||||||
|
|
||||||
# outputs 的参数都是 inputs 中定义的依赖项,可以通过它们的名称来引用。
|
|
||||||
# 不过 self 是个例外,这个特殊参数指向 outputs 自身(自引用),以及 flake 根目录
|
|
||||||
# 这里的 @ 语法将函数的参数 attribute set 取了个别名,方便在内部使用
|
|
||||||
outputs = inputs@{
|
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
home-manager,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
nixosConfigurations = {
|
|
||||||
msi-rtx4090 = nixpkgs.lib.nixosSystem {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
|
|
||||||
specialArgs = inputs;
|
|
||||||
modules = [
|
|
||||||
./hosts/msi-rtx4090
|
|
||||||
|
|
||||||
# home-manager 作为 nixos 的一个 module
|
|
||||||
# 这样在 nixos-rebuild switch 时,home-manager 也会被自动部署,不需要额外执行 home-manager switch 命令
|
|
||||||
home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
|
|
||||||
# 使用 home-manager.extraSpecialArgs 自定义传递给 ./home 的参数
|
|
||||||
home-manager.extraSpecialArgs = inputs;
|
|
||||||
home-manager.users.ryan = import ./home;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
nixos-test = nixpkgs.lib.nixosSystem {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
specialArgs = inputs;
|
|
||||||
modules = [
|
|
||||||
./hosts/nixos-test
|
|
||||||
|
|
||||||
# home-manager 作为 nixos 的一个 module
|
|
||||||
# 这样在 nixos-rebuild switch 时,home-manager 也会被自动部署,不需要额外执行 home-manager switch 命令
|
|
||||||
home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
|
|
||||||
# 使用 home-manager.extraSpecialArgs 自定义传递给 ./home 的参数
|
|
||||||
home-manager.extraSpecialArgs = inputs;
|
|
||||||
home-manager.users.ryan = import ./home;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||||
|
|
||||||
|
# home-manager, used for managing user configuration
|
||||||
|
home-manager = {
|
||||||
|
# url = "github:nix-community/home-manager/release-23.11";
|
||||||
|
url = "github:nix-community/home-manager/master";
|
||||||
|
|
||||||
|
# The `follows` keyword in inputs is used for inheritance.
|
||||||
|
# Here, `inputs.nixpkgs` of home-manager is kept consistent with the `inputs.nixpkgs` of the current flake,
|
||||||
|
# to avoid problems caused by different versions of nixpkgs dependencies.
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
lanzaboote = {
|
||||||
|
url = "github:nix-community/lanzaboote/v0.3.0";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
impermanence.url = "github:nix-community/impermanence";
|
||||||
|
|
||||||
|
hyprland = {
|
||||||
|
url = "github:hyprwm/Hyprland/v0.33.1";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
# community wayland nixpkgs
|
||||||
|
# nixpkgs-wayland.url = "github:nix-community/nixpkgs-wayland";
|
||||||
|
# anyrun - a wayland launcher
|
||||||
|
anyrun = {
|
||||||
|
url = "github:Kirottu/anyrun";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
# generate iso/qcow2/docker/... image from nixos configuration
|
||||||
|
nixos-generators = {
|
||||||
|
url = "github:nix-community/nixos-generators";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
# secrets management
|
||||||
|
agenix = {
|
||||||
|
# lock with git commit at 0.15.0
|
||||||
|
url = "github:ryantm/agenix/564595d0ad4be7277e07fa63b5a991b3c645655d";
|
||||||
|
# replaced with a type-safe reimplementation to get a better error message and less bugs.
|
||||||
|
# url = "github:ryan4yin/ragenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
nix-gaming.url = "github:fufexan/nix-gaming";
|
||||||
|
|
||||||
|
disko = {
|
||||||
|
url = "github:nix-community/disko";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
# add git hooks to format nix code before commit
|
||||||
|
pre-commit-hooks = {
|
||||||
|
url = "github:cachix/pre-commit-hooks.nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
nuenv.url = "github:DeterminateSystems/nuenv";
|
||||||
|
|
||||||
|
# daeuniverse.url = "github:daeuniverse/flake.nix/unstable";
|
||||||
|
daeuniverse.url = "github:daeuniverse/flake.nix/exp";
|
||||||
|
|
||||||
|
attic.url = "github:zhaofengli/attic";
|
||||||
|
|
||||||
|
haumea = {
|
||||||
|
url = "github:nix-community/haumea/v0.2.2";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
######################## Some non-flake repositories #########################################
|
||||||
|
|
||||||
|
# AstroNvim is an aesthetic and feature-rich neovim config.
|
||||||
|
astronvim = {
|
||||||
|
url = "github:AstroNvim/AstroNvim/v3.41.2";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
# doom-emacs is a configuration framework for GNU Emacs.
|
||||||
|
doomemacs = {
|
||||||
|
url = "github:doomemacs/doomemacs";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
polybar-themes = {
|
||||||
|
url = "github:adi1090x/polybar-themes";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
######################## My own repositories #########################################
|
||||||
|
|
||||||
|
# my private secrets, it's a private repository, you need to replace it with your own.
|
||||||
|
# use ssh protocol to authenticate via ssh-agent/ssh-key, and shallow clone to save time
|
||||||
|
mysecrets = {
|
||||||
|
url = "git+ssh://git@github.com/ryan4yin/nix-secrets.git?shallow=1";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# my wallpapers
|
||||||
|
wallpapers = {
|
||||||
|
url = "github:ryan4yin/wallpapers";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
nur-ryan4yin = {
|
||||||
|
url = "github:ryan4yin/nur-packages";
|
||||||
|
# inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
# riscv64 SBCs
|
||||||
|
nixos-licheepi4a.url = "github:ryan4yin/nixos-licheepi4a";
|
||||||
|
# nixos-jh7110.url = "github:ryan4yin/nixos-jh7110";
|
||||||
|
|
||||||
|
# aarch64 SBCs
|
||||||
|
nixos-rk3588.url = "github:ryan4yin/nixos-rk3588";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
{ lib, stdenvNoCC, fetchgit }:
|
|
||||||
|
|
||||||
stdenvNoCC.mkDerivation rec {
|
|
||||||
pname = "archcraft-font";
|
|
||||||
version = "2023-05-07";
|
|
||||||
|
|
||||||
src = fetchgit {
|
|
||||||
url = "https://github.com/archcraft-os/archcraft-packages.git";
|
|
||||||
rev = "88030ee6d2df80db958541b53bd3673e081720cf"; # git commit id
|
|
||||||
sparseCheckout = [ "archcraft-fonts/files/icon-fonts/archcraft.ttf" ]; # only fetch the feather.ttf file
|
|
||||||
|
|
||||||
# the sha256 is used to verify the integrity of the downloaded source, and alse cache the build result.
|
|
||||||
# so if you copy other package src's sha256, you will get a cached build result of that package, and all configs in this file will be ignored.
|
|
||||||
# specify sha256 to empty and build it, then an error will indicate the correct sha256
|
|
||||||
sha256 = "sha256-DrGN8lN4Yr1RTyCUZhJjzKgCuC0vTnSWjOKovNg3T/U=";
|
|
||||||
};
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
install -Dm644 archcraft-fonts/files/icon-fonts/archcraft.ttf -t $out/share/fonts/truetype/
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://github.com/archcraft-os/archcraft-packages";
|
|
||||||
description = "Archcraft icon font";
|
|
||||||
version = version;
|
|
||||||
longDescription = ''Archcraft icon font'';
|
|
||||||
license = licenses.mit;
|
|
||||||
maintainers = [ maintainers.ryan4yin ];
|
|
||||||
platforms = platforms.all;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
{ lib, stdenvNoCC, fetchgit }:
|
|
||||||
|
|
||||||
stdenvNoCC.mkDerivation rec {
|
|
||||||
pname = "icomoon-feather-font";
|
|
||||||
version = "2023-05-06";
|
|
||||||
|
|
||||||
# 参考 https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=ttf-icomoon-feather
|
|
||||||
src = fetchgit {
|
|
||||||
url = "https://github.com/adi1090x/polybar-themes.git";
|
|
||||||
rev = "47b66337a92a1afd2240ed7094ffcb039cc686cf"; # git commit id
|
|
||||||
sparseCheckout = [ "fonts/feather.ttf" ]; # only fetch the feather.ttf file
|
|
||||||
|
|
||||||
# the sha256 is used to verify the integrity of the downloaded source, and alse cache the build result.
|
|
||||||
# so if you copy other package src's sha256, you will get a cached build result of that package, and all configs in this file will be ignored.
|
|
||||||
# specify sha256 to empty and build it, then an error will indicate the correct sha256
|
|
||||||
sha256 = "sha256-R+UpUFkXDrxKcX7ljLara+1B1rOMdKGZiLQq1/ojgP4=";
|
|
||||||
};
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
install -Dm644 fonts/feather.ttf -t $out/share/fonts/truetype/
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://github.com/feathericons/feather";
|
|
||||||
description = "Icomoon feather font";
|
|
||||||
version = version;
|
|
||||||
longDescription = ''
|
|
||||||
Feather is a collection of simply beautiful open source icons.
|
|
||||||
Each icon is designed on a 24x24 grid with an emphasis on simplicity, consistency, and flexibility.
|
|
||||||
'';
|
|
||||||
license = licenses.mit;
|
|
||||||
maintainers = [ maintainers.ryan4yin ];
|
|
||||||
platforms = platforms.all;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Home Manager's Submodules
|
||||||
|
|
||||||
|
1. `base`: The base module that is suitable for both Linux and macOS.
|
||||||
|
2. `linux`: Linux-specific configuration.
|
||||||
|
3. `darwin`: macOS-specific configuration.
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Home Manager's Base Submodules
|
||||||
|
|
||||||
|
1. `server`: Configuration which is suitable for both servers and desktops.
|
||||||
|
1. `desktop`: Configuration for desktop environments, such as Hyprland, I3, etc.
|
||||||
|
1. `core.nix`: Minimal home-manager's config
|
||||||
|
|
||||||
@@ -1,21 +1,8 @@
|
|||||||
{ config, pkgs, ... }:
|
{myvars, ...}: {
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
./fcitx5
|
|
||||||
./hyprland
|
|
||||||
# ./i3
|
|
||||||
./programs
|
|
||||||
./rofi
|
|
||||||
./shell
|
|
||||||
];
|
|
||||||
|
|
||||||
# Home Manager needs a bit of information about you and the
|
# Home Manager needs a bit of information about you and the
|
||||||
# paths it should manage.
|
# paths it should manage.
|
||||||
home = {
|
home = {
|
||||||
username = "ryan";
|
inherit (myvars) username;
|
||||||
homeDirectory = "/home/ryan";
|
|
||||||
|
|
||||||
# This value determines the Home Manager release that your
|
# This value determines the Home Manager release that your
|
||||||
# configuration is compatible with. This helps avoid breakage
|
# configuration is compatible with. This helps avoid breakage
|
||||||
@@ -25,7 +12,7 @@
|
|||||||
# You can update Home Manager without changing this value. See
|
# You can update Home Manager without changing this value. See
|
||||||
# the Home Manager release notes for a list of state version
|
# the Home Manager release notes for a list of state version
|
||||||
# changes in each release.
|
# changes in each release.
|
||||||
stateVersion = "22.11";
|
stateVersion = "23.11";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
# Let Home Manager install and manage itself.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
home.packages = with pkgs;
|
||||||
|
[
|
||||||
|
# infrastructure as code
|
||||||
|
# pulumi
|
||||||
|
# pulumictl
|
||||||
|
# tf2pulumi
|
||||||
|
# crd2pulumi
|
||||||
|
# pulumiPackages.pulumi-random
|
||||||
|
# pulumiPackages.pulumi-command
|
||||||
|
# pulumiPackages.pulumi-aws-native
|
||||||
|
# pulumiPackages.pulumi-language-go
|
||||||
|
# pulumiPackages.pulumi-language-python
|
||||||
|
# pulumiPackages.pulumi-language-nodejs
|
||||||
|
|
||||||
|
# aws
|
||||||
|
awscli2
|
||||||
|
ssm-session-manager-plugin # Amazon SSM Session Manager Plugin
|
||||||
|
aws-iam-authenticator
|
||||||
|
eksctl
|
||||||
|
|
||||||
|
# aliyun
|
||||||
|
aliyun-cli
|
||||||
|
]
|
||||||
|
++ (
|
||||||
|
lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
# cloud tools that nix do not have cache for.
|
||||||
|
terraform
|
||||||
|
terraformer # generate terraform configs from existing cloud resources
|
||||||
|
packer # machine image builder
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{mylib, ...}: {
|
||||||
|
imports = mylib.scanPaths ./.;
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
pkgs-unstable,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
#############################################################
|
||||||
|
#
|
||||||
|
# Basic settings for development environment
|
||||||
|
#
|
||||||
|
# Please avoid to install language specific packages here(globally),
|
||||||
|
# instead, install them:
|
||||||
|
# 1. per IDE, such as `programs.neovim.extraPackages`
|
||||||
|
# 2. per-project, using https://github.com/the-nix-way/dev-templates
|
||||||
|
#
|
||||||
|
#############################################################
|
||||||
|
|
||||||
|
home.packages = with pkgs;
|
||||||
|
[
|
||||||
|
colmena # nixos's remote deployment tool
|
||||||
|
|
||||||
|
# db related
|
||||||
|
dbeaver
|
||||||
|
mycli
|
||||||
|
pgcli
|
||||||
|
mongosh
|
||||||
|
sqlite
|
||||||
|
|
||||||
|
# embedded development
|
||||||
|
minicom
|
||||||
|
|
||||||
|
# ai related
|
||||||
|
python311Packages.huggingface-hub # huggingface-cli
|
||||||
|
|
||||||
|
# misc
|
||||||
|
pkgs-unstable.devbox
|
||||||
|
bfg-repo-cleaner # remove large files from git history
|
||||||
|
k6 # load testing tool
|
||||||
|
protobuf # protocol buffer compiler
|
||||||
|
|
||||||
|
# solve coding extercises - learn by doing
|
||||||
|
exercism
|
||||||
|
]
|
||||||
|
++ (
|
||||||
|
lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
# Automatically trims your branches whose tracking remote refs are merged or gone
|
||||||
|
# It's really useful when you work on a project for a long time.
|
||||||
|
git-trim
|
||||||
|
|
||||||
|
# need to run `conda-install` before using it
|
||||||
|
# need to run `conda-shell` before using command `conda`
|
||||||
|
# conda is not available for MacOS
|
||||||
|
conda
|
||||||
|
|
||||||
|
mitmproxy # http/https proxy tool
|
||||||
|
insomnia # REST client
|
||||||
|
wireshark # network analyzer
|
||||||
|
ventoy # create bootable usb
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
direnv = {
|
||||||
|
enable = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Editors Glossary
|
||||||
|
|
||||||
|
### LSP - Language Server Protocol
|
||||||
|
|
||||||
|
> https://en.wikipedia.org/wiki/Language_Server_Protocol
|
||||||
|
|
||||||
|
> https://langserver.org/
|
||||||
|
|
||||||
|
The Language Server Protocol (LSP) is an open, JSON-RPC-based protocol for use between source code editors or integrated development environments (IDEs) and servers that provide programming language-specific features like:
|
||||||
|
|
||||||
|
- motions such as go-to-definition, find-references, hover.
|
||||||
|
- **code completion**
|
||||||
|
- **marking of warnings and errors**
|
||||||
|
- **refactoring routines**
|
||||||
|
- syntax highlighting (use Tree-sitter instead)
|
||||||
|
- code formatting (use a dedicated formatter instead)
|
||||||
|
|
||||||
|
The goal of the protocol is to allow programming language support to be implemented and distributed independently of any given editor or IDE.
|
||||||
|
|
||||||
|
LSP was originally developed for Microsoft Visual Studio Code and is now an open standard.
|
||||||
|
In the early 2020s LSP quickly became a "norm" for language intelligence tools providers.
|
||||||
|
|
||||||
|
### Tree-sitter
|
||||||
|
|
||||||
|
> https://tree-sitter.github.io/tree-sitter/
|
||||||
|
|
||||||
|
> https://www.reddit.com/r/neovim/comments/1109wgr/treesitter_vs_lsp_differences_ans_overlap/
|
||||||
|
|
||||||
|
Tree-sitter is a parser generator tool and an **incremental parsing** library. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited.
|
||||||
|
|
||||||
|
It is used by many editors and IDEs to provide:
|
||||||
|
|
||||||
|
- **syntax highlighting**
|
||||||
|
- **indentation**
|
||||||
|
- **creating foldable code regions**
|
||||||
|
- **Incremental selection**
|
||||||
|
- **simple refactoring in a single file**
|
||||||
|
- such as join/split lines, structural editing, cursor motion, etc.
|
||||||
|
|
||||||
|
**Treesitter process each file independently**, and it is not aware of the semantics of your code.
|
||||||
|
For example, it does not know does a function/variable really exist, or what is the type/return-type of a variable. This is where LSP comes in.
|
||||||
|
|
||||||
|
The LSP server parses the code much more deeply and it **not only parses a single file but your whole project**.
|
||||||
|
So, the LSP server will know whether a function/variable does exist with the same type/return-type. If it does not, it will mark it as an error.
|
||||||
|
|
||||||
|
**LSP does understand the code semantically, while Treesitter only cares about correct syntax**.
|
||||||
|
|
||||||
|
#### LSP vs Tree-sitter
|
||||||
|
|
||||||
|
- Tree-sitter: lightweight, fast, but limited knowledge of your code. mainly used for **syntax highlighting, indentation, and folding/refactoring in a single file**.
|
||||||
|
- LSP: heavy and slow on large projects, but it has a deep understanding of your code. mainly used for **code completion, refactoring in the projects, errors/warnings, and other semantic-aware features**.
|
||||||
|
|
||||||
|
### Formatter vs Linter
|
||||||
|
|
||||||
|
Linting is distinct from Formatting because:
|
||||||
|
|
||||||
|
1. **formatting** only restructures how code appears.
|
||||||
|
1. `prettier` is a popular formatter.
|
||||||
|
1. **linting** analyzes how the code runs and detects errors, it may also suggest improvements such as replace `var` with `let` or `const`.
|
||||||
|
|
||||||
|
Formatters and Linters process each file independently, they do not need to know about other files in the project.
|
||||||
|
* [ ]
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
# Editors
|
||||||
|
|
||||||
|
My editors:
|
||||||
|
|
||||||
|
1. Neovim
|
||||||
|
2. Emacs
|
||||||
|
3. Helix
|
||||||
|
|
||||||
|
And `Zellij` for a smooth and stable terminal experience.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
1. Many useful keys are already provided by vim, check vim/neovim's docs before you install a new plugin / reinvent the wheel.
|
||||||
|
1. After using Emacs/Neovim more skillfully, I strongly recommend that you read the official documentation of Neovim/vim:
|
||||||
|
1. <https://vimhelp.org/>: The official vim documentation.
|
||||||
|
1. <https://neovim.io/doc/user/>: Neovim's official user documentation.
|
||||||
|
1. Use Zellij for terminal related operations, and use Neovim/Helix for editing.
|
||||||
|
1. As for Emacs, Use its GUI version & terminal emulator `vterm` for terminal related operations.
|
||||||
|
1. Two powerful file search & jump tools:
|
||||||
|
1. Tree-view plugins are beginner-friendly and intuitive, but they're not very efficient.
|
||||||
|
1. **Search by the file path**: Useful when you're familiar with the project structure, especially on a large project.
|
||||||
|
1. **Search by the content**: Useful when you're familiar with the code.
|
||||||
|
|
||||||
|
## Tutorial
|
||||||
|
|
||||||
|
Type `:tutor`(`:Tutor` in Neovim) to learn the basics usage of vim/neovim.
|
||||||
|
|
||||||
|
## VIM's Cheetsheet
|
||||||
|
|
||||||
|
> Here only record my commonly used keys, to see **a more comprehensive cheetsheet**: <https://vimhelp.org/quickref.txt.html>
|
||||||
|
|
||||||
|
Both Emacs-Evil & Neovim are compatible with vim, sothe key-bindings described here are common in both Emacs-Evil, Neovim & vim.
|
||||||
|
|
||||||
|
### Terminal Related
|
||||||
|
|
||||||
|
I mainly use Zellij for terminal related operations, here is its terminal shortcuts I use frequently now:
|
||||||
|
|
||||||
|
| Action | Zellij's Shortcut |
|
||||||
|
| ------------------------- | ----------------- |
|
||||||
|
| Floating Terminal | `Ctrl + p + w` |
|
||||||
|
| Horizontal Split Terminal | `Ctrl + p + d` |
|
||||||
|
| Vertical Split Terminal | `Ctrl + p + n` |
|
||||||
|
| Execute a command | `!xxx` |
|
||||||
|
|
||||||
|
### File Management
|
||||||
|
|
||||||
|
> <https://neovim.io/doc/user/usr_22.html>
|
||||||
|
|
||||||
|
> <https://vimhelp.org/editing.txt.html>
|
||||||
|
|
||||||
|
| Action | |
|
||||||
|
| ----------------------------------- | ------------------------------------------------ |
|
||||||
|
| Save selected text to a file | `:w filename` (Will show `:'<,'>w filename`) |
|
||||||
|
| Save and close the current buffer | `:wq` |
|
||||||
|
| Save all buffers | `:wa` |
|
||||||
|
| Save and close all buffers | `:wqa` |
|
||||||
|
| Edit a file | `:e filename`(or `:e <TAB>` to show a file list) |
|
||||||
|
| Browse the file list | `:Ex` or `:e .` |
|
||||||
|
| Discard changes and reread the file | `:e!` |
|
||||||
|
|
||||||
|
### Motion
|
||||||
|
|
||||||
|
> https://vimhelp.org/motion.txt.html
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
| --------------------------------------------------- | -------------------------------------------------- |
|
||||||
|
| Move to the start/end of the buffer | `gg`/`G` |
|
||||||
|
| Move the line number 5 | `5gg` / `5G` |
|
||||||
|
| Move left/down/up/right | h/j/k/l or `5h`/`5j`/`5k`/`5l` or `Ctr-n`/`Ctrl-p` |
|
||||||
|
| Move to the matchpairs, default to `()`, `{}`, `[]` | `%` |
|
||||||
|
| Move to the start/end of the line | `0` / `$` |
|
||||||
|
| Move a sentence forward/backward | `(` / `)` |
|
||||||
|
| Move a paragraph forward/backward | `{` / `}` |
|
||||||
|
| Move a section forward/backward | `[[` / `]]` |
|
||||||
|
| Jump to various positions | `'` + some other keys(neovim has prompt) |
|
||||||
|
|
||||||
|
Text Objects:
|
||||||
|
|
||||||
|
- **sentence**: text ending at a '.', '!' or '?' followed by either the end of a line, or by a space or tab.
|
||||||
|
- **paragraph**: text ending at a blank line.
|
||||||
|
- **section**: text starting with a section header and ending at the start of the next section header (or at the end of the file). - The "`]]`" and "`[[`" commands stop at the '`{`' in the first column. This is
|
||||||
|
useful to find the start of a function in a C/Go/Java/... program.
|
||||||
|
|
||||||
|
### Text Manipulation
|
||||||
|
|
||||||
|
Basics:
|
||||||
|
|
||||||
|
| Action | |
|
||||||
|
| --------------------------------------- | -------------------------- |
|
||||||
|
| Delete the current character | `x` |
|
||||||
|
| Paste the copied text | `p` |
|
||||||
|
| Delete the selection | `d` |
|
||||||
|
| Undo the last word | `CTRL-w`(in insert mode) |
|
||||||
|
| Undo the last line | `CTRL-u`(in insert mode) |
|
||||||
|
| Undo the last change | `u` |
|
||||||
|
| Redo the last change | `Ctrl + r` |
|
||||||
|
| Inserts the text of the previous insert | `Ctrl + a` |
|
||||||
|
| Repeat the last command | `.` |
|
||||||
|
| Toggle text's case | `~` |
|
||||||
|
| Convert to uppercase | `U` (visual mode) |
|
||||||
|
| Convert to lowercase | `u` (visual mode) |
|
||||||
|
| Align the selected conent | `:center`/`:left`/`:right` |
|
||||||
|
|
||||||
|
Misc:
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ----------------------------- | ---------------------------------------- |
|
||||||
|
| Toggle visual mode | `v` (lower case v) |
|
||||||
|
| Select the current line | `V` (upper case v) |
|
||||||
|
| Toggle visual block mode | `<Ctrl> + v` (select a block vertically) |
|
||||||
|
| Fold the current code block | `zc` |
|
||||||
|
| Unfold the current code block | `zo` |
|
||||||
|
| Jump to Definition | `gd` |
|
||||||
|
| Jump to References | `gD` |
|
||||||
|
| (Un)Comment the current line | `gcc` |
|
||||||
|
|
||||||
|
| Action | |
|
||||||
|
| ------------------------------------------------------------------------- | -------------- |
|
||||||
|
| Sort tye selected lines | `:sort` |
|
||||||
|
| Join Selection of Lines With Space | `:join` or `J` |
|
||||||
|
| Join without spaces | `:join!` |
|
||||||
|
| Enter Insert mode at the start/end of the line | `I` / `A` |
|
||||||
|
| Delete from the cursor to the end of the line | `D` |
|
||||||
|
| Delete from the cursor to the end of the line, and then enter insert mode | `C` |
|
||||||
|
|
||||||
|
Advance Techs:
|
||||||
|
|
||||||
|
- Add at the end of multiple lines: `:normal A<text>`
|
||||||
|
|
||||||
|
- Execublock: `:A<text>`
|
||||||
|
- visual block mode(ctrl + v)
|
||||||
|
- Append text at the end of each line in the selected block
|
||||||
|
- If position exceeds line end, neovim adds spaces automatically
|
||||||
|
|
||||||
|
- Delete the last char of multivle lines: `:normal $x`
|
||||||
|
|
||||||
|
- Execute `$x` on each line
|
||||||
|
- visual mode(v)
|
||||||
|
- `$` moves cursor to the end of line
|
||||||
|
- `x` deletes the character under the cursor
|
||||||
|
|
||||||
|
- Delete the last word of multiple lines: `:normal $bD`
|
||||||
|
- Execute `$bD` on each line
|
||||||
|
- visual mode(v)
|
||||||
|
- `$` moves cursor to the end of line
|
||||||
|
- `b` moves cursor to the beginning of the last word
|
||||||
|
|
||||||
|
### Search
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
| ----------------------------------------------------- | --------- |
|
||||||
|
| Search forward/backword for a pattern | `/` / `?` |
|
||||||
|
| Repeat the last search in the same/opposite direction | `n` / `N` |
|
||||||
|
|
||||||
|
### Find and Replace
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
| -------------------------------- | ----------------------------------- |
|
||||||
|
| Replace in selected area | `:s/old/new/g` |
|
||||||
|
| Replace in current line | Same as above |
|
||||||
|
| Replace all the lines | `:% s/old/new/g` |
|
||||||
|
| Replace all the lines with regex | `:% s@\vhttp://(\w+)@https://\1@gc` |
|
||||||
|
|
||||||
|
1. `\v` means means that in the regex pattern after it can be used without backslash escaping(similar to python's raw string).
|
||||||
|
2. `\1` means the first matched group in the pattern.
|
||||||
|
|
||||||
|
### Replace in the specific lines
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
| ----------------------------------------- | -------------------------------------- |
|
||||||
|
| From the 10th line to the end of the file | `:10,$ s/old/new/g` or `:10,$ s@^@#@g` |
|
||||||
|
| From the 10th line to the 20th line | `:10,20 s/old/new/g` |
|
||||||
|
| Remove the trailing spaces | `:% s/\s\+$//g` |
|
||||||
|
|
||||||
|
The postfix(flags) in the above commands:
|
||||||
|
|
||||||
|
1. `g` means replace all the matched strings in the current line/file.
|
||||||
|
2. `c` means ask for confirmation before replacing.
|
||||||
|
3. `i` means ignore case.
|
||||||
|
|
||||||
|
### Buffers, Windows and Tabs
|
||||||
|
|
||||||
|
> <https://neovim.io/doc/user/usr_08.html>
|
||||||
|
|
||||||
|
> <https://vimhelp.org/windows.txt.html>
|
||||||
|
|
||||||
|
- A buffer is the in-memory text of a file.
|
||||||
|
- A window is a viewport on a buffer.
|
||||||
|
- A tab page is a collection of windows.
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
| ----------------------------------- | ----------------------------------- |
|
||||||
|
| Split the window horizontally | `:sp[lit]` or `:sp filename` |
|
||||||
|
| Split the window horizontally | `:vs[plit]` or `:vs filename` |
|
||||||
|
| Switch to the next/previous window | `Ctrl-w + w` or `Ctrl-w + h/j/k/l` |
|
||||||
|
| Show all buffers | `:ls` |
|
||||||
|
| show next/previous buffer | `]b`/`[b` or `:bn[ext]` / `bp[rev]` |
|
||||||
|
| New Tab(New Workspace in DoomEmacs) | `:tabnew` |
|
||||||
|
| Next/Previews Tab | `gt`/`gT` |
|
||||||
|
|
||||||
|
### History
|
||||||
|
|
||||||
|
| Action | Command |
|
||||||
|
| ------------------------ | ------- |
|
||||||
|
| Show the command history | `q:` |
|
||||||
|
| Show the search history | `q/` |
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Structured Editing
|
||||||
|
|
||||||
|
## S-expression data(Lisp)
|
||||||
|
|
||||||
|
- paredit/[lispy](https://github.com/doomemacs/doomemacs/tree/master/modules/editor/lispy): too complex.
|
||||||
|
- [evil-cleverparens](https://github.com/emacs-evil/evil-cleverparens): simple and useful.
|
||||||
|
- [parinfer(par-in-fer)](https://shaunlebron.github.io/parinfer/): morden, simple, elegant and useful, but works not well with some other completion plugins...
|
||||||
|
- to make parinfer works, you should disable sexp & smartparens in any lisp mode.
|
||||||
|
|
||||||
|
Some plugins:
|
||||||
|
|
||||||
|
- Emacs
|
||||||
|
- [parinfer-rusT-mode](https://github.com/justinbarclay/parinfer-rust-mode)
|
||||||
|
- Neovim
|
||||||
|
- [parinfer-rust](https://github.com/eraserhd/parinfer-rust)
|
||||||
|
- <https://github.com/Olical/conjure>
|
||||||
|
- Helix
|
||||||
|
- [parinfer #4090 - Helix](https://github.com/helix-editor/helix/discussions/4090)
|
||||||
|
|
||||||
|
## Other Languages
|
||||||
|
|
||||||
|
1. treesitter
|
||||||
|
1. ...
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{mylib, ...}: {
|
||||||
|
imports = mylib.scanPaths ./.;
|
||||||
|
}
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
# Emacs Editor
|
||||||
|
|
||||||
|
## Why emacs?
|
||||||
|
|
||||||
|
1. Explore the unknown, just for fun!
|
||||||
|
2. Org Mode
|
||||||
|
3. Lisp Coding
|
||||||
|
4. A top-level tutorial for Emacs(Chinese): <https://nyk.ma/tags/emacs/>
|
||||||
|
5. A Beginner's Guide to Emacs(Chinese): <https://github.com/emacs-tw/emacs-101-beginner-survival-guide>
|
||||||
|
|
||||||
|
## Screenshot
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Usefull Links
|
||||||
|
|
||||||
|
- Framework: <https://github.com/doomemacs/doomemacs>
|
||||||
|
- key bindings:
|
||||||
|
- source code: <https://github.com/doomemacs/doomemacs/blob/master/modules/config/default/%2Bevil-bindings.el>
|
||||||
|
- docs: <https://github.com/doomemacs/doomemacs/blob/master/modules/editor/evil/README.org>
|
||||||
|
- module index: <https://github.com/doomemacs/doomemacs/blob/master/docs/modules.org>
|
||||||
|
- LSP Client: <https://github.com/manateelazycat/lsp-bridge>
|
||||||
|
- Emacs Wiki: <https://www.emacswiki.org/emacs/SiteMap>
|
||||||
|
- Awesome Emacs: <https://github.com/emacs-tw/awesome-emacs#lsp-client>
|
||||||
|
- Chinese(rime) support: <https://github.com/DogLooksGood/emacs-rime>
|
||||||
|
- modal editing:
|
||||||
|
- <https://github.com/emacs-evil/evil>: evil mode, enabled by default in doom-emacs.
|
||||||
|
- <https://github.com/meow-edit/meow>
|
||||||
|
|
||||||
|
## Install or Update
|
||||||
|
|
||||||
|
After deploying this nix flake, run the following command to install or update emacs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
doom sync
|
||||||
|
```
|
||||||
|
|
||||||
|
when in doubt, run `doom sync`!
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
> via `Justfile` located at the root of this repo.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# testing
|
||||||
|
just emacs-test
|
||||||
|
jsut emacs-purge
|
||||||
|
just emacs-reload
|
||||||
|
|
||||||
|
# clear test data
|
||||||
|
just emacs-clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Limits
|
||||||
|
|
||||||
|
- It's too slow to start up and install(compile/build) packages.
|
||||||
|
- I have to use emacs in daemon/client mode to avoid this issue.
|
||||||
|
- It's too large in size, not suitable for servers.
|
||||||
|
- So vim/neovim is still the best choice for servers.
|
||||||
|
- Emacs's markdown-mode works not well with tables, see:
|
||||||
|
- https://github.com/jrblevin/markdown-mode/issues/380
|
||||||
|
- I use git command frequently, but doomemacs only autoupdates status of git diff / treemacs when using magit.
|
||||||
|
- I have to learn magit to avoid this issue...
|
||||||
|
- GitHub's orgmode support is not well, Markdown is better for GitHub.
|
||||||
|
- Use markdown for repo's README.md, and use orgmode for my personal notes and docs only.
|
||||||
|
|
||||||
|
## Cheetsheet
|
||||||
|
|
||||||
|
Here is the cheetsheet related to my DoomEmacs configs. Please read vim's common cheetsheet at [../README.md](../README.md) before reading the following.
|
||||||
|
|
||||||
|
### Basics
|
||||||
|
|
||||||
|
> Terminal(vterm) is useful in GUI mode, I use Zellij instead in terminal mode.
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ---------------------- | ------------------------------------------------- |
|
||||||
|
| Popup Terminal(vterm) | `SPC + o + t` |
|
||||||
|
| Open Terminal | `SPC + o + T` |
|
||||||
|
| Open file tree sidebar | `SPC + o + p` |
|
||||||
|
| Frame fullscreen | `SPC + t + F` |
|
||||||
|
| Exit | `M-x C-c` |
|
||||||
|
| Execute Command | `M-x`(hold on `Alt`/`option`, and then press `x`) |
|
||||||
|
| Eval Lisp Code | `M-:`(hold on `Alt`/`option`, and then press `:`) |
|
||||||
|
|
||||||
|
### Window Navigation
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ------------------------------------------ | --------------------------------------------------------------------- |
|
||||||
|
| Split a window vertically and horizontally | `SPC w v/s` |
|
||||||
|
| Move to a window in a specific direction | `Ctrl-w + h/j/k/l` |
|
||||||
|
| Move a window to a specific direction | `Ctrl-w + H/J/K/L` |
|
||||||
|
| Move to the next window | `SPC w w` |
|
||||||
|
| Close the current window | `SPC w q` |
|
||||||
|
| Rebalance all windows | `SPC w =` |
|
||||||
|
| Set window's width(columns) | `80 SPC w \|` (the Vertical line is escaped due to markdown's limits) |
|
||||||
|
| Set window's height | `30 SPC w _ ` |
|
||||||
|
|
||||||
|
### File Tree
|
||||||
|
|
||||||
|
- treemacs: <https://github.com/Alexander-Miller/treemacs/blob/master/src/elisp/treemacs-mode.el>
|
||||||
|
- treemacs-evil: <https://github.com/Alexander-Miller/treemacs/blob/master/src/extra/treemacs-evil.el>
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ------------------------------------- | --------- |
|
||||||
|
| Resize Treemacs's window | `>` & `<` |
|
||||||
|
| Extra Wide Window | `W` |
|
||||||
|
| Rename | `R` |
|
||||||
|
| Delete File/Direcoty | `d` |
|
||||||
|
| New File | `cf` |
|
||||||
|
| New Directory | `cd` |
|
||||||
|
| Go to parent | `u` |
|
||||||
|
| Run shell command in for current node | `!` |
|
||||||
|
| Refresh file tree | `gr` |
|
||||||
|
| Copy project-path into pasteboard | `yp` |
|
||||||
|
| Copy absolute-path into pasteboard | `ya` |
|
||||||
|
| Copy relative-path into pasteboard | `yr` |
|
||||||
|
| Copy file to another location | `yf` |
|
||||||
|
| Move file to another location | `m` |
|
||||||
|
| quit | `q` |
|
||||||
|
|
||||||
|
And bookmarks:
|
||||||
|
|
||||||
|
- Add bookmarks in treemacs: `b`
|
||||||
|
- Show Bookmark List: `SPC s m`
|
||||||
|
|
||||||
|
### Splitting and Buffers
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ----------------------- | ----------------- |
|
||||||
|
| Buffer List | `<Space> + ,` |
|
||||||
|
| Save all buffers(Tab) | `<Space> + b + S` |
|
||||||
|
| Kill the current buffer | `<Space> + b + k` |
|
||||||
|
| Kill all buffers | `<Space> + b + K` |
|
||||||
|
|
||||||
|
### Editing and Formatting
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ------------------------------------------ | ------------------- |
|
||||||
|
| Format Document | `<Space> + cf` |
|
||||||
|
| Code Actions | `<Space> + ca` |
|
||||||
|
| Rename | `<Space> + cr` |
|
||||||
|
| Opening LSP symbols | `<Space> + cS` |
|
||||||
|
| Show all LSP Errors | `<Space> + c + x/X` |
|
||||||
|
| Show infinite undo history(really useful!) | `<Space> + s + u` |
|
||||||
|
| Open filepath/URL at cursor | `gf` |
|
||||||
|
| Find files by keyword in path | `<Space> + <Space>` |
|
||||||
|
| Grep string in files (vertico + ripgrep) | `<Space> + sd` |
|
||||||
|
|
||||||
|
### Image Preview(GUI mode only)
|
||||||
|
|
||||||
|
Use `-`, `+` to resize the image, `r` to rotate the image.
|
||||||
|
|
||||||
|
### Search & replace
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SPC s p foo C-; E C-c C-p :%s/foo/bar/g RET Z Z
|
||||||
|
```
|
||||||
|
|
||||||
|
1. `SPC s p`: search in project
|
||||||
|
1. `foo`: the keyword to search
|
||||||
|
1. `C-; E`: exports what you’re looking at into a new buffer in grep-mode
|
||||||
|
1. `C-c C-p` to run wgrep-change-to-wgrep-mode to make the search results writable.
|
||||||
|
1. `:%s/foo/bar/g RET`: replace in the current buffer(just like neovim/vim)
|
||||||
|
1. `Z Z`: to write all the changes to their respective files
|
||||||
|
|
||||||
|
### Projects
|
||||||
|
|
||||||
|
> easily switch between projects without exit emacs!
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| -------------------------- | ------------- |
|
||||||
|
| Switch between projects | `SPC + p + p` |
|
||||||
|
| Browse the current project | `SPC + p + .` |
|
||||||
|
| Add new project | `SPC + p + a` |
|
||||||
|
|
||||||
|
### Workspaces
|
||||||
|
|
||||||
|
> Very useful when run emacs in daemon/client modes
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| --------------------------- | --------------------------- |
|
||||||
|
| Switch between workspaces | `M-1/2/3/...`(Alt-1/2/3/..) |
|
||||||
|
| New Workspace | `SPC + TAB + n` |
|
||||||
|
| New Named Workspace | `SPC + TAB + N` |
|
||||||
|
| Delete Workspace | `SPC + TAB + d` |
|
||||||
|
| Display Workspaces bar blow | `SPC + TAB + TAB` |
|
||||||
|
|
||||||
|
### Magit
|
||||||
|
|
||||||
|
> https://github.com/magit/magit
|
||||||
|
|
||||||
|
Magit is a powerful tool that make git operations easy and intuitive.
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ------------------------ | ------------------------ |
|
||||||
|
| Open Magit | `C-x g` or `SPC + g + g` |
|
||||||
|
| Switch branch | `SPC + g + b` |
|
||||||
|
| Show buffer's commit log | `SPC + g + L` |
|
||||||
|
|
||||||
|
Shortcuts in magit's pane:
|
||||||
|
|
||||||
|
> When run `git commit` / `git add` / `git push` /... via magit, multiple Arguments can be set.
|
||||||
|
> Set arguments won't trigger a git command immediately. Magit will try to run a git command only after an Action key is pressed.
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| -------------------------------------------------- | --------------------------------------------- |
|
||||||
|
| Quit the current Magit pane | `q` |
|
||||||
|
| Show log | `l` |
|
||||||
|
| Show current branch's log | `l + l` |
|
||||||
|
| Show current reflog | `l + r` |
|
||||||
|
| Commit | `c` |
|
||||||
|
| Stage | `s` |
|
||||||
|
| Unstage | `u` |
|
||||||
|
| Push | `p` |
|
||||||
|
| Pull | `f` |
|
||||||
|
| Rebase | `r` |
|
||||||
|
| Rebase Interactively | `r + i`, select on a commit, then `C-c + C-c` |
|
||||||
|
| Stash | `z` |
|
||||||
|
| Merge | `m` |
|
||||||
|
| Fold/Unfold | `TAB` |
|
||||||
|
| Show details of the current unit(commit/stage/...) | `<ENTER>` |
|
||||||
|
|
||||||
|
KeyBinding full list: <https://github.com/emacs-evil/evil-collection/tree/master/modes/magit#key-bindings>
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
# ==============================================
|
||||||
|
# Based on doomemacs's auther's config:
|
||||||
|
# https://github.com/hlissner/dotfiles/blob/master/modules/editors/emacs.nix
|
||||||
|
#
|
||||||
|
# Emacs Tutorials:
|
||||||
|
# 1. Official: <https://www.gnu.org/software/emacs/tour/index.html>
|
||||||
|
# 2. Doom Emacs: <https://github.com/doomemacs/doomemacs/blob/master/docs/index.org>
|
||||||
|
#
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
doomemacs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.modules.editors.emacs;
|
||||||
|
envExtra = ''
|
||||||
|
export PATH="${config.xdg.configHome}/emacs/bin:$PATH"
|
||||||
|
'';
|
||||||
|
shellAliases = {
|
||||||
|
e = "emacsclient --create-frame"; # gui
|
||||||
|
et = "emacsclient --create-frame --tty"; # termimal
|
||||||
|
};
|
||||||
|
librime-dir = "${config.xdg.dataHome}/emacs/librime";
|
||||||
|
parinfer-rust-lib-dir = "${config.xdg.dataHome}/emacs/parinfer-rust";
|
||||||
|
myEmacsPackagesFor = emacs: ((pkgs.emacsPackagesFor emacs).emacsWithPackages (epkgs: [
|
||||||
|
epkgs.vterm
|
||||||
|
]));
|
||||||
|
in {
|
||||||
|
options.modules.editors.emacs = {
|
||||||
|
enable = mkEnableOption "Emacs Editor";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
## Doom dependencies
|
||||||
|
git
|
||||||
|
(ripgrep.override {withPCRE2 = true;})
|
||||||
|
gnutls # for TLS connectivity
|
||||||
|
|
||||||
|
## Optional dependencies
|
||||||
|
fd # faster projectile indexing
|
||||||
|
imagemagick # for image-dired
|
||||||
|
fd # faster projectile indexing
|
||||||
|
zstd # for undo-fu-session/undo-tree compression
|
||||||
|
|
||||||
|
# go-mode
|
||||||
|
# gocode # project archived, use gopls instead
|
||||||
|
|
||||||
|
## Module dependencies
|
||||||
|
# :checkers spell
|
||||||
|
(aspellWithDicts (ds: with ds; [en en-computers en-science]))
|
||||||
|
# :tools editorconfig
|
||||||
|
editorconfig-core-c # per-project style config
|
||||||
|
# :tools lookup & :lang org +roam
|
||||||
|
sqlite
|
||||||
|
# :lang latex & :lang org (latex previews)
|
||||||
|
texlive.combined.scheme-medium
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.bash.bashrcExtra = envExtra;
|
||||||
|
programs.zsh.envExtra = envExtra;
|
||||||
|
home.shellAliases = shellAliases;
|
||||||
|
programs.nushell.shellAliases = shellAliases;
|
||||||
|
|
||||||
|
xdg.configFile."doom" = {
|
||||||
|
source = ./doom;
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
home.activation.installDoomEmacs = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||||
|
${pkgs.rsync}/bin/rsync -avz --chmod=D2755,F744 ${doomemacs}/ ${config.xdg.configHome}/emacs/
|
||||||
|
|
||||||
|
# librime for emacs-rime
|
||||||
|
mkdir -p ${librime-dir}
|
||||||
|
${pkgs.rsync}/bin/rsync -avz --chmod=D2755,F744 ${pkgs.librime}/ ${librime-dir}/
|
||||||
|
|
||||||
|
# libparinfer_rust for emacs' parinfer-rust-mode
|
||||||
|
mkdir -p ${parinfer-rust-lib-dir}
|
||||||
|
${pkgs.rsync}/bin/rsync -avz --chmod=D2755,F744 ${pkgs.vimPlugins.parinfer-rust}/lib/libparinfer_rust.* ${parinfer-rust-lib-dir}/parinfer-rust.so
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf pkgs.stdenv.isLinux (
|
||||||
|
let
|
||||||
|
# Do not use emacs-nox here, which makes the mouse wheel work abnormally in terminal mode.
|
||||||
|
# pgtk (pure gtk) build add native support for wayland.
|
||||||
|
# https://www.gnu.org/savannah-checkouts/gnu/emacs/emacs.html#Releases
|
||||||
|
emacsPkg = myEmacsPackagesFor pkgs.emacs29-pgtk;
|
||||||
|
in {
|
||||||
|
home.packages = [emacsPkg];
|
||||||
|
services.emacs = {
|
||||||
|
enable = true;
|
||||||
|
package = emacsPkg;
|
||||||
|
client = {
|
||||||
|
enable = true;
|
||||||
|
arguments = [" --create-frame"];
|
||||||
|
};
|
||||||
|
startWithUserSession = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
(mkIf pkgs.stdenv.isDarwin (
|
||||||
|
let
|
||||||
|
# macport adds some native features based on GNU Emacs 29
|
||||||
|
# https://bitbucket.org/mituharu/emacs-mac/src/master/README-mac
|
||||||
|
emacsPkg = myEmacsPackagesFor pkgs.emacs29;
|
||||||
|
in {
|
||||||
|
home.packages = [emacsPkg];
|
||||||
|
launchd.enable = true;
|
||||||
|
launchd.agents.emacs = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
"${pkgs.bash}/bin/bash"
|
||||||
|
"-l"
|
||||||
|
"-c"
|
||||||
|
"${emacsPkg}/bin/emacs --fg-daemon"
|
||||||
|
];
|
||||||
|
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/emacs-daemon.stderr.log";
|
||||||
|
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/emacs-daemon.stdout.log";
|
||||||
|
RunAtLoad = true;
|
||||||
|
KeepAlive = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
))
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Place your private configuration here! Remember, you do not need to run 'doom
|
||||||
|
;; sync' after modifying this file!
|
||||||
|
|
||||||
|
|
||||||
|
;; Some functionality uses this to identify you, e.g. GPG configuration, email
|
||||||
|
;; clients, file templates and snippets. It is optional.
|
||||||
|
;; (setq user-full-name "John Doe"
|
||||||
|
;; user-mail-address "john@doe.com")
|
||||||
|
|
||||||
|
;; Doom exposes five (optional) variables for controlling fonts in Doom:
|
||||||
|
;;
|
||||||
|
;; - `doom-font' -- the primary font to use
|
||||||
|
;; - `doom-variable-pitch-font' -- a non-monospace font (where applicable)
|
||||||
|
;; - `doom-big-font' -- used for `doom-big-font-mode'; use this for
|
||||||
|
;; presentations or streaming.
|
||||||
|
;; - `doom-symbol-font' -- for symbols
|
||||||
|
;; - `doom-serif-font' -- for the `fixed-pitch-serif' face
|
||||||
|
;;
|
||||||
|
;; See 'C-h v doom-font' for documentation and more examples of what they
|
||||||
|
;; accept. For example:
|
||||||
|
;;
|
||||||
|
(setq doom-font (font-spec :family "JetBrainsMono Nerd Font" :size 18)
|
||||||
|
doom-variable-pitch-font (font-spec :family "DejaVu Sans")
|
||||||
|
doom-symbol-font (font-spec :family "Symbols Nerd Font Mono")
|
||||||
|
doom-big-font (font-spec :family "JetBrainsMono Nerd Font" :size 28))
|
||||||
|
|
||||||
|
;; Users should inject their own font logic in `after-setting-font-hook'
|
||||||
|
;; Add font for CJK charset
|
||||||
|
(defun init-cjk-fonts()
|
||||||
|
(dolist (charset '(kana han cjk-misc bopomofo))
|
||||||
|
(set-fontset-font (frame-parameter nil 'font)
|
||||||
|
charset (font-spec :family "Source Han Sans SC"))))
|
||||||
|
(add-hook 'after-setting-font-hook 'init-cjk-fonts)
|
||||||
|
|
||||||
|
|
||||||
|
;; If you or Emacs can't find your font, use 'M-x describe-font' to look them
|
||||||
|
;; up, `M-x eval-region' to execute elisp code, and 'M-x doom/reload-font' to
|
||||||
|
;; refresh your font settings. If Emacs still can't find your font, it likely
|
||||||
|
;; wasn't installed correctly. Font issues are rarely Doom issues!
|
||||||
|
|
||||||
|
;; There are two ways to load a theme. Both assume the theme is installed and
|
||||||
|
;; available. You can either set `doom-theme' or manually load a theme with the
|
||||||
|
;; `load-theme' function. This is the default:
|
||||||
|
;; other doom's official themes:
|
||||||
|
;; https://github.com/doomemacs/themes
|
||||||
|
(setq doom-theme 'doom-dracula) ;; doom-one doom-dracula doom-nord
|
||||||
|
(if (eq system-type 'darwin)
|
||||||
|
;; Transparent Backgroud - for macOS
|
||||||
|
;;(set-frame-parameter (selected-frame) 'alpha '(<active> . <inactive>))
|
||||||
|
;;(set-frame-parameter (selected-frame) 'alpha <both>)
|
||||||
|
(progn
|
||||||
|
(set-frame-parameter (selected-frame) 'alpha '(85 . 70))
|
||||||
|
(add-to-list 'default-frame-alist '(alpha . (85 . 70))))
|
||||||
|
;; Transparent Background - for Linux Xorg/Wayland
|
||||||
|
(set-frame-parameter nil 'alpha-background 93) ; For current frame
|
||||||
|
(add-to-list 'default-frame-alist '(alpha-background . 93))); For all new frames henceforth
|
||||||
|
|
||||||
|
;; This determines the style of line numbers in effect. If set to `nil', line
|
||||||
|
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
||||||
|
(setq display-line-numbers-type t)
|
||||||
|
(setq warning-minimum-level :error)
|
||||||
|
;; If you use `org' and don't want your org files in the default location below,
|
||||||
|
;; change `org-directory'. It must be set before org loads!
|
||||||
|
(setq org-directory "~/org/")
|
||||||
|
;; Whenever you reconfigure a package, make sure to wrap your config in an
|
||||||
|
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
|
||||||
|
;;
|
||||||
|
;; (after! PACKAGE
|
||||||
|
;; (setq x y))
|
||||||
|
;;
|
||||||
|
;; The exceptions to this rule:
|
||||||
|
;;
|
||||||
|
;; - Setting file/directory variables (like `org-directory')
|
||||||
|
;; - Setting variables which explicitly tell you to set them before their
|
||||||
|
;; package is loaded (see 'C-h v VARIABLE' to look up their documentation).
|
||||||
|
;; - Setting doom variables (which start with 'doom-' or '+').
|
||||||
|
;;
|
||||||
|
;; Here are some additional functions/macros that will help you configure Doom.
|
||||||
|
;;
|
||||||
|
;; - `load!' for loading external *.el files relative to this one
|
||||||
|
;; - `use-package!' for configuring packages
|
||||||
|
;; - `after!' for running code after a package has loaded
|
||||||
|
;; - `add-load-path!' for adding directories to the `load-path', relative to
|
||||||
|
;; this file. Emacs searches the `load-path' when you load packages with
|
||||||
|
;; `require' or `use-package'.
|
||||||
|
;; - `map!' for binding new keys
|
||||||
|
;;
|
||||||
|
;; To get information about any of these functions/macros, move the cursor over
|
||||||
|
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
|
||||||
|
;; This will open documentation for it, including demos of how they are used.
|
||||||
|
;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
|
||||||
|
;; etc).
|
||||||
|
;;
|
||||||
|
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
|
||||||
|
;; they are implemented.
|
||||||
|
|
||||||
|
;; use alejandra to format nix files
|
||||||
|
(use-package! lsp-nix
|
||||||
|
:ensure lsp-mode
|
||||||
|
:after
|
||||||
|
(lsp-mode)
|
||||||
|
:demand t
|
||||||
|
:custom
|
||||||
|
(lsp-nix-nil-formatter
|
||||||
|
["alejandra"]))
|
||||||
|
|
||||||
|
(use-package! nushell-mode
|
||||||
|
:config
|
||||||
|
(setq nushell-enable-auto-indent 1))
|
||||||
|
(after! vterm
|
||||||
|
(setq vterm-shell "nu")) ; use nushell by defualt
|
||||||
|
|
||||||
|
;; emacs-rime
|
||||||
|
(use-package! rime
|
||||||
|
:custom
|
||||||
|
(default-input-method "rime")
|
||||||
|
(rime-librime-root "~/.local/share/emacs/librime"))
|
||||||
|
|
||||||
|
;; use parinfer for lisp editing
|
||||||
|
(use-package! parinfer-rust-mode
|
||||||
|
:hook ((emacs-lisp-mode
|
||||||
|
clojure-mode
|
||||||
|
scheme-mode
|
||||||
|
lisp-mode
|
||||||
|
racket-mode
|
||||||
|
fennel-mode
|
||||||
|
hy-mode) . parinfer-rust-mode)
|
||||||
|
:init
|
||||||
|
;; parinfer-rust library do not provide a apple silicon binary.
|
||||||
|
;; fix: https://github.com/doomemacs/doomemacs/issues/6163
|
||||||
|
(setq parinfer-rust-auto-download 0)
|
||||||
|
;; we need to download it manually and put it in this path
|
||||||
|
(setq parinfer-rust-library "~/.local/share/emacs/parinfer-rust/parinfer-rust.so")
|
||||||
|
:config
|
||||||
|
(map! :map parinfer-rust-mode-map
|
||||||
|
:localleader
|
||||||
|
"p" #'parinfer-rust-switch-mode
|
||||||
|
"P" #'parinfer-rust-toggle-disable))
|
||||||
|
|
||||||
|
;; disable smatparens-mode here to void conflict with parinfer
|
||||||
|
;; https://discourse.doomemacs.org/t/disable-smartparens-or-parenthesis-completion/134
|
||||||
|
(add-hook 'clojure-mode-hook #'turn-off-smartparens-mode)
|
||||||
|
(add-hook 'scheme-mode-hook #'turn-off-smartparens-mode)
|
||||||
|
(add-hook 'lisp-mode-hook #'turn-off-smartparens-mode)
|
||||||
|
(add-hook 'racket-mode-hook #'turn-off-smartparens-mode)
|
||||||
|
(add-hook 'fennel-mode-hook #'turn-off-smartparens-mode)
|
||||||
|
(add-hook 'hy-mode-hook #'turn-off-smartparens-mode)
|
||||||
|
|
||||||
|
;; auto-save
|
||||||
|
(use-package super-save
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(super-save-mode +1)
|
||||||
|
(setq super-save-auto-save-when-idle t)
|
||||||
|
(setq auto-save-default nil))
|
||||||
|
|
||||||
|
;; save on find-file
|
||||||
|
(add-to-list 'super-save-hook-triggers 'find-file-hook)
|
||||||
|
|
||||||
|
(use-package! copilot
|
||||||
|
:hook
|
||||||
|
(prog-mode . copilot-mode)
|
||||||
|
:bind
|
||||||
|
(:map copilot-completion-map
|
||||||
|
("<tab>" . 'copilot-accept-completion)
|
||||||
|
("TAB" . 'copilot-accept-completion)
|
||||||
|
("C-TAB" . 'copilot-accept-completion-by-word)
|
||||||
|
("C-<tab>" . 'copilot-accept-completion-by-word))
|
||||||
|
:config
|
||||||
|
(copilot-mode +1))
|
||||||
|
|
||||||
|
(use-package! wakatime-mode :ensure t)
|
||||||
|
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
;;; init.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; This file controls what Doom modules are enabled and what order they load
|
||||||
|
;; in. Remember to run 'doom sync' after modifying it!
|
||||||
|
|
||||||
|
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
|
||||||
|
;; documentation. There you'll find a link to Doom's Module Index where all
|
||||||
|
;; of our modules are listed, including what flags they support.
|
||||||
|
|
||||||
|
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
|
||||||
|
;; 'C-c c k' for non-vim users) to view its documentation. This works on
|
||||||
|
;; flags as well (those symbols that start with a plus).
|
||||||
|
;;
|
||||||
|
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
|
||||||
|
;; directory (for easy access to its source code).
|
||||||
|
|
||||||
|
|
||||||
|
(doom! :input
|
||||||
|
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
|
||||||
|
chinese
|
||||||
|
;;japanese
|
||||||
|
;;layout ; auie,ctsrnm is the superior home row
|
||||||
|
|
||||||
|
:completion
|
||||||
|
;; (company +childframe) ; conflict with lsp-bridge
|
||||||
|
; the ultimate code completion backend
|
||||||
|
;;helm ; the *other* search engine for love and life
|
||||||
|
;;ido ; the other *other* search engine...
|
||||||
|
;;ivy ; a search engine for love and life
|
||||||
|
vertico ; the search engine of the future
|
||||||
|
|
||||||
|
:ui
|
||||||
|
;;deft ; notational velocity for Emacs
|
||||||
|
doom ; what makes DOOM look the way it does
|
||||||
|
doom-dashboard ; a nifty splash screen for Emacs
|
||||||
|
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||||
|
;; (emoji +unicode) ; Emacs 29 provides native support for inserting Unicode emojis.
|
||||||
|
; 🙂
|
||||||
|
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||||||
|
indent-guides ; highlighted indent columns
|
||||||
|
ligatures ; ligatures and symbols to make your code pretty again
|
||||||
|
modeline ; snazzy, Atom-inspired modeline, plus API
|
||||||
|
ophints ; highlight the region an operation acts on
|
||||||
|
(popup +defaults)
|
||||||
|
; tame sudden yet inevitable temporary windows
|
||||||
|
tabs ; a tab bar for Emacs
|
||||||
|
treemacs ; a project drawer, like neotree but cooler
|
||||||
|
unicode ; extended unicode support for various languages
|
||||||
|
(vc-gutter +pretty)
|
||||||
|
; vcs diff in the fringe
|
||||||
|
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||||
|
;;window-select ; visually switch windows
|
||||||
|
workspaces ; tab emulation, persistence & separate workspaces
|
||||||
|
;;zen ; distraction-free coding or writing
|
||||||
|
|
||||||
|
:editor
|
||||||
|
(evil +everywhere)
|
||||||
|
; come to the dark side, we have cookies
|
||||||
|
file-templates ; auto-snippets for empty files
|
||||||
|
fold ; (nigh) universal code folding
|
||||||
|
(format +onsave)
|
||||||
|
; automated prettiness
|
||||||
|
;; multiple-cursors ; editing in many places at once
|
||||||
|
;; objed ; text object editing for the innocent, conflict with parinfer
|
||||||
|
parinfer ; turn lisp into python, sort of, conflict with copilot/objed/smartparens
|
||||||
|
;;rotate-text ; cycle region at point between text candidates
|
||||||
|
snippets ; my elves. They type so I don't have to
|
||||||
|
word-wrap ; soft wrapping with language-aware indent
|
||||||
|
|
||||||
|
:emacs
|
||||||
|
dired ; making dired pretty [functional]
|
||||||
|
electric ; smarter, keyword-based electric-indent
|
||||||
|
ibuffer ; interactive buffer management
|
||||||
|
undo ; persistent, smarter undo for your inevitable mistakes
|
||||||
|
vc ; version-control and Emacs, sitting in a tree
|
||||||
|
|
||||||
|
:term
|
||||||
|
;;eshell ; the elisp shell that works everywhere
|
||||||
|
;;shell ; simple shell REPL for Emacs
|
||||||
|
;;term ; basic terminal emulator for Emacs
|
||||||
|
vterm ; the best terminal emulation in Emacs
|
||||||
|
|
||||||
|
:checkers
|
||||||
|
syntax ; tasing you for every semicolon you forget
|
||||||
|
(spell +flyspell)
|
||||||
|
; tasing you for misspelling mispelling
|
||||||
|
grammar ; tasing grammar mistake every you make
|
||||||
|
|
||||||
|
:tools
|
||||||
|
;;ansible
|
||||||
|
;;biblio ; Writes a PhD for you (citation needed)
|
||||||
|
;;collab ; buffers with friends
|
||||||
|
;;debugger ; FIXME stepping through code, to help you add bugs
|
||||||
|
;;direnv
|
||||||
|
(docker)
|
||||||
|
editorconfig ; let someone else argue about tabs vs spaces
|
||||||
|
;;ein ; tame Jupyter notebooks with emacs
|
||||||
|
(eval +overlay)
|
||||||
|
; run code, run (also, repls)
|
||||||
|
lookup ; navigate your code and its documentation
|
||||||
|
lsp ; lsp-mode, conflict with lsp-bridge
|
||||||
|
magit ; a git porcelain for Emacs
|
||||||
|
;;make ; run make tasks from Emacs
|
||||||
|
;;pass ; password manager for nerds
|
||||||
|
pdf ; pdf enhancements
|
||||||
|
;;prodigy ; FIXME managing external services & code builders
|
||||||
|
(terraform)
|
||||||
|
; infrastructure as code
|
||||||
|
tree-sitter ; syntax and parsing, sitting in a tree...
|
||||||
|
;;upload ; map local to remote projects via ssh/ftp
|
||||||
|
|
||||||
|
:os
|
||||||
|
(:if IS-MAC macos)
|
||||||
|
; improve compatibility with macOS
|
||||||
|
tty ; improve the terminal Emacs experience
|
||||||
|
|
||||||
|
:lang
|
||||||
|
;;agda ; types of types of types of types...
|
||||||
|
;;beancount ; mind the GAAP
|
||||||
|
(cc +lsp +tree-sitter)
|
||||||
|
; C > C++ == 1
|
||||||
|
;;clojure ; java with a lisp
|
||||||
|
;;common-lisp ; if you've seen one lisp, you've seen them all
|
||||||
|
;;coq ; proofs-as-programs
|
||||||
|
;;crystal ; ruby at the speed of c
|
||||||
|
;;csharp ; unity, .NET, and mono shenanigans
|
||||||
|
data ; config/data formats
|
||||||
|
;;(dart +flutter) ; paint ui and not much else
|
||||||
|
;;dhall
|
||||||
|
;;elixir ; erlang done right
|
||||||
|
;;elm ; care for a cup of TEA?
|
||||||
|
emacs-lisp ; drown in parentheses
|
||||||
|
;;erlang ; an elegant language for a more civilized age
|
||||||
|
;;ess ; emacs speaks statistics
|
||||||
|
;;factor
|
||||||
|
;;faust ; dsp, but you get to keep your soul
|
||||||
|
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
|
||||||
|
;;fsharp ; ML stands for Microsoft's Language
|
||||||
|
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||||||
|
;;gdscript ; the language you waited for
|
||||||
|
(go +lsp +tree-sitter) ;; disable go-mode, use lsp-bridge instead
|
||||||
|
; the hipster dialect
|
||||||
|
;;(graphql) ; Give queries a REST
|
||||||
|
;;(haskell) ; a language that's lazier than I am
|
||||||
|
;;hy ; readability of scheme w/ speed of python
|
||||||
|
;;idris ; a language you can depend on
|
||||||
|
(json +lsp +tree-sitter)
|
||||||
|
; At least it ain't XML
|
||||||
|
(java +lsp +tree-sitter)
|
||||||
|
; the poster child for carpal tunnel syndrome
|
||||||
|
(javascript +lsp +tree-sitter)
|
||||||
|
; all(hope(abandon(ye(who(enter(here))))))
|
||||||
|
;;julia ; a better, faster MATLAB
|
||||||
|
;;kotlin ; a better, slicker Java(Script)
|
||||||
|
(latex)
|
||||||
|
; writing papers in Emacs has never been so fun
|
||||||
|
;;lean ; for folks with too much to prove
|
||||||
|
;;ledger ; be audit you can be
|
||||||
|
(lua +lsp +tree-sitter)
|
||||||
|
; one-based indices? one-based indices
|
||||||
|
(markdown +grip)
|
||||||
|
; writing docs for people to ignore
|
||||||
|
;;nim ; python + lisp at the speed of c
|
||||||
|
(nix +lsp +tree-sitter)
|
||||||
|
; I hereby declare "nix geht mehr!"
|
||||||
|
;;ocaml ; an objective camel
|
||||||
|
(org +pandoc +hugo +jupyter) ; organize your plain life in plain text
|
||||||
|
;;php ; perl's insecure younger brother
|
||||||
|
;;plantuml ; diagrams for confusing people more
|
||||||
|
;;purescript ; javascript, but functional
|
||||||
|
(python +lsp +tree-sitter +pyright)
|
||||||
|
; beautiful is better than ugly
|
||||||
|
;;qt ; the 'cutest' gui framework ever
|
||||||
|
racket ; a DSL for DSLs
|
||||||
|
;;raku ; the artist formerly known as perl6
|
||||||
|
;;rest ; Emacs as a REST client
|
||||||
|
;;rst ; ReST in peace
|
||||||
|
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||||
|
(rust +lsp +tree-sitter)
|
||||||
|
; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||||
|
;;scala ; java, but good
|
||||||
|
(scheme +guile)
|
||||||
|
; a fully conniving family of lisps
|
||||||
|
(sh +lsp +tree-sitter)
|
||||||
|
; she sells {ba,z,fi}sh shells on the C xor
|
||||||
|
;;sml
|
||||||
|
;;solidity ; do you need a blockchain? No.
|
||||||
|
;;swift ; who asked for emoji variables?
|
||||||
|
;;terra ; Earth and Moon in alignment for performance.
|
||||||
|
(web +lsp +tree-sitter)
|
||||||
|
; support for various web languages, including HTML5, CSS, SASS/SCSS, Pug/Jade/Slim, and more
|
||||||
|
(yaml +lsp +tree-sitter)
|
||||||
|
; JSON, but readable
|
||||||
|
;;zig ; C, but simpler
|
||||||
|
|
||||||
|
:email
|
||||||
|
;;(mu4e +org +gmail)
|
||||||
|
;;notmuch
|
||||||
|
;;(wanderlust +gmail)
|
||||||
|
|
||||||
|
:app
|
||||||
|
;;calendar
|
||||||
|
;;emms
|
||||||
|
;;everywhere ; *leave* Emacs!? You must be joking
|
||||||
|
;;irc ; how neckbeards socialize
|
||||||
|
;;(rss +org) ; emacs as an RSS reader
|
||||||
|
;;twitter ; twitter client https://twitter.com/vnought
|
||||||
|
|
||||||
|
:config
|
||||||
|
;;literate
|
||||||
|
(default +bindings +smartparens))
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
;;; $DOOMDIR/packages.el
|
||||||
|
|
||||||
|
;; To install a package with Doom you must declare them here and run 'doom sync'
|
||||||
|
;; on the command line, then restart Emacs for the changes to take effect -- or
|
||||||
|
;; use 'M-x doom/reload'.
|
||||||
|
|
||||||
|
(package! super-save)
|
||||||
|
(package! rime)
|
||||||
|
(package! wakatime-mode
|
||||||
|
:recipe
|
||||||
|
(:host github :repo "wakatime/wakatime-mode" :files
|
||||||
|
("*.el" "dist")))
|
||||||
|
|
||||||
|
(package! nushell-mode :recipe
|
||||||
|
(:host github :repo "mrkkrp/nushell-mode"))
|
||||||
|
|
||||||
|
(package! copilot
|
||||||
|
:recipe
|
||||||
|
(:host github :repo "copilot-emacs/copilot.el" :files
|
||||||
|
("*.el" "dist")))
|
||||||
|
|
||||||
|
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
|
||||||
|
;; (package! some-package)
|
||||||
|
|
||||||
|
;; To install a package directly from a remote git repo, you must specify a
|
||||||
|
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
|
||||||
|
;; https://github.com/radian-software/straight.el#the-recipe-format
|
||||||
|
;; (package! another-package
|
||||||
|
;; :recipe (:host github :repo "username/repo"))
|
||||||
|
|
||||||
|
;; If the package you are trying to install does not contain a PACKAGENAME.el
|
||||||
|
;; file, or is located in a subdirectory of the repo, you'll need to specify
|
||||||
|
;; `:files' in the `:recipe':
|
||||||
|
;; (package! this-package
|
||||||
|
;; :recipe (:host github :repo "username/repo"
|
||||||
|
;; :files ("some-file.el" "src/lisp/*.el")))
|
||||||
|
|
||||||
|
;; If you'd like to disable a package included with Doom, you can do so here
|
||||||
|
;; with the `:disable' property:
|
||||||
|
;; (package! builtin-package :disable t)
|
||||||
|
|
||||||
|
;; You can override the recipe of a built in package without having to specify
|
||||||
|
;; all the properties for `:recipe'. These will inherit the rest of its recipe
|
||||||
|
;; from Doom or MELPA/ELPA/Emacsmirror:
|
||||||
|
;; (package! builtin-package :recipe (:nonrecursive t))
|
||||||
|
;; (package! builtin-package-2 :recipe (:repo "myfork/package"))
|
||||||
|
|
||||||
|
;; Specify a `:branch' to install a package from a particular branch or tag.
|
||||||
|
;; This is required for some packages whose default branch isn't 'master' (which
|
||||||
|
;; our package manager can't deal with; see radian-software/straight.el#279)
|
||||||
|
;; (package! builtin-package :recipe (:branch "develop"))
|
||||||
|
|
||||||
|
;; Use `:pin' to specify a particular commit to install.
|
||||||
|
;; (package! builtin-package :pin "1a2b3c4d5e")
|
||||||
|
|
||||||
|
|
||||||
|
;; Doom's packages are pinned to a specific commit and updated from release to
|
||||||
|
;; release. The `unpin!' macro allows you to unpin single packages...
|
||||||
|
;; (unpin! pinned-package)
|
||||||
|
;; ...or multiple packages
|
||||||
|
;; (unpin! pinned-package another-pinned-package)
|
||||||
|
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
||||||
|
;; (unpin! t)
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Helix Editor
|
||||||
|
|
||||||
|
Neovim is really powerful, and have a very active community. I use it as my main editor, and I'm very happy with it. I use it for everything, from writing code to writing this document.
|
||||||
|
|
||||||
|
But its configuration is a bit complex, and finding the right plugins, writing configurations, and keeping everything up to date is not easy.
|
||||||
|
|
||||||
|
That's why I'm interested in Helix, Helix is similar to Neovim, but it's more opinionated, and it's batteries included.
|
||||||
|
Whether I'll switch my main editor to Helix or not, it gives me a lot of ideas on how to improve my Neovim workflow.
|
||||||
|
|
||||||
|
## Tutorial
|
||||||
|
|
||||||
|
Use `:tutor` in helix to start the tutorial.
|
||||||
|
|
||||||
|
## Differences between Neovim and Helixer
|
||||||
|
|
||||||
|
1. Selecting first, then action.
|
||||||
|
1. Helix: delete 2 word: `2w` then `x`. You can always see what you're selecting before you apply the action.
|
||||||
|
2. Neovim: delete 2 word: `d`. then `2w`. No visual feedback before you apply the action.
|
||||||
|
1. Helix - Morden builtin features: LSP, tree-sitter, fuzzy finder, multi cursors, surround and more.
|
||||||
|
1. They're all available in Neovim too, but you need to find and use the right plugins manually, which takes time and effort.
|
||||||
|
1. Helix is built in Rust from scratch. The result is a much smaller codebase and a modern set of defaults. No VimScript. No Lua.
|
||||||
|
1. Neovim contains a lot of VimScript, and lua is too dynamic, it's hard to debug.
|
||||||
|
1. Personally I'm glad to take a look at a Rust codebase, but not a VimScript/Lua codebase.
|
||||||
|
1. Neovim have a very activate plugin ecosystem, and it's easy to find plugins for almost everything.
|
||||||
|
1. Helix is still new, and it even do have a stable plugin system yet. A PR to add a plugin system is still envolving: <https://github.com/helix-editor/helix/pull/8675>
|
||||||
|
2. Neovim has intergrated terminal, and it's very powerful. It's quite similar to VSCode's intergrated terminal. I use it a lot.
|
||||||
|
1. Helix doesn't have a intergrated terminal yet, as it's complicated to implement. Users are recommended to use tmux/Zellij or Wezterm/Kitty to implement this feature instead.
|
||||||
|
1. <https://github.com/helix-editor/helix/issues/1976#issuecomment-1091074719>
|
||||||
|
1. <https://github.com/helix-editor/helix/pull/4649>
|
||||||
|
1. **My Neovim often gets stuck when I switch to [toggleterm.nvim](https://github.com/akinsho/toggleterm.nvim), this Helix issue made me consider to switch from this Neovim plugin to Zellij**.
|
||||||
|
1. Helix do not have a tree-view panel, it's recommended to use Yazi/ranger/Broot instead, and open Helix in them.
|
||||||
|
1. a tree-view plugin may be added after the plugin system is stable, but no one knows when it will be.
|
||||||
|
2. and some Helix users stated that they don't need a tree-view plugin, Helix's file picker is useful and good enough.
|
||||||
|
1. It seems Helix lacks a global substitution command, you should run it in another window(via wm or Zellij).
|
||||||
|
1. <https://github.com/helix-editor/helix/issues/196>
|
||||||
|
1. Neovim's substitution command allow you to preview the changes before you apply it, and it's very useful. if I switch to Helix, I'll need to find some other tools with similar feature(such as https://github.com/ms-jpq/sad).
|
||||||
|
1. Complexity and Maintenance Costs vs Batteries Included: <https://github.com/helix-editor/helix/discussions/6356>
|
||||||
|
|
||||||
|
|
||||||
|
I think Use Helix/Neovim within a terminal file manager(Yazi/ranger/Broot) and Zellij is a good idea.
|
||||||
|
It's quite different from the workflow I migrated from VSCode/JetBrains before, I'm very interested in it.
|
||||||
|
|
||||||
|
In Neovim I can make the workflow similar to VSCode/JetBrains by using some plugins, but Helix forces me to get out of my comfort zone, and try something new.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
nur-ryan4yin,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# https://github.com/catppuccin/helix
|
||||||
|
xdg.configFile."helix/themes".source = "${nur-ryan4yin.packages.${pkgs.system}.catppuccin-helix}/themes/default";
|
||||||
|
|
||||||
|
programs.helix = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.helix;
|
||||||
|
settings = {
|
||||||
|
theme = "catppuccin_mocha";
|
||||||
|
editor = {
|
||||||
|
line-number = "relative";
|
||||||
|
cursorline = true;
|
||||||
|
color-modes = true;
|
||||||
|
lsp.display-messages = true;
|
||||||
|
cursor-shape = {
|
||||||
|
insert = "bar";
|
||||||
|
normal = "block";
|
||||||
|
select = "underline";
|
||||||
|
};
|
||||||
|
indent-guides.render = true;
|
||||||
|
};
|
||||||
|
keys.normal = {
|
||||||
|
space = {
|
||||||
|
space = "file_picker";
|
||||||
|
w = ":w";
|
||||||
|
q = ":q";
|
||||||
|
};
|
||||||
|
esc = ["collapse_selection" "keep_primary_selection"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
# Neovim Editor
|
||||||
|
|
||||||
|
My Neovim config based on [AstroNvim](https://github.com/AstroNvim/AstroNvim).
|
||||||
|
For more details, visit the [AstroNvim website](https://astronvim.com/).
|
||||||
|
|
||||||
|
This document outlines neovim's configuration structure and various shortcuts/commands for efficient usage.
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## Configuration Structure
|
||||||
|
|
||||||
|
| Description | Standard Location | My Location |
|
||||||
|
| ------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
|
||||||
|
| Neovim's config | `~/.config/nvim` | AstroNvim's github repository, referenced as a flake input in this flake. |
|
||||||
|
| AstroNvim's user configuration | `$XDG_CONFIG_HOME/astronvim/lua/user` | [./astronvim_user/](./astronvim_user/) |
|
||||||
|
| Plugins installation directory (lazy.nvim) | `~/.local/share/nvim/` | The same as standard location, generated and managed by lazy.nvim. |
|
||||||
|
| LSP servers, DAP servers, linters, and formatters | `~/.local/share/nvim/mason/`(by mason.nvim) | [./default.nix](./default.nix), installed by nix. |
|
||||||
|
|
||||||
|
## Update/Clean Plugins
|
||||||
|
|
||||||
|
Note that lazy.nvim will not automatically update plugins, so you need to update them manually.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
:Lazy update
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove all unused plugins:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
:Lazy clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
> via `Justfile` located at the root of this repo.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# testing
|
||||||
|
just nvim-test
|
||||||
|
|
||||||
|
# clear test data
|
||||||
|
just nvim-clear
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cheetsheet
|
||||||
|
|
||||||
|
Here is the cheetsheet related to my Neovim configs. Please read vim's common cheetsheet at [../README.md](../README.md) before reading the following.
|
||||||
|
|
||||||
|
### Incremental Selection
|
||||||
|
|
||||||
|
Provided by nvim-treesitter.
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ----------------- | -------------- |
|
||||||
|
| init selection | `<Ctrl-space>` |
|
||||||
|
| node incremental | `<Ctrl-space>` |
|
||||||
|
| scope incremental | `<Alt-Space>` |
|
||||||
|
| node decremental | `Backspace` |
|
||||||
|
|
||||||
|
### Search and Jump
|
||||||
|
|
||||||
|
Provided by [flash.nvim](https://github.com/folke/flash.nvim), it's a intelligent search and jump plugin.
|
||||||
|
|
||||||
|
1. It enhaces the default search and jump behavior of neovim.(search with prefix `/`)
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ----------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Search | `/`(normal search), `s`(disable all code highlight, only highlight matches) |
|
||||||
|
| Treesitter Search | `yR`,`dR`, `cR`, `vR`, `ctrl+v+R`(arround your matches, all the surrounding Treesitter nodes will be labeled) |
|
||||||
|
| Remote Flash | `yr`, `dr`, `cr`, (arround your matches, all the surrounding Treesitter nodes will be labeled) |
|
||||||
|
|
||||||
|
### Commands & Shortcuts
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ----------------------------- | -------------- |
|
||||||
|
| Open file explorer | `<Space> + e` |
|
||||||
|
| Focus Neotree to current file | `<Space> + o` |
|
||||||
|
| Toggle line wrap | `<Space> + uw` |
|
||||||
|
| Show line diagnostics | `gl` |
|
||||||
|
| Show function/variable info | `K` |
|
||||||
|
| References of a symbol | `gr` |
|
||||||
|
|
||||||
|
### Window Navigation
|
||||||
|
|
||||||
|
- Switch between windows: `<Ctrl> + h/j/k/l`
|
||||||
|
- Resize windows: `<Ctrl> + Up/Down/Left/Right`
|
||||||
|
- Note: On macOS, conflicts with system shortcuts
|
||||||
|
- Disable in System Preferences -> Keyboard -> Shortcuts -> Mission Control
|
||||||
|
|
||||||
|
### Splitting and Buffers
|
||||||
|
|
||||||
|
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| --------------------- | ------------- |
|
||||||
|
| Horizontal Split | `\` |
|
||||||
|
| Vertical Split | `\|` |
|
||||||
|
| Close Buffer | `<Space> + c` |
|
||||||
|
|
||||||
|
### Editing and Formatting
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ----------------------------------------------------- | -------------- |
|
||||||
|
| Toggle buffer auto formatting | `<Space> + uf` |
|
||||||
|
| Format Document | `<Space> + lf` |
|
||||||
|
| Code Actions | `<Space> + la` |
|
||||||
|
| Rename | `<Space> + lr` |
|
||||||
|
| Opening LSP symbols | `<Space> + lS` |
|
||||||
|
| Comment Line(support multiple lines) | `<Space> + /` |
|
||||||
|
| Open filepath/URL at cursor(neovim's builtin command) | `gx` |
|
||||||
|
| Find files by name (fzf) | `<Space> + ff` |
|
||||||
|
| Grep string in files (ripgrep) | `<Space> + fw` |
|
||||||
|
|
||||||
|
### Sessions
|
||||||
|
|
||||||
|
| Action | Shortcut |
|
||||||
|
| ------------------------------ | -------------- |
|
||||||
|
| Save Session | `<Space> + Ss` |
|
||||||
|
| Last Session | `<Space> + Sl` |
|
||||||
|
| Delete Session | `<Space> + Sd` |
|
||||||
|
| Search Session | `<Space> + Sf` |
|
||||||
|
| Load Current Directory Session | `<Space> + S.` |
|
||||||
|
|
||||||
|
### Debugging
|
||||||
|
|
||||||
|
Press `<Space> + D` to view available bindings and options.
|
||||||
|
|
||||||
|
### Search and Replace Globally
|
||||||
|
|
||||||
|
| Description | Shortcut |
|
||||||
|
| ------------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||||
|
| Open spectre.nvim search and replace panel | `<Space> + ss` |
|
||||||
|
|
||||||
|
Search and replace via cli(fd + sad + delta):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fd "\\.nix$" . | sad '<pattern>' '<replacement>' | delta
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Surrounding Characters
|
||||||
|
|
||||||
|
Provided by mini.surround plugin.
|
||||||
|
|
||||||
|
- Prefix `gz`
|
||||||
|
|
||||||
|
| Action | Shortcut | Description |
|
||||||
|
| ------------------------------ | -------- | ----------------------------------------------- |
|
||||||
|
| Add surrounding characters | `gzaiw'` | Add `'` around the word under cursor |
|
||||||
|
| Delete surrounding characters | `gzd'` | Delete `'` around the word under cursor |
|
||||||
|
| Replace surrounding characters | `gzr'"` | Replace `'` by `"` around the word under cursor |
|
||||||
|
| Highlight surrounding | `gzh'` | Highlight `'` around the word under cursor |
|
||||||
|
|
||||||
|
### Text Manipulation
|
||||||
|
|
||||||
|
| Action | |
|
||||||
|
| -------------------------------------- | ------------- |
|
||||||
|
| Join with LSP intelligence(treesj) | `<Space> + j` |
|
||||||
|
| Split Line into Multiple Lines(treesj) | `<Space> + s` |
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
|
||||||
|
| Action | |
|
||||||
|
| --------------------- | --------------- |
|
||||||
|
| Show all Yank History | `:<Space> + yh` |
|
||||||
|
| Show undo history | `:<Space> + uh` |
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
For more detailed information and advanced usage, refer to:
|
||||||
|
|
||||||
|
1. [AstroNvim walkthrough](https://astronvim.com/Basic%20Usage/walkthrough)
|
||||||
|
2. [./astronvim_user/mapping.lua](./astronvim_user/mappings.lua)
|
||||||
|
3. All the plugins' documentations
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
.clj-kondo/
|
||||||
|
.nrepl-port
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{:source-file-patterns ["*.fnl" "**/*.fnl"]}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
column_width = 120
|
||||||
|
line_endings = "Unix"
|
||||||
|
indent_type = "Spaces"
|
||||||
|
indent_width = 2
|
||||||
|
quote_style = "AutoPreferDouble"
|
||||||
|
call_parentheses = "None"
|
||||||
|
collapse_simple_statement = "Always"
|
||||||
@@ -0,0 +1,579 @@
|
|||||||
|
return {
|
||||||
|
colorscheme = "catppuccin",
|
||||||
|
|
||||||
|
options = {
|
||||||
|
opt = {
|
||||||
|
relativenumber = true, -- Show relative numberline
|
||||||
|
signcolumn = "auto", -- Show sign column when used only
|
||||||
|
spell = false, -- Spell checking
|
||||||
|
swapfile = false, -- Swapfile
|
||||||
|
smartindent = false, -- fix https://github.com/ryan4yin/nix-config/issues/4
|
||||||
|
title = true, -- Set the title of window to `filename [+=-] (path) - NVIM`
|
||||||
|
-- The percentage of 'columns' to use for the title
|
||||||
|
-- When the title is longer, only the end of the path name is shown.
|
||||||
|
titlelen = 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins = {
|
||||||
|
"AstroNvim/astrocommunity",
|
||||||
|
-- Motion
|
||||||
|
{ import = "astrocommunity.motion.mini-surround" },
|
||||||
|
-- https://github.com/echasnovski/mini.ai
|
||||||
|
{ import = "astrocommunity.motion.mini-ai" },
|
||||||
|
{ import = "astrocommunity.motion.flash-nvim" },
|
||||||
|
-- diable toggleterm.nvim, zellij's terminal is far better than neovim's one
|
||||||
|
{ "akinsho/toggleterm.nvim", enabled = false },
|
||||||
|
{ "folke/flash.nvim", vscode = false },
|
||||||
|
-- Highly experimental plugin that completely replaces
|
||||||
|
-- the UI for messages, cmdline and the popupmenu.
|
||||||
|
-- { import = "astrocommunity.utility.noice-nvim" },
|
||||||
|
-- Fully featured & enhanced replacement for copilot.vim
|
||||||
|
-- <Tab> work with both auto completion in cmp and copilot
|
||||||
|
{ import = "astrocommunity.media.vim-wakatime" },
|
||||||
|
{ import = "astrocommunity.motion.leap-nvim" },
|
||||||
|
{ import = "astrocommunity.motion.flit-nvim" },
|
||||||
|
{ import = "astrocommunity.scrolling.nvim-scrollbar" },
|
||||||
|
{ import = "astrocommunity.editing-support.todo-comments-nvim" },
|
||||||
|
-- Language Support
|
||||||
|
---- Frontend & NodeJS
|
||||||
|
{ import = "astrocommunity.pack.typescript-all-in-one" },
|
||||||
|
{ import = "astrocommunity.pack.tailwindcss" },
|
||||||
|
{ import = "astrocommunity.pack.html-css" },
|
||||||
|
{ import = "astrocommunity.pack.prisma" },
|
||||||
|
{ import = "astrocommunity.pack.vue" },
|
||||||
|
---- Configuration Language
|
||||||
|
{ import = "astrocommunity.pack.markdown" },
|
||||||
|
{ import = "astrocommunity.pack.json" },
|
||||||
|
{ import = "astrocommunity.pack.yaml" },
|
||||||
|
{ import = "astrocommunity.pack.toml" },
|
||||||
|
---- Backend / System
|
||||||
|
{ import = "astrocommunity.pack.lua" },
|
||||||
|
{ import = "astrocommunity.pack.go" },
|
||||||
|
{ import = "astrocommunity.pack.rust" },
|
||||||
|
{ import = "astrocommunity.pack.python" },
|
||||||
|
{ import = "astrocommunity.pack.java" },
|
||||||
|
{ import = "astrocommunity.pack.cmake" },
|
||||||
|
{ import = "astrocommunity.pack.cpp" },
|
||||||
|
-- { import = "astrocommunity.pack.nix" }, -- manually add config for nix, comment this one.
|
||||||
|
{ import = "astrocommunity.pack.proto" },
|
||||||
|
|
||||||
|
---- Operation & Cloud Native
|
||||||
|
{ import = "astrocommunity.pack.terraform" },
|
||||||
|
{ import = "astrocommunity.pack.bash" },
|
||||||
|
{ import = "astrocommunity.pack.docker" },
|
||||||
|
{ import = "astrocommunity.pack.helm" },
|
||||||
|
|
||||||
|
-- colorscheme
|
||||||
|
{ import = "astrocommunity.colorscheme.catppuccin" },
|
||||||
|
{
|
||||||
|
"catppuccin/nvim",
|
||||||
|
name = "catppuccin",
|
||||||
|
opts = function(_, opts)
|
||||||
|
opts.flavour = "mocha" -- latte, frappe, macchiato, mocha
|
||||||
|
opts.transparent_background = true -- setting the background color.
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
-- Language Parser for syntax highlighting / indentation / folding / Incremental selection
|
||||||
|
{
|
||||||
|
"nvim-treesitter/nvim-treesitter",
|
||||||
|
opts = function(_, opts)
|
||||||
|
local utils = require("astronvim.utils")
|
||||||
|
opts.incremental_selection = {
|
||||||
|
enable = true,
|
||||||
|
keymaps = {
|
||||||
|
init_selection = "<C-space>", -- Ctrl + Space
|
||||||
|
node_incremental = "<C-space>",
|
||||||
|
scope_incremental = "<A-space>", -- Alt + Space
|
||||||
|
node_decremental = "<bs>", -- Backspace
|
||||||
|
},
|
||||||
|
}
|
||||||
|
opts.ignore_install = { "gotmpl" }
|
||||||
|
opts.ensure_installed = utils.list_insert_unique(opts.ensure_installed, {
|
||||||
|
-- neovim
|
||||||
|
"vim",
|
||||||
|
"lua",
|
||||||
|
-- operation & cloud native
|
||||||
|
"dockerfile",
|
||||||
|
"hcl",
|
||||||
|
"jsonnet",
|
||||||
|
"regex",
|
||||||
|
"terraform",
|
||||||
|
"nix",
|
||||||
|
"csv",
|
||||||
|
-- other programming language
|
||||||
|
"diff",
|
||||||
|
"gitignore",
|
||||||
|
"gitcommit",
|
||||||
|
"latex",
|
||||||
|
"sql",
|
||||||
|
-- Lisp like
|
||||||
|
"fennel",
|
||||||
|
"clojure",
|
||||||
|
"commonlisp",
|
||||||
|
-- customized languages:
|
||||||
|
"scheme",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- add support for scheme
|
||||||
|
local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
|
||||||
|
parser_config.scheme = {
|
||||||
|
install_info = {
|
||||||
|
url = "https://github.com/6cdh/tree-sitter-scheme", -- local path or git repo
|
||||||
|
files = { "src/parser.c" },
|
||||||
|
-- optional entries:
|
||||||
|
branch = "main", -- default branch in case of git repo if different from master
|
||||||
|
generate_requires_npm = false, -- if stand-alone parser without npm dependencies
|
||||||
|
requires_generate_from_grammar = false, -- if folder contains pre-generated src/parser.c
|
||||||
|
},
|
||||||
|
}
|
||||||
|
-- use scheme parser for filetypes: scm
|
||||||
|
vim.treesitter.language.register("scheme", "scm")
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"eraserhd/parinfer-rust",
|
||||||
|
build = "cargo build --release",
|
||||||
|
ft = { "scm", "scheme" },
|
||||||
|
},
|
||||||
|
{ "Olical/nfnl", ft = "fennel" },
|
||||||
|
{
|
||||||
|
"Olical/conjure",
|
||||||
|
ft = { "clojure", "fennel", "python", "scheme" }, -- etc
|
||||||
|
-- [Optional] cmp-conjure for cmp
|
||||||
|
dependencies = {
|
||||||
|
{
|
||||||
|
"PaterJason/cmp-conjure",
|
||||||
|
config = function()
|
||||||
|
local cmp = require("cmp")
|
||||||
|
local config = cmp.get_config()
|
||||||
|
table.insert(config.sources, {
|
||||||
|
name = "buffer",
|
||||||
|
option = {
|
||||||
|
sources = {
|
||||||
|
{ name = "conjure" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
cmp.setup(config)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config = function(_, opts)
|
||||||
|
require("conjure.main").main()
|
||||||
|
require("conjure.mapping")["on-filetype"]()
|
||||||
|
end,
|
||||||
|
init = function()
|
||||||
|
-- Set configuration options here
|
||||||
|
vim.g["conjure#debug"] = true
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nvim-orgmode/orgmode",
|
||||||
|
dependencies = {
|
||||||
|
{ "nvim-treesitter/nvim-treesitter", lazy = true },
|
||||||
|
},
|
||||||
|
event = "VeryLazy",
|
||||||
|
config = function()
|
||||||
|
-- Load treesitter grammar for org
|
||||||
|
require("orgmode").setup_ts_grammar()
|
||||||
|
|
||||||
|
-- Setup treesitter
|
||||||
|
require("nvim-treesitter.configs").setup({
|
||||||
|
highlight = {
|
||||||
|
enable = true,
|
||||||
|
additional_vim_regex_highlighting = { "org" },
|
||||||
|
},
|
||||||
|
ensure_installed = { "org" },
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Setup orgmode
|
||||||
|
require("orgmode").setup({
|
||||||
|
org_agenda_files = "~/org/**/*",
|
||||||
|
org_default_notes_file = "~/org/refile.org",
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Lua implementation of CamelCaseMotion, with extra consideration of punctuation.
|
||||||
|
{ import = "astrocommunity.motion.nvim-spider" },
|
||||||
|
-- AI Assistant
|
||||||
|
{ import = "astrocommunity.completion.copilot-lua-cmp" },
|
||||||
|
-- Custom copilot-lua to enable filtypes: markdown
|
||||||
|
{
|
||||||
|
"zbirenbaum/copilot.lua",
|
||||||
|
opts = function(_, opts)
|
||||||
|
opts.filetypes = {
|
||||||
|
yaml = true,
|
||||||
|
markdown = true,
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"0x00-ketsu/autosave.nvim",
|
||||||
|
-- lazy-loading on events
|
||||||
|
event = { "InsertLeave", "TextChanged" },
|
||||||
|
opts = function(_, opts)
|
||||||
|
opts.prompt_style = "stdout" -- notify or stdout
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- markdown preview
|
||||||
|
{
|
||||||
|
"0x00-ketsu/markdown-preview.nvim",
|
||||||
|
ft = { "md", "markdown", "mkd", "mkdn", "mdwn", "mdown", "mdtxt", "mdtext", "rmd", "wiki" },
|
||||||
|
config = function()
|
||||||
|
require("markdown-preview").setup({
|
||||||
|
-- your configuration comes here
|
||||||
|
-- or leave it empty to use the default settings
|
||||||
|
-- refer to the setup section below
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- clipboard manager
|
||||||
|
{
|
||||||
|
"gbprod/yanky.nvim",
|
||||||
|
opts = function()
|
||||||
|
local mapping = require("yanky.telescope.mapping")
|
||||||
|
local mappings = mapping.get_defaults()
|
||||||
|
mappings.i["<c-p>"] = nil
|
||||||
|
return {
|
||||||
|
highlight = { timer = 200 },
|
||||||
|
picker = {
|
||||||
|
telescope = {
|
||||||
|
use_default_mappings = false,
|
||||||
|
mappings = mappings,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"y",
|
||||||
|
"<Plug>(YankyYank)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
desc = "Yank text",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"p",
|
||||||
|
"<Plug>(YankyPutAfter)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
desc = "Put yanked text after cursor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P",
|
||||||
|
"<Plug>(YankyPutBefore)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
desc = "Put yanked text before cursor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gp",
|
||||||
|
"<Plug>(YankyGPutAfter)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
desc = "Put yanked text after selection",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gP",
|
||||||
|
"<Plug>(YankyGPutBefore)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
desc = "Put yanked text before selection",
|
||||||
|
},
|
||||||
|
{ "[y", "<Plug>(YankyCycleForward)", desc = "Cycle forward through yank history" },
|
||||||
|
{ "]y", "<Plug>(YankyCycleBackward)", desc = "Cycle backward through yank history" },
|
||||||
|
{ "]p", "<Plug>(YankyPutIndentAfterLinewise)", desc = "Put indented after cursor (linewise)" },
|
||||||
|
{ "[p", "<Plug>(YankyPutIndentBeforeLinewise)", desc = "Put indented before cursor (linewise)" },
|
||||||
|
{ "]P", "<Plug>(YankyPutIndentAfterLinewise)", desc = "Put indented after cursor (linewise)" },
|
||||||
|
{ "[P", "<Plug>(YankyPutIndentBeforeLinewise)", desc = "Put indented before cursor (linewise)" },
|
||||||
|
{ ">p", "<Plug>(YankyPutIndentAfterShiftRight)", desc = "Put and indent right" },
|
||||||
|
{ "<p", "<Plug>(YankyPutIndentAfterShiftLeft)", desc = "Put and indent left" },
|
||||||
|
{ ">P", "<Plug>(YankyPutIndentBeforeShiftRight)", desc = "Put before and indent right" },
|
||||||
|
{ "<P", "<Plug>(YankyPutIndentBeforeShiftLeft)", desc = "Put before and indent left" },
|
||||||
|
{ "=p", "<Plug>(YankyPutAfterFilter)", desc = "Put after applying a filter" },
|
||||||
|
{ "=P", "<Plug>(YankyPutBeforeFilter)", desc = "Put before applying a filter" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Enhanced matchparen.vim plugin for Neovim to highlight the outer pair.
|
||||||
|
{
|
||||||
|
"utilyre/sentiment.nvim",
|
||||||
|
version = "*",
|
||||||
|
event = "VeryLazy", -- keep for lazy loading
|
||||||
|
opts = {
|
||||||
|
-- config
|
||||||
|
},
|
||||||
|
init = function()
|
||||||
|
-- `matchparen.vim` needs to be disabled manually in case of lazy loading
|
||||||
|
vim.g.loaded_matchparen = 1
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- joining blocks of code into oneline, or splitting one line into multiple lines.
|
||||||
|
{
|
||||||
|
"Wansmer/treesj",
|
||||||
|
keys = { "<space>m", "<space>j", "<space>s" },
|
||||||
|
dependencies = { "nvim-treesitter/nvim-treesitter" },
|
||||||
|
config = function()
|
||||||
|
require("treesj").setup({ --[[ your config ]]
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- File explorer(Custom configs)
|
||||||
|
{
|
||||||
|
"nvim-neo-tree/neo-tree.nvim",
|
||||||
|
opts = {
|
||||||
|
filesystem = {
|
||||||
|
filtered_items = {
|
||||||
|
visible = true, -- visible by default
|
||||||
|
hide_dotfiles = false,
|
||||||
|
hide_gitignored = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- The plugin offers the alibity to refactor code.
|
||||||
|
{
|
||||||
|
"ThePrimeagen/refactoring.nvim",
|
||||||
|
dependencies = {
|
||||||
|
{ "nvim-lua/plenary.nvim" },
|
||||||
|
{ "nvim-treesitter/nvim-treesitter" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- The plugin offers the abilibty to search and replace.
|
||||||
|
{
|
||||||
|
"nvim-pack/nvim-spectre",
|
||||||
|
dependencies = {
|
||||||
|
{ "nvim-lua/plenary.nvim" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- full signature help, docs and completion for the nvim lua API.
|
||||||
|
{ "folke/neodev.nvim", opts = {} },
|
||||||
|
-- automatically highlighting other uses of the word under the cursor using either LSP, Tree-sitter, or regex matching.
|
||||||
|
{ "RRethy/vim-illuminate", config = function() end },
|
||||||
|
-- implementation/definition preview
|
||||||
|
{
|
||||||
|
"rmagatti/goto-preview",
|
||||||
|
config = function()
|
||||||
|
require("goto-preview").setup({})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Undo tree
|
||||||
|
{ "debugloop/telescope-undo.nvim" },
|
||||||
|
|
||||||
|
-- Install lsp, formmatter and others via home manager instead of Mason.nvim
|
||||||
|
-- LSP installations
|
||||||
|
{
|
||||||
|
"williamboman/mason-lspconfig.nvim",
|
||||||
|
-- mason is unusable on NixOS, disable it.
|
||||||
|
-- ensure_installed nothing
|
||||||
|
opts = function(_, opts)
|
||||||
|
opts.ensure_installed = nil
|
||||||
|
opts.automatic_installation = false
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
-- Formatters/Linter installation
|
||||||
|
{
|
||||||
|
"jay-babu/mason-null-ls.nvim",
|
||||||
|
-- mason is unusable on NixOS, disable it.
|
||||||
|
-- ensure_installed nothing
|
||||||
|
opts = function(_, opts)
|
||||||
|
opts.ensure_installed = nil
|
||||||
|
opts.automatic_installation = false
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
-- Debugger installation
|
||||||
|
{
|
||||||
|
"jay-babu/mason-nvim-dap.nvim",
|
||||||
|
-- mason is unusable on NixOS, disable it.
|
||||||
|
-- ensure_installed nothing
|
||||||
|
opts = function(_, opts)
|
||||||
|
opts.ensure_installed = nil
|
||||||
|
opts.automatic_installation = false
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"jose-elias-alvarez/null-ls.nvim",
|
||||||
|
opts = function(_, opts)
|
||||||
|
local null_ls = require("null-ls")
|
||||||
|
local code_actions = null_ls.builtins.code_actions
|
||||||
|
local diagnostics = null_ls.builtins.diagnostics
|
||||||
|
local formatting = null_ls.builtins.formatting
|
||||||
|
local hover = null_ls.builtins.hover
|
||||||
|
local completion = null_ls.builtins.completion
|
||||||
|
-- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md
|
||||||
|
if type(opts.sources) == "table" then
|
||||||
|
vim.list_extend(opts.sources, {
|
||||||
|
-- Common Code Actions
|
||||||
|
code_actions.gitsigns,
|
||||||
|
-- common refactoring actions based off the Refactoring book by Martin Fowler
|
||||||
|
code_actions.refactoring,
|
||||||
|
code_actions.gomodifytags, -- Go - modify struct field tags
|
||||||
|
code_actions.impl, -- Go - generate interface method stubs
|
||||||
|
code_actions.shellcheck,
|
||||||
|
code_actions.proselint, -- English prose linter
|
||||||
|
code_actions.statix, -- Lints and suggestions for Nix.
|
||||||
|
|
||||||
|
-- Diagnostic
|
||||||
|
diagnostics.actionlint, -- GitHub Actions workflow syntax checking
|
||||||
|
diagnostics.buf, -- check text in current buffer
|
||||||
|
diagnostics.checkmake, -- check Makefiles
|
||||||
|
diagnostics.deadnix, -- Scan Nix files for dead code.
|
||||||
|
|
||||||
|
-- Formatting
|
||||||
|
formatting.prettier, -- js/ts/vue/css/html/json/... formatter
|
||||||
|
diagnostics.hadolint, -- Dockerfile linter
|
||||||
|
formatting.black, -- Python formatter
|
||||||
|
formatting.ruff, -- extremely fast Python linter
|
||||||
|
formatting.goimports, -- Go formatter
|
||||||
|
formatting.shfmt, -- Shell formatter
|
||||||
|
formatting.rustfmt, -- Rust formatter
|
||||||
|
formatting.taplo, -- TOML formatteautoindentr
|
||||||
|
formatting.terraform_fmt, -- Terraform formatter
|
||||||
|
formatting.stylua, -- Lua formatter
|
||||||
|
formatting.alejandra, -- Nix formatter
|
||||||
|
formatting.sqlfluff.with({ -- SQL formatter
|
||||||
|
extra_args = { "--dialect", "postgres" }, -- change to your dialect
|
||||||
|
}),
|
||||||
|
formatting.nginx_beautifier, -- Nginx formatter
|
||||||
|
formatting.verible_verilog_format, -- Verilog formatter
|
||||||
|
formatting.emacs_scheme_mode, -- using emacs in batch mode to format scheme files.
|
||||||
|
formatting.fnlfmt, -- Format Fennel code
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"nvim-telescope/telescope.nvim",
|
||||||
|
branch = "0.1.x",
|
||||||
|
dependencies = { "nvim-lua/plenary.nvim" },
|
||||||
|
init = function()
|
||||||
|
-- 1. Disable highlighting for certain filetypes
|
||||||
|
-- 2. Ignore files larger than a certain filesize
|
||||||
|
local previewers = require("telescope.previewers")
|
||||||
|
|
||||||
|
local _bad = { ".*%.csv", ".*%.min.js" } -- Put all filetypes that slow you down in this array
|
||||||
|
local filesize_threshold = 300 * 1024 -- 300KB
|
||||||
|
local bad_files = function(filepath)
|
||||||
|
for _, v in ipairs(_bad) do
|
||||||
|
if filepath:match(v) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_maker = function(filepath, bufnr, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
if opts.use_ft_detect == nil then
|
||||||
|
opts.use_ft_detect = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 1. Check if the file is in the bad_files array, and if so, don't highlight it
|
||||||
|
opts.use_ft_detect = opts.use_ft_detect == false and false or bad_files(filepath)
|
||||||
|
|
||||||
|
-- 2. Check the file size, and ignore it if it's too big(preview nothing).
|
||||||
|
filepath = vim.fn.expand(filepath)
|
||||||
|
vim.loop.fs_stat(filepath, function(_, stat)
|
||||||
|
if not stat then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if stat.size > filesize_threshold then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
previewers.buffer_previewer_maker(filepath, bufnr, opts)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
require("telescope").setup({
|
||||||
|
defaults = {
|
||||||
|
buffer_previewer_maker = new_maker,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Configure require("lazy").setup() options
|
||||||
|
lazy = {
|
||||||
|
defaults = { lazy = true },
|
||||||
|
performance = {
|
||||||
|
rtp = {
|
||||||
|
-- customize default disabled vim plugins
|
||||||
|
disabled_plugins = {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
|
||||||
|
lsp = {
|
||||||
|
config = {
|
||||||
|
-- the offset_enconding of clangd will confilicts whit null-ls
|
||||||
|
-- so we need to manually set it to utf-8
|
||||||
|
clangd = {
|
||||||
|
capabilities = {
|
||||||
|
offsetEncoding = "utf-8",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scheme_langserver = {
|
||||||
|
filetypes = { "scheme", "scm" },
|
||||||
|
single_file_support = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- enable servers that installed by home-manager instead of mason
|
||||||
|
servers = {
|
||||||
|
---- Frontend & NodeJS
|
||||||
|
"tsserver", -- typescript/javascript language server
|
||||||
|
"tailwindcss", -- tailwindcss language server
|
||||||
|
"html", -- html language server
|
||||||
|
"cssls", -- css language server
|
||||||
|
"prismals", -- prisma language server
|
||||||
|
"volar", -- vue language server
|
||||||
|
---- Configuration Language
|
||||||
|
"marksman", -- markdown ls
|
||||||
|
"jsonls", -- json language server
|
||||||
|
"yamlls", -- yaml language server
|
||||||
|
"taplo", -- toml language server
|
||||||
|
---- Backend
|
||||||
|
"lua_ls", -- lua
|
||||||
|
"gopls", -- go
|
||||||
|
"rust_analyzer", -- rust
|
||||||
|
"pyright", -- python
|
||||||
|
"ruff_lsp", -- extremely fast Python linter and code transformation
|
||||||
|
"jdtls", -- java
|
||||||
|
"nil_ls", -- nix language server
|
||||||
|
"bufls", -- protocol buffer language server
|
||||||
|
"zls", -- zig language server
|
||||||
|
---- HDL
|
||||||
|
"verible", -- verilog language server
|
||||||
|
---- Operation & Cloud Nativautoindente
|
||||||
|
"bashls", -- bash
|
||||||
|
"cmake", -- cmake language server
|
||||||
|
"clangd", -- c/c++
|
||||||
|
"dockerls", -- dockerfile
|
||||||
|
"jsonnet_ls", -- jsonnet language server
|
||||||
|
"terraformls", -- terraform hcl
|
||||||
|
"nushell", -- nushell language server
|
||||||
|
"scheme_langserver", -- scheme language server
|
||||||
|
},
|
||||||
|
formatting = {
|
||||||
|
disabled = {},
|
||||||
|
format_on_save = {
|
||||||
|
enabled = true,
|
||||||
|
allow_filetypes = {
|
||||||
|
"go",
|
||||||
|
"jsonnet",
|
||||||
|
"rust",
|
||||||
|
"terraform",
|
||||||
|
"nu",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
-- Mapping data with "desc" stored directly by vim.keymap.set().
|
||||||
|
--
|
||||||
|
-- Please use this mappings table to set keyboard mapping since this is the
|
||||||
|
-- lower level configuration and more robust one. (which-key will
|
||||||
|
-- automatically pick-up stored data by this setting.)
|
||||||
|
local utils = require "astronvim.utils"
|
||||||
|
|
||||||
|
require("telescope").load_extension("refactoring")
|
||||||
|
require("telescope").load_extension("yank_history")
|
||||||
|
require("telescope").load_extension("undo")
|
||||||
|
|
||||||
|
return {
|
||||||
|
-- normal mode
|
||||||
|
n = {
|
||||||
|
-- second key is the lefthand side of the map
|
||||||
|
-- mappings seen under group name "Buffer"
|
||||||
|
["<leader>bn"] = { "<cmd>tabnew<cr>", desc = "New tab" },
|
||||||
|
-- quick save
|
||||||
|
["<C-s>"] = { ":w!<cr>", desc = "Save File" }, -- change description but the same command
|
||||||
|
|
||||||
|
-- Terminal
|
||||||
|
-- NOTE: https://neovim.io/doc/user/builtin.html#jobstart()
|
||||||
|
-- 1. If {cmd} is a List it runs directly (no 'shell')
|
||||||
|
-- 2. If {cmd} is a String it runs in the 'shell'
|
||||||
|
-- search and replace globally
|
||||||
|
['<leader>ss'] = {'<cmd>lua require("spectre").toggle()<CR>', desc = "Toggle Spectre" },
|
||||||
|
['<leader>sw'] = {'<cmd>lua require("spectre").open_visual({select_word=true})<CR>', desc = "Search current word" },
|
||||||
|
['<leader>sp'] ={'<cmd>lua require("spectre").open_file_search({select_word=true})<CR>', desc = "Search on current file" },
|
||||||
|
|
||||||
|
-- refactoring
|
||||||
|
["<leader>ri"] = { function() require('refactoring').refactor('Inline Variable') end, desc = "Inverse of extract variable" },
|
||||||
|
["<leader>rb"] = { function() require('refactoring').refactor('Extract Block') end, desc = "Extract Block" },
|
||||||
|
["<leader>rbf"] = { function() require('refactoring').refactor('Extract Block To File') end, desc = "Extract Block To File" },
|
||||||
|
["<leader>rr"] = { function() require('telescope').extensions.refactoring.refactors() end, desc = "Prompt for a refactor to apply" },
|
||||||
|
["<leader>rp"] = { function() require('refactoring').debug.printf({below = false}) end, desc = "Insert print statement to mark the calling of a function" },
|
||||||
|
["<leader>rv"] = { function() require('refactoring').debug.print_var() end, desc = "Insert print statement to print a variable" },
|
||||||
|
["<leader>rc"] = { function() require('refactoring').debug.cleanup({}) end, desc = "Cleanup of all generated print statements" },
|
||||||
|
|
||||||
|
-- yank_history
|
||||||
|
["<leader>yh"] = { function() require("telescope").extensions.yank_history.yank_history() end, desc = "Preview Yank History" },
|
||||||
|
|
||||||
|
-- undo history
|
||||||
|
["<leader>uh"] = {"<cmd>Telescope undo<cr>", desc="Telescope undo" },
|
||||||
|
|
||||||
|
-- implementation/definition preview
|
||||||
|
["gpd"] = { "<cmd>lua require('goto-preview').goto_preview_definition()<CR>", desc="goto_preview_definition" },
|
||||||
|
["gpt"] = { "<cmd>lua require('goto-preview').goto_preview_type_definition()<CR>", desc="goto_preview_type_definition" },
|
||||||
|
["gpi"] = { "<cmd>lua require('goto-preview').goto_preview_implementation()<CR>", desc="goto_preview_implementation" },
|
||||||
|
["gP" ] = { "<cmd>lua require('goto-preview').close_all_win()<CR>", desc="close_all_win" },
|
||||||
|
["gpr"] = { "<cmd>lua require('goto-preview').goto_preview_references()<CR>", desc="goto_preview_references" },
|
||||||
|
},
|
||||||
|
-- Visual mode
|
||||||
|
v = {
|
||||||
|
-- search and replace globally
|
||||||
|
['<leader>sw'] = {'<esc><cmd>lua require("spectre").open_visual()<CR>', desc = "Search current word" },
|
||||||
|
},
|
||||||
|
-- visual mode(what's the difference between v and x???)
|
||||||
|
x = {
|
||||||
|
-- refactoring
|
||||||
|
["<leader>ri"] = { function() require('refactoring').refactor('Inline Variable') end, desc = "Inverse of extract variable" },
|
||||||
|
["<leader>re"] = { function() require('refactoring').refactor('Extract Function') end, desc = "Extracts the selected code to a separate function" },
|
||||||
|
["<leader>rf"] = { function() require('refactoring').refactor('Extract Function To File') end, desc = "Extract Function To File" },
|
||||||
|
["<leader>rv"] = { function() require('refactoring').refactor('Extract Variable') end, desc = "Extracts occurrences of a selected expression to its own variable" },
|
||||||
|
["<leader>rr"] = { function() require('telescope').extensions.refactoring.refactors() end, desc = "Prompt for a refactor to apply" },
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
astronvim,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# AstroNvim's configuration and all its dependencies(lsp, formatter, etc.)
|
||||||
|
#
|
||||||
|
#e#############################################################################
|
||||||
|
let
|
||||||
|
shellAliases = {
|
||||||
|
v = "nvim";
|
||||||
|
vdiff = "nvim -d";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
xdg.configFile = {
|
||||||
|
# astronvim's config
|
||||||
|
"nvim" = {
|
||||||
|
source = astronvim;
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# my custom astronvim config, astronvim will load it after base config
|
||||||
|
# https://github.com/AstroNvim/AstroNvim/blob/v3.32.0/lua/astronvim/bootstrap.lua#L15-L16
|
||||||
|
"astronvim/lua/user" = {
|
||||||
|
source = ./astronvim_user;
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.shellAliases = shellAliases;
|
||||||
|
programs.nushell.shellAliases = shellAliases;
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
neovim = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
defaultEditor = true;
|
||||||
|
viAlias = true;
|
||||||
|
vimAlias = true;
|
||||||
|
|
||||||
|
# currently we use lazy.nvim as neovim's package manager, so comment this one.
|
||||||
|
# Install packages that will compile locally or download FHS binaries via Nix!
|
||||||
|
# and use lazy.nvim's `dir` option to specify the package directory in nix store.
|
||||||
|
# so that these plugins can work on NixOS.
|
||||||
|
#
|
||||||
|
# related project:
|
||||||
|
# https://github.com/b-src/lazy-nix-helper.nvim
|
||||||
|
plugins = with pkgs.vimPlugins; [
|
||||||
|
# search all the plugins using https://search.nixos.org/packages
|
||||||
|
telescope-fzf-native-nvim
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
nixpkgs.config = {
|
||||||
|
programs.npm.npmrc = ''
|
||||||
|
prefix = ''${HOME}/.npm-global
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = with pkgs;
|
||||||
|
[
|
||||||
|
#-- c/c++
|
||||||
|
cmake
|
||||||
|
cmake-language-server
|
||||||
|
gnumake
|
||||||
|
checkmake
|
||||||
|
# c/c++ compiler, required by nvim-treesitter!
|
||||||
|
gcc
|
||||||
|
# c/c++ tools with clang-tools, the unwrapped version won't
|
||||||
|
# add alias like `cc` and `c++`, so that it won't conflict with gcc
|
||||||
|
llvmPackages.clang-unwrapped
|
||||||
|
lldb
|
||||||
|
|
||||||
|
#-- python
|
||||||
|
nodePackages.pyright # python language server
|
||||||
|
(python311.withPackages (
|
||||||
|
ps:
|
||||||
|
with ps; [
|
||||||
|
ruff-lsp
|
||||||
|
black # python formatter
|
||||||
|
|
||||||
|
jupyter
|
||||||
|
ipython
|
||||||
|
pandas
|
||||||
|
requests
|
||||||
|
pyquery
|
||||||
|
pyyaml
|
||||||
|
|
||||||
|
## emacs's lsp-bridge dependenciesge
|
||||||
|
epc
|
||||||
|
orjson
|
||||||
|
sexpdata
|
||||||
|
six
|
||||||
|
setuptools
|
||||||
|
paramiko
|
||||||
|
rapidfuzz
|
||||||
|
]
|
||||||
|
))
|
||||||
|
|
||||||
|
#-- rust
|
||||||
|
rust-analyzer
|
||||||
|
cargo # rust package manager
|
||||||
|
rustfmt
|
||||||
|
|
||||||
|
#-- zig
|
||||||
|
zls
|
||||||
|
|
||||||
|
#-- nix
|
||||||
|
nil
|
||||||
|
rnix-lsp
|
||||||
|
# nixd
|
||||||
|
statix # Lints and suggestions for the nix programming language
|
||||||
|
deadnix # Find and remove unused code in .nix source files
|
||||||
|
alejandra # Nix Code Formatter
|
||||||
|
|
||||||
|
#-- golang
|
||||||
|
go
|
||||||
|
gomodifytags
|
||||||
|
iferr # generate error handling code for go
|
||||||
|
impl # generate function implementation for go
|
||||||
|
gotools # contains tools like: godoc, goimports, etc.
|
||||||
|
gopls # go language server
|
||||||
|
delve # go debugger
|
||||||
|
|
||||||
|
# -- java
|
||||||
|
jdk17
|
||||||
|
gradle
|
||||||
|
maven
|
||||||
|
spring-boot-cli
|
||||||
|
|
||||||
|
#-- lua
|
||||||
|
stylua
|
||||||
|
lua-language-server
|
||||||
|
|
||||||
|
#-- bash
|
||||||
|
nodePackages.bash-language-server
|
||||||
|
shellcheck
|
||||||
|
shfmt
|
||||||
|
|
||||||
|
#-- javascript/typescript --#
|
||||||
|
nodePackages.nodejs
|
||||||
|
nodePackages.typescript
|
||||||
|
nodePackages.typescript-language-server
|
||||||
|
# HTML/CSS/JSON/ESLint language servers extracted from vscode
|
||||||
|
nodePackages.vscode-langservers-extracted
|
||||||
|
nodePackages."@tailwindcss/language-server"
|
||||||
|
emmet-ls
|
||||||
|
|
||||||
|
#-- CloudNative
|
||||||
|
nodePackages.dockerfile-language-server-nodejs
|
||||||
|
# terraform # install via brew on macOS
|
||||||
|
terraform-ls
|
||||||
|
jsonnet
|
||||||
|
jsonnet-language-server
|
||||||
|
hadolint # Dockerfile linter
|
||||||
|
|
||||||
|
# -- Lisp like Languages
|
||||||
|
guile
|
||||||
|
racket-minimal
|
||||||
|
fnlfmt # fennel
|
||||||
|
|
||||||
|
#-- Others
|
||||||
|
taplo # TOML language server / formatter / validator
|
||||||
|
nodePackages.yaml-language-server
|
||||||
|
sqlfluff # SQL linter
|
||||||
|
actionlint # GitHub Actions linter
|
||||||
|
buf # protoc plugin for linting and formatting
|
||||||
|
proselint # English prose linter
|
||||||
|
|
||||||
|
#-- Misc
|
||||||
|
tree-sitter # common language parser/highlighter
|
||||||
|
nodePackages.prettier # common code formatter
|
||||||
|
marksman # language server for markdown
|
||||||
|
glow # markdown previewer
|
||||||
|
fzf
|
||||||
|
pandoc # document converter
|
||||||
|
hugo # static site generator
|
||||||
|
|
||||||
|
#-- Optional Requirements:
|
||||||
|
gdu # disk usage analyzer, required by AstroNvim
|
||||||
|
(ripgrep.override {withPCRE2 = true;}) # recursively searches directories for a regex pattern
|
||||||
|
]
|
||||||
|
++ (
|
||||||
|
lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
#-- verilog / systemverilog
|
||||||
|
verible
|
||||||
|
gdb
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Encryption
|
||||||
|
|
||||||
|
We have GnuPG & password-store installed by default, mainly for password management, authentication & communication encryption.
|
||||||
|
|
||||||
|
We also have LUKS2 for disk encryption on Linux, and [rclone](https://rclone.org/crypt/) for cross-platform data encryption & syncing.
|
||||||
|
|
||||||
|
[age](https://github.com/FiloSottile/age) may be more general for file encryption.
|
||||||
|
|
||||||
|
[Sops](https://github.com/getsops/sops/tree/main) can be used for file encryption too, if you prefer
|
||||||
|
using a Cloud provider for key management.
|
||||||
|
|
||||||
|
|
||||||
|
## Asymmetric Encryption
|
||||||
|
|
||||||
|
Both age, Sops & GnuPG provide asymmetric encryption, which is useful for encrypting files for a specific user.
|
||||||
|
|
||||||
|
For morden use, age is recommended, as it use [AEAD encryption function - ChaCha20-Poly1305][age Format v1],
|
||||||
|
If you do not want to manage the keys by yourself, Sops is recommended, as it use KMS for key management.
|
||||||
|
|
||||||
|
## Symmetric Encryption
|
||||||
|
|
||||||
|
Both age & GnuPG provide symmetric encryption, which is useful for encrypting files for a specific user.
|
||||||
|
|
||||||
|
As described in [age Format v1][age Format v1], age use scrypt to encrypt and decrypt the file key with a provided passphrase,
|
||||||
|
which is more secure than GnuPG's symmetric encryption.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[age Format v1]: https://age-encryption.org/v1
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
age
|
||||||
|
sops
|
||||||
|
rclone
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,660 @@
|
|||||||
|
# GNU Privacy Guard(GnuPG)
|
||||||
|
|
||||||
|
> Offical Website: https://www.gnupg.org/
|
||||||
|
|
||||||
|
The GNU Privacy Guard is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as **PGP**). GnuPG allows to encrypt and sign your data and communication, features a versatile key management system as well as access modules for all kind of public key directories.
|
||||||
|
|
||||||
|
> In the following content, we will use GPG to refer to GnuPG tool, and PGP to refer to various concepts defined in the OepnPGP standard(e.g. PGP key, PGP key server).
|
||||||
|
|
||||||
|
Key functions of GnuPG:
|
||||||
|
|
||||||
|
1. Keypair(keyring) management
|
||||||
|
2. Sign and Verify your data
|
||||||
|
3. Encrypt and Decrypt your data
|
||||||
|
|
||||||
|
Main usage scenarios of GnuPG:
|
||||||
|
|
||||||
|
1. Sign or encrypt your email
|
||||||
|
1. Verify or decrypt the email you received
|
||||||
|
2. Sign your git commit
|
||||||
|
3. Manage your ssh key
|
||||||
|
4. Encrypt your data and store it somewhere.
|
||||||
|
|
||||||
|
GnuPG/OpenPGP is complex, so while using it, I have been looking forward to finding an encryption tool that is simple enough, functional enough, and widely adopted.
|
||||||
|
|
||||||
|
Currently I use both age & GnuPG:
|
||||||
|
|
||||||
|
1. Age for secrets encryption(ssh key & other secret files), it's simple and easy to use.
|
||||||
|
2. GnuPG for password-store and email encryption.
|
||||||
|
|
||||||
|
> At present, the safe and efficient use of GPG is probably combined with hardware keys such as yubikey. but I don't have one, so I won't talk about it here.
|
||||||
|
|
||||||
|
## Practical Cryptography for Developers
|
||||||
|
|
||||||
|
To use GnuGP without seamlessly, Some Practical Cryptography knowledge is required, here is dome tutorials:
|
||||||
|
|
||||||
|
- English version: <https://github.com/nakov/Practical-Cryptography-for-Developers-Book>
|
||||||
|
- Chinese version: <https://thiscute.world/tags/cryptography/>
|
||||||
|
|
||||||
|
## Overview of GnuPG
|
||||||
|
|
||||||
|
> GnuPG's Official User Guides: <https://www.gnupg.org/documentation/guides.html>
|
||||||
|
|
||||||
|
> ArchWiki's GnuPG page: <https://wiki.archlinux.org/title/GnuPG>
|
||||||
|
|
||||||
|
### 0. How GnuGP generate & protect your keypair?
|
||||||
|
|
||||||
|
Related Docs:
|
||||||
|
|
||||||
|
- [2021年,用更现代的方法使用PGP(上)][2021年,用更现代的方法使用PGP(上)]
|
||||||
|
- [Predictable, Passphrase-Derived PGP Keys][Predictable, Passphrase-Derived PGP Keys]
|
||||||
|
- [OpenPGP - The almost perfect key pair][OpenPGP - The almost perfect key pair]
|
||||||
|
|
||||||
|
|
||||||
|
GnuPG generate every secret key separately, and encrypt them with a symmetric key derived from your passphrase.
|
||||||
|
OpenPGP standard defines [String-to-Key (S2K)](https://datatracker.ietf.org/doc/html/rfc4880#section-3.7)
|
||||||
|
algorithm to derive a symmetric key from your passphrase.
|
||||||
|
|
||||||
|
GnuPG's [OpenPGP protocol specific options](https://gnupg.org/documentation/manuals/gnupg/OpenPGP-Options.html#OpenPGP-Options) shows that:
|
||||||
|
|
||||||
|
```
|
||||||
|
--s2k-cipher-algo name
|
||||||
|
|
||||||
|
Use name as the cipher algorithm for symmetric encryption with a passphrase if --personal-cipher-preferences and --cipher-algo are not given. The default is AES-128.
|
||||||
|
--s2k-digest-algo name
|
||||||
|
|
||||||
|
Use name as the digest algorithm used to mangle the passphrases for symmetric encryption. The default is SHA-1.
|
||||||
|
--s2k-mode n
|
||||||
|
|
||||||
|
Selects how passphrases for symmetric encryption are mangled. If n is 0 a plain passphrase (which is in general not recommended) will be used, a 1 adds a salt (which should not be used) to the passphrase and a 3 (the default) iterates the whole process a number of times (see --s2k-count).
|
||||||
|
--s2k-count n
|
||||||
|
|
||||||
|
Specify how many times the passphrases mangling for symmetric encryption is repeated. This value may range between 1024 and 65011712 inclusive. The default is inquired from gpg-agent. Note that not all values in the 1024-65011712 range are legal and if an illegal value is selected, GnuPG will round up to the nearest legal value. This option is only meaningful if --s2k-mode is set to the default of 3.
|
||||||
|
```
|
||||||
|
|
||||||
|
The strongest options should be:
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg --s2k-mode 3 --s2k-count 65011712 --s2k-digest-algo SHA512 --s2k-cipher-algo AES256 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
To use the strongest options globally, you can specify these options in your `~/.gnupg/gpg.conf`.
|
||||||
|
I've added them to my Home Manager's `programs.gpg.settings` option.
|
||||||
|
|
||||||
|
|
||||||
|
### 1. PGP Key(Primary Key) generation
|
||||||
|
|
||||||
|
Key management is the core of OpenPGP standard / GnuPG.
|
||||||
|
|
||||||
|
GnuPG uses public-key cryptography so that users may communicate securely. In a public-key system, each user has a pair of keys consisting of a private key and a public key. **A user's private key is kept secret; it need **never be revealed. The public key may be given to anyone with whom the user wants to communicate**. GnuPG uses a somewhat more sophisticated scheme in which a user has a primary keypair and then zero or more additional subordinate keypairs. The primary and subordinate keypairs are bundled to facilitate key management and the bundle can often be considered simply as one keypair, or a keyring/keychain(which contains multiple sub key-pairs).
|
||||||
|
|
||||||
|
Let's generate a keypair interactively:
|
||||||
|
|
||||||
|
> Now in 2024, GnuPG 2.4.1 defaults to ECC algorithm (9) and Curve 25519 for ECC, which is morden and safe, I would recommend to use these defaults directly.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --full-gen-key
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will ask you for some algorithm related settings(ECC & Curve 25519), your personal info, and a strong passphrase to protect your PGP key. e.g.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
› gpg --full-gen-key
|
||||||
|
gpg (GnuPG) 2.4.1; Copyright (C) 2023 g10 Code GmbH
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
|
gpg: directory '/Users/ryan/.gnupg' created
|
||||||
|
Please select what kind of key you want:
|
||||||
|
(1) RSA and RSA
|
||||||
|
(2) DSA and Elgamal
|
||||||
|
(3) DSA (sign only)
|
||||||
|
(4) RSA (sign only)
|
||||||
|
(9) ECC (sign and encrypt) *default*
|
||||||
|
(10) ECC (sign only)
|
||||||
|
(14) Existing key from card
|
||||||
|
Your selection? 9
|
||||||
|
Please select which elliptic curve you want:
|
||||||
|
(1) Curve 25519 *default*
|
||||||
|
(4) NIST P-384
|
||||||
|
(6) Brainpool P-256
|
||||||
|
Your selection? 1
|
||||||
|
Please specify how long the key should be valid.
|
||||||
|
0 = key does not expire
|
||||||
|
<n> = key expires in n days
|
||||||
|
<n>w = key expires in n weeks
|
||||||
|
<n>m = key expires in n months
|
||||||
|
<n>y = key expires in n years
|
||||||
|
Key is valid for? (0) 10y
|
||||||
|
Key expires at 一 1/ 4 13:50:31 2044 CST
|
||||||
|
Is this correct? (y/N) y
|
||||||
|
|
||||||
|
GnuPG needs to construct a user ID to identify your key.
|
||||||
|
|
||||||
|
Real name:
|
||||||
|
Email address:
|
||||||
|
Comment:
|
||||||
|
You selected this USER-ID:
|
||||||
|
"Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>"
|
||||||
|
|
||||||
|
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
gpg: /Users/ryan/.gnupg/trustdb.gpg: trustdb created
|
||||||
|
gpg: directory '/Users/ryan/.gnupg/openpgp-revocs.d' created
|
||||||
|
gpg: revocation certificate stored as '/Users/ryan/.gnupg/openpgp-revocs.d/C8D84EBC5F82494F432ACEF042E49B284C30A0DA.rev'
|
||||||
|
public and secret key created and signed.
|
||||||
|
|
||||||
|
pub ed25519 2024-01-09 [SC] [expires: 2034-01-04]
|
||||||
|
C8D84EBC5F82494F432ACEF042E49B284C30A0DA
|
||||||
|
uid Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||||
|
sub cv25519 2024-01-09 [E] [expires: 2034-01-04]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configuration Files
|
||||||
|
|
||||||
|
> https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration.html
|
||||||
|
|
||||||
|
The generated keys are stored in `~/.gnupg` by default, the functions of each file are as follows:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
› tree ~/.gnupg/
|
||||||
|
/Users/ryan/.gnupg/
|
||||||
|
|-- S.gpg-agent # socket file
|
||||||
|
|-- S.gpg-agent.browser # socket file
|
||||||
|
|-- S.gpg-agent.extra # socket file
|
||||||
|
|-- S.gpg-agent.ssh # socket file
|
||||||
|
|-- S.keyboxd # socket file
|
||||||
|
|-- common.conf # config file
|
||||||
|
|-- openpgp-revocs.d # Revocation certificates
|
||||||
|
| `-- F680C6D7215674ADEA421CC5E22EC419FF93EA98.rev
|
||||||
|
|-- private-keys-v1.d # private keys with user info & protect by passphrase
|
||||||
|
| |-- 2083133619AB24DC32DA68F9FE83C58D375284E3.key
|
||||||
|
| `-- 9350704F120643C504491E92CA97255223778C8A.key
|
||||||
|
|-- public-keys.d # public keys
|
||||||
|
| |-- pubring.db
|
||||||
|
| `-- pubring.db.lock
|
||||||
|
`-- trustdb.gpg # a trust database
|
||||||
|
|
||||||
|
4 directories, 12 files
|
||||||
|
```
|
||||||
|
|
||||||
|
The functions of most files are quite clear at a glance, but the `trustdb.gpg` in them is a bit difficult to understand. Here are the details: <https://www.gnupg.org/gph/en/manual/x334.html>
|
||||||
|
|
||||||
|
Home Manager will manage all the things in `~/.gnupg/` EXCEPT `~/.gnupg/openpgp-revocs.d/` and `~/.gnupg/private-keys-v1.d/`, which is expected.
|
||||||
|
|
||||||
|
### 3. Sub Key Generation & Best Practice
|
||||||
|
|
||||||
|
In PGP, every keys has a **usage flag** to indicate its usage:
|
||||||
|
|
||||||
|
- `C` means this key can be used to **Certify** other keys, which means this key can be used to **create/delete/revoke/modify** other keys.
|
||||||
|
- `S` means this key can be used to **Sign** data.
|
||||||
|
- `E` means this key can be used to **Encrypt** data.
|
||||||
|
- `A` means this key can be used to **Authenticate** data with various non-GnuPG programs. The key can be used as e.g. an **SSH key**.
|
||||||
|
|
||||||
|
The **best practice** is:
|
||||||
|
|
||||||
|
1. Generate a primary key with strong cryptography arguments(such as ECC + Curve 25519).
|
||||||
|
2. Then generate 3 sub keys with `E`, `S` and `A` usage flag respectively.
|
||||||
|
3. **The Primary Key is extremely important**, Backup the primary key to somewhere absolutely safe(such as two encryptd USB drivers, keep them in different places), and then **delete it from your computer immediately**.
|
||||||
|
4. The sub key is also important, but you can generate a new one and replace it easily. You can backup it to somewhere else, and import it to another machine to use your keypair.
|
||||||
|
5. Backup your Primary key's revocation certificate to somewhere safe, it's the last way to rescure your safety if your primary key is compromised!
|
||||||
|
1. It's a big problem if your revocation certificate is compromised, but not the bigest one. because it's only used to revoke your keypair, your data is still safe. But you should generate a new keypair and revoke the old one immediately.
|
||||||
|
1. It will be a big problem if your primary key is compromised, and you don't have a revocation certificate to revoke it. But since OpenPGP do not have a good way to distribute revocation certificate, even you have a revocation certificate, it's still hard to distribute it to others...
|
||||||
|
|
||||||
|
To keep your keypair safe, you should backup your keypair according to the following steps.
|
||||||
|
|
||||||
|
Now let's add the sub keys to the keypair we generated above:
|
||||||
|
|
||||||
|
> `E` sub key is already generated by default, so we only need to generate `S` and `A` sub keys.
|
||||||
|
|
||||||
|
> GnuPG will ask you to input your passphrase to unlock your primary key.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
› gpg --expert --edit-key ryan4yin@linux.com
|
||||||
|
gpg (GnuPG) 2.4.1; Copyright (C) 2023 g10 Code GmbH
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
|
Secret key is available.
|
||||||
|
|
||||||
|
sec ed25519/42E49B284C30A0DA
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb cv25519/6CB4A81FFB3C99B6
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: E
|
||||||
|
[ultimate] (1). Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||||
|
|
||||||
|
gpg> addkey
|
||||||
|
Please select what kind of key you want:
|
||||||
|
(3) DSA (sign only)
|
||||||
|
(4) RSA (sign only)
|
||||||
|
(5) Elgamal (encrypt only)
|
||||||
|
(6) RSA (encrypt only)
|
||||||
|
(7) DSA (set your own capabilities)
|
||||||
|
(8) RSA (set your own capabilities)
|
||||||
|
(10) ECC (sign only)
|
||||||
|
(11) ECC (set your own capabilities)
|
||||||
|
(12) ECC (encrypt only)
|
||||||
|
(13) Existing key
|
||||||
|
(14) Existing key from card
|
||||||
|
Your selection? 10
|
||||||
|
Please select which elliptic curve you want:
|
||||||
|
(1) Curve 25519 *default*
|
||||||
|
(2) Curve 448
|
||||||
|
(3) NIST P-256
|
||||||
|
(4) NIST P-384
|
||||||
|
(5) NIST P-521
|
||||||
|
(6) Brainpool P-256
|
||||||
|
(7) Brainpool P-384
|
||||||
|
(8) Brainpool P-512
|
||||||
|
(9) secp256k1
|
||||||
|
Your selection? 1
|
||||||
|
Please specify how long the key should be valid.
|
||||||
|
0 = key does not expire
|
||||||
|
<n> = key expires in n days
|
||||||
|
<n>w = key expires in n weeks
|
||||||
|
<n>m = key expires in n months
|
||||||
|
<n>y = key expires in n years
|
||||||
|
Key is valid for? (0) 10y
|
||||||
|
Key expires at Mon Jan 4 17:47:24 2044 CST
|
||||||
|
Is this correct? (y/N) y
|
||||||
|
Really create? (y/N) y
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
|
||||||
|
sec ed25519/42E49B284C30A0DA
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb cv25519/6CB4A81FFB3C99B6
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: E
|
||||||
|
ssb ed25519/A42813E03A10F504
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: S
|
||||||
|
[ultimate] (1). Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||||
|
|
||||||
|
gpg> addkey
|
||||||
|
Please select what kind of key you want:
|
||||||
|
(3) DSA (sign only)
|
||||||
|
(4) RSA (sign only)
|
||||||
|
(5) Elgamal (encrypt only)
|
||||||
|
(6) RSA (encrypt only)
|
||||||
|
(7) DSA (set your own capabilities)
|
||||||
|
(8) RSA (set your own capabilities)
|
||||||
|
(10) ECC (sign only)
|
||||||
|
(11) ECC (set your own capabilities)
|
||||||
|
(12) ECC (encrypt only)
|
||||||
|
(13) Existing key
|
||||||
|
(14) Existing key from card
|
||||||
|
Your selection? 11
|
||||||
|
|
||||||
|
Possible actions for this ECC key: Sign Authenticate
|
||||||
|
Current allowed actions: Sign
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? S
|
||||||
|
|
||||||
|
Possible actions for this ECC key: Sign Authenticate
|
||||||
|
Current allowed actions:
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? A
|
||||||
|
|
||||||
|
Possible actions for this ECC key: Sign Authenticate
|
||||||
|
Current allowed actions: Authenticate
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? Q
|
||||||
|
Please select which elliptic curve you want:
|
||||||
|
(1) Curve 25519 *default*
|
||||||
|
(2) Curve 448
|
||||||
|
(3) NIST P-256
|
||||||
|
(4) NIST P-384
|
||||||
|
(5) NIST P-521
|
||||||
|
(6) Brainpool P-256
|
||||||
|
(7) Brainpool P-384
|
||||||
|
(8) Brainpool P-512
|
||||||
|
(9) secp256k1
|
||||||
|
Your selection? 1
|
||||||
|
Please specify how long the key should be valid.
|
||||||
|
0 = key does not expire
|
||||||
|
<n> = key expires in n days
|
||||||
|
<n>w = key expires in n weeks
|
||||||
|
<n>m = key expires in n months
|
||||||
|
<n>y = key expires in n years
|
||||||
|
Key is valid for? (0) 10y
|
||||||
|
Key expires at Mon Jan 4 17:48:27 2044 CST
|
||||||
|
Is this correct? (y/N) y
|
||||||
|
Really create? (y/N) y
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
|
||||||
|
sec ed25519/42E49B284C30A0DA
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb cv25519/6CB4A81FFB3C99B6
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: E
|
||||||
|
ssb ed25519/A42813E03A10F504
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: S
|
||||||
|
ssb ed25519/5469C4FACC81B60F
|
||||||
|
created: 2024-01-09 expires: 2034-01-04 usage: A
|
||||||
|
[ultimate] (1). Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||||
|
|
||||||
|
gpg> save
|
||||||
|
```
|
||||||
|
|
||||||
|
Check the secret keys and public keys we generated:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
› gpg --list-secret-keys --with-subkey-fingerprint
|
||||||
|
[keyboxd]
|
||||||
|
---------
|
||||||
|
sec ed25519 2024-01-09 [SC] [expires: 2034-01-04]
|
||||||
|
C8D84EBC5F82494F432ACEF042E49B284C30A0DA
|
||||||
|
uid [ultimate] Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||||
|
ssb cv25519 2024-01-09 [E] [expires: 2034-01-04]
|
||||||
|
1146D48B93C2177C92D186026CB4A81FFB3C99B6
|
||||||
|
ssb ed25519 2024-01-09 [S] [expires: 2034-01-04]
|
||||||
|
DF64002A822948B17783BBB1A42813E03A10F504
|
||||||
|
ssb ed25519 2024-01-09 [A] [expires: 2034-01-04]
|
||||||
|
65E2C6C1C3559362ABB7047C5469C4FACC81B60F
|
||||||
|
|
||||||
|
› gpg --list-public-keys
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Backup & Restore
|
||||||
|
|
||||||
|
Export Public Keys(Both Primary Key & Sub Keys):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --armor --export ryan4yin@linux.com > ryan4yin-gpg-keys.pub
|
||||||
|
# check what we have exported, we should see 4 public keys
|
||||||
|
nix run nixpkgs#pgpdump ryan4yin-gpg-keys.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
Export Primary Key(The exported key is still encrypted by your passphrase):
|
||||||
|
|
||||||
|
> the `!` at the end of the key ID is to force GnuPG to export only the specified key, not the subkeys.
|
||||||
|
|
||||||
|
> GnuPG will ask you to input your passphrase to unlock your keypair,
|
||||||
|
> because GnuPG need to convert the secret key's format from its internal protection format to the one specified by the OpenPGP protocol.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# replace the key ID with your own sec key's ID
|
||||||
|
gpg --armor --export-secret-keys C8D84EBC5F82494F432ACEF042E49B284C30A0DA! > ryan4yin-primary-key.priv
|
||||||
|
|
||||||
|
# Check the exported primary key's detail info,
|
||||||
|
nix run nixpkgs#pgpdump ryan4yin-primary-key.priv
|
||||||
|
...
|
||||||
|
Old: Secret Key Packet(tag 5)(134 bytes)
|
||||||
|
Ver 4 - new
|
||||||
|
Public key creation time - Sat Jan 27 14:13:13 CST 2024
|
||||||
|
Pub alg - EdDSA Edwards-curve Digital Signature Algorithm(pub 22)
|
||||||
|
Elliptic Curve - Ed25519 (0x2B 06 01 04 01 DA 47 0F 01)
|
||||||
|
EdDSA Q(263 bits) - ...
|
||||||
|
Sym alg - AES with 128-bit key(sym 7)
|
||||||
|
Iterated and salted string-to-key(s2k 3):
|
||||||
|
Hash alg - SHA1(hash 2)
|
||||||
|
Salt - 8c 78 58 c0 87 83 8c 2c
|
||||||
|
Count - 65011712(coded count 255)
|
||||||
|
IV - xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
|
||||||
|
Encrypted EdDSA x
|
||||||
|
Encrypted SHA1 hash
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
As [Predictable, Passphrase-Derived PGP Keys][Predictable, Passphrase-Derived PGP Keys] says, we'll find that gpg ignored the `--s2k-count` option we specified when generating the keypair, and the `--s2k` related options we specified in `~/.gnupg/gpg.conf`,
|
||||||
|
the exported primary key is protectd by `SHA1` and `AES128`, which is not secure enough!
|
||||||
|
|
||||||
|
So to increase the security of the exported primary key, we need to encrypt it again with a stronger algorithm, I choose `age` here(which use `scrypt` to encrypt the file key with a provided passphrase):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# for simplicity, use the same passphrase as your gpg keypair here
|
||||||
|
age --passphrase -o ryan4yin-primary-key.priv.age ryan4yin-primary-key.priv
|
||||||
|
rm ryan4yin-primary-key.priv
|
||||||
|
```
|
||||||
|
|
||||||
|
Export Sub Keys one by one(The exported keys is still encrypted by your passphrase):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --armor --export-secret-subkeys > ryan4yin-gpg-subkeys.priv
|
||||||
|
|
||||||
|
# Check the exported primary key's detail info,
|
||||||
|
nix run nixpkgs#pgpdump ryan4yin-gpg-subkeys.priv
|
||||||
|
|
||||||
|
# encrypt it again with age(scrypt)
|
||||||
|
age --passphrase -o ryan4yin-gpg-subkeys.priv.age ryan4yin-gpg-subkeys.priv
|
||||||
|
rm ryan4yin-gpg-subkeys.priv
|
||||||
|
```
|
||||||
|
|
||||||
|
Your can import the exported Private Key via `gpg --import <keyfile>` to restore it, but you need to decrypt it via age first.
|
||||||
|
|
||||||
|
As for Public Keys, please import your publicKeys via Home Manager's `programs.gpg.publicKeys` option, DO NOT import it manually(via `gpg --import <keyfile>`).
|
||||||
|
|
||||||
|
To ensure security, delete the master key and revoke the certificate immediately after the backup is completed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# delete the primary key and all its sub keys
|
||||||
|
gpg --delete-secret-keys ryan4yin@linux.com
|
||||||
|
|
||||||
|
# delete the revocation certificate
|
||||||
|
rm ~/.gnupg/openpgp-revocs.d/C8D84EBC5F82494F432ACEF042E49B284C30A0DA.rev
|
||||||
|
|
||||||
|
# import our subkeys back
|
||||||
|
age --decrypt -o ryan4yin-primary-key.priv ryan4yin-primary-key.priv.age
|
||||||
|
gpg --import ryan4yin-gpg-subkeys.priv
|
||||||
|
```
|
||||||
|
|
||||||
|
Now check the secret keys and public keys again:
|
||||||
|
|
||||||
|
> A `#` at the end of the key ID means that the key is not available, because we have deleted it.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
› gpg --list-secret-keys --keyid-format=long
|
||||||
|
/home/ryan/.gnupg/pubring.kbx
|
||||||
|
-----------------------------
|
||||||
|
sec# ed25519/D1C5FFA3118A41FC 2024-01-09 [SC] [expires: 2034-01-04]
|
||||||
|
Key fingerprint = E267 943C 33AD C5AF 3D76 4D96 D1C5 FFA3 118A 41FC
|
||||||
|
uid [ unknown] Ryan Yin (Personal) <ryan4yin@linux.com>
|
||||||
|
ssb cv25519/62526A4A0CF43E33 2024-01-09 [E] [expires: 2034-01-04]
|
||||||
|
ssb ed25519/433A66D63805BD1A 2024-01-09 [S] [expires: 2034-01-04]
|
||||||
|
ssb ed25519/441E3D8FBD313BF2 2024-01-09 [A] [expires: 2034-01-04]
|
||||||
|
|
||||||
|
|
||||||
|
› gpg --list-public-keys --keyid-format=long
|
||||||
|
/home/ryan/.gnupg/pubring.kbx
|
||||||
|
-----------------------------
|
||||||
|
pub ed25519/D1C5FFA3118A41FC 2024-01-09 [SC] [expires: 2034-01-04]
|
||||||
|
Key fingerprint = E267 943C 33AD C5AF 3D76 4D96 D1C5 FFA3 118A 41FC
|
||||||
|
uid [ unknown] Ryan Yin (Personal) <ryan4yin@linux.com>
|
||||||
|
sub cv25519/62526A4A0CF43E33 2024-01-09 [E] [expires: 2034-01-04]
|
||||||
|
sub ed25519/433A66D63805BD1A 2024-01-09 [S] [expires: 2034-01-04]
|
||||||
|
sub ed25519/441E3D8FBD313BF2 2024-01-09 [A] [expires: 2034-01-04]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Signing & Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Make a cleartext signature.
|
||||||
|
gpg --clearsign <file>
|
||||||
|
|
||||||
|
# Make a detached signature, with text output.
|
||||||
|
gpg --armor --detach-sign <file>
|
||||||
|
|
||||||
|
# verify the file contains a valid signature.
|
||||||
|
gpg --verify <file>
|
||||||
|
|
||||||
|
# verify the file with a detached signature.
|
||||||
|
gpg --verify <file> <signature-file>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Encryption & Decryption
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Encrypt a file via recipient's public key, sign it via your private key for signing, and output cleartext.
|
||||||
|
# so that the reciiptent can decrypt it via his/her private key.
|
||||||
|
gpg --armor --sign --encrypt --recipient ryan4yin@linux.com <file>
|
||||||
|
# or use this short version
|
||||||
|
gpg -aser ryan4yin@linux.com <file>
|
||||||
|
|
||||||
|
# Descrypt a file via your private key, and verify the signature via the sender's public key.
|
||||||
|
gpg --decrypt <file>
|
||||||
|
# or
|
||||||
|
gpg -d <file>
|
||||||
|
```
|
||||||
|
|
||||||
|
If you just want to encrypt/decrypt a file quickly, you can use `age` with a passphrase, `gpg` can also do this, but it's not recommended(as age(scrypt)'s more secure):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Encrypt a file via symmetric encryption(AES256), and output cleartext.
|
||||||
|
gpg --armor --symmetric --cipher-algo AES256 <file>
|
||||||
|
# or
|
||||||
|
gpg -ac <file>
|
||||||
|
|
||||||
|
# Decrypt a file via symmetric encryption.
|
||||||
|
gpg --decrypt <file>
|
||||||
|
# or
|
||||||
|
gpg -d <file>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Public Key Exchange & Revocation
|
||||||
|
|
||||||
|
In the case of many users, it is very difficult to exchange public keys securely and reliably with each other.
|
||||||
|
In the Web world, There is a **Chain of Trust**** to resolve this problem:
|
||||||
|
|
||||||
|
- A Certificate Authority(CA) is responsible to verify & sign all the certificate signing request.
|
||||||
|
- Web Server can safely transmit its Web Certificate to the client via TLS protocol.
|
||||||
|
- Client can verify the recevied Web Certificate via the CA's root certificate(which is built in Browser/OS).
|
||||||
|
|
||||||
|
But in OpenPGP:
|
||||||
|
|
||||||
|
- There is key servers to distribute(exchange) public keys, but it **do not verify the identity of the key owner**, and any uploaded data is **not allowed to be deleted**. Which make it **insecure and dangerous**.
|
||||||
|
- Why key server is dangerous?
|
||||||
|
- Many PGP novices follow various tutorials to upload various key with personal privacy (such as real names) to the public key server, and then find that they can't delete them, which is very embarrassing.
|
||||||
|
- Anyone can upload a key to the key server, and claim that it is the key of a certain person(such as Linus), which is very insecure.
|
||||||
|
- **key server** is not recommend to use.
|
||||||
|
- GnuPG will generate revocation certificate when generating keypair(`~/.gnupg/private-keys-v1.d/<Key-ID.rev>`), anyone can import this certificate to revoke the keypair. But OpenPGP standard **DO NOT provide a way to distribute this certificate to others**.
|
||||||
|
- Not to mention some key status query protocol like OCSP in Web PKI.
|
||||||
|
- Users has to pulish their revocation certificate to their blog, github profile or somewhere else, and others has to check it and run `gpg --import <revocation-certificate>` to revoke the keypair manually.
|
||||||
|
|
||||||
|
In summary, **there is no good way to distribute public keys and revoke them in OpenPGP**, which is a big problem.
|
||||||
|
|
||||||
|
Currently, You have to distribute your public key or revocation certificate via your blog, github profile, or somewhere else, and others has to check it and run `gpg --import` to import your public key or revocation certificate manually.
|
||||||
|
|
||||||
|
Anyway, let's try to revoke a keypair:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
› gpg --list-keys
|
||||||
|
gpg: checking the trustdb
|
||||||
|
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||||
|
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
|
||||||
|
/home/ryan/.gnupg/pubring.kbx
|
||||||
|
-----------------------------
|
||||||
|
pub ed25519/0x55859965C2742B4B 2024-01-09 [SC]
|
||||||
|
Key fingerprint = A2CD 07BD 9631 44CB 2725 5A6B 5585 9965 C274 2B4B
|
||||||
|
uid [ultimate] test <test@test.t>
|
||||||
|
sub cv25519/0x9E78E897B6490D6B 2024-01-09 [E]
|
||||||
|
|
||||||
|
# encrypt some file before revoke the keypair
|
||||||
|
› gpg -aer test@test.t README.md > README.md.asc
|
||||||
|
|
||||||
|
# try to decrypt the file, it should works
|
||||||
|
› gpg -d README.md.asc
|
||||||
|
gpg: encrypted with cv25519 key, ID 0x9E78E897B6490D6B, created 2024-01-09
|
||||||
|
"test <test@test.t>"
|
||||||
|
# ......
|
||||||
|
|
||||||
|
# take a look at the revocation certificate
|
||||||
|
› cat gpg-test-revoke.rev
|
||||||
|
This is a revocation certificate for the OpenPGP key:
|
||||||
|
|
||||||
|
pub ed25519/0x55859965C2742B4B 2024-01-09 [S]
|
||||||
|
Key fingerprint = A2CD 07BD 9631 44CB 2725 5A6B 5585 9965 C274 2B4B
|
||||||
|
uid test <test@test.t>
|
||||||
|
|
||||||
|
A revocation certificate is a kind of "kill switch" to publicly
|
||||||
|
declare that a key shall not anymore be used. It is not possible
|
||||||
|
to retract such a revocation certificate once it has been published.
|
||||||
|
|
||||||
|
Use it to revoke this key in case of a compromise or loss of
|
||||||
|
the secret key. However, if the secret key is still accessible,
|
||||||
|
it is better to generate a new revocation certificate and give
|
||||||
|
a reason for the revocation. For details see the description of
|
||||||
|
of the gpg command "--generate-revocation" in the GnuPG manual.
|
||||||
|
|
||||||
|
To avoid an accidental use of this file, a colon has been inserted
|
||||||
|
before the 5 dashes below. Remove this colon with a text editor
|
||||||
|
before importing and publishing this revocation certificate.
|
||||||
|
|
||||||
|
:-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Comment: This is a revocation certificate
|
||||||
|
|
||||||
|
iHgEIBYKACAWIQSizQe9ljFEyyclWmtVhZllwnQrSwUCZZ1T9wIdAAAKCRBVhZll
|
||||||
|
wnQrS2LVAQCegRF1qPqY/OCS5QCz8G0ra0XgPYlQYo9pSOjHgfY39AD+Psin2/6t
|
||||||
|
STuJCp+gru6OtbTCu8Y2LugQeDh7UicM7Ak=
|
||||||
|
=Xfs6
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
```
|
||||||
|
|
||||||
|
As the revocation certificate says, we need to remove the first colon(`:`) before the 5 dashes(`-----BEGIN PGP PUBLIC KEY BLOCK-----`), then import it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
› gpg --import gpg-test-revoke.rev
|
||||||
|
gpg: key 0x55859965C2742B4B: "test <test@test.t>" revocation certificate imported
|
||||||
|
gpg: Total number processed: 1
|
||||||
|
gpg: new key revocations: 1
|
||||||
|
gpg: no ultimately trusted keys found
|
||||||
|
|
||||||
|
› gpg --list-secret-keys --keyid-format=long
|
||||||
|
/home/ryan/.gnupg/pubring.kbx
|
||||||
|
-----------------------------
|
||||||
|
sec ed25519/55859965C2742B4B 2024-01-09 [SC] [revoked: 2024-01-09]
|
||||||
|
Key fingerprint = A2CD 07BD 9631 44CB 2725 5A6B 5585 9965 C274 2B4B
|
||||||
|
uid [ revoked] test <test@test.t>
|
||||||
|
|
||||||
|
|
||||||
|
# try to decrypt the file, it still works, but will indicate that the key is revoked.
|
||||||
|
› gpg -d README.md.asc
|
||||||
|
gpg: encrypted with cv25519 key, ID 0x9E78E897B6490D6B, created 2024-01-09
|
||||||
|
"test <test@test.t>"
|
||||||
|
gpg: Note: key has been revoked
|
||||||
|
gpg: reason for revocation: No reason specified
|
||||||
|
# ......
|
||||||
|
|
||||||
|
# try to encrypt some file via the revoked key, it will fail.
|
||||||
|
› gpg -aer 9E78E897B6490D6B README.md
|
||||||
|
gpg: 9E78E897B6490D6B: skipped: Unusable public key
|
||||||
|
gpg: README.md: encryption failed: Unusable public key
|
||||||
|
```
|
||||||
|
|
||||||
|
But if you delete the `trustdb.gpg` and `pubring.kbx`, then import the revoked public key again, it will be valid and usable again... which is very dangerous.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [2021年,用更现代的方法使用PGP(上)][2021年,用更现代的方法使用PGP(上)]
|
||||||
|
- [Predictable, Passphrase-Derived PGP Keys][Predictable, Passphrase-Derived PGP Keys]
|
||||||
|
- [OpenPGP - The almost perfect key pair][OpenPGP - The almost perfect key pair]
|
||||||
|
|
||||||
|
[2021年,用更现代的方法使用PGP(上)]: https://ulyc.github.io/2021/01/13/2021%E5%B9%B4-%E7%94%A8%E6%9B%B4%E7%8E%B0%E4%BB%A3%E7%9A%84%E6%96%B9%E6%B3%95%E4%BD%BF%E7%94%A8PGP-%E4%B8%8A/
|
||||||
|
[Predictable, Passphrase-Derived PGP Keys]: https://nullprogram.com/blog/2019/07/10/
|
||||||
|
[OpenPGP - The almost perfect key pair]: https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1/
|
||||||
|
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
mysecrets,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
programs.gpg = {
|
||||||
|
enable = true;
|
||||||
|
homedir = "${config.home.homeDirectory}/.gnupg";
|
||||||
|
# $GNUPGHOME/trustdb.gpg stores all the trust level you specified in `programs.gpg.publicKeys` option.
|
||||||
|
#
|
||||||
|
# If set `mutableTrust` to false, the path $GNUPGHOME/trustdb.gpg will be overwritten on each activation.
|
||||||
|
# Thus we can only update trsutedb.gpg via home-manager.
|
||||||
|
mutableTrust = false;
|
||||||
|
|
||||||
|
# $GNUPGHOME/pubring.kbx stores all the public keys you specified in `programs.gpg.publicKeys` option.
|
||||||
|
#
|
||||||
|
# If set `mutableKeys` to false, the path $GNUPGHOME/pubring.kbx will become an immutable link to the Nix store, denying modifications.
|
||||||
|
# Thus we can only update pubring.kbx via home-manager
|
||||||
|
mutableKeys = false;
|
||||||
|
publicKeys = [
|
||||||
|
# https://www.gnupg.org/gph/en/manual/x334.html
|
||||||
|
{
|
||||||
|
source = "${mysecrets}/public/ryan4yin-gpg-keys-2014-01-27.pub";
|
||||||
|
trust = 5;
|
||||||
|
} # ultimate trust, my own keys.
|
||||||
|
];
|
||||||
|
|
||||||
|
# This configuration is based on the tutorial below, it allows for a robust setup
|
||||||
|
# https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1
|
||||||
|
# ~/.gnupg/gpg.conf
|
||||||
|
settings = {
|
||||||
|
# Get rid of the copyright notice
|
||||||
|
no-greeting = true;
|
||||||
|
|
||||||
|
# Disable inclusion of the version string in ASCII armored output
|
||||||
|
no-emit-version = true;
|
||||||
|
# Do not write comment packets
|
||||||
|
no-comments = false;
|
||||||
|
# Export the smallest key possible
|
||||||
|
# This removes all signatures except the most recent self-signature on each user ID
|
||||||
|
export-options = "export-minimal";
|
||||||
|
|
||||||
|
# Display long key IDs
|
||||||
|
keyid-format = "0xlong";
|
||||||
|
# List all keys (or the specified ones) along with their fingerprints
|
||||||
|
with-fingerprint = true;
|
||||||
|
|
||||||
|
# Display the calculated validity of user IDs during key listings
|
||||||
|
list-options = "show-uid-validity";
|
||||||
|
verify-options = "show-uid-validity show-keyserver-urls";
|
||||||
|
|
||||||
|
# Select the strongest cipher
|
||||||
|
personal-cipher-preferences = "AES256";
|
||||||
|
# Select the strongest digest
|
||||||
|
personal-digest-preferences = "SHA512";
|
||||||
|
# This preference list is used for new keys and becomes the default for "setpref" in the edit menu
|
||||||
|
default-preference-list = "SHA512 SHA384 SHA256 RIPEMD160 AES256 TWOFISH BLOWFISH ZLIB BZIP2 ZIP Uncompressed";
|
||||||
|
|
||||||
|
# Use the strongest cipher algorithm
|
||||||
|
cipher-algo = "AES256";
|
||||||
|
# Use the strongest digest algorithm
|
||||||
|
digest-algo = "SHA512";
|
||||||
|
# Message digest algorithm used when signing a key
|
||||||
|
cert-digest-algo = "SHA512";
|
||||||
|
# Use RFC-1950 ZLIB compression
|
||||||
|
compress-algo = "ZLIB";
|
||||||
|
|
||||||
|
# Disable weak algorithm
|
||||||
|
disable-cipher-algo = "3DES";
|
||||||
|
# Treat the specified digest algorithm as weak
|
||||||
|
weak-digest = "SHA1";
|
||||||
|
|
||||||
|
# The cipher algorithm for symmetric encryption for symmetric encryption with a passphrase
|
||||||
|
s2k-cipher-algo = "AES256";
|
||||||
|
# The digest algorithm used to mangle the passphrases for symmetric encryption
|
||||||
|
s2k-digest-algo = "SHA512";
|
||||||
|
# Selects how passphrases for symmetric encryption are mangled
|
||||||
|
s2k-mode = "3";
|
||||||
|
# Specify how many times the passphrases mangling for symmetric encryption is repeated
|
||||||
|
s2k-count = "65011712";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
# processing audio/video
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
ffmpeg-full
|
||||||
|
|
||||||
|
# images
|
||||||
|
viu # Terminal image viewer with native support for iTerm and Kitty
|
||||||
|
imagemagick
|
||||||
|
graphviz
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Password Manager
|
||||||
|
|
||||||
|
- https://www.passwordstore.org/
|
||||||
|
- [awesome-password-store](https://github.com/tijn/awesome-password-store)
|
||||||
|
- <https://github.com/gopasspw/gopass>: reimplement in go, with more features.
|
||||||
|
- Clients
|
||||||
|
- Android: <https://github.com/android-password-store/Android-Password-Store>
|
||||||
|
- Brosers(Chrome/Firefox): <https://github.com/browserpass/browserpass-extension>
|
||||||
|
|
||||||
|
## How to change the gpg key of the pass password store?
|
||||||
|
|
||||||
|
To ensure security, we should change the GPG key every two or three years. Here is how to do this.
|
||||||
|
|
||||||
|
1. Create a new GPG key pair and backup it to a safe place.
|
||||||
|
2. Ensure you can access both the old and new GPG keys.
|
||||||
|
3. Update `./default.nix` to use the new GPG sub keys.
|
||||||
|
4. Check which Key `pass` currently uses:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/.local/share/password-store/
|
||||||
|
# check which key is used by pass
|
||||||
|
cat .gpg-id
|
||||||
|
# check which key is really used to encrypt the password
|
||||||
|
gpg --list-packets path/to/any/password.gpg
|
||||||
|
```
|
||||||
|
4. Change the key used by `pass`:
|
||||||
|
```bash
|
||||||
|
# change the key used by pass, see `man pass` for more details
|
||||||
|
# you will be asked to enter the password of both the new and old keys
|
||||||
|
# then pass will re-encrypt all the passwords with the new key
|
||||||
|
pass init <new-key-id>
|
||||||
|
```
|
||||||
|
5. Check if the key is changed:
|
||||||
|
```bash
|
||||||
|
# check which key is used by pass
|
||||||
|
cat .gpg-id
|
||||||
|
# check which key is really used to encrypt the password
|
||||||
|
gpg --list-packets path/to/any/password.gpg
|
||||||
|
```
|
||||||
|
6. Delete the old GPG key pair:
|
||||||
|
```bash
|
||||||
|
# delete the old key pair
|
||||||
|
gpg --delete-secret-keys <old-key-id>
|
||||||
|
gpg --delete-keys <old-key-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
passwordStoreDir = "${config.xdg.dataHome}/password-store";
|
||||||
|
in {
|
||||||
|
programs.password-store = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.pass.withExtensions (exts: [
|
||||||
|
# support for one-time-password (OTP) tokens
|
||||||
|
# NOTE: Saving the password and OTP together runs counter to the purpose of secondary verification!
|
||||||
|
# exts.pass-otp
|
||||||
|
|
||||||
|
exts.pass-import # a generic importer tool from other password managers
|
||||||
|
exts.pass-update # an easy flow for updating passwords
|
||||||
|
]);
|
||||||
|
# See the “Environment variables” section of pass(1) and the extension man pages for more information about the available keys.
|
||||||
|
settings = {
|
||||||
|
PASSWORD_STORE_DIR = passwordStoreDir;
|
||||||
|
# Overrides the default gpg key identification set by init.
|
||||||
|
# Hexadecimal key signature is recommended.
|
||||||
|
# Multiple keys may be specified separated by spaces.
|
||||||
|
PASSWORD_STORE_KEY = lib.strings.concatStringsSep " " [
|
||||||
|
"EF824EB73CFD6CC7" # E - Ryan Yin (For pass & ssh only) <ryan4yin@linux.com>
|
||||||
|
];
|
||||||
|
# all .gpg-id files and non-system extension files must be signed using a detached signature using the GPG key specified by
|
||||||
|
# the full 40 character upper-case fingerprint in this variable.
|
||||||
|
# If multiple fingerprints are specified, each separated by a whitespace character, then signatures must match at least one.
|
||||||
|
# The init command will keep signatures of .gpg-id files up to date.
|
||||||
|
PASSWORD_STORE_SIGNING_KEY = lib.strings.concatStringsSep " " [
|
||||||
|
"C2A313F98166C942" # S - Ryan Yin (For pass & ssh only) <ryan4yin@linux.com>
|
||||||
|
];
|
||||||
|
PASSWORD_STORE_CLIP_TIME = "60";
|
||||||
|
PASSWORD_STORE_GENERATED_LENGTH = "15";
|
||||||
|
PASSWORD_STORE_ENABLE_EXTENSIONS = "true";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# password-store extensions for browsers
|
||||||
|
# you need to install the browser extension for this to work
|
||||||
|
# https://github.com/browserpass/browserpass-extension
|
||||||
|
programs.browserpass = {
|
||||||
|
enable = true;
|
||||||
|
browsers = [
|
||||||
|
"chrome"
|
||||||
|
"chromium"
|
||||||
|
"firefox"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{pkgs-unstable, ...}: let
|
||||||
|
inherit (pkgs-unstable) nu_scripts;
|
||||||
|
in {
|
||||||
|
programs.bash = {
|
||||||
|
# load the alias file for work
|
||||||
|
bashrcExtra = ''
|
||||||
|
alias_for_work=/etc/agenix/alias-for-work.bash
|
||||||
|
if [ -f $alias_for_work ]; then
|
||||||
|
. $alias_for_work
|
||||||
|
else
|
||||||
|
echo "No alias file found for work"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.nushell = {
|
||||||
|
# load the alias file for work
|
||||||
|
# the file must exist, otherwise nushell will complain about it!
|
||||||
|
#
|
||||||
|
# currently, nushell does not support conditional sourcing of files
|
||||||
|
# https://github.com/nushell/nushell/issues/8214
|
||||||
|
extraConfig = ''
|
||||||
|
source /etc/agenix/alias-for-work.nushell
|
||||||
|
# completion
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/git/git-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/glow/glow-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/just/just-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/make/make-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/man/man-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/nix/nix-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/cargo/cargo-completions.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/custom-completions/zellij/zellij-completions.nu *
|
||||||
|
# alias
|
||||||
|
use ${nu_scripts}/share/nu_scripts/aliases/git/git-aliases.nu *
|
||||||
|
use ${nu_scripts}/share/nu_scripts/aliases/eza/eza-aliases.nu *
|
||||||
|
# use ${nu_scripts}/share/nu_scripts/aliases/bat/bat-aliases.nu *
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{mysecrets, ...}: {
|
||||||
|
home.file.".ssh/romantic.pub".source = "${mysecrets}/public/romantic.pub";
|
||||||
|
|
||||||
|
programs.ssh = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# All my ssh private key are generated by `ssh-keygen -t ed25519 -a 256 -C "xxx@xxx"`
|
||||||
|
# Config format:
|
||||||
|
# Host — given the pattern used to match against the host name given on the command line.
|
||||||
|
# HostName — specify nickname or abbreviation for host
|
||||||
|
# IdentityFile — the location of your SSH key authentication file for the account.
|
||||||
|
# Format in details:
|
||||||
|
# https://www.ssh.com/academy/ssh/config
|
||||||
|
extraConfig = ''
|
||||||
|
# a private key that is used during authentication will be added to ssh-agent if it is running
|
||||||
|
AddKeysToAgent yes
|
||||||
|
|
||||||
|
Host 192.168.*
|
||||||
|
# allow to securely use local SSH agent to authenticate on the remote machine.
|
||||||
|
# It has the same effect as adding cli option `ssh -A user@host`
|
||||||
|
ForwardAgent yes
|
||||||
|
# romantic holds my homelab~
|
||||||
|
IdentityFile /etc/agenix/ssh-key-romantic
|
||||||
|
# Specifies that ssh should only use the identity file explicitly configured above
|
||||||
|
# required to prevent sending default identity files first.
|
||||||
|
IdentitiesOnly yes
|
||||||
|
|
||||||
|
Host gtr5
|
||||||
|
HostName 192.168.5.172
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host um560
|
||||||
|
HostName 192.168.5.173
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host s500plus
|
||||||
|
HostName 192.168.5.174
|
||||||
|
Port 22
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Termianl Emulators
|
||||||
|
|
||||||
|
I used to spend a lot of time on terminal emulators, to make them match my taste,
|
||||||
|
but now I found that it's not worth it, **Zellij can provide a user-friendly and unified user experience for all terminal emulators! without any pain**!
|
||||||
|
|
||||||
|
Currently, I only use the most basic features of terminal emulators, such as true color, graphics protocol, etc.
|
||||||
|
Other features such as tabs, scrollback buffer, select/search/copy, etc, are all provided by zellij!
|
||||||
|
|
||||||
|
My current terminal emulators are:
|
||||||
|
|
||||||
|
1. kitty: My main terminal emulator.
|
||||||
|
1. to select/copy a large mount of text, We should do some tricks via kitty's `scrollback_pager` with neovim, it's really painful: <https://github.com/kovidgoyal/kitty/issues/719>
|
||||||
|
2. wezterm: My secondary terminal emulator.
|
||||||
|
1. its search ability is very basic, and it's not easy to use.
|
||||||
|
1. its scrollback buffer's copy mode is very like vim, which is nice, but zellij's even better, it can use neovim as its default scrollback buffer's editor without any pain!
|
||||||
|
3. foot: a fast, lightweight and minimalistic Wayland terminal emulator.
|
||||||
|
1. foot only do the things a terminal emulator should do, no more, no less.
|
||||||
|
1. It's really suitable for tiling window manager or zellij users!
|
||||||
|
|
||||||
|
## 'xterm-kitty': unknown terminal type when `ssh` into a remote host or `sudo xxx`
|
||||||
|
|
||||||
|
> https://sw.kovidgoyal.net/kitty/faq/#i-get-errors-about-the-terminal-being-unknown-or-opening-the-terminal-failing-or-functional-keys-like-arrow-keys-don-t-work
|
||||||
|
|
||||||
|
> https://wezfurlong.org/wezterm/config/lua/config/term.html
|
||||||
|
|
||||||
|
kitty set `TERM` to `xterm-kitty` by default, and TUI apps like `viu`, `yazi`, `curses` will try to search in the host's [terminfo(terminal capability data base)](https://linux.die.net/man/5/terminfo) for value of `TERM` to determine the capabilities of the terminal.
|
||||||
|
|
||||||
|
But when you `ssh` into a remote host, the remote host is very likely to not have `xterm-kitty` in its terminfo, so you will get this error:
|
||||||
|
|
||||||
|
```
|
||||||
|
'xterm-kitty': unknown terminal type
|
||||||
|
```
|
||||||
|
|
||||||
|
Or when you `sudo xxx`, `sudo` won't preserve the `TERM` variable, it will be reset to root's default `TERM` value, which is `xterm` or `xterm-256color` in most linux distributions, so you will get this error:
|
||||||
|
|
||||||
|
```
|
||||||
|
'xterm-256color': unknown terminal type
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```
|
||||||
|
Error opening terminal: xterm-kitty.
|
||||||
|
```
|
||||||
|
|
||||||
|
NixOS preserve the `TERMINFO` and `TERMINFO_DIRS` environment variables, for `root` and the `wheel` group: [nixpkgs/nixos/modules/config/terminfo.nix](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/config/terminfo.nix#L18)
|
||||||
|
|
||||||
|
For nix-darwin, take a look at <https://github.com/LnL7/nix-darwin/wiki/Terminfo-issues>
|
||||||
|
|
||||||
|
### Solutions
|
||||||
|
|
||||||
|
Simplest solution, it will automatically copy over the terminfo files and also magically enable shell integration on the remote machine:
|
||||||
|
|
||||||
|
```
|
||||||
|
kitten ssh user@host
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you do not care about kitty's features(such as true color & graphics protocol), you can simply set `TERM` to `xterm-256color`, which is built-in in most linux distributions:
|
||||||
|
|
||||||
|
```
|
||||||
|
export TERM=xterm-256color
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need kitty's features, but do not like the magic of `kitten`, you can manually install kitty's terminfo on the remote host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# install on ubuntu / debian
|
||||||
|
sudo apt-get install kitty-terminfo
|
||||||
|
|
||||||
|
# or copy from local machine
|
||||||
|
infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
|
||||||
|
```
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{mylib, ...}: {
|
||||||
|
imports = mylib.scanPaths ./.;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
###########################################################
|
||||||
|
#
|
||||||
|
# Kitty Configuration
|
||||||
|
#
|
||||||
|
# Useful Hot Keys for Linux(replace `ctrl + shift` with `cmd` on macOS)):
|
||||||
|
# 1. Increase Font Size: `ctrl + shift + =` | `ctrl + shift + +`
|
||||||
|
# 2. Decrease Font Size: `ctrl + shift + -` | `ctrl + shift + _`
|
||||||
|
# 3. And Other common shortcuts such as Copy, Paste, Cursor Move, etc.
|
||||||
|
#
|
||||||
|
###########################################################
|
||||||
|
{
|
||||||
|
programs.kitty = {
|
||||||
|
enable = true;
|
||||||
|
# kitty has catppuccin theme built-in,
|
||||||
|
# all the built-in themes are packaged into an extra package named `kitty-themes`
|
||||||
|
# and it's installed by home-manager if `theme` is specified.
|
||||||
|
theme = "Catppuccin-Mocha";
|
||||||
|
font = {
|
||||||
|
name = "JetBrainsMono Nerd Font";
|
||||||
|
# use different font size on macOS
|
||||||
|
size =
|
||||||
|
if pkgs.stdenv.isDarwin
|
||||||
|
then 14
|
||||||
|
else 13;
|
||||||
|
};
|
||||||
|
|
||||||
|
# consistent with wezterm
|
||||||
|
keybindings = {
|
||||||
|
"ctrl+shift+m" = "toggle_maximized";
|
||||||
|
"ctrl+shift+f" = "show_scrollback"; # search in the current window
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
background_opacity = "0.93";
|
||||||
|
macos_option_as_alt = true; # Option key acts as Alt on macOS
|
||||||
|
enable_audio_bell = false;
|
||||||
|
tab_bar_edge = "top"; # tab bar on top
|
||||||
|
# To resolve issues:
|
||||||
|
# 1. https://github.com/ryan4yin/nix-config/issues/26
|
||||||
|
# 2. https://github.com/ryan4yin/nix-config/issues/8
|
||||||
|
# Spawn a nushell in login mode via `bash`
|
||||||
|
shell = "${pkgs.bash}/bin/bash --login -c 'nu --login --interactive'";
|
||||||
|
};
|
||||||
|
|
||||||
|
# macOS specific settings
|
||||||
|
darwinLaunchOptions = ["--start-as=maximized"];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
{pkgs, ...}:
|
||||||
|
###########################################################
|
||||||
|
#
|
||||||
|
# Wezterm Configuration
|
||||||
|
#
|
||||||
|
# Useful Hot Keys for Linux(replace `ctrl + shift` with `cmd` on macOS)):
|
||||||
|
# 1. Increase Font Size: `ctrl + shift + =` | `ctrl + shift + +`
|
||||||
|
# 2. Decrease Font Size: `ctrl + shift + -` | `ctrl + shift + _`
|
||||||
|
# 3. And Other common shortcuts such as Copy, Paste, Cursor Move, etc.
|
||||||
|
#
|
||||||
|
# Default Keybindings: https://wezfurlong.org/wezterm/config/default-keys.html
|
||||||
|
#
|
||||||
|
###########################################################
|
||||||
|
{
|
||||||
|
# wezterm has catppuccin theme built-in,
|
||||||
|
# it's not necessary to install it separately.
|
||||||
|
|
||||||
|
# we can add wezterm as a flake input once this PR is merged:
|
||||||
|
# https://github.com/wez/wezterm/pull/3547
|
||||||
|
|
||||||
|
programs.wezterm = {
|
||||||
|
enable = true; # disable
|
||||||
|
|
||||||
|
# install wezterm via homebrew on macOS to avoid compilation, dummy package here.
|
||||||
|
package =
|
||||||
|
if pkgs.stdenv.isLinux
|
||||||
|
then pkgs.wezterm
|
||||||
|
else pkgs.hello;
|
||||||
|
|
||||||
|
enableBashIntegration = pkgs.stdenv.isLinux;
|
||||||
|
enableZshIntegration = pkgs.stdenv.isLinux;
|
||||||
|
|
||||||
|
extraConfig = let
|
||||||
|
fontsize =
|
||||||
|
if pkgs.stdenv.isLinux
|
||||||
|
then "13.0"
|
||||||
|
else "14.0";
|
||||||
|
in ''
|
||||||
|
-- Pull in the wezterm API
|
||||||
|
local wezterm = require 'wezterm'
|
||||||
|
|
||||||
|
-- This table will hold the configuration.
|
||||||
|
local config = {}
|
||||||
|
|
||||||
|
-- In newer versions of wezterm, use the config_builder which will
|
||||||
|
-- help provide clearer error messages
|
||||||
|
if wezterm.config_builder then
|
||||||
|
config = wezterm.config_builder()
|
||||||
|
end
|
||||||
|
|
||||||
|
wezterm.on('toggle-opacity', function(window, pane)
|
||||||
|
local overrides = window:get_config_overrides() or {}
|
||||||
|
if not overrides.window_background_opacity then
|
||||||
|
overrides.window_background_opacity = 0.93
|
||||||
|
else
|
||||||
|
overrides.window_background_opacity = nil
|
||||||
|
end
|
||||||
|
window:set_config_overrides(overrides)
|
||||||
|
end)
|
||||||
|
|
||||||
|
wezterm.on('toggle-maximize', function(window, pane)
|
||||||
|
window:maximize()
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- This is where you actually apply your config choices
|
||||||
|
config.color_scheme = "Catppuccin Mocha"
|
||||||
|
config.font = wezterm.font_with_fallback {
|
||||||
|
"JetBrainsMono Nerd Font",
|
||||||
|
"FiraCode Nerd Font",
|
||||||
|
|
||||||
|
-- To avoid 'Chinese characters displayed as variant (Japanese) glyphs'
|
||||||
|
"Source Han Sans SC",
|
||||||
|
"Source Han Sans TC"
|
||||||
|
}
|
||||||
|
|
||||||
|
config.hide_tab_bar_if_only_one_tab = true
|
||||||
|
config.scrollback_lines = 10000
|
||||||
|
config.enable_scroll_bar = true
|
||||||
|
config.term = 'wezterm'
|
||||||
|
|
||||||
|
config.keys = {
|
||||||
|
-- toggle opacity(CTRL + SHIFT + B)
|
||||||
|
{
|
||||||
|
key = 'B',
|
||||||
|
mods = 'CTRL',
|
||||||
|
action = wezterm.action.EmitEvent 'toggle-opacity',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key = 'M',
|
||||||
|
mods = 'CTRL',
|
||||||
|
action = wezterm.action.EmitEvent 'toggle-maximize',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
config.font_size = ${fontsize}
|
||||||
|
|
||||||
|
-- To resolve issues:
|
||||||
|
-- 1. https://github.com/ryan4yin/nix-config/issues/26
|
||||||
|
-- 2. https://github.com/ryan4yin/nix-config/issues/8
|
||||||
|
-- Spawn a nushell in login mode via `bash`
|
||||||
|
config.default_prog = { '${pkgs.bash}/bin/bash', '--login', '-c', 'nu --login --interactive' }
|
||||||
|
|
||||||
|
return config
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Zellij - A workspace lives in your terminal
|
||||||
|
|
||||||
|
Zellij is a terminal workspace with batteries included.
|
||||||
|
At its core, it is a terminal multiplexer (similar to tmux and screen), but this is merely its infrastructure layer.
|
||||||
|
|
||||||
|
Zellij is very user-friendly and easy to use, with a step-by-step hint system that will help you get to know the keybindings, which is very like the Neovim or helix.
|
||||||
|
|
||||||
|
> By contrast, tmux's key design is counterintuitive, there is no prompt system, and the plug-in performance is rubbish. It's really a pain to use.
|
||||||
|
> tmux's inital release was in 2007, it's too old, I would recommend any users that do not have a experience with multiplexer to use zellij instead of tmux.
|
||||||
|
|
||||||
|
## Why use zellij as the detault terminal environment?
|
||||||
|
|
||||||
|
By auto start zellij on shell login, and exit the shell session on zellij exit, we can use zellij as the default terminal environment.
|
||||||
|
|
||||||
|
By this way, We will only use the most basic features of the terminal emulator(kitty/alacritty/wezterm/...),
|
||||||
|
while most of the functions of terminal are provided by zellij.
|
||||||
|
Thus we can easily switch to any terminal emulator without losing any key functions,
|
||||||
|
and do not need to take care of the differences between different terminal emulators.
|
||||||
|
|
||||||
|
And Zellij can be used not only locally, but also on any remote server, which is very convenient. Learn once and use everywhere!
|
||||||
|
|
||||||
|
> Yeah, you didn't misread it, zellij is very suitable for not only remotely, but also locally!
|
||||||
|
|
||||||
|
Some features such as search/copy/scrollback in different terminal emulators are implemented in different ways, and has different user experience.
|
||||||
|
For example, Wezterm's default search function is very basic, and it's not easy to use. Kitty's scrollback search/copy is really tricky to use.
|
||||||
|
As for some Editor such as Neovim, its intergrated terminal is really useful, but zellij is more powerful and useful than it, and more stable!
|
||||||
|
Zellij overcomes these problems, and provides a unified user experience for all terminal emulators!
|
||||||
|
|
||||||
|
Teminal emulators should only be responsible for displaying characters.
|
||||||
|
|
||||||
|
## Passthrough mode(Lock Mode)
|
||||||
|
|
||||||
|
`Ctrl + g` lock the outer zellij interface, and all keys will be sent to the focused pane.
|
||||||
|
|
||||||
|
It's extremely useful when you want to:
|
||||||
|
|
||||||
|
1. Use zellij locally for daily work, and use a remote zellij via ssh to do some work on the remote server.
|
||||||
|
1. To avoid the key conflicts between zellij and the program running in the terminal, such as vim, tmux, etc.
|
||||||
|
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
// If you'd like to override the default keybindings completely, be sure to change "keybinds" to "keybinds clear-defaults=true"
|
||||||
|
keybinds clear-defaults=true {
|
||||||
|
normal {
|
||||||
|
// uncomment this and adjust key if using copy_on_select=false
|
||||||
|
// bind "Alt c" { Copy; }
|
||||||
|
}
|
||||||
|
locked {
|
||||||
|
bind "Ctrl g" { SwitchToMode "Normal"; }
|
||||||
|
}
|
||||||
|
resize {
|
||||||
|
bind "Ctrl n" { SwitchToMode "Normal"; }
|
||||||
|
bind "h" "Left" { Resize "Increase Left"; }
|
||||||
|
bind "j" "Down" { Resize "Increase Down"; }
|
||||||
|
bind "k" "Up" { Resize "Increase Up"; }
|
||||||
|
bind "l" "Right" { Resize "Increase Right"; }
|
||||||
|
bind "H" { Resize "Decrease Left"; }
|
||||||
|
bind "J" { Resize "Decrease Down"; }
|
||||||
|
bind "K" { Resize "Decrease Up"; }
|
||||||
|
bind "L" { Resize "Decrease Right"; }
|
||||||
|
bind "=" "+" { Resize "Increase"; }
|
||||||
|
bind "-" { Resize "Decrease"; }
|
||||||
|
}
|
||||||
|
pane {
|
||||||
|
bind "Ctrl p" { SwitchToMode "Normal"; }
|
||||||
|
bind "h" "Left" { MoveFocus "Left"; }
|
||||||
|
bind "l" "Right" { MoveFocus "Right"; }
|
||||||
|
bind "j" "Down" { MoveFocus "Down"; }
|
||||||
|
bind "k" "Up" { MoveFocus "Up"; }
|
||||||
|
bind "p" { SwitchFocus; }
|
||||||
|
bind "n" { NewPane; SwitchToMode "Normal"; }
|
||||||
|
bind "d" { NewPane "Down"; SwitchToMode "Normal"; }
|
||||||
|
bind "r" { NewPane "Right"; SwitchToMode "Normal"; }
|
||||||
|
bind "x" { CloseFocus; SwitchToMode "Normal"; }
|
||||||
|
bind "f" { ToggleFocusFullscreen; SwitchToMode "Normal"; }
|
||||||
|
bind "z" { TogglePaneFrames; SwitchToMode "Normal"; }
|
||||||
|
bind "w" { ToggleFloatingPanes; SwitchToMode "Normal"; }
|
||||||
|
bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "Normal"; }
|
||||||
|
bind "c" { SwitchToMode "RenamePane"; PaneNameInput 0;}
|
||||||
|
}
|
||||||
|
move {
|
||||||
|
bind "Ctrl h" { SwitchToMode "Normal"; }
|
||||||
|
bind "n" "Tab" { MovePane; }
|
||||||
|
bind "p" { MovePaneBackwards; }
|
||||||
|
bind "h" "Left" { MovePane "Left"; }
|
||||||
|
bind "j" "Down" { MovePane "Down"; }
|
||||||
|
bind "k" "Up" { MovePane "Up"; }
|
||||||
|
bind "l" "Right" { MovePane "Right"; }
|
||||||
|
}
|
||||||
|
tab {
|
||||||
|
bind "Ctrl t" { SwitchToMode "Normal"; }
|
||||||
|
bind "r" { SwitchToMode "RenameTab"; TabNameInput 0; }
|
||||||
|
bind "h" "Left" "Up" "k" { GoToPreviousTab; }
|
||||||
|
bind "l" "Right" "Down" "j" { GoToNextTab; }
|
||||||
|
bind "n" { NewTab; SwitchToMode "Normal"; }
|
||||||
|
bind "x" { CloseTab; SwitchToMode "Normal"; }
|
||||||
|
bind "s" { ToggleActiveSyncTab; SwitchToMode "Normal"; }
|
||||||
|
bind "1" { GoToTab 1; SwitchToMode "Normal"; }
|
||||||
|
bind "2" { GoToTab 2; SwitchToMode "Normal"; }
|
||||||
|
bind "3" { GoToTab 3; SwitchToMode "Normal"; }
|
||||||
|
bind "4" { GoToTab 4; SwitchToMode "Normal"; }
|
||||||
|
bind "5" { GoToTab 5; SwitchToMode "Normal"; }
|
||||||
|
bind "6" { GoToTab 6; SwitchToMode "Normal"; }
|
||||||
|
bind "7" { GoToTab 7; SwitchToMode "Normal"; }
|
||||||
|
bind "8" { GoToTab 8; SwitchToMode "Normal"; }
|
||||||
|
bind "9" { GoToTab 9; SwitchToMode "Normal"; }
|
||||||
|
bind "Tab" { ToggleTab; }
|
||||||
|
}
|
||||||
|
scroll {
|
||||||
|
bind "Ctrl s" { SwitchToMode "Normal"; }
|
||||||
|
bind "e" { EditScrollback; SwitchToMode "Normal"; }
|
||||||
|
bind "s" { SwitchToMode "EnterSearch"; SearchInput 0; }
|
||||||
|
bind "Ctrl c" { ScrollToBottom; SwitchToMode "Normal"; }
|
||||||
|
bind "j" "Down" { ScrollDown; }
|
||||||
|
bind "k" "Up" { ScrollUp; }
|
||||||
|
bind "Ctrl f" "PageDown" "Right" "l" { PageScrollDown; }
|
||||||
|
bind "Ctrl b" "PageUp" "Left" "h" { PageScrollUp; }
|
||||||
|
bind "d" { HalfPageScrollDown; }
|
||||||
|
bind "u" { HalfPageScrollUp; }
|
||||||
|
// uncomment this and adjust key if using copy_on_select=false
|
||||||
|
// bind "Alt c" { Copy; }
|
||||||
|
}
|
||||||
|
search {
|
||||||
|
bind "Ctrl s" { SwitchToMode "Normal"; }
|
||||||
|
bind "Ctrl c" { ScrollToBottom; SwitchToMode "Normal"; }
|
||||||
|
bind "j" "Down" { ScrollDown; }
|
||||||
|
bind "k" "Up" { ScrollUp; }
|
||||||
|
bind "Ctrl f" "PageDown" "Right" "l" { PageScrollDown; }
|
||||||
|
bind "Ctrl b" "PageUp" "Left" "h" { PageScrollUp; }
|
||||||
|
bind "d" { HalfPageScrollDown; }
|
||||||
|
bind "u" { HalfPageScrollUp; }
|
||||||
|
bind "n" { Search "down"; }
|
||||||
|
bind "p" { Search "up"; }
|
||||||
|
bind "c" { SearchToggleOption "CaseSensitivity"; }
|
||||||
|
bind "w" { SearchToggleOption "Wrap"; }
|
||||||
|
bind "o" { SearchToggleOption "WholeWord"; }
|
||||||
|
}
|
||||||
|
entersearch {
|
||||||
|
bind "Ctrl c" "Esc" { SwitchToMode "Scroll"; }
|
||||||
|
bind "Enter" { SwitchToMode "Search"; }
|
||||||
|
}
|
||||||
|
renametab {
|
||||||
|
bind "Ctrl c" { SwitchToMode "Normal"; }
|
||||||
|
bind "Esc" { UndoRenameTab; SwitchToMode "Tab"; }
|
||||||
|
}
|
||||||
|
renamepane {
|
||||||
|
bind "Ctrl c" { SwitchToMode "Normal"; }
|
||||||
|
bind "Esc" { UndoRenamePane; SwitchToMode "Pane"; }
|
||||||
|
}
|
||||||
|
session {
|
||||||
|
bind "Ctrl o" { SwitchToMode "Normal"; }
|
||||||
|
bind "Ctrl s" { SwitchToMode "Scroll"; }
|
||||||
|
bind "d" { Detach; }
|
||||||
|
}
|
||||||
|
// tmux {
|
||||||
|
// bind "[" { SwitchToMode "Scroll"; }
|
||||||
|
// bind "Ctrl b" { Write 2; SwitchToMode "Normal"; }
|
||||||
|
// bind "\"" { NewPane "Down"; SwitchToMode "Normal"; }
|
||||||
|
// bind "%" { NewPane "Right"; SwitchToMode "Normal"; }
|
||||||
|
// bind "z" { ToggleFocusFullscreen; SwitchToMode "Normal"; }
|
||||||
|
// bind "c" { NewTab; SwitchToMode "Normal"; }
|
||||||
|
// bind "," { SwitchToMode "RenameTab"; }
|
||||||
|
// bind "p" { GoToPreviousTab; SwitchToMode "Normal"; }
|
||||||
|
// bind "n" { GoToNextTab; SwitchToMode "Normal"; }
|
||||||
|
// bind "Left" { MoveFocus "Left"; SwitchToMode "Normal"; }
|
||||||
|
// bind "Right" { MoveFocus "Right"; SwitchToMode "Normal"; }
|
||||||
|
// bind "Down" { MoveFocus "Down"; SwitchToMode "Normal"; }
|
||||||
|
// bind "Up" { MoveFocus "Up"; SwitchToMode "Normal"; }
|
||||||
|
// bind "h" { MoveFocus "Left"; SwitchToMode "Normal"; }
|
||||||
|
// bind "l" { MoveFocus "Right"; SwitchToMode "Normal"; }
|
||||||
|
// bind "j" { MoveFocus "Down"; SwitchToMode "Normal"; }
|
||||||
|
// bind "k" { MoveFocus "Up"; SwitchToMode "Normal"; }
|
||||||
|
// bind "o" { FocusNextPane; }
|
||||||
|
// bind "d" { Detach; }
|
||||||
|
// bind "Space" { NextSwapLayout; }
|
||||||
|
// bind "x" { CloseFocus; SwitchToMode "Normal"; }
|
||||||
|
// }
|
||||||
|
shared_except "locked" {
|
||||||
|
bind "Ctrl g" { SwitchToMode "Locked"; }
|
||||||
|
bind "Ctrl q" { Quit; }
|
||||||
|
bind "Alt n" { NewPane; }
|
||||||
|
bind "Alt h" "Alt Left" { MoveFocusOrTab "Left"; }
|
||||||
|
bind "Alt l" "Alt Right" { MoveFocusOrTab "Right"; }
|
||||||
|
bind "Alt j" "Alt Down" { MoveFocus "Down"; }
|
||||||
|
bind "Alt k" "Alt Up" { MoveFocus "Up"; }
|
||||||
|
bind "Alt =" "Alt +" { Resize "Increase"; }
|
||||||
|
bind "Alt -" { Resize "Decrease"; }
|
||||||
|
bind "Alt [" { PreviousSwapLayout; }
|
||||||
|
bind "Alt ]" { NextSwapLayout; }
|
||||||
|
}
|
||||||
|
shared_except "normal" "locked" {
|
||||||
|
bind "Enter" "Esc" { SwitchToMode "Normal"; }
|
||||||
|
}
|
||||||
|
shared_except "pane" "locked" {
|
||||||
|
bind "Ctrl p" { SwitchToMode "Pane"; }
|
||||||
|
}
|
||||||
|
shared_except "resize" "locked" {
|
||||||
|
bind "Ctrl n" { SwitchToMode "Resize"; }
|
||||||
|
}
|
||||||
|
shared_except "scroll" "locked" {
|
||||||
|
bind "Ctrl s" { SwitchToMode "Scroll"; }
|
||||||
|
}
|
||||||
|
shared_except "session" "locked" {
|
||||||
|
bind "Ctrl o" { SwitchToMode "Session"; }
|
||||||
|
}
|
||||||
|
shared_except "tab" "locked" {
|
||||||
|
bind "Ctrl t" { SwitchToMode "Tab"; }
|
||||||
|
}
|
||||||
|
shared_except "move" "locked" {
|
||||||
|
bind "Ctrl h" { SwitchToMode "Move"; }
|
||||||
|
}
|
||||||
|
// shared_except "tmux" "locked" {
|
||||||
|
// bind "Ctrl b" { SwitchToMode "Tmux"; }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
tab-bar { path "tab-bar"; }
|
||||||
|
status-bar { path "status-bar"; }
|
||||||
|
strider { path "strider"; }
|
||||||
|
compact-bar { path "compact-bar"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
|
||||||
|
// eg. when terminal window with an active zellij session is closed
|
||||||
|
// Options:
|
||||||
|
// - detach (Default)
|
||||||
|
// - quit
|
||||||
|
//
|
||||||
|
// on_force_close "quit"
|
||||||
|
|
||||||
|
// Send a request for a simplified ui (without arrow fonts) to plugins
|
||||||
|
// Options:
|
||||||
|
// - true
|
||||||
|
// - false (Default)
|
||||||
|
//
|
||||||
|
// simplified_ui true
|
||||||
|
|
||||||
|
// Choose the path to the default shell that zellij will use for opening new panes
|
||||||
|
// Default: $SHELL
|
||||||
|
// Change to nushell
|
||||||
|
//
|
||||||
|
default_shell "nu"
|
||||||
|
|
||||||
|
// Toggle between having pane frames around the panes
|
||||||
|
// Options:
|
||||||
|
// - true (default)
|
||||||
|
// - false
|
||||||
|
//
|
||||||
|
// pane_frames true
|
||||||
|
|
||||||
|
// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
|
||||||
|
// Options:
|
||||||
|
// - true (default)
|
||||||
|
// - false
|
||||||
|
//
|
||||||
|
// auto_layout true
|
||||||
|
|
||||||
|
// Define color themes for Zellij
|
||||||
|
// For more examples, see: https://github.com/zellij-org/zellij/tree/main/example/themes
|
||||||
|
// Once these themes are defined, one of them should to be selected in the "theme" section of this file
|
||||||
|
//
|
||||||
|
themes {
|
||||||
|
// https://github.com/zellij-org/zellij/blob/main/zellij-utils/assets/themes/catppuccin.kdl
|
||||||
|
catppuccin-latte {
|
||||||
|
bg "#acb0be" // Surface2
|
||||||
|
fg "#acb0be" // Surface2
|
||||||
|
red "#d20f39"
|
||||||
|
green "#40a02b"
|
||||||
|
blue "#1e66f5"
|
||||||
|
yellow "#df8e1d"
|
||||||
|
magenta "#ea76cb" // Pink
|
||||||
|
orange "#fe640b" // Peach
|
||||||
|
cyan "#04a5e5" // Sky
|
||||||
|
black "#dce0e8" // Crust
|
||||||
|
white "#4c4f69" // Text
|
||||||
|
}
|
||||||
|
|
||||||
|
catppuccin-frappe {
|
||||||
|
bg "#626880" // Surface2
|
||||||
|
fg "#c6d0f5"
|
||||||
|
red "#e78284"
|
||||||
|
green "#a6d189"
|
||||||
|
blue "#8caaee"
|
||||||
|
yellow "#e5c890"
|
||||||
|
magenta "#f4b8e4" // Pink
|
||||||
|
orange "#ef9f76" // Peach
|
||||||
|
cyan "#99d1db" // Sky
|
||||||
|
black "#292c3c" // Mantle
|
||||||
|
white "#c6d0f5"
|
||||||
|
}
|
||||||
|
|
||||||
|
catppuccin-macchiato {
|
||||||
|
bg "#5b6078" // Surface2
|
||||||
|
fg "#cad3f5"
|
||||||
|
red "#ed8796"
|
||||||
|
green "#a6da95"
|
||||||
|
blue "#8aadf4"
|
||||||
|
yellow "#eed49f"
|
||||||
|
magenta "#f5bde6" // Pink
|
||||||
|
orange "#f5a97f" // Peach
|
||||||
|
cyan "#91d7e3" // Sky
|
||||||
|
black "#1e2030" // Mantle
|
||||||
|
white "#cad3f5"
|
||||||
|
}
|
||||||
|
|
||||||
|
catppuccin-mocha {
|
||||||
|
bg "#585b70" // Surface2
|
||||||
|
fg "#cdd6f4"
|
||||||
|
red "#f38ba8"
|
||||||
|
green "#a6e3a1"
|
||||||
|
blue "#89b4fa"
|
||||||
|
yellow "#f9e2af"
|
||||||
|
magenta "#f5c2e7" // Pink
|
||||||
|
orange "#fab387" // Peach
|
||||||
|
cyan "#89dceb" // Sky
|
||||||
|
black "#181825" // Mantle
|
||||||
|
white "#cdd6f4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose the theme that is specified in the themes section.
|
||||||
|
// Default: default
|
||||||
|
//
|
||||||
|
theme "catppuccin-mocha"
|
||||||
|
|
||||||
|
// The name of the default layout to load on startup
|
||||||
|
// Default: "default"
|
||||||
|
//
|
||||||
|
// default_layout "compact"
|
||||||
|
|
||||||
|
// Choose the mode that zellij uses when starting up.
|
||||||
|
// Default: normal
|
||||||
|
//
|
||||||
|
// default_mode "locked"
|
||||||
|
|
||||||
|
// Toggle enabling the mouse mode.
|
||||||
|
// On certain configurations, or terminals this could
|
||||||
|
// potentially interfere with copying text.
|
||||||
|
// Options:
|
||||||
|
// - true (default)
|
||||||
|
// - false
|
||||||
|
//
|
||||||
|
// mouse_mode false
|
||||||
|
|
||||||
|
// Configure the scroll back buffer size
|
||||||
|
// This is the number of lines zellij stores for each pane in the scroll back
|
||||||
|
// buffer. Excess number of lines are discarded in a FIFO fashion.
|
||||||
|
// Valid values: positive integers
|
||||||
|
// Default value: 10000
|
||||||
|
//
|
||||||
|
// scroll_buffer_size 10000
|
||||||
|
|
||||||
|
// Provide a command to execute when copying text. The text will be piped to
|
||||||
|
// the stdin of the program to perform the copy. This can be used with
|
||||||
|
// terminal emulators which do not support the OSC 52 ANSI control sequence
|
||||||
|
// that will be used by default if this option is not set.
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// copy_command "xclip -selection clipboard" // x11
|
||||||
|
// copy_command "wl-copy" // wayland
|
||||||
|
// copy_command "pbcopy" // osx
|
||||||
|
|
||||||
|
// Choose the destination for copied text
|
||||||
|
// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard.
|
||||||
|
// Does not apply when using copy_command.
|
||||||
|
// Options:
|
||||||
|
// - system (default)
|
||||||
|
// - primary
|
||||||
|
//
|
||||||
|
// copy_clipboard "primary"
|
||||||
|
|
||||||
|
// Enable or disable automatic copy (and clear) of selection when releasing mouse
|
||||||
|
// Default: true
|
||||||
|
//
|
||||||
|
// copy_on_select false
|
||||||
|
|
||||||
|
// Path to the default editor to use to edit pane scrollbuffer
|
||||||
|
// Default: $EDITOR or $VISUAL
|
||||||
|
//
|
||||||
|
// scrollback_editor "/usr/bin/vim"
|
||||||
|
|
||||||
|
// When attaching to an existing session with other users,
|
||||||
|
// should the session be mirrored (true)
|
||||||
|
// or should each user have their own cursor (false)
|
||||||
|
// Default: false
|
||||||
|
//
|
||||||
|
// mirror_session true
|
||||||
|
|
||||||
|
// The folder in which Zellij will look for layouts
|
||||||
|
//
|
||||||
|
// layout_dir "/path/to/my/layout_dir"
|
||||||
|
|
||||||
|
// The folder in which Zellij will look for themes
|
||||||
|
//
|
||||||
|
// theme_dir "/path/to/my/theme_dir"
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
let
|
||||||
|
shellAliases = {
|
||||||
|
"zj" = "zellij";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
programs.zellij = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
# auto start zellij in nushell
|
||||||
|
programs.nushell.extraConfig = ''
|
||||||
|
# auto start zellij
|
||||||
|
# except when in emacs or zellij itself
|
||||||
|
if (not ("ZELLIJ" in $env)) and (not ("INSIDE_EMACS" in $env)) {
|
||||||
|
if "ZELLIJ_AUTO_ATTACH" in $env and $env.ZELLIJ_AUTO_ATTACH == "true" {
|
||||||
|
^zellij attach -c
|
||||||
|
} else {
|
||||||
|
^zellij
|
||||||
|
}
|
||||||
|
|
||||||
|
# Auto exit the shell session when zellij exit
|
||||||
|
$env.ZELLIJ_AUTO_EXIT = "false" # disable auto exit
|
||||||
|
if "ZELLIJ_AUTO_EXIT" in $env and $env.ZELLIJ_AUTO_EXIT == "true" {
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# only works in bash/zsh, not nushell
|
||||||
|
home.shellAliases = shellAliases;
|
||||||
|
programs.nushell.shellAliases = shellAliases;
|
||||||
|
|
||||||
|
xdg.configFile."zellij/config.kdl".source = ./config.kdl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
nur-ryan4yin,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# https://github.com/catppuccin/btop/blob/main/themes/catppuccin_mocha.theme
|
||||||
|
xdg.configFile."btop/themes".source = "${nur-ryan4yin.packages.${pkgs.system}.catppuccin-btop}/themes";
|
||||||
|
|
||||||
|
# replacement of htop/nmon
|
||||||
|
programs.btop = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
color_theme = "catppuccin_mocha";
|
||||||
|
theme_background = false; # make btop transparent
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
pkgs-unstable,
|
||||||
|
nur-ryan4yin,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
skopeo
|
||||||
|
docker-compose
|
||||||
|
dive # explore docker layers
|
||||||
|
lazydocker # Docker terminal UI.
|
||||||
|
|
||||||
|
kubectl
|
||||||
|
istioctl
|
||||||
|
kubevirt # virtctl
|
||||||
|
kubernetes-helm
|
||||||
|
fluxcd
|
||||||
|
argocd
|
||||||
|
];
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
k9s = {
|
||||||
|
enable = true;
|
||||||
|
# https://k9scli.io/topics/aliases/
|
||||||
|
# aliases = {};
|
||||||
|
settings = {
|
||||||
|
skin = "catppuccino-mocha";
|
||||||
|
};
|
||||||
|
skins.catppuccin-mocha = let
|
||||||
|
skin_file = "${nur-ryan4yin.packages.${pkgs.system}.catppuccin-k9s}/dist/mocha.yml"; # theme - catppuccin mocha
|
||||||
|
skin_attr = builtins.fromJSON (
|
||||||
|
builtins.readFile
|
||||||
|
# replace 'base: &base "#1e1e2e"' with 'base: &base "default"'
|
||||||
|
# to make fg/bg color transparent. "default" means transparent in k9s skin.
|
||||||
|
(pkgs.runCommandNoCC "get-skin-json" {} ''
|
||||||
|
cat ${skin_file} \
|
||||||
|
| sed -E 's@(base: &base ).+@\1 "default"@g' \
|
||||||
|
| ${pkgs.yj}/bin/yj > $out
|
||||||
|
'')
|
||||||
|
);
|
||||||
|
in
|
||||||
|
skin_attr;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
attic,
|
||||||
|
nur-ryan4yin,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
home.packages = with pkgs;
|
||||||
|
[
|
||||||
|
# Misc
|
||||||
|
tldr
|
||||||
|
cowsay
|
||||||
|
gnupg
|
||||||
|
gnumake
|
||||||
|
|
||||||
|
# Morden cli tools, replacement of grep/sed/...
|
||||||
|
|
||||||
|
# Interactively filter its input using fuzzy searching, not limit to filenames.
|
||||||
|
fzf
|
||||||
|
# search for files by name, faster than find
|
||||||
|
fd
|
||||||
|
# search for files by its content, replacement of grep
|
||||||
|
(ripgrep.override {withPCRE2 = true;})
|
||||||
|
|
||||||
|
# A fast and polyglot tool for code searching, linting, rewriting at large scale
|
||||||
|
# supported languages: only some mainstream languages currently(do not support nix/nginx/yaml/toml/...)
|
||||||
|
ast-grep
|
||||||
|
|
||||||
|
sad # CLI search and replace, just like sed, but with diff preview.
|
||||||
|
yq-go # yaml processer https://github.com/mikefarah/yq
|
||||||
|
just # a command runner like make, but simpler
|
||||||
|
delta # A viewer for git and diff output
|
||||||
|
lazygit # Git terminal UI.
|
||||||
|
hyperfine # command-line benchmarking tool
|
||||||
|
gping # ping, but with a graph(TUI)
|
||||||
|
doggo # DNS client for humans
|
||||||
|
duf # Disk Usage/Free Utility - a better 'df' alternative
|
||||||
|
du-dust # A more intuitive version of `du` in rust
|
||||||
|
ncdu # analyzer your disk usage Interactively, via TUI(replacement of `du`)
|
||||||
|
gdu # disk usage analyzer(replacement of `du`)
|
||||||
|
|
||||||
|
# nix related
|
||||||
|
#
|
||||||
|
# it provides the command `nom` works just like `nix
|
||||||
|
# with more details log output
|
||||||
|
nix-output-monitor
|
||||||
|
hydra-check # check hydra(nix's build farm) for the build status of a package
|
||||||
|
nix-index # A small utility to index nix store paths
|
||||||
|
nix-init # generate nix derivation from url
|
||||||
|
# https://github.com/nix-community/nix-melt
|
||||||
|
nix-melt # A TUI flake.lock viewer
|
||||||
|
# https://github.com/utdemir/nix-tree
|
||||||
|
nix-tree # A TUI to visualize the dependency graph of a nix derivation
|
||||||
|
|
||||||
|
# productivity
|
||||||
|
caddy # A webserver with automatic HTTPS via Let's Encrypt(replacement of nginx)
|
||||||
|
croc # File transfer between computers securely and easily
|
||||||
|
]
|
||||||
|
# self-hosted nix cache server
|
||||||
|
++ lib.optionals pkgs.stdenv.isLinux [attic.packages.${pkgs.system}.attic-client];
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
# A modern replacement for ‘ls’
|
||||||
|
# useful in bash/zsh prompt, not in nushell.
|
||||||
|
eza = {
|
||||||
|
enable = true;
|
||||||
|
enableAliases = false; # do not enable aliases in nushell!
|
||||||
|
git = true;
|
||||||
|
icons = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# a cat(1) clone with syntax highlighting and Git integration.
|
||||||
|
bat = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
pager = "less -FR";
|
||||||
|
theme = "catppuccin-mocha";
|
||||||
|
};
|
||||||
|
themes = {
|
||||||
|
# https://raw.githubusercontent.com/catppuccin/bat/main/Catppuccin-mocha.tmTheme
|
||||||
|
catppuccin-mocha = {
|
||||||
|
src = nur-ryan4yin.packages.${pkgs.system}.catppuccin-bat;
|
||||||
|
file = "Catppuccin-mocha.tmTheme";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# A command-line fuzzy finder
|
||||||
|
fzf = {
|
||||||
|
enable = true;
|
||||||
|
# https://github.com/catppuccin/fzf
|
||||||
|
# catppuccin-mocha
|
||||||
|
colors = {
|
||||||
|
"bg+" = "#313244";
|
||||||
|
"bg" = "#1e1e2e";
|
||||||
|
"spinner" = "#f5e0dc";
|
||||||
|
"hl" = "#f38ba8";
|
||||||
|
"fg" = "#cdd6f4";
|
||||||
|
"header" = "#f38ba8";
|
||||||
|
"info" = "#cba6f7";
|
||||||
|
"pointer" = "#f5e0dc";
|
||||||
|
"marker" = "#f5e0dc";
|
||||||
|
"fg+" = "#cdd6f4";
|
||||||
|
"prompt" = "#cba6f7";
|
||||||
|
"hl+" = "#f38ba8";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# zoxide is a smarter cd command, inspired by z and autojump.
|
||||||
|
# It remembers which directories you use most frequently,
|
||||||
|
# so you can "jump" to them in just a few keystrokes.
|
||||||
|
# zoxide works on all major shells.
|
||||||
|
#
|
||||||
|
# z foo # cd into highest ranked directory matching foo
|
||||||
|
# z foo bar # cd into highest ranked directory matching foo and bar
|
||||||
|
# z foo / # cd into a subdirectory starting with foo
|
||||||
|
#
|
||||||
|
# z ~/foo # z also works like a regular cd command
|
||||||
|
# z foo/ # cd into relative path
|
||||||
|
# z .. # cd one level up
|
||||||
|
# z - # cd into previous directory
|
||||||
|
#
|
||||||
|
# zi foo # cd with interactive selection (using fzf)
|
||||||
|
#
|
||||||
|
# z foo<SPACE><TAB> # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)
|
||||||
|
zoxide = {
|
||||||
|
enable = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Atuin replaces your existing shell history with a SQLite database,
|
||||||
|
# and records additional context for your commands.
|
||||||
|
# Additionally, it provides optional and fully encrypted
|
||||||
|
# synchronisation of your history between machines, via an Atuin server.
|
||||||
|
atuin = {
|
||||||
|
enable = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{mylib, ...}: {
|
||||||
|
imports = mylib.scanPaths ./.;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Editors
|
||||||
|
|
||||||
|
See [desktop/editors/](../../desktop/editors/) for more details.
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{mylib, ...}: {
|
||||||
|
imports = mylib.scanPaths ./.;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.helix = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs = {
|
||||||
|
neovim = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
defaultEditor = true;
|
||||||
|
viAlias = true;
|
||||||
|
vimAlias = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
myvars,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# `programs.git` will generate the config file: ~/.config/git/config
|
||||||
|
# to make git use this config file, `~/.gitconfig` should not exist!
|
||||||
|
#
|
||||||
|
# https://git-scm.com/docs/git-config#Documentation/git-config.txt---global
|
||||||
|
home.activation.removeExistingGitconfig = lib.hm.dag.entryBefore ["checkLinkTargets"] ''
|
||||||
|
rm -f ${config.home.homeDirectory}/.gitconfig
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
lfs.enable = true;
|
||||||
|
|
||||||
|
userName = myvars.userfullname;
|
||||||
|
userEmail = myvars.useremail;
|
||||||
|
|
||||||
|
includes = [
|
||||||
|
{
|
||||||
|
# use diffrent email & name for work
|
||||||
|
path = "~/work/.gitconfig";
|
||||||
|
condition = "gitdir:~/work/";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
extraConfig = {
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
push.autoSetupRemote = true;
|
||||||
|
pull.rebase = true;
|
||||||
|
|
||||||
|
# replace https with ssh
|
||||||
|
url = {
|
||||||
|
"ssh://git@github.com/ryan4yin" = {
|
||||||
|
insteadOf = "https://github.com/ryan4yin";
|
||||||
|
};
|
||||||
|
# "ssh://git@gitlab.com/" = {
|
||||||
|
# insteadOf = "https://gitlab.com/";
|
||||||
|
# };
|
||||||
|
# "ssh://git@bitbucket.com/" = {
|
||||||
|
# insteadOf = "https://bitbucket.com/";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# signing = {
|
||||||
|
# key = "xxx";
|
||||||
|
# signByDefault = true;
|
||||||
|
# };
|
||||||
|
|
||||||
|
# A syntax-highlighting pager in Rust(2019 ~ Now)
|
||||||
|
delta = {
|
||||||
|
enable = true;
|
||||||
|
options = {
|
||||||
|
diff-so-fancy = true;
|
||||||
|
line-numbers = true;
|
||||||
|
true-color = "always";
|
||||||
|
# features => named groups of settings, used to keep related settings organized
|
||||||
|
# features = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
aliases = {
|
||||||
|
# common aliases
|
||||||
|
br = "branch";
|
||||||
|
co = "checkout";
|
||||||
|
st = "status";
|
||||||
|
ls = "log --pretty=format:\"%C(yellow)%h%Cred%d\\\\ %Creset%s%Cblue\\\\ [%cn]\" --decorate";
|
||||||
|
ll = "log --pretty=format:\"%C(yellow)%h%Cred%d\\\\ %Creset%s%Cblue\\\\ [%cn]\" --decorate --numstat";
|
||||||
|
cm = "commit -m"; # commit via `git cm <message>`
|
||||||
|
ca = "commit -am"; # commit all changes via `git ca <message>`
|
||||||
|
dc = "diff --cached";
|
||||||
|
|
||||||
|
amend = "commit --amend -m"; # amend commit message via `git amend <message>`
|
||||||
|
unstage = "reset HEAD --"; # unstage file via `git unstage <file>`
|
||||||
|
merged = "branch --merged"; # list merged(into HEAD) branches via `git merged`
|
||||||
|
unmerged = "branch --no-merged"; # list unmerged(into HEAD) branches via `git unmerged`
|
||||||
|
nonexist = "remote prune origin --dry-run"; # list non-exist(remote) branches via `git nonexist`
|
||||||
|
|
||||||
|
# delete merged branches except master & dev & staging
|
||||||
|
# `!` indicates it's a shell script, not a git subcommand
|
||||||
|
delmerged = ''! git branch --merged | egrep -v "(^\*|main|master|dev|staging)" | xargs git branch -d'';
|
||||||
|
# delete non-exist(remote) branches
|
||||||
|
delnonexist = "remote prune origin";
|
||||||
|
|
||||||
|
# aliases for submodule
|
||||||
|
update = "submodule update --init --recursive";
|
||||||
|
foreach = "submodule foreach";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
_: {
|
||||||
|
# use mirror for pip install
|
||||||
|
xdg.configFile."pip/pip.conf".text = ''
|
||||||
|
[global]
|
||||||
|
index-url = https://mirrors.ustc.edu.cn/pypi/web/simple
|
||||||
|
format = columns
|
||||||
|
'';
|
||||||
|
|
||||||
|
# xdg.configFile."pip/pip.conf".text = ''
|
||||||
|
# [global]
|
||||||
|
# index-url = https://mirrors.bfsu.edu.cn/pypi/web/simple
|
||||||
|
# '';
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
# Nushell Config File
|
||||||
|
#
|
||||||
|
# version = 0.81.1
|
||||||
|
|
||||||
|
# let's define some colors
|
||||||
|
|
||||||
|
# https://github.com/catppuccin/i3/blob/main/themes/catppuccin-mocha
|
||||||
|
let rosewater = "#f5e0dc"
|
||||||
|
let flamingo = "#f2cdcd"
|
||||||
|
let pink = "#f5c2e7"
|
||||||
|
let mauve = "#cba6f7"
|
||||||
|
let red = "#f38ba8"
|
||||||
|
let maroon = "#eba0ac"
|
||||||
|
let peach = "#fab387"
|
||||||
|
let green = "#a6e3a1"
|
||||||
|
let teal = "#94e2d5"
|
||||||
|
let sky = "#89dceb"
|
||||||
|
let sapphire = "#74c7ec"
|
||||||
|
let blue = "#89b4fa"
|
||||||
|
let lavender = "#b4befe"
|
||||||
|
let text = "#cdd6f4"
|
||||||
|
let subtext1 = "#bac2de"
|
||||||
|
let subtext0 = "#a6adc8"
|
||||||
|
let overlay2 = "#9399b2"
|
||||||
|
let overlay1 = "#7f849c"
|
||||||
|
let overlay0 = "#6c7086"
|
||||||
|
let surface2 = "#585b70"
|
||||||
|
let surface1 = "#45475a"
|
||||||
|
let surface0 = "#313244"
|
||||||
|
let base = "#1e1e2e"
|
||||||
|
let mantle = "#181825"
|
||||||
|
let crust = "#11111b"
|
||||||
|
|
||||||
|
# we're creating a theme here that uses the colors we defined above.
|
||||||
|
|
||||||
|
let catppuccin_theme = {
|
||||||
|
separator: $overlay2
|
||||||
|
leading_trailing_space_bg: $surface2
|
||||||
|
header: $red
|
||||||
|
date: $pink
|
||||||
|
filesize: $green
|
||||||
|
row_index: $text
|
||||||
|
bool: $peach
|
||||||
|
int: $red
|
||||||
|
duration: $sky
|
||||||
|
range: $sapphire
|
||||||
|
float: $lavender
|
||||||
|
string: $text
|
||||||
|
nothing: $overlay1
|
||||||
|
binary: $subtext1
|
||||||
|
cellpath: $subtext0
|
||||||
|
hints: dark_gray
|
||||||
|
|
||||||
|
shape_garbage: { fg: $overlay2 bg: $red attr: b}
|
||||||
|
shape_bool: $maroon
|
||||||
|
shape_int: { fg: $pink attr: b}
|
||||||
|
shape_float: { fg: $pink attr: b}
|
||||||
|
shape_range: { fg: $overlay0 attr: b}
|
||||||
|
shape_internalcall: { fg: $maroon attr: b}
|
||||||
|
shape_external: $mauve
|
||||||
|
shape_externalarg: { fg: $red attr: b}
|
||||||
|
shape_literal: $flamingo
|
||||||
|
shape_operator: $rosewater
|
||||||
|
shape_signature: { fg: $red attr: b}
|
||||||
|
shape_string: $red
|
||||||
|
shape_filepath: $peach
|
||||||
|
shape_globpattern: { fg: $teal attr: b}
|
||||||
|
shape_variable: $pink
|
||||||
|
shape_flag: { fg: $mauve attr: b}
|
||||||
|
shape_custom: {attr: b}
|
||||||
|
}
|
||||||
|
|
||||||
|
# The default config record. This is where much of your global configuration is setup.
|
||||||
|
$env.config = {
|
||||||
|
color_config: $catppuccin_theme # <-- this is the theme
|
||||||
|
use_ansi_coloring: true
|
||||||
|
|
||||||
|
# true or false to enable or disable the welcome banner at startup
|
||||||
|
show_banner: false
|
||||||
|
|
||||||
|
table: {
|
||||||
|
mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
|
||||||
|
index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column
|
||||||
|
show_empty: true # show 'empty list' and 'empty record' placeholders for command output
|
||||||
|
trim: {
|
||||||
|
methodology: wrapping # wrapping or truncating
|
||||||
|
wrapping_try_keep_words: true # A strategy used by the 'wrapping' methodology
|
||||||
|
truncating_suffix: "..." # A suffix used by the 'truncating' methodology
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completions: {
|
||||||
|
case_sensitive: false # set to true to enable case-sensitive completions
|
||||||
|
quick: true # set this to false to prevent auto-selecting completions when only one remains
|
||||||
|
partial: true # set this to false to prevent partial filling of the prompt
|
||||||
|
algorithm: "prefix" # prefix or fuzzy
|
||||||
|
external: {
|
||||||
|
enable: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up may be very slow
|
||||||
|
max_results: 100 # setting it lower can improve completion performance at the cost of omitting some options
|
||||||
|
completer: null # check 'carapace_completer' above as an example
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filesize: {
|
||||||
|
metric: true # true => KB, MB, GB (ISO standard), false => KiB, MiB, GiB (Windows standard)
|
||||||
|
format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
|
||||||
|
}
|
||||||
|
cursor_shape: {
|
||||||
|
emacs: line # block, underscore, line, blink_block, blink_underscore, blink_line (line is the default)
|
||||||
|
vi_insert: block # block, underscore, line , blink_block, blink_underscore, blink_line (block is the default)
|
||||||
|
vi_normal: underscore # block, underscore, line, blink_block, blink_underscore, blink_line (underscore is the default)
|
||||||
|
}
|
||||||
|
use_grid_icons: true
|
||||||
|
footer_mode: "25" # always, never, number_of_rows, auto
|
||||||
|
float_precision: 2 # the precision for displaying floats in tables
|
||||||
|
# buffer_editor: "emacs" # command that will be used to edit the current line buffer with ctrl+o, if unset fallback to $env.EDITOR and $env.VISUAL
|
||||||
|
bracketed_paste: true # enable bracketed paste, currently useless on windows
|
||||||
|
edit_mode: emacs # emacs, vi
|
||||||
|
shell_integration: true # enables terminal markers and a workaround to arrow keys stop working issue
|
||||||
|
render_right_prompt_on_last_line: false # true or false to enable or disable right prompt to be rendered on last line of the prompt.
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
let
|
||||||
|
shellAliases = {
|
||||||
|
k = "kubectl";
|
||||||
|
|
||||||
|
urldecode = "python3 -c 'import sys, urllib.parse as ul; print(ul.unquote_plus(sys.stdin.read()))'";
|
||||||
|
urlencode = "python3 -c 'import sys, urllib.parse as ul; print(ul.quote_plus(sys.stdin.read()))'";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
# only works in bash/zsh, not nushell
|
||||||
|
home.shellAliases = shellAliases;
|
||||||
|
|
||||||
|
programs.nushell = {
|
||||||
|
enable = true;
|
||||||
|
configFile.source = ./config.nu;
|
||||||
|
inherit shellAliases;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.bash = {
|
||||||
|
enable = true;
|
||||||
|
enableCompletion = true;
|
||||||
|
bashrcExtra = ''
|
||||||
|
export PATH="$HOME/.local/bin:$HOME/go/bin:$PATH"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
nur-ryan4yin,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
programs.starship = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
|
||||||
|
settings =
|
||||||
|
{
|
||||||
|
character = {
|
||||||
|
success_symbol = "[›](bold green)";
|
||||||
|
error_symbol = "[›](bold red)";
|
||||||
|
};
|
||||||
|
aws = {
|
||||||
|
symbol = "🅰 ";
|
||||||
|
};
|
||||||
|
gcloud = {
|
||||||
|
# do not show the account/project's info
|
||||||
|
# to avoid the leak of sensitive information when sharing the terminal
|
||||||
|
format = "on [$symbol$active(\($region\))]($style) ";
|
||||||
|
symbol = "🅶 ️";
|
||||||
|
};
|
||||||
|
|
||||||
|
palette = "catppuccin_mocha";
|
||||||
|
}
|
||||||
|
// builtins.fromTOML (builtins.readFile "${nur-ryan4yin.packages.${pkgs.system}.catppuccin-starship}/palettes/mocha.toml");
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
pkgs-unstable,
|
||||||
|
nur-ryan4yin,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# terminal file manager
|
||||||
|
programs.yazi = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs-unstable.yazi;
|
||||||
|
# Changing working directory when exiting Yazi
|
||||||
|
enableBashIntegration = true;
|
||||||
|
# TODO: nushellIntegration is broken on release-23.11, wait for master's fix to be released
|
||||||
|
enableNushellIntegration = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."yazi/theme.toml".source = "${nur-ryan4yin.packages.${pkgs.system}.catppuccin-yazi}/mocha.toml";
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
let
|
||||||
|
shellAliases = {
|
||||||
|
"zj" = "zellij";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
programs.zellij = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
# only works in bash/zsh, not nushell
|
||||||
|
home.shellAliases = shellAliases;
|
||||||
|
programs.nushell.shellAliases = shellAliases;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Home Manager's Darwin Submodules
|
||||||
|
|
||||||
|
1. `core.nix`: some basic configuration.
|
||||||
|
2. `shell.nix`: shell related.
|
||||||
|
3. `rime-squirrel.nix`: [rime-squirrel](https://github.com/rime/squirrel)'s configuration.
|
||||||
|
4. `default.nix`: the entrypoint of darwin's configuration, it import all the submodules above.
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{myvars, ...}: {
|
||||||
|
home.homeDirectory = "/Users/${myvars.username}";
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{mylib, ...}: {
|
||||||
|
imports =
|
||||||
|
(mylib.scanPaths ./.)
|
||||||
|
++ [
|
||||||
|
../base/server
|
||||||
|
../base/desktop
|
||||||
|
../base/core.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
clash-meta
|
||||||
|
];
|
||||||
|
home.file.".proxychains/proxychains.conf".source = ./proxychains.conf;
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
|
||||||
|
# proxychains.conf VER 4.x
|
||||||
|
#
|
||||||
|
# HTTP, SOCKS4a, SOCKS5 tunneling proxifier with DNS.
|
||||||
|
|
||||||
|
|
||||||
|
# The option below identifies how the ProxyList is treated.
|
||||||
|
# only one option should be uncommented at time,
|
||||||
|
# otherwise the last appearing option will be accepted
|
||||||
|
#
|
||||||
|
#dynamic_chain
|
||||||
|
#
|
||||||
|
# Dynamic - Each connection will be done via chained proxies
|
||||||
|
# all proxies chained in the order as they appear in the list
|
||||||
|
# at least one proxy must be online to play in chain
|
||||||
|
# (dead proxies are skipped)
|
||||||
|
# otherwise EINTR is returned to the app
|
||||||
|
#
|
||||||
|
strict_chain
|
||||||
|
#
|
||||||
|
# Strict - Each connection will be done via chained proxies
|
||||||
|
# all proxies chained in the order as they appear in the list
|
||||||
|
# all proxies must be online to play in chain
|
||||||
|
# otherwise EINTR is returned to the app
|
||||||
|
#
|
||||||
|
#round_robin_chain
|
||||||
|
#
|
||||||
|
# Round Robin - Each connection will be done via chained proxies
|
||||||
|
# of chain_len length
|
||||||
|
# all proxies chained in the order as they appear in the list
|
||||||
|
# at least one proxy must be online to play in chain
|
||||||
|
# (dead proxies are skipped).
|
||||||
|
# the start of the current proxy chain is the proxy after the last
|
||||||
|
# proxy in the previously invoked proxy chain.
|
||||||
|
# if the end of the proxy chain is reached while looking for proxies
|
||||||
|
# start at the beginning again.
|
||||||
|
# otherwise EINTR is returned to the app
|
||||||
|
# These semantics are not guaranteed in a multithreaded environment.
|
||||||
|
#
|
||||||
|
#random_chain
|
||||||
|
#
|
||||||
|
# Random - Each connection will be done via random proxy
|
||||||
|
# (or proxy chain, see chain_len) from the list.
|
||||||
|
# this option is good to test your IDS :)
|
||||||
|
|
||||||
|
# Make sense only if random_chain or round_robin_chain
|
||||||
|
#chain_len = 2
|
||||||
|
|
||||||
|
# Quiet mode (no output from library)
|
||||||
|
#quiet_mode
|
||||||
|
|
||||||
|
## Proxy DNS requests - no leak for DNS data
|
||||||
|
# (disable all of the 3 items below to not proxy your DNS requests)
|
||||||
|
|
||||||
|
# method 1. this uses the proxychains4 style method to do remote dns:
|
||||||
|
# a thread is spawned that serves DNS requests and hands down an ip
|
||||||
|
# assigned from an internal list (via remote_dns_subnet).
|
||||||
|
# this is the easiest (setup-wise) and fastest method, however on
|
||||||
|
# systems with buggy libcs and very complex software like webbrowsers
|
||||||
|
# this might not work and/or cause crashes.
|
||||||
|
proxy_dns
|
||||||
|
|
||||||
|
# method 2. use the old proxyresolv script to proxy DNS requests
|
||||||
|
# in proxychains 3.1 style. requires `proxyresolv` in $PATH
|
||||||
|
# plus a dynamically linked `dig` binary.
|
||||||
|
# this is a lot slower than `proxy_dns`, doesn't support .onion URLs,
|
||||||
|
# but might be more compatible with complex software like webbrowsers.
|
||||||
|
#proxy_dns_old
|
||||||
|
|
||||||
|
# method 3. use proxychains4-daemon process to serve remote DNS requests.
|
||||||
|
# this is similar to the threaded `proxy_dns` method, however it requires
|
||||||
|
# that proxychains4-daemon is already running on the specified address.
|
||||||
|
# on the plus side it doesn't do malloc/threads so it should be quite
|
||||||
|
# compatible with complex, async-unsafe software.
|
||||||
|
# note that if you don't start proxychains4-daemon before using this,
|
||||||
|
# the process will simply hang.
|
||||||
|
#proxy_dns_daemon 127.0.0.1:1053
|
||||||
|
|
||||||
|
# set the class A subnet number to use for the internal remote DNS mapping
|
||||||
|
# we use the reserved 224.x.x.x range by default,
|
||||||
|
# if the proxified app does a DNS request, we will return an IP from that range.
|
||||||
|
# on further accesses to this ip we will send the saved DNS name to the proxy.
|
||||||
|
# in case some control-freak app checks the returned ip, and denies to
|
||||||
|
# connect, you can use another subnet, e.g. 10.x.x.x or 127.x.x.x.
|
||||||
|
# of course you should make sure that the proxified app does not need
|
||||||
|
# *real* access to this subnet.
|
||||||
|
# i.e. dont use the same subnet then in the localnet section
|
||||||
|
#remote_dns_subnet 127
|
||||||
|
#remote_dns_subnet 10
|
||||||
|
remote_dns_subnet 224
|
||||||
|
|
||||||
|
# Some timeouts in milliseconds
|
||||||
|
tcp_read_time_out 15000
|
||||||
|
tcp_connect_time_out 8000
|
||||||
|
|
||||||
|
### Examples for localnet exclusion
|
||||||
|
## localnet ranges will *not* use a proxy to connect.
|
||||||
|
## note that localnet works only when plain IP addresses are passed to the app,
|
||||||
|
## the hostname resolves via /etc/hosts, or proxy_dns is disabled or proxy_dns_old used.
|
||||||
|
|
||||||
|
## Exclude connections to 192.168.1.0/24 with port 80
|
||||||
|
# localnet 192.168.1.0:80/255.255.255.0
|
||||||
|
|
||||||
|
## Exclude connections to 192.168.100.0/24
|
||||||
|
# localnet 192.168.100.0/255.255.255.0
|
||||||
|
|
||||||
|
## Exclude connections to ANYwhere with port 80
|
||||||
|
# localnet 0.0.0.0:80/0.0.0.0
|
||||||
|
# localnet [::]:80/0
|
||||||
|
|
||||||
|
## RFC6890 Loopback address range
|
||||||
|
## if you enable this, you have to make sure remote_dns_subnet is not 127
|
||||||
|
## you'll need to enable it if you want to use an application that
|
||||||
|
## connects to localhost.
|
||||||
|
# localnet 127.0.0.0/255.0.0.0
|
||||||
|
# localnet ::1/128
|
||||||
|
|
||||||
|
## RFC1918 Private Address Ranges
|
||||||
|
# localnet 10.0.0.0/255.0.0.0
|
||||||
|
# localnet 172.16.0.0/255.240.0.0
|
||||||
|
# localnet 192.168.0.0/255.255.0.0
|
||||||
|
|
||||||
|
### Examples for dnat
|
||||||
|
## Trying to proxy connections to destinations which are dnatted,
|
||||||
|
## will result in proxying connections to the new given destinations.
|
||||||
|
## Whenever I connect to 1.1.1.1 on port 1234 actually connect to 1.1.1.2 on port 443
|
||||||
|
# dnat 1.1.1.1:1234 1.1.1.2:443
|
||||||
|
|
||||||
|
## Whenever I connect to 1.1.1.1 on port 443 actually connect to 1.1.1.2 on port 443
|
||||||
|
## (no need to write :443 again)
|
||||||
|
# dnat 1.1.1.2:443 1.1.1.2
|
||||||
|
|
||||||
|
## No matter what port I connect to on 1.1.1.1 port actually connect to 1.1.1.2 on port 443
|
||||||
|
# dnat 1.1.1.1 1.1.1.2:443
|
||||||
|
|
||||||
|
## Always, instead of connecting to 1.1.1.1, connect to 1.1.1.2
|
||||||
|
# dnat 1.1.1.1 1.1.1.2
|
||||||
|
|
||||||
|
# ProxyList format
|
||||||
|
# type ip port [user pass]
|
||||||
|
# (values separated by 'tab' or 'blank')
|
||||||
|
#
|
||||||
|
# only numeric ipv4 addresses are valid
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# socks5 192.168.67.78 1080 lamer secret
|
||||||
|
# http 192.168.89.3 8080 justu hidden
|
||||||
|
# socks4 192.168.1.49 1080
|
||||||
|
# http 192.168.39.93 8080
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# proxy types: http, socks4, socks5, raw
|
||||||
|
# * raw: The traffic is simply forwarded to the proxy without modification.
|
||||||
|
# ( auth types supported: "basic"-http "user/pass"-socks )
|
||||||
|
#
|
||||||
|
[ProxyList]
|
||||||
|
# add proxy here ...
|
||||||
|
# set to clash's http/socks5 port
|
||||||
|
socks5 127.0.0.1 7890
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
# Squirrel Input Method
|
||||||
|
home.file."Library/Rime" = {
|
||||||
|
# my custom squirrel data (flypy input method)
|
||||||
|
source = "${pkgs.flypy-squirrel}/share/rime-data";
|
||||||
|
recursive = true;
|
||||||
|
# overwrite possible existing data dynamically generated by squirrel
|
||||||
|
# https://github.com/nix-community/home-manager/blob/release-23.05/modules/lib/file-type.nix#L101-L111
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
let
|
||||||
|
envExtra = ''
|
||||||
|
export PATH="$PATH:/opt/homebrew/bin:/usr/local/bin"
|
||||||
|
'';
|
||||||
|
# copied from the content generated by `conda init bash`
|
||||||
|
initExtra = ''
|
||||||
|
arch=$(uname -m)
|
||||||
|
|
||||||
|
if [ "aarch64" = "$arch" ] || [ "arm64" = "$arch" ]; then
|
||||||
|
# >>> (miniforge)conda initialize >>>
|
||||||
|
# !! Contents within this block are managed by 'conda init' !!
|
||||||
|
if [ -f "/opt/homebrew/Caskroom/miniforge/base/etc/profile.d/conda.sh" ]; then
|
||||||
|
. "/opt/homebrew/Caskroom/miniforge/base/etc/profile.d/conda.sh"
|
||||||
|
else
|
||||||
|
export PATH="/opt/homebrew/Caskroom/miniforge/base/bin:$PATH"
|
||||||
|
fi
|
||||||
|
# <<< conda initialize <<<
|
||||||
|
elif [[ "x86_64" = "$arch" ]]; then
|
||||||
|
# do nothing
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
# Homebrew's default install location:
|
||||||
|
# /opt/homebrew for Apple Silicon
|
||||||
|
# /usr/local for macOS Intel
|
||||||
|
# The prefix /opt/homebrew was chosen to allow installations
|
||||||
|
# in /opt/homebrew for Apple Silicon and /usr/local for Rosetta 2 to coexist and use bottles.
|
||||||
|
programs.bash = {
|
||||||
|
enable = true;
|
||||||
|
bashrcExtra = envExtra + initExtra;
|
||||||
|
};
|
||||||
|
programs.zsh = {
|
||||||
|
enable = true;
|
||||||
|
inherit envExtra initExtra;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{myvars, ...}: {
|
||||||
|
programs.ssh.extraConfig = myvars.networking.ssh.extraConfig;
|
||||||
|
}
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
{pkgs, config, lib, ... }: {
|
|
||||||
|
|
||||||
home.file.".config/fcitx5/profile".source = ./profile;
|
|
||||||
home.file.".config/fcitx5/profile-bak".source = ./profile; # used for backup
|
|
||||||
# fcitx5 每次切换输入法,就会修改 ~/.config/fcitx5/profile 文件,导致我用 hm 管理的配置被覆盖
|
|
||||||
# 解决方法是通过如下内置,每次 rebuild 前都先删除下 profile 文件
|
|
||||||
home.activation.removeExistingFcitx5Profile = lib.hm.dag.entryBefore ["checkLinkTargets"] ''
|
|
||||||
rm -f "${config.xdg.configHome}/fcitx5/profile"
|
|
||||||
'';
|
|
||||||
|
|
||||||
i18n.inputMethod = {
|
|
||||||
enabled = "fcitx5";
|
|
||||||
fcitx5.addons = with pkgs; [
|
|
||||||
# for flypy chinese input method
|
|
||||||
fcitx5-rime
|
|
||||||
# needed enable rime using configtool after installed
|
|
||||||
fcitx5-configtool
|
|
||||||
fcitx5-chinese-addons
|
|
||||||
# fcitx5-mozc # japanese input method
|
|
||||||
fcitx5-gtk # gtk im module
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.sessionVariables = {
|
|
||||||
# copy from https://github.com/nix-community/home-manager/blob/master/modules/i18n/input-method/fcitx5.nix
|
|
||||||
GLFW_IM_MODULE = "fcitx";
|
|
||||||
GTK_IM_MODULE = "fcitx";
|
|
||||||
QT_IM_MODULE = "fcitx";
|
|
||||||
XMODIFIERS = "@im=fcitx";
|
|
||||||
INPUT_METHOD = "fcitx";
|
|
||||||
IMSETTINGS_MODULE = "fcitx";
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
# hyprland configs, based on https://github.com/notwidow/hyprland
|
|
||||||
home.file.".config/hypr" = {
|
|
||||||
source = ./hypr-conf;
|
|
||||||
# copy the scripts directory recursively
|
|
||||||
recursive = true;
|
|
||||||
};
|
|
||||||
home.file.".config/gtk-3.0" = {
|
|
||||||
source = ./gtk-3.0;
|
|
||||||
recursive = true;
|
|
||||||
};
|
|
||||||
home.file.".gtkrc-2.0".source = ./gtkrc-2.0;
|
|
||||||
home.file.".config/hypr/wallpapers/wallpaper.png".source = ../wallpapers/wallpaper.png;
|
|
||||||
|
|
||||||
# allow fontconfig to discover fonts and configurations installed through home.packages
|
|
||||||
fonts.fontconfig.enable = true;
|
|
||||||
|
|
||||||
systemd.user.sessionVariables = {
|
|
||||||
"NIXOS_OZONE_WL" = "1"; # for any ozone-based browser & electron apps to run on wayland
|
|
||||||
"MOZ_ENABLE_WAYLAND" = "1"; # for firefox to run on wayland
|
|
||||||
"MOZ_WEBRENDER" = "1";
|
|
||||||
|
|
||||||
# for hyprland with nvidia gpu, ref https://wiki.hyprland.org/Nvidia/
|
|
||||||
"LIBVA_DRIVER_NAME" = "nvidia";
|
|
||||||
"XDG_SESSION_TYPE" = "wayland";
|
|
||||||
"GBM_BACKEND" = "nvidia-drm";
|
|
||||||
"__GLX_VENDOR_LIBRARY_NAME" = "nvidia";
|
|
||||||
"WLR_NO_HARDWARE_CURSORS" = "1";
|
|
||||||
"WLR_EGL_NO_MODIFIRES" = "1";
|
|
||||||
};
|
|
||||||
|
|
||||||
# set cursor size and dpi for 4k monitor
|
|
||||||
# this is for xwayland
|
|
||||||
xresources.properties = {
|
|
||||||
"Xcursor.size" = 16;
|
|
||||||
"Xft.dpi" = 160;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
[Settings]
|
|
||||||
gtk-theme-name=Arc-Dark
|
|
||||||
gtk-icon-theme-name=Qogir-dark
|
|
||||||
gtk-font-name=Noto Sans 10
|
|
||||||
gtk-cursor-theme-name=Qogir-dark
|
|
||||||
gtk-cursor-theme-size=0
|
|
||||||
gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ
|
|
||||||
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
|
|
||||||
gtk-button-images=0
|
|
||||||
gtk-menu-images=0
|
|
||||||
gtk-enable-event-sounds=1
|
|
||||||
gtk-enable-input-feedback-sounds=1
|
|
||||||
gtk-xft-antialias=1
|
|
||||||
gtk-xft-hinting=1
|
|
||||||
gtk-xft-hintstyle=hintmedium
|
|
||||||
gtk-xft-rgba=rgb
|
|
||||||