From 7d4f510f26444923741ab9554d1402f040978f62 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 18 Oct 2023 21:46:54 +0100 Subject: [PATCH 1/8] home-environment: add home.sessionSearchVariables This commit introduces `home.sessionSearchVariables` option, that is created to be a "generic" version of `home.sessionPath` for any environment variables that is similar to PATH (e.g.: MANPATH). This allows composition of those variables between multiple modules, avoiding issues like this one: https://github.com/nix-community/home-manager/pull/4579/files#r1364374048 This commit also reimplements `home.sessionPath` as terms of `home.sessionSearchVariables`, to reduce code duplication and show that the code is correct. --- modules/home-environment.nix | 34 +++++++++++++++++-- tests/modules/home-environment/default.nix | 3 +- .../session-search-variables.nix | 15 ++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 tests/modules/home-environment/session-search-variables.nix diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 87046460..69d04a12 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -319,6 +319,28 @@ 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 add 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 = ""; @@ -555,11 +577,17 @@ in export __HM_SESS_VARS_SOURCED=1 ${config.lib.shell.exportAll cfg.sessionVariables} - '' + lib.optionalString (cfg.sessionPath != [ ]) '' - export PATH="$PATH''${PATH:+:}${concatStringsSep ":" cfg.sessionPath}" - '' + cfg.sessionVariablesExtra; + '' + concatStringsSep "\n" + (mapAttrsToList + (env: values: '' + export ${env}="''$${env}''${${env}:+:}${concatStringsSep ":" values}"'') + cfg.sessionSearchVariables) + + cfg.sessionVariablesExtra; }; + home.sessionSearchVariables.PATH = + mkIf (cfg.sessionPath != [ ]) cfg.sessionPath; + home.packages = [ config.home.sessionVariablesPackage ]; # A dummy entry acting as a boundary between the activation diff --git a/tests/modules/home-environment/default.nix b/tests/modules/home-environment/default.nix index e76e248a..c38ad5ce 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-search-variables.nix b/tests/modules/home-environment/session-search-variables.nix new file mode 100644 index 00000000..c260e6fe --- /dev/null +++ b/tests/modules/home-environment/session-search-variables.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +{ + 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="$TEST''${TEST:+:}bar:baz:foo"' + ''; +} From 52ea78741bd45732b5478a64f316a42b5fbe4335 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 18 Oct 2023 21:50:35 +0100 Subject: [PATCH 2/8] im/fcitx5: use home.sessionSearchVariables for QT_PLUGIN_PATH --- modules/i18n/input-method/fcitx5.nix | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/i18n/input-method/fcitx5.nix b/modules/i18n/input-method/fcitx5.nix index 3599fd2d..610df25f 100644 --- a/modules/i18n/input-method/fcitx5.nix +++ b/modules/i18n/input-method/fcitx5.nix @@ -23,13 +23,15 @@ in { config = mkIf (im.enabled == "fcitx5") { i18n.inputMethod.package = fcitx5Package; - home.sessionVariables = { - GLFW_IM_MODULE = "ibus"; # IME support in kitty - GTK_IM_MODULE = "fcitx"; - QT_IM_MODULE = "fcitx"; - XMODIFIERS = "@im=fcitx"; - QT_PLUGIN_PATH = - "$QT_PLUGIN_PATH\${QT_PLUGIN_PATH:+:}${fcitx5Package}/${pkgs.qt6.qtbase.qtPluginPrefix}"; + home = { + sessionVariables = { + GLFW_IM_MODULE = "ibus"; # IME support in kitty + GTK_IM_MODULE = "fcitx"; + QT_IM_MODULE = "fcitx"; + XMODIFIERS = "@im=fcitx"; + }; + sessionSearchVariables.QT_PLUGIN_PATH = + [ "${fcitx5Package}/${pkgs.qt6.qtbase.qtPluginPrefix}" ]; }; systemd.user.services.fcitx5-daemon = { From f9b4b85ca393f03407d783b469c859b78f08b0df Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 18 Oct 2023 23:42:23 +0100 Subject: [PATCH 3/8] debug: use home.sessionSearchVariables for NIX_DEBUG_INFO_DIRS --- modules/misc/debug.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/misc/debug.nix b/modules/misc/debug.nix index fc0d8946..908b9114 100644 --- a/modules/misc/debug.nix +++ b/modules/misc/debug.nix @@ -18,9 +18,8 @@ with lib; config = mkIf config.home.enableDebugInfo { home.extraOutputsToInstall = [ "debug" ]; - home.sessionVariables = { - NIX_DEBUG_INFO_DIRS = - "$NIX_DEBUG_INFO_DIRS\${NIX_DEBUG_INFO_DIRS:+:}${config.home.profileDirectory}/lib/debug"; + home.sessionSearchVariables = { + NIX_DEBUG_INFO_DIRS = [ "${config.home.profileDirectory}/lib/debug" ]; }; }; } From 5921a96caf482d10284e6412020be5ef8cc811ef Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 18 Oct 2023 23:59:16 +0100 Subject: [PATCH 4/8] home-cursor: use home.sessionSearchVariables for XCURSOR_PATH --- modules/config/home-cursor.nix | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/config/home-cursor.nix b/modules/config/home-cursor.nix index c696908d..89f5409d 100644 --- a/modules/config/home-cursor.nix +++ b/modules/config/home-cursor.nix @@ -136,16 +136,17 @@ in { home.packages = [ cfg.package defaultIndexThemePackage ]; + home.sessionVariables = { + XCURSOR_SIZE = mkDefault cfg.size; + XCURSOR_THEME = mkDefault cfg.name; + }; + # Set directory to look for cursors in, needed for some applications # that are unable to find cursors otherwise. See: # https://github.com/nix-community/home-manager/issues/2812 # https://wiki.archlinux.org/title/Cursor_themes#Environment_variable - home.sessionVariables = { - XCURSOR_PATH = mkDefault ("$XCURSOR_PATH\${XCURSOR_PATH:+:}" - + "${config.home.profileDirectory}/share/icons"); - XCURSOR_SIZE = mkDefault cfg.size; - XCURSOR_THEME = mkDefault cfg.name; - }; + home.sessionSearchVariables.XCURSOR_PATH = + [ "${config.home.profileDirectory}/share/icons" ]; # Add symlink of cursor icon directory to $HOME/.icons, needed for # backwards compatibility with some applications. See: From 1e030277ba0196ea0a8d88a3af81a1191c16e197 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Thu, 19 Oct 2023 00:01:00 +0100 Subject: [PATCH 5/8] targets/generic-linux: use home.sessionSearchVariables for XCURSOR_PATH --- modules/targets/generic-linux.nix | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/targets/generic-linux.nix b/modules/targets/generic-linux.nix index b5a07d5f..d6a045b4 100644 --- a/modules/targets/generic-linux.nix +++ b/modules/targets/generic-linux.nix @@ -48,12 +48,8 @@ in { # We need to append system-wide FHS directories due to the default prefix # resolving to the Nix store. # https://github.com/nix-community/home-manager/pull/2891#issuecomment-1101064521 - home.sessionVariables = { - XCURSOR_PATH = "$XCURSOR_PATH\${XCURSOR_PATH:+:}" + concatStringsSep ":" [ - "${config.home.profileDirectory}/share/icons" - "/usr/share/icons" - "/usr/share/pixmaps" - ]; + home.sessionSearchVariables = { + XCURSOR_PATH = [ "/usr/share/icons" "/usr/share/pixmaps" ]; }; home.sessionVariablesExtra = '' From 664086fa4c9eb05bbd986cc4d6f41325efa1491b Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Thu, 19 Oct 2023 01:02:01 +0100 Subject: [PATCH 6/8] lib/shell: add appendToVar function --- modules/home-environment.nix | 5 +++-- modules/lib/shell.nix | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 69d04a12..3533ea2c 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -579,8 +579,9 @@ in ${config.lib.shell.exportAll cfg.sessionVariables} '' + concatStringsSep "\n" (mapAttrsToList - (env: values: '' - export ${env}="''$${env}''${${env}:+:}${concatStringsSep ":" values}"'') + (env: values: config.lib.shell.export + env + (config.lib.shell.appendToVar ":" env values)) cfg.sessionSearchVariables) + cfg.sessionVariablesExtra; }; diff --git a/modules/lib/shell.nix b/modules/lib/shell.nix index 5e5743f5..cdcfdefa 100644 --- a/modules/lib/shell.nix +++ b/modules/lib/shell.nix @@ -1,6 +1,14 @@ { lib }: rec { + # Produces a Bourne shell like statement that appends new values to + # an possibly existing variable, using sep(ator). + # Example: + # appendToVar ":" "PATH" [ "$HOME/bin" "$HOME/.local/bin" ] + # => "$PATH\${PATH:+:}$HOME/bin:$HOME/.local/bin" + appendToVar = sep: n: v: + "\$${n}\${${n}:+${sep}}${lib.concatStringsSep sep v}"; + # Produces a Bourne shell like variable export statement. export = n: v: ''export ${n}="${toString v}"''; From 0b25ac41ee8754cecfacfbbb311ed008e5670260 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Thu, 19 Oct 2023 13:02:18 +0100 Subject: [PATCH 7/8] home-environment: prepend instead of append --- modules/home-environment.nix | 10 +++++----- modules/lib/shell.nix | 10 +++++----- tests/modules/home-environment/session-path.nix | 2 +- .../home-environment/session-search-variables.nix | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 3533ea2c..8f40eae3 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 be prepend to {env}`PATH`. These directories are added to the {env}`PATH` variable in a double-quoted context, so expressions like `$HOME` are @@ -329,9 +329,9 @@ in ]; }; description = '' - Extra directories to add to arbitrary PATH-like environment - variables (e.g.: {env}`MANPATH`). The values will be concatenated - by `:`. + Extra directories to be 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 @@ -581,7 +581,7 @@ in (mapAttrsToList (env: values: config.lib.shell.export env - (config.lib.shell.appendToVar ":" env values)) + (config.lib.shell.prependToVar ":" env values)) cfg.sessionSearchVariables) + cfg.sessionVariablesExtra; }; diff --git a/modules/lib/shell.nix b/modules/lib/shell.nix index cdcfdefa..c6113d0f 100644 --- a/modules/lib/shell.nix +++ b/modules/lib/shell.nix @@ -1,13 +1,13 @@ { lib }: rec { - # Produces a Bourne shell like statement that appends new values to + # Produces a Bourne shell like statement that prepend new values to # an possibly existing variable, using sep(ator). # Example: - # appendToVar ":" "PATH" [ "$HOME/bin" "$HOME/.local/bin" ] - # => "$PATH\${PATH:+:}$HOME/bin:$HOME/.local/bin" - appendToVar = sep: n: v: - "\$${n}\${${n}:+${sep}}${lib.concatStringsSep sep v}"; + # 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/session-path.nix b/tests/modules/home-environment/session-path.nix index 57cfeced..55c4084a 100644 --- a/tests/modules/home-environment/session-path.nix +++ b/tests/modules/home-environment/session-path.nix @@ -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 index c260e6fe..66dcb034 100644 --- a/tests/modules/home-environment/session-search-variables.nix +++ b/tests/modules/home-environment/session-search-variables.nix @@ -10,6 +10,6 @@ hmSessVars=home-path/etc/profile.d/hm-session-vars.sh assertFileExists $hmSessVars assertFileContains $hmSessVars \ - 'export TEST="$TEST''${TEST:+:}bar:baz:foo"' + 'export TEST="bar:baz:foo''${TEST:+:}$TEST"' ''; } From dbc1ebb0eb0463ecdc19817156088c785cd7c627 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Tue, 21 Nov 2023 18:59:20 +0000 Subject: [PATCH 8/8] qt: use home.sessionSearchVariables --- modules/misc/qt.nix | 22 ++++++------------- .../modules/misc/qt/qt-platform-theme-gtk.nix | 1 - 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/modules/misc/qt.nix b/modules/misc/qt.nix index f02bc186..18a90cb8 100644 --- a/modules/misc/qt.nix +++ b/modules/misc/qt.nix @@ -170,13 +170,10 @@ in { inherit (config.home) profileDirectory; qtVersions = with pkgs; [ qt5 qt6 ]; makeQtPath = prefix: - lib.concatStringsSep ":" (map (qt: "${profileDirectory}/${qt.qtbase.${prefix}}") qtVersions); in { - QT_PLUGIN_PATH = "$QT_PLUGIN_PATH\${QT_PLUGIN_PATH:+:}" - + (makeQtPath "qtPluginPrefix"); - QML2_IMPORT_PATH = "$QML2_IMPORT_PATH\${QML2_IMPORT_PATH:+:}" - + (makeQtPath "qtQmlPrefix"); + QT_PLUGIN_PATH = makeQtPath "qtPluginPrefix"; + QML2_IMPORT_PATH = makeQtPath "qtQmlPrefix"; }; in lib.mkIf cfg.enable { @@ -194,19 +191,14 @@ in { home = { sessionVariables = envVars; - # home.sessionVariables does not support setting the same environment - # variable to different values. - # Since some other modules may set the QT_PLUGIN_PATH or QML2_IMPORT_PATH - # to their own value, e.g.: fcitx5, we avoid conflicts by setting - # the values in home.sessionVariablesExtra instead. - sessionVariablesExtra = '' - export QT_PLUGIN_PATH=${envVarsExtra.QT_PLUGIN_PATH} - export QML2_IMPORT_PATH=${envVarsExtra.QML2_IMPORT_PATH} - ''; + sessionSearchVariables = envVarsExtra; }; # Apply theming also to apps started by systemd. - systemd.user.sessionVariables = envVars // envVarsExtra; + systemd.user.sessionVariables = envVars // { + QT_PLUGIN_PATH = lib.concatStringsSep ":" envVarsExtra.QT_PLUGIN_PATH; + QML2_IMPORT_PATH = lib.concatStringsSep ":" envVarsExtra.QML2_IMPORT_PATH; + }; home.packages = (lib.optionals (cfg.platformTheme != null) platformPackages.${cfg.platformTheme} or [ ]) diff --git a/tests/modules/misc/qt/qt-platform-theme-gtk.nix b/tests/modules/misc/qt/qt-platform-theme-gtk.nix index 070c8020..b91496b5 100644 --- a/tests/modules/misc/qt/qt-platform-theme-gtk.nix +++ b/tests/modules/misc/qt/qt-platform-theme-gtk.nix @@ -6,7 +6,6 @@ enable = true; platformTheme = "gtk"; }; - i18n.inputMethod.enabled = "fcitx5"; nmt.script = '' assertFileRegex home-path/etc/profile.d/hm-session-vars.sh \