about summary refs log tree commit diff
path: root/modules/user/sternenseemann/documentation/mandoc.nix
blob: 10fde4eb35470cde8a021d955abcd88884c3dcdf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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
      '';
    };
  };
}