aboutsummaryrefslogtreecommitdiff
path: root/modules/manual.nix
blob: d597d002dbf324470976ce3ff65fdf748213dc06 (plain)
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
{ config, lib, pkgs, baseModules, ... }:

with lib;

let

  cfg = config.manual;

  /* For the purpose of generating docs, evaluate options with each derivation
    in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
    It isn't perfect, but it seems to cover a vast majority of use cases.
    Caveat: even if the package is reached by a different means,
    the path above will be shown and not e.g. `${config.services.foo.package}`. */
  homeManagerManual = import ../doc {
    inherit pkgs config;
    version = "0.1";
    revision = "master";
    options =
      let
        scrubbedEval = evalModules {
          modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules;
          args = (config._module.args) // { modules = [ ]; };
          specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
        };
        scrubDerivations = namePrefix: pkgSet: mapAttrs
          (name: value:
            let wholeName = "${namePrefix}.${name}"; in
            if isAttrs value then
              scrubDerivations wholeName value
              // (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
            else value
          )
          pkgSet;
      in scrubbedEval.options;
  };

  manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";

  helpScript = pkgs.writeShellScriptBin "home-manager-help" ''
    #!${pkgs.bash}/bin/bash -e

    if [ -z "$BROWSER" ]; then
      for candidate in xdg-open open w3m; do
        BROWSER="$(type -P $candidate || true)"
        if [ -x "$BROWSER" ]; then
          break;
        fi
      done
    fi

    if [ -z "$BROWSER" ]; then
      echo "$0: unable to start a web browser; please set \$BROWSER"
      exit 1
    fi

    exec "$BROWSER" ${manualHtmlRoot}
  '';

in

{
  options = {
    manual.html.enable = mkOption {
      type = types.bool;
      default = false;
      description = ''
        Whether to install the HTML manual. This also installs the
        <command>home-manager-help</command> tool, which opens a local
        copy of the Home Manager manual in the system web browser.
      '';
    };

    manual.manpages.enable = mkOption {
      type = types.bool;
      default = true;
      example = false;
      description = ''
        Whether to install the configuration manual page. The manual can
        be reached by <command>man home-configuration.nix</command>.
        </para><para>
        When looking at the manual page pretend that all references to
        NixOS stuff are actually references to Home Manager stuff.
        Thanks!
      '';
    };
  };

  config = {
    home.packages = mkMerge [
      (mkIf cfg.html.enable [ helpScript homeManagerManual.manual  ])

      (mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
    ];
  };

  # To fix error during manpage build.
  meta = {
    maintainers = [ maintainers.rycee ];
    doc = builtins.toFile "nothingness" "";
  };
}