355 lines
17 KiB
Nix
355 lines
17 KiB
Nix
|
{ config, ... }: {
|
||
|
sops.secrets.moonythm_mail_pass.sopsFile = ./secrets.yaml;
|
||
|
|
||
|
programs.msmtp.enable = true;
|
||
|
programs.mbsync.enable = true;
|
||
|
services.mbsync.enable = true;
|
||
|
programs.notmuch = {
|
||
|
enable = true;
|
||
|
hooks = {
|
||
|
preNew = "mbsync --all";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
accounts.email.accounts = {
|
||
|
# {{{ Moonythm
|
||
|
moonythm = rec {
|
||
|
# {{{ Primary config
|
||
|
address = "colimit@moonythm.dev";
|
||
|
realName = "prescientmoon";
|
||
|
userName = address;
|
||
|
aliases = [ "hi@moonythm.dev" ];
|
||
|
|
||
|
folders = {
|
||
|
inbox = "Inbox";
|
||
|
sent = "Sent";
|
||
|
drafts = "Drafts";
|
||
|
trash = "Trash";
|
||
|
};
|
||
|
|
||
|
passwordCommand = "cat ${config.sops.secrets.moonythm_mail_pass.path}";
|
||
|
primary = true;
|
||
|
# }}}
|
||
|
# {{{ Imap / smtp configuration
|
||
|
imap = {
|
||
|
host = "imap.migadu.com";
|
||
|
port = 993;
|
||
|
};
|
||
|
|
||
|
smtp = {
|
||
|
host = "smtp.migadu.com";
|
||
|
port = 465;
|
||
|
};
|
||
|
# }}}
|
||
|
# {{{ Auxilliary services
|
||
|
msmtp = {
|
||
|
enable = true;
|
||
|
};
|
||
|
|
||
|
mbsync = {
|
||
|
enable = true;
|
||
|
create = "both"; # sync folders both ways
|
||
|
expunge = "maildir"; # Delete messages when the local dir says so
|
||
|
};
|
||
|
|
||
|
notmuch = {
|
||
|
enable = true;
|
||
|
neomutt.enable = true;
|
||
|
};
|
||
|
# }}}
|
||
|
# {{{ Email client
|
||
|
neomutt = {
|
||
|
enable = true;
|
||
|
sendMailCommand = "msmtpq --read-envelope-from --read-recipients";
|
||
|
extraMailboxes = [ "Archive" "Drafts" "Junk" "Sent" "Trash" ];
|
||
|
};
|
||
|
# }}}
|
||
|
# {{{ Aerc
|
||
|
aerc = {
|
||
|
enable = true;
|
||
|
};
|
||
|
# }}}
|
||
|
};
|
||
|
# }}}
|
||
|
};
|
||
|
|
||
|
# {{{ Aerc
|
||
|
programs.aerc = {
|
||
|
enable = true;
|
||
|
extraConfig.general.unsafe-accounts-conf = true;
|
||
|
};
|
||
|
# }}}
|
||
|
# {{{ Neomutt
|
||
|
programs.neomutt = {
|
||
|
# {{{ Primary config
|
||
|
enable = true;
|
||
|
vimKeys = true;
|
||
|
checkStatsInterval = 60; # How often to check for new mail
|
||
|
sidebar = {
|
||
|
enable = true;
|
||
|
width = 30;
|
||
|
};
|
||
|
# }}}
|
||
|
|
||
|
binds = [
|
||
|
# {{{ Toggle sidebar
|
||
|
{
|
||
|
map = [ "index" "pager" ];
|
||
|
key = "B";
|
||
|
action = "sidebar-toggle-visible";
|
||
|
}
|
||
|
# }}}
|
||
|
# {{{ Highlight previous sidebar item
|
||
|
{
|
||
|
map = [ "index" "pager" ];
|
||
|
key = "\\CK";
|
||
|
action = "sidebar-prev";
|
||
|
}
|
||
|
# }}}
|
||
|
# {{{ Highlight next sidebar item
|
||
|
{
|
||
|
map = [ "index" "pager" ];
|
||
|
key = "\\CJ";
|
||
|
action = "sidebar-next";
|
||
|
}
|
||
|
# }}}
|
||
|
# {{{ Open highlighted sidebar item
|
||
|
{
|
||
|
map = [ "index" "pager" ];
|
||
|
key = "\\CO";
|
||
|
action = "sidebar-open";
|
||
|
}
|
||
|
# }}}
|
||
|
];
|
||
|
|
||
|
macros = [
|
||
|
# {{{ Sync emails
|
||
|
{
|
||
|
map = [ "index" ];
|
||
|
key = "S";
|
||
|
action = "<shell-escape>mbsync -a<enter><shell-escape>notmuch new<enter>";
|
||
|
}
|
||
|
# }}}
|
||
|
# # {{{ show only messages matching a notmuch pattern
|
||
|
# {
|
||
|
# map = [ "index" ];
|
||
|
# key = "\\Cf";
|
||
|
# action = ''"<enter-command>unset wait_key<enter><shell-escape>read -p 'Enter a search term to find with notmuch: ' x;''
|
||
|
# + ''echo \\$x >~/.cache/mutt_terms<enter><limit>~i \\"\\`notmuch search - -output=messages \\$(cat ~/.cache/mutt_terms) ''
|
||
|
# + ''| head -n 600 | perl -le '@a=<>;s/\^ id:// for@a;$, = \\"|\\";print@a' | perl -le '@a=<>; chomp@a; s/\\\\+/\\\\\\\\+/ for@a;print@a' \`\\"<enter>"'';
|
||
|
# }
|
||
|
# # }}}
|
||
|
];
|
||
|
|
||
|
extraConfig = ''
|
||
|
# Starting point: https://seniormars.com/posts/neomutt/#introduction-and-why
|
||
|
# {{{ Settings
|
||
|
set pager_index_lines = 10
|
||
|
set pager_context = 3 # show 3 lines of context
|
||
|
set pager_stop # stop at end of message
|
||
|
set menu_scroll # scroll menu
|
||
|
set tilde # use ~ to pad mutt
|
||
|
set move=no # don't move messages when marking as read
|
||
|
set sleep_time = 0 # don't sleep when idle
|
||
|
set wait_key = no # mutt won't ask "press key to continue"
|
||
|
set envelope_from # which from?
|
||
|
# set edit_headers # show headers when composing
|
||
|
set fast_reply # skip to compose when replying
|
||
|
set askcc # ask for CC:
|
||
|
set fcc_attach # save attachments with the body
|
||
|
set forward_format = "Fwd: %s" # format of subject when forwarding
|
||
|
set forward_decode # decode when forwarding
|
||
|
set forward_quote # include message in forwards
|
||
|
set mime_forward # forward attachments as part of body
|
||
|
set attribution = "On %d, %n wrote:" # format of quoting header
|
||
|
set reply_to # reply to Reply to: field
|
||
|
set reverse_name # reply as whomever it was to
|
||
|
set include # include message in replies
|
||
|
set text_flowed=yes # correct indentation for plain text
|
||
|
unset sig_dashes # no dashes before sig
|
||
|
unset markers
|
||
|
# }}}
|
||
|
# {{{ Sort by newest conversation first.
|
||
|
set charset = "utf-8"
|
||
|
set uncollapse_jump
|
||
|
set sort_re
|
||
|
set sort = reverse-threads
|
||
|
set sort_aux = last-date-received
|
||
|
# }}}
|
||
|
# {{{ How we reply and quote emails.
|
||
|
set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"
|
||
|
set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
|
||
|
set send_charset = "utf-8:iso-8859-1:us-ascii" # send in utf-8
|
||
|
# }}}
|
||
|
# {{{ Sidebar
|
||
|
set sidebar_visible # comment to disable sidebar by default
|
||
|
set sidebar_short_path
|
||
|
set sidebar_folder_indent
|
||
|
set sidebar_format = "%B %* [%?N?%N / ?%S]"
|
||
|
set mail_check_stats
|
||
|
# }}}
|
||
|
# {{{ Theme
|
||
|
# From: https://github.com/altercation/mutt-colors-solarized/blob/master/mutt-colors-solarized-dark-16.muttrc
|
||
|
# basic colors ---------------------------------------------------------
|
||
|
color normal brightyellow default
|
||
|
color error red default
|
||
|
color tilde black default
|
||
|
color message cyan default
|
||
|
color markers red white
|
||
|
color attachment white default
|
||
|
color search brightmagenta default
|
||
|
color status brightyellow black
|
||
|
color indicator brightblack yellow
|
||
|
color tree cyan default # arrow in threads
|
||
|
|
||
|
# basic monocolor screen
|
||
|
mono bold bold
|
||
|
mono underline underline
|
||
|
mono indicator reverse
|
||
|
mono error bold
|
||
|
|
||
|
# index ----------------------------------------------------------------
|
||
|
|
||
|
color index red default "~A" # all messages
|
||
|
color index blue default "~N" # new messages
|
||
|
color index brightred default "~E" # expired messages
|
||
|
color index blue default "~N" # new messages
|
||
|
color index blue default "~O" # old messages
|
||
|
color index brightmagenta default "~Q" # messages that have been replied to
|
||
|
color index brightgreen default "~R" # read messages
|
||
|
color index blue default "~U" # unread messages
|
||
|
color index blue default "~U~$" # unread, unreferenced messages
|
||
|
color index cyan default "~v" # messages part of a collapsed thread
|
||
|
color index magenta default "~P" # messages from me
|
||
|
color index cyan default "~p!~F" # messages to me
|
||
|
color index cyan default "~N~p!~F" # new messages to me
|
||
|
color index cyan default "~U~p!~F" # unread messages to me
|
||
|
color index brightgreen default "~R~p!~F" # messages to me
|
||
|
color index red default "~F" # flagged messages
|
||
|
color index red default "~F~p" # flagged messages to me
|
||
|
color index red default "~N~F" # new flagged messages
|
||
|
color index red default "~N~F~p" # new flagged messages to me
|
||
|
color index red default "~U~F~p" # new flagged messages to me
|
||
|
color index brightcyan default "~v~(!~N)" # collapsed thread with no unread
|
||
|
color index yellow default "~v~(~N)" # collapsed thread with some unread
|
||
|
color index green default "~N~v~(~N)" # collapsed thread with unread parent
|
||
|
color index red black "~v~(~F)!~N" # collapsed thread with flagged, no unread
|
||
|
color index yellow black "~v~(~F~N)" # collapsed thread with some unread & flagged
|
||
|
color index green black "~N~v~(~F~N)" # collapsed thread with unread parent & flagged
|
||
|
color index green black "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged
|
||
|
color index cyan black "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly
|
||
|
color index yellow red "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial)
|
||
|
color index yellow default "~(~N)" # messages in threads with some unread
|
||
|
color index green default "~S" # superseded messages
|
||
|
color index black red "~D" # deleted messages
|
||
|
color index black red "~N~D" # deleted messages
|
||
|
color index red default "~T" # tagged messages
|
||
|
|
||
|
# message headers ------------------------------------------------------
|
||
|
|
||
|
color hdrdefault brightgreen default
|
||
|
color header brightyellow default "^(From)"
|
||
|
color header blue default "^(Subject)"
|
||
|
|
||
|
# body -----------------------------------------------------------------
|
||
|
|
||
|
color quoted blue default
|
||
|
color quoted1 cyan default
|
||
|
color quoted2 yellow default
|
||
|
color quoted3 red default
|
||
|
color quoted4 brightred default
|
||
|
|
||
|
color signature brightgreen default
|
||
|
color bold black default
|
||
|
color underline black default
|
||
|
color normal default default
|
||
|
color body brightcyan default "[;:][-o][)/(|]" # emoticons
|
||
|
color body brightcyan default "[;:][)(|]" # emoticons
|
||
|
color body brightcyan default "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
|
||
|
|FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
|
||
|
|IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
|
||
|
color body brightcyan default "[ ][*][^*]*[*][ ]?" # more emoticon?
|
||
|
color body brightcyan default "[ ]?[*][^*]*[*][ ]" # more emoticon?
|
||
|
|
||
|
## pgp
|
||
|
|
||
|
color body red default "(BAD signature)"
|
||
|
color body cyan default "(Good signature)"
|
||
|
color body brightblack default "^gpg: Good signature .*"
|
||
|
color body brightyellow default "^gpg: "
|
||
|
color body brightyellow red "^gpg: BAD signature from.*"
|
||
|
mono body bold "^gpg: Good signature"
|
||
|
mono body bold "^gpg: BAD signature from.*"
|
||
|
|
||
|
# yes, an insance URL regex
|
||
|
color body red default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
|
||
|
# and a heavy handed email regex
|
||
|
color body magenta default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
|
||
|
|
||
|
# Various smilies and the like
|
||
|
color body brightwhite default "<[Gg]>" # <g>
|
||
|
color body brightwhite default "<[Bb][Gg]>" # <bg>
|
||
|
color body yellow default " [;:]-*[})>{(<|]" # :-) etc...
|
||
|
# *bold*
|
||
|
color body blue default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
|
||
|
mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
|
||
|
# _underline_
|
||
|
color body blue default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
|
||
|
mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
|
||
|
# /italic/ (Sometimes gets directory names)
|
||
|
color body blue default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
|
||
|
mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
|
||
|
|
||
|
# Border lines.
|
||
|
color body blue default "( *[-+=#*~_]){6,}"
|
||
|
|
||
|
# From https://github.com/jessfraz/dockerfiles/blob/master/mutt/.mutt/mutt-patch-highlighting.muttrc
|
||
|
color body cyan default ^(Signed-off-by).*
|
||
|
color body cyan default ^(Docker-DCO-1.1-Signed-off-by).*
|
||
|
color body brightwhite default ^(Cc)
|
||
|
color body yellow default "^diff \-.*"
|
||
|
color body brightwhite default "^index [a-f0-9].*"
|
||
|
color body brightblue default "^---$"
|
||
|
color body white default "^\-\-\- .*"
|
||
|
color body white default "^[\+]{3} .*"
|
||
|
color body green default "^[\+][^\+]+.*"
|
||
|
color body red default "^\-[^\-]+.*"
|
||
|
color body brightblue default "^@@ .*"
|
||
|
color body green default "LGTM"
|
||
|
color body brightmagenta default "-- Commit Summary --"
|
||
|
color body brightmagenta default "-- File Changes --"
|
||
|
color body brightmagenta default "-- Patch Links --"
|
||
|
# }}}
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
# {{{ Neomutt desktop entry
|
||
|
# Taken from here: https://github.com/Misterio77/nix-config/blob/main/home/misterio/features/productivity/neomutt.nix
|
||
|
xdg = {
|
||
|
desktopEntries = {
|
||
|
neomutt = {
|
||
|
name = "Neomutt";
|
||
|
genericName = "Email Client";
|
||
|
comment = "Read and send emails";
|
||
|
exec = "neomutt %U";
|
||
|
icon = "mutt";
|
||
|
terminal = true;
|
||
|
categories = [ "Network" "Email" "ConsoleOnly" ];
|
||
|
type = "Application";
|
||
|
mimeType = [ "x-scheme-handler/mailto" ];
|
||
|
};
|
||
|
};
|
||
|
mimeApps.defaultApplications = {
|
||
|
"x-scheme-handler/mailto" = "neomutt.desktop";
|
||
|
};
|
||
|
};
|
||
|
# }}}
|
||
|
# }}}
|
||
|
# {{{ Storage & persistence
|
||
|
accounts.email.maildirBasePath = "${config.home.homeDirectory}/maildir";
|
||
|
satellite.persistence.at.data.apps.mail.directories = [
|
||
|
config.accounts.email.maildirBasePath
|
||
|
];
|
||
|
# }}}
|
||
|
}
|