Skip to content

hyprland: init module #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions modules/collection/programs/hyprland.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
lib,
osConfig,
config,
...
}: let
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.modules) mkIf;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.rum.attrsets) filterKeysPrefixes;
inherit (lib.rum.generators.environment) toEnvExport;
inherit (lib.rum.generators.hypr) toHyprconf pluginsToHyprconf;
inherit (lib.rum.types) hyprType;
inherit (lib.strings) optionalString;
inherit (lib.types) either lines listOf package path str;

cfg = config.rum.programs.hyprland;
in {
options.rum.programs.hyprland = {
enable = mkEnableOption "Hyprland";

settings = mkOption {
type = hyprType;
example = {
"$mod" = "SUPER";
decoration = {
rounding = "3";
};
};
default = {};
description = ''
Hyprland configuration written in Nix. Entries with the same key
should be written as lists. Variables' and colors' names should be
quoted. See <https://wiki.hyprland.org> for more examples.
'';
};

plugins = mkOption {
type = listOf (either package path);
default = [];
description = ''
List of Hyprland plugins to use. Can either be packages or
absolute plugin paths.
'';
};

importantPrefixes = mkOption {
type = listOf str;
default = ["$" "bezier" "name"];
example = ["$" "bezier"];
description = ''
List of prefix of attributes to source at the top of the config.
'';
};

extraConfig = mkOption {
type = lines;
default = "";
description = ''
Extra configuration that will be appended verbatim at the end of your `hyprland.conf`.
'';
};
};

config = mkIf cfg.enable {
files = let
check = {
plugins = cfg.plugins != [];
settings = cfg.settings != {};
variables = {
noUWSM = config.environment.sessionVariables != {} && !osConfig.programs.hyprland.withUWSM;
withUWSM = config.environment.sessionVariables != {} && osConfig.programs.hyprland.withUWSM;
};
extraConfig = cfg.extraConfig != "";
};
in {
".config/hypr/hyprland.conf".text = mkIf (check.plugins || check.settings || check.variables.noUWSM || check.extraConfig) (
optionalString check.plugins (pluginsToHyprconf cfg.plugins cfg.importantPrefixes)
+ optionalString check.settings (toHyprconf {
attrs = cfg.settings;
inherit (cfg) importantPrefixes;
})
+ optionalString check.variables.noUWSM (toHyprconf {
attrs.env =
# https://wiki.hyprland.org/Configuring/Environment-variables/#xdg-specifications
[
"XDG_CURRENT_DESKTOP,Hyprland"
"XDG_SESSION_TYPE,wayland"
"XDG_SESSION_DESKTOP,Hyprland"
]
++ mapAttrsToList (key: value: "${key},${value}") config.environment.sessionVariables;
})
+ optionalString check.extraConfig cfg.extraConfig
);

/*
uwsm environment variables are advised to be separated
(see https://wiki.hyprland.org/Configuring/Environment-variables/)
*/
".config/uwsm/env".text =
mkIf check.variables.withUWSM
(toEnvExport config.environment.sessionVariables);

".config/uwsm/env-hyprland".text = let
/*
this is needed as we're using a predicate so we don't create an empty file
(improvements are welcome)
*/
filteredVars =
filterKeysPrefixes ["HYPRLAND_" "AQ_"] config.environment.sessionVariables;
in
mkIf (check.variables.withUWSM && filteredVars != {})
(toEnvExport filteredVars);
};
};
}
3 changes: 3 additions & 0 deletions modules/lib/attrsets/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{lib}: {
filterKeysPrefixes = import ./filterKeysPrefixes.nix {inherit lib;};
}
28 changes: 28 additions & 0 deletions modules/lib/attrsets/filterKeysPrefixes.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{lib}: let
inherit (builtins) any;
inherit (lib.attrsets) filterAttrs;
inherit (lib.strings) hasPrefix;
in
/*
Filters an attribute set with prefixes applied to keys.

# Inputs

`prefixes`

: A list of prefixes to filter the attribute set with.

`attrs`

: The attribute set to apply the filter on.

Value
: The filtered attribute set.
*/
prefixes: attrs:
if prefixes == []
then attrs
else
filterAttrs
(name: _: any (prefix: hasPrefix prefix name) prefixes)
attrs
2 changes: 1 addition & 1 deletion modules/lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# lib is extended under lib.rum due to annoyances with lib extensions
# and also to maximize transparency of what is and isn't custom
rum = {
attrsets = import ./attrsets {inherit lib;};
generators = import ./generators {inherit lib;};

types = import ./types {inherit lib;};
};
}
2 changes: 2 additions & 0 deletions modules/lib/generators/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{lib}: {
environment = import ./environment.nix {inherit lib;};
gtk = import ./gtk.nix {inherit lib;};
hypr = import ./hypr.nix {inherit lib;};
ncmpcpp = import ./ncmpcpp.nix {inherit lib;};
}
17 changes: 17 additions & 0 deletions modules/lib/generators/environment.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{lib}: let
inherit (builtins) map isList toString;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) concatStringsSep;

toEnvValue = env:
if isList env
then concatStringsSep ":" (map toString env)
else toString env;

toEnvExport = vars: (concatStringsSep "\n"
(mapAttrsToList
(name: value: "export ${name}=\"${toEnvValue value}\"")
vars));
in {
inherit toEnvExport toEnvValue;
}
71 changes: 71 additions & 0 deletions modules/lib/generators/hypr.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# basically 1:1 taken from https://github.com/nix-community/home-manager/blob/master/modules/services/window-managers/hyprland.nix
{lib}: let
toHyprconf = {
attrs,
indentLevel ? 0,
importantPrefixes ? ["$"],
}: let
inherit (builtins) all isAttrs isList removeAttrs;
inherit (lib.attrsets) filterAttrs mapAttrsToList;
inherit (lib.generators) toKeyValue;
inherit (lib.lists) foldl replicate;
inherit (lib.strings) concatStrings concatStringsSep concatMapStringsSep hasPrefix;

initialIndent = concatStrings (replicate indentLevel " ");

toHyprconf' = indent: attrs: let
sections =
filterAttrs (_: v: isAttrs v || (isList v && all isAttrs v)) attrs;

mkSection = n: attrs:
if lib.isList attrs
then (concatMapStringsSep "\n" (a: mkSection n a) attrs)
else ''
${indent}${n} {
${toHyprconf' " ${indent}" attrs}${indent}}
'';

mkFields = toKeyValue {
listsAsDuplicateKeys = true;
inherit indent;
};

allFields =
filterAttrs (_: v: !(isAttrs v || (isList v && all isAttrs v)))
attrs;

isImportantField = n: _:
foldl (acc: prev:
if hasPrefix prev n
then true
else acc)
false
importantPrefixes;

importantFields = filterAttrs isImportantField allFields;

fields =
removeAttrs allFields
(mapAttrsToList (n: _: n) importantFields);
in
mkFields importantFields
+ concatStringsSep "\n" (mapAttrsToList mkSection sections)
+ mkFields fields;
in
toHyprconf' initialIndent attrs;

# taken from https://github.com/hyprwm/Hyprland/blob/f4b148df1e2d8edc96bd878a4cfde32ca6515ac8/nix/module.nix#L185-L197
pluginsToHyprconf = plugins: importantPrefixes:
toHyprconf {
attrs = {
plugin = let
mkEntry = entry:
if lib.types.package.check entry
then "${entry}/lib/lib${entry.pname}.so"
else entry;
in
map mkEntry plugins;
};
inherit importantPrefixes;
};
in {inherit toHyprconf pluginsToHyprconf;}
1 change: 1 addition & 0 deletions modules/lib/types/default.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{lib}: {
gtkType = import ./gtkType.nix {inherit lib;};
hyprType = import ./hyprType.nix {inherit lib;};
ncmpcppBindingType = import ./ncmpcppBindingType.nix {inherit lib;};
tofiSettingsType = import ./tofiSettingsType.nix {inherit lib;};
}
8 changes: 8 additions & 0 deletions modules/lib/types/hyprType.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{lib}: let
inherit (lib.types) attrsOf listOf oneOf bool float int path str;

hyprValue = oneOf [str path bool int float hyprList hyprMap];
hyprMap = attrsOf hyprValue;
hyprList = listOf hyprValue;
in
hyprMap