about summary refs log tree commit diff
path: root/nixos/modules/programs/direnv.nix
blob: 6061de58eb8e2bc8e6e465f346f7ce4ef75f9169 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
{
  lib,
  config,
  pkgs,
  ...
}: let
  cfg = config.programs.direnv;
in {
  options.programs.direnv = {

    enable = lib.mkEnableOption ''
      direnv integration. Takes care of both installation and
      setting up the sourcing of the shell. Additionally enables nix-direnv
      integration. Note that you need to logout and login for this change to apply
    '';

    package = lib.mkPackageOption pkgs "direnv" {};

    direnvrcExtra = lib.mkOption {
      type = lib.types.lines;
      default = "";
      example = ''
        export FOO="foo"
        echo "loaded direnv!"
      '';
      description = ''
        Extra lines to append to the sourced direnvrc
      '';
    };

    silent = lib.mkEnableOption ''
      the hiding of direnv logging
    '';

    loadInNixShell =
      lib.mkEnableOption ''
        loading direnv in `nix-shell` `nix shell` or `nix develop`
      ''
      // {
        default = true;
      };

    nix-direnv = {
      enable =
        (lib.mkEnableOption ''
          a faster, persistent implementation of use_nix and use_flake, to replace the built-in one
        '')
        // {
          default = true;
        };

      package = lib.mkOption {
        default = pkgs.nix-direnv.override { nix = config.nix.package; };
        defaultText = "pkgs.nix-direnv";
        type = lib.types.package;
        description = ''
          The nix-direnv package to use
        '';
      };
    };
  };

  imports = [
    (lib.mkRemovedOptionModule ["programs" "direnv" "persistDerivations"] "persistDerivations was removed as it is no longer necessary")
  ];

  config = lib.mkIf cfg.enable {

    programs = {
      zsh.interactiveShellInit = ''
        if ${lib.boolToString cfg.loadInNixShell} || printenv PATH | grep -vqc '/nix/store'; then
         eval "$(${lib.getExe cfg.package} hook zsh)"
        fi
      '';

      #$NIX_GCROOT for "nix develop" https://github.com/NixOS/nix/blob/6db66ebfc55769edd0c6bc70fcbd76246d4d26e0/src/nix/develop.cc#L530
      #$IN_NIX_SHELL for "nix-shell"
      bash.interactiveShellInit = ''
        if ${lib.boolToString cfg.loadInNixShell} || [ -z "$IN_NIX_SHELL$NIX_GCROOT$(printenv PATH | grep '/nix/store')" ] ; then
         eval "$(${lib.getExe cfg.package} hook bash)"
        fi
      '';

      fish.interactiveShellInit = ''
        if ${lib.boolToString cfg.loadInNixShell};
        or printenv PATH | grep -vqc '/nix/store';
         ${lib.getExe cfg.package} hook fish | source
        end
      '';
    };

    environment = {
      systemPackages =
        if cfg.loadInNixShell then [cfg.package]
        else [
          #direnv has a fish library which sources direnv for some reason
          (cfg.package.overrideAttrs (old: {
            installPhase =
              (old.installPhase or "")
              + ''
                rm -rf $out/share/fish
              '';
          }))
        ];

      variables = {
        DIRENV_CONFIG = "/etc/direnv";
        DIRENV_LOG_FORMAT = lib.mkIf cfg.silent "";
      };

      etc = {
        "direnv/direnvrc".text = ''
          ${lib.optionalString cfg.nix-direnv.enable ''
            #Load nix-direnv
            source ${cfg.nix-direnv.package}/share/nix-direnv/direnvrc
          ''}

           #Load direnvrcExtra
           ${cfg.direnvrcExtra}

           #Load user-configuration if present (~/.direnvrc or ~/.config/direnv/direnvrc)
           direnv_config_dir_home="''${DIRENV_CONFIG_HOME:-''${XDG_CONFIG_HOME:-$HOME/.config}/direnv}"
           if [[ -f $direnv_config_dir_home/direnvrc ]]; then
             source "$direnv_config_dir_home/direnvrc" >&2
           elif [[ -f $HOME/.direnvrc ]]; then
             source "$HOME/.direnvrc" >&2
           fi

           unset direnv_config_dir_home
        '';

        "direnv/lib/zz-user.sh".text = ''
          direnv_config_dir_home="''${DIRENV_CONFIG_HOME:-''${XDG_CONFIG_HOME:-$HOME/.config}/direnv}"

          for lib in "$direnv_config_dir_home/lib/"*.sh; do
            source "$lib"
          done

          unset direnv_config_dir_home
        '';
      };
    };
  };
}