{ config, lib, pkgs, ... }: with lib; with builtins; let cfg = config.programs.astroid; astroidAccounts = filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts; boolOpt = b: if b then "true" else "false"; accountAttr = account: with account; { email = address; name = realName; sendmail = astroid.sendMailCommand; additional_sent_tags = ""; default = boolOpt primary; save_drafts_to = "${maildir.absPath}/${folders.drafts}"; save_sent = "true"; save_sent_to = "${maildir.absPath}/${folders.sent}"; select_query = ""; } // optionalAttrs (signature.showSignature != "none") { signature_attach = boolOpt (signature.showSignature == "attach"); signature_default_on = boolOpt (signature.showSignature != "none"); signature_file = pkgs.writeText "signature.txt" signature.text; signature_file_markdown = "false"; signature_separate = "true"; # prepends '--\n' to the signature } // optionalAttrs (gpg != null) { always_gpg_sign = boolOpt gpg.signByDefault; gpgkey = gpg.key; } // astroid.extraConfig; # See https://github.com/astroidmail/astroid/wiki/Configuration-Reference configFile = mailAccounts: let template = fromJSON (readFile ./astroid-config-template.json); astroidConfig = foldl' recursiveUpdate template [ { astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc"; accounts = mapAttrs (n: accountAttr) astroidAccounts; crypto.gpg.path = "${pkgs.gnupg}/bin/gpg"; } cfg.extraConfig cfg.externalEditor ]; in builtins.toJSON astroidConfig; in { options = { programs.astroid = { enable = mkEnableOption "Astroid"; pollScript = mkOption { type = types.str; default = ""; example = "mbsync gmail"; description = '' Script to run to fetch/update mails. ''; }; externalEditor = mkOption { type = types.nullOr types.str; default = null; # Converts it into JSON that can be merged into the configuration. apply = cmd: optionalAttrs (cmd != null) { editor = { "external_editor" = "true"; "cmd" = cmd; }; }; example = "nvim-qt -- -c 'set ft=mail' '+set fileencoding=utf-8' '+set ff=unix' '+set enc=utf-8' '+set fo+=w' %1"; description = '' You can use %1, %2, and %3 to refer respectively to: file name server name socket ID See . ''; }; extraConfig = mkOption { type = types.attrs; default = {}; example = { poll.interval = 0; }; description = '' JSON config that will override the default Astroid configuration. ''; }; }; }; config = mkIf cfg.enable { assertions = [ { assertion = config.programs.notmuch.maildir.synchronizeFlags; message = "The astroid module requires" + " 'programs.notmuch.maildir.synchronizeFlags = true'."; } ]; home.packages = [ pkgs.astroid ]; xdg.configFile."astroid/config".source = pkgs.runCommand "out.json" { json = configFile astroidAccounts; preferLocalBuild = true; allowSubstitutes = false; } '' echo -n "$json" | ${pkgs.jq}/bin/jq . > $out ''; xdg.configFile."astroid/poll.sh" = { executable = true; text = '' # Generated by Home Manager ${cfg.pollScript} ''; }; }; }