aboutsummaryrefslogtreecommitdiff
path: root/home-manager/modules/programs/mpv.nix
blob: 3a4e5092f9aed8a7c27edef6beca2d2c27ba110e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{ 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";

      scripts = mkOption {
        type = with types; listOf (either package str);
        default = [ ];
        example = literalExample "[ pkgs.mpvScripts.mpris ]";
        description = ''
          List of scripts to use with mpv.
        '';
      };

      config = mkOption {
        description = ''
          Configuration written to
          <filename>~/.config/mpv/mpv.conf</filename>. See
          <citerefentry>
            <refentrytitle>mpv</refentrytitle>
            <manvolnum>1</manvolnum>
          </citerefentry>
          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
          <filename>~/.config/mpv/mpv.conf</filename>. See
          <option>programs.mpv.config</option> 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
          <filename>~/.config/mpv/input.conf</filename>. See
          <citerefentry>
            <refentrytitle>mpv</refentrytitle>
            <manvolnum>1</manvolnum>
          </citerefentry>
          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 = [
        (if cfg.scripts == [ ] then
          pkgs.mpv
        else
          pkgs.mpv-with-scripts.override { scripts = cfg.scripts; })
      ];
    }
    (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 ];
}