home-manager/modules/programs/cosmic.nix

199 lines
5.5 KiB
Nix
Raw Normal View History

2024-08-01 05:21:30 +02:00
{ pkgs, lib, config, ... }:
let
inherit (lib)
filterAttrs concatStrings concatStringsSep mapAttrsToList concatLists
foldlAttrs concatMapAttrs mapAttrs' nameValuePair boolToString;
2024-08-01 05:00:43 +02:00
inherit (builtins) typeOf toString stringLength;
# build up serialisation machinery from here for various types
# list -> array
array = a: "[${concatStringsSep "," a}]";
# attrset -> hashmap
_assoc = a: mapAttrsToList (name: val: "${name}: ${val}") a;
2024-08-01 05:21:30 +02:00
assoc = a: ''
{
${
concatStringsSep ''
,
'' (concatLists (map _assoc a))
}
2024-08-01 05:00:43 +02:00
}'';
# attrset -> struct
_struct_kv = k: v:
2024-08-01 05:21:30 +02:00
if v == null then
""
else
(concatStringsSep ":" [ k (serialise.${typeOf v} v) ]);
2024-08-01 05:00:43 +02:00
_struct_concat = s:
2024-08-01 05:21:30 +02:00
foldlAttrs (acc: k: v:
if stringLength acc > 0 then
concatStringsSep ", " [ acc (_struct_kv k v) ]
else
_struct_kv k v) "" s;
_struct_filt = s: _struct_concat (filterAttrs (k: v: v != null) s);
2024-08-01 05:00:43 +02:00
struct = s: "(${_struct_filt s})";
toQuotedString = s: ''"${toString s}"'';
# make an attrset for struct serialisation
serialise = {
int = toString;
float = toString;
bool = boolToString;
string = toString;
path = toString;
null = toString;
set = struct;
list = array;
};
# define the key for a keybind
defineBinding = binding:
struct {
inherit (binding) modifiers;
2024-08-01 05:21:30 +02:00
key = if isNull binding.key then null else toQuotedString binding.key;
2024-08-01 05:00:43 +02:00
};
# map keybinding from list of attrset to hashmap of (mod,key): action
_mapBindings = bindings:
2024-08-01 05:21:30 +02:00
map (inner: {
"${defineBinding inner}" = maybeToString (checkAction inner.action);
}) bindings;
mapBindings = bindings: assoc (_mapBindings bindings);
2024-08-01 05:00:43 +02:00
# check a keybinding's action
# escape with quotes if it's a Spawn action
checkAction = a:
2024-08-01 05:21:30 +02:00
if typeOf a == "set" && a.type == "Spawn" then {
2024-08-01 05:00:43 +02:00
inherit (a) type;
data = toQuotedString a.data;
2024-08-01 05:21:30 +02:00
} else
a;
2024-08-01 05:00:43 +02:00
maybeToString = s:
2024-08-01 05:21:30 +02:00
if typeOf s == "set" then
concatStrings [ s.type "(" (toString s.data) ")" ]
else
s;
2024-08-01 05:00:43 +02:00
mapCosmicSettings = application: options:
mapAttrs' (k: v:
nameValuePair "cosmic/${application}/v${options.version}/${k}" {
enable = true;
text = serialise.${typeOf v} v;
2024-08-01 05:21:30 +02:00
}) options.option;
2024-08-01 05:00:43 +02:00
cfg = config.programs.cosmic;
in {
options.programs.cosmic = {
2024-08-01 05:21:30 +02:00
enable = with lib; mkEnableOption "COSMIC DE";
2024-08-01 05:00:43 +02:00
defaultKeybindings = with lib;
mkOption {
default = true;
type = types.bool;
description = "Whether to enable the default COSMIC keybindings.";
};
keybindings = with lib;
mkOption {
2024-08-01 05:21:30 +02:00
default = [ ];
2024-08-01 05:00:43 +02:00
type = with types;
listOf (submodule {
options = {
modifiers = mkOption {
type = listOf str;
2024-08-01 05:21:30 +02:00
default = [ ];
2024-08-01 05:00:43 +02:00
};
key = mkOption {
type = nullOr str;
default = null;
};
action = mkOption {
type = either str (submodule {
options = {
2024-08-01 05:21:30 +02:00
type = mkOption { type = str; };
2024-08-01 05:00:43 +02:00
data = mkOption {
2024-08-01 05:21:30 +02:00
type = oneOf [ str int ];
2024-08-01 05:00:43 +02:00
default = "";
};
};
});
};
};
});
description = ''
A set of keybindings and actions for the COSMIC DE.
The list of actions and possible values can be found presently at: https://github.com/pop-os/cosmic-settings-daemon/blob/master/config/src/shortcuts/action.rs
'';
example = literalExpression ''
[
# Key + mod + Spawn action
{
key = "Return";
modifiers = ["Super"];
action = {
type = "Spawn";
data = "kitty";
};
}
# Only mod - activates if no key is pressed with the modifier
{
modifiers = ["Super"];
action = {
type = "Spawn";
data = "wofi";
}
}
# Key only and plain action
{
key = "G";
action = "ToggleWindowFloating";
}
]
'';
};
settings = with lib;
mkOption {
2024-08-01 05:21:30 +02:00
default = { };
2024-08-01 05:00:43 +02:00
type = with types;
attrsOf (submodule {
options = {
version = mkOption {
type = str;
default = "1";
};
2024-08-01 05:21:30 +02:00
option = mkOption { type = attrsOf anything; };
2024-08-01 05:00:43 +02:00
};
});
description = ''
A list of explicit settings for COSMIC apps, using their full config path.
'';
example = literalExpression ''
{
"com.system76.CosmicPanel.Dock" = {
option.opacity = 0.8;
};
};
'';
};
};
config = lib.mkIf cfg.enable {
2024-08-01 05:21:30 +02:00
assertions =
[ (hm.assertions.assertPlatform "programs.cosmic" pkgs platforms.linux) ];
2024-08-01 05:00:43 +02:00
2024-08-01 05:21:30 +02:00
xdg.configFile = {
"cosmic/com.system76.CosmicSettings.Shortcuts/v1/custom".text =
mapBindings cfg.keybindings;
"cosmic/com.system76.CosmicSettings.Shortcuts/v1/defaults" = {
text = "{}";
enable = !cfg.defaultKeybindings;
};
} // concatMapAttrs
(application: options: mapCosmicSettings application options)
2024-08-01 05:00:43 +02:00
config.programs.cosmic.settings;
};
}