This repository has no description
9.3 kB
232 lines
1{ self, ... }:
2{
3 perSystem =
4 {
5 pkgs,
6 lib,
7 system,
8 ...
9 }:
10 {
11 packages.mutt =
12 let
13 # Mailboxes configuration from mail.nix
14 mailboxes = self.packages.${system}.notmuch.mailboxes;
15 notmuchConfig = self.packages.${system}.notmuch.passthru.config.configFile.path;
16
17 mailcap = pkgs.writeText "mailcap" ''
18 text/html; ${pkgs.elinks}/bin/elinks -dump ; copiousoutput;
19 '';
20
21 msmtprc = pkgs.writeText "msmtprc" ''
22 defaults
23 logfile ~/.msmtp.log
24 account prism
25 host neoprism.r
26 account c-base
27 from lassulus@c-base.org
28 host c-mail.c-base.org
29 port 465
30 tls on
31 tls_starttls off
32 auth on
33 user lassulus
34 passwordeval pass show c-base/pass
35 account default: prism
36 '';
37
38 msmtp = pkgs.writeShellScriptBin "msmtp" ''
39 export NOTMUCH_CONFIG="${notmuchConfig}"
40
41 # Check if using c-base account (either explicit -a c-base or via From: header)
42 using_cbase=0
43 for arg in "$@"; do
44 if [[ "$arg" == "c-base" ]] || [[ "$arg" =~ @c-base\.org ]]; then
45 using_cbase=1
46 break
47 fi
48 done
49
50 # For c-base account, always send directly
51 if [ "$using_cbase" -eq 1 ]; then
52 ${pkgs.coreutils}/bin/tee >(${pkgs.notmuch}/bin/notmuch insert +sent) | \
53 ${pkgs.msmtp}/bin/msmtp -C ${msmtprc} "$@"
54 # For default account, try neoprism.r first, then SSH
55 elif ping -W2 -c1 neoprism.r >/dev/null 2>&1; then
56 ${pkgs.coreutils}/bin/tee >(${pkgs.notmuch}/bin/notmuch insert +sent) | \
57 ${pkgs.msmtp}/bin/msmtp -C ${msmtprc} "$@"
58 else
59 # Fall back to SSH tunnel to neoprism, submit via SMTP to local daemon
60 echo "neoprism.r not reachable, sending via SSH..." >&2
61 ${pkgs.coreutils}/bin/tee >(${pkgs.notmuch}/bin/notmuch insert +sent) | \
62 ${pkgs.openssh}/bin/ssh -p 45621 neoprism.lassul.us 'msmtp -C /dev/null --host=localhost --port=25 --read-envelope-from --read-recipients'
63 fi
64 '';
65
66 muttrc = pkgs.writeText "muttrc" ''
67 # read html mails
68 auto_view text/html
69 set mailcap_path = ${mailcap}
70
71 # notmuch
72 set folder="$HOME/Maildir"
73 set nm_default_uri = "notmuch://$HOME/Maildir"
74 set nm_record = yes
75 set nm_record_tags = "-inbox me archive"
76 set spoolfile = +Inbox
77 set virtual_spoolfile = yes
78
79 set sendmail="${msmtp}/bin/msmtp"
80 set from="lassulus@lassul.us"
81 alternates ^.*@lassul\.us$ ^.*@.*\.r$
82 unset envelope_from_address
83 set use_envelope_from
84 set reverse_name
85 set markers=no
86
87 set sort=threads
88
89 set index_format="%4C %Z %?GI?%GI& ? %[%y-%m-%d] %-20.20a %?M?(%3M)& ? %s %> %r %g"
90
91 virtual-mailboxes "Unread" "notmuch://?query=tag:unread"
92 virtual-mailboxes "INBOX" "notmuch://?query=tag:inbox"
93 ${lib.concatMapStringsSep "\n" (
94 i: ''${" "}virtual-mailboxes "${i.name}" "notmuch://?query=tag:${i.name}"''
95 ) (lib.mapAttrsToList lib.nameValuePair mailboxes)}
96 virtual-mailboxes "TODO" "notmuch://?query=tag:TODO"
97 virtual-mailboxes "Starred" "notmuch://?query=tag:*"
98 virtual-mailboxes "Archive" "notmuch://?query=tag:archive"
99 virtual-mailboxes "Sent" "notmuch://?query=tag:sent"
100 virtual-mailboxes "Junk" "notmuch://?query=tag:junk"
101 virtual-mailboxes "All" "notmuch://?query=*"
102
103 # clan.lol IMAP - no mailboxes declaration to prevent any startup connection
104 # Select the separator entry in sidebar, folder-hook will redirect to the IMAP server
105 virtual-mailboxes "clan-infra" "notmuch://?query=tag:nonexistent-separator-tag"
106 account-hook imaps://mail.clan.lol "set imap_user = 'infra@clan.lol'; set imap_pass = \"\`SOPS_AGE_KEY=\$(rbw get --folder clan.lol clan-infra --field age-key) nix develop git+https://git.clan.lol/clan/clan-infra -c clan vars get --flake git+https://git.clan.lol/clan/clan-infra web01 infra-mail/infra-password\`\""
107 folder-hook "notmuch://\\?query=tag:nonexistent-separator-tag" "push '<change-folder>imaps://mail.clan.lol<enter>'"
108
109 tag-transforms "junk" "k" \
110 "unread" "u" \
111 "replied" "↻" \
112 "TODO" "T" \
113
114 # notmuch bindings
115 macro index \\\\ "<vfolder-from-query>"
116 macro index + "<modify-labels>+*\n<sync-mailbox>"
117 macro index - "<modify-labels>-*\n<sync-mailbox>"
118
119 # muchsync
120 bind index \Cr noop
121 macro index \Cr \
122 "<enter-command>unset wait_key<enter> \
123 <sync-mailbox> \
124 <shell-escape>${self.packages.${pkgs.system}.muchsync}/bin/muchsync -vv<enter> \
125 <sync-mailbox>
126
127 #killed
128 bind index d noop
129 bind pager d noop
130
131 bind index S noop
132 bind index s noop
133 bind pager S noop
134 bind pager s noop
135 macro index S "<modify-labels-then-hide>-inbox -unread +junk\n"
136 macro index s "<modify-labels>-junk\n"
137 macro pager S "<modify-labels-then-hide>-inbox -unread +junk\n"
138 macro pager s "<modify-labels>-junk\n"
139
140 bind index A noop
141 bind index a noop
142 bind pager A noop
143 bind pager a noop
144 macro index A "<modify-labels>+archive -unread -inbox\n"
145 macro index a "<modify-labels>-archive\n"
146 macro pager A "<modify-labels>+archive -unread -inbox\n"
147 macro pager a "<modify-labels>-archive\n"
148
149 bind index U noop
150 bind index u noop
151 bind pager U noop
152 bind pager u noop
153 macro index U "<modify-labels>+unread\n"
154 macro index u "<modify-labels>-unread\n"
155 macro pager U "<modify-labels>+unread\n"
156 macro pager u "<modify-labels>-unread\n"
157
158 bind index t noop
159 bind pager t noop
160 macro index t "<modify-labels>"
161
162 # top index bar in email view
163 set pager_index_lines=7
164 # top_index_bar toggle
165 macro pager ,@1 "<enter-command> set pager_index_lines=0; macro pager ] ,@2 'Toggle indexbar<Enter>"
166 macro pager ,@2 "<enter-command> set pager_index_lines=3; macro pager ] ,@3 'Toggle indexbar<Enter>"
167 macro pager ,@3 "<enter-command> set pager_index_lines=7; macro pager ] ,@1 'Toggle indexbar<Enter>"
168 macro pager ] ,@1 'Toggle indexbar
169
170 # scan urls from emails
171 macro index,pager \cb "<pipe-message> ${lib.getExe pkgs.urlscan}<Enter>"
172 macro attach,compose \cb "<pipe-entry> ${lib.getExe pkgs.urlscan}<Enter>"
173
174 # sidebar
175 set sidebar_divider_char = '│'
176 set sidebar_delim_chars = "/"
177 set sidebar_short_path
178 set sidebar_folder_indent
179 set sidebar_visible = yes
180 set sidebar_format = '%D%?F? [%F]?%* %?N?%N/? %?S?%S?'
181 set sidebar_width = 20
182 color sidebar_new yellow red
183
184 # sidebar bindings
185 bind index <left> sidebar-prev
186 bind index <right> sidebar-next
187 bind index <space> sidebar-open
188 # sidebar toggle
189 macro index,pager ,@) "<enter-command> set sidebar_visible=no; macro index,pager [ ,@( 'Toggle sidebar'<Enter>"
190 macro index,pager ,@( "<enter-command> set sidebar_visible=yes; macro index,pager [ ,@) 'Toggle sidebar'<Enter>"
191 macro index,pager [ ,@( 'Toggle sidebar'
192
193 # forward with attachment
194 set mime_forward = no
195 set forward_attachments = yes
196
197 # better handling of long URLs
198 set wrap = 0 # don't wrap lines in the pager
199 set markers = no # don't show + markers for wrapped lines
200 set smart_wrap = yes # wrap at word boundaries when displaying
201 set pager_stop = yes # don't jump to next message at end of pager
202 '';
203
204 in
205 (self.wrapLib.makeWrapper {
206 pkgs = pkgs;
207 package = pkgs.neomutt;
208 aliases = [ "mutt" ];
209 runtimeInputs = [
210 pkgs.elinks
211 pkgs.msmtp
212 pkgs.notmuch
213 pkgs.openssh
214 pkgs.urlscan
215 ]
216 ++ lib.optionals pkgs.stdenv.isLinux [
217 pkgs.iputils
218 ];
219 env = {
220 NOTMUCH_CONFIG = notmuchConfig;
221 };
222 flags = {
223 "-F" = "${muttrc}";
224 };
225 }).overrideAttrs
226 (old: {
227 passthru = (old.passthru or { }) // {
228 inherit msmtp;
229 };
230 });
231 };
232}