1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00
home-manager/modules/programs/mpv.nix
Austin Horstman 86402a17b6 treewide: flatten single file modules
Some files don't need nesting and can be root level again to reduce
conflicts with other PRs.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-06-23 16:20:26 -05:00

258 lines
7 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
generators
literalExpression
mkIf
mkOption
types
;
inherit (builtins) typeOf stringLength;
cfg = config.programs.mpv;
mpvOption = with types; either str (either int (either bool float));
mpvOptionDup = with types; either mpvOption (listOf mpvOption);
mpvOptions = with types; attrsOf mpvOptionDup;
mpvProfiles = with types; attrsOf mpvOptions;
mpvBindings = with types; attrsOf str;
mpvDefaultProfiles = with types; listOf str;
renderOption =
option:
rec {
int = toString option;
float = int;
bool = lib.hm.booleans.yesNo option;
string = option;
}
.${typeOf option};
renderOptionValue =
value:
let
rendered = renderOption value;
length = toString (stringLength rendered);
in
"%${length}%${rendered}";
renderOptions = generators.toKeyValue {
mkKeyValue = generators.mkKeyValueDefault { mkValueString = renderOptionValue; } "=";
listsAsDuplicateKeys = true;
};
renderScriptOptions = generators.toKeyValue {
mkKeyValue = generators.mkKeyValueDefault { mkValueString = renderOption; } "=";
listsAsDuplicateKeys = true;
};
renderProfiles = generators.toINI {
mkKeyValue = generators.mkKeyValueDefault { mkValueString = renderOptionValue; } "=";
listsAsDuplicateKeys = true;
};
renderBindings =
bindings: lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${value}") bindings);
renderDefaultProfiles = profiles: renderOptions { profile = lib.concatStringsSep "," profiles; };
mpvPackage =
if cfg.scripts == [ ] then cfg.package else pkgs.mpv.override { inherit (cfg) scripts; };
in
{
options = {
programs.mpv = {
enable = lib.mkEnableOption "mpv";
package = lib.mkPackageOption pkgs "mpv" {
example = "pkgs.mpv-unwrapped.wrapper { mpv = pkgs.mpv-unwrapped.override { vapoursynthSupport = true; }; youtubeSupport = true; }";
};
finalPackage = mkOption {
type = types.package;
readOnly = true;
visible = false;
description = ''
Resulting mpv package.
'';
};
scripts = mkOption {
type = with types; listOf package;
default = [ ];
example = literalExpression "[ pkgs.mpvScripts.mpris ]";
description = ''
List of scripts to use with mpv.
'';
};
scriptOpts = mkOption {
description = ''
Script options added to
{file}`$XDG_CONFIG_HOME/mpv/script-opts/`. See
{manpage}`mpv(1)`
for the full list of options of builtin scripts.
'';
type = types.attrsOf mpvOptions;
default = { };
example = {
osc = {
scalewindowed = 2.0;
vidscale = false;
visibility = "always";
};
};
};
config = mkOption {
description = ''
Configuration written to
{file}`$XDG_CONFIG_HOME/mpv/mpv.conf`. See
{manpage}`mpv(1)`
for the full list of options.
'';
type = mpvOptions;
default = { };
example = literalExpression ''
{
profile = "gpu-hq";
force-window = true;
ytdl-format = "bestvideo+bestaudio";
cache-default = 4000000;
}
'';
};
includes = mkOption {
type = types.listOf types.str;
default = [ ];
example = literalExpression ''
[
"~/path/to/config.inc";
"~/path/to/conditional.inc";
]
'';
description = "List of configuration files to include at the end of mpv.conf.";
};
profiles = mkOption {
description = ''
Sub-configuration options for specific profiles written to
{file}`$XDG_CONFIG_HOME/mpv/mpv.conf`. See
{option}`programs.mpv.config` for more information.
'';
type = mpvProfiles;
default = { };
example = literalExpression ''
{
fast = {
vo = "vdpau";
};
"protocol.dvd" = {
profile-desc = "profile for dvd:// streams";
alang = "en";
};
}
'';
};
defaultProfiles = mkOption {
description = ''
Profiles to be applied by default. Options set by them are overridden
by options set in [](#opt-programs.mpv.config).
'';
type = mpvDefaultProfiles;
default = [ ];
example = [ "gpu-hq" ];
};
bindings = mkOption {
description = ''
Input configuration written to
{file}`$XDG_CONFIG_HOME/mpv/input.conf`. See
{manpage}`mpv(1)`
for the full list of options.
'';
type = mpvBindings;
default = { };
example = literalExpression ''
{
WHEEL_UP = "seek 10";
WHEEL_DOWN = "seek -10";
"Alt+0" = "set window-scale 0.5";
}
'';
};
extraInput = mkOption {
description = ''
Additional lines that are appended to {file}`$XDG_CONFIG_HOME/mpv/input.conf`.
See {manpage}`mpv(1)` for the full list of options.
'';
type = with types; lines;
default = "";
example = ''
esc quit #! Quit
# script-binding uosc/video #! Video tracks
# additional comments
'';
};
};
};
config = mkIf cfg.enable (
lib.mkMerge [
{
assertions = [
{
assertion = (cfg.scripts == [ ]) || (cfg.package == pkgs.mpv);
message = ''The programs.mpv "package" option is mutually exclusive with "scripts" option.'';
}
];
}
{
home.packages = [ mpvPackage ];
programs.mpv.finalPackage = mpvPackage;
}
(mkIf (cfg.includes != [ ]) {
xdg.configFile."mpv/mpv.conf" = {
text = lib.mkAfter (lib.concatMapStringsSep "\n" (x: "include=${x}") cfg.includes);
};
})
(mkIf (cfg.config != { } || cfg.profiles != { }) {
xdg.configFile."mpv/mpv.conf".text = ''
${lib.optionalString (cfg.defaultProfiles != [ ]) (renderDefaultProfiles cfg.defaultProfiles)}
${lib.optionalString (cfg.config != { }) (renderOptions cfg.config)}
${lib.optionalString (cfg.profiles != { }) (renderProfiles cfg.profiles)}
'';
})
(mkIf (cfg.bindings != { } || cfg.extraInput != "") {
xdg.configFile."mpv/input.conf".text = lib.mkMerge [
(mkIf (cfg.bindings != { }) (renderBindings cfg.bindings))
(mkIf (cfg.extraInput != "") cfg.extraInput)
];
})
{
xdg.configFile = lib.mapAttrs' (
name: value:
lib.nameValuePair "mpv/script-opts/${name}.conf" {
text = renderScriptOptions value;
}
) cfg.scriptOpts;
}
]
);
meta.maintainers = with lib.maintainers; [
thiagokokada
chuangzhu
];
}