]>
Commit | Line | Data |
---|---|---|
ebc5806e JR |
1 | # vim:ft=diff: |
2 | This is the trash folder patch by Cedric Duval <cedricduval@free.fr>. | |
3 | ||
4 | With this patch, if the trash variable is set to a path (unset by default), the | |
5 | deleted mails will be moved to a trash folder instead of being irremediably | |
6 | purged when syncing the mailbox. | |
7 | ||
8 | For instance, set trash="~/Mail/trash" will cause every deleted mail to go to | |
9 | this folder. | |
10 | ||
11 | Note that the append to the trash folder doesn't occur until the resync is | |
12 | done. This allows you to change your mind and undo deletes, and thus the moves | |
13 | to the trash folder are unnecessary. | |
14 | ||
15 | Notes | |
16 | ||
17 | * You might also want to have a look at the purge message feature below | |
18 | which is related to this patch. | |
19 | * IMAP is now supported. To retain the previous behavior, add this to your | |
20 | muttrc: | |
21 | folder-hook ^imap:// 'unset trash' | |
22 | ||
23 | FAQ | |
24 | ||
25 | Every once in a while, someone asks what are the advantages of this patch over | |
26 | a macro based solution. Here's an attempt to answer this question: | |
27 | ||
28 | * The folder history doesn't clutter up with unwanted trash entries. | |
29 | * Delayed move to the trash allows to change one's mind. | |
30 | * No need to treat the case of "normal folders" and trash folders | |
31 | separately with folder-hooks, and to create two sets of macros (one for | |
32 | the index, one for the pager). | |
33 | * Works not only with delete-message, but also with every deletion | |
34 | functions like delete-pattern, delete-thread or delete-subthread. | |
35 | ||
36 | To sum up, it's more integrated and transparent to the user. | |
37 | ||
38 | * Patch last synced with upstream: | |
39 | - Date: 2007-02-15 | |
40 | - File: http://cedricduval.free.fr/mutt/patches/download/patch-1.5.5.1.cd.trash_folder.3.4 | |
41 | ||
42 | * Changes made: | |
43 | - Updated to 1.5.13: | |
44 | - structure of _mutt_save_message changed (commands.c) | |
45 | - context of option (OPTCONFIRMAPPEND) changed (muttlib.c) | |
46 | - Fixed indentation of "appended" in mutt.h. | |
47 | ||
48 | == END PATCH | |
49 | --- a/commands.c | |
50 | +++ b/commands.c | |
51 | @@ -717,6 +717,7 @@ | |
68eeb855 | 52 | if (option (OPTDELETEUNTAG)) |
53 | mutt_set_flag (Context, h, M_TAG, 0); | |
3b22acf6 | 54 | } |
68eeb855 | 55 | + mutt_set_flag (Context, h, M_APPENDED, 1); |
56 | ||
57 | return 0; | |
3b22acf6 | 58 | } |
ebc5806e JR |
59 | --- a/flags.c |
60 | +++ b/flags.c | |
61 | @@ -65,7 +65,13 @@ | |
62 | { | |
63 | h->deleted = 0; | |
64 | update = 1; | |
65 | - if (upd_ctx) ctx->deleted--; | |
66 | + if (upd_ctx) | |
67 | + { | |
68 | + ctx->deleted--; | |
69 | + if (h->appended) | |
70 | + ctx->appended--; | |
71 | + } | |
72 | + h->appended = 0; /* when undeleting, also reset the appended flag */ | |
73 | #ifdef USE_IMAP | |
74 | /* see my comment above */ | |
75 | if (ctx->magic == M_IMAP) | |
76 | @@ -87,6 +93,17 @@ | |
68eeb855 | 77 | } |
3b22acf6 | 78 | break; |
79 | ||
80 | + case M_APPENDED: | |
81 | + if (bf) | |
82 | + { | |
83 | + if (!h->appended) | |
84 | + { | |
85 | + h->appended = 1; | |
86 | + if (upd_ctx) ctx->appended++; | |
87 | + } | |
88 | + } | |
89 | + break; | |
90 | + | |
91 | case M_NEW: | |
68eeb855 | 92 | |
ebc5806e JR |
93 | if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN)) |
94 | --- a/globals.h | |
95 | +++ b/globals.h | |
96 | @@ -139,6 +139,7 @@ | |
68eeb855 | 97 | WHERE char *Status; |
3b22acf6 | 98 | WHERE char *Tempdir; |
99 | WHERE char *Tochars; | |
100 | +WHERE char *TrashPath; | |
2c6e17e3 JP |
101 | WHERE char *TSStatusFormat; |
102 | WHERE char *TSIconFormat; | |
103 | WHERE short TSSupported; | |
ebc5806e JR |
104 | --- a/imap/message.c |
105 | +++ b/imap/message.c | |
106 | @@ -876,6 +876,7 @@ | |
107 | if (ctx->hdrs[n]->tagged) | |
108 | { | |
109 | mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1); | |
110 | + mutt_set_flag (ctx, ctx->hdrs[n], M_APPENDED, 1); | |
111 | if (option (OPTDELETEUNTAG)) | |
112 | mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0); | |
113 | } | |
114 | @@ -883,6 +884,7 @@ | |
115 | else | |
116 | { | |
117 | mutt_set_flag (ctx, h, M_DELETE, 1); | |
118 | + mutt_set_flag (ctx, h, M_APPENDED, 1); | |
119 | if (option (OPTDELETEUNTAG)) | |
120 | mutt_set_flag (ctx, h, M_TAG, 0); | |
121 | } | |
122 | --- a/init.h | |
123 | +++ b/init.h | |
124 | @@ -3195,6 +3195,16 @@ | |
68eeb855 | 125 | ** by \fIyou\fP. The sixth character is used to indicate when a mail |
ebc5806e | 126 | ** was sent to a mailing-list you subscribe to. |
3b22acf6 | 127 | */ |
128 | + { "trash", DT_PATH, R_NONE, UL &TrashPath, 0 }, | |
129 | + /* | |
130 | + ** .pp | |
131 | + ** If set, this variable specifies the path of the trash folder where the | |
132 | + ** mails marked for deletion will be moved, instead of being irremediably | |
133 | + ** purged. | |
ebc5806e JR |
134 | + ** .pp |
135 | + ** NOTE: When you delete a message in the trash folder, it is really | |
136 | + ** deleted, so that you have a way to clean the trash. | |
3b22acf6 | 137 | + */ |
138 | #ifdef USE_SOCKET | |
139 | { "tunnel", DT_STR, R_NONE, UL &Tunnel, UL 0 }, | |
68eeb855 | 140 | /* |
ebc5806e JR |
141 | --- a/mutt.h |
142 | +++ b/mutt.h | |
143 | @@ -187,6 +187,7 @@ | |
68eeb855 | 144 | M_DELETE, |
3b22acf6 | 145 | M_UNDELETE, |
146 | M_DELETED, | |
147 | + M_APPENDED, | |
148 | M_FLAG, | |
149 | M_TAG, | |
68eeb855 | 150 | M_UNTAG, |
ebc5806e JR |
151 | @@ -707,6 +708,7 @@ |
152 | unsigned int mime : 1; /* has a MIME-Version header? */ | |
3b22acf6 | 153 | unsigned int flagged : 1; /* marked important? */ |
154 | unsigned int tagged : 1; | |
ebc5806e | 155 | + unsigned int appended : 1; /* has been saved */ |
3b22acf6 | 156 | unsigned int deleted : 1; |
157 | unsigned int changed : 1; | |
68eeb855 | 158 | unsigned int attach_del : 1; /* has an attachment marked for deletion */ |
ebc5806e | 159 | @@ -879,6 +881,7 @@ |
68eeb855 | 160 | int new; /* how many new messages? */ |
3b22acf6 | 161 | int unread; /* how many unread messages? */ |
162 | int deleted; /* how many deleted messages */ | |
163 | + int appended; /* how many saved messages? */ | |
164 | int flagged; /* how many flagged messages */ | |
165 | int msgnotreadyet; /* which msg "new" in pager, -1 if none */ | |
ebc5806e JR |
166 | |
167 | --- a/muttlib.c | |
168 | +++ b/muttlib.c | |
169 | @@ -1515,7 +1515,9 @@ | |
170 | ||
171 | if (magic > 0 && !mx_access (s, W_OK)) | |
172 | { | |
173 | - if (option (OPTCONFIRMAPPEND)) | |
174 | + if (option (OPTCONFIRMAPPEND) && | |
175 | + (!TrashPath || (mutt_strcmp (s, TrashPath) != 0))) | |
176 | + /* if we're appending to the trash, there's no point in asking */ | |
177 | { | |
178 | snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s); | |
179 | if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO) | |
180 | --- a/mx.c | |
181 | +++ b/mx.c | |
182 | @@ -776,6 +776,53 @@ | |
68eeb855 | 183 | return rc; |
3b22acf6 | 184 | } |
185 | ||
186 | +/* move deleted mails to the trash folder */ | |
187 | +static int trash_append (CONTEXT *ctx) | |
188 | +{ | |
189 | + CONTEXT *ctx_trash; | |
ebc5806e | 190 | + int i = 0; |
3b22acf6 | 191 | + struct stat st, stc; |
192 | + | |
ebc5806e JR |
193 | + if (!TrashPath || !ctx->deleted || |
194 | + (ctx->magic == M_MAILDIR && option (OPTMAILDIRTRASH))) | |
3b22acf6 | 195 | + return 0; |
196 | + | |
ebc5806e JR |
197 | + for (;i < ctx->msgcount && (!ctx->hdrs[i]->deleted || |
198 | + ctx->hdrs[i]->appended); i++); | |
199 | + if (i == ctx->msgcount) | |
200 | + return 0; /* nothing to be done */ | |
201 | + | |
202 | + if (mutt_save_confirm (TrashPath, &st) != 0) | |
3b22acf6 | 203 | + { |
204 | + mutt_error _("message(s) not deleted"); | |
205 | + return -1; | |
206 | + } | |
207 | + | |
208 | + if (lstat (ctx->path, &stc) == 0 && stc.st_ino == st.st_ino | |
209 | + && stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev) | |
210 | + return 0; /* we are in the trash folder: simple sync */ | |
211 | + | |
212 | + if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL) | |
213 | + { | |
214 | + for (i = 0 ; i < ctx->msgcount ; i++) | |
215 | + if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->appended | |
216 | + && mutt_append_message (ctx_trash, ctx, ctx->hdrs[i], 0, 0) == -1) | |
217 | + { | |
218 | + mx_close_mailbox (ctx_trash, NULL); | |
219 | + return -1; | |
220 | + } | |
221 | + | |
222 | + mx_close_mailbox (ctx_trash, NULL); | |
223 | + } | |
224 | + else | |
225 | + { | |
226 | + mutt_error _("Can't open trash folder"); | |
227 | + return -1; | |
228 | + } | |
229 | + | |
230 | + return 0; | |
231 | +} | |
232 | + | |
233 | /* save changes and close mailbox */ | |
234 | int mx_close_mailbox (CONTEXT *ctx, int *index_hint) | |
68eeb855 | 235 | { |
ebc5806e JR |
236 | @@ -912,6 +959,7 @@ |
237 | if (mutt_append_message (&f, ctx, ctx->hdrs[i], 0, CH_UPDATE_LEN) == 0) | |
238 | { | |
239 | mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, 1); | |
240 | + mutt_set_flag (ctx, ctx->hdrs[i], M_APPENDED, 1); | |
241 | } | |
242 | else | |
243 | { | |
244 | @@ -936,6 +984,14 @@ | |
245 | return 0; | |
3b22acf6 | 246 | } |
ebc5806e JR |
247 | |
248 | + /* copy mails to the trash before expunging */ | |
249 | + if (purge && ctx->deleted && mutt_strcmp(ctx->path, TrashPath)) | |
250 | + if (trash_append (ctx) != 0) | |
251 | + { | |
252 | + ctx->closing = 0; | |
253 | + return -1; | |
254 | + } | |
255 | + | |
256 | #ifdef USE_IMAP | |
257 | /* allow IMAP to preserve the deleted flag across sessions */ | |
68eeb855 | 258 | if (ctx->magic == M_IMAP) |
ebc5806e JR |
259 | @@ -1133,6 +1189,12 @@ |
260 | msgcount = ctx->msgcount; | |
261 | deleted = ctx->deleted; | |
262 | ||
263 | + if (purge && ctx->deleted && mutt_strcmp(ctx->path, TrashPath)) | |
3b22acf6 | 264 | + { |
265 | + if (trash_append (ctx) == -1) | |
266 | + return -1; | |
3b22acf6 | 267 | + } |
ebc5806e | 268 | + |
68eeb855 | 269 | #ifdef USE_IMAP |
ebc5806e JR |
270 | if (ctx->magic == M_IMAP) |
271 | rc = imap_sync_mailbox (ctx, purge, index_hint); | |
272 | --- a/postpone.c | |
273 | +++ b/postpone.c | |
274 | @@ -277,6 +277,9 @@ | |
68eeb855 | 275 | /* finished with this message, so delete it. */ |
3b22acf6 | 276 | mutt_set_flag (PostContext, h, M_DELETE, 1); |
277 | ||
278 | + /* and consider it saved, so that it won't be moved to the trash folder */ | |
279 | + mutt_set_flag (PostContext, h, M_APPENDED, 1); | |
280 | + | |
281 | /* update the count for the status display */ | |
282 | PostCount = PostContext->msgcount - PostContext->deleted; | |
68eeb855 | 283 |