diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 0e3bef900..652ac086c 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -309,7 +309,7 @@ in ".git/safe/../../bin" ]; description = '' - Extra directories to add to {env}`PATH`. + Extra directories to prepend to {env}`PATH`. These directories are added to the {env}`PATH` variable in a double-quoted context, so expressions like `$HOME` are @@ -319,6 +319,27 @@ in ''; }; + home.sessionSearchVariables = mkOption { + default = { }; + type = with types; attrsOf (listOf str); + example = { + MANPATH = [ + "$HOME/.npm-packages/man" + "\${xdg.configHome}/.local/share/man" + ]; + }; + description = '' + Extra directories to prepend to arbitrary PATH-like + environment variables (e.g.: {env}`MANPATH`). The values + will be concatenated by `:`. + These directories are added to the environment variable in a + double-quoted context, so expressions like `$HOME` are + expanded by the shell. However, since expressions like `~` or + `*` are escaped, they will end up in the environment + verbatim. + ''; + }; + home.sessionVariablesExtra = mkOption { type = types.lines; default = ""; @@ -575,11 +596,18 @@ in export __HM_SESS_VARS_SOURCED=1 ${config.lib.shell.exportAll cfg.sessionVariables} - '' + lib.optionalString (cfg.sessionPath != [ ]) '' - export PATH="$PATH''${PATH:+:}${lib.concatStringsSep ":" cfg.sessionPath}" - '' + cfg.sessionVariablesExtra; + '' + lib.concatStringsSep "\n" + (lib.mapAttrsToList + (env: values: config.lib.shell.export + env + (config.lib.shell.prependToVar ":" env values)) + cfg.sessionSearchVariables) + + cfg.sessionVariablesExtra; }; + home.sessionSearchVariables.PATH = + lib.mkIf (cfg.sessionPath != [ ]) cfg.sessionPath; + home.packages = [ config.home.sessionVariablesPackage ]; # The entry acting as a boundary between the activation script's "check" and diff --git a/modules/lib/shell.nix b/modules/lib/shell.nix index ae30e0b0f..04f9135cf 100644 --- a/modules/lib/shell.nix +++ b/modules/lib/shell.nix @@ -17,6 +17,14 @@ let }; in rec { + # Produces a Bourne shell like statement that prepend new values to + # an possibly existing variable, using sep(arator). + # Example: + # prependToVar ":" "PATH" [ "$HOME/bin" "$HOME/.local/bin" ] + # => "$HOME/bin:$HOME/.local/bin:${PATH:+:}\$PATH" + prependToVar = sep: n: v: + "${lib.concatStringsSep sep v}\${${n}:+${sep}}\$${n}"; + # Produces a Bourne shell like variable export statement. export = n: v: ''export ${n}="${toString v}"''; diff --git a/tests/modules/home-environment/default.nix b/tests/modules/home-environment/default.nix index e76e248a1..c38ad5ce5 100644 --- a/tests/modules/home-environment/default.nix +++ b/tests/modules/home-environment/default.nix @@ -1,4 +1,5 @@ { - home-session-variables = ./session-variables.nix; home-session-path = ./session-path.nix; + home-session-search-variables = ./session-search-variables.nix; + home-session-variables = ./session-variables.nix; } diff --git a/tests/modules/home-environment/session-path.nix b/tests/modules/home-environment/session-path.nix index 57cfeceda..907d6c398 100644 --- a/tests/modules/home-environment/session-path.nix +++ b/tests/modules/home-environment/session-path.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ ... }: { imports = [ @@ -10,6 +10,6 @@ hmSessVars=home-path/etc/profile.d/hm-session-vars.sh assertFileExists $hmSessVars assertFileContains $hmSessVars \ - 'export PATH="$PATH''${PATH:+:}bar:baz:foo"' + 'export PATH="bar:baz:foo''${PATH:+:}$PATH"' ''; } diff --git a/tests/modules/home-environment/session-search-variables.nix b/tests/modules/home-environment/session-search-variables.nix new file mode 100644 index 000000000..b12009f2b --- /dev/null +++ b/tests/modules/home-environment/session-search-variables.nix @@ -0,0 +1,15 @@ +{ ... }: + +{ + imports = [ + ({ ... }: { config.home.sessionSearchVariables.TEST = [ "foo" ]; }) + ({ ... }: { config.home.sessionSearchVariables.TEST = [ "bar" "baz" ]; }) + ]; + + nmt.script = '' + hmSessVars=home-path/etc/profile.d/hm-session-vars.sh + assertFileExists $hmSessVars + assertFileContains $hmSessVars \ + 'export TEST="bar:baz:foo''${TEST:+:}$TEST"' + ''; +}