{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.mujmap;
mujmapAccounts =
filter (a: a.mujmap.enable) (attrValues config.accounts.email.accounts);
missingNotmuchAccounts = map (a: a.name)
(filter (a: !a.notmuch.enable && a.mujmap.notmuchSetupWarning)
mujmapAccounts);
notmuchConfigHelp =
map (name: "accounts.email.accounts.${name}.notmuch.enable = true;")
missingNotmuchAccounts;
settingsFormat = pkgs.formats.toml { };
filterNull = attrs: attrsets.filterAttrs (n: v: v != null) attrs;
configFile = account:
let
settings'' = if (account.jmap == null) then
{ }
else
filterNull {
fqdn = account.jmap.host;
session_url = account.jmap.sessionUrl;
};
settings' = settings'' // {
username = account.userName;
password_command = escapeShellArgs account.passwordCommand;
} // filterNull account.mujmap.settings;
settings = if (hasAttr "fqdn" settings') then
(removeAttrs settings' [ "session_url" ])
else
settings';
in {
name = "${account.maildir.absPath}/mujmap.toml";
value.source = settingsFormat.generate
"mujmap-${lib.replaceStrings [ "@" ] [ "_at_" ] account.address}.toml"
settings;
};
tagsOpts = {
lowercase = mkOption {
type = types.bool;
default = false;
description = ''
If true, translate all mailboxes to lowercase names when mapping to notmuch
tags.
'';
};
directory_separator = mkOption {
type = types.str;
default = "/";
example = ".";
description = ''
Directory separator for mapping notmuch tags to maildirs.
'';
};
inbox = mkOption {
type = types.str;
default = "inbox";
description = ''
Tag for notmuch to use for messages stored in the mailbox labeled with the
Inbox name attribute.
If set to an empty string, this mailbox and its child
mailboxes are not synchronized with a tag.
'';
};
deleted = mkOption {
type = types.str;
default = "deleted";
description = ''
Tag for notmuch to use for messages stored in the mailbox labeled with the
Trash name attribute.
If set to an empty string, this mailbox and its child
mailboxes are not synchronized with a tag.
'';
};
sent = mkOption {
type = types.str;
default = "sent";
description = ''
Tag for notmuch to use for messages stored in the mailbox labeled with the
Sent name attribute.
If set to an empty string, this mailbox and its child
mailboxes are not synchronized with a tag.
'';
};
spam = mkOption {
type = types.str;
default = "spam";
description = ''
Tag for notmuch to use for messages stored in the mailbox labeled with the
Junk name attribute and/or with the $Junk keyword,
except for messages with the $NotJunk keyword.
If set to an empty string, this mailbox, its child
mailboxes, and these keywords are not synchronized with a tag.
'';
};
important = mkOption {
type = types.str;
default = "important";
description = ''
Tag for notmuch to use for messages stored in the mailbox labeled with the
Important name attribute and/or with the $Important
keyword.
If set to an empty string, this mailbox, its child
mailboxes, and these keywords are not synchronized with a tag.
'';
};
phishing = mkOption {
type = types.str;
default = "phishing";
description = ''
Tag for notmuch to use for the IANA $Phishing keyword.
If set to an empty string, this keyword is not synchronized with a tag.
'';
};
};
rootOpts = {
username = mkOption {
type = types.nullOr types.str;
default = null;
example = "alice@example.com";
description = ''
Username for basic HTTP authentication.
If null, defaults to
.
'';
};
password_command = mkOption {
type = types.nullOr (types.either types.str (types.listOf types.str));
default = null;
apply = p: if isList p then escapeShellArgs p else p;
example = "pass alice@example.com";
description = ''
Shell command which will print a password to stdout for basic HTTP
authentication.
If null, defaults to
.
'';
};
fqdn = mkOption {
type = types.nullOr types.str;
default = null;
example = "example.com";
description = ''
Fully qualified domain name of the JMAP service.
mujmap looks up the JMAP SRV record for this host to determine the JMAP session
URL. Mutually exclusive with
.
If null, defaults to
.
'';
};
session_url = mkOption {
type = types.nullOr types.str;
default = null;
example = "https://jmap.example.com/.well-known/jmap";
description = ''
Sesion URL to connect to.
Mutually exclusive with
.
If null, defaults to
.
'';
};
auto_create_new_mailboxes = mkOption {
type = types.bool;
default = true;
description = ''
Whether to create new mailboxes automatically on the server from notmuch
tags.
'';
};
cache_dir = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The cache directory in which to store mail files while they are being
downloaded. The default is operating-system specific.
'';
};
tags = mkOption {
type = types.submodule {
freeformType = settingsFormat.type;
options = tagsOpts;
};
default = { };
description = ''
Tag configuration.
Beware that there are quirks that require manual consideration if changing the
values of these files; please see
for more details.
'';
};
};
mujmapOpts = {
enable = mkEnableOption "mujmap JMAP synchronization for notmuch";
notmuchSetupWarning = mkOption {
type = types.bool;
default = true;
description = ''
Warn if Notmuch is not also enabled for this account.
This can safely be disabled if mujmap.toml is managed
outside of Home Manager.
'';
};
settings = mkOption {
type = types.submodule {
freeformType = settingsFormat.type;
options = rootOpts;
};
default = { };
description = ''
Settings which are applied to mujmap.toml
for the account.
See the mujmap project
for documentation of settings not explicitly covered by this module.
'';
};
};
mujmapModule = types.submodule { options = { mujmap = mujmapOpts; }; };
in {
meta.maintainers = with maintainers; [ elizagamedev ];
options = {
programs.mujmap = {
enable = mkEnableOption "mujmap Gmail synchronization for notmuch";
package = mkOption {
type = types.package;
default = pkgs.mujmap;
defaultText = "pkgs.mujmap";
description = ''
mujmap package to use.
'';
};
};
accounts.email.accounts =
mkOption { type = with types; attrsOf mujmapModule; };
};
config = mkIf cfg.enable (mkMerge [
(mkIf (missingNotmuchAccounts != [ ]) {
warnings = [''
mujmap is enabled for the following email accounts, but notmuch is not:
${concatStringsSep "\n " missingNotmuchAccounts}
Notmuch can be enabled with:
${concatStringsSep "\n " notmuchConfigHelp}
If you have configured notmuch outside of Home Manager, you can suppress this
warning with:
programs.mujmap.notmuchSetupWarning = false;
''];
})
{
warnings = flatten (map (account: account.warnings) mujmapAccounts);
home.packages = [ cfg.package ];
# Notmuch should ignore non-mail files created by mujmap.
programs.notmuch.new.ignore = [ "/.*[.](toml|json|lock)$/" ];
home.file = listToAttrs (map configFile mujmapAccounts);
}
]);
}