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.
This commit is contained in:
parent
71308a9284
commit
47c5bd5338
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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 <key sequence> = <command to run>
|
||||
# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>"
|
||||
# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit
|
||||
|
@ -147,163 +144,167 @@ in
|
|||
"<C-t>" = ":term<Enter>";
|
||||
};
|
||||
|
||||
sections = {
|
||||
messages = {
|
||||
"q" = ":quit<Enter>";
|
||||
messages = {
|
||||
"q" = ":quit<Enter>";
|
||||
|
||||
"<C-r>" = ":exec notmuch new<Enter>";
|
||||
"<C-r>" = ":exec notmuch new<Enter>";
|
||||
|
||||
"j" = ":next<Enter>";
|
||||
"<Down>" = ":next<Enter>";
|
||||
"<C-d>" = ":next 50%<Enter>";
|
||||
"<C-f>" = ":next 100%<Enter>";
|
||||
"<PgDn>" = ":next 100%<Enter>";
|
||||
"j" = ":next<Enter>";
|
||||
"<Down>" = ":next<Enter>";
|
||||
"<C-d>" = ":next 50%<Enter>";
|
||||
"<C-f>" = ":next 100%<Enter>";
|
||||
"<PgDn>" = ":next 100%<Enter>";
|
||||
|
||||
"k" = ":prev<Enter>";
|
||||
"<Up>" = ":prev<Enter>";
|
||||
"<C-u>" = ":prev 50%<Enter>";
|
||||
"<C-b>" = ":prev 100%<Enter>";
|
||||
"<PgUp>" = ":prev 100%<Enter>";
|
||||
"g" = ":select 0<Enter>";
|
||||
"G" = ":select -1<Enter>";
|
||||
"k" = ":prev<Enter>";
|
||||
"<Up>" = ":prev<Enter>";
|
||||
"<C-u>" = ":prev 50%<Enter>";
|
||||
"<C-b>" = ":prev 100%<Enter>";
|
||||
"<PgUp>" = ":prev 100%<Enter>";
|
||||
"g" = ":select 0<Enter>";
|
||||
"G" = ":select -1<Enter>";
|
||||
|
||||
"J" = ":next-folder<Enter>";
|
||||
"K" = ":prev-folder<Enter>";
|
||||
"H" = ":collapse-folder<Enter>";
|
||||
"L" = ":expand-folder<Enter>";
|
||||
"J" = ":next-folder<Enter>";
|
||||
"K" = ":prev-folder<Enter>";
|
||||
"H" = ":collapse-folder<Enter>";
|
||||
"L" = ":expand-folder<Enter>";
|
||||
|
||||
"v" = ":mark -t<Enter>";
|
||||
"V" = ":mark -v<Enter>";
|
||||
"v" = ":mark -t<Enter>";
|
||||
"V" = ":mark -v<Enter>";
|
||||
|
||||
"T" = ":toggle-threads<Enter>";
|
||||
"T" = ":toggle-threads<Enter>";
|
||||
|
||||
"<Enter>" = ":view<Enter>";
|
||||
#"d" = ":prompt 'Really delete this message?' ':modify-labels +deleted'<Enter>"; # does not work
|
||||
"D" = ":modify-labels +deleted -inbox<Enter>";
|
||||
"A" = ":modify-labels -inbox<Enter>";
|
||||
"<Enter>" = ":view<Enter>";
|
||||
#"d" = ":prompt 'Really delete this message?' ':modify-labels +deleted'<Enter>"; # does not work
|
||||
"D" = ":modify-labels +deleted -inbox<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>";
|
||||
"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>";
|
||||
|
||||
"rr" = ":reply -a<Enter>";
|
||||
"rq" = ":reply -aq<Enter>";
|
||||
"Rr" = ":reply<Enter>";
|
||||
"Rq" = ":reply -q<Enter>";
|
||||
"rr" = ":reply -a<Enter>";
|
||||
"rq" = ":reply -aq<Enter>";
|
||||
"Rr" = ":reply<Enter>";
|
||||
"Rq" = ":reply -q<Enter>";
|
||||
|
||||
"c" = ":cf<space>";
|
||||
"$" = ":term<space>";
|
||||
"!" = ":term<space>";
|
||||
"|" = ":pipe<space>";
|
||||
"c" = ":cf<space>";
|
||||
"$" = ":term<space>";
|
||||
"!" = ":term<space>";
|
||||
"|" = ":pipe<space>";
|
||||
|
||||
"/" = ":search<space>";
|
||||
"\\" = ":filter<space>";
|
||||
"n" = ":next-result<Enter>";
|
||||
"N" = ":prev-result<Enter>";
|
||||
"<Esc>" = ":clear<Enter>";
|
||||
};
|
||||
"/" = ":search<space>";
|
||||
"\\" = ":filter<space>";
|
||||
"n" = ":next-result<Enter>";
|
||||
"N" = ":prev-result<Enter>";
|
||||
"<Esc>" = ":clear<Enter>";
|
||||
};
|
||||
|
||||
view = {
|
||||
"/" = ":toggle-key-passthrough<Enter>/";
|
||||
"q" = ":close<Enter>";
|
||||
"O" = ":open<Enter>";
|
||||
"S" = ":save<space>";
|
||||
"|" = ":pipe<space>";
|
||||
"D" = ":modify-labels +deleted -inbox<Enter>";
|
||||
"A" = ":modify-labels -inbox<Enter>";
|
||||
view = {
|
||||
"/" = ":toggle-key-passthrough<Enter>/";
|
||||
"q" = ":close<Enter>";
|
||||
"O" = ":open<Enter>";
|
||||
"S" = ":save<space>";
|
||||
"|" = ":pipe<space>";
|
||||
"D" = ":modify-labels +deleted -inbox<Enter>";
|
||||
"A" = ":modify-labels -inbox<Enter>";
|
||||
|
||||
"f" = ":forward<Enter>";
|
||||
"rr" = ":reply -a<Enter>";
|
||||
"rq" = ":reply -aq<Enter>";
|
||||
"Rr" = ":reply<Enter>";
|
||||
"Rq" = ":reply -q<Enter>";
|
||||
"f" = ":forward<Enter>";
|
||||
"rr" = ":reply -a<Enter>";
|
||||
"rq" = ":reply -aq<Enter>";
|
||||
"Rr" = ":reply<Enter>";
|
||||
"Rq" = ":reply -q<Enter>";
|
||||
|
||||
"H" = ":toggle-headers<Enter>";
|
||||
"<C-k>" = ":prev-part<Enter>";
|
||||
"<C-j>" = ":next-part<Enter>";
|
||||
"J" = ":next<Enter>";
|
||||
"K" = ":prev<Enter>";
|
||||
};
|
||||
"H" = ":toggle-headers<Enter>";
|
||||
"<C-k>" = ":prev-part<Enter>";
|
||||
"<C-j>" = ":next-part<Enter>";
|
||||
"J" = ":next<Enter>";
|
||||
"K" = ":prev<Enter>";
|
||||
};
|
||||
|
||||
"view::passthrough" = {
|
||||
"$noinherit" = "true";
|
||||
"$ex" = "<C-x>";
|
||||
"<Esc>" = ":toggle-key-passthrough<Enter>";
|
||||
};
|
||||
"view::passthrough" = {
|
||||
"$noinherit" = "true";
|
||||
"$ex" = "<C-x>";
|
||||
"<Esc>" = ":toggle-key-passthrough<Enter>";
|
||||
};
|
||||
|
||||
# Keybindings used when the embedded terminal is not selected in the compose view"
|
||||
compose = {
|
||||
"$ex" = "<C-x>";
|
||||
"<C-k>" = ":prev-field<Enter>";
|
||||
"<C-j>" = ":next-field<Enter>";
|
||||
"<tab>" = ":next-field<Enter>";
|
||||
"<backtab>" = ":prev-field<Enter>";
|
||||
};
|
||||
# Keybindings used when the embedded terminal is not selected in the compose view"
|
||||
compose = {
|
||||
"$ex" = "<C-x>";
|
||||
"<C-k>" = ":prev-field<Enter>";
|
||||
"<C-j>" = ":next-field<Enter>";
|
||||
"<tab>" = ":next-field<Enter>";
|
||||
"<backtab>" = ":prev-field<Enter>";
|
||||
};
|
||||
|
||||
# Keybindings used when the embedded terminal is selected in the compose view
|
||||
"compose::editor" = {
|
||||
"$noinherit" = "true";
|
||||
"$ex" = "<C-x>";
|
||||
"<C-k>" = ":prev-field<Enter>";
|
||||
"<C-j>" = ":next-field<Enter>";
|
||||
"<C-p>" = ":prev-tab<Enter>";
|
||||
"<C-n>" = ":next-tab<Enter>";
|
||||
};
|
||||
# Keybindings used when the embedded terminal is selected in the compose view
|
||||
"compose::editor" = {
|
||||
"$noinherit" = "true";
|
||||
"$ex" = "<C-x>";
|
||||
"<C-k>" = ":prev-field<Enter>";
|
||||
"<C-j>" = ":next-field<Enter>";
|
||||
"<C-p>" = ":prev-tab<Enter>";
|
||||
"<C-n>" = ":next-tab<Enter>";
|
||||
};
|
||||
|
||||
# Keybindings used when reviewing a message to be sent
|
||||
"compose::review" = {
|
||||
"y" = ":send<Enter>";
|
||||
"n" = ":abort<Enter>";
|
||||
"p" = ":postpone<Enter>";
|
||||
"q" = ":choose -o d discard abort -o p postpone postpone<Enter>";
|
||||
"e" = ":edit<Enter>";
|
||||
"a" = ":attach<space>";
|
||||
"d" = ":detach<space>";
|
||||
};
|
||||
# Keybindings used when reviewing a message to be sent
|
||||
"compose::review" = {
|
||||
"y" = ":send<Enter>";
|
||||
"n" = ":abort<Enter>";
|
||||
"p" = ":postpone<Enter>";
|
||||
"q" = ":choose -o d discard abort -o p postpone postpone<Enter>";
|
||||
"e" = ":edit<Enter>";
|
||||
"a" = ":attach<space>";
|
||||
"d" = ":detach<space>";
|
||||
};
|
||||
|
||||
terminal = {
|
||||
"$noinherit" = "true";
|
||||
"$ex" = "<C-x>";
|
||||
terminal = {
|
||||
"$noinherit" = "true";
|
||||
"$ex" = "<C-x>";
|
||||
|
||||
"<C-p>" = ":prev-tab<Enter>";
|
||||
"<C-n>" = ":next-tab<Enter>";
|
||||
};
|
||||
"<C-p>" = ":prev-tab<Enter>";
|
||||
"<C-n>" = ":next-tab<Enter>";
|
||||
};
|
||||
};
|
||||
|
||||
"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" ];
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue