mail: Add notmuch

Aerc’s notmuch support is not yet very mature, so it needs a hacky
workaround to work somewhat well.
This commit is contained in:
Simon Bruder 2022-06-17 01:58:28 +02:00
parent 6d061fa210
commit 2787c28a3d
Signed by: simon
GPG key ID: 8D3C82F9F309F8EC
5 changed files with 102 additions and 12 deletions

View file

@ -13,13 +13,14 @@ let
in in
{ {
accounts.email = { accounts.email = {
maildirBasePath = "${config.xdg.dataHome}/mail";
accounts = { accounts = {
personal = rec { personal = rec {
primary = true; primary = true;
realName = "Simon Bruder"; realName = "Simon Bruder";
address = "simon@sbruder.de"; address = "simon@sbruder.de";
aliases = [ ]; # FIXME!?
userName = address; userName = address;
passwordCommand = "pass sbruder.de/mail"; passwordCommand = "pass sbruder.de/mail";
@ -30,6 +31,7 @@ in
}; };
smtp = { smtp = {
host = "vueko.sbruder.de"; host = "vueko.sbruder.de";
port = 587;
tls.useStartTls = true; tls.useStartTls = true;
}; };
@ -42,6 +44,14 @@ in
signature.text = signaturePersonal; signature.text = signaturePersonal;
aerc.enable = true; aerc.enable = true;
mbsync = {
enable = true;
#flatten = ".";
create = "both";
expunge = "both";
};
msmtp.enable = true;
notmuch.enable = true;
}; };
riseup = rec { riseup = rec {
realName = "Simon Bruder"; realName = "Simon Bruder";
@ -56,6 +66,7 @@ in
}; };
smtp = { smtp = {
host = "mail.riseup.net"; host = "mail.riseup.net";
port = 587;
tls.useStartTls = true; tls.useStartTls = true;
}; };

View file

@ -18,13 +18,20 @@ in
xdg.configFile = { xdg.configFile = {
"aerc/accounts.conf".text = lib.generators.toINI { } (lib.mapAttrs "aerc/accounts.conf".text = lib.generators.toINI { } (lib.mapAttrs
# incomplete support for all configuration options! # incomplete support for all configuration options!
(name: config: with config; let (name: accountConfig: with accountConfig; let
quoteMailAddress = lib.replaceChars [ "@" ] [ "%40" ]; quoteMailAddress = lib.replaceChars [ "@" ] [ "%40" ];
in in
{ {
source = "`imap://${quoteMailAddress address}@${imap.host}`"; source =
if notmuch.enable
then "notmuch://${config.accounts.email.maildirBasePath}"
else "`imap://${quoteMailAddress address}@${imap.host}`";
source-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`"; source-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`";
outgoing = "`smtp+plain://${quoteMailAddress address}@${smtp.host}`"; # TODO: remove when copy-to is implemented in aerc for notmuch
outgoing =
if notmuch.enable
then "${./msmtp-wrapper} ${name}"
else "`smtp+plain://${quoteMailAddress address}@${smtp.host}`";
outgoing-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`"; outgoing-cred-cmd = "`${lib.concatStringsSep " " passwordCommand}`";
from = "${realName} <${address}>"; from = "${realName} <${address}>";
smtp-starttls = if smtp.tls.useStartTls then "yes" else "no"; smtp-starttls = if smtp.tls.useStartTls then "yes" else "no";
@ -33,7 +40,24 @@ in
pgp-key-id = gpg.key; pgp-key-id = gpg.key;
pgp-auto-sign = gpg.signByDefault; pgp-auto-sign = gpg.signByDefault;
pgp-opportunistic-encrypt = gpg.encryptByDefault; 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 (lib.filterAttrs
(_: config: config.aerc.enable) (_: config: config.aerc.enable)
config.accounts.email.accounts)); config.accounts.email.accounts));
@ -47,7 +71,7 @@ in
}; };
ui = { ui = {
index-format = "%-17.17D %-20.20n %Z %s"; index-format = "%-17.17D %-20.20n %Z %-20.20g %s";
# See https://godoc.org/time#Time.Format # See https://godoc.org/time#Time.Format
timestamp-format = "2006-01-02 15:04 MST"; timestamp-format = "2006-01-02 15:04 MST";
@ -62,7 +86,7 @@ in
fuzzy-complete = true; fuzzy-complete = true;
threading-enabled = true; #threading-enabled = true; # broken
new-message-bell = false; new-message-bell = false;
}; };
@ -122,6 +146,8 @@ in
messages = { messages = {
"q" = ":quit<Enter>"; "q" = ":quit<Enter>";
"<C-r>" = ":exec notmuch new<Enter>";
"j" = ":next<Enter>"; "j" = ":next<Enter>";
"<Down>" = ":next<Enter>"; "<Down>" = ":next<Enter>";
"<C-d>" = ":next 50%<Enter>"; "<C-d>" = ":next 50%<Enter>";
@ -147,9 +173,14 @@ in
"T" = ":toggle-threads<Enter>"; "T" = ":toggle-threads<Enter>";
"<Enter>" = ":view<Enter>"; "<Enter>" = ":view<Enter>";
"d" = ":prompt 'Really delete this message?' 'delete-message'<Enter>"; #"d" = ":prompt 'Really delete this message?' ':modify-labels +deleted'<Enter>"; # does not work
"D" = ":delete<Enter>"; "D" = ":modify-labels +deleted -inbox<Enter>";
"A" = ":archive flat<Enter>"; "A" = ":modify-labels -inbox<Enter>";
"ms" = ":modify-labels +spam -inbox<Enter>";
"mS" = ":modify-labels -spam +inbox<Enter>";
"mn" = ":modify-labels +newsletter<Enter>";
"mN" = ":modify-labels -newsletter<Enter>";
"C" = ":compose<Enter>"; "C" = ":compose<Enter>";
@ -176,8 +207,8 @@ in
"O" = ":open<Enter>"; "O" = ":open<Enter>";
"S" = ":save<space>"; "S" = ":save<space>";
"|" = ":pipe<space>"; "|" = ":pipe<space>";
"D" = ":delete<Enter>"; "D" = ":modify-labels +deleted -inbox<Enter>";
"A" = ":archive flat<Enter>"; "A" = ":modify-labels -inbox<Enter>";
"f" = ":forward<Enter>"; "f" = ":forward<Enter>";
"rr" = ":reply -a<Enter>"; "rr" = ":reply -a<Enter>";

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Based on https://paste.sr.ht/~nihil/3a930baa56efba7d56fe03833386ba8b27a23989
# Originally by Samuel Fadel
# For a discussion, see
# https://lists.sr.ht/~rjarry/aerc-devel/%3C93983e01d0226c34394702886ca748b9cca6a046.camel%40posteo.de%3E
set -euo pipefail
EMAIL="$(mktemp -u --suffix=.eml)"
clean_email() {
rm -f "$EMAIL"
}
account="$1"
shift
# <stdin> of script gets the email, we save temporarily for using it twice
# ensure clean_email() is called when we exit abnormally
trap 'clean_email' 0 1 2 3 15
cat > "$EMAIL"
# assumes all maildir accounts are configured with a 'Sent' directory
# make sure to tag it correctly
notmuch insert --folder="$account/Sent" -inbox -unread +sent < "$EMAIL"
# assumes all accounts are configured with the same name as dir name above in msmtprc
# msmtp could be called with args from aerc, but --read-recipients already does the job
msmtp --account="$account" --read-recipients --read-envelope-from < "$EMAIL"

View file

@ -2,5 +2,6 @@
imports = [ imports = [
./accounts.nix ./accounts.nix
./aerc ./aerc
./notmuch.nix
]; ];
} }

View file

@ -0,0 +1,21 @@
{
programs.mbsync.enable = true;
# TODO: remove when copy-to is implemented in aerc for notmuch
programs.msmtp.enable = true;
programs.notmuch = {
enable = true;
hooks = {
preNew = ''
mbsync --all
'';
postNew = ''
notmuch tag +sent -inbox -unread "folder:personal/Sent"
notmuch tag +ebay "to:ebay@sbruder.de"
notmuch tag +kleinanzeigen "to:ebay-kleinanzeigen@sbruder.de"
notmuch tag +git "from:{.*@github.com or .*@gitlab.com or (no-reply+)?gitea@sbruder.de} or subject:[PATCH]"
notmuch tag +newsletter "subject:newsletter and tag:unread"
'';
};
};
}