diff --git a/checks/default.nix b/checks/default.nix index d4de7c0..1ea5427 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -17,13 +17,13 @@ projectRootFile = ".git/config"; programs = { nixfmt-rfc-style.enable = true; - deadnix.enable = true; + deadnix.enable = false; }; }; pre-commit.settings.hooks = { nixfmt-rfc-style.enable = true; - deadnix.enable = true; + deadnix.enable = false; }; }; diff --git a/flake.lock b/flake.lock index 1168cce..3833c5c 100644 --- a/flake.lock +++ b/flake.lock @@ -23,11 +23,11 @@ }, "catppuccin": { "locked": { - "lastModified": 1726952185, - "narHash": "sha256-l/HbsQjJMT6tlf8KCooFYi3J6wjIips3n6/aWAoLY4g=", + "lastModified": 1730036420, + "narHash": "sha256-rv2bz7J6Wo7AenPiu4+ptCB1AFyaMcS77y89zbRAtI8=", "owner": "catppuccin", "repo": "nix", - "rev": "630b559cc1cb4c0bdd525af506935323e4ccd5d1", + "rev": "0b7bf04628414a402d255924f65e9a0d1a53d92b", "type": "github" }, "original": { @@ -37,18 +37,12 @@ } }, "crane": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ] - }, "locked": { - "lastModified": 1721842668, - "narHash": "sha256-k3oiD2z2AAwBFLa4+xfU+7G5fisRXfkvrMTCJrjZzXo=", + "lastModified": 1730060262, + "narHash": "sha256-RMgSVkZ9H03sxC+Vh4jxtLTCzSjPq18UWpiM0gq6shQ=", "owner": "ipetkov", "repo": "crane", - "rev": "529c1a0b1f29f0d78fa3086b8f6a134c71ef3aaf", + "rev": "498d9f122c413ee1154e8131ace5a35a80d8fa76", "type": "github" }, "original": { @@ -86,11 +80,11 @@ ] }, "locked": { - "lastModified": 1727156717, - "narHash": "sha256-Ef7UgoTdOB4PGQKSkHGu6SOxnTiArPHGcRf8qGFC39o=", + "lastModified": 1730190761, + "narHash": "sha256-o5m5WzvY6cGIDupuOvjgNSS8AN6yP2iI9MtUC6q/uos=", "owner": "nix-community", "repo": "disko", - "rev": "c61e50b63ad50dda5797b1593ad7771be496efbb", + "rev": "3979285062d6781525cded0f6c4ff92e71376b55", "type": "github" }, "original": { @@ -106,11 +100,11 @@ "pyproject-nix": "pyproject-nix" }, "locked": { - "lastModified": 1726523340, - "narHash": "sha256-Av5mdR2lAGUVdA6DJ8Anon3/FZg3DX4gl1Ff72rCpKU=", + "lastModified": 1729932741, + "narHash": "sha256-Ko3a3hWt7CbVn9Db0/Tj9zln3bB/CMIhlQsP92mUejU=", "owner": "nix-community", "repo": "dream2nix", - "rev": "b76c529f377100516c40c5b6e239a4525fdcabe0", + "rev": "7acdae705dcc79f307e752f749a9f513a0ed9b83", "type": "github" }, "original": { @@ -119,6 +113,26 @@ "type": "github" } }, + "emacs-overlay": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_3", + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1730362724, + "narHash": "sha256-vCBIFtcplEBhogZseFycQNowdSDETH65HJxOuap2WSs=", + "owner": "nix-community", + "repo": "emacs-overlay", + "rev": "620e6fc31925817272633f9f5a4245feac41e1f1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "emacs-overlay", + "type": "github" + } + }, "fan-control": { "flake": false, "locked": { @@ -167,6 +181,22 @@ "type": "github" } }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-parts": { "inputs": { "nixpkgs-lib": [ @@ -175,11 +205,11 @@ ] }, "locked": { - "lastModified": 1719994518, - "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=", + "lastModified": 1727826117, + "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7", + "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", "type": "github" }, "original": { @@ -267,6 +297,24 @@ "inputs": { "systems": "systems_3" }, + "locked": { + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_4" + }, "locked": { "lastModified": 1681202837, "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", @@ -286,11 +334,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1726153070, - "narHash": "sha256-HO4zgY0ekfwO5bX0QH/3kJ/h4KvUDFZg8YpkNwIbg1U=", + "lastModified": 1727826117, + "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "bcef6817a8b2aa20a5a6dbb19b43e63c5bf8619a", + "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", "type": "github" }, "original": { @@ -316,19 +364,19 @@ }, "git-hooks-nix": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": "flake-compat_2", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable" + "nixpkgs-stable": "nixpkgs-stable_2" }, "locked": { - "lastModified": 1726745158, - "narHash": "sha256-D5AegvGoEjt4rkKedmxlSEmC+nNLMBPWFxvmYnVLhjk=", + "lastModified": 1730302582, + "narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "4e743a6920eab45e8ba0fbe49dc459f1423a4b74", + "rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf", "type": "github" }, "original": { @@ -383,7 +431,7 @@ "hercules-ci-effects": { "inputs": { "flake-parts": "flake-parts_3", - "nixpkgs": "nixpkgs_4" + "nixpkgs": "nixpkgs_6" }, "locked": { "lastModified": 1701009247, @@ -448,11 +496,11 @@ ] }, "locked": { - "lastModified": 1727111745, - "narHash": "sha256-EYLvFRoTPWtD+3uDg2wwQvlz88OrIr3zld+jFE5gDcY=", + "lastModified": 1730016908, + "narHash": "sha256-bFCxJco7d8IgmjfNExNz9knP8wvwbXU4s/d53KOK6U0=", "owner": "nix-community", "repo": "home-manager", - "rev": "21c021862fa696c8199934e2153214ab57150cb6", + "rev": "e83414058edd339148dc142a8437edb9450574c8", "type": "github" }, "original": { @@ -484,11 +532,11 @@ }, "impermanence": { "locked": { - "lastModified": 1727198257, - "narHash": "sha256-/qMVI+SG9zvhLbQFOnqb4y4BH6DdK3DQHZU5qGptehc=", + "lastModified": 1729068498, + "narHash": "sha256-C2sGRJl1EmBq0nO98TNd4cbUy20ABSgnHWXLIJQWRFA=", "owner": "nix-community", "repo": "impermanence", - "rev": "8514fff0f048557723021ffeb31ca55f69b67de3", + "rev": "e337457502571b23e449bf42153d7faa10c0a562", "type": "github" }, "original": { @@ -517,7 +565,7 @@ "lanzaboote": { "inputs": { "crane": "crane", - "flake-compat": "flake-compat_2", + "flake-compat": "flake-compat_3", "flake-parts": "flake-parts", "nixpkgs": [ "nixpkgs" @@ -526,11 +574,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1725379389, - "narHash": "sha256-qS1H/5/20ewJIXmf8FN2A5KTOKKU9elWvCPwdBi1P/U=", + "lastModified": 1730107060, + "narHash": "sha256-EnVVq1oNcimZmQYl6UlLYs0jhC6aLah0bsFMy2syEak=", "owner": "nix-community", "repo": "lanzaboote", - "rev": "e7bd94e0b5ff3c1e686f2101004ebf4fcea9d871", + "rev": "0ad4ce46649b390da8bebcc229917f9863c98fe2", "type": "github" }, "original": { @@ -542,11 +590,11 @@ "lix": { "flake": false, "locked": { - "lastModified": 1726905313, - "narHash": "sha256-jsOyXonevsNaKxM9burYc2S4JVle+VMCJ8+AAp0MDCc=", + "lastModified": 1730328739, + "narHash": "sha256-qs7u2nCwfEV93SKV1QSikOwRbHDEA1CWYZiVKI9Hhxk=", "ref": "refs/heads/main", - "rev": "5f298f74c92402a8390b01c736463b17b36277e3", - "revCount": 16254, + "rev": "beb193d1e2121cdbd51e8309572522ee9a841395", + "revCount": 16432, "type": "git", "url": "https://git@git.lix.systems/lix-project/lix" }, @@ -557,7 +605,7 @@ }, "lix-module": { "inputs": { - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "flakey-profile": "flakey-profile", "lix": [ "lix" @@ -567,11 +615,11 @@ ] }, "locked": { - "lastModified": 1726631249, - "narHash": "sha256-b2rMO8+jKjY55d8uynX7FjV4NIPu/WzPux0kWOAzwoo=", + "lastModified": 1727752861, + "narHash": "sha256-jowmo2aEzrEpPSM96IWtajuogdJm7DjAWxFTEb7Ct0s=", "ref": "refs/heads/main", - "rev": "b0e6f359500d66670cc16f521e4f62d6a0a4864e", - "revCount": 110, + "rev": "fd186f535a4ac7ae35d98c1dd5d79f0a81b7976d", + "revCount": 116, "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module" }, @@ -583,11 +631,11 @@ "mobile-nixos": { "flake": false, "locked": { - "lastModified": 1726960027, - "narHash": "sha256-BJe+6Gpqu98Mhi1oAfrJK25SZvvQgfYqpmLaXvXgQ9g=", + "lastModified": 1730307383, + "narHash": "sha256-EJYo2VPXVMGQbY+bI4Xav14fXXioBt3KICtXNI6i76o=", "owner": "NixOS", "repo": "mobile-nixos", - "rev": "a386813d9ec46fa32e51488f7d48c0e1bde77f8e", + "rev": "0516be85630befa2c1e8042ac873342ce186b2f6", "type": "github" }, "original": { @@ -626,7 +674,7 @@ "inputs": { "home-manager": "home-manager_2", "nix-formatter-pack": "nix-formatter-pack", - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_4", "nixpkgs-docs": "nixpkgs-docs", "nixpkgs-for-bootstrap": "nixpkgs-for-bootstrap", "nmd": "nmd" @@ -647,16 +695,14 @@ }, "nixDarwin": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ] + "nixpkgs": "nixpkgs_5" }, "locked": { - "lastModified": 1727003835, - "narHash": "sha256-Cfllbt/ADfO8oxbT984MhPHR6FJBaglsr1SxtDGbpec=", + "lastModified": 1730184279, + "narHash": "sha256-6OB+WWR6gnaWiqSS28aMJypKeK7Pjc2Wm6L0MtOrTuA=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "bd7d1e3912d40f799c5c0f7e5820ec950f1e0b3d", + "rev": "b379bd4d872d159e5189053ce9a4adf86d56db4b", "type": "github" }, "original": { @@ -675,27 +721,26 @@ "osx-kvm": "osx-kvm" }, "locked": { - "lastModified": 1708168451, - "narHash": "sha256-loWlwexnfQGFsEHeJbXpWbnmeDFkBwZB38+4BkUcGhM=", - "owner": "aciceri", + "lastModified": 1727105240, + "narHash": "sha256-FEuqbcZ4TDUMwCpTA/E3J5L7pLD4U+zXPnZbmXSmaJo=", + "owner": "MatthewCroughan", "repo": "NixThePlanet", - "rev": "e8c91035d01f5082ccf30e351dcd993a5b480a72", + "rev": "2f622af217807da78e44a5a15f620743dac57f46", "type": "github" }, "original": { - "owner": "aciceri", - "ref": "nix-in-darwin", + "owner": "MatthewCroughan", "repo": "NixThePlanet", "type": "github" } }, "nixosHardware": { "locked": { - "lastModified": 1727040444, - "narHash": "sha256-19FNN5QT9Z11ZUMfftRplyNN+2PgcHKb3oq8KMW/hDA=", + "lastModified": 1730368399, + "narHash": "sha256-F8vJtG389i9fp3k2/UDYHMed3PLCJYfxCqwiVP7b9ig=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "d0cb432a9d28218df11cbd77d984a2a46caeb5ac", + "rev": "da14839ac5f38ee6adbdb4e6db09b5eef6d6ccdc", "type": "github" }, "original": { @@ -770,14 +815,14 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1725233747, - "narHash": "sha256-Ss8QWLXdr2JCBPcYChJhz4xJm+h/xjl4G0c0XlP6a74=", + "lastModified": 1727825735, + "narHash": "sha256-0xHYkMkeLVQAMa7gvkddbPqpxph+hDzdu1XdGPJR+Os=", "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz" + "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" }, "original": { "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/356624c12086a18f2ea2825fed34523d60ccc4e3.tar.gz" + "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" } }, "nixpkgs-lib_2": { @@ -818,11 +863,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1720386169, - "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", + "lastModified": 1730137625, + "narHash": "sha256-9z8oOgFZiaguj+bbi3k4QhAD6JabWrnv7fscC/mt0KE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", + "rev": "64b80bfb316b57cdb8919a9110ef63393d74382a", "type": "github" }, "original": { @@ -848,13 +893,29 @@ "type": "github" } }, - "nixpkgs_2": { + "nixpkgs-stable_3": { "locked": { - "lastModified": 1720181791, - "narHash": "sha256-i4vJL12/AdyuQuviMMd1Hk2tsGt02hDNhA0Zj1m16N8=", + "lastModified": 1720386169, + "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4284c2b73c8bce4b46a6adf23e16d9e2ec8da4bb", + "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1729850857, + "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "41dea55321e5a999b17033296ac05fe8a8b5a257", "type": "github" }, "original": { @@ -865,6 +926,22 @@ } }, "nixpkgs_3": { + "locked": { + "lastModified": 1730200266, + "narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { "locked": { "lastModified": 1708172716, "narHash": "sha256-3M94oln0b61m3dUmLyECCA9hYAHXZEszM4saE3CmQO4=", @@ -879,7 +956,21 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_5": { + "locked": { + "lastModified": 1718149104, + "narHash": "sha256-Ds1QpobBX2yoUDx9ZruqVGJ/uQPgcXoYuobBguyKEh8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e913ae340076bbb73d9f4d3d065c2bca7caafb16", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_6": { "locked": { "lastModified": 1697723726, "narHash": "sha256-SaTWPkI8a5xSHX/rrKzUe+/uVNy6zCGMXgoeMb7T9rg=", @@ -895,13 +986,13 @@ "type": "github" } }, - "nixpkgs_5": { + "nixpkgs_7": { "locked": { - "lastModified": 1726937504, - "narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=", + "lastModified": 1730200266, + "narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9357f4f23713673f310988025d9dc261c20e70c6", + "rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd", "type": "github" }, "original": { @@ -911,7 +1002,7 @@ "type": "github" } }, - "nixpkgs_6": { + "nixpkgs_8": { "locked": { "lastModified": 1678470307, "narHash": "sha256-OEeMUr3ueLIXyW/OaFUX5jUdimyQwMg/7e+/Q0gC/QE=", @@ -927,7 +1018,7 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_9": { "locked": { "lastModified": 1682134069, "narHash": "sha256-TnI/ZXSmRxQDt2sjRYK/8j8iha4B4zP2cnQCZZ3vp7k=", @@ -1022,14 +1113,14 @@ "lanzaboote", "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable_2" + "nixpkgs-stable": "nixpkgs-stable_3" }, "locked": { - "lastModified": 1721042469, - "narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=", + "lastModified": 1729104314, + "narHash": "sha256-pZRZsq5oCdJt3upZIU4aslS9XwFJ+/nVtALHIciX/BI=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "f451c19376071a90d8c58ab1a953c6e9840527fd", + "rev": "3c3e88f0f544d6bb54329832616af7eb971b6be6", "type": "github" }, "original": { @@ -1040,6 +1131,7 @@ }, "purescript-overlay": { "inputs": { + "flake-compat": "flake-compat", "nixpkgs": [ "dream2nix", "nixpkgs" @@ -1047,11 +1139,11 @@ "slimlock": "slimlock" }, "locked": { - "lastModified": 1696022621, - "narHash": "sha256-eMjFmsj2G1E0Q5XiibUNgFjTiSz0GxIeSSzzVdoN730=", + "lastModified": 1728546539, + "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", "owner": "thomashoneyman", "repo": "purescript-overlay", - "rev": "047c7933abd6da8aa239904422e22d190ce55ead", + "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", "type": "github" }, "original": { @@ -1082,7 +1174,7 @@ "fan-control": "fan-control", "flake-parts": "flake-parts_4", "kernel-src": "kernel-src", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_8", "nixpkgs-kernel": "nixpkgs-kernel", "panfork": "panfork", "tow-boot": "tow-boot", @@ -1108,6 +1200,7 @@ "catppuccin": "catppuccin", "disko": "disko", "dream2nix": "dream2nix", + "emacs-overlay": "emacs-overlay", "flakeParts": "flakeParts", "git-hooks-nix": "git-hooks-nix", "homeManager": "homeManager", @@ -1121,7 +1214,7 @@ "nixDarwin": "nixDarwin", "nixThePlanet": "nixThePlanet", "nixosHardware": "nixosHardware", - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_7", "rock5b": "rock5b", "treefmt-nix": "treefmt-nix_2", "vscode-server": "vscode-server" @@ -1135,11 +1228,11 @@ ] }, "locked": { - "lastModified": 1722219664, - "narHash": "sha256-xMOJ+HW4yj6e69PvieohUJ3dBSdgCfvI0nnCEe6/yVc=", + "lastModified": 1729996302, + "narHash": "sha256-QEU1NQq1+7s1na69Chig9K0iDDTKN0O4Zreo9A9rccA=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "a6fbda5d9a14fb5f7c69b8489d24afeb349c7bb4", + "rev": "a1b337569f334ff0a01b57627f17b201d746d24c", "type": "github" }, "original": { @@ -1173,11 +1266,11 @@ ] }, "locked": { - "lastModified": 1688610262, - "narHash": "sha256-Wg0ViDotFWGWqKIQzyYCgayeH8s4U1OZcTiWTQYdAp4=", + "lastModified": 1688756706, + "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", "owner": "thomashoneyman", "repo": "slimlock", - "rev": "b5c6cdcaf636ebbebd0a1f32520929394493f1a6", + "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", "type": "github" }, "original": { @@ -1231,6 +1324,21 @@ "type": "github" } }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "tow-boot": { "flake": false, "locked": { @@ -1276,11 +1384,11 @@ ] }, "locked": { - "lastModified": 1727098951, - "narHash": "sha256-gplorAc0ISAUPemUNOnRUs7jr3WiLiHZb3DJh++IkZs=", + "lastModified": 1730321837, + "narHash": "sha256-vK+a09qq19QNu2MlLcvN4qcRctJbqWkX7ahgPZ/+maI=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "35dfece10c642eb52928a48bee7ac06a59f93e9a", + "rev": "746901bb8dba96d154b66492a29f5db0693dbfcc", "type": "github" }, "original": { @@ -1291,15 +1399,15 @@ }, "vscode-server": { "inputs": { - "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_7" + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_9" }, "locked": { - "lastModified": 1713958148, - "narHash": "sha256-8PDNi/dgoI2kyM7uSiU4eoLBqUKoA+3TXuz+VWmuCOc=", + "lastModified": 1729422940, + "narHash": "sha256-DlvJv33ml5UTKgu4b0HauOfFIoDx6QXtbqUF3vWeRCY=", "owner": "nix-community", "repo": "nixos-vscode-server", - "rev": "fc900c16efc6a5ed972fb6be87df018bcf3035bc", + "rev": "8b6db451de46ecf9b4ab3d01ef76e59957ff549f", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 001eca4..72b2a1f 100644 --- a/flake.nix +++ b/flake.nix @@ -30,12 +30,11 @@ }; dream2nix.url = "github:nix-community/dream2nix"; nixThePlanet = { - url = "github:aciceri/NixThePlanet/nix-in-darwin"; + url = "github:MatthewCroughan/NixThePlanet/"; inputs.nixpkgs.follows = "nixpkgs"; }; nixDarwin = { url = "github:LnL7/nix-darwin"; - inputs.nixpkgs.follows = "nixpkgs"; }; nix-on-droid.url = "github:nix-community/nix-on-droid"; lix = { @@ -58,6 +57,7 @@ inputs.nixpkgs.follows = "nixpkgs"; }; catppuccin.url = "github:catppuccin/nix"; + emacs-overlay.url = "github:nix-community/emacs-overlay"; }; outputs = diff --git a/hmModules/catppuccin/default.nix b/hmModules/catppuccin/default.nix index 7b00ca9..4d485ac 100644 --- a/hmModules/catppuccin/default.nix +++ b/hmModules/catppuccin/default.nix @@ -10,30 +10,4 @@ platformTheme.name = lib.mkForce "kvantum"; style.name = lib.mkForce "kvantum"; }; - - # TODO move away - programs.alacritty = { - enable = true; - settings = { - font = { - normal = { - family = "Fira Code"; - style = "Regular"; - }; - bold = { - family = "Fira Code"; - style = "Bold"; - }; - italic = { - family = "Cascadia Code"; - style = "Italic"; - }; - bold_italic = { - family = "Fira Code"; - style = "Bold Italic"; - }; - size = 13; - }; - }; - }; } diff --git a/hmModules/emacs/default.nix b/hmModules/emacs/default.nix index 98463cc..e8bdebf 100644 --- a/hmModules/emacs/default.nix +++ b/hmModules/emacs/default.nix @@ -1,10 +1,73 @@ { lib, + fleetFlake, + pkgs, age, ... }: +let + emacs = fleetFlake.packages.${pkgs.system}.emacs; + inherit (emacs.passthru) treesitGrammars; +in { - ccrEmacs.enable = true; - home.sessionVariables.EDITOR = lib.mkForce "emacsclient"; - systemd.user.services.emacs.Service.EnvironmentFile = age.secrets.chatgpt-token.path; + systemd.user.sessionVariables = { + EDITOR = lib.mkForce "emacsclient -c"; + OPENAI_API_KEY_PATH = age.secrets.chatgpt-token.path; + }; + programs.emacs = { + enable = true; + package = emacs; + }; + services.emacs = { + enable = true; + client.enable = true; + defaultEditor = true; + socketActivation.enable = false; + startWithUserSession = true; + package = emacs; + }; + home.packages = + with pkgs; + [ + binutils + delta + (ripgrep.override { withPCRE2 = true; }) + gnutls + fd + hunspell + python3 + imagemagick + ghostscript_headless + mupdf-headless + poppler_utils + ffmpegthumbnailer + mediainfo + unzipNLS + nodejs_20 + pkgs.qadwaitadecorations + pkgs.kdePackages.qtwayland + ] + ++ (with hunspellDicts; [ + en_US-large + it_IT + ]); + home.activation = { + cloneCcrEmacsFlake = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + PATH=$PATH:${ + lib.makeBinPath ( + with pkgs; + [ + git + openssh + ] + ) + } + if [ ! -d "$HOME/.config/emacs" ]; then + mkdir "$HOME/.config/emacs" + $DRY_RUN_CMD ln -s "$HOME/projects/aciceri/nixfleet/hmModules/emacs/init.el" "$HOME/.config/emacs/init.el" + $DRY_RUN_CMD ln -s "$HOME/.config/emacs" "$HOME/emacs" + fi + $DRY_RUN_CMD ln -sfn ${treesitGrammars} "$HOME/.config/emacs/tree-sitter" + ''; + }; } diff --git a/hmModules/emacs/init.el b/hmModules/emacs/init.el new file mode 100644 index 0000000..e630922 --- /dev/null +++ b/hmModules/emacs/init.el @@ -0,0 +1,943 @@ +;; package --- My Emacs config -*- lexical-binding:t -*- +;; Author: Andrea Ciceri +;;; Commentary: +;; TODO +;; - org-roam +;; - org goodies +;; - persp-mode? +;; - understand how to configure cape +;;; Code: + + +(use-package flymake + :config + ;; TODO write "E", "W" or "N" in margins overriding the margin created by diff-hl + ;; (push `(before-string . ,(propertize " " 'display '((margin left-margin) "E"))) (get :error 'flymake-overlay-control)) + ;; (push `(before-string . ,(propertize " " 'display '((margin left-margin) "W"))) (get :warning 'flymake-overlay-control)) + ;; (push `(before-string . ,(propertize " " 'display '((margin left-margin) "N"))) (get :note 'flymake-overlay-control)) + ;; TODO set following only when on terminal (where wavy underlines are not shown) + ;; (set-face-attribute 'flymake-error nil :inverse-video t) + ;; (set-face-attribute 'flymake-warning nil :inverse-video t) + ;; (set-face-attribute 'flymake-note nil :inverse-video t) + :custom + (flymake-mode-line-lighter "Fly") + :hook prog-mode) + +(use-package eglot + :custom + ;; Tricks that should make Emacs faster + (eglot-events-buffer-size 0) ; disable events logging, it should be enabled only when debuggigng LSP servers + (eglot-sync-connect-nil 0) ; disable UI freeze when opening big files + (eglot-connect-timeout nil) ; never timeout + ) + +(use-package consult-eglot + :after (consult eglot embark) + :config + (require 'consult-eglot-embark) + (consult-eglot-embark-mode) + ) + +(use-package emacs + :bind (("" . scroll-down-line) + ("" . scroll-up-line) + (("C-x F" . recentf-open))) + :hook (server-after-make-frame . (lambda () (xterm-mouse-mode +1))) ;; FIXME why is this needed? + :custom + (use-dialog-box nil) + (use-short-answers t) + (native-comp-async-report-warnings-errors nil) + (inhibit-startup-message t) + (visible-bell t) + (scroll-conservatively 101) ;; more than 100 => redisplay doesn't recenter point) + (scroll-margin 3) + (temporary-file-directory "~/.emacs-saves/") + (backup-directory-alist `(("." . ,temporary-file-directory))) + (auto-save-files-name-transforms `((".*" ,temporary-file-directory t))) + (backup-by-copying t) + (focus-follows-mouse t) + (mouse-autoselect-window t) + (treesit-font-lock-level 4) + :config + (set-face-background 'vertical-border (face-background 'default)) + (set-display-table-slot standard-display-table 'vertical-border (make-glyph-code ?┃)) + (menu-bar-mode -1) + (scroll-bar-mode -1) + (xterm-mouse-mode +1) + (tool-bar-mode -1) + (global-hl-line-mode -1) + (global-auto-revert-mode t) + (show-paren-mode +1) + (column-number-mode +1) + (add-to-list 'default-frame-alist '(font . "Iosevka Comfy-13")) + (recentf-mode +1) + (fset #'jsonrpc--log-event #'ignore) ; this should be enabled only when needed, otherwise makes Emacs slower + (setq save-interprogram-paste-before-kill 't) ; system clipboard will be saved in the kill ring + (defun ccr/reload-emacs () + (interactive) + (load-file "~/.config/emacs/init.el")) + (load-theme 'catppuccin 't) + (defun ccr/nixos-rebuild () + (interactive) + (let* ((operation (completing-read "nixos-rebuild " '("switch" "boot" "test" "dry-activate"))) + (buffer-name (format "nixos-rebuild-%s" operation))) + (async-shell-command (format "sudo nixos-rebuild --flake fleet %s -L" operation) buffer-name))) + ) + +(use-package doc-view + :custom + (doc-view-scale-internally nil) + (doc-view-imenu-enabled 't) + (doc-view-continuous t)) + +(use-package tramp + :config + ;; TODO ugly `ccr' hardcoded, moreover this makes sense only when connecting to NixOS machines + (add-to-list 'tramp-remote-path "/home/ccr/.nix-profile/bin" 't) + (add-to-list 'tramp-remote-path "/etc/profiles/per-user/ccr/bin" 't) + (add-to-list 'tramp-remote-path "/run/current-system/sw/bin" 't) + (add-to-list 'tramp-remote-path 'tramp-own-remote-path) + :custom + (tramp-use-ssh-controlmaster-options nil) ;; makes tramp use ~/.ssh/config + ) + +(use-package ligature + :config + (ligature-set-ligatures 't '("www")) + (ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi")) + (ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "" "---" "-<<" + "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->" + "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "" "###" "#_(" "..<" + "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~=" + "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|" + "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:" + ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:" + "<$" "<=" "<>" "<-" "<<" "<+" "" "++" "?:" + "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)" + "\\\\" "://")) + (global-ligature-mode t)) + +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) + +(use-package clipetty + :delight + :ensure t + :hook (after-init . global-clipetty-mode)) + +(use-package nerd-icons) + +(use-package nerd-icons-completion + :after marginalia + :config (nerd-icons-completion-mode +1) + :hook ( + (marginalia-mode . nerd-icons-completion-marginalia-setup) + (ibuffer-mode . nerd-icons-completion-marginalia-setup))) + +(use-package nerd-icons-ibuffer + :hook (ibuffer-mode . nerd-icons-ibuffer-mode)) + +(use-package treemacs-nerd-icons + :config + (treemacs-load-theme "nerd-icons")) + +(use-package nerd-icons-dired + :hook + (dired-mode . nerd-icons-dired-mode)) + +(use-package indent-bars + :config + (require 'indent-bars-ts) + :custom + (indent-bars-treesit-support t) + (indent-bars-spacing-override 2) + ;; (indent-bars-treesit-wrap '()) + (indent-bars-color-by-depth '(:regexp "outline-\\([0-9]+\\)" :blend 0.4)) + (indent-bars-no-stipple-char (string-to-char "┋")) + (indent-bars-prefer-character 't) ;; so it works also in terminal +) + +(use-package diredfl + :config (diredfl-global-mode)) + +(use-package treemacs + :after solaire-mode + :custom + (treemacs-show-cursor nil) + (treemacs-display-current-project-exclusively t) + (treemacs-project-followlinto-home nil) + (treemacs-display-current-project-exclusively t) + (treemacs-git-mode 'deferred) + :bind (("C-c w t" . treemacs-select-window) + ("C-c o T" . treemacs)) + ) + +(use-package meow + :hook (server-after-make-frame . (lambda () (meow--prepare-face))) + :custom + (meow-use-clipboard 't) + :config + (add-hook 'after-make-frame-functions (defun ccr/meow--prepare-face (_) + (meow--prepare-face) + (remove-hook 'after-make-frame-functions 'ccr/meow--prepare-face))) + (add-to-list 'meow-mode-state-list '(eshell-mode . insert)) + (add-to-list 'meow-mode-state-list '(eat-mode . insert)) + (add-to-list 'meow-mode-state-list '(notmuch-hello-mode . insert)) + (add-to-list 'meow-mode-state-list '(notmuch-search-mode . insert)) + :init + (meow-global-mode 1) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("" . ignore)) + (meow-leader-define-key + ;; SPC j/k will run the original command in MOTION state. + '("j" . "H-j") + '("k" . "H-k") + ;; Use SPC (0-9) for digit arguments. + '("1" . meow-digit-argument) + '("2" . meow-digit-argument) + '("3" . meow-digit-argument) + '("4" . meow-digit-argument) + '("5" . meow-digit-argument) + '("6" . meow-digit-argument) + '("7" . meow-digit-argument) + '("8" . meow-digit-argument) + '("9" . meow-digit-argument) + '("0" . meow-digit-argument) + '("/" . meow-keypad-describe-key) + '("?" . meow-cheatsheet)) + (meow-normal-define-key + '("0" . meow-expand-0) + '("9" . meow-expand-9) + '("8" . meow-expand-8) + '("7" . meow-expand-7) + '("6" . meow-expand-6) + '("5" . meow-expand-5) + '("4" . meow-expand-4) + '("3" . meow-expand-3) + '("2" . meow-expand-2) + '("1" . meow-expand-1) + '("-" . negative-argument) + '(";" . meow-reverse) + '("," . meow-inner-of-thing) + '("." . meow-bounds-of-thing) + '("[" . meow-beginning-of-thing) + '("]" . meow-end-of-thing) + '(">" . indent-rigidly-right) + '("<" . indent-rigidly-left) + '("a" . meow-append) + '("A" . meow-open-below) + '("b" . meow-back-word) + '("B" . meow-back-symbol) + '("c" . meow-change) + '("d" . meow-delete) + '("D" . meow-backward-delete) + '("e" . meow-next-word) + '("E" . meow-next-symbol) + '("f" . meow-find) + '("g" . meow-cancel-selection) + '("G" . meow-grab) + '("h" . meow-left) + '("H" . meow-left-expand) + '("i" . meow-insert) + '("I" . meow-open-above) + '("j" . meow-next) + '("J" . meow-next-expand) + '("k" . meow-prev) + '("K" . meow-prev-expand) + '("l" . meow-right) + '("L" . meow-right-expand) + '("m" . meow-join) + '("n" . meow-search) + '("o" . meow-block) + '("O" . meow-to-block) + '("p" . meow-yank) + '("q" . meow-quit) + '("Q" . meow-goto-line) + '("r" . meow-replace) + '("R" . meow-swap-grab) + '("s" . meow-kill) + '("t" . meow-till) + '("u" . meow-undo) + '("U" . meow-undo-in-selection) + '("/" . meow-visit) + '("v" . meow-visit) + '("w" . meow-mark-word) + '("W" . meow-mark-symbol) + '("x" . meow-line) + '("X" . meow-goto-line) + '("y" . meow-save) + '("Y" . meow-sync-grab) + '("z" . meow-pop-selection) + '("'" . repeat) + '("" . ignore))) + + +(use-package windmove + :config + (windmove-mode +1) + (defcustom ccr/v-resize-amount 4 + "How smany rows move when calling `ccr/v-resize`" + :type 'integer + :group 'ccr) + (defcustom ccr/h-resize-amount 4 + "How many columns move when calling `ccr/h-resize`" + :type 'integer + :group 'ccr + ) + (defun ccr/v-resize (key) + "Interactively vertically resize the window" + (interactive "cHit >/< to enlarge/shrink") + (cond ((eq key (string-to-char ">")) + (enlarge-window-horizontally ccr/v-resize-amount) + (call-interactively 'ccr/v-resize)) + ((eq key (string-to-char "<")) + (enlarge-window-horizontally (- ccr/v-resize-amount)) + (call-interactively 'ccr/v-resize)) + (t (push key unread-command-events)))) + (defun ccr/h-resize (key) + "Interactively horizontally resize the window" + (interactive "cHit >/< to enlarge/shrink") + (cond ((eq key (string-to-char ">")) + (enlarge-window ccr/h-resize-amount) + (call-interactively 'ccr/h-resize)) + ((eq key (string-to-char "<")) + (enlarge-window (- ccr/h-resize-amount)) + (call-interactively 'ccr/h-resize)) + (t (push key unread-command-events)))) + :bind (("C-c w k" . windmove-up) + ("C-c w l" . windmove-right) + ("C-c w j" . windmove-down) + ("C-c w h" . windmove-left) + ("M-k" . windmove-up) + ("M-l" . windmove-right) + ("M-j" . windmove-down) + ("M-h" . windmove-left) + ("C-c w " . windmove-up) + ("C-c w " . windmove-right) + ("C-c w " . windmove-down) + ("C-c w " . windmove-left) + ("C-c w q" . delete-window) + ("C-c w K" . windmove-delete-up) + ("C-c w L" . windmove-delete-right) + ("C-c w J" . windmove-delete-down) + ("C-c w H" . windmove-delete-left) + ("C-c w x" . kill-buffer-and-window) + ("C-c w v" . split-window-right) + ("C-c w s" . split-window-below) + ("C-c w V" . ccr/v-resize) + ("C-c w S" . ccr/h-resize))) + +(use-package vertico + :custom + (vertico-mouse-mode t) + ;; (vertico-reverse-mode t) ;; FIXME breaks vertico-posframe + (vertico-count 16) + (vertico-resize t) + (vertico-cycle t) + (vertico-mode t) + :bind (:map vertico-map + (("DEL" . vertico-directory-delete-char) + ("C-DEL" . vertico-directory-delete-word)))) + +;; (use-package vertico-posframe +;; :after vertico +;; :config +;; (vertico-posframe-mode +1) +;; :custom +;; (vertico-multiform-commands +;; '((t +;; posframe +;; (vertico-posframe-poshandler . posframe-poshandler-frame-center) +;; (vertico-posframe-fallback-mode . vertico-buffer-mode)))) +;; (vertico-posframe-min-height 1) +;; ;; (vertico-posframe-min-width 80) +;; (vertico-posframe-parameters '((alpha-background . 80))) +;; ) + +(use-package marginalia + :init + (marginalia-mode +1) + :custom + (marginalia-aligh 'right)) + +(use-package consult + :bind (([remap switch-to-buffer] . consult-buffer) + ([remap goto-line] . consult-goto-line) + ([remazp imenu] . consult-imenu) + ([remap project-switch-to-buffer] . consult-project-buffer) + ("C-c b b" . consult-project-buffer) + ("C-c b B" . consult-buffer) + ("C-c g l" . consult-goto-line) + ("C-c b i" . consult-imenu) + ("C-c f f" . consult-find) + ("C-c F" . consult-ripgrep) + ("C-c f" . consult-find) + ("C-c l" . consult-line) + ("C-c m" . wconsult-mark) + ("C-c o o" . consult-outline) + ("C-c e" . consult-flymake)) + :custom + (xref-show-xrefs-function #'consult-xref) + (xref-show-definitions-function #'consult-xref)) + +(use-package orderless + :custom + (completion-styles '(orderless))) + +(use-package embark + :bind (("C-'" . embark-act) + ("C-=" . embark-dwim))) + +(use-package corfu + :config + (corfu-terminal-mode) + (corfu-popupinfo-mode) + (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter) + :custom + (completion-cycle-threshold nil) + (tab-always-indent 'complete) + (kind-icon-default-face 'corfu-default) + :bind (:map corfu-map + (("M-d" . corfu-doc-toggle) + ("M-l" . corfu-show-location) + ("SPC" . corfu-insert-separator))) + :init + (global-corfu-mode)) + +(use-package cape + :config + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file)) + +(use-package prog-mode + :hook ((prog-mode . hl-line-mode) + (prog-mode . display-line-numbers-mode))) + +(use-package which-key :delight :config + (which-key-mode) + (which-key-setup-side-window-right)) + +(use-package magit + :bind (("C-c o g" . magit))) + +(use-package magit-delta + :hook (magit-mode . magit-delta-mode)) + +;; FIXME +;; (use-package magit-todos +;; :after magit +;; :custom (magit-todos-keyword-suffix "\\(?:([^)]+)\\)?:?") +;; :config (magit-todos-mode 1)) + +(use-package difftastic + :demand t + :bind (:map magit-blame-read-only-mode-map + ("D" . difftastic-magit-show) + ("S" . difftastic-magit-show)) + :config + (eval-after-load 'magit-diff + '(transient-append-suffix 'magit-diff '(-1 -1) + [("D" "Difftastic diff (dwim)" difftastic-magit-diff) + ("S" "Difftastic show" difftastic-magit-show)]))) + +;; FIXME there is something deeply wrong about how nix is configured here +;; (use-package nix-mode +;; :delight nix-prettify-mode +;; :config +;; (global-nix-prettify-mode)) + +(use-package agenix + :after envrc + :hook (agenix-pre-mode . envrc-mode)) + +(use-package nix-ts-mode + :hook ( + (nix-ts-mode . (lambda () + (require 'eglot) + (add-to-list 'eglot-server-programs + '(nix-ts-mode . ("nixd"))) + (eglot-ensure))) + (nix-ts-mode . electric-pair-mode) + (nix-ts-mode . (lambda () (setq-local indent-bars-spacing-override 2) (indent-bars-mode))) + (nix-ts-mode . (lambda () + (setq-local + treesit-font-lock-settings + (append treesit-font-lock-settings + (treesit-font-lock-rules + :language 'nix + :feature 'function + :override t + `((formal) @font-lock-type-face) + + :language 'nix + :feature 'function + `((attrpath) @font-lock-function-name-face) + ))))) + ) + :mode "\\.nix\\'" + ) + +(use-package dockerfile-ts-mode + :mode "Dockerfile\\'") + +(use-package python-ts-mode + :hook ((python-ts-mode . (lambda () + (require 'eglot) + (add-to-list 'eglot-server-programs + '(python-ts-mode . ("jedi-language-server"))) + (eglot-ensure)))) + :mode "\\.py\\'") + +(use-package typescript-ts-mode + :hook ((typescript-ts-mode . (lambda () + (require 'eglot) + (eglot-ensure)))) + :mode "\\.ts\\'") + +(use-package haskell-ts-mode + :hook ((haskell--ts-mode . eglot-ensure)) + :mode "\\.hs\\'" + :config + (add-to-list 'eglot-server-programs + '(haskell-ts-mode . ("haskell-language-server-wrapper" "--lsp")))) + +(use-package purescript-mode + :custom ((project-vc-extra-root-markers '("spago.dhall"))) + :hook ((purescript-mode . eglot-ensure) + (purescript-mode . turn-on-purescript-indentation) + (purescript-mode . (lambda () (setq project-vc-extra-root-markers '("spago.dhall")))))) + +(use-package terraform-mode + :after eglot + :config + (add-to-list 'eglot-server-programs + '(terraform-mode . ("terraform-lsp"))) + :hook ((terraform-mode . eglot-ensure) + ;; (terraform-mode . tree-sitter-hl-mode) + (terraform-mode . (lambda () (setq indent-bars-spacing-override 2) (indent-bars-mode))) + )) + +(use-package yaml-mode + :hook (yaml-mode . tree-sitter-hl-mode)) + +(use-package sh-mode + :hook (sh-mode . tree-sitter-hl-mode)) + +;; FIXME +;; (use-package mmm-mode +;; :config +;; (mmm-add-group 'nix-sh +;; '((sh-command +;; :submode sh-mode +;; :face mmm-output-submode-face +;; :front "[^'a-zA-Z]''[^']" +;; :back "''[^$\\']" +;; :include-front t +;; :front-offset 4 +;; :end-not-begin t))) +;; (mmm-add-mode-ext-class 'nix-mode "\\.nix\\'" 'nix-sh)) + +(use-package paredit + :delight + :hook ((lisp-mode . enable-paredit-mode) + (emacs-lisp-mode . enable-paredit-mode))) + +(use-package eldoc + :delight) + +(use-package eldoc-box + :after eglot + :custom + (eldoc-box-only-multiline nil) + (eldoc-box-lighter "ElBox") + :bind (("C-c h" . eldoc-box-help-at-point))) + + (use-package diff-hl + :init + (global-diff-hl-mode 1) + (diff-hl-margin-mode 1)) + +(use-package envrc + :config + (envrc-global-mode +1)) + +(use-package hl-todo + :init + (global-hl-todo-mode)) + +(use-package eat + :init + ;; FIXME if we not load eat on startup then adding more non bound keys in :config + ;; will a cause "nesting exceeds `max-lisp-eval-depth'" on (eat-reload) + (eat) + :custom + (eat-kill-buffer-on-exit t) + :config + (add-to-list 'eat-semi-char-non-bound-keys '[?\e 104]) ; M-h + (add-to-list 'eat-semi-char-non-bound-keys '[?\e 106]) ; M-j + (add-to-list 'eat-semi-char-non-bound-keys '[?\e 107]) ; M-k + (add-to-list 'eat-semi-char-non-bound-keys '[?\e 108]) ; M-l + (eat-update-semi-char-mode-map) + (eat-reload) + :hook (eat-mode . (lambda () (setq-local scroll-margin 0))) + :bind (("C-c o t" . eat-project)) + ;; FIXME doesn't work well + ;; ((eat-mode . compilation-shell-minor-mode)) + ) + +(use-package eshell + :init (require 'eshell) ;; this slows down Emacs startup but it's needed when starting eshell with + ;; emacsclient --eval before opening another eshell buffer directly from inside Emacs + (eat-eshell-mode) + (eat-eshell-visual-command-mode) + :custom ((eshell-prefer-lisp-functions t) + (eshell-history-size 10000)) + :config + (defun ccr/start-eshell () ;; Used from outside Emacs by emacsclient --eval + (eshell 'N) + (add-hook 'kill-buffer-hook 'delete-frame nil 't)) ;; destroy frame on exit + + ;; Wrapping this in order to merge histories from different shells + ;; (advice-add 'eshell-write-history + ;; :around #'ccr/wrap-eshell-write-history) + + (add-to-list 'eshell-modules-list 'eshell-tramp) ;; to use sudo in eshell + ;; (add-to-list 'eshell-modules-list 'eshell-smart) ;; plan 9 style + + (setq ccr/eshell-aliases + '((g . magit) + (gl . magit-log) + (d . dired) + (o . find-file) + (oo . find-file-other-window) + (l . (lambda () (eshell/ls '-la))) + (eshell/clear . eshell/clear-scrollback))) + + (mapc (lambda (alias) + (defalias (car alias) (cdr alias))) + ccr/eshell-aliases) + + :hook (eshell-mode . (lambda () (setq-local scroll-margin 0))) + :bind (("C-c o e" . project-eshell) + :map eshell-mode-map + ("C-r" . eshell-atuin-history))) ;; i.e. just C-r in semi-char-mode + +(use-package eshell-command-not-found + :custom ((eshell-command-not-found-command "command-not-found")) + :hook ((eshell-mode . eshell-command-not-found-mode))) + +(use-package eshell-atuin + :hook ((eshell-mode . eshell-atuin-mode))) + +(use-package fish-completion-mode + :hook ((eshell-mode . fish-completion-mode))) + +(use-package eshell-syntax-highlighting + :custom + ((eshell-syntax-highlighting-highlight-in-remote-dirs nil)) + :config + (eshell-syntax-highlighting-global-mode +1)) + +(use-package eshell-prompt-extras + :custom ((eshell-highlight-prompt nil) + (eshell-prompt-function 'epe-theme-lambda))) + +(use-package popper + :custom + (popper-reference-buffers '("\*Messages\*" + "Output\*$" + "\\*Async Shell Command\\*" + (completion-list-mode . hide) + help-mode + compilation-mode + "^\\*Nix-REPL*\\*$" nix-repl-mode ;eshell as a popup + "^\\*.+-eshell.*\\*$" eshell-mode ;eshell as a popup + "^\\*shell.*\\*$" shell-mode ;shell as a popup + "^\\*term.*\\*$" term-mode ;term as a popup + "^\\*eat.*\\*$" eat-mode ;eat as a popup + )) + (popper-window-height 0.33) + (popper-echo-lines 1) + (popper-mode-line nil) + :init + (popper-mode 1) + (popper-echo-mode 1) + :bind (("C-c t t" . popper-toggle-latest) + ("C-c t c" . popper-cycle) + ("C-c t p" . popper-toggle-type))) + +(use-package org + :hook ((org-mode . variable-pitch-mode) + (org-mode . visual-line-mode) + (org-mode . visual-fill-column-mode)) + :custom ((org-log-done 'time) + (org-return-follows-link t) + (org-hide-emphasis-markers t) + (visual-fill-column-center-text t) + (visual-fill-column-width 100) + (fill-column 100) + (org-capture-templates '( + ("j" "Work Log Entry" + entry (file+datetree "~/org/work-log.org") + "* %?" + :empty-lines 0) + ("n" "Note" + entry (file+headline "~/org/notes.org" "Random Notes") + "** %?" + :empty-lines 0) + )) + (org-auto-align-tags nil) + (org-tags-column 0) + (org-catch-invisible-edits 'show-and-error) + (org-special-ctrl-a/e t) + (org-insert-heading-respect-content t) + (org-pretty-entities t) + (org-ellipsis "…") + ) + :bind (("C-c o l" . org-store-link) + ("C-c o a" . org-agenda) + ("C-c o c" . org-capture) + ("C-c b o" . org-switchb)) + :config + (defun ccr/org-capture (key) + "Capture a note using the template KEY and close the frame when done. +This is meant to be an helper to be called from the window manager." + (interactive) + (org-capture nil key) + (add-hook 'kill-buffer-hook 'delete-frame nil 't) ;; destroy frame on exit + (delete-other-windows)) + + (dolist (face '(org-block-begin-line + org-block-end-line + org-verbatim + org-code + )) + (set-face-attribute face nil :inherit 'fixed-pitch)) + + (org-babel-do-load-languages + 'org-babel-load-languages '((haskell . t)))) + +(use-package org-agenda + :custom + (org-agenda-files '("~/org")) + (org-agenda-tags-column 0) + (org-agenda-block-separator ?─) + (org-agenda-time-grid + '((daily today require-timed) + (800 1000 1200 1400 1600 1800 2000) + " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")) + (org-agenda-current-time-string + "◀── now ─────────────────────────────────────────────────") + :bind (("C-c o a" . org-agenda))) + +(use-package org-modern + :after org + :init + (global-org-modern-mode) + ;; FIXME the following doesn't work when using the daemon, it should be executed only + ;; one time after the first frame is created + :hook (server-after-make-frame . (lambda () + (set-face-font 'variable-pitch "Dejavu Serif-14") + (set-face-font 'fixed-pitch "Iosevka Comfy-14") + (set-face-font 'org-table "Iosevka Comfy-14") + (set-face-font 'org-meta-line "Iosevka Comfy-14") + (set-face-font 'org-drawer "Iosevka Comfy-14") + (set-face-font 'org-special-keyword "Iosevka Comfy-14") + (set-face-font 'org-property-value "Iosevka Comfy-14") + (set-face-font 'org-block "Iosevka Comfy-14") + (set-face-font 'org-modern-tag "Iosevka Comfy-14") + (set-face-font 'org-modern-date-active "Iosevka Comfy-14") + (set-face-font 'org-modern-date-inactive "Iosevka Comfy-14"))) +) + +(use-package org-roam + :custom + (org-roam-v2-ack t) + (org-roam-directory (file-truename "~/org")) + (org-roam-complete-everywhere 't) + (org-roam-dailies-capture-templates + '( + ("d" "Generic entry" entry + "* %?" + :target (file+head "%<%Y-%m-%d>.org" "#+title %<%Y-%m-%d>")) + ("b" "Billable entry" entry + "* TODO ${Entry} :billable:${Client}:\n:PROPERTIES:\n:SPENT: ${Spent}\n:END:\n%?" + :target (file+head "%<%Y-%m-%d>.org" "#+title %<%Y-%m-%d>") + :create-id t)) + ) + :config + (require 'org-roam-dailies) + (org-roam-db-autosync-mode) + + ;; In order to automatically add an org id for some capture templates (using the :create-id keyword) + (defun ccr/org-capture-maybe-create-id () + (when (org-capture-get :create-id) + (org-id-get-create))) + (add-hook 'org-capture-mode-hook #'ccr/org-capture-maybe-create-id) + + ;; The following functions name are relevant because org-roam-ql columns in queries use their suffix + (defun org-roam-node-spent (node) + "Return the hours spent as number" + (string-to-number (cdr (assoc "SPENT" (org-roam-node-properties node))))) + (defun org-roam-node-date (node) + "Return the org datestring when a node was created (obtained from the filename)" + (format "<%s>" (file-name-sans-extension (file-name-nondirectory (org-roam-node-file node))))) + + (defun ccr/org-roam-spent-hours (client) + "Return the total spent hours on something (usually a client)" + (apply #'+(mapcar #'org-roam-node-spent (org-roam-ql-nodes `(tags ,client "billable"))))) + ) + +(use-package org-roam-ql + :after org-roam + :bind ((:map org-roam-mode-map + ("v" . org-roam-ql-buffer-dispatch) + :map minibuffer-mode-map + ("C-c n i" . org-roam-ql-insert-node-title)))) + +(use-package consult-org-roam + :delight + :after org-roam + :init + (require 'consult-org-roam) + ;; Activate the minor mode + (consult-org-roam-mode 1) + :custom + (consutl-org-roam-grep-func #'consult-ripgrep) + (consult-org-roam-buffer-narrow-key ?r) + (consult-org-roam-buffer-after-buffers t) + (setq org-roam-database-connector 'sqlite-builtin) + :config + (consult-customize + consult-org-roam-forward-links + :preview-key (kbd "M-.")) + :bind + ("C-c n f" . consult-org-roam-file-find) + ("C-c n b" . consult-org-roam-backlinks) + ("C-c n l" . consult-org-roam-forward-links) + ("C-c n s" . consult-org-roam-search)) + +(use-package gptel + :custom + (gptel-api-key (lambda () (require 'f) (f-read-text (getenv "OPENAI_API_KEY_PATH")))) + (gptel-model "gpt-4o") + :config + (require 'gptel-curl) + + (add-hook 'gptel-post-response-functions 'gptel-end-of-response) + (add-hook 'gptel-post-stream-hook 'gptel-auto-scroll) + + (defun ccr/suggest-eshell-command () + (interactive) + (save-excursion + (eshell-bol) + (let ((start-pos (point)) + (end-pos (line-end-position))) + (gptel-request + (buffer-substring-no-properties start-pos end-pos) ;the prompt + :system "You are proficient with emacs shell (eshell), translate the following to something I could directly prompt to the shell. Your responses should only be code, without explanation or formatting." + :buffer (current-buffer) + :context (cons (set-marker (make-marker) start-pos) + (set-marker (make-marker) end-pos)) + :callback + (lambda (response info) + (if (not response) + (message "ChatGPT response failed with: %s" (plist-get info :status)) + (kill-region start-pos end-pos) + (insert response))))))) + + (add-to-list 'display-buffer-alist + '("^\\*ChatGPT\\*" + (display-buffer-full-frame) + (name . "floating"))) + + (defun ccr/start-chatgpt () ;; Used from outside Emacs by emacsclient --eval + (display-buffer (gptel "*ChatGPT*")) + (set-frame-name "floating") + ;; (delete-other-windows) + ;; (add-hook 'kill-buffer-hook 'delete-frame nil 't) + ) ;; destroy frame on exit + ) + +(use-package pass + :config + (require 'password-store-otp) ;; FIXME use `use-pacakge' idiomatic way + + :bind (("C-c p p" . password-store-copy) + ("C-c p o" . password-store-otp-token-copy) + ("C-c p e" . password-store-edit) + ("C-c p i" . password-store-insert))) + +(use-package with-editor + :init (shell-command-with-editor-mode +1)) + +(use-package go-translate + :custom + (gts-translate-list '(("it" "en") ("en" "it"))) + (gts-default-translator + (gts-translator + :picker (gts-prompt-picker) + :engines `(,(gts-bing-engine) + ,(gts-google-engine :parser (gts-google-summary-parser))) + :render (gts-buffer-render))) + (gts-buffer-follow-p 't) + :bind (("C-c T t" . gts-do-translate))) + +(use-package message + :custom + (message-send-mail-function 'smtpmail-send-it) + (send-mail-function 'smtpmail-send-it) + (user-mail-address "andrea.ciceri@autistici.org") + (smtpmail-smtp-server "mail.autistici.org") + (smtpmail-stream-type 'ssl) + (smtpmail-smtp-service 465) + ;; also the following line is needeed in ~/.authinfo.gpg + ;; machine mail.autistici.org login andrea.ciceri@autistici.org password + ) + +(use-package notmuch + :custom + (notmuch-show-logo nil) + (send-mail-function 'sendmail-send-it) + (notmuch-archive-tags '("-new")) + (notmuch-saved-searches + '((:name "Inbox" :query "tag:new" :key "i") + (:name "Sent" :query "tag:sent" :key "s") + (:name "Draft" :query "tag:draft" :key "s") + (:name "GitHub" :query "tag:github" :key "g") + (:name "Trash" :query "tag:trash" :key "t")))) + +(provide 'init) +;;; init.el ends here +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(custom-safe-themes + '("5bafdfa3e21f921abf9b9fd77e1e0ce032e62e3a6f8f13ec8ce7945727c654e9" + "5f92b9fc442528b6f106eaefa18bb5e7bfa0d737164e18f1214410fef2a6678d" + "b7f70bd00f79099f11d67a25c592d70593377488a263bb3dd73dee99b0549dba" + "7d10494665024176a90895ff7836a8e810d9549a9872c17db8871900add93d5c" + "b5c3c59e2fff6877030996eadaa085a5645cc7597f8876e982eadc923f597aca" default)) + '(magit-todos-insert-after '(bottom) nil nil "Changed by setter of obsolete option `magit-todos-insert-at'") + '(org-fold-catch-invisible-edits 'show-and-error nil nil "Customized with use-package org") + '(safe-local-variable-values + '((eval progn (require 'org-re-reveal) + (add-hook 'after-save-hook #'org-re-reveal-export-to-html nil t)) + (copilot-mode 0) (copilot-mode -1)))) + +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) +;; Local Variables: +;; byte-compile-warnings: (not free-vars noruntime unresolved) +;; End: diff --git a/hmModules/email/default.nix b/hmModules/email/default.nix index 648bbc8..5ae160a 100644 --- a/hmModules/email/default.nix +++ b/hmModules/email/default.nix @@ -1,12 +1,26 @@ { pkgs, secrets, + fleetFlake, + lib, ... }: { programs.mbsync.enable = true; programs.msmtp.enable = true; - services.mbsync.enable = true; + services.mbsync = { + enable = true; + postExec = lib.getExe ( + pkgs.writeShellScriptBin "mbsync-post-exec" '' + ${lib.getExe pkgs.notmuch} new + for _ in _ _ + do + afew -C ~/.config/notmuch/default/config --tag --new -vv + afew -C ~/.config/notmuch/default/config --move --new -vv + done + '' + ); + }; home.file.".config/aerc/stylesets" = let @@ -175,9 +189,6 @@ compose = { no-attachment-warning = "^[^>]*attach(ed|ment)"; }; - triggers = { - email-received = ''exec notify-send "New email from %n" "%s"''; - }; filters = { "text/plain" = "colorize"; "text/html" = "html"; @@ -188,6 +199,70 @@ }; }; }; + + programs.notmuch = { + enable = true; + new.tags = [ "new" ]; + search.excludeTags = [ + "trash" + "deleted" + "spam" + ]; + maildir.synchronizeFlags = true; + }; + + programs.afew = { + enable = true; + extraConfig = '' + [Filter.1] + message = "Tag GitHub notifications" + tags = +github + query = from:noreply@github.com OR from:notifications@github.com + + [Filter.2] + query = "folder:autistici/Inbox" + tags = +autistici + message = "Tag personal autistici emails" + + [Filter.3] + query = "not folder:autistici/Inbox" + tag = -new + message = "Sanity check: remove the new tag for emails moved out from Inbox" + + [Filter.4] + query = "not folder:autistici/Inbox" + tag = -new + message = "Sanity check: remove the new tag for emails moved out from Inbox" + + [Filter.5] + query = "not folder:autistici/Sent" + tag = +sent + message = "Sanity check: add the sent tag for emails in Sent" + + [Filter.6] + query = "not folder:autistici/Drafts" + tag = +draft + message = "Sanity check: add the draft tag for emails in Draft" + + [MailMover] + folders = autistici/Inbox + rename = true + + autistici/Inbox = 'tag:archive':autistici/Archive 'tag:github':autistici/GitHub 'NOT tag:new':autistici/Trash + ''; + }; + + systemd.user.services.emails-watcher = { + Unit.Description = "Send notifications when new emails arrive"; + Install = { + WantedBy = [ "default.target" ]; + }; + Service = { + ExecStart = "${lib.getExe fleetFlake.packages.${pkgs.system}.emails-watcher}"; + Environment = [ "INBOX_NEW=~/Maildir/autistici/Inbox/new" ]; + }; + }; + accounts.email = { accounts.autistici = { aerc.enable = true; @@ -203,6 +278,8 @@ mbsync = { enable = true; create = "maildir"; + expunge = "both"; + remove = "both"; }; msmtp.enable = true; notmuch.enable = true; diff --git a/hmModules/firefox/catppuccin.css b/hmModules/firefox/catppuccin.css new file mode 100644 index 0000000..8cad578 --- /dev/null +++ b/hmModules/firefox/catppuccin.css @@ -0,0 +1,187 @@ +:root { /* Catppuccin Colors */ + --bg: #1e1e2e; + --currentline: #302D41; + --fg: #d9e0ee; + --comment: #575268; + --flamingo: #f2cdcd; + --mauve: #ddb6f2; + --pink: #f5c2e7; + --maroon: #e8a2af; + --red: #f28fad; + --peach: #f8bd96; + --yellow: #fae3b0; + --green: #abe9b3; + --teal: #b5e8e0; + --blue: #96cdfb; + --sky: #89dceb; + --lavender: #c9cbff; + --rosewater: #f5e0dc; + --font: monospace; /*"FiraCode Nerd Font Mono";*/ + + /* vimium theme uses colors: flamingo, peach, rosewater, green, blue, lavender */ + --tridactyl-fg: var(--fg); + --tridactyl-bg: var(--bg); + --tridactyl-url-fg: var(--rosewater); + --tridactyl-url-bg: var(--bg); + --tridactyl-highlight-box-bg: var(--currentline); + --tridactyl-highlight-box-fg: var(--fg); + --tridactyl-of-fg: var(--fg); + --tridactyl-of-bg: var(--currentline); + --tridactyl-cmdl-fg: var(--bg); + --tridactyl-cmdl-font-family: var(--font); + --tridactyl-cmplt-font-family: var(--font); + --tridactyl-hintspan-font-family: var(--font); + + /* Hint character tags */ + --tridactyl-hintspan-fg: var(--bg) !important; + --tridactyl-hintspan-bg: var(--green) !important; + + /* Element Highlights */ + --tridactyl-hint-active-fg: none; + --tridactyl-hint-active-bg: none; + --tridactyl-hint-active-outline: none; + --tridactyl-hint-bg: none; + --tridactyl-hint-outline: none; +} + +#command-line-holder { + order: 1; + border: 2px solid var(--lavender); + background: var(--tridactyl-bg); +} + +#tridactyl-input { + padding: 1rem; + color: var(--tridactyl-fg); + width: 90%; + font-size: 1.5rem; + line-height: 1.5; + background: var(--tridactyl-bg); + padding-left: unset; + padding: 1rem; +} + +#completions table { + font-size: 0.8rem; + font-weight: 200; + border-spacing: 0; + table-layout: fixed; + padding: 1rem 0; + /* padding-top: 1rem; */ + /* padding-bottom: 1rem; */ +} + +#completions > div { + max-height: calc(20 * var(--option-height)); + min-height: calc(10 * var(--option-height)); +} + +/* COMPLETIONS */ + +#completions { + --option-height: 1.4em; + color: var(--tridactyl-fg); + background: var(--tridactyl-bg); + display: inline-block; + font-size: unset; + font-weight: 200; + overflow: hidden; + width: 100%; + border-top: unset; + order: 2; +} + +/* Olie doesn't know how CSS inheritance works */ +#completions .HistoryCompletionSource { + max-height: unset; + min-height: unset; +} + +#completions .HistoryCompletionSource table { + width: 100%; + font-size: 9pt; + border-spacing: 0; + table-layout: fixed; +} + +/* redundancy 2: redundancy 2: more redundancy */ +#completions .BmarkCompletionSource { + max-height: unset; + min-height: unset; +} + +#completions table tr td.prefix,#completions table tr td.privatewindow,#completions table tr td.container,#completions table tr td.icon { + display: none; +} + +#completions .BufferCompletionSource table { + width: unset; + font-size: unset; + border-spacing: unset; + table-layout: unset; +} + +#completions table tr .title, #completions table tr td.excmd { + width: 50%; + padding-left: 1rem; + color: var(--blue); +} + +#completions table tr .content, #completions table tr td.documentation { + padding-right: 1rem; +} + +#completions table tr { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +#completions table tr td { + padding: .5rem 0; +} + +#completions .sectionHeader { + background: unset; + font-weight: bold; + border-bottom: unset; + padding: 1rem 1rem 0 !important; + padding-left: unset; + padding-bottom: 0.2rem; + color: var(--peach); +} + +#cmdline_iframe { + position: fixed !important; + bottom: unset; + top: 25% !important; + left: 10% !important; + z-index: 2147483647 !important; + width: 80% !important; + box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 20px !important; +} + +.TridactylStatusIndicator { + position: fixed !important; + bottom: 0 !important; + background: var(--tridactyl-bg) !important; + border: unset !important; + border: 1px var(--purple) solid !important; + font-size: 12pt !important; + /*font-weight: 200 !important;*/ + padding: 0.8ex !important; +} + +#completions .focused { + background: var(--currentline); + /* color: var(--blue); */ + font-weight: bold; +} +#completions .focused td.title { + color: var(--pink); +} + +#completions .focused .url { + background: var(--currentline); + color: var(--green); +} diff --git a/hmModules/firefox/default.nix b/hmModules/firefox/default.nix index f6ae31e..43d60a3 100644 --- a/hmModules/firefox/default.nix +++ b/hmModules/firefox/default.nix @@ -1,30 +1,68 @@ { pkgs, - username, ... }: +let + mkExtension = shortId: uuid: { + name = uuid; + value = { + install_url = "https://addons.mozilla.org/en-US/firefox/downloads/latest/${shortId}/latest.xpi"; + installation_mode = "normal_installed"; + }; + }; +in { programs.firefox = { enable = true; - package = pkgs.wrapFirefox pkgs.firefox-unwrapped { - extraPolicies = { - ExtensionSettings = { }; + nativeMessagingHosts = [ pkgs.tridactyl-native ]; + policies = { + DisableTelemetry = true; + DisableFirefoxStudies = true; + EnableTrackingProtection = { + Value = true; + Locked = true; + Cryptomining = true; + Fingerprinting = true; + EmailTracking = true; }; - nativeMessagingHosts = [ pkgs.tridactyl-native ]; + HardwareAcceleration = true; + FirefoxHome = { + TopSites = false; + SponsoredTopSites = false; + Highlights = false; + Pocket = false; + SponsoredPocket = false; + Snippets = false; + Locked = false; + }; + FirefoxSuggest = { + WebSuggestions = true; + SponsoredSuggestions = false; + ImproveSuggest = false; + Locked = true; + }; + OverrideFirstRunPage = ""; + OverridePostUpdatePage = ""; + DontCheckDefaultBrowser = true; + DisplayMenuBar = "default-off"; # alternatives: "always", "never" or "default-on" + SearchBar = "unified"; # alternative: "separate" + HttpsOnlyMode = "force_enabled"; + NoDefaultBookmarks = true; + OfferToSaveLogins = false; + OfferToSaveLoginsDefault = false; + PasswordManagerEnabled = true; + DefaultDownloadDirectory = "\${home}/Downloads"; + PromptForDownloadLocation = false; + RequestedLocales = "en-US"; + + ExtensionSettings = builtins.listToAttrs [ + (mkExtension "ublock-origin" "uBlock0@raymondhill.net") + (mkExtension "tridactyl-vim" "tridactyl.vim@cmcaine.co.uk") + (mkExtension "styl-us" "7a7a4a92-a2a0-41d1-9fd7-1e92480d612d") + ]; }; - profiles.${username} = { - settings = { - "browser.startup.homepage" = "https://google.it"; - "browser.search.region" = "IT"; - "browser.search.isUS" = false; - "distribution.searchplugins.defaultLocale" = "it-IT"; - "general.useragent.locale" = "it-IT"; - "browser.bookmarks.showMobileBookmarks" = true; - "browser.download.folderList" = 2; - "browser.download.lastDir" = "/home/${username}/Downloads/"; - "browser.shell.checkDefaultBrowser" = false; - }; - search.force = true; + profiles.default = { + search.default = "DuckDuckGo"; search.engines = { "Searx" = { urls = [ @@ -40,10 +78,19 @@ ]; }; }; + bookmarks = [ ]; + extensions = [ ]; + userChrome = builtins.readFile ./userchrome.css; }; }; - home.sessionVariables = { - MOZ_ENABLE_WAYLAND = 1; - NIXOS_OZONE_WL = 1; + + xdg.configFile."tridactyl/tridactylrc".text = '' + set editorcmd footclient -e hx %f + + colors catppuccin + ''; + + xdg.configFile."tridactyl/themes/catppuccin.css" = { + source = ./catppuccin.css; }; } diff --git a/hmModules/firefox/userchrome.css b/hmModules/firefox/userchrome.css new file mode 100644 index 0000000..7abb436 --- /dev/null +++ b/hmModules/firefox/userchrome.css @@ -0,0 +1,67 @@ + +/* * Do not remove the @namespace line -- it's required for correct functioning */ +/* set default namespace to XUL */ +@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); + +/* Remove Back button when there's nothing to go Back to */ +#back-button[disabled="true"] { display: none; } + +/* Remove Forward button when there's nothing to go Forward to */ +#forward-button[disabled="true"] { display: none; } + +/* Remove Home button (never use it) */ +#home-button { display: none; } + +.titlebar-spacer { + display: none !important; +} + +/* Remove import bookmarks button */ +#import-button { + display: none; +} + +/* Remove bookmark toolbar */ +toolbarbutton.bookmark-item:not(.subviewbutton) { + display: none; +} + +/* Remove whitespace in toolbar */ +#nav-bar toolbarpaletteitem[id^="wrapper-customizableui-special-spring"], #nav-bar toolbarspring { + display: none; +} + +/* Hide dumb Firefox View button */ +#firefox-view-button { + visibility: hidden; +} + +/* Hide Firefox tab icon */ +.tab-icon-image { + display: none; +} + +/* Linux stuff to keep GNOME system theme */ +.titlebar-min { + appearance: auto !important; + -moz-default-appearance: -moz-window-button-minimize !important; +} + +.titlebar-max { + appearance: auto !important; + -moz-default-appearance: -moz-window-button-maximize !important; +} + +.titlebar-restore { + appearance: auto !important; + -moz-default-appearance: -moz-window-button-restore !important; +} + +.titlebar-close { + appearance: auto !important; + -moz-default-appearance: -moz-window-button-close !important; +} + +.titlebar-button { + list-style-image: none !important; +} diff --git a/hmModules/helix/default.nix b/hmModules/helix/default.nix index c6ef610..ee9cc32 100644 --- a/hmModules/helix/default.nix +++ b/hmModules/helix/default.nix @@ -10,7 +10,6 @@ programs.helix = { enable = true; - defaultEditor = true; settings = { editor = { indent-guides.render = true; diff --git a/hmModules/hyprland/hyprland.conf b/hmModules/hyprland/hyprland.conf index cfc9db7..473e740 100644 --- a/hmModules/hyprland/hyprland.conf +++ b/hmModules/hyprland/hyprland.conf @@ -30,10 +30,13 @@ windowrulev2 = workspace 9, class:^(Spotify)$ windowrulev2 = float, title:^(floating)$ bind = $mod, b, exec, firefox -bind = $mod, t, exec, footclient -bind = $mod, y, exec, waypipe --compress lz4=10 ssh picard.fleet emacsclient -c +bind = $mod, t, exec, footclient $SHELL -C "zellij" +bind = $mod, RETURN, exec, emacsclient -c --eval "(ccr/start-eshell)" +bind = $mod, m, exec, footclient $SHELL -C "aerc" bind = $mod, d, exec, fuzzel --background-color=253559cc --border-radius=5 --border-width=0 bind = $mod, s, exec, screenshot.sh +bind = $mod, n, exec, logseq +bind = $mod, x, exec, emacsclient -c bind = , XF86MonBrightnessUp, exec, brightnessctl s +5% bind = , XF86MonBrightnessDown, exec, brightnessctl s 5%- bind = $mod, code:60, exec, brightnessctl s +5% diff --git a/hmModules/imv/default.nix b/hmModules/imv/default.nix new file mode 100644 index 0000000..02ebcb3 --- /dev/null +++ b/hmModules/imv/default.nix @@ -0,0 +1,3 @@ +{ + programs.imv.enable = true; +} diff --git a/hmModules/libreoffice/default.nix b/hmModules/libreoffice/default.nix new file mode 100644 index 0000000..1e846d4 --- /dev/null +++ b/hmModules/libreoffice/default.nix @@ -0,0 +1,4 @@ +{ pkgs, ... }: +{ + home.packages = [ pkgs.libreoffice ]; +} diff --git a/hmModules/logseq/default.nix b/hmModules/logseq/default.nix new file mode 100644 index 0000000..dffb462 --- /dev/null +++ b/hmModules/logseq/default.nix @@ -0,0 +1,15 @@ +{ pkgs, lib, ... }: +let + logseq = pkgs.appimageTools.wrapType2 { + name = "logseq"; + version = "nightly-20240909"; + src = pkgs.fetchurl { + url = "https://github.com/logseq/logseq/releases/download/nightly/Logseq-linux-x64-0.10.10-alpha+nightly.20240909.AppImage"; + hash = "sha256-Hy/zk8ZCkWajsMRUMsewLvkKpMpsBZYnFootPU9y6Z0="; + }; + }; + logseq-wayland = pkgs.writeScriptBin "logseq" "${lib.getExe' logseq "logseq"} --enable-features=UseOzonePlatform --ozone-platform=wayland"; +in +{ + home.packages = [ logseq-wayland ]; +} diff --git a/hmModules/password-store/default.nix b/hmModules/password-store/default.nix index 69be6e1..69dbc78 100644 --- a/hmModules/password-store/default.nix +++ b/hmModules/password-store/default.nix @@ -3,6 +3,14 @@ username, ... }: +let + fzfpass = pkgs.writeShellApplication { + name = "fzfpass"; + text = '' + find "$PASSWORD_STORE_DIR" -name "*.gpg" | sed "s|$PASSWORD_STORE_DIR/||; s|\.gpg||" | fzf --border --info=inline | xargs pass "$@" + ''; + }; +in { programs.password-store = { enable = true; @@ -11,4 +19,5 @@ }; package = pkgs.pass.withExtensions (e: [ e.pass-otp ]); }; + home.packages = [ fzfpass ]; } diff --git a/hmModules/shell/default.nix b/hmModules/shell/default.nix index 32f4a8f..22ced2b 100644 --- a/hmModules/shell/default.nix +++ b/hmModules/shell/default.nix @@ -20,6 +20,8 @@ programs.ripgrep.enable = true; + programs.fd.enable = true; + programs.direnv = { enable = true; config = { @@ -29,7 +31,7 @@ }; programs.lsd = { - enable = false; + enable = true; enableAliases = true; }; @@ -62,6 +64,16 @@ programs.fish = { enable = true; + plugins = [ + # { + # name = "fifc"; + # src = pkgs.fishPlugins.fifc.src; + # } + { + name = "z"; + src = pkgs.fishPlugins.z.src; + } + ]; shellInit = '' fish_vi_key_bindings @@ -84,8 +96,14 @@ ffmpeg-headless jless nix-melt + nurl jq yq-go + procs + chafa + hexyl + broot + file ] ++ (lib.optionals (builtins.elem hostname [ diff --git a/hmModules/vial/default.nix b/hmModules/vial/default.nix new file mode 100644 index 0000000..af49514 --- /dev/null +++ b/hmModules/vial/default.nix @@ -0,0 +1,4 @@ +{ pkgs, ... }: +{ + home.packages = [ pkgs.vial ]; +} diff --git a/hmModules/zellij/default.nix b/hmModules/zellij/default.nix new file mode 100644 index 0000000..45a8487 --- /dev/null +++ b/hmModules/zellij/default.nix @@ -0,0 +1,108 @@ +{ + config, + pkgs, + lib, + ... +}: +let + zjstatus = pkgs.fetchurl { + url = "https://github.com/dj95/zjstatus/releases/download/v0.17.0/zjstatus.wasm"; + hash = "sha256-IgTfSl24Eap+0zhfiwTvmdVy/dryPxfEF7LhVNVXe+U="; + }; + cfg = config.programs.fzf.catppuccin; + palette = (lib.importJSON "${config.catppuccin.sources.palette}/palette.json").${cfg.flavor}.colors; + selectColor = color: palette.${color}.hex; + color_fg = selectColor "text"; + color_bg = selectColor "mantle"; + color_black = selectColor "surface1"; + color_red = selectColor "red"; + color_green = selectColor "green"; + color_yellow = selectColor "yellow"; + color_blue = selectColor "blue"; + color_magenta = selectColor "pink"; + color_cyan = selectColor "teal"; + color_white = selectColor "subtext1"; + layout = pkgs.writeText "layout.kdl" '' + layout { + default_tab_template { + pane size=1 borderless=true { + plugin location="file:${zjstatus}" { + color_fg "${color_fg}" + color_bg "${color_bg}" + color_black "${color_black}" + color_red "${color_red}" + color_green "${color_green}" + color_yellow "${color_yellow}" + color_blue "${color_blue}" + color_magenta "${color_magenta}" + color_cyan "${color_cyan}" + color_white "${color_white}" + + format_left "{mode}#[bg=$bg] {tabs}" + // format_center "#[bg=$bg,fg=$fg] Zellij: #[bg=$bg,fg=$fg]{session}" + // format_right "{datetime}" + format_right "#[bg=$bg,fg=$fg] Zellij: #[bg=$bg,fg=$fg]{session} " + format_space "#[bg=$bg]" + format_hide_on_overlength "true" + format_precedence "crl" + + border_enabled "false" + border_char "─" + border_format "#[fg=#6C7086]{char}" + border_position "top" + + hide_frame_for_single_pane "true" + + mode_normal "#[bg=$green,fg=$bg,bold] NORMAL #[bg=$bg,fg=$green]" + mode_locked "#[bg=$red,fg=$bg,bold] LOCKED  #[bg=$bg,fg=$red]" + mode_resize "#[bg=$blue,fg=$bg,bold] RESIZE #[bg=$bg,fg=$blue]" + mode_pane "#[bg=$blue,fg=$bg,bold] PANE #[bg=$bg,fg=$blue]" + mode_tab "#[bg=$yellow,fg=$bg,bold] TAB #[bg=$bg,fg=$yellow]" + mode_scroll "#[bg=$blue,fg=$bg,bold] SCROLL #[bg=$bg,fg=$blue]" + mode_enter_search "#[bg=$yellow,fg=$bg,bold] ENT-SEARCH #[bg=$bg,fg=$yellow]" + mode_search "#[bg=$yellow,fg=$bg,bold] SEARCHARCH #[bg=$bg,fg=$yellow]" + mode_rename_tab "#[bg=$yellow,fg=$bg,bold] RENAME-TAB #[bg=$bg,fg=$yellow]" + mode_rename_pane "#[bg=$blue,fg=$bg,bold] RENAME-PANE #[bg=$bg,fg=$blue]" + mode_session "#[bg=$blue,fg=$bg,bold] SESSION #[bg=$bg,fg=$blue]" + mode_move "#[bg=$blue,fg=$bg,bold] MOVE #[bg=$bg,fg=$blue]" + mode_prompt "#[bg=$blue,fg=$bg,bold] PROMPT #[bg=$bg,fg=$blue]" + mode_tmux "#[bg=$magenta,fg=$bg,bold] TMUX #[bg=$bg,fg=$magenta]" + + // formatting for inactive tabs + tab_normal "#[bg=$bg,fg=$cyan] #[bg=$cyan,fg=$bg,bold] {index} {floating_indicator}#[bg=$bg,fg=$bg,bold]" + tab_normal_fullscreen "#[bg=$bg,fg=$cyan] #[bg=$cyan,fg=$bg,bold] {index} {fullscreen_indicator}#[bg=$bg,fg=$bg,bold]" + tab_normal_sync "#[bg=$bg,fg=$cyan] #[bg=$cyan,fg=$bg,bold] {index} {sync_indicator}#[bg=$bg,fg=$bg,bold]" + + // formatting for the current active tab + tab_active "#[bg=$bg,fg=$yellow] #[bg=$yellow,fg=$bg,bold] {index} {floating_indicator}#[bg=$bg,fg=$bg,bold]" + tab_active_fullscreen "#[bg=$bg,fg=$yellow] #[bg=$yellow,fg=$bg,bold] {index} {fullscreen_indicator}#[bg=$bg,fg=$bg,bold]" + tab_active_sync "#[bg=$bg,fg=$yellow] #[bg=$yellow,fg=$bg,bold] {index} {sync_indicator}#[bg=$bg,fg=$bg,bold]" + + // separator between the tabs + tab_separator "#[bg=$bg] " + + // indicators + tab_sync_indicator " " + tab_fullscreen_indicator " 󰊓" + tab_floating_indicator " 󰹙" + + datetime "#[fg=$fg] {format} " + datetime_format "%Y-%m-%d %H:%M" + datetime_timezone "Europe/Rome" + } + } + children + } + } + ''; +in +{ + programs.zellij = { + enable = true; + enableFishIntegration = false; + settings = { + default_layout = "${layout}"; + pane_frames = false; + }; + }; +} diff --git a/hmModules/zmkbatx/default.nix b/hmModules/zmkbatx/default.nix index 0070092..ff8c992 100644 --- a/hmModules/zmkbatx/default.nix +++ b/hmModules/zmkbatx/default.nix @@ -16,7 +16,9 @@ }; Service = { - ExecStart = "sleep 5 && ${lib.getExe pkgs.zmkBATx}"; + ExecStart = '' + ${pkgs.runtimeShell} -l -c "${lib.getExe' pkgs.busybox "sleep"} 5 && ${lib.getExe pkgs.zmkBATx}" + ''; Restart = "on-failure"; RestartSec = 3; }; diff --git a/hosts/default.nix b/hosts/default.nix index 480c37d..0498e19 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -44,9 +44,11 @@ inputs.disko.nixosModules.disko inputs.nixosHardware.nixosModules.lenovo-thinkpad-x1-7th-gen inputs.lix-module.nixosModules.default + inputs.catppuccin.nixosModules.catppuccin ]; extraHmModules = [ "${inputs.homeManagerGitWorkspace}/modules/services/git-workspace.nix" + inputs.catppuccin.homeManagerModules.catppuccin ]; secrets = { "kirk-wireguard-private-key" = { }; @@ -90,6 +92,7 @@ sisko = { system = "aarch64-linux"; + enableHomeManager = false; vpn = { ip = "10.100.0.1"; publicKey = "bc5giljukT1+ChbbyTLdOfejfR3c8RZ4XoXmQM54nTY="; @@ -101,7 +104,6 @@ ]; secrets = { "sisko-wireguard-private-key" = { }; - "cachix-personal-token".owner = "ccr"; "home-planimetry".owner = "hass"; "home-assistant-token".owner = "prometheus"; "grafana-password".owner = "grafana"; @@ -123,6 +125,10 @@ ip = "10.100.0.4"; publicKey = "9ccx4C4xvPC6lPgTZAHDSfK4FS2BP2i4D57u9IZjw18="; }; + macos-ventura = { + ip = "10.100.0.6"; + publicKey = "/Eee1V0PsjZSzj7un1NxHKtFR+TpUIgJ7VAdIAzmvzQ="; + }; }; }; } diff --git a/hosts/kirk/default.nix b/hosts/kirk/default.nix index f2ee46a..272dd30 100644 --- a/hosts/kirk/default.nix +++ b/hosts/kirk/default.nix @@ -1,7 +1,7 @@ { fleetModules, lib, - config, + pkgs, ... }: { @@ -27,13 +27,14 @@ "printing" "pam" "wireguard-client" - "restic" "greetd" "syncthing" - "mount-rock5b" + "mount-sisko" "adb" "binfmt" "prometheus-exporters" + "promtail" + "syncthing" ] ++ [ ./disko.nix @@ -47,6 +48,7 @@ "git-workspace" "helix" "shell" + "zellij" "element" "firefox" "gpg" @@ -67,6 +69,12 @@ "remmina" "zulip" "calibre" + "zathura" + "imv" + "catppuccin" + "libreoffice" + "logseq" + "emacs" ]; extraGroups = [ ]; backupPaths = [ ]; @@ -83,7 +91,7 @@ "kvm-intel" ]; - boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages; + boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_10; boot.loader.efi.canTouchEfiVariables = true; boot.loader.systemd-boot = { @@ -97,8 +105,13 @@ powerManagement.cpuFreqGovernor = lib.mkDefault "schedutil"; hardware.enableRedistributableFirmware = lib.mkDefault true; - hardware.opengl = { + hardware.graphics = { enable = true; - driSupport32Bit = true; + enable32Bit = true; + }; + + zramSwap = { + enable = true; + algorithm = "zstd"; }; } diff --git a/hosts/picard/default.nix b/hosts/picard/default.nix index be7d2f8..c5773d4 100644 --- a/hosts/picard/default.nix +++ b/hosts/picard/default.nix @@ -31,13 +31,13 @@ "wireguard-client" "binfmt" "greetd" - # "syncthing" + "syncthing" "hass-poweroff" "forgejo-runners" "teamviewer" - # "macos-ventura" + "macos-ventura" "sunshine" - "mount-rock5b" + "mount-sisko" "adb" "guix" "prometheus-exporters" @@ -55,6 +55,7 @@ "git-workspace" "helix" "shell" + "zellij" "element" "zmkbatx" "tremotesf" @@ -86,6 +87,12 @@ "zk" "catppuccin" "freecad" + "zathura" + "imv" + "libreoffice" + "logseq" + "emacs" + "vial" ]; extraGroups = [ ]; backupPaths = [ ]; diff --git a/hosts/sisko/default.nix b/hosts/sisko/default.nix index 8341327..6295c63 100644 --- a/hosts/sisko/default.nix +++ b/hosts/sisko/default.nix @@ -1,7 +1,6 @@ { fleetModules, pkgs, - config, ... }: { @@ -9,7 +8,6 @@ fleetModules [ "common" "ssh" - "ccr" "wireguard-server" "mediatomb" "transmission" @@ -17,10 +15,10 @@ "home-assistant" "adguard-home" "cloudflare-dyndns" - "rock5b-proxy" + "sisko-proxy" "invidious" "searx" - "rock5b-samba" + "sisko-nfs" "forgejo" "prometheus" "grafana" @@ -30,37 +28,20 @@ "garmin-collector" "restic" "atuin" + "immich" + "paperless" + "syncthing" ] ++ [ ./disko.nix ]; - # boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_8; - boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_6_10; - # boot.kernelPackages = let - # pkgs = fleetFlake.inputs.nixpkgsForSisko.legacyPackages.aarch64-linux; - # in - # pkgs.linuxPackagesFor pkgs.linux_testing; - # boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_6_9.override { - # argsOverride = { - # src = pkgs.fetchFromGitLab { - # domain = "gitlab.collabora.com"; - # owner = "hardware-enablement/rockchip-3588"; - # repo = "linux"; - # rev = "23bb9c65a88c114bbe945b7ef5366bb02d3d9b80"; - # sha256 = "sha256-6TygOl5r7/N2jlcPznWlvJfVVeXKSR8yMoGuTDbIdTA="; - # }; - # version = "6.9"; - # modDirVersion = "6.9.0"; - # }; - # }); + boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_6_11; system.stateVersion = "24.05"; powerManagement.cpuFreqGovernor = "schedutil"; - ccr.enable = true; - nixpkgs.hostPlatform = "aarch64-linux"; swapDevices = [ ]; @@ -98,7 +79,6 @@ "/var/log" "/var/lib/containers" "/var/lib/postgresql" - "/home/${config.ccr.username}/.ssh" ]; files = [ "/etc/machine-id" @@ -117,12 +97,6 @@ fileSystems."/persist".neededForBoot = true; boot.tmp.cleanOnBoot = true; - fileSystems."/mnt/hd" = { - device = "/dev/disk/by-id/ata-WDC_WD5000AAKX-08U6AA0_WD-WCC2E5TR40FU-part1"; - fsType = "ext4"; - options = [ "nofail" ]; - }; - environment.systemPackages = with pkgs; [ cifs-utils ]; diff --git a/hosts/sisko/disko.nix b/hosts/sisko/disko.nix index 909a33b..ba5c708 100644 --- a/hosts/sisko/disko.nix +++ b/hosts/sisko/disko.nix @@ -1,9 +1,7 @@ let ssd = "/dev/disk/by-id/ata-CT240BX300SSD1_1739E1042F3C"; + hd = "/dev/disk/by-id/ata-ST12000NM0558_ZHZ6006Q"; in -# hd1 = "/dev/disk/by-id/ata-WDC_WD10EADS-22M2B0_WD-WCAV52709550"; -# hd2 = "/dev/disk/by-id/ata-WDC_WD10EADX-22TDHB0_WD-WCAV5V359530"; -# old_hd = "/dev/disk/by-id/ata-WDC_WD5000AAKX-08U6AA0_WD-WCC2E5TR40FU"; { disko.devices = { nodev."/" = { @@ -58,6 +56,63 @@ in }; }; }; + hd = { + device = hd; + type = "disk"; + content = { + type = "gpt"; + partitions = { + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "bcachefs"; + mountpoint = "/mnt/hd"; + }; + }; + }; + }; + }; + # hd = { + # type = "disk"; + # device = hd; + # content = { + # type = "gpt"; + # partitions = { + # zfs = { + # size = "100%"; + # content = { + # type = "zfs"; + # pool = "zroot"; + # }; + # }; + # }; + # }; + # }; + # }; + # zpool = { + # zroot = { + # type = "zpool"; + # rootFsOptions = { + # compression = "lz4"; + # acltype = "posixacl"; + # xattr = "sa"; + # "com.sun:auto-snapshot" = "true"; + # mountpoint = "none"; + # }; + # datasets = { + # "root" = { + # type = "zfs_fs"; + # options.mountpoint = "/mnt/hd"; + # mountpoint = "/mnt/hd"; + # }; + # "root/torrent" = { + # type = "zfs_fs"; + # options.mountpoint = "/mnt/hd/torrent"; + # mountpoint = "/mnt/hd/torrent"; + # }; + # }; + # }; }; }; } diff --git a/modules/cloudflare-dyndns/default.nix b/modules/cloudflare-dyndns/default.nix index b70c98d..e86c6b6 100644 --- a/modules/cloudflare-dyndns/default.nix +++ b/modules/cloudflare-dyndns/default.nix @@ -12,12 +12,10 @@ "search.aciceri.dev" "invidious.aciceri.dev" "vpn.aciceri.dev" - "cache.aciceri.dev" - "matrix.aciceri.dev" - "syncv3.matrix.aciceri.dev" - "jellyfin.aciceri.dev" "photos.aciceri.dev" "status.aciceri.dev" + "paper.aciceri.dev" + "cloud.aciceri.dev" ]; apiTokenFile = config.age.secrets.cloudflare-dyndns-api-token.path; }; diff --git a/modules/forgejo-runners/default.nix b/modules/forgejo-runners/default.nix index 4cbb492..1d88c82 100644 --- a/modules/forgejo-runners/default.nix +++ b/modules/forgejo-runners/default.nix @@ -115,6 +115,7 @@ lib.mkMerge [ # extraGroups = [ "podman" ]; }; users.groups.nixuser = { }; + nix.settings.trusted-users = [ "nixuser" ]; } { # Format of the token file: diff --git a/modules/forgejo/default.nix b/modules/forgejo/default.nix index ae7f0c4..d67ccc5 100644 --- a/modules/forgejo/default.nix +++ b/modules/forgejo/default.nix @@ -4,6 +4,7 @@ }: { services.forgejo = { + # TODO migrate to Postgres enable = true; settings = { DEFAULT = { diff --git a/modules/immich/default.nix b/modules/immich/default.nix index be7e905..ffa5968 100644 --- a/modules/immich/default.nix +++ b/modules/immich/default.nix @@ -1,20 +1,99 @@ +{ ... }: +let + vars = { + serviceConfigRoot = "/mnt/hd/immich/state"; + mainArray = "/mnt/hd/immich/"; + domainName = "photos.aciceri.dev"; + }; + directories = [ + "${vars.serviceConfigRoot}/immich" + "${vars.serviceConfigRoot}/immich/postgresql" + "${vars.serviceConfigRoot}/immich/postgresql/data" + "${vars.serviceConfigRoot}/immich/config" + "${vars.serviceConfigRoot}/immich/machine-learning" + "${vars.mainArray}/Photos" + "${vars.mainArray}/Photos/Immich" + "${vars.mainArray}/Photos/S10m" + ]; +in { - containers.immich = { - nixpkgs = builtins.getFlake "github:NixOS/nixpkgs/51296fce6f2b33717f710788af4e134aa7ff0e58"; - autoStart = true; - privateNetwork = true; - # hostAddress = "192.168.100.10"; - # localAddress = "192.168.100.11"; - # hostAddress6 = "fc00::1"; - # localAddress6 = "fc00::2"; - config = - { - ... - }: - { - services.immich = { - enable = true; - }; + systemd.tmpfiles.rules = map (x: "d ${x} 0775 root root - -") directories; + systemd.services = { + podman-immich = { + requires = [ + "podman-immich-redis.service" + "podman-immich-postgres.service" + ]; + after = [ + "podman-immich-redis.service" + "podman-immich-postgres.service" + ]; + }; + podman-immich-postgres = { + requires = [ "podman-immich-redis.service" ]; + after = [ "podman-immich-redis.service" ]; + }; + }; + + virtualisation.oci-containers.containers = { + immich = { + autoStart = true; + image = "ghcr.io/imagegenius/immich:latest"; + volumes = [ + "${vars.serviceConfigRoot}/immich/config:/config" + "${vars.mainArray}/Photos/Immich:/photos" + "${vars.mainArray}/Photos/S10m:/import:ro" + "${vars.serviceConfigRoot}/immich/machine-learning:/config/machine-learning" + ]; + # environmentFiles = [ config.age.secrets.ariaImmichDatabase.path ]; + environment = { + PUID = "994"; + PGID = "993"; + TZ = "Europe/Rome"; + DB_HOSTNAME = "immich-postgres"; + DB_USERNAME = "immich"; + DB_DATABASE_NAME = "immich"; + REDIS_HOSTNAME = "immich-redis"; + DB_PASSWORD = "password"; }; + extraOptions = [ + "--pull=newer" + "--network=container:immich-redis" + ]; + }; + + immich-redis = { + autoStart = true; + image = "redis"; + extraOptions = [ + "--pull=newer" + "-l=traefik.enable=true" + "-l=traefik.http.routers.immich.rule=Host(`photos.${vars.domainName}`)" + "-l=traefik.http.routers.immich.service=immich" + "-l=traefik.http.services.immich.loadbalancer.server.port=8080" + ]; + ports = [ + "8080:8080" + ]; + }; + + immich-postgres = { + autoStart = true; + image = "tensorchord/pgvecto-rs:pg14-v0.2.1"; + volumes = [ + "${vars.serviceConfigRoot}/immich/postgresql/data:/var/lib/postgresql/data" + ]; + # environmentFiles = [ config.age.secrets.ariaImmichDatabase.path ]; + environment = { + POSTGRES_USER = "immich"; + POSTGRES_DB = "immich"; + POSTGRES_HOST_AUTH_METHOD = "trust"; + POSTGRES_PASSWORD = "password"; + }; + extraOptions = [ + "--pull=newer" + "--network=container:immich-redis" + ]; + }; }; } diff --git a/modules/immich/env b/modules/immich/env deleted file mode 100644 index 5c8b109..0000000 --- a/modules/immich/env +++ /dev/null @@ -1,5 +0,0 @@ -PUBLIC_LOGIN_PAGE_MESSAGE= - -IMMICH_WEB_URL=http://immich-web:3000 -IMMICH_SERVER_URL=http://immich-server:3001 -IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003 \ No newline at end of file diff --git a/modules/immich/module.nix b/modules/immich/module.nix deleted file mode 100644 index 230691a..0000000 --- a/modules/immich/module.nix +++ /dev/null @@ -1,584 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) - hasAttr - hasPrefix - maintainers - mapAttrs - mkDefault - mkEnableOption - mkIf - mkMerge - mkOption - mkPackageOption - optional - optionalAttrs - optionalString - types - ; - - cfg = config.services.immich; - serverCfg = config.services.immich.server; - backendCfg = serverCfg.backend; - microservicesCfg = serverCfg.microservices; - webCfg = cfg.web; - mlCfg = cfg.machineLearning; - - isServerPostgresUnix = hasPrefix "/" serverCfg.postgres.host; - postgresEnv = - if isServerPostgresUnix then - { - # If passwordFile is given, this will be overwritten in ExecStart - DB_URL = "socket://${serverCfg.postgres.host}?dbname=${serverCfg.postgres.database}"; - } - else - { - DB_HOSTNAME = serverCfg.postgres.host; - DB_PORT = toString serverCfg.postgres.port; - DB_DATABASE_NAME = serverCfg.postgres.database; - DB_USERNAME = serverCfg.postgres.username; - }; - - typesenseEnv = - { - TYPESENSE_ENABLED = toString serverCfg.typesense.enable; - } - // optionalAttrs serverCfg.typesense.enable { - TYPESENSE_HOST = serverCfg.typesense.host; - TYPESENSE_PORT = toString serverCfg.typesense.port; - TYPESENSE_PROTOCOL = serverCfg.typesense.protocol; - }; - - # Don't start a redis instance if the user sets a custom redis connection - enableRedis = - !hasAttr "REDIS_URL" serverCfg.extraConfig && !hasAttr "REDIS_SOCKET" serverCfg.extraConfig; - redisServerCfg = config.services.redis.servers.immich; - redisEnv = optionalAttrs enableRedis { - REDIS_SOCKET = redisServerCfg.unixSocket; - }; - - serverEnv = - postgresEnv - // typesenseEnv - // redisEnv - // { - NODE_ENV = "production"; - - IMMICH_MEDIA_LOCATION = serverCfg.mediaDir; - IMMICH_MACHINE_LEARNING_URL = - if serverCfg.machineLearningUrl != null then serverCfg.machineLearningUrl else "false"; - }; - - serverStartWrapper = program: '' - set -euo pipefail - mkdir -p ${serverCfg.mediaDir} - - ${optionalString (serverCfg.postgres.passwordFile != null) ( - if isServerPostgresUnix then - ''export DB_URL="socket://${serverCfg.postgres.username}:$(cat ${serverCfg.postgres.passwordFile})@${serverCfg.postgres.host}?dbname=${serverCfg.postgres.database}"'' - else - "export DB_PASSWORD=$(cat ${serverCfg.postgres.passwordFile})" - )} - - ${optionalString serverCfg.typesense.enable '' - export TYPESENSE_API_KEY=$(cat ${serverCfg.typesense.apiKeyFile}) - ''} - - exec ${program} - ''; - - commonServiceConfig = { - Restart = "on-failure"; - - # Hardening - CapabilityBoundingSet = ""; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateUsers = true; - PrivateTmp = true; - PrivateDevices = true; - PrivateMounts = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "invisible"; - ProcSubset = "pid"; - # Would re-mount paths ignored by temporary root - # TODO ProtectSystem = "strict"; - RemoveIPC = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_UNIX" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service" - "~@privileged" - "@pkey" - ]; - UMask = "0077"; - }; - - serverServiceConfig = { - DynamicUser = true; - User = "immich"; - Group = "immich"; - SupplementaryGroups = optional enableRedis redisServerCfg.user; - - StateDirectory = "immich"; - StateDirectoryMode = "0750"; - WorkingDirectory = "/var/lib/immich"; - - MemoryDenyWriteExecute = false; # nodejs requires this. - EnvironmentFile = mkIf (serverCfg.environmentFile != null) serverCfg.environmentFile; - - TemporaryFileSystem = "/:ro"; - BindReadOnlyPaths = [ - "/nix/store" - "-/etc/resolv.conf" - "-/etc/nsswitch.conf" - "-/etc/hosts" - "-/etc/localtime" - "-/run/postgresql" - ] ++ optional enableRedis redisServerCfg.unixSocket; - }; -in -{ - options.services.immich = { - enable = mkEnableOption "immich" // { - description = '' - Enables immich which consists of a backend server, microservices, - machine-learning and web ui. You can disable or reconfigure components - individually using the subsections. - ''; - }; - - package = mkPackageOption pkgs "immich" { }; - - server = { - mediaDir = mkOption { - type = types.str; - default = "/var/lib/immich/media"; - description = "Directory used to store media files."; - }; - - backend = { - enable = mkEnableOption "immich backend server" // { - default = true; - }; - port = mkOption { - type = types.port; - default = 3001; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - LOG_LEVEL = "debug"; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'server' for available options. - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file as defined in systemd.exec(5). May be used to provide - additional secret variables to the service without adding them to the - world-readable Nix store. - ''; - }; - }; - - microservices = { - enable = mkEnableOption "immich microservices" // { - default = true; - }; - - port = mkOption { - type = types.port; - default = 3002; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - REVERSE_GEOCODING_PRECISION = 1; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'microservices' for available options. - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file as defined in systemd.exec(5). May be used to provide - additional secret variables to the service without adding them to the - world-readable Nix store. - ''; - }; - }; - - typesense = { - enable = mkEnableOption "typesense" // { - default = true; - }; - - host = mkOption { - type = types.str; - default = "127.0.0.1"; - example = "typesense.example.com"; - description = "Hostname/address of the typesense server to use."; - }; - - port = mkOption { - type = types.port; - default = 8108; - description = "The port of the typesense server to use."; - }; - - protocol = mkOption { - type = types.str; - default = "http"; - description = "The protocol to use when connecting to the typesense server."; - }; - - apiKeyFile = mkOption { - type = types.path; - description = "Sets the api key for authentication with typesense."; - }; - }; - - postgres = { - host = mkOption { - type = types.str; - default = "/run/postgresql"; - description = "Hostname/address of the postgres server to use. If an absolute path is given here, it will be interpreted as a unix socket path."; - }; - - port = mkOption { - type = types.port; - default = 5432; - description = "The port of the postgres server to use."; - }; - - username = mkOption { - type = types.str; - default = "immich"; - description = "The postgres username to use."; - }; - - passwordFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Sets the password for authentication with postgres. - May be unset when using socket authentication. - ''; - }; - - database = mkOption { - type = types.str; - default = "immich"; - description = "The postgres database to use."; - }; - }; - - useMachineLearning = mkOption { - description = "Use the given machine learning server endpoint to enable ML functionality in immich."; - default = true; - type = types.bool; - }; - - machineLearningUrl = mkOption { - type = types.str; - default = "http://127.0.0.1:3003"; - example = "https://immich-ml.internal.example.com"; - description = "The machine learning server endpoint to use."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - REDIS_SOCKET = "/run/custom-redis"; - }; - description = '' - Extra configuration options (environment variables) for both backend and microservices. - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with both 'server' and 'microservices' for available options. - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file as defined in systemd.exec(5). May be used to provide - additional secret variables to the backend and microservices servers without - adding them to the world-readable Nix store. - ''; - }; - }; - - web = { - enable = mkEnableOption "immich web frontend" // { - default = true; - }; - - port = mkOption { - type = types.port; - default = 3000; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - serverUrl = mkOption { - type = types.str; - default = "http://127.0.0.1:3001"; - example = "https://immich-backend.internal.example.com"; - description = "The backend server url to use."; - }; - - apiUrlExternal = mkOption { - type = types.str; - default = "/web"; - description = "The api url to use for external requests."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - PUBLIC_LOGIN_PAGE_MESSAGE = "My awesome Immich instance!"; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'web' for available options. - ''; - }; - }; - - machineLearning = { - enable = mkEnableOption "immich machine-learning server" // { - default = true; - }; - - port = mkOption { - type = types.port; - default = 3003; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - MACHINE_LEARNING_MODEL_TTL = 600; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'machine learning' for available options. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - assertions = [ - { - assertion = !isServerPostgresUnix -> serverCfg.postgres.passwordFile != null; - message = "A database password must be provided when unix sockets are not used."; - } - ]; - - networking.firewall.allowedTCPPorts = mkMerge [ - (mkIf (backendCfg.enable && backendCfg.openFirewall) [ backendCfg.port ]) - (mkIf (microservicesCfg.enable && microservicesCfg.openFirewall) [ microservicesCfg.port ]) - (mkIf (webCfg.enable && webCfg.openFirewall) [ webCfg.port ]) - (mkIf (mlCfg.enable && mlCfg.openFirewall) [ mlCfg.port ]) - ]; - - services.redis.servers.immich.enable = mkIf enableRedis true; - services.redis.vmOverCommit = mkIf enableRedis (mkDefault true); - - systemd.services.immich-server = mkIf backendCfg.enable { - description = "Immich backend server (Self-hosted photo and video backup solution)"; - after = [ - "network.target" - "typesense.service" - "postgresql.service" - "immich-machine-learning.service" - ] ++ optional enableRedis "redis-immich.service"; - wantedBy = [ "multi-user.target" ]; - - environment = - serverEnv - // { - SERVER_PORT = toString backendCfg.port; - } - // mapAttrs (_: toString) serverCfg.extraConfig - // mapAttrs (_: toString) backendCfg.extraConfig; - - script = serverStartWrapper "${cfg.package}/bin/server"; - serviceConfig = mkMerge [ - (commonServiceConfig // serverServiceConfig) - { - EnvironmentFile = mkIf (backendCfg.environmentFile != null) backendCfg.environmentFile; - } - ]; - }; - - systemd.services.immich-microservices = mkIf microservicesCfg.enable { - description = "Immich microservices (Self-hosted photo and video backup solution)"; - after = [ - "network.target" - "typesense.service" - "postgresql.service" - "immich-machine-learning.service" - ] ++ optional enableRedis "redis-immich.service"; - wantedBy = [ "multi-user.target" ]; - - environment = - serverEnv - // { - MICROSERVICES_PORT = toString microservicesCfg.port; - } - // mapAttrs (_: toString) serverCfg.extraConfig - // mapAttrs (_: toString) microservicesCfg.extraConfig; - - script = serverStartWrapper "${cfg.package}/bin/microservices"; - serviceConfig = mkMerge [ - (commonServiceConfig // serverServiceConfig) - { - EnvironmentFile = mkIf (microservicesCfg.environmentFile != null) microservicesCfg.environmentFile; - } - ]; - }; - - systemd.services.immich-web = mkIf webCfg.enable { - description = "Immich web (Self-hosted photo and video backup solution)"; - after = [ - "network.target" - "immich-server.service" - ]; - wantedBy = [ "multi-user.target" ]; - - environment = { - NODE_ENV = "production"; - PORT = toString webCfg.port; - IMMICH_SERVER_URL = webCfg.serverUrl; - IMMICH_API_URL_EXTERNAL = webCfg.apiUrlExternal; - } // mapAttrs (_: toString) webCfg.extraConfig; - - script = '' - set -euo pipefail - export PUBLIC_IMMICH_SERVER_URL=$IMMICH_SERVER_URL - export PUBLIC_IMMICH_API_URL_EXTERNAL=$IMMICH_API_URL_EXTERNAL - exec ${cfg.package.web}/bin/web - ''; - serviceConfig = commonServiceConfig // { - DynamicUser = true; - User = "immich-web"; - Group = "immich-web"; - - MemoryDenyWriteExecute = false; # nodejs requires this. - - TemporaryFileSystem = "/:ro"; - BindReadOnlyPaths = [ - "/nix/store" - "-/etc/resolv.conf" - "-/etc/nsswitch.conf" - "-/etc/hosts" - "-/etc/localtime" - ]; - }; - }; - - systemd.services.immich-machine-learning = mkIf mlCfg.enable { - description = "Immich machine learning (Self-hosted photo and video backup solution)"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - - environment = { - NODE_ENV = "production"; - MACHINE_LEARNING_PORT = toString mlCfg.port; - - MACHINE_LEARNING_CACHE_FOLDER = "/var/cache/immich-ml"; - TRANSFORMERS_CACHE = "/var/cache/immich-ml"; - } // mapAttrs (_: toString) mlCfg.extraConfig; - - serviceConfig = commonServiceConfig // { - ExecStart = "${cfg.package.machine-learning}/bin/machine-learning"; - DynamicUser = true; - User = "immich-ml"; - Group = "immich-ml"; - - MemoryDenyWriteExecute = false; # onnxruntime_pybind11 requires this. - ProcSubset = "all"; # Needs /proc/cpuinfo - - CacheDirectory = "immich-ml"; - CacheDirectoryMode = "0700"; - - # TODO gpu access - - TemporaryFileSystem = "/:ro"; - BindReadOnlyPaths = [ - "/nix/store" - "-/etc/resolv.conf" - "-/etc/nsswitch.conf" - "-/etc/hosts" - "-/etc/localtime" - ]; - }; - }; - - meta.maintainers = with maintainers; [ oddlama ]; - }; -} diff --git a/modules/macos-ventura/default.nix b/modules/macos-ventura/default.nix index 919e4c8..b3824a5 100644 --- a/modules/macos-ventura/default.nix +++ b/modules/macos-ventura/default.nix @@ -1,15 +1,24 @@ -{ fleetFlake, ... }: +{ lib, ... }: { services.macos-ventura = { enable = true; cores = 8; threads = 8; - mem = "8G"; + mem = "16G"; vncListenAddr = "0.0.0.0"; + sshListenAddr = "127.0.0.1"; extraQemuFlags = [ "-nographic" ]; - sshPort = 2021; - installNix = true; - stateless = true; - darwinConfig = fleetFlake.darwinConfigurations.archer; + sshPort = 2022; + vncDisplayNumber = 1; # means port 59001 + stateless = false; + openFirewall = true; + autoStart = false; }; + + programs.ssh.extraConfig = lib.mkAfter '' + Host macos-ventura + Hostname localhost + Port 2022 + Compression yes + ''; } diff --git a/modules/mediatomb/default.nix b/modules/mediatomb/default.nix index 5608e81..d3e85b0 100644 --- a/modules/mediatomb/default.nix +++ b/modules/mediatomb/default.nix @@ -2,7 +2,7 @@ services.mediatomb = { enable = true; openFirewall = true; - serverName = "Rock 5B"; + serverName = "Sisko"; mediaDirectories = [ { path = "/mnt/hd/torrent"; diff --git a/modules/mount-rock5b/default.nix b/modules/mount-rock5b/default.nix deleted file mode 100644 index a31eb1c..0000000 --- a/modules/mount-rock5b/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - pkgs, - config, - ... -}: -{ - fileSystems."/home/${config.ccr.username}/torrent" = { - device = "//sisko.fleet/torrent"; - fsType = "cifs"; - options = - let - credentials = pkgs.writeText "credentials" '' - username=guest - password= - ''; - in - [ - "credentials=${credentials},x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s" - ]; - }; -} diff --git a/modules/mount-sisko/default.nix b/modules/mount-sisko/default.nix new file mode 100644 index 0000000..61671a5 --- /dev/null +++ b/modules/mount-sisko/default.nix @@ -0,0 +1,27 @@ +{ + pkgs, + config, + ... +}: +{ + environment.systemPackages = with pkgs; [ nfs-utils ]; + boot.supportedFilesystems = [ "nfs" ]; + services.rpcbind.enable = true; + + security.wrappers."mount.nfs" = { + setuid = true; + owner = "root"; + group = "root"; + source = "${pkgs.nfs-utils.out}/bin/mount.nfs"; + }; + + fileSystems."/home/${config.ccr.username}/nas" = { + device = "sisko.fleet:/hd"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "user" + ]; + }; +} diff --git a/modules/nextcloud/default.nix b/modules/nextcloud/default.nix index 37340e4..77d6230 100644 --- a/modules/nextcloud/default.nix +++ b/modules/nextcloud/default.nix @@ -8,11 +8,9 @@ "d /mnt/raid/nextcloud 770 nextcloud nextcloud" ]; - ccr.extraGroups = [ "nextcloud" ]; - services.nextcloud = { enable = true; - package = pkgs.nextcloud26; + package = pkgs.nextcloud_30; database.createLocally = true; home = "/mnt/raid/nextcloud"; hostName = "nextcloud.aciceri.dev"; @@ -21,6 +19,4 @@ overwriteProtocol = "https"; }; }; - - networking.firewall.allowedTCPPorts = [ 80 ]; } diff --git a/modules/paperless/default.nix b/modules/paperless/default.nix index 6770ce5..4918ed7 100644 --- a/modules/paperless/default.nix +++ b/modules/paperless/default.nix @@ -4,8 +4,7 @@ enable = true; address = "0.0.0.0"; passwordFile = builtins.toFile "paperless-initial-password" "paperless"; - mediaDir = "/mnt/hd/paperless/media"; - consumptionDir = "/mnt/hd/paperless/consume"; + mediaDir = "/mnt/hd/paperless/"; settings = { PAPERLESS_OCR_LANGUAGE = "ita+eng"; PAPERLESS_CONSUMER_IGNORE_PATTERN = builtins.toJSON [ @@ -15,11 +14,12 @@ PAPERLESS_OCR_USER_ARGS = builtins.toJSON { optimize = 1; pdfa_image_compression = "lossless"; + invalidate_digital_signatures = true; }; }; }; - backup.paths = [ + environment.persistence."/persist".directories = [ config.services.paperless.dataDir ]; } diff --git a/modules/restic/default.nix b/modules/restic/default.nix index 0d082b3..c3ba948 100644 --- a/modules/restic/default.nix +++ b/modules/restic/default.nix @@ -25,14 +25,34 @@ in host }".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs"; + services.postgresqlBackup = { + enable = true; + backupAll = true; + location = "/var/backup/postgresql"; + }; + + environment.persistence."/persist".directories = [ + config.services.postgresqlBackup.location + ]; + services.restic.backups.sisko = { - paths = [ "/persist" ]; + paths = [ + "/persist" + "/mnt/hd/immich" + "/mnt/hd/paperless" + ]; + exclude = [ " /persist/var/lib/containers" ]; passwordFile = config.age.secrets.SISKO_RESTIC_PASSWORD.path; extraOptions = [ "sftp.command='${lib.getExe pkgs.sshpass} -f ${config.age.secrets.HETZNER_STORAGE_BOX_SISKO_SSH_PASSWORD.path} ssh -p${port} ${user}@${host} -s sftp'" ]; repository = "sftp://${user}@${host}:${port}/"; initialize = true; + pruneOpts = [ + "--keep-yearly 1" + "--keep-monthly 2" + "--keep-daily 7" + ]; timerConfig.OnCalendar = "daily"; timerConfig.RandomizedDelaySec = "1h"; }; diff --git a/modules/sisko-nfs/default.nix b/modules/sisko-nfs/default.nix new file mode 100644 index 0000000..7e9b82b --- /dev/null +++ b/modules/sisko-nfs/default.nix @@ -0,0 +1,20 @@ +{ + systemd.tmpfiles.rules = [ + "d /export 770 nobody nogroup" + ]; + + fileSystems."/export/hd" = { + device = "/mnt/hd"; + options = [ "bind" ]; + }; + + services.nfs.server = { + enable = true; + exports = '' + /export 10.100.0.1/24(rw,fsid=0,no_subtree_check) + /export/hd 10.100.0.1/24(rw,nohide,insecure,no_subtree_check,no_root_squash) + ''; + }; + + networking.firewall.allowedTCPPorts = [ 2049 ]; +} diff --git a/modules/rock5b-proxy/default.nix b/modules/sisko-proxy/default.nix similarity index 85% rename from modules/rock5b-proxy/default.nix rename to modules/sisko-proxy/default.nix index 926f664..c6c1a7b 100644 --- a/modules/rock5b-proxy/default.nix +++ b/modules/sisko-proxy/default.nix @@ -36,24 +36,27 @@ proxyPass = "http://localhost:${builtins.toString config.services.invidious.port}"; }; }; - # "photos.aciceri.dev" = { - # extraConfig = '' - # client_max_body_size 50000M; - # ''; + "photos.aciceri.dev" = { + extraConfig = '' + client_max_body_size 50000M; + ''; + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:8080"; + proxyWebsockets = true; + }; + }; + "paper.aciceri.dev" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:${builtins.toString config.services.paperless.port}"; + }; + }; + # "${config.services.nextcloud.hostName}" = { # forceSSL = true; # enableACME = true; - # locations."/" = { - # proxyPass = "http://localhost:2283"; - # proxyWebsockets = true; - # }; - # }; - - # "jellyfin.aciceri.dev" = { - # forceSSL = true; - # enableACME = true; - # locations."/" = { - # proxyPass = "http://localhost:8096"; - # }; # }; # "sevenofnix.aciceri.dev" = { # forceSSL = true; diff --git a/modules/rock5b-samba/default.nix b/modules/sisko-samba/default.nix similarity index 94% rename from modules/rock5b-samba/default.nix rename to modules/sisko-samba/default.nix index 3791c92..9350089 100644 --- a/modules/rock5b-samba/default.nix +++ b/modules/sisko-samba/default.nix @@ -9,7 +9,7 @@ samba = { enable = true; - securityType = "user"; + # global.security = "user"; settings.global = { "workgroup" = "WORKGROUP"; "server string" = "rock5b"; @@ -21,7 +21,7 @@ "recycle:keeptree" = "yes"; "recycle:versions" = "yes"; }; - shares = { + settings = { torrent = { path = "/mnt/hd/torrent"; comment = "torrent"; diff --git a/modules/ssh-initrd/default.nix b/modules/ssh-initrd/default.nix index 79a936d..a67e1f3 100644 --- a/modules/ssh-initrd/default.nix +++ b/modules/ssh-initrd/default.nix @@ -14,9 +14,10 @@ extraConfig = '' HostKey /ssh_initrd_host_ed25519_key ''; - authorizedKeys = with (import ../../lib).keys.users; [ - ccr-gpg - ccr-ssh + authorizedKeys = with (import ../../lib).keys; [ + users.ccr-gpg + users.ccr-ssh + hosts.sisko ]; }; }; diff --git a/modules/syncthing/default.nix b/modules/syncthing/default.nix index b857df4..eb25947 100644 --- a/modules/syncthing/default.nix +++ b/modules/syncthing/default.nix @@ -4,12 +4,13 @@ syncthing = { enable = true; guiAddress = "${config.networking.hostName}.fleet:8434"; - user = config.ccr.username; - dataDir = "/home/${config.ccr.username}"; + # TODO Use the home-manager module instead of the following conditions + user = if config.networking.hostName == "sisko" then "syncthing" else "ccr"; + dataDir = if config.networking.hostName == "sisko" then "/mnt/hd/syncthing" else "/home/ccr"; settings = { options = { urAccepted = 1; # anonymous usage data report - globalAnnounceEnabled = false; # Only sync on the VPN + globalAnnounceEnabled = false; # Only sync when connected to the VPN }; devices = { picard = { @@ -19,7 +20,7 @@ ]; }; sisko = { - id = "L5RAQXR-6U3ANNK-UJJ5AVN-37VKQRB-UK6HXSU-NN3V6HF-JNZEVA5-NI6UEAP"; + id = "5JYQLMP-KNBMSOE-I452UDU-UTKPXJI-K27X2DI-MSCSRCG-6V54Q6U-NVGXPQA"; addresses = [ "tcp://sisko.fleet" ]; @@ -31,7 +32,7 @@ ]; }; oneplus8t = { - id = "76BJ2ZE-FPFDWUZ-3UZIENZ-TS6YBGG-EZSF6UE-GLHRBQ2-KTHTRMI-3JWNRAT"; + id = "KMB2YRF-DGTWU24-SLITU23-5TN7BMQ-6PFAQQZ-CZ7J2QL-PIGVBTU-VRFRMQV"; addresses = [ "tcp://oneplus8t.fleet" ]; @@ -41,9 +42,9 @@ org = { path = { - picard = "/home/${config.ccr.username}/org"; - sisko = "/home/${config.ccr.username}/org"; - kirk = "/home/${config.ccr.username}/org"; + picard = "/home/ccr/org"; + sisko = "/mnt/hd/syncthing/org"; + kirk = "/home/ccr/org"; } .${config.networking.hostName}; devices = [ @@ -56,9 +57,9 @@ sync = { path = { - picard = "/home/${config.ccr.username}/sync"; - sisko = "/home/${config.ccr.username}/sync"; - kirk = "/home/${config.ccr.username}/sync"; + picard = "/home/ccr/sync"; + sisko = "/mnt/hd/syncthing/sync"; + kirk = "/home/ccr/sync"; } .${config.networking.hostName}; devices = [ diff --git a/modules/transmission/default.nix b/modules/transmission/default.nix index 2a1f3cb..15db1d1 100644 --- a/modules/transmission/default.nix +++ b/modules/transmission/default.nix @@ -4,8 +4,6 @@ enable = true; openRPCPort = true; openPeerPorts = true; - # FIXME remove after https://github.com/NixOS/nixpkgs/issues/279049 - webHome = "${config.services.transmission.package}/share/transmission/web"; settings = { download-dir = "/mnt/hd/torrent"; incomplete-dir = "/mnt/hd/torrent/.incomplete"; @@ -32,7 +30,7 @@ alt-speed-time-day = 127; # all days, bitmap, 0111110 is weekends and 1000001 is weekdays ratio-limit-enabled = true; - ratio-limit = 100; # I am a generous god + ratio-limit = 2; }; }; @@ -45,8 +43,6 @@ "d /mnt/hd/torrent/.incomplete 770 transmission transmission" ]; - ccr.extraGroups = [ "transmission" ]; - environment.persistence."/persist".directories = [ config.services.transmission.home ]; diff --git a/packages/default.nix b/packages/default.nix index ace7ede..258985d 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -54,10 +54,10 @@ (name: value: { inherit name; value = pkgs.callPackage "${self}/packages/${name}" { - pkgsStable = inputs.nixpkgsStable.legacyPackages.${system}; dream2nix = inputs.dream2nix; projectRoot = self.outPath; packagePath = "packages/${name}"; + inherit inputs; }; }) (lib.filterAttrs (_: type: type == "directory") (builtins.readDir "${self}/packages")) diff --git a/packages/emacs/default.nix b/packages/emacs/default.nix new file mode 100644 index 0000000..fe77b46 --- /dev/null +++ b/packages/emacs/default.nix @@ -0,0 +1,35 @@ +{ + lib, + inputs, + pkgs, + ... +}: +let + pkgs' = pkgs.extend ( + lib.composeManyExtensions [ + inputs.emacs-overlay.overlays.package + inputs.emacs-overlay.overlays.emacs + ] + ); + all-grammars = pkgs'.tree-sitter.withPlugins builtins.attrValues; + treesitGrammars = pkgs'.runCommand "treesit-grammars" { } '' + mkdir $out + for f in ${all-grammars}/* + do + cp $f $out/"libtree-sitter-$(basename $f)" + done + ''; + emacsWithoutPackages = pkgs'.emacs-git.override { + withSQLite3 = true; + withWebP = true; + withPgtk = true; + }; + emacs = (pkgs'.emacsPackagesFor emacsWithoutPackages).emacsWithPackages ( + import ./packages.nix pkgs' + ); +in +emacs.overrideAttrs { + passthru = { + inherit treesitGrammars; + }; +} diff --git a/packages/emacs/packages.nix b/packages/emacs/packages.nix new file mode 100644 index 0000000..7baa25f --- /dev/null +++ b/packages/emacs/packages.nix @@ -0,0 +1,108 @@ +pkgs: epkgs: +let + inherit (epkgs) melpaPackages nongnuPackages elpaPackages; + + # *Attrset* containig extra emacs packages from flake inputs + + # *List* containing emacs packages from (M)ELPA + mainPackages = + # builtins.filter + # if an extra package has the same name then give precedence to it + # (package: ! builtins.elem package.pname (builtins.attrNames extraPackages)) + (with melpaPackages; [ + meow + meow-tree-sitter + dracula-theme + nord-theme + catppuccin-theme + modus-themes + # solaire-mode + nerd-icons + nerd-icons-completion + nerd-icons-ibuffer + nerd-icons-dired + ligature + treemacs-nerd-icons + eshell-syntax-highlighting + fish-completion # fish completion for eshell + eshell-prompt-extras + eshell-atuin + eshell-command-not-found + clipetty + sideline + consult-eglot + # sideline-flymake + rainbow-delimiters + vertico + marginalia + consult + orderless + embark + embark-consult + magit + magit-delta + magit-todos + difftastic + with-editor + diff-hl + corfu + cape + which-key + nix-mode + nix-ts-mode + agenix + zig-mode + unisonlang-mode + purescript-mode + dhall-mode + envrc + inheritenv + popper + paredit + yaml-mode + hl-todo + markdown-mode + haskell-mode + terraform-mode + diredfl + org-modern + org-roam + org-roam-ql + visual-fill-column + consult-org-roam + pass + password-store-otp + eldoc-box + go-translate + notmuch + consult-notmuch + poly-org + casual-calc + gptel + agenix + solidity-mode + # org-re-reveal # FIXME very not nice hash mismatch when building + # gptel # TODO uncomment when there will be a new release including GPT-4o + ]) + ++ (with elpaPackages; [ + delight + kind-icon + ef-themes + indent-bars + ]) + ++ (with nongnuPackages; [ + eat + corfu-terminal + haskell-ts-mode + ]); +in +mainPackages +# ++ (builtins.attrValues extraPackages) +# Playing with EAF +++ [ + # Disabled because pymupdf was broken + # (pkgs.callPackage ./eaf.nix { + # inherit (epkgs) melpaBuild; + # inherit (melpaPackages) ctable deferred epc s; + # }) +] diff --git a/packages/emails-watcher/default.nix b/packages/emails-watcher/default.nix new file mode 100644 index 0000000..965086f --- /dev/null +++ b/packages/emails-watcher/default.nix @@ -0,0 +1,12 @@ +{ + writers, + python3Packages, + ... +}: +writers.writePython3Bin "emails-watcher" { + libraries = with python3Packages; [ + watchdog + desktop-notifier + ]; + flakeIgnore = [ ]; +} (builtins.readFile ./emails-watcher.py) diff --git a/packages/emails-watcher/emails-watcher.py b/packages/emails-watcher/emails-watcher.py new file mode 100644 index 0000000..b9716da --- /dev/null +++ b/packages/emails-watcher/emails-watcher.py @@ -0,0 +1,43 @@ +import os +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from email import message_from_file +from desktop_notifier import DesktopNotifierSync, DEFAULT_SOUND, Icon + + +class MaildirHandler(FileSystemEventHandler): + def __init__(self, notifier): + super().__init__() + self.notifier = notifier + + def on_created(self, event): + if not event.is_directory: + print(f"New email found: {event.src_path}") + with open(event.src_path, 'r') as email_file: + msg = message_from_file(email_file) + print(f'{msg["From"]}: {msg["Subject"]}') + self.notifier.send( + title=msg["From"], + message=msg["Subject"], + sound=DEFAULT_SOUND, + icon=Icon(name="mail-message-new"), + timeout=20 + ) + + +if __name__ == "__main__": + maildir_new = os.path.expanduser(os.environ.get("INBOX_NEW")) + notifier = DesktopNotifierSync( + app_name="Mails", + notification_limit=10 + ) + + event_handler = MaildirHandler(notifier) + observer = Observer() + + observer.schedule(event_handler, maildir_new, recursive=False) + + print(f"Monitoring {maildir_new} for new emails...") + + observer.start() + observer.join() diff --git a/secrets/chatgpt-token.age b/secrets/chatgpt-token.age index 1356565..65223f0 100644 Binary files a/secrets/chatgpt-token.age and b/secrets/chatgpt-token.age differ