1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
diff --git a/app/account.go b/app/account.go
index 817b9b74c56585aa557bd7fa514c900d4520c84e..b5bed86e27c03d4926cc3dbd95ad612ab8508e54 100644
--- a/app/account.go
+++ b/app/account.go
@@ -256,6 +256,15 @@ }, func() {
if uiConf.NewMessageBell {
aerc.Beep()
}
+ }, func() {
+ err := hooks.RunHook(&hooks.MailDeleted{
+ Account: acct.Name(),
+ Folder: name,
+ })
+ if err != nil {
+ msg := fmt.Sprintf("mail-deleted hook: %s", err)
+ PushError(msg)
+ }
},
acct.updateSplitView,
acct.dirlist.UiConfig(name).ThreadContext,
diff --git a/commands/msg/recall.go b/commands/msg/recall.go
index cea02ddb4df375afed225e3d768296252c5b09de..a676010a06f5739ee685075136ad759e6cc6c0be 100644
--- a/commands/msg/recall.go
+++ b/commands/msg/recall.go
@@ -61,20 +61,20 @@ subject = "Recalled email"
}
composer.Tab = app.NewTab(composer, subject)
composer.OnClose(func(composer *app.Composer) {
- worker := composer.Worker()
uids := []uint32{msgInfo.Uid}
deleteMessage := func() {
- worker.PostAction(&types.DeleteMessages{
- Uids: uids,
- }, func(msg types.WorkerMessage) {
- switch msg := msg.(type) {
- case *types.Done:
- app.PushStatus("Recalled message deleted", 10*time.Second)
- case *types.Error:
- app.PushError(msg.Error.Error())
- }
- })
+ store.Delete(
+ uids,
+ func(msg types.WorkerMessage) {
+ switch msg := msg.(type) {
+ case *types.Done:
+ app.PushStatus("Recalled message deleted", 10*time.Second)
+ case *types.Error:
+ app.PushError(msg.Error.Error())
+ }
+ },
+ )
}
if composer.Sent() || composer.Postponed() {
diff --git a/config/aerc.conf b/config/aerc.conf
index 1d5ffe8b617aebbdd96f322cd90e2a0c2a0deaaa..cf9aafa249ff79c1ba0777169eaa2514f06fc6ac 100644
--- a/config/aerc.conf
+++ b/config/aerc.conf
@@ -581,6 +581,10 @@ # Executed when a new email arrives in the selected folder
#mail-received=notify-send "[$AERC_ACCOUNT/$AERC_FOLDER] New mail from $AERC_FROM_NAME" "$AERC_SUBJECT"
#
+# Executed when mail is deleted from a folder
+#mail-deleted=mbsync "$AERC_ACCOUNT:$AERC_FOLDER" &
+
+#
# Executed when aerc starts
#aerc-startup=aerc :terminal calcurse && aerc :next-tab
diff --git a/config/hooks.go b/config/hooks.go
index bfdf4fe12f2840e1f460bb491a2def8090211e6c..7a6047c10ebb90f5cffb97b7404f7fd91dfe880c 100644
--- a/config/hooks.go
+++ b/config/hooks.go
@@ -11,6 +11,7 @@ type HooksConfig struct {
AercStartup string `ini:"aerc-startup"`
AercShutdown string `ini:"aerc-shutdown"`
MailReceived string `ini:"mail-received"`
+ MailDeleted string `ini:"mail-deleted"`
}
var Hooks HooksConfig
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index a45e244394e5e1704ec3100f5cb9179548b431a9..200c0609376bc0b81c04c0948db2782ec1ef2895 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -958,6 +958,19 @@ Example:
*mail-received* = _notify-send "[$AERC_ACCOUNT/$AERC_FOLDER] New mail from $AERC_FROM_NAME" "$AERC_SUBJECT"_
+*mail-deleted* = _<command>_
+ Executed when a message is deleted from a folder. Note that this hook is
+ triggered when moving a message from one folder to another.
+
+ Variables:
+
+ - *AERC_ACCOUNT*
+ - *AERC_FOLDER*
+
+ Example:
+
+ *mail-deleted* = _mbsync "$AERC_ACCOUNT:$AERC_FOLDER"_
+
*aerc-shutdown* = _<command>_
Executed when aerc shuts down. Aerc will wait for the command to finish
before exiting.
diff --git a/lib/hooks/mail-deleted.go b/lib/hooks/mail-deleted.go
new file mode 100644
index 0000000000000000000000000000000000000000..e9f1310537a2d7cf2dd53844c896bada5bcbf86c
--- /dev/null
+++ b/lib/hooks/mail-deleted.go
@@ -0,0 +1,23 @@
+package hooks
+
+import (
+ "fmt"
+
+ "git.sr.ht/~rjarry/aerc/config"
+)
+
+type MailDeleted struct {
+ Account string
+ Folder string
+}
+
+func (m *MailDeleted) Cmd() string {
+ return config.Hooks.MailDeleted
+}
+
+func (m *MailDeleted) Env() []string {
+ return []string{
+ fmt.Sprintf("AERC_ACCOUNT=%s", m.Account),
+ fmt.Sprintf("AERC_FOLDER=%s", m.Folder),
+ }
+}
diff --git a/lib/msgstore.go b/lib/msgstore.go
index e54c256572eee2c5b661ba6057c87bbab9043dc9..9c6b750dc419c7f20488b2c813f172fa2fc15781 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -68,6 +68,7 @@ fetchFlagsDelay time.Duration
triggerNewEmail func(*models.MessageInfo)
triggerDirectoryChange func()
+ triggerMailDeleted func()
threadBuilderDebounce *time.Timer
threadBuilderDelay time.Duration
@@ -87,8 +88,8 @@ defaultSortCriteria []*types.SortCriterion,
thread bool, clientThreads bool, clientThreadsDelay time.Duration,
reverseOrder bool, reverseThreadOrder bool, sortThreadSiblings bool,
triggerNewEmail func(*models.MessageInfo),
- triggerDirectoryChange func(), onSelect func(*models.MessageInfo),
- threadContext bool,
+ triggerDirectoryChange func(), triggerMailDeleted func(),
+ onSelect func(*models.MessageInfo), threadContext bool,
) *MessageStore {
if !worker.Backend.Capabilities().Thread {
clientThreads = true
@@ -122,6 +123,7 @@ fetchFlagsDelay: 50 * time.Millisecond,
triggerNewEmail: triggerNewEmail,
triggerDirectoryChange: triggerDirectoryChange,
+ triggerMailDeleted: triggerMailDeleted,
threadBuilderDelay: clientThreadsDelay,
@@ -580,6 +582,9 @@ }
if _, ok := msg.(*types.Unsupported); ok {
store.revertDeleted(uids)
}
+ if _, ok := msg.(*types.Done); ok {
+ store.triggerMailDeleted()
+ }
cb(msg)
})
}
@@ -629,6 +634,7 @@ case *types.Error:
store.revertDeleted(uids)
cb(msg)
case *types.Done:
+ store.triggerMailDeleted()
cb(msg)
}
})
|