diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 698c37ca..aaf6c1c3 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -1084,6 +1084,13 @@ in
A new module is available: 'services.rsibreak'.
'';
}
+
+ {
+ time = "2019-05-07T20:49:29+00:00";
+ message = ''
+ A new module is available: 'programs.mpv'.
+ '';
+ }
];
};
}
diff --git a/modules/modules.nix b/modules/modules.nix
index d7bbd8dd..45251167 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -66,6 +66,7 @@ let
(loadModule ./programs/matplotlib.nix { })
(loadModule ./programs/mbsync.nix { })
(loadModule ./programs/mercurial.nix { })
+ (loadModule ./programs/mpv.nix { })
(loadModule ./programs/msmtp.nix { })
(loadModule ./programs/neovim.nix { })
(loadModule ./programs/newsboat.nix { })
diff --git a/modules/programs/mpv.nix b/modules/programs/mpv.nix
new file mode 100644
index 00000000..9303e53f
--- /dev/null
+++ b/modules/programs/mpv.nix
@@ -0,0 +1,139 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ inherit (builtins) typeOf stringLength;
+
+ cfg = config.programs.mpv;
+
+ mpvOption = with types; either str (either int (either bool float));
+ mpvOptions = with types; attrsOf mpvOption;
+ mpvProfiles = with types; attrsOf mpvOptions;
+ mpvBindings = with types; attrsOf str;
+
+ renderOption = option:
+ rec {
+ int = toString option;
+ float = int;
+
+ bool = if option then "yes" else "no";
+
+ string = option;
+ }.${typeOf option};
+
+ renderOptions = options:
+ concatStringsSep "\n"
+ (mapAttrsToList
+ (name: value:
+ let
+ rendered = renderOption value;
+ length = toString (stringLength rendered);
+ in
+ "${name}=%${length}%${rendered}")
+ options);
+
+ renderProfiles = profiles:
+ concatStringsSep "\n"
+ (mapAttrsToList
+ (name: value: ''
+ [${name}]
+ ${renderOptions value}
+ '')
+ profiles);
+
+ renderBindings = bindings:
+ concatStringsSep "\n"
+ (mapAttrsToList
+ (name: value:
+ "${name} ${value}")
+ bindings);
+
+in {
+ options = {
+ programs.mpv = {
+ enable = mkEnableOption "mpv";
+
+ config = mkOption {
+ description = ''
+ Configuration written to
+ ~/.config/mpv/mpv.conf. See
+
+ mpv
+ 1
+
+ for the full list of options.
+ '';
+ type = mpvOptions;
+ default = {};
+ example = literalExample ''
+ {
+ profile = "gpu-hq";
+ force-window = "yes";
+ ytdl-format = "bestvideo+bestaudio";
+ cache-default = 4000000;
+ }
+ '';
+ };
+
+ profiles = mkOption {
+ description = ''
+ Sub-configuration options for specific profiles written to
+ ~/.config/mpv/mpv.conf. See
+ for more information.
+ '';
+ type = mpvProfiles;
+ default = {};
+ example = literalExample ''
+ {
+ fast = {
+ vo = "vdpau";
+ };
+ "protocol.dvd" = {
+ profile-desc = "profile for dvd:// streams";
+ alang = "en";
+ };
+ }
+ '';
+ };
+
+ bindings = mkOption {
+ description = ''
+ Input configuration written to
+ ~/.config/mpv/input.conf. See
+
+ mpv
+ 1
+
+ for the full list of options.
+ '';
+ type = mpvBindings;
+ default = {};
+ example = literalExample ''
+ {
+ WHEEL_UP = "seek 10";
+ WHEEL_DOWN = "seek -10";
+ "Alt+0" = "set window-scale 0.5";
+ }
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable (mkMerge [
+ {
+ home.packages = [ pkgs.mpv ];
+ }
+ (mkIf (cfg.config != {} || cfg.profiles != {}) {
+ xdg.configFile."mpv/mpv.conf".text = ''
+ ${optionalString (cfg.config != {}) (renderOptions cfg.config)}
+ ${optionalString (cfg.profiles != {}) (renderProfiles cfg.profiles)}
+ '';
+ })
+ (mkIf (cfg.bindings != {}) {
+ xdg.configFile."mpv/input.conf".text = renderBindings cfg.bindings;
+ })
+ ]);
+
+ meta.maintainers = with maintainers; [ tadeokondrak ];
+}