main
1{lib, ...}: {
2 flake.modules.homeManager.desktop = {
3 config,
4 pkgs,
5 ...
6 }: {
7 options.programs.deadbeef = let
8 inherit (lib) mkOption types;
9
10 keyValueFormat = pkgs.formats.keyValue {};
11 JSONFormat = pkgs.formats.json {};
12
13 embededJSONType = types.submodule {freeformType = JSONFormat.type;};
14 in {
15 enable = lib.mkEnableOption "Enable DeaDBeeF";
16 package = lib.mkPackageOption pkgs "deadbeef-with-plugins" {};
17 plugins = mkOption {
18 type = types.listOf types.package;
19 default = [];
20 example = lib.literalExpression ''
21 with pkgs.deadbeefPlugins; [
22 mpris2
23 ];
24 '';
25 };
26 settings = mkOption {
27 default = {};
28 example = lib.literalExpression ''
29 {
30 "gtkui.start_hidden" = 1;
31 "hotkey.key1" = "\"space\" 0 0 toggle_pause";
32 }
33 '';
34 type = types.submodule {
35 freeformType = keyValueFormat.type;
36 options = {
37 gtkui.layout = mkOption {
38 default = {};
39 description = ''
40 This option will generate a JSON string into "gtkui.layout.1.9.0" key.
41 '';
42 type = embededJSONType;
43 };
44 gtkui.columns.playlist = mkOption {
45 default = [];
46 description = ''
47 This option will generate a JSON string into "gtkui.columns.playlist" key.
48 '';
49 type = types.listOf embededJSONType;
50 };
51 gtkui.columns.search = mkOption {
52 default = [];
53 description = ''
54 This option will generate a JSON string into "gtkui.columns.search" key.
55 '';
56 type = types.listOf embededJSONType;
57 };
58 };
59 };
60 };
61 };
62
63 config = let
64 cfg = config.programs.deadbeef;
65 in
66 lib.mkIf cfg.enable {
67 assertions = [
68 {
69 assertion = pkgs.stdenv.hostPlatform.isLinux;
70 message = "DeaDBeeF is a Linux software.";
71 }
72 ];
73 home.packages = [(cfg.package.override {plugins = cfg.plugins;})];
74 systemd.user.services.merge-deadbeef-config = let
75 deadbeefProcessedConfig =
76 {
77 "gtkui.layout.1.9.0" = builtins.toJSON cfg.settings.gtkui.layout;
78 "gtkui.columns.playlist" = builtins.toJSON cfg.settings.gtkui.columns.playlist;
79 "gtkui.columns.search" = builtins.toJSON cfg.settings.gtkui.columns.search;
80 }
81 // (lib.removeAttrs cfg.settings ["gtkui"]);
82 deadbeefConfig = with lib.generators;
83 toKeyValue {mkKeyValue = mkKeyValueDefault {} " ";} deadbeefProcessedConfig;
84 in {
85 Unit = {
86 Description = "Merge Nix-managed DeaDBeeF configuration";
87 After = ["graphical-session-pre.target"];
88 PartOf = ["graphical-session.target"];
89 };
90 Service = {
91 Type = "oneshot";
92 ExecStart = lib.getExe (pkgs.writeShellScriptBin "merge-deadbeef-config" ''
93 #!${pkgs.runtimeShell}
94 set -eu
95
96 MANAGED_CONFIG_FILE="${pkgs.writeText "deadbeef-managed-config" deadbeefConfig}"
97
98 TARGET_CONFIG_FILE="$HOME/.config/deadbeef/config"
99 mkdir -p "$(dirname "$TARGET_CONFIG_FILE")"
100 touch "$TARGET_CONFIG_FILE"
101
102 ${pkgs.gawk}/bin/awk '
103 NR==FNR { a[$1]=$0; next }
104 {
105 if ($1 in a) {
106 print a[$1]
107 delete a[$1]
108 } else {
109 print $0
110 }
111 }
112 END {
113 for (k in a) {
114 print a[k]
115 }
116 }
117 ' "$MANAGED_CONFIG_FILE" "$TARGET_CONFIG_FILE" > "$TARGET_CONFIG_FILE.tmp" && \
118 mv "$TARGET_CONFIG_FILE.tmp" "$TARGET_CONFIG_FILE"
119 echo "DeaDBeeF config merged successfully."
120 '');
121 };
122 Install = {
123 WantedBy = ["graphical-session.target"];
124 };
125 };
126 };
127 };
128}