2023-01-10 09:35:00 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
cfg = config.programs.aerc;
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
primitive = with types;
|
|
|
|
((type: either type (listOf type)) (nullOr (oneOf [ str int bool float ])))
|
|
|
|
// {
|
|
|
|
description =
|
2023-08-08 10:19:01 +00:00
|
|
|
"values (null, bool, int, string, or float) or a list of values, that will be joined with a comma";
|
2023-01-10 09:35:00 +00:00
|
|
|
};
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
confSection = types.attrsOf primitive;
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
confSections = types.attrsOf confSection;
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
sectionsOrLines = types.either types.lines confSections;
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
accounts = import ./aerc-accounts.nix {
|
|
|
|
inherit config pkgs lib confSection confSections;
|
|
|
|
};
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
aerc-accounts =
|
|
|
|
attrsets.filterAttrs (_: v: v.aerc.enable) config.accounts.email.accounts;
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2024-01-05 11:06:15 +00:00
|
|
|
configDir = if (pkgs.stdenv.isDarwin && !config.xdg.enable) then
|
|
|
|
"Library/Preferences/aerc"
|
|
|
|
else
|
|
|
|
"${config.xdg.configHome}/aerc";
|
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
in {
|
|
|
|
meta.maintainers = with lib.hm.maintainers; [ lukasngl ];
|
|
|
|
|
|
|
|
options.accounts.email.accounts = accounts.type;
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
options.programs.aerc = {
|
|
|
|
|
|
|
|
enable = mkEnableOption "aerc";
|
|
|
|
|
2023-08-08 10:19:01 +00:00
|
|
|
package = mkPackageOption pkgs "aerc" { };
|
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
extraAccounts = mkOption {
|
|
|
|
type = sectionsOrLines;
|
|
|
|
default = { };
|
|
|
|
example = literalExpression
|
|
|
|
''{ Work = { source = "maildir://~/Maildir/work"; }; }'';
|
|
|
|
description = ''
|
2023-08-08 10:19:01 +00:00
|
|
|
Extra lines added to {file}`$HOME/.config/aerc/accounts.conf`.
|
|
|
|
|
|
|
|
See {manpage}`aerc-config(5)`.
|
2023-01-10 09:35:00 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraBinds = mkOption {
|
|
|
|
type = sectionsOrLines;
|
|
|
|
default = { };
|
|
|
|
example = literalExpression ''{ messages = { q = ":quit<Enter>"; }; }'';
|
|
|
|
description = ''
|
2023-08-08 10:19:01 +00:00
|
|
|
Extra lines added to {file}`$HOME/.config/aerc/binds.conf`.
|
2023-01-10 09:35:00 +00:00
|
|
|
Global keybindings can be set in the `global` section.
|
2023-08-08 10:19:01 +00:00
|
|
|
|
|
|
|
See {manpage}`aerc-config(5)`.
|
2023-01-10 09:35:00 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = sectionsOrLines;
|
|
|
|
default = { };
|
|
|
|
example = literalExpression ''{ ui = { sort = "-r date"; }; }'';
|
|
|
|
description = ''
|
2023-08-08 10:19:01 +00:00
|
|
|
Extra lines added to {file}`$HOME/.config/aerc/aerc.conf`.
|
|
|
|
|
|
|
|
See {manpage}`aerc-config(5)`.
|
2023-01-10 09:35:00 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
stylesets = mkOption {
|
|
|
|
type = with types; attrsOf (either confSection lines);
|
|
|
|
default = { };
|
|
|
|
example = literalExpression ''
|
|
|
|
{ default = { ui = { "tab.selected.reverse" = toggle; }; }; };
|
|
|
|
'';
|
|
|
|
description = ''
|
2023-08-08 10:19:01 +00:00
|
|
|
Stylesets added to {file}`$HOME/.config/aerc/stylesets/`.
|
|
|
|
|
|
|
|
See {manpage}`aerc-stylesets(7)`.
|
2023-01-10 09:35:00 +00:00
|
|
|
'';
|
|
|
|
};
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
templates = mkOption {
|
|
|
|
type = with types; attrsOf lines;
|
|
|
|
default = { };
|
|
|
|
example = literalExpression ''
|
|
|
|
{ new_message = "Hello!"; };
|
|
|
|
'';
|
|
|
|
description = ''
|
2023-08-08 10:19:01 +00:00
|
|
|
Templates added to {file}`$HOME/.config/aerc/templates/`.
|
|
|
|
|
|
|
|
See {manpage}`aerc-templates(7)`.
|
2023-01-10 09:35:00 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = let
|
2023-08-08 10:19:01 +00:00
|
|
|
joinCfg = cfgs: concatStringsSep "\n" (filter (v: v != "") cfgs);
|
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
toINI = conf: # quirk: global section is prepended w/o section heading
|
|
|
|
let
|
|
|
|
global = conf.global or { };
|
|
|
|
local = removeAttrs conf [ "global" ];
|
|
|
|
mkValueString = v:
|
|
|
|
if isList v then # join with comma
|
|
|
|
concatStringsSep "," (map (generators.mkValueStringDefault { }) v)
|
|
|
|
else
|
|
|
|
generators.mkValueStringDefault { } v;
|
|
|
|
mkKeyValue =
|
|
|
|
generators.mkKeyValueDefault { inherit mkValueString; } " = ";
|
|
|
|
in joinCfg [
|
|
|
|
(generators.toKeyValue { inherit mkKeyValue; } global)
|
|
|
|
(generators.toINI { inherit mkKeyValue; } local)
|
|
|
|
];
|
2023-08-08 10:19:01 +00:00
|
|
|
|
|
|
|
mkINI = conf: if isString conf then conf else toINI conf;
|
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
mkStyleset = attrsets.mapAttrs' (k: v:
|
2023-08-08 10:19:01 +00:00
|
|
|
let value = if isString v then v else toINI { global = v; };
|
2023-01-10 09:35:00 +00:00
|
|
|
in {
|
2024-01-05 11:06:15 +00:00
|
|
|
name = "${configDir}/stylesets/${k}";
|
2023-01-10 09:35:00 +00:00
|
|
|
value.text = joinCfg [ header value ];
|
|
|
|
});
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
mkTemplates = attrsets.mapAttrs' (k: v: {
|
2024-01-05 11:06:15 +00:00
|
|
|
name = "${configDir}/templates/${k}";
|
2023-01-10 09:35:00 +00:00
|
|
|
value.text = v;
|
|
|
|
});
|
2023-08-08 10:19:01 +00:00
|
|
|
|
|
|
|
primaryAccount = attrsets.filterAttrs (_: v: v.primary) aerc-accounts;
|
|
|
|
otherAccounts = attrsets.filterAttrs (_: v: !v.primary) aerc-accounts;
|
|
|
|
|
|
|
|
primaryAccountAccounts = mapAttrs accounts.mkAccount primaryAccount;
|
|
|
|
|
|
|
|
accountsExtraAccounts = mapAttrs accounts.mkAccount otherAccounts;
|
|
|
|
|
|
|
|
accountsExtraConfig = mapAttrs accounts.mkAccountConfig aerc-accounts;
|
|
|
|
|
|
|
|
accountsExtraBinds = mapAttrs accounts.mkAccountBinds aerc-accounts;
|
|
|
|
|
|
|
|
joinContextual = contextual: joinCfg (map mkINI (attrValues contextual));
|
|
|
|
|
|
|
|
isRecursivelyEmpty = x:
|
|
|
|
if isAttrs x then
|
|
|
|
all (x: x == { } || isRecursivelyEmpty x) (attrValues x)
|
|
|
|
else
|
|
|
|
false;
|
|
|
|
|
|
|
|
genAccountsConf = ((cfg.extraAccounts != "" && cfg.extraAccounts != { })
|
|
|
|
|| !(isRecursivelyEmpty accountsExtraAccounts)
|
|
|
|
|| !(isRecursivelyEmpty primaryAccountAccounts));
|
|
|
|
|
|
|
|
genAercConf = ((cfg.extraConfig != "" && cfg.extraConfig != { })
|
|
|
|
|| !(isRecursivelyEmpty accountsExtraConfig));
|
|
|
|
|
|
|
|
genBindsConf = ((cfg.extraBinds != "" && cfg.extraBinds != { })
|
|
|
|
|| !(isRecursivelyEmpty accountsExtraBinds));
|
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
header = ''
|
|
|
|
# Generated by Home Manager.
|
|
|
|
'';
|
2023-08-08 10:19:01 +00:00
|
|
|
|
2023-01-10 09:35:00 +00:00
|
|
|
in mkIf cfg.enable {
|
2023-08-08 10:19:01 +00:00
|
|
|
warnings = if genAccountsConf
|
2023-01-10 09:35:00 +00:00
|
|
|
&& (cfg.extraConfig.general.unsafe-accounts-conf or false) == false then [''
|
2023-08-08 10:19:01 +00:00
|
|
|
aerc: `programs.aerc.enable` is set, but `...extraConfig.general.unsafe-accounts-conf` is set to false or unset.
|
|
|
|
This will prevent aerc from starting; see `unsafe-accounts-conf` in the man page aerc-config(5):
|
|
|
|
> By default, the file permissions of accounts.conf must be restrictive and only allow reading by the file owner (0600).
|
|
|
|
> Set this option to true to ignore this permission check. Use this with care as it may expose your credentials.
|
|
|
|
These permissions are not possible with home-manager, since the generated file is in the nix-store (permissions 0444).
|
|
|
|
Therefore, please set `programs.aerc.extraConfig.general.unsafe-accounts-conf = true`.
|
|
|
|
This option is safe; if `passwordCommand` is properly set, no credentials will be written to the nix store.
|
2023-01-10 09:35:00 +00:00
|
|
|
''] else
|
|
|
|
[ ];
|
2023-08-08 10:19:01 +00:00
|
|
|
|
|
|
|
assertions = [{
|
|
|
|
assertion = let
|
|
|
|
extraConfigSections = (unique (flatten
|
|
|
|
(mapAttrsToList (_: v: attrNames v.aerc.extraConfig) aerc-accounts)));
|
|
|
|
in extraConfigSections == [ ] || extraConfigSections == [ "ui" ];
|
|
|
|
message = ''
|
|
|
|
Only the ui section of $XDG_CONFIG_HOME/aerc.conf supports contextual (per-account) configuration.
|
|
|
|
Please configure it with accounts.email.accounts._.aerc.extraConfig.ui and move any other
|
|
|
|
configuration to programs.aerc.extraConfig.
|
|
|
|
'';
|
|
|
|
}];
|
|
|
|
|
|
|
|
home.packages = [ cfg.package ];
|
|
|
|
|
2024-01-05 11:06:15 +00:00
|
|
|
home.file = {
|
|
|
|
"${configDir}/accounts.conf" = mkIf genAccountsConf {
|
2023-08-08 10:19:01 +00:00
|
|
|
text = joinCfg [
|
|
|
|
header
|
|
|
|
(mkINI cfg.extraAccounts)
|
|
|
|
(mkINI primaryAccountAccounts)
|
|
|
|
(mkINI accountsExtraAccounts)
|
|
|
|
];
|
|
|
|
};
|
|
|
|
|
2024-01-05 11:06:15 +00:00
|
|
|
"${configDir}/aerc.conf" = mkIf genAercConf {
|
2023-08-08 10:19:01 +00:00
|
|
|
text = joinCfg [
|
|
|
|
header
|
|
|
|
(mkINI cfg.extraConfig)
|
|
|
|
(joinContextual accountsExtraConfig)
|
|
|
|
];
|
|
|
|
};
|
|
|
|
|
2024-01-05 11:06:15 +00:00
|
|
|
"${configDir}/binds.conf" = mkIf genBindsConf {
|
2023-08-08 10:19:01 +00:00
|
|
|
text = joinCfg [
|
|
|
|
header
|
|
|
|
(mkINI cfg.extraBinds)
|
|
|
|
(joinContextual accountsExtraBinds)
|
|
|
|
];
|
|
|
|
};
|
2023-01-10 09:35:00 +00:00
|
|
|
} // (mkStyleset cfg.stylesets) // (mkTemplates cfg.templates);
|
|
|
|
};
|
|
|
|
}
|