From 47c5bd533803a79391a3f5f529a96fcfbb42451d Mon Sep 17 00:00:00 2001 From: Simon Bruder Date: Sat, 10 Dec 2022 16:03:16 +0100 Subject: [PATCH] mail/aerc: Use home-manager module (mostly) This does not use the home-manager provided account module, because it does not support notmuch, LOGIN authentication and special characters in user names. --- users/simon/modules/mail/accounts.nix | 6 +- users/simon/modules/mail/aerc/default.nix | 381 +++++++++++----------- 2 files changed, 194 insertions(+), 193 deletions(-) diff --git a/users/simon/modules/mail/accounts.nix b/users/simon/modules/mail/accounts.nix index 70f5bc1..6939ed5 100644 --- a/users/simon/modules/mail/accounts.nix +++ b/users/simon/modules/mail/accounts.nix @@ -44,7 +44,7 @@ in signature.text = signaturePersonal; - aerc.enable = true; + aerc-sbruder.enable = true; mbsync = { enable = true; #flatten = "."; @@ -79,7 +79,7 @@ in signature.text = signaturePersonal; - aerc.enable = true; + aerc-sbruder.enable = true; }; tu-dresden = rec { realName = "Simon Bruder"; @@ -106,7 +106,7 @@ in signature.text = signaturePersonal; - aerc.enable = true; + aerc-sbruder.enable = true; }; }; }; diff --git a/users/simon/modules/mail/aerc/default.nix b/users/simon/modules/mail/aerc/default.nix index 297e203..c246bff 100644 --- a/users/simon/modules/mail/aerc/default.nix +++ b/users/simon/modules/mail/aerc/default.nix @@ -1,73 +1,70 @@ { config, lib, pkgs, ... }: -let - package = pkgs.aerc; -in + { options = { accounts.email.accounts = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { - options.aerc.enable = lib.mkEnableOption "aerc"; + options.aerc-sbruder.enable = lib.mkEnableOption "aerc (custom implementation)"; }); }; }; config = { - home.packages = [ - package - ]; + programs.aerc = { + enable = true; - xdg.configFile = { - "aerc/accounts.conf".text = lib.generators.toINI { } (lib.mapAttrs - # incomplete support for all configuration options! - (name: accountConfig: with accountConfig; let - quoteMailAddress = lib.replaceChars [ "@" "\\" ] [ "%40" "%5C" ]; - # home-manager has no way to set if an account requires AUTH LOGIN - # this emulats this by setting a list of known providers that do require it - requiresLogin = lib.elem - (lib.elemAt (lib.strings.splitString "@" address) 1) - [ "mailbox.tu-dresden.de" ]; - in - { - source = - if notmuch.enable - then "notmuch://${config.accounts.email.maildirBasePath}" - else "`imap://${quoteMailAddress userName}@${imap.host}`"; - source-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`"; - # TODO: remove when copy-to is implemented in aerc for notmuch - outgoing = - if notmuch.enable - then "${./msmtp-wrapper} ${name}" - else "`smtp${lib.optionalString requiresLogin "+login"}://${quoteMailAddress userName}@${smtp.host}`"; - outgoing-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`"; - from = "${realName} <${address}>"; - smtp-starttls = if smtp.tls.useStartTls then "yes" else "no"; - copy-to = "Sent"; - signature-file = pkgs.writeText "signature-${name}" signature.text; - pgp-key-id = gpg.key; - pgp-auto-sign = gpg.signByDefault; - pgp-opportunistic-encrypt = gpg.encryptByDefault; - } // (lib.optionalAttrs notmuch.enable { - query-map = pkgs.writeText "aerc-query-map" '' - Archive=not tag:inbox and not tag:sent - Git=tag:git - INBOX=tag:inbox - Newsletter=tag:newsletter - Sent=tag:sent - Spam=tag:spam - Trash=tag:deleted - eBay Kleinanzeigen=tag:kleinanzeigen - eBay=tag:ebay - ''; - exclude-tags = lib.concatStringsSep "," [ - "archived" - "deleted" - "spam" - ]; - })) - (lib.filterAttrs - (_: config: config.aerc.enable) - config.accounts.email.accounts)); + # incomplete support for all configuration options! + extraAccounts = + (lib.mapAttrs + (name: accountConfig: with accountConfig; let + quoteMailAddress = lib.replaceChars [ "@" "\\" ] [ "%40" "%5C" ]; + # home-manager has no way to set if an account requires AUTH LOGIN + # this emulats this by setting a list of known providers that do require it + requiresLogin = lib.elem + (lib.elemAt (lib.strings.splitString "@" address) 1) + [ "mailbox.tu-dresden.de" ]; + in + { + source = + if notmuch.enable + then "notmuch://${config.accounts.email.maildirBasePath}" + else "`imap://${quoteMailAddress userName}@${imap.host}`"; + source-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`"; + # TODO: remove when copy-to is implemented in aerc for notmuch + outgoing = + if notmuch.enable + then "${./msmtp-wrapper} ${name}" + else "`smtp${lib.optionalString requiresLogin "+login"}://${quoteMailAddress userName}@${smtp.host}`"; + outgoing-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`"; + from = "${realName} <${address}>"; + smtp-starttls = if smtp.tls.useStartTls then "yes" else "no"; + copy-to = "Sent"; + signature-file = toString (pkgs.writeText "signature-${name}" signature.text); + pgp-key-id = gpg.key; + pgp-auto-sign = gpg.signByDefault; + pgp-opportunistic-encrypt = gpg.encryptByDefault; + } // (lib.optionalAttrs notmuch.enable { + query-map = toString (pkgs.writeText "aerc-query-map" '' + Archive=not tag:inbox and not tag:sent + Git=tag:git + INBOX=tag:inbox + Newsletter=tag:newsletter + Sent=tag:sent + Spam=tag:spam + Trash=tag:deleted + eBay Kleinanzeigen=tag:kleinanzeigen + eBay=tag:ebay + ''); + exclude-tags = lib.concatStringsSep "," [ + "archived" + "deleted" + "spam" + ]; + })) + (lib.filterAttrs + (_: config: config.aerc-sbruder.enable) + config.accounts.email.accounts)); - "aerc/aerc.conf".text = lib.generators.toINI { } { + extraConfig = { general = { pgp-provider = "gpg"; # internal does not work @@ -124,10 +121,10 @@ in }; filters = { - "subject,~^\\[PATCH" = "awk -f ${package}/share/aerc/filters/hldiff"; + "subject,~^\\[PATCH" = "awk -f ${pkgs.aerc}/share/aerc/filters/hldiff"; "text/plain" = "${./colorize}"; # taken from upstream and patched "text/html" = "html"; # internal filter - "text/calendar" = "${pkgs.python3.withPackages (ps: with ps; [ vobject ])}/bin/python ${package}/share/aerc/filters/show-ics-details.py"; # hacky fix for broken nix support + "text/calendar" = "${pkgs.python3.withPackages (ps: with ps; [ vobject ])}/bin/python ${pkgs.aerc}/share/aerc/filters/show-ics-details.py"; # hacky fix for broken nix support }; triggers = { @@ -137,8 +134,8 @@ in templates = { }; }; - "aerc/binds.conf".text = lib.generators.toINIWithGlobalSection { } { - globalSection = { + extraBinds = { + global = { # Binds are of the form = # To use '=' in a key sequence, substitute it with "Eq": "" # If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit @@ -147,163 +144,167 @@ in "" = ":term"; }; - sections = { - messages = { - "q" = ":quit"; + messages = { + "q" = ":quit"; - "" = ":exec notmuch new"; + "" = ":exec notmuch new"; - "j" = ":next"; - "" = ":next"; - "" = ":next 50%"; - "" = ":next 100%"; - "" = ":next 100%"; + "j" = ":next"; + "" = ":next"; + "" = ":next 50%"; + "" = ":next 100%"; + "" = ":next 100%"; - "k" = ":prev"; - "" = ":prev"; - "" = ":prev 50%"; - "" = ":prev 100%"; - "" = ":prev 100%"; - "g" = ":select 0"; - "G" = ":select -1"; + "k" = ":prev"; + "" = ":prev"; + "" = ":prev 50%"; + "" = ":prev 100%"; + "" = ":prev 100%"; + "g" = ":select 0"; + "G" = ":select -1"; - "J" = ":next-folder"; - "K" = ":prev-folder"; - "H" = ":collapse-folder"; - "L" = ":expand-folder"; + "J" = ":next-folder"; + "K" = ":prev-folder"; + "H" = ":collapse-folder"; + "L" = ":expand-folder"; - "v" = ":mark -t"; - "V" = ":mark -v"; + "v" = ":mark -t"; + "V" = ":mark -v"; - "T" = ":toggle-threads"; + "T" = ":toggle-threads"; - "" = ":view"; - #"d" = ":prompt 'Really delete this message?' ':modify-labels +deleted'"; # does not work - "D" = ":modify-labels +deleted -inbox"; - "A" = ":modify-labels -inbox"; + "" = ":view"; + #"d" = ":prompt 'Really delete this message?' ':modify-labels +deleted'"; # does not work + "D" = ":modify-labels +deleted -inbox"; + "A" = ":modify-labels -inbox"; - "ms" = ":modify-labels +spam -inbox"; - "mS" = ":modify-labels -spam +inbox"; - "mn" = ":modify-labels +newsletter"; - "mN" = ":modify-labels -newsletter"; + "ms" = ":modify-labels +spam -inbox"; + "mS" = ":modify-labels -spam +inbox"; + "mn" = ":modify-labels +newsletter"; + "mN" = ":modify-labels -newsletter"; - "C" = ":compose"; + "C" = ":compose"; - "rr" = ":reply -a"; - "rq" = ":reply -aq"; - "Rr" = ":reply"; - "Rq" = ":reply -q"; + "rr" = ":reply -a"; + "rq" = ":reply -aq"; + "Rr" = ":reply"; + "Rq" = ":reply -q"; - "c" = ":cf"; - "$" = ":term"; - "!" = ":term"; - "|" = ":pipe"; + "c" = ":cf"; + "$" = ":term"; + "!" = ":term"; + "|" = ":pipe"; - "/" = ":search"; - "\\" = ":filter"; - "n" = ":next-result"; - "N" = ":prev-result"; - "" = ":clear"; - }; + "/" = ":search"; + "\\" = ":filter"; + "n" = ":next-result"; + "N" = ":prev-result"; + "" = ":clear"; + }; - view = { - "/" = ":toggle-key-passthrough/"; - "q" = ":close"; - "O" = ":open"; - "S" = ":save"; - "|" = ":pipe"; - "D" = ":modify-labels +deleted -inbox"; - "A" = ":modify-labels -inbox"; + view = { + "/" = ":toggle-key-passthrough/"; + "q" = ":close"; + "O" = ":open"; + "S" = ":save"; + "|" = ":pipe"; + "D" = ":modify-labels +deleted -inbox"; + "A" = ":modify-labels -inbox"; - "f" = ":forward"; - "rr" = ":reply -a"; - "rq" = ":reply -aq"; - "Rr" = ":reply"; - "Rq" = ":reply -q"; + "f" = ":forward"; + "rr" = ":reply -a"; + "rq" = ":reply -aq"; + "Rr" = ":reply"; + "Rq" = ":reply -q"; - "H" = ":toggle-headers"; - "" = ":prev-part"; - "" = ":next-part"; - "J" = ":next"; - "K" = ":prev"; - }; + "H" = ":toggle-headers"; + "" = ":prev-part"; + "" = ":next-part"; + "J" = ":next"; + "K" = ":prev"; + }; - "view::passthrough" = { - "$noinherit" = "true"; - "$ex" = ""; - "" = ":toggle-key-passthrough"; - }; + "view::passthrough" = { + "$noinherit" = "true"; + "$ex" = ""; + "" = ":toggle-key-passthrough"; + }; - # Keybindings used when the embedded terminal is not selected in the compose view" - compose = { - "$ex" = ""; - "" = ":prev-field"; - "" = ":next-field"; - "" = ":next-field"; - "" = ":prev-field"; - }; + # Keybindings used when the embedded terminal is not selected in the compose view" + compose = { + "$ex" = ""; + "" = ":prev-field"; + "" = ":next-field"; + "" = ":next-field"; + "" = ":prev-field"; + }; - # Keybindings used when the embedded terminal is selected in the compose view - "compose::editor" = { - "$noinherit" = "true"; - "$ex" = ""; - "" = ":prev-field"; - "" = ":next-field"; - "" = ":prev-tab"; - "" = ":next-tab"; - }; + # Keybindings used when the embedded terminal is selected in the compose view + "compose::editor" = { + "$noinherit" = "true"; + "$ex" = ""; + "" = ":prev-field"; + "" = ":next-field"; + "" = ":prev-tab"; + "" = ":next-tab"; + }; - # Keybindings used when reviewing a message to be sent - "compose::review" = { - "y" = ":send"; - "n" = ":abort"; - "p" = ":postpone"; - "q" = ":choose -o d discard abort -o p postpone postpone"; - "e" = ":edit"; - "a" = ":attach"; - "d" = ":detach"; - }; + # Keybindings used when reviewing a message to be sent + "compose::review" = { + "y" = ":send"; + "n" = ":abort"; + "p" = ":postpone"; + "q" = ":choose -o d discard abort -o p postpone postpone"; + "e" = ":edit"; + "a" = ":attach"; + "d" = ":detach"; + }; - terminal = { - "$noinherit" = "true"; - "$ex" = ""; + terminal = { + "$noinherit" = "true"; + "$ex" = ""; - "" = ":prev-tab"; - "" = ":next-tab"; - }; + "" = ":prev-tab"; + "" = ":next-tab"; }; }; - "aerc/stylesets/default".text = lib.concatStrings - (lib.mapAttrsToList - (k: v: "${k} = ${if lib.isBool v then (if v then "true" else "false") else toString v}\n") - { - "*.selected.reverse" = true; + stylesets = { + default = { + "*.selected.reverse" = true; - "title.reverse" = true; - "header.bold" = true; + "title.reverse" = true; + "header.bold" = true; - "*error.bold" = true; - "error.fg" = 1; - "warning.fg" = 3; - "success.fg" = 2; + "*error.bold" = true; + "error.fg" = 1; + "warning.fg" = 3; + "success.fg" = 2; - "statusline_default.bg" = 0; - "statusline_error.fg" = 1; - "statusline_error.reverse" = true; - "statusline_success.fg" = 2; - "statusline_success.reverse" = true; + "statusline_default.bg" = 0; + "statusline_error.fg" = 1; + "statusline_error.reverse" = true; + "statusline_success.fg" = 2; + "statusline_success.reverse" = true; - "msglist_unread.bold" = true; - "msglist_deleted.fg" = 10; + "msglist_unread.bold" = true; + "msglist_deleted.fg" = 10; - "tab.bg" = 11; - "tab.selected.reverse" = false; - "tab.selected.bg" = 12; - "tab.fg" = 0; + "tab.bg" = 11; + "tab.selected.reverse" = false; + "tab.selected.bg" = 12; + "tab.fg" = 0; - "completion_default.bg" = 0; - }); + "completion_default.bg" = 0; + }; + }; }; + + #quoteMailAddress = lib.replaceChars [ "@" "\\" ] [ "%40" "%5C" ]; + ## home-manager has no way to set if an account requires AUTH LOGIN + ## this emulats this by setting a list of known providers that do require it + #requiresLogin = lib.elem + # (lib.elemAt (lib.strings.splitString "@" address) 1) + # [ "mailbox.tu-dresden.de" ]; }; }