about summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--configurations/manwe/default.nix5
-rw-r--r--configurations/manwe/webserver.nix1
-rw-r--r--configurations/varda/default.nix8
-rw-r--r--flake.lock84
-rw-r--r--lib/default.nix10
-rw-r--r--lib/my.nix2
-rw-r--r--modules/nixfiles/alacritty.nix2
-rw-r--r--modules/nixfiles/alertmanager.nix6
-rw-r--r--modules/nixfiles/aspell.nix23
-rw-r--r--modules/nixfiles/bluetooth.nix5
-rw-r--r--modules/nixfiles/chromium.nix15
-rw-r--r--modules/nixfiles/common/nix/default.nix26
-rw-r--r--modules/nixfiles/common/xdg.nix8
-rw-r--r--modules/nixfiles/curl.nix2
-rw-r--r--modules/nixfiles/default.nix2
-rw-r--r--modules/nixfiles/emacs/default.nix25
-rw-r--r--modules/nixfiles/emacs/doom/init.el4
-rw-r--r--modules/nixfiles/endlessh-go.nix2
-rw-r--r--modules/nixfiles/firefox/default.nix8
-rw-r--r--modules/nixfiles/firefox/profile.nix2
-rw-r--r--modules/nixfiles/firefox/userContent.css9
-rw-r--r--modules/nixfiles/git.nix293
-rw-r--r--modules/nixfiles/gnome.nix65
-rw-r--r--modules/nixfiles/gnupg.nix7
-rw-r--r--modules/nixfiles/gotify.nix6
-rw-r--r--modules/nixfiles/grafana.nix6
-rw-r--r--modules/nixfiles/ipfs.nix6
-rw-r--r--modules/nixfiles/kde.nix15
-rw-r--r--modules/nixfiles/loki.nix6
-rw-r--r--modules/nixfiles/matrix/dendrite.nix2
-rw-r--r--modules/nixfiles/monitoring/default.nix4
-rw-r--r--modules/nixfiles/nsd.nix22
-rw-r--r--modules/nixfiles/openssh.nix8
-rw-r--r--modules/nixfiles/profiles/dev/default.nix2
-rw-r--r--modules/nixfiles/profiles/dev/pystartup.py12
-rw-r--r--modules/nixfiles/profiles/headful.nix4
-rw-r--r--modules/nixfiles/prometheus.nix6
-rw-r--r--modules/nixfiles/qutebrowser.nix2
-rw-r--r--modules/nixfiles/radicale.nix6
-rw-r--r--modules/nixfiles/rtorrent.nix20
-rw-r--r--modules/nixfiles/searx.nix6
-rw-r--r--modules/nixfiles/shadowsocks.nix5
-rw-r--r--modules/nixfiles/syncthing.nix6
-rw-r--r--modules/nixfiles/zathura.nix4
44 files changed, 387 insertions, 375 deletions
diff --git a/configurations/manwe/default.nix b/configurations/manwe/default.nix
index 47a2040..5531cb9 100644
--- a/configurations/manwe/default.nix
+++ b/configurations/manwe/default.nix
@@ -23,6 +23,11 @@ with lib; {
 
     monitoring.enable = true;
 
+    git.server = {
+      enable = true;
+      domain = "git.${my.domain.azahi}";
+    };
+
     gotify.enable = true;
     matrix.dendrite = {
       enable = true;
diff --git a/configurations/manwe/webserver.nix b/configurations/manwe/webserver.nix
index fd23432..8c68441 100644
--- a/configurations/manwe/webserver.nix
+++ b/configurations/manwe/webserver.nix
@@ -7,6 +7,7 @@ with lib; {
   config.nixfiles.modules.nginx.virtualHosts = with my.domain;
     {
       ${shire}.locations."/".return = "301 https://www.youtube.com/watch?v=dQw4w9WgXcQ";
+      "git.${shire}".locations."/".return = "301 https://git.azahi.cc";
       ${azahi} = {
         serverAliases = ["frodo.${gondor}" "frodo.${rohan}"];
         locations."/".root = inputs.azahi-cc;
diff --git a/configurations/varda/default.nix b/configurations/varda/default.nix
index c0789f5..ac7b493 100644
--- a/configurations/varda/default.nix
+++ b/configurations/varda/default.nix
@@ -7,10 +7,10 @@ with lib; {
   nixfiles.modules = {
     wireguard.client.enable = true;
 
-    games.minecraft.server = {
-      enable = true;
-      memory = "6G";
-    };
+    # games.minecraft.server = {
+    #   enable = true;
+    #   memory = "6G";
+    # };
 
     acme.enable = true;
   };
diff --git a/flake.lock b/flake.lock
index 6bdb354..425a61a 100644
--- a/flake.lock
+++ b/flake.lock
@@ -98,11 +98,11 @@
     "doom-snippets": {
       "flake": false,
       "locked": {
-        "lastModified": 1659894476,
-        "narHash": "sha256-1arRqlTos5uj6N47N4hyzHMMoUBxsxaZ/NK7iN5A+ZY=",
+        "lastModified": 1662645711,
+        "narHash": "sha256-XKpPCtECGZQ5bFPPDUX3oAltXOJNwAI/OktxiLnADRE=",
         "owner": "doomemacs",
         "repo": "snippets",
-        "rev": "f957f8d195872f19c7ab0a777d592c611e10e9bb",
+        "rev": "03a62fe7edf7e87fdbd925713fbd3bf292d14b00",
         "type": "github"
       },
       "original": {
@@ -121,11 +121,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1662827147,
-        "narHash": "sha256-jq9kLeZ2iX0Vp2UcG2IbwDKjxTwG8xayFjzmQdVqBtQ=",
+        "lastModified": 1663410592,
+        "narHash": "sha256-WkcXd6uAfSfJscflb2ivOPqCgCyQGo4nUkQwIUTXtjg=",
         "owner": "nix-community",
         "repo": "emacs-overlay",
-        "rev": "463d805e875fc1ff1d15ae9c664e5aaf9b7618d3",
+        "rev": "350a3df35560f727046192cefd19e0d7e496a652",
         "type": "github"
       },
       "original": {
@@ -329,11 +329,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1662759269,
-        "narHash": "sha256-lt8bAfEZudCQb+MxoNKmenhMTXhu3RCCyLYxU9t5FFk=",
+        "lastModified": 1663328500,
+        "narHash": "sha256-7n+J/exp8ky4dmk02y5a9R7CGmJvHpzrHMzfEkMtSWA=",
         "owner": "nix-community",
         "repo": "home-manager",
-        "rev": "9f7fe353b613d0e45d7a5cdbd1f13c96c15803dd",
+        "rev": "5427f3d1f0ea4357cd4af0bffee7248d640c6ffc",
         "type": "github"
       },
       "original": {
@@ -396,11 +396,11 @@
         "ws-butler": "ws-butler"
       },
       "locked": {
-        "lastModified": 1662665437,
-        "narHash": "sha256-Aksr5xArGPbyrqEa/jxXn0/d9hc639SvpgUqfkdPLCY=",
+        "lastModified": 1662839665,
+        "narHash": "sha256-TGSRXMmRTn4eza3q0XvqpuPoeCnkktPeD0TaM/V1pZ0=",
         "owner": "nix-community",
         "repo": "nix-doom-emacs",
-        "rev": "a62512125de85c81fa8d1bb77ba8c8fe96d5b390",
+        "rev": "acbf1b70335d4fd6a6c05bc417d7f3ca44739437",
         "type": "github"
       },
       "original": {
@@ -420,11 +420,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1662774856,
-        "narHash": "sha256-vgvkBNzRs3Ukwc2sVAoPGeSglltNqLHEvbxmE89fB0I=",
+        "lastModified": 1663120334,
+        "narHash": "sha256-6OzKHiEWvvXCmoDZtiUhox8QwhftiU4yfIxhg3psPqQ=",
         "owner": "jyooru",
         "repo": "nix-minecraft-servers",
-        "rev": "d5934f64d688bba60c633b8966170b575a220867",
+        "rev": "e4e9f126df09d00e3284dbe79a92768aa898efa1",
         "type": "github"
       },
       "original": {
@@ -452,11 +452,11 @@
     },
     "nixos-hardware": {
       "locked": {
-        "lastModified": 1662714967,
-        "narHash": "sha256-IOTq5tAGGmBFj7tQbkcyLE261JUeTUucEE3p0WLZ4qM=",
+        "lastModified": 1663229557,
+        "narHash": "sha256-1uU4nsDLXKG0AHc/VCsNBAEPkTA/07juYhcEWRb1O1E=",
         "owner": "NixOS",
         "repo": "nixos-hardware",
-        "rev": "1fec8fda86dac5701146c77d5f8a414b14ed1ff6",
+        "rev": "a0df6cd6e199df4a78c833c273781ea92fa62cfb",
         "type": "github"
       },
       "original": {
@@ -468,11 +468,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1662818301,
-        "narHash": "sha256-uRjbKN924ptf5CvQ4cfki3R9nIm5EhrJBeb/xUxwfcM=",
+        "lastModified": 1663372752,
+        "narHash": "sha256-HxP/vZFDD/5Q9VEyX3VmsnCnm7vsH4IX6j/xE/+IVkc=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "a25f0b9bbdfedee45305da5d1e1410c5bcbd48f6",
+        "rev": "d9a1414346059619d9e13ab93e749bbb82e5252a",
         "type": "github"
       },
       "original": {
@@ -500,11 +500,11 @@
     },
     "nixpkgs-master": {
       "locked": {
-        "lastModified": 1662833910,
-        "narHash": "sha256-C3BbSul+GU/WoYL11s1UCeMnZ/8YaM04kOsUiCFi4fs=",
+        "lastModified": 1663446975,
+        "narHash": "sha256-MRF4NO010nzVVWRFGErFxv8/P2wRfU3BEda4H07kSOM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6b29af2b84aea67176da8ccb949555e705a04550",
+        "rev": "e986ddf417949e1a045430326a7238f9972827c9",
         "type": "github"
       },
       "original": {
@@ -516,11 +516,11 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1662824676,
-        "narHash": "sha256-KSCI31DwGmahH260LpzRLhRVFi0fNxVfgyBfTVLNZxA=",
+        "lastModified": 1663433994,
+        "narHash": "sha256-Bpthhv1PdZRrIFct8KbHACNvOu9bsYAMEaqoH83cvqM=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "15493135c0af2e5562500ab5225f2bd75b38af09",
+        "rev": "17989edb05615c4f61803b9c427d80b84c289c6b",
         "type": "github"
       },
       "original": {
@@ -582,11 +582,11 @@
     },
     "nur": {
       "locked": {
-        "lastModified": 1662834336,
-        "narHash": "sha256-GzUnijmmG37Fa1t1ygmRE1ZxthgVRj+HA/3upIZMdGw=",
+        "lastModified": 1663440270,
+        "narHash": "sha256-RkBoLyxamsBqRn9lB9RbFSDg7KHiGgHBsrpffEVXWCQ=",
         "owner": "nix-community",
         "repo": "NUR",
-        "rev": "9eb35b9992286b4c7a134b1d7fc19f9222fc8506",
+        "rev": "7511d58da488c67887745f40fd4846aa8c876d25",
         "type": "github"
       },
       "original": {
@@ -615,11 +615,11 @@
     "org": {
       "flake": false,
       "locked": {
-        "lastModified": 1662044935,
-        "narHash": "sha256-ZpxKw8L/IpxolkGyQMDut6V4i8I1T5za0QBBrztfcts=",
+        "lastModified": 1662614940,
+        "narHash": "sha256-9eAqhKXpTfZQH3bn19ien3HIzF100h8z97iHqs/QUgY=",
         "owner": "emacs-straight",
         "repo": "org-mode",
-        "rev": "e36c3cc21b8b1471e1f7928a118de693819c3f12",
+        "rev": "eb5ef0ae1424a725f933ef3929e5396a2ab727ab",
         "type": "github"
       },
       "original": {
@@ -711,11 +711,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1660830093,
-        "narHash": "sha256-HUhx3a82C7bgp2REdGFeHJdhEAzMGCk3V8xIvfBqg1I=",
+        "lastModified": 1663082609,
+        "narHash": "sha256-lmCCIu4dj59qbzkGKHQtolhpIEQMeAd2XUbXVPqgPYo=",
         "owner": "cachix",
         "repo": "pre-commit-hooks.nix",
-        "rev": "8cb8ea5f1c7bc2984f460587fddd5f2e558f6eb8",
+        "rev": "60cad1a326df17a8c6cf2bb23436609fdd83024e",
         "type": "github"
       },
       "original": {
@@ -728,11 +728,11 @@
     "revealjs": {
       "flake": false,
       "locked": {
-        "lastModified": 1660499724,
-        "narHash": "sha256-BhnEmX+8h0MVol7T4Zr2w53A+AmgzcVirpwHCR/G73U=",
+        "lastModified": 1662369032,
+        "narHash": "sha256-1BZWA3W77YbNZUj+7vJbkTeWY8O4jjPg7t5PvlEVDYA=",
         "owner": "hakimel",
         "repo": "reveal.js",
-        "rev": "b23d15c4304a9a1b72f484171fc97682e5ed85a3",
+        "rev": "8a97ad58b04045fe5a9c964aa31659bd27e665c5",
         "type": "github"
       },
       "original": {
@@ -831,11 +831,11 @@
     "ts-fold": {
       "flake": false,
       "locked": {
-        "lastModified": 1662006199,
-        "narHash": "sha256-gDelW/h2LyknTQNkHODvzCJCKelLdLIQoDh/L1lk3KA=",
+        "lastModified": 1662386895,
+        "narHash": "sha256-pYW2hcHgkr9KYdRvX2EkpOt/OL8yl+mkZ21JbMKWc8Q=",
         "owner": "jcs-elpa",
         "repo": "ts-fold",
-        "rev": "28409a0ceede0751ed9d520c6a19d1f5f1211502",
+        "rev": "017402713bd2f1fd7a691aa48afb4330f5397432",
         "type": "github"
       },
       "original": {
diff --git a/lib/default.nix b/lib/default.nix
index 6517125..d121f5e 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -28,5 +28,13 @@ lib: _: rec {
 
   mkTcpMem = min: ini: max:
     assert min <= ini && ini <= max;
-      builtins.concatMapStrings (x: toString x + " ") (map (pow 2) [min ini max]);
+      lib.concatMapStrings (x: toString x + " ") (map (pow 2) [min ini max]);
+
+  # TODO Move this somehow to the NGINX module itself.
+  nginxInternalOnly = ''
+    if ($internal != 1) {
+      return 403;
+    }
+    access_log off;
+  '';
 }
diff --git a/lib/my.nix b/lib/my.nix
index a6d88cc..6f744bc 100644
--- a/lib/my.nix
+++ b/lib/my.nix
@@ -143,6 +143,8 @@ with lib;
                 "alertmanager.${shire}"
                 "frodo.${rohan}"
                 "frodo.${gondor}"
+                "git.${azahi}"
+                "git.${shire}"
                 "gotify.${shire}"
                 "grafana.${shire}"
                 "loki.${shire}"
diff --git a/modules/nixfiles/alacritty.nix b/modules/nixfiles/alacritty.nix
index 728e6ee..bafc0d9 100644
--- a/modules/nixfiles/alacritty.nix
+++ b/modules/nixfiles/alacritty.nix
@@ -20,7 +20,7 @@ in {
           };
           dynamic_padding = false;
           decorations =
-            if (kde.enable || gnome.enable)
+            if kde.enable
             then "full"
             else "none";
         };
diff --git a/modules/nixfiles/alertmanager.nix b/modules/nixfiles/alertmanager.nix
index ee53467..e6564fb 100644
--- a/modules/nixfiles/alertmanager.nix
+++ b/modules/nixfiles/alertmanager.nix
@@ -28,11 +28,7 @@ in {
       upstreams.alertmanager.servers."127.0.0.1:${toString cfg.port}" = {};
       virtualHosts.${cfg.domain}.locations."/" = {
         proxyPass = "http://alertmanager";
-        extraConfig = ''
-          if ($internal != 1) {
-            return 403;
-          }
-        '';
+        extraConfig = nginxInternalOnly;
       };
     };
 
diff --git a/modules/nixfiles/aspell.nix b/modules/nixfiles/aspell.nix
deleted file mode 100644
index f397944..0000000
--- a/modules/nixfiles/aspell.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib; let
-  cfg = config.nixfiles.modules.aspell;
-in {
-  options.nixfiles.modules.aspell.enable =
-    mkEnableOption "GNU Aspell";
-
-  config = mkIf cfg.enable {
-    hm.home = {
-      file.".aspell.conf".text = ''
-        personal /dev/null
-        repl /dev/null
-      '';
-
-      packages = with pkgs; [(aspellWithDicts (p: with p; [en ru]))];
-    };
-  };
-}
diff --git a/modules/nixfiles/bluetooth.nix b/modules/nixfiles/bluetooth.nix
index 69622a1..a1fd58f 100644
--- a/modules/nixfiles/bluetooth.nix
+++ b/modules/nixfiles/bluetooth.nix
@@ -24,11 +24,6 @@ in {
           UserspaceHID = true;
         };
       };
-
-      systemPackages = with pkgs;
-      with config.nixfiles.modules;
-        optional gnome.enable gnome.gnome-bluetooth
-        ++ optional kde.enable plasma5Packages.bluedevil;
     };
   };
 }
diff --git a/modules/nixfiles/chromium.nix b/modules/nixfiles/chromium.nix
index 0f5a93e..337acc8 100644
--- a/modules/nixfiles/chromium.nix
+++ b/modules/nixfiles/chromium.nix
@@ -11,7 +11,11 @@ in {
 
   config = mkIf cfg.enable {
     hm = {
-      # home.sessionVariables.BROWSER = mkOverride 300 "chromium";
+      home = {
+        # sessionVariables.BROWSER = mkOverride 300 "chromium";
+
+        packages = with pkgs; [profile-cleaner];
+      };
 
       programs.chromium = {
         enable = true;
@@ -21,15 +25,6 @@ in {
         extensions =
           [
             {id = "cjpalhdlnbpafiamejdnhcphjbkeiagm";} # UBlock Origin
-            {id = "clngdbkpkpeebahjckkjfobafhncgmne";} # Stylus
-            {id = "cnojnbdhbhnkbcieeekonklommdnndci";} # Search By Image
-            {id = "doojmbjmlfjjnbmnoijecmcbfeoakpjm";} # NoScript
-            {id = "eimadpbcbfnmbkopoojfekhnkhdbieeh";} # Dark Reader
-            {id = "hlepfoohegkhhmjieoechaddaejaokhf";} # Refined GitHub
-            {id = "jinjaccalgkegednnccohejagnlnfdag";} # Violentmonkey
-            {id = "nibjojkomfdiaoajekhjakgkdhaomnch";} # IPFS Companion
-            {id = "nngceckbapebfimnlniiiahkandclblb";} # Bitwarden
-            {id = "pmcmeagblkinmogikoikkdjiligflglb";} # Privacy Redirect
           ]
           ++ optional config.nixfiles.modules.kde.enable {
             id = "cimiefiiaegbelhefglklhhakcgmhkai"; # KDE Plasma Integration
diff --git a/modules/nixfiles/common/nix/default.nix b/modules/nixfiles/common/nix/default.nix
index 9fc585b..878505c 100644
--- a/modules/nixfiles/common/nix/default.nix
+++ b/modules/nixfiles/common/nix/default.nix
@@ -82,23 +82,43 @@ with lib; {
           '';
         });
 
+        helm = with super;
+          kubernetes-helm-wrapped.override {
+            plugins = with kubernetes-helmPlugins; [helm-secrets];
+          };
+
         alejandra = super.alejandra.overrideAttrs (_: _: {
           patches = [./patches/alejandra-no-ads.patch];
         });
 
-        # https://github.com/NixOS/nixpkgs/pull/190714
-        inherit (pkgsPR "190714" "sha256-T2SXzubuN0q74QmmamPWvZHgxH7YpU8JRU0bg9RLKls=") nheko;
+        # https://github.com/NixOS/nixpkgs/pull/191633
+        inherit
+          (pkgsPR
+            "191633"
+            "sha256-gk0x/hZ/XfLo5PZ4lai4oRhawDUw68LsE2dp5c3FYIA=")
+          soju
+          ;
+
+        # Currently broken in Nixpkgs.
+        inherit
+          (pkgsRev
+            "ee01de29d2f58d56b1be4ae24c24bd91c5380cea"
+            "sha256-R18MixER2iwduNqOlLzXUms0Z7G3emnKZOKyQS52SSA=")
+          gotify-server
+          ;
       }
       // (with super; let
         np = nodePackages;
       in {
         # Normalises package names. This is done purely for aesthetics.
+        css-language-server = np.vscode-css-languageserver-bin;
         dockerfile-language-server = np.dockerfile-language-server-nodejs;
         editorconfig = editorconfig-core-c;
+        html-language-server = np.vscode-html-languageserver-bin;
         inherit (np) bash-language-server;
         inherit (np) vim-language-server;
         inherit (np) yaml-language-server;
-        json-language-server = np.vscode-json-languageserver;
+        json-language-server = np.vscode-json-languageserver-bin;
         k3d = kube3d;
         lua-language-server = sumneko-lua-language-server;
         nix-language-server = rnix-lsp;
diff --git a/modules/nixfiles/common/xdg.nix b/modules/nixfiles/common/xdg.nix
index 60d5286..8ddf1ac 100644
--- a/modules/nixfiles/common/xdg.nix
+++ b/modules/nixfiles/common/xdg.nix
@@ -25,16 +25,14 @@ with lib; {
       in {
         enable = true;
 
-        createDirectories = this.isHeadful;
-
         desktop = tmp;
         documents = "${home}/doc";
         download = tmp;
         music = tmp;
         pictures = tmp;
-        videos = tmp;
-        templates = tmp;
         publicShare = "${home}/share";
+        templates = tmp;
+        videos = tmp;
       };
     }
     (mkIf this.isHeadful {
@@ -59,7 +57,7 @@ with lib; {
               "x-scheme-handler/http"
               "x-scheme-handler/https"
             ];
-            gwenview = [
+            imv = [
               "image/bmp"
               "image/gif"
               "image/jpeg"
diff --git a/modules/nixfiles/curl.nix b/modules/nixfiles/curl.nix
index ac5e938..e7bee31 100644
--- a/modules/nixfiles/curl.nix
+++ b/modules/nixfiles/curl.nix
@@ -11,7 +11,7 @@ in {
     mkEnableOption "Wether to enable cURL.";
 
   config = mkIf cfg.enable {
-    hm.xdg.configFile.".curlrc".text = ''
+    hm.home.file.".curlrc".text = ''
       connect-timeout = 60
       progress-bar
       referer = ";auto"
diff --git a/modules/nixfiles/default.nix b/modules/nixfiles/default.nix
index c85ae77..d59273e 100644
--- a/modules/nixfiles/default.nix
+++ b/modules/nixfiles/default.nix
@@ -4,7 +4,6 @@
     ./alacritty.nix
     ./alertmanager.nix
     ./aria2.nix
-    ./aspell.nix
     ./bat.nix
     ./beets.nix
     ./bluetooth.nix
@@ -22,7 +21,6 @@
     ./fonts.nix
     ./games
     ./git.nix
-    ./gnome.nix
     ./gnupg.nix
     ./gotify.nix
     ./grafana.nix
diff --git a/modules/nixfiles/emacs/default.nix b/modules/nixfiles/emacs/default.nix
index 41b2085..6b73151 100644
--- a/modules/nixfiles/emacs/default.nix
+++ b/modules/nixfiles/emacs/default.nix
@@ -21,7 +21,7 @@ in {
 
     nixfiles.modules = {
       fonts.enable = true;
-      git.enable = true;
+      git.client.enable = true;
       gnupg.enable = true;
       x11.enable = true;
     };
@@ -40,12 +40,25 @@ in {
           # NOTE gopls will require a Go executable, which must be provided by
           # the project's flake.
           extraBins = with pkgs; [
-            (aspellWithDicts (p: with p; [en ru])) # :checkers spell (+aspell)
+            (aspellWithDicts (p: with p; [en ru])) # :checkers (spell +aspell)
+            (python3.withPackages (p:
+              with p; [
+                # :lang python :ui (treemacs +lsp)
+                black # :lang python :editor format
+                isort # :lang python
+                pyflakes # :lang python
+                python-lsp-server # :lang (python +lsp)
+              ]))
+            python3Packages.black
+            python3Packages.isort
+            python3Packages.pyflakes
+            python3Packages.python-lsp-server
             asmfmt # :editor format
             bash-language-server # :lang (sh +lsp)
             clang-tools # :lang (cc +lsp) :editor format
             cmake-format # :lang cc :editor format
             cmigemo # :lang japanese
+            css-language-server # :lang (web +lsp)
             dockerfile-language-server # :tools (docker +lsp)
             editorconfig # :tools editorconfig
             fd # doom!
@@ -62,8 +75,10 @@ in {
             haskellPackages.cabal-fmt # :lang haskell :editor format
             haskellPackages.cabal-install # :lang haskell
             haskellPackages.hoogle # :lang haskell
+            html-language-server # :lang (web +lsp)
             html-tidy # :lang web
             jre # :lang plantuml
+            json-language-server # :lang (json +lsp)
             lua-language-server # :lang (lua +lsp)
             nix-language-server # :lang (nix +lsp)
             nixfmt # :lang nix :editor format
@@ -74,11 +89,9 @@ in {
             pandoc # :lang org markdown latex
             pinentry-emacs # doom!
             pre-commit # :tools magit
-            python3Packages.black # :lang python :editor format
-            python3Packages.isort # :lang python
-            python3Packages.pyflakes # :lang python
             ripgrep # doom!
-            rust-analyzer # :lang rust
+            rust-analyzer # :lang (rust +lsp)
+            rustfmt # :lang rust
             shellcheck # :lang sh
             shfmt # :lang sh :editor format
             sqlite # :lang (org +roam2) :tools lookup
diff --git a/modules/nixfiles/emacs/doom/init.el b/modules/nixfiles/emacs/doom/init.el
index 9da7f4b..98317ec 100644
--- a/modules/nixfiles/emacs/doom/init.el
+++ b/modules/nixfiles/emacs/doom/init.el
@@ -20,7 +20,7 @@
        ophints
        (popup +defaults)
        ;; tabs
-       ;; (treemacs +lsp)
+       (treemacs +lsp)
        ;; unicode
        (vc-gutter +diff-hl +pretty)
        window-select
@@ -90,7 +90,7 @@
        (java +lsp +tree-sitter)
        (javascript +lsp +tree-sitter)
        json
-       (latex +lsp)
+       (latex +lsp +tree-sittter)
        (lua +lsp +tree-sitter)
        markdown
        (nix +lsp)
diff --git a/modules/nixfiles/endlessh-go.nix b/modules/nixfiles/endlessh-go.nix
index b89ffc4..891d484 100644
--- a/modules/nixfiles/endlessh-go.nix
+++ b/modules/nixfiles/endlessh-go.nix
@@ -27,7 +27,7 @@ in {
           listenAddress = this.wireguard.ipv4.address;
           port = 9229;
         };
-        extraOptions = ["-conn_type=tcp4" "-geoip_supplier=ip-api" "-v=1"];
+        extraOptions = ["-geoip_supplier=ip-api" "-v=1"];
       };
 
       networking.firewall.allowedTCPPorts = [port];
diff --git a/modules/nixfiles/firefox/default.nix b/modules/nixfiles/firefox/default.nix
index 6e42d76..6dde7c3 100644
--- a/modules/nixfiles/firefox/default.nix
+++ b/modules/nixfiles/firefox/default.nix
@@ -7,7 +7,7 @@
 with lib; let
   cfg = config.nixfiles.modules.firefox;
 in {
-  options.nixfiles.modules.firefox.enable = mkEnableOption "";
+  options.nixfiles.modules.firefox.enable = mkEnableOption "Firefox";
 
   config = mkIf cfg.enable {
     hm = {
@@ -16,7 +16,7 @@ in {
 
         packages = with pkgs; [
           (writeShellScriptBin "firefox-vanilla" ''
-            ${config.hm.programs.firefox.package}/bin/firefox -p vanilla $@
+            ${config.hm.programs.firefox.package}/bin/firefox -p vanilla "$@"
           '')
           profile-cleaner
         ];
@@ -28,7 +28,6 @@ in {
         package = pkgs.firefox.override {
           cfg = with config.nixfiles.modules; {
             enablePlasmaBrowserIntegration = kde.enable;
-            enableGnomeExtensions = gnome.enable;
           };
         };
 
@@ -39,9 +38,8 @@ in {
             bitwarden
             darkreader
             ipfs-companion
+            libredirect
             noscript
-            privacy-redirect
-            refined-github
             stylus
             ublock-origin
             violentmonkey
diff --git a/modules/nixfiles/firefox/profile.nix b/modules/nixfiles/firefox/profile.nix
index 6735db3..93ade51 100644
--- a/modules/nixfiles/firefox/profile.nix
+++ b/modules/nixfiles/firefox/profile.nix
@@ -474,7 +474,7 @@ in {
     # Toolbar
     #
     "browser.uiCustomization.state" = ''
-      {"placements":{"widget-overflow-fixed-list":["ublock0_raymondhill_net-browser-action","_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action","_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","ipfs-firefox-addon_lidel_org-browser-action","addon_darkreader_org-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_aecec67f-0d10-4fa7-b7c7-609a2db280cf_-browser-action"],"nav-bar":["back-button","forward-button","urlbar-container","save-to-pocket-button"],"toolbar-menubar":["menubar-items"],"TabsToolbar":["tabbrowser-tabs","new-tab-button","alltabs-button"],"PersonalToolbar":["personal-bookmarks"]},"seen":["addon_darkreader_org-browser-action","ipfs-firefox-addon_lidel_org-browser-action","plasma-browser-integration_kde_org-browser-action","ublock0_raymondhill_net-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action","_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_aecec67f-0d10-4fa7-b7c7-609a2db280cf_-browser-action","_b7f9d2cd-d772-4302-8c3f-eb941af36f76_-browser-action","developer-button","_a4c4eda4-fb84-4a84-b4a1-f7c1cbf2a1ad_-browser-action"],"dirtyAreaCache":["nav-bar","widget-overflow-fixed-list","toolbar-menubar","TabsToolbar","PersonalToolbar"],"currentVersion":17,"newElementCount":7}
+      {"placements":{"widget-overflow-fixed-list":["ublock0_raymondhill_net-browser-action","_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action","7esoorv3_alefvanoon_anonaddy_me-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action","ipfs-firefox-addon_lidel_org-browser-action","addon_darkreader_org-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_aecec67f-0d10-4fa7-b7c7-609a2db280cf_-browser-action"],"nav-bar":["back-button","forward-button","urlbar-container","save-to-pocket-button"],"toolbar-menubar":["menubar-items"],"TabsToolbar":["tabbrowser-tabs","new-tab-button","alltabs-button"],"PersonalToolbar":["personal-bookmarks"]},"seen":["addon_darkreader_org-browser-action","ipfs-firefox-addon_lidel_org-browser-action","plasma-browser-integration_kde_org-browser-action","ublock0_raymondhill_net-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action","_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_aecec67f-0d10-4fa7-b7c7-609a2db280cf_-browser-action","_b7f9d2cd-d772-4302-8c3f-eb941af36f76_-browser-action","developer-button","_a4c4eda4-fb84-4a84-b4a1-f7c1cbf2a1ad_-browser-action","7esoorv3_alefvanoon_anonaddy_me-browser-action"],"dirtyAreaCache":["nav-bar","widget-overflow-fixed-list","toolbar-menubar","TabsToolbar","PersonalToolbar"],"currentVersion":17,"newElementCount":8}
     '';
   };
 }
diff --git a/modules/nixfiles/firefox/userContent.css b/modules/nixfiles/firefox/userContent.css
index a6421e7..1dc3add 100644
--- a/modules/nixfiles/firefox/userContent.css
+++ b/modules/nixfiles/firefox/userContent.css
@@ -16,7 +16,7 @@
     }
 }
 
-@-moz-document regexp("https?:\/\/(\.*.)?gitlab(\..*)?\.(com|org).*") {
+@-moz-document regexp("https?:\/\/(.*.)?gitlab(\..*)?\.(com|org).*") {
     code {
         font-family: var(--monospace-font-family) !important;
         font-size: var(--monospace-font-size) !important;
@@ -235,11 +235,14 @@
 }
 
 @-moz-document regexp("https?:\/\/tabs\.ultimate-guitar\.com.*") {
-    #comment,
+    #comments,
     #shots,
     a[rel*="noreferrer"],
     a[target="_blank"],
-    div[class*="SiteWideBanner"] {
+    button,
+    div[class*="SiteWideBanner"],
+    footer,
+    iframe {
         display: none !important;
     }
 }
diff --git a/modules/nixfiles/git.nix b/modules/nixfiles/git.nix
index e3659f4..bccb4b3 100644
--- a/modules/nixfiles/git.nix
+++ b/modules/nixfiles/git.nix
@@ -8,120 +8,223 @@
 with lib; let
   cfg = config.nixfiles.modules.git;
 in {
-  options.nixfiles.modules.git.enable = mkEnableOption "Git";
-
-  config = mkIf cfg.enable {
-    secrets = {
-      glab-cli-config = {
-        file = "${inputs.self}/secrets/glab-cli-config";
-        path = "${config.dirs.config}/glab-cli/config.yml";
-        owner = my.username;
-        inherit (config.my) group;
-      };
-      gh-hosts = {
-        file = "${inputs.self}/secrets/gh-hosts";
-        path = "${config.dirs.config}/gh/hosts.yml";
-        owner = my.username;
-        inherit (config.my) group;
+  options.nixfiles.modules.git = {
+    client.enable = mkEnableOption "Git client";
+    server = {
+      enable = mkEnableOption "Git server";
+
+      domain = mkOption {
+        description = "Domain name sans protocol scheme.";
+        type = with types; nullOr str;
+        default = "git.${config.networking.domain}";
       };
-      hut = {
-        file = "${inputs.self}/secrets/hut";
-        path = "${config.dirs.config}/hut/config";
-        owner = my.username;
-        inherit (config.my) group;
+
+      package = mkOption {
+        description = "Package.";
+        type = types.package;
+        default = pkgs.cgit-pink;
       };
     };
+  };
 
-    hm = {
-      home.packages = with pkgs; [glab hut];
+  config = mkMerge [
+    (mkIf cfg.client.enable {
+      secrets = {
+        glab-cli-config = {
+          file = "${inputs.self}/secrets/glab-cli-config";
+          path = "${config.dirs.config}/glab-cli/config.yml";
+          owner = my.username;
+          inherit (config.my) group;
+        };
+        gh-hosts = {
+          file = "${inputs.self}/secrets/gh-hosts";
+          path = "${config.dirs.config}/gh/hosts.yml";
+          owner = my.username;
+          inherit (config.my) group;
+        };
+        hut = {
+          file = "${inputs.self}/secrets/hut";
+          path = "${config.dirs.config}/hut/config";
+          owner = my.username;
+          inherit (config.my) group;
+        };
+      };
 
-      programs = {
-        git = {
-          enable = true;
+      hm = {
+        home.packages = with pkgs; [glab hut];
 
-          package = pkgs.git.override {
-            sendEmailSupport = true;
-            withSsh = true;
-          };
+        programs = {
+          git = {
+            enable = true;
 
-          userName = my.fullname;
-          userEmail = my.email;
-          signing = {
-            inherit (my.pgp) key;
-            signByDefault = true;
-          };
+            package = pkgs.git.override {
+              doInstallCheck = false;
+              pythonSupport = false;
+              sendEmailSupport = true;
+              withLibsecret = false;
+              withSsh = true;
+            };
+
+            userName = my.fullname;
+            userEmail = my.email;
+            signing = {
+              inherit (my.pgp) key;
+              signByDefault = true;
+            };
 
-          extraConfig =
-            {
-              advice.detachedHead = false;
-              color.ui = true;
-              core.whitespace = "trailing-space";
-              diff = {
-                mnemonicPrefix = true;
-                renames = "copies";
-                submodule = "log";
+            extraConfig =
+              {
+                advice.detachedHead = false;
+                color.ui = true;
+                core.whitespace = "trailing-space";
+                diff = {
+                  mnemonicPrefix = true;
+                  renames = "copies";
+                  submodule = "log";
+                };
+                init.defaultBranch = "master";
+                status.submoduleSummary = true;
+                github.user = my.username;
+                gitlab.user = my.username;
+              }
+              // mapAttrs'
+              (n: v: nameValuePair ''url "git@${v}:"'' {insteadOf = "${n}:";}) {
+                "bitbucket" = "bitbucket.com";
+                "codeberg" = "codeberg.org";
+                "github" = "github.com";
+                "gitlab" = "gitlab.com";
+                "sourcehut" = "git.sr.ht";
               };
-              init.defaultBranch = "master";
-              status.submoduleSummary = true;
-              github.user = my.username;
-              gitlab.user = my.username;
-            }
-            // mapAttrs'
-            (n: v: nameValuePair ''url "git@${v}:"'' {insteadOf = "${n}:";}) {
-              "bitbucket" = "bitbucket.com";
-              "codeberg" = "codeberg.org";
-              "github" = "github.com";
-              "gitlab" = "gitlab.com";
-              "sourcehut" = "git.sr.ht";
+
+            aliases = let
+              git = "${config.hm.programs.git.package}/bin/git";
+              curl = "${pkgs.curl}/bin/curl";
+            in {
+              fuck = "!${git} reset --hard && ${git} clean -fdx";
+              gud = ''commit -m "git gud"'';
+              wtc = "!${curl} -sq whatthecommit.com/index.txt | ${git} commit -F -";
             };
 
-          aliases = let
-            git = "${config.hm.programs.git.package}/bin/git";
-            curl = "${pkgs.curl}/bin/curl";
-          in {
-            fuck = "!${git} reset --hard && ${git} clean -fdx";
-            gud = ''commit -m "git gud"'';
-            wtc = "!${curl} -sq whatthecommit.com/index.txt | ${git} commit -F -";
+            # All helper tools/editor generated files should go here. This must
+            # be kept relatively clean and void of any project-specific residual
+            # files.
+            ignores = [
+              "*~"
+              ".cache/clangd/"
+              ".ccls-cache/"
+              ".dir-locals.el"
+              ".gdb_history"
+              ".netrwhist"
+              ".projectile"
+              "[._]*.s[a-v][a-z]"
+              "[._]*.sw[a-p]"
+              "[._]s[a-rt-v][a-z]"
+              "[._]ss[a-gi-z]"
+              "[._]sw[a-p]"
+              "\#*\#"
+              "compile_commands.json"
+              "cscope.*"
+              "vgcore.*"
+            ];
+          };
+
+          gh = {
+            enable = true;
+            settings.git_protocol = "ssh";
           };
 
-          # All helper tool/editor generated files should go here. This must be
-          # kept relatively clean and void of any tooling/project-specific
-          # residual files.
-          ignores = [
-            "*~"
-            ".ccls-cache/"
-            ".clangd/"
-            ".dir-locals.el"
-            ".gdb_history"
-            ".netrwhist"
-            "[._]*.s[a-v][a-z]"
-            "[._]*.sw[a-p]"
-            "[._]s[a-rt-v][a-z]"
-            "[._]ss[a-gi-z]"
-            "[._]sw[a-p]"
-            "\\#*\\#"
-            "compile_commands.json"
-            "cscope.*"
-            "vgcore.*"
-          ];
+          bash = {
+            shellAliases.gl = "${pkgs.glab}/bin/glab";
+            initExtra = mkAfter "_complete_alias gl __start_glab glab";
+          };
         };
 
-        gh = {
-          enable = true;
-          settings.git_protocol = "ssh";
+        xdg.configFile."glab-cli/aliases.yml".text = generators.toYAML {} {
+          ci = "pipeline ci";
+          co = "mr checkout";
+          li = "ci lint";
         };
+      };
+    })
+    (mkIf cfg.server.enable {
+      nixfiles.modules.nginx = {
+        enable = true;
+        virtualHosts.${cfg.server.domain} = {
+          locations = {
+            "/".extraConfig = let
+              projectList = pkgs.writeText "cgit-project-list" ''
+                nixfiles.git
+              '';
+
+              cgitrc = pkgs.writeText "cgitrc" ''
+                root-title=azahi’s git stuff
+                root-desc=鯛も一人はうまからず
+
+                about-filter=${cfg.server.package}/lib/cgit/filters/about-formatting.sh
+                source-filter=${cfg.server.package}/lib/cgit/filters/syntax-highlighting.py
+                commit-filter=${cfg.server.package}/lib/cgit/filters/commit-links.sh
+
+                enable-blame=1
+                enable-commit-graph=1
+                enable-follow-links=1
+                enable-git-config=1
+                enable-html-serving=1
+                enable-index-links=1
+                enable-index-owner=1
+                enable-log-filecount=1
+                enable-log-linecount=1
+                enable-remote-branches=1
+                enable-subject-links=1
+                enable-tree-linenumbers=1
+
+                remove-suffix=1
+
+                snapshots=tar.gz tar.bz2 zip
+
+                readme=:README
+                readme=:README.md
+                readme=:README.org
+                readme=:README.txt
+                readme=:readme
+                readme=:readme.md
+                readme=:readme.org
+                readme=:readme.txt
 
-        bash = {
-          shellAliases.gl = "${pkgs.glab}/bin/glab";
-          initExtra = mkAfter "_complete_alias gl __start_glab glab";
+                project-list=${projectList}
+                scan-path=${config.services.gitolite.dataDir}/repositories
+              '';
+            in ''
+              include ${config.services.nginx.package}/conf/fastcgi_params;
+              fastcgi_split_path_info ^(/?)(.+)$;
+              fastcgi_pass unix:${config.services.fcgiwrap.socketAddress};
+              fastcgi_param SCRIPT_FILENAME ${cfg.server.package}/cgit/cgit.cgi;
+              fastcgi_param CGIT_CONFIG ${cgitrc};
+              fastcgi_param PATH_INFO $uri;
+              fastcgi_param QUERY_STRING $args;
+              fastcgi_param HTTP_HOST $server_name;
+            '';
+            "~* ^/(.+.(ico|css|png))$".extraConfig = ''
+              alias ${cfg.server.package}/cgit/$1;
+            '';
+          };
         };
       };
 
-      xdg.configFile."glab-cli/aliases.yml".text = generators.toYAML {} {
-        ci = "pipeline ci";
-        co = "mr checkout";
-        li = "ci lint";
+      services = let
+        user = "git";
+        group = "git";
+      in {
+        gitolite = {
+          enable = true;
+          inherit user group;
+          adminPubkey = my.ssh.key;
+        };
+
+        fcgiwrap = {
+          enable = true;
+          inherit user group;
+        };
       };
-    };
-  };
+    })
+  ];
 }
diff --git a/modules/nixfiles/gnome.nix b/modules/nixfiles/gnome.nix
deleted file mode 100644
index 4646d94..0000000
--- a/modules/nixfiles/gnome.nix
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-with lib; let
-  cfg = config.nixfiles.modules.gnome;
-in {
-  options.nixfiles.modules.gnome.enable =
-    mkEnableOption "GNOME desktop environment";
-
-  config = mkIf cfg.enable {
-    nixfiles.modules = {
-      gnupg.pinentry = mkForce "gnome";
-      sound.enable = true;
-      x11.enable = true;
-    };
-
-    services = {
-      xserver = {
-        enable = true;
-        desktopManager.gnome.enable = true;
-        displayManager.gdm = {
-          enable = true;
-          wayland = false;
-        };
-      };
-
-      gnome = {
-        core-os-services.enable = true;
-        core-shell.enable = true;
-        core-utilities.enable = false;
-        core-developer-tools.enable = false;
-        games.enable = false;
-
-        chrome-gnome-shell.enable = false;
-        gnome-initial-setup.enable = false;
-        gnome-online-accounts.enable = false;
-        gnome-remote-desktop.enable = false;
-        gnome-settings-daemon.enable = true;
-        gnome-user-share.enable = false;
-        rygel.enable = false;
-        tracker-miners.enable = false;
-        tracker.enable = false;
-      };
-
-      dleyna-renderer.enable = false;
-      dleyna-server.enable = false;
-    };
-
-    environment = {
-      gnome = {
-        excludePackages = with pkgs.gnome; [
-          geary
-          gnome-disk-utility
-          seahorse
-          sushi
-        ];
-      };
-
-      systemPackages = with pkgs; [pinentry-gnome];
-    };
-  };
-}
diff --git a/modules/nixfiles/gnupg.nix b/modules/nixfiles/gnupg.nix
index 67d36d8..c1419e4 100644
--- a/modules/nixfiles/gnupg.nix
+++ b/modules/nixfiles/gnupg.nix
@@ -12,12 +12,7 @@ in {
     pinentry = mkOption {
       description = "Name of a pinentry implementation.";
       type = types.str;
-      default = with config.nixfiles.modules;
-        if kde.enable
-        then "qt"
-        else if gnome.enable
-        then "gnome"
-        else "curses";
+      default = "curses";
     };
   };
 
diff --git a/modules/nixfiles/gotify.nix b/modules/nixfiles/gotify.nix
index 1cfd9a7..8489e93 100644
--- a/modules/nixfiles/gotify.nix
+++ b/modules/nixfiles/gotify.nix
@@ -27,11 +27,7 @@ in {
           virtualHosts.${cfg.domain}.locations."/" = {
             proxyPass = "http://gotify";
             proxyWebsockets = true;
-            extraConfig = ''
-              if ($internal != 1) {
-                return 403;
-              }
-            '';
+            extraConfig = nginxInternalOnly;
           };
         };
         postgresql.enable = true;
diff --git a/modules/nixfiles/grafana.nix b/modules/nixfiles/grafana.nix
index fcc85f8..c29bf75 100644
--- a/modules/nixfiles/grafana.nix
+++ b/modules/nixfiles/grafana.nix
@@ -44,11 +44,7 @@ in {
         virtualHosts.${cfg.domain}.locations."/" = {
           proxyPass = "http://grafana";
           proxyWebsockets = true;
-          extraConfig = ''
-            if ($internal != 1) {
-              return 403;
-            }
-          '';
+          extraConfig = nginxInternalOnly;
         };
       };
       postgresql.enable = true;
diff --git a/modules/nixfiles/ipfs.nix b/modules/nixfiles/ipfs.nix
index 1b1c802..f998d6d 100644
--- a/modules/nixfiles/ipfs.nix
+++ b/modules/nixfiles/ipfs.nix
@@ -159,11 +159,7 @@ in {
             # TODO Redirect "/" to "/webui" but keep other endpoints.
             locations."/" = {
               proxyPass = "http://ipfs_api";
-              extraConfig = ''
-                if ($internal != 1) {
-                  return 403;
-                }
-              '';
+              extraConfig = nginxInternalOnly;
             };
           };
         };
diff --git a/modules/nixfiles/kde.nix b/modules/nixfiles/kde.nix
index 934f114..e22663c 100644
--- a/modules/nixfiles/kde.nix
+++ b/modules/nixfiles/kde.nix
@@ -7,17 +7,26 @@
 with lib; let
   cfg = config.nixfiles.modules.kde;
 in {
-  options.nixfiles.modules.kde.enable = mkEnableOption "KDE Plasma 5 desktop environment";
+  options.nixfiles.modules.kde.enable = mkEnableOption "KDE Plasma";
 
   config = mkIf cfg.enable {
     nixfiles.modules = {
-      gnupg.pinentry = mkForce "qt";
+      gnupg.pinentry = "qt";
       sound.enable = true;
       x11.enable = true;
     };
 
     services.xserver = {
-      desktopManager.plasma5.enable = true;
+      desktopManager.plasma5 = {
+        enable = true;
+        excludePackages = with pkgs.plasma5Packages; [
+          elisa
+          gwenview
+          khelpcenter
+          okular
+          print-manager
+        ];
+      };
       displayManager.sddm.enable = true;
     };
 
diff --git a/modules/nixfiles/loki.nix b/modules/nixfiles/loki.nix
index 77b6ca0..4d9aab7 100644
--- a/modules/nixfiles/loki.nix
+++ b/modules/nixfiles/loki.nix
@@ -29,11 +29,7 @@ in {
       upstreams.loki.servers."127.0.0.1:${toString cfg.port}" = {};
       virtualHosts.${domain}.locations."/" = {
         proxyPass = "http://loki";
-        extraConfig = ''
-          if ($internal != 1) {
-            return 403;
-          }
-        '';
+        extraConfig = nginxInternalOnly;
       };
     };
 
diff --git a/modules/nixfiles/matrix/dendrite.nix b/modules/nixfiles/matrix/dendrite.nix
index 4792f0e..8dbc318 100644
--- a/modules/nixfiles/matrix/dendrite.nix
+++ b/modules/nixfiles/matrix/dendrite.nix
@@ -21,7 +21,7 @@ in {
   config = mkIf cfg.enable {
     secrets.dendrite-private-key = {
       file = "${inputs.self}/secrets/dendrite-private-key";
-      mode = "0444"; # User is dynamic.
+      mode = "0444"; # FIXME User is dynamic so the file must be world-readable.
     };
 
     nixfiles.modules = {
diff --git a/modules/nixfiles/monitoring/default.nix b/modules/nixfiles/monitoring/default.nix
index c439614..35261e2 100644
--- a/modules/nixfiles/monitoring/default.nix
+++ b/modules/nixfiles/monitoring/default.nix
@@ -7,7 +7,7 @@
 with lib; let
   cfg = config.nixfiles.modules.monitoring;
 in {
-  options.nixfiles.modules.monitoring.enable = mkEnableOption "custom monitoring stack";
+  options.nixfiles.modules.monitoring.enable = mkEnableOption "a custom monitoring stack";
 
   config = mkIf cfg.enable {
     nixfiles.modules = {
@@ -65,6 +65,8 @@ in {
       loki.configuration.ruler.alertmanager_url = "https://${config.nixfiles.modules.alertmanager.domain}";
 
       prometheus = {
+        # It would be nice if these could be generated dynamically. That would
+        # require a complete rework of how configurations are defined, though.
         scrapeConfigs = with my.configurations;
         with config.services.prometheus.exporters; [
           {
diff --git a/modules/nixfiles/nsd.nix b/modules/nixfiles/nsd.nix
index acbfd07..57973ee 100644
--- a/modules/nixfiles/nsd.nix
+++ b/modules/nixfiles/nsd.nix
@@ -26,7 +26,6 @@ in {
         ipTransparent = true;
         ratelimit.enable = true;
 
-        # TODO DNSSEC.
         zones = let
           dns = inputs.dns-nix.lib;
         in
@@ -37,7 +36,6 @@ in {
                 AAAA = [(aaaa ipv6.address)];
               };
 
-            # TODO Try moving DKIM keys somewhere in "my" or secrets maybe?
             mkEmailEntries = {
               domain ? my.domain.shire,
               dkimKey ? null,
@@ -70,7 +68,7 @@ in {
                   SOA = {
                     nameServer = "${cfg.fqdn}.";
                     adminEmail = "admin+dns@${my.domain.shire}";
-                    serial = 2022091420;
+                    serial = 2022091601; # Don't forget to bump the revision!
                   };
 
                   NS = with my.domain; [
@@ -84,6 +82,10 @@ in {
                 extra
               ]);
             };
+
+            # https://ariadne.id/
+            # https://docs.keyoxide.org/service-providers/dns/
+            ariadneIdProof.TXT = ["openpgp4fpr:${my.pgp.fingerprint}"];
           in
             mkMerge [
               (mkZone {
@@ -105,15 +107,18 @@ in {
                       # ns2 = varda;
 
                       alertmanager = manwe;
-                      flood = yavanna;
+                      git = manwe;
                       gotify = manwe;
                       grafana = manwe;
                       loki = manwe;
-                      minecraft = varda;
                       prometheus = manwe;
                       radicale = manwe;
                       rss-bridge = manwe;
                       vaultwarden = manwe;
+
+                      minecraft = varda;
+
+                      flood = yavanna;
                     };
                   }
                 ];
@@ -124,8 +129,9 @@ in {
                   (mkEmailEntries {
                     dkimKey = "@DKIM_KEY@";
                   })
+                  ariadneIdProof
                   {
-                    TXT = ["openpgp4fpr:${my.pgp.fingerprint}"]; # https://docs.keyoxide.org/service-providers/dns/
+                    subdomains.git = ips "manwe";
                   }
                 ];
               })
@@ -136,7 +142,7 @@ in {
                     dkimKey = "@DKIM_KEY@";
                   })
                   {
-                    subdomains.frodo = ips "manwe";
+                    subdomains.frodo = ips "manwe" // ariadneIdProof;
                   }
                 ];
               })
@@ -147,7 +153,7 @@ in {
                     dkimKey = "@DKIM_KEY@";
                   })
                   {
-                    subdomains.frodo = ips "manwe";
+                    subdomains.frodo = ips "manwe" // ariadneIdProof;
                   }
                 ];
               })
diff --git a/modules/nixfiles/openssh.nix b/modules/nixfiles/openssh.nix
index 2bae2da..bf470ca 100644
--- a/modules/nixfiles/openssh.nix
+++ b/modules/nixfiles/openssh.nix
@@ -54,9 +54,11 @@ in {
             in
               internalServers
               // (mapAttrs' mkBlock {
-                # Custom blocks go here.
-                #
-                # example.hostname = "129.168.70.80";
+                gitolite = {
+                  user = "git";
+                  hostname = "git.${my.domain.shire}";
+                  inherit port;
+                };
               });
           };
         };
diff --git a/modules/nixfiles/profiles/dev/default.nix b/modules/nixfiles/profiles/dev/default.nix
index 14c0730..1a0ad07 100644
--- a/modules/nixfiles/profiles/dev/default.nix
+++ b/modules/nixfiles/profiles/dev/default.nix
@@ -20,7 +20,7 @@ in {
       bat.enable = true;
       curl.enable = true;
       direnv.enable = true;
-      git.enable = true;
+      git.client.enable = true;
       gnupg.enable = true;
       nmap.enable = true;
       wget.enable = true;
diff --git a/modules/nixfiles/profiles/dev/pystartup.py b/modules/nixfiles/profiles/dev/pystartup.py
index 1a78b55..adde66c 100644
--- a/modules/nixfiles/profiles/dev/pystartup.py
+++ b/modules/nixfiles/profiles/dev/pystartup.py
@@ -32,9 +32,7 @@ class TermColors(dict):
     color_base = "\001\033[%sm\002"
 
     def __init__(self):
-        self.update(
-            dict([(k, self.color_base % v) for k, v in self.color_templates])
-        )
+        self.update(dict([(k, self.color_base % v) for k, v in self.color_templates]))
 
 
 class Completer(object):
@@ -44,16 +42,12 @@ class Completer(object):
         readline.write_history_file(self.python_histfile)
 
     def __init__(self):
-        self.python_dir = os.path.expanduser(
-            "%s/python" % os.environ["XDG_DATA_HOME"]
-        )
+        self.python_dir = os.path.expanduser("%s/python" % os.environ["XDG_DATA_HOME"])
 
         if not os.path.exists(self.python_dir):
             os.mkdir(self.python_dir)
 
-        self.python_histfile = os.path.expanduser(
-            "%s/history" % self.python_dir
-        )
+        self.python_histfile = os.path.expanduser("%s/history" % self.python_dir)
 
         if os.path.exists(self.python_histfile):
             readline.read_history_file(self.python_histfile)
diff --git a/modules/nixfiles/profiles/headful.nix b/modules/nixfiles/profiles/headful.nix
index ba54b03..afe9194 100644
--- a/modules/nixfiles/profiles/headful.nix
+++ b/modules/nixfiles/profiles/headful.nix
@@ -27,7 +27,6 @@ in {
       x11.enable = true;
 
       dwm.enable = mkDefault false;
-      gnome.enable = mkDefault false;
       kde.enable = mkDefault true;
       xmonad.enable = mkDefault false;
     };
@@ -35,8 +34,7 @@ in {
     hm = {
       home.packages = with pkgs; [
         calibre
-        convmv
-        dos2unix
+        imv
         kotatogram-desktop
         nheko
         tor-browser
diff --git a/modules/nixfiles/prometheus.nix b/modules/nixfiles/prometheus.nix
index e816b74..0b0c096 100644
--- a/modules/nixfiles/prometheus.nix
+++ b/modules/nixfiles/prometheus.nix
@@ -28,11 +28,7 @@ in {
       upstreams.prometheus.servers."127.0.0.1:${toString cfg.port}" = {};
       virtualHosts.${domain}.locations."/" = {
         proxyPass = "http://prometheus";
-        extraConfig = ''
-          if ($internal != 1) {
-            return 403;
-          }
-        '';
+        extraConfig = nginxInternalOnly;
       };
     };
 
diff --git a/modules/nixfiles/qutebrowser.nix b/modules/nixfiles/qutebrowser.nix
index dd1d027..186623a 100644
--- a/modules/nixfiles/qutebrowser.nix
+++ b/modules/nixfiles/qutebrowser.nix
@@ -245,7 +245,7 @@ in {
           };
 
           window = {
-            hide_decoration = false; # TODO Test in a WM.
+            hide_decoration = false;
             title_format = "{perc}{current_title}{title_sep}qutebrowser";
           };
 
diff --git a/modules/nixfiles/radicale.nix b/modules/nixfiles/radicale.nix
index 679a8be..76f6b49 100644
--- a/modules/nixfiles/radicale.nix
+++ b/modules/nixfiles/radicale.nix
@@ -32,11 +32,7 @@ in {
         upstreams.radicale.servers."127.0.0.1:${toString port}" = {};
         virtualHosts.${cfg.domain}.locations."/" = {
           proxyPass = "http://radicale";
-          extraConfig = ''
-            if ($internal != 1) {
-              return 403;
-            }
-          '';
+          extraConfig = nginxInternalOnly;
         };
       };
 
diff --git a/modules/nixfiles/rtorrent.nix b/modules/nixfiles/rtorrent.nix
index 121f1ca..9f28c61 100644
--- a/modules/nixfiles/rtorrent.nix
+++ b/modules/nixfiles/rtorrent.nix
@@ -196,22 +196,16 @@ in {
               locations = {
                 "/" = {
                   tryFiles = "$uri /index.html";
-                  extraConfig = ''
-                    if ($internal != 1) {
-                      return 403;
-                    }
-                  '';
+                  extraConfig = nginxInternalOnly;
                 };
                 "/api" = {
                   proxyPass = "http://flood";
-                  extraConfig = ''
-                    proxy_buffering off;
-                    proxy_cache off;
-
-                    if ($internal != 1) {
-                      return 403;
-                    }
-                  '';
+                  extraConfig =
+                    nginxInternalOnly
+                    + ''
+                      proxy_buffering off;
+                      proxy_cache off;
+                    '';
                 };
               };
             };
diff --git a/modules/nixfiles/searx.nix b/modules/nixfiles/searx.nix
index fd11904..24482cc 100644
--- a/modules/nixfiles/searx.nix
+++ b/modules/nixfiles/searx.nix
@@ -35,11 +35,7 @@ in {
       upstreams.searx.servers."127.0.0.1:${toString cfg.port}" = {};
       virtualHosts.${cfg.domain}.locations."/" = {
         proxyPass = "http://searx";
-        extraConfig = ''
-          if ($internal != 1) {
-            return 403;
-          }
-        '';
+        extraConfig = nginxInternalOnly;
       };
     };
 
diff --git a/modules/nixfiles/shadowsocks.nix b/modules/nixfiles/shadowsocks.nix
index 6e98e97..b59359c 100644
--- a/modules/nixfiles/shadowsocks.nix
+++ b/modules/nixfiles/shadowsocks.nix
@@ -19,10 +19,7 @@ in {
   };
 
   config = mkIf cfg.enable {
-    secrets.shadowsocks-password = {
-      file = "${inputs.self}/secrets/shadowsocks-password";
-      mode = "0444"; # User is dynamic.
-    };
+    secrets.shadowsocks-password.file = "${inputs.self}/secrets/shadowsocks-password";
 
     services = {
       shadowsocks = {
diff --git a/modules/nixfiles/syncthing.nix b/modules/nixfiles/syncthing.nix
index 31286fa..ed51e73 100644
--- a/modules/nixfiles/syncthing.nix
+++ b/modules/nixfiles/syncthing.nix
@@ -137,11 +137,7 @@ in {
         upstreams.syncthing.servers.${config.services.syncthing.guiAddress} = {};
         virtualHosts.${cfg.domain}.locations."/" = {
           proxyPass = "http://syncthing";
-          extraConfig = ''
-            if ($internal != 1) {
-              return 403;
-            }
-          '';
+          extraConfig = nginxInternalOnly;
         };
       };
     })
diff --git a/modules/nixfiles/zathura.nix b/modules/nixfiles/zathura.nix
index 03a8311..1a0b39a 100644
--- a/modules/nixfiles/zathura.nix
+++ b/modules/nixfiles/zathura.nix
@@ -112,8 +112,8 @@ in {
           scroll-wrap = true;
           scroll-page-aware = false;
 
-          selection-clipboard = with config.nixfiles.modules;
-            if (kde.enable || gnome.enable)
+          selection-clipboard =
+            if config.nixfiles.modules.kde.enable
             then "clipboard"
             else "primary";
           selection-notification = false;

Consider giving Nix/NixOS a try! <3