about summary refs log tree commit diff
path: root/modules/user/sternenseemann
diff options
context:
space:
mode:
authorsternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-02-09 00:27:19 +0100
committersternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-02-09 11:49:47 +0100
commite3d77b33503950330c2f0a4b7c8d6d23d4cb61dc (patch)
tree30e26fd94f0b92b2c622a6e69736a465d3778dab /modules/user/sternenseemann
parent3601fa5464c7501719f23bfe56de5842a9e83b6c (diff)
modules/user/sternenseemann: add mandoc module
This module implements a drop-in replacement for documentation.man which
finally lets me get rid of pkgs.man-db. This is still to be considered
experimental as the required patch hasn't landed in upstream mandoc yet.
Should that happen, I'll try to contribute this module back to nixpkgs.

A more detailed description on the module and mandoc on NixOS can be
found at the top of modules/user/sternenseemann/documentation/mandoc.nix
Diffstat (limited to 'modules/user/sternenseemann')
-rw-r--r--modules/user/sternenseemann/documentation/mandoc.nix112
1 files changed, 112 insertions, 0 deletions
diff --git a/modules/user/sternenseemann/documentation/mandoc.nix b/modules/user/sternenseemann/documentation/mandoc.nix
new file mode 100644
index 00000000..10fde4eb
--- /dev/null
+++ b/modules/user/sternenseemann/documentation/mandoc.nix
@@ -0,0 +1,112 @@
+/*
+
+  This module is the result of a more serious endeavour into
+  using mandoc as a complete replacement for man-db. Using
+  mandoc for viewing manual pages already kind of works by
+  just adding mandoc to environment.systemPackages — which
+  results in a lot of ugly environment clashes.
+
+  man-db and mandoc only partially implement the same interface,
+  so it's not just a matter of switching out the used package
+  in documentation.man. However, a separate module is entirely
+  possible and even simpler than the one for man-db.
+
+  However with generating the mandoc.db for apropos(1),
+  whatis(1) and -k of man(1), we hit a bump in the road:
+  makewhatis(8) does some sanity checking of the indexed
+  man pages which also includes checking that the realpath(3)
+  of any given man page is below the indexed directory.
+  This means that all man pages which are located in /nix/store
+  (i. e. all of them) will get skipped.
+
+  This behavior is easily patched and there is also a similar
+  feature intended for homebrew which could be (ab)used. While
+  I try to get this particular fix/feature into upstream mandoc,
+  the patched package and the experimental module reside in
+  vuizvui. When everything is sorted, I'll (hopefully) be able
+  to contribute this module to nixpkgs upstream as well.
+
+  Therefore this is also a user module in vuizvui despite its
+  non-me-specific nature — I hope this will only be temporary!
+  I do promise to fix your system configurations should you
+  use this particular module, though.
+
+*/
+{ config, lib, pkgs, ... }:
+
+let
+
+  inherit (pkgs.vuizvui.sternenseemann)
+    mandoc
+    ;
+
+  inherit (pkgs.vuizvui.profpatsch)
+    getBins
+    ;
+
+  bins = getBins mandoc [ "makewhatis" ];
+
+  cfg = config.vuizvui.user.sternenseemann.documentation.mandoc;
+  docCfg = config.documentation;
+
+in {
+  options = {
+    vuizvui.user.sternenseemann.documentation.mandoc = {
+      enable = lib.mkOption {
+        type = lib.types.bool;
+        default = false;
+        description = ''
+          Whether to install the man utilities from
+          <literal>mandoc</literal> as well as manual
+          pages for installed packages from their
+          <literal>man</literal> outputs.
+          This can be used as a drop-in replacement
+          for <literal>documentation.man</literal>
+          with a few smaller differences.
+        '';
+      };
+
+      generateCaches = lib.mkOption {
+        type = lib.types.bool;
+        default = false;
+        description = ''
+          Whether to generate a <literal>mandoc.db</literal> indexing
+          the installed man pages for <literal>apropos(1)</literal>,
+          <literal>whatis(1)</literal> and the <literal>-k</literal>
+          option of <literal>man(1)</literal> using
+          <literal>makewhatis(8)</literal>.
+        '';
+      };
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    assertions = [
+      {
+        assertion = !(cfg.enable && docCfg.man.enable);
+        message = ''
+          vuizvui.user.sternenseemann.documentation.mandoc is a
+          replacement for documentation.man meaning they can't be
+          enabled at the same time.
+        '';
+      }
+    ];
+
+    environment = {
+      # globally install man pages
+      pathsToLink = [ "/share/man" ];
+      extraOutputsToInstall = [ "man" ]
+        ++ lib.optional docCfg.dev.enable "devman";
+      # tell mandoc about man pages
+      systemPackages = [ mandoc ];
+      etc."man.conf".text = ''
+        manpath /run/current-system/sw/share/man
+      '';
+      # create mandoc.db for whatis(1), apropos(1) and man(1) -k
+      # TODO(sterni): remove -p for production™
+      extraSetup = lib.optionalString cfg.generateCaches ''
+        ${bins.makewhatis} -p -T utf8 $out/share/man
+      '';
+    };
+  };
+}