From 194a3a7d97d3d533e9ce52df77b0673d75bfe07f Mon Sep 17 00:00:00 2001 From: Gerg-L Date: Tue, 4 Jul 2023 13:04:42 -0400 Subject: [PATCH] nixos/direnv: init --- nixos/modules/module-list.nix | 1 + nixos/modules/programs/direnv.nix | 147 ++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 nixos/modules/programs/direnv.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index bd715535dd6..f866933923b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -156,6 +156,7 @@ ./programs/darling.nix ./programs/dconf.nix ./programs/digitalbitbox/default.nix + ./programs/direnv.nix ./programs/dmrconfig.nix ./programs/droidcam.nix ./programs/environment.nix diff --git a/nixos/modules/programs/direnv.nix b/nixos/modules/programs/direnv.nix new file mode 100644 index 00000000000..53717fae11a --- /dev/null +++ b/nixos/modules/programs/direnv.nix @@ -0,0 +1,147 @@ +{ + lib, + config, + pkgs, + ... +}: let + cfg = config.programs.direnv; +in { + options.programs.direnv = { + + enable = lib.mkEnableOption (lib.mdDoc '' + 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.mkPackageOptionMD pkgs "direnv" {}; + + direnvrcExtra = lib.mkOption { + type = lib.types.lines; + default = ""; + example = '' + export FOO="foo" + echo "loaded direnv!" + ''; + description = lib.mdDoc '' + Extra lines to append to the sourced direnvrc + ''; + }; + + silent = lib.mkEnableOption (lib.mdDoc '' + the hiding of direnv logging + ''); + + persistDerivations = + (lib.mkEnableOption (lib.mdDoc '' + setting keep-derivations and keep-outputs to true + to prevent shells from getting garbage collected + '')) + // { + default = true; + }; + + loadInNixShell = + lib.mkEnableOption (lib.mdDoc '' + loading direnv in `nix-shell` `nix shell` or `nix develop` + '') + // { + default = true; + }; + + nix-direnv = { + enable = + (lib.mkEnableOption (lib.mdDoc '' + a faster, persistent implementation of use_nix and use_flake, to replace the built-in one + '')) + // { + default = true; + }; + + package = lib.mkPackageOptionMD pkgs "nix-direnv" {}; + }; + }; + + 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 + ''; + }; + + nix.settings = lib.mkIf cfg.persistDerivations { + keep-outputs = true; + keep-derivations = true; + }; + + 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 + ''; + }; + }; + }; +}