diff --git a/configs/nixos/modules/desktop/apps/ghostty.nix b/configs/nixos/modules/desktop/apps/ghostty.nix index dd07245..045d553 100644 --- a/configs/nixos/modules/desktop/apps/ghostty.nix +++ b/configs/nixos/modules/desktop/apps/ghostty.nix @@ -16,7 +16,7 @@ in keys = "SUPER + Return"; action = { kind = "exec"; - command = "${pkgs.ghostty}/bin/ghostty"; + command = lib.getExe pkgs.ghostty; }; }; diff --git a/configs/nixos/modules/desktop/session/hyprland/hypridle.nix b/configs/nixos/modules/desktop/session/hyprland/hypridle.nix index 53370db..b454ad7 100644 --- a/configs/nixos/modules/desktop/session/hyprland/hypridle.nix +++ b/configs/nixos/modules/desktop/session/hyprland/hypridle.nix @@ -21,10 +21,10 @@ general = { # The guard drops the call when a locker is already up, so no idle # trigger stacks a second hyprlock over the first. - lock_cmd = "${pkgs.procps}/bin/pidof hyprlock || ${pkgs.hyprlock}/bin/hyprlock"; + lock_cmd = "${lib.getExe' pkgs.procps "pidof"} hyprlock || ${lib.getExe pkgs.hyprlock}"; before_sleep_cmd = "loginctl lock-session"; # Waking pokes the compositor in case firmware leaves displays dark. - after_sleep_cmd = "${config.programs.hyprland.package}/bin/hyprctl dispatch 'hl.dsp.dpms({ action = \"enable\" })'"; + after_sleep_cmd = "${lib.getExe' config.programs.hyprland.package "hyprctl"} dispatch 'hl.dsp.dpms({ action = \"enable\" })'"; }; listener = [ diff --git a/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix b/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix index 0e2f771..0fde487 100644 --- a/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix +++ b/configs/nixos/modules/desktop/session/hyprland/hyprlock.nix @@ -13,28 +13,28 @@ let unit=lockscreen-idle-inhibit.service refresh_waybar() { - ${pkgs.procps}/bin/pkill -RTMIN+9 waybar >/dev/null 2>&1 || true + ${lib.getExe' pkgs.procps "pkill"} -RTMIN+9 waybar >/dev/null 2>&1 || true } - if ${pkgs.systemd}/bin/systemctl --user is-active --quiet "$unit"; then - ${pkgs.systemd}/bin/systemctl --user stop "$unit" + if ${lib.getExe' pkgs.systemd "systemctl"} --user is-active --quiet "$unit"; then + ${lib.getExe' pkgs.systemd "systemctl"} --user stop "$unit" refresh_waybar - ${pkgs.swayosd}/bin/swayosd-client --custom-message "${sleepIcon}" + ${lib.getExe' pkgs.swayosd "swayosd-client"} --custom-message "${sleepIcon}" exit 0 fi - if ${pkgs.systemd}/bin/systemd-run \ + if ${lib.getExe' pkgs.systemd "systemd-run"} \ --user \ --collect \ --unit=lockscreen-idle-inhibit \ --description="Disable idle-triggered screen locking" \ - ${pkgs.systemd}/bin/systemd-inhibit \ + ${lib.getExe' pkgs.systemd "systemd-inhibit"} \ --what=idle \ --who=lockscreen-hotkey \ --why="lock screen disabled by hotkey" \ - ${pkgs.coreutils}/bin/sleep infinity >/dev/null; then + ${lib.getExe' pkgs.coreutils "sleep"} infinity >/dev/null; then refresh_waybar - ${pkgs.swayosd}/bin/swayosd-client --custom-message "${sleepOffIcon}" + ${lib.getExe' pkgs.swayosd "swayosd-client"} --custom-message "${sleepOffIcon}" fi ''; in @@ -85,7 +85,7 @@ in kind = "exec"; # The guard drops the call when a locker is already up, so no manual # trigger stacks a second hyprlock over the first. - command = "${pkgs.procps}/bin/pidof hyprlock || ${pkgs.hyprlock}/bin/hyprlock"; + command = "${lib.getExe' pkgs.procps "pidof"} hyprlock || ${lib.getExe pkgs.hyprlock}"; }; }; diff --git a/src/skills/style/nix/rules/general.md b/src/skills/style/nix/rules/general.md index e0d0a58..ed367ef 100644 --- a/src/skills/style/nix/rules/general.md +++ b/src/skills/style/nix/rules/general.md @@ -21,3 +21,32 @@ Do not call `lib.removeSuffix ".nix"` outside the utility definition. ### Rationale The utility centralizes Nix file-name normalization. + +## Use executable helpers for package commands + +### Rule + +Use `lib.getExe` for a package's main executable. +Use `lib.getExe'` for a package's non-main executable. +Do not build executable paths with `"${pkg}/bin/name"` when an executable helper names the target. +Use `lib.getExe' config.programs..package "tool"` when a command follows a configured package option. + +### Rationale + +Executable helpers select the package output that contains binaries. +They make package ownership explicit. +`lib.getExe'` prevents calls to a package's main executable when code needs another tool. + +## Prefer NixOS package ownership for commands + +### Rule + +Use `pkgs.` for Home Manager tools. +Use `config.programs..package` when a NixOS module owns the package selection. +Do not read `config.home-manager.users..programs..package` for command paths. + +### Rationale + +Home Manager uses the NixOS package set in this repository. +`pkgs.` avoids dependency paths through the user tree under Home Manager. +Configured NixOS package options preserve package selection when a module owns the tool.