mime: support multiple implementors of the same association, with different priorities

This commit is contained in:
Colin 2023-07-15 10:04:22 +00:00
parent 29b53d934f
commit 088286d8f7
9 changed files with 48 additions and 20 deletions

View File

@ -1,14 +1,25 @@
{ config, lib, ...}:
let
# ProgramConfig -> { "<mime-type>" = { priority, desktop }; }
weightedMimes = prog: builtins.mapAttrs (_key: desktop: { priority = prog.mime.priority; desktop = desktop; }) prog.mime.associations;
# [ { "<mime-type>" = { priority, desktop } ]; } ] -> { "<mime-type>" = [ { priority, desktop } ... ]; }
mergeMimes = mimes: lib.foldAttrs (item: acc: [item] ++ acc) [] mimes;
# [ { priority, desktop } ... ] -> Self
sortOneMimeType = associations: builtins.sort (l: r: assert l.priority != r.priority; l.priority < r.priority) associations;
sortMimes = mimes: builtins.mapAttrs (_k: sortOneMimeType) mimes;
removePriorities = mimes: builtins.mapAttrs (_k: associations: builtins.map (a: a.desktop) associations) mimes;
# [ ProgramConfig ]
enabledPrograms = builtins.filter (p: p.enabled) (builtins.attrValues config.sane.programs);
# [ { "<mime-type>" = { prority, desktop } ]
enabledWeightedMimes = builtins.map weightedMimes enabledPrograms;
in
{
# the xdg mime type for a file can be found with:
# - `xdg-mime query filetype path/to/thing.ext`
# we can have single associations or a list of associations.
# there's also options to *remove* [non-default] associations from specific apps
xdg.mime.enable = true;
xdg.mime.defaultApplications = lib.mkMerge (
builtins.map
(p: lib.mkIf p.enabled p.mime)
(builtins.attrValues config.sane.programs)
);
xdg.mime.defaultApplications = removePriorities (sortMimes (mergeMimes enabledWeightedMimes));
}

View File

@ -4,6 +4,6 @@
{
sane.programs.aerc = {
secrets.".config/aerc/accounts.conf" = ../../../secrets/common/aerc_accounts.conf.bin;
mime."x-scheme-handler/mailto" = "aerc.desktop";
mime.associations."x-scheme-handler/mailto" = "aerc.desktop";
};
}

View File

@ -31,5 +31,15 @@
".local/share/epiphany"
# also .config/epiphany, but appears empty
];
mime.priority = 200; # default priority is 100: install epiphany only as a fallback
mime.associations = let
desktop = "org.gnome.Epiphany.desktop";
in {
"text/html" = desktop;
"x-scheme-handler/http" = desktop;
"x-scheme-handler/https" = desktop;
"x-scheme-handler/about" = desktop;
"x-scheme-handler/unknown" = desktop;
};
};
}

View File

@ -1,4 +1,4 @@
{ ... }:
{
sane.programs.evince.mime."application/pdf" = "org.gnome.Evince.desktop";
sane.programs.evince.mime.associations."application/pdf" = "org.gnome.Evince.desktop";
}

View File

@ -193,7 +193,7 @@ in
sane.programs.firefox = {
inherit package;
mime = let
mime.associations = let
inherit (cfg.browser) desktop;
in {
"text/html" = desktop;

View File

@ -3,8 +3,8 @@
sane.programs.gthumb = {
# compile without webservices to avoid the expensive webkitgtk dependency
package = pkgs.gthumb.override { withWebservices = false; };
mime."image/heif" = "org.gnome.gThumb.desktop"; # apple codec
mime."image/png" = "org.gnome.gThumb.desktop";
mime."image/jpeg" = "org.gnome.gThumb.desktop";
mime.associations."image/heif" = "org.gnome.gThumb.desktop"; # apple codec
mime.associations."image/png" = "org.gnome.gThumb.desktop";
mime.associations."image/jpeg" = "org.gnome.gThumb.desktop";
};
}

View File

@ -1,4 +1,4 @@
{ ... }:
{
sane.programs.obsidian.mime."text/markdown" = "obsidian.desktop";
sane.programs.obsidian.mime.associations."text/markdown" = "obsidian.desktop";
}

View File

@ -26,12 +26,12 @@ in
qt-privacy-ask=0
'';
mime."audio/flac" = "vlc.desktop";
mime."audio/mpeg" = "vlc.desktop";
mime."audio/x-vorbis+ogg" = "vlc.desktop";
mime."video/mp4" = "vlc.desktop";
mime."video/quicktime" = "vlc.desktop";
mime."video/webm" = "vlc.desktop";
mime."video/x-matroska" = "vlc.desktop";
mime.associations."audio/flac" = "vlc.desktop";
mime.associations."audio/mpeg" = "vlc.desktop";
mime.associations."audio/x-vorbis+ogg" = "vlc.desktop";
mime.associations."video/mp4" = "vlc.desktop";
mime.associations."video/quicktime" = "vlc.desktop";
mime.associations."video/webm" = "vlc.desktop";
mime.associations."video/x-matroska" = "vlc.desktop";
};
}

View File

@ -79,7 +79,14 @@ let
type = types.bool;
default = true;
};
mime = mkOption {
mime.priority = mkOption {
type = types.int;
default = 100;
description = ''
program with the numerically lower priority takes precedence whenever two mime associations overlap.
'';
};
mime.associations = mkOption {
type = types.attrsOf types.str;
default = {};
description = ''