mutt: fetch {sidebar,trash}.patch from AUR

This commit is contained in:
Joachim Fasting 2016-07-16 13:58:27 +02:00
parent 3bfe30a042
commit a317a15b30
No known key found for this signature in database
GPG Key ID: 4330820E1E04DCF4
3 changed files with 11 additions and 5250 deletions

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, ncurses, which, perl, autoreconfHook
{ stdenv, fetchurl, fetchpatch, ncurses, which, perl, autoreconfHook
, gdbm ? null
, openssl ? null
, cyrus_sasl ? null
@ -61,8 +61,16 @@ stdenv.mkDerivation rec {
++ optional saslSupport "--with-sasl";
patches =
optional withTrash ./trash.patch ++
optional withSidebar ./sidebar.patch;
optional withTrash (fetchpatch {
name = "trash.patch";
url = "https://aur.archlinux.org/cgit/aur.git/plain/trash.patch?h=mutt-sidebar";
sha256 = "1hrib9jk28mqd02nzv0sx01jfdabzvnwcc5qjc3810zfglzc1nql";
}) ++
optional withSidebar (fetchpatch {
name = "sidebar.patch";
url = "https://aur.archlinux.org/cgit/aur.git/plain/sidebar.patch?h=mutt-sidebar";
sha256 = "1l63wj7kw41jrh00mcxdw4p4vrbc9wld42s99liw8kz2aclymq5m";
});
meta = {
description = "A small but very powerful text-based mail client";

File diff suppressed because it is too large Load Diff

View File

@ -1,797 +0,0 @@
diff -urN mutt-1.6.1/commands.c mutt-1.6.1-trash/commands.c
--- mutt-1.6.1/commands.c 2016-06-12 18:43:00.397447512 +0100
+++ mutt-1.6.1-trash/commands.c 2016-06-12 18:43:04.892517610 +0100
@@ -720,6 +720,7 @@
if (option (OPTDELETEUNTAG))
mutt_set_flag (Context, h, M_TAG, 0);
}
+ mutt_set_flag (Context, h, M_APPENDED, 1);
return 0;
}
diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-trash/curs_main.c
--- mutt-1.6.1/curs_main.c 2016-06-12 18:43:00.399447544 +0100
+++ mutt-1.6.1-trash/curs_main.c 2016-06-12 18:43:04.895517656 +0100
@@ -1919,6 +1919,7 @@
MAYBE_REDRAW (menu->redraw);
break;
+ case OP_PURGE_MESSAGE:
case OP_DELETE:
CHECK_MSGCOUNT;
@@ -1930,6 +1931,7 @@
if (tag)
{
mutt_tag_set_flag (M_DELETE, 1);
+ mutt_tag_set_flag (M_PURGED, (op != OP_PURGE_MESSAGE) ? 0 : 1);
if (option (OPTDELETEUNTAG))
mutt_tag_set_flag (M_TAG, 0);
menu->redraw = REDRAW_INDEX;
@@ -1937,6 +1939,8 @@
else
{
mutt_set_flag (Context, CURHDR, M_DELETE, 1);
+ mutt_set_flag (Context, CURHDR, M_PURGED,
+ (op != OP_PURGE_MESSAGE) ? 0 : 1);
if (option (OPTDELETEUNTAG))
mutt_set_flag (Context, CURHDR, M_TAG, 0);
if (option (OPTRESOLVE))
@@ -2242,11 +2246,13 @@
if (tag)
{
mutt_tag_set_flag (M_DELETE, 0);
+ mutt_tag_set_flag (M_PURGED, 0);
menu->redraw = REDRAW_INDEX;
}
else
{
mutt_set_flag (Context, CURHDR, M_DELETE, 0);
+ mutt_set_flag (Context, CURHDR, M_PURGED, 0);
if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
{
menu->current++;
@@ -2268,9 +2274,11 @@
CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
- op == OP_UNDELETE_THREAD ? 0 : 1);
+ op == OP_UNDELETE_THREAD ? 0 : 1)
+ + mutt_thread_set_flag (CURHDR, M_PURGED, 0,
+ (op == OP_UNDELETE_THREAD) ? 0 : 1);
- if (rc != -1)
+ if (rc > -1)
{
if (option (OPTRESOLVE))
{
diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-trash/doc/manual.xml.head
--- mutt-1.6.1/doc/manual.xml.head 2016-06-12 18:43:00.402447590 +0100
+++ mutt-1.6.1-trash/doc/manual.xml.head 2016-06-12 18:43:04.901517750 +0100
@@ -7467,6 +7467,16 @@
</sect2>
+<sect2 id="mutt-patches">
+<title>Mutt Patches</title>
+<para>
+Mutt may also be <quote>patched</quote> to support smaller features.
+These patches should add a free-form string to the end Mutt's version string.
+Running <literal>mutt -v</literal> might show:
+<screen>patch-1.6.1.sidebar.20160502</screen>
+</para>
+</sect2>
+
<sect2 id="url-syntax">
<title>URL Syntax</title>
@@ -8081,6 +8091,175 @@
</sect1>
+<sect1 id="trash-folder">
+ <title>Trash Folder Patch</title>
+ <subtitle>Automatically move "deleted" emails to a trash bin</subtitle>
+
+ <sect2 id="trash-folder-patch">
+ <title>Patch</title>
+
+ <para>
+ To check if Mutt supports <quote>Trash Folder</quote>, look for
+ <quote>patch-trash</quote> in the mutt version.
+ See: <xref linkend="mutt-patches"/>.
+ </para>
+
+ If IMAP is enabled, this patch will use it
+
+ <itemizedlist>
+ <title>Dependencies:</title>
+ <listitem><para>mutt-1.6.1</para></listitem>
+ <listitem><para>IMAP support</para></listitem>
+ </itemizedlist>
+
+ <para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ </sect2>
+
+ <sect2 id="trash-folder-intro">
+ <title>Introduction</title>
+
+ <para>
+ In Mutt, when you <quote>delete</quote> an email it is first marked
+ deleted. The email isn't really gone until
+ <link linkend="index-map">&lt;sync-mailbox&gt;</link> is called.
+ This happens when the user leaves the folder, or the function is called
+ manually.
+ </para>
+
+ <para>
+ After <literal>&lt;sync-mailbox&gt;</literal> has been called the email is gone forever.
+ </para>
+
+ <para>
+ The <link linkend="trash">$trash</link> variable defines a folder in
+ which to keep old emails. As before, first you mark emails for
+ deletion. When &lt;sync-mailbox&gt; is called the emails are moved to
+ the trash folder.
+ </para>
+
+ <para>
+ The <literal>$trash</literal> path can be either a full directory,
+ or be relative to the <link linkend="folder">$folder</link>
+ variable, like the <literal>mailboxes</literal> command.
+ </para>
+
+ <note>
+ Emails deleted from the trash folder are gone forever.
+ </note>
+ </sect2>
+
+ <sect2 id="trash-folder-variables">
+ <title>Variables</title>
+ <table id="table-trash-variables">
+ <title>Trash Variables</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Default</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>trash</entry>
+ <entry>string</entry>
+ <entry>(none)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="trash-folder-functions">
+ <title>Functions</title>
+ <table id="table-trash-functions">
+ <title>Trash Functions</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Menus</entry>
+ <entry>Default Key</entry>
+ <entry>Function</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>index,pager</entry>
+ <entry>(none)</entry>
+ <entry><literal>&lt;purge-message&gt;</literal></entry>
+ <entry>really delete the current entry, bypassing the trash folder</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+<!--
+ <sect2 id="trash-folder-commands">
+ <title>Commands</title>
+ <para>None</para>
+ </sect2>
+
+ <sect2 id="trash-folder-colors">
+ <title>Colors</title>
+ <para>None</para>
+ </sect2>
+
+ <sect2 id="trash-folder-sort">
+ <title>Sort</title>
+ <para>None</para>
+ </sect2>
+-->
+
+ <sect2 id="trash-folder-muttrc">
+ <title>Muttrc</title>
+<screen>
+<emphasis role="comment"># Example Mutt config file for the 'trash' feature.
+
+# This feature defines a new 'trash' folder.
+# When mail is deleted it will be moved to this folder.
+
+# Folder in which to put deleted emails</emphasis>
+set trash='+Trash'
+set trash='/home/flatcap/Mail/Trash'
+
+<emphasis role="comment"># The default delete key 'd' will move an email to the 'trash' folder
+# Bind 'D' to REALLY delete an email</emphasis>
+bind index D purge-message
+
+<emphasis role="comment"># Note: Deleting emails from the 'trash' folder will REALLY delete them.
+
+# vim: syntax=muttrc</emphasis>
+</screen>
+ </sect2>
+
+ <sect2 id="trash-folder-see-also">
+ <title>See Also</title>
+
+ <itemizedlist>
+ <listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ <listitem><para><link linkend="folder-hook">folder-hook</link></para></listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="trash-folder-known-bugs">
+ <title>Known Bugs</title>
+ <para>None</para>
+ </sect2>
+
+ <sect2 id="trash-folder-credits">
+ <title>Credits</title>
+ <itemizedlist>
+ <listitem><para>Cedric Duval <email>cedricduval@free.fr</email></para></listitem>
+ <listitem><para>Benjamin Kuperman <email>kuperman@acm.org</email></para></listitem>
+ <listitem><para>Paul Miller <email>paul@voltar.org</email></para></listitem>
+ <listitem><para>Richard Russon <email>rich@flatcap.org</email></para></listitem>
+ </itemizedlist>
+ </sect2>
+</sect1>
+
</chapter>
<chapter id="security">
diff -urN mutt-1.6.1/doc/muttrc.trash mutt-1.6.1-trash/doc/muttrc.trash
--- mutt-1.6.1/doc/muttrc.trash 1970-01-01 01:00:00.000000000 +0100
+++ mutt-1.6.1-trash/doc/muttrc.trash 2016-06-12 18:43:04.768515676 +0100
@@ -0,0 +1,16 @@
+# Example Mutt config file for the 'trash' feature.
+
+# This feature defines a new 'trash' folder.
+# When mail is deleted it will be moved to this folder.
+
+# Folder in which to put deleted emails
+set trash='+Trash'
+set trash='/home/flatcap/Mail/Trash'
+
+# The default delete key 'd' will move an email to the 'trash' folder
+# Bind 'D' to REALLY delete an email
+bind index D purge-message
+
+# Note: Deleting emails from the 'trash' folder will REALLY delete them.
+
+# vim: syntax=muttrc
diff -urN mutt-1.6.1/doc/vimrc.trash mutt-1.6.1-trash/doc/vimrc.trash
--- mutt-1.6.1/doc/vimrc.trash 1970-01-01 01:00:00.000000000 +0100
+++ mutt-1.6.1-trash/doc/vimrc.trash 2016-06-12 18:43:04.769515692 +0100
@@ -0,0 +1,7 @@
+" Vim syntax file for the mutt trash patch
+
+syntax keyword muttrcVarStr contained skipwhite trash nextgroup=muttrcVarEqualsIdxFmt
+
+syntax match muttrcFunction contained "\<purge-message\>"
+
+" vim: syntax=vim
diff -urN mutt-1.6.1/flags.c mutt-1.6.1-trash/flags.c
--- mutt-1.6.1/flags.c 2016-06-12 18:43:00.403447606 +0100
+++ mutt-1.6.1-trash/flags.c 2016-06-12 18:43:04.902517766 +0100
@@ -65,7 +65,13 @@
{
h->deleted = 0;
update = 1;
- if (upd_ctx) ctx->deleted--;
+ if (upd_ctx) {
+ ctx->deleted--;
+ if (h->appended) {
+ ctx->appended--;
+ }
+ }
+ h->appended = 0; /* when undeleting, also reset the appended flag */
#ifdef USE_IMAP
/* see my comment above */
if (ctx->magic == M_IMAP)
@@ -87,6 +93,27 @@
}
break;
+ case M_APPENDED:
+ if (bf) {
+ if (!h->appended) {
+ h->appended = 1;
+ if (upd_ctx) {
+ ctx->appended++;
+ }
+ }
+ }
+ break;
+
+ case M_PURGED:
+ if (bf) {
+ if (!h->purged) {
+ h->purged = 1;
+ }
+ } else if (h->purged) {
+ h->purged = 0;
+ }
+ break;
+
case M_NEW:
if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
diff -urN mutt-1.6.1/functions.h mutt-1.6.1-trash/functions.h
--- mutt-1.6.1/functions.h 2016-06-12 18:43:00.403447606 +0100
+++ mutt-1.6.1-trash/functions.h 2016-06-12 18:43:04.902517766 +0100
@@ -121,6 +121,7 @@
{ "toggle-write", OP_TOGGLE_WRITE, "%" },
{ "next-thread", OP_MAIN_NEXT_THREAD, "\016" },
{ "next-subthread", OP_MAIN_NEXT_SUBTHREAD, "\033n" },
+ { "purge-message", OP_PURGE_MESSAGE, NULL },
{ "query", OP_QUERY, "Q" },
{ "quit", OP_QUIT, "q" },
{ "reply", OP_REPLY, "r" },
@@ -213,6 +214,7 @@
{ "print-message", OP_PRINT, "p" },
{ "previous-thread", OP_MAIN_PREV_THREAD, "\020" },
{ "previous-subthread",OP_MAIN_PREV_SUBTHREAD, "\033p" },
+ { "purge-message", OP_PURGE_MESSAGE, NULL },
{ "quit", OP_QUIT, "Q" },
{ "exit", OP_EXIT, "q" },
{ "reply", OP_REPLY, "r" },
diff -urN mutt-1.6.1/globals.h mutt-1.6.1-trash/globals.h
--- mutt-1.6.1/globals.h 2016-06-12 18:43:00.403447606 +0100
+++ mutt-1.6.1-trash/globals.h 2016-06-12 18:43:04.903517781 +0100
@@ -141,6 +141,7 @@
WHERE char *Status;
WHERE char *Tempdir;
WHERE char *Tochars;
+WHERE char *TrashPath;
WHERE char *TSStatusFormat;
WHERE char *TSIconFormat;
WHERE short TSSupported;
diff -urN mutt-1.6.1/imap/imap.c mutt-1.6.1-trash/imap/imap.c
--- mutt-1.6.1/imap/imap.c 2016-06-12 18:43:00.405447637 +0100
+++ mutt-1.6.1-trash/imap/imap.c 2016-06-12 18:43:04.905517812 +0100
@@ -888,6 +888,12 @@
if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
match = invert ^ hdrs[n]->deleted;
break;
+ case M_EXPIRED: /* imap_fast_trash version of M_DELETED */
+ if (hdrs[n]->purged)
+ break;
+ if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
+ match = invert ^ (hdrs[n]->deleted && !hdrs[n]->appended);
+ break;
case M_FLAG:
if (hdrs[n]->flagged != HEADER_DATA(hdrs[n])->flagged)
match = invert ^ hdrs[n]->flagged;
@@ -2038,3 +2044,53 @@
return -1;
}
+
+/**
+ * imap_fast_trash - XXX
+ */
+int
+imap_fast_trash (void)
+{
+ if ((Context->magic == M_IMAP) && mx_is_imap (TrashPath)) {
+ IMAP_MBOX mx;
+ IMAP_DATA *idata = (IMAP_DATA *) Context->data;
+ char mbox[LONG_STRING];
+ char mmbox[LONG_STRING];
+ int rc;
+ dprint (1, (debugfile, "[itf] trashcan seems to be on imap.\n"));
+
+ if (imap_parse_path (TrashPath, &mx) == 0) {
+ if (mutt_account_match (&(idata->conn->account), &(mx.account))) {
+ dprint (1, (debugfile, "[itf] trashcan seems to be on the same account.\n"));
+
+ imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
+ if (!*mbox)
+ strfcpy (mbox, "INBOX", sizeof (mbox));
+ imap_munge_mbox_name (idata, mmbox, sizeof (mmbox), mbox);
+
+ rc = imap_exec_msgset (idata, "UID COPY", mmbox, M_EXPIRED, 0, 0);
+ if (rc == 0) {
+ dprint (1, (debugfile, "imap_copy_messages: No messages del-tagged\n"));
+ rc = -1;
+ goto old_way;
+ } else if (rc < 0) {
+ dprint (1, (debugfile, "could not queue copy\n"));
+ goto old_way;
+ } else {
+ mutt_message (_("Copying %d messages to %s..."), rc, mbox);
+ return 0;
+ }
+ } else {
+ dprint (1, (debugfile, "[itf] trashcan seems to be on a different account.\n"));
+ }
+old_way:
+ FREE(&mx.mbox); /* we probably only need to free this when the parse works */
+ } else {
+ dprint (1, (debugfile, "[itf] failed to parse TrashPath.\n"));
+ }
+
+ dprint (1, (debugfile, "[itf] giving up and trying old fasioned way.\n"));
+ }
+
+ return 1;
+}
diff -urN mutt-1.6.1/imap/imap.h mutt-1.6.1-trash/imap/imap.h
--- mutt-1.6.1/imap/imap.h 2016-06-12 18:43:00.405447637 +0100
+++ mutt-1.6.1-trash/imap/imap.h 2016-06-12 18:43:04.774515769 +0100
@@ -72,4 +72,7 @@
int imap_account_match (const ACCOUNT* a1, const ACCOUNT* a2);
+/* trash */
+int imap_fast_trash (void);
+
#endif
diff -urN mutt-1.6.1/imap/message.c mutt-1.6.1-trash/imap/message.c
--- mutt-1.6.1/imap/message.c 2016-06-12 18:43:00.406447652 +0100
+++ mutt-1.6.1-trash/imap/message.c 2016-06-12 18:43:04.906517828 +0100
@@ -886,6 +886,7 @@
if (ctx->hdrs[n]->tagged)
{
mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1);
+ mutt_set_flag (ctx, ctx->hdrs[n], M_APPENDED, 1);
if (option (OPTDELETEUNTAG))
mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0);
}
@@ -893,6 +894,7 @@
else
{
mutt_set_flag (ctx, h, M_DELETE, 1);
+ mutt_set_flag (ctx, h, M_APPENDED, 1);
if (option (OPTDELETEUNTAG))
mutt_set_flag (ctx, h, M_TAG, 0);
}
diff -urN mutt-1.6.1/init.h mutt-1.6.1-trash/init.h
--- mutt-1.6.1/init.h 2016-06-12 18:43:00.408447684 +0100
+++ mutt-1.6.1-trash/init.h 2016-06-12 18:43:04.909517875 +0100
@@ -3419,6 +3419,16 @@
** provided that ``$$ts_enabled'' has been set. This string is identical in
** formatting to the one used by ``$$status_format''.
*/
+ { "trash", DT_PATH, R_NONE, UL &TrashPath, 0 },
+ /*
+ ** .pp
+ ** If set, this variable specifies the path of the trash folder where the
+ ** mails marked for deletion will be moved, instead of being irremediably
+ ** purged.
+ ** .pp
+ ** NOTE: When you delete a message in the trash folder, it is really
+ ** deleted, so that you have a way to clean the trash.
+ */
#ifdef USE_SOCKET
{ "tunnel", DT_STR, R_NONE, UL &Tunnel, UL 0 },
/*
diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-trash/mutt.h
--- mutt-1.6.1/mutt.h 2016-06-12 18:43:00.410447715 +0100
+++ mutt-1.6.1-trash/mutt.h 2016-06-12 18:43:04.912517922 +0100
@@ -182,6 +182,8 @@
M_DELETE,
M_UNDELETE,
M_DELETED,
+ M_APPENDED,
+ M_PURGED,
M_FLAG,
M_TAG,
M_UNTAG,
@@ -719,6 +721,8 @@
unsigned int mime : 1; /* has a MIME-Version header? */
unsigned int flagged : 1; /* marked important? */
unsigned int tagged : 1;
+ unsigned int appended : 1; /* has been saved */
+ unsigned int purged : 1; /* bypassing the trash folder */
unsigned int deleted : 1;
unsigned int changed : 1;
unsigned int attach_del : 1; /* has an attachment marked for deletion */
@@ -891,6 +895,7 @@
int new; /* how many new messages? */
int unread; /* how many unread messages? */
int deleted; /* how many deleted messages */
+ int appended; /* how many saved messages? */
int flagged; /* how many flagged messages */
int msgnotreadyet; /* which msg "new" in pager, -1 if none */
diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-trash/muttlib.c
--- mutt-1.6.1/muttlib.c 2016-06-12 18:43:00.411447731 +0100
+++ mutt-1.6.1-trash/muttlib.c 2016-06-12 18:43:04.913517937 +0100
@@ -1511,7 +1511,9 @@
if (magic > 0 && !mx_access (s, W_OK))
{
- if (option (OPTCONFIRMAPPEND))
+ if (option (OPTCONFIRMAPPEND) &&
+ (!TrashPath || (mutt_strcmp (s, TrashPath) != 0)))
+ /* if we're appending to the trash, there's no point in asking */
{
snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
diff -urN mutt-1.6.1/mx.c mutt-1.6.1-trash/mx.c
--- mutt-1.6.1/mx.c 2016-06-12 18:43:00.411447731 +0100
+++ mutt-1.6.1-trash/mx.c 2016-06-12 18:43:04.914517953 +0100
@@ -776,6 +776,62 @@
return rc;
}
+/**
+ * trash_append - XXX
+ *
+ * move deleted mails to the trash folder
+ */
+static int trash_append (CONTEXT *ctx)
+{
+ CONTEXT *ctx_trash;
+ int i = 0;
+ struct stat st, stc;
+
+ if (!TrashPath || !ctx->deleted ||
+ ((ctx->magic == M_MAILDIR) && option (OPTMAILDIRTRASH))) {
+ return 0;
+ }
+
+ for (; i < ctx->msgcount && (!ctx->hdrs[i]->deleted || ctx->hdrs[i]->appended); i++);
+ /* nothing */
+
+ if (i == ctx->msgcount)
+ return 0; /* nothing to be done */
+
+ if (mutt_save_confirm (TrashPath, &st) != 0) {
+ mutt_error _("message(s) not deleted");
+ return -1;
+ }
+
+ if (lstat (ctx->path, &stc) == 0 && stc.st_ino == st.st_ino
+ && stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev) {
+ return 0; /* we are in the trash folder: simple sync */
+ }
+
+#ifdef USE_IMAP
+ if (!imap_fast_trash())
+ return 0;
+#endif
+
+ if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL) {
+ for (i = 0 ; i < ctx->msgcount ; i++) {
+ if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->appended
+ && !ctx->hdrs[i]->purged
+ && mutt_append_message (ctx_trash, ctx, ctx->hdrs[i], 0, 0) == -1) {
+ mx_close_mailbox (ctx_trash, NULL);
+ return -1;
+ }
+ }
+
+ mx_close_mailbox (ctx_trash, NULL);
+ } else {
+ mutt_error _("Can't open trash folder");
+ return -1;
+ }
+
+ return 0;
+}
+
/* save changes and close mailbox */
int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
{
@@ -912,6 +968,7 @@
if (mutt_append_message (&f, ctx, ctx->hdrs[i], 0, CH_UPDATE_LEN) == 0)
{
mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, 1);
+ mutt_set_flag (ctx, ctx->hdrs[i], M_APPENDED, 1);
}
else
{
@@ -936,6 +993,14 @@
return 0;
}
+ /* copy mails to the trash before expunging */
+ if (purge && ctx->deleted && mutt_strcmp (ctx->path, TrashPath)) {
+ if (trash_append (ctx) != 0) {
+ ctx->closing = 0;
+ return -1;
+ }
+ }
+
#ifdef USE_IMAP
/* allow IMAP to preserve the deleted flag across sessions */
if (ctx->magic == M_IMAP)
@@ -1140,6 +1205,12 @@
msgcount = ctx->msgcount;
deleted = ctx->deleted;
+ if (purge && ctx->deleted && mutt_strcmp (ctx->path, TrashPath)) {
+ if (trash_append (ctx) == -1) {
+ return -1;
+ }
+ }
+
#ifdef USE_IMAP
if (ctx->magic == M_IMAP)
rc = imap_sync_mailbox (ctx, purge, index_hint);
diff -urN mutt-1.6.1/OPS mutt-1.6.1-trash/OPS
--- mutt-1.6.1/OPS 2016-06-12 18:43:00.389447388 +0100
+++ mutt-1.6.1-trash/OPS 2016-06-12 18:43:04.883517469 +0100
@@ -142,6 +142,7 @@
OP_PREV_LINE "scroll up one line"
OP_PREV_PAGE "move to the previous page"
OP_PRINT "print the current entry"
+OP_PURGE_MESSAGE "really delete the current entry, bypassing the trash folder"
OP_QUERY "query external program for addresses"
OP_QUERY_APPEND "append new query results to current results"
OP_QUIT "save changes to mailbox and quit"
diff -urN mutt-1.6.1/pager.c mutt-1.6.1-trash/pager.c
--- mutt-1.6.1/pager.c 2016-06-12 18:43:00.412447746 +0100
+++ mutt-1.6.1-trash/pager.c 2016-06-12 18:43:04.915517968 +0100
@@ -2351,6 +2351,7 @@
MAYBE_REDRAW (redraw);
break;
+ case OP_PURGE_MESSAGE:
case OP_DELETE:
CHECK_MODE(IsHeader (extra));
CHECK_READONLY;
@@ -2358,6 +2359,8 @@
CHECK_ACL(M_ACL_DELETE, _("Cannot delete message"));
mutt_set_flag (Context, extra->hdr, M_DELETE, 1);
+ mutt_set_flag (Context, extra->hdr, M_PURGED,
+ ch != OP_PURGE_MESSAGE ? 0 : 1);
if (option (OPTDELETEUNTAG))
mutt_set_flag (Context, extra->hdr, M_TAG, 0);
redraw = REDRAW_STATUS | REDRAW_INDEX;
@@ -2688,6 +2691,7 @@
CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message"));
mutt_set_flag (Context, extra->hdr, M_DELETE, 0);
+ mutt_set_flag (Context, extra->hdr, M_PURGED, 0);
redraw = REDRAW_STATUS | REDRAW_INDEX;
if (option (OPTRESOLVE))
{
@@ -2704,9 +2708,11 @@
CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0,
+ ch == OP_UNDELETE_THREAD ? 0 : 1)
+ + mutt_thread_set_flag (extra->hdr, M_PURGED, 0,
ch == OP_UNDELETE_THREAD ? 0 : 1);
- if (r != -1)
+ if (r > -1)
{
if (option (OPTRESOLVE))
{
diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-trash/PATCHES
--- mutt-1.6.1/PATCHES 2016-06-12 18:43:00.395447481 +0100
+++ mutt-1.6.1-trash/PATCHES 2016-06-12 18:43:04.889517563 +0100
@@ -0,0 +1 @@
+patch-trash-neo-20160612
diff -urN mutt-1.6.1/pattern.c mutt-1.6.1-trash/pattern.c
--- mutt-1.6.1/pattern.c 2016-06-12 18:43:00.413447762 +0100
+++ mutt-1.6.1-trash/pattern.c 2016-06-12 18:43:04.916517984 +0100
@@ -1367,8 +1367,9 @@
{
switch (op)
{
- case M_DELETE:
case M_UNDELETE:
+ mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_PURGED, 0);
+ case M_DELETE:
mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_DELETE,
(op == M_DELETE));
break;
diff -urN mutt-1.6.1/postpone.c mutt-1.6.1-trash/postpone.c
--- mutt-1.6.1/postpone.c 2016-06-12 18:43:00.414447777 +0100
+++ mutt-1.6.1-trash/postpone.c 2016-06-12 18:43:04.917518000 +0100
@@ -277,6 +277,9 @@
/* finished with this message, so delete it. */
mutt_set_flag (PostContext, h, M_DELETE, 1);
+ /* and consider it saved, so that it won't be moved to the trash folder */
+ mutt_set_flag (PostContext, h, M_APPENDED, 1);
+
/* update the count for the status display */
PostCount = PostContext->msgcount - PostContext->deleted;
diff -urN mutt-1.6.1/README.trash mutt-1.6.1-trash/README.trash
--- mutt-1.6.1/README.trash 1970-01-01 01:00:00.000000000 +0100
+++ mutt-1.6.1-trash/README.trash 2016-06-12 18:43:04.748515364 +0100
@@ -0,0 +1,74 @@
+Trash Folder Patch
+==================
+
+ Automatically move "deleted" emails to a trash bin
+
+Patch
+-----
+
+ To check if Mutt supports "Trash Folder", look for "patch-trash" in the
+ mutt version.
+
+ If IMAP is enabled, this patch will use it
+
+ Dependencies
+ * mutt-1.6.1
+ * IMAP support
+
+Introduction
+------------
+
+ In Mutt, when you "delete" an email it is first marked deleted. The email
+ isn't really gone until <sync-mailbox> is called. This happens when the
+ user leaves the folder, or the function is called manually.
+
+ After '<sync-mailbox>' has been called the email is gone forever.
+
+ The $trash variable defines a folder in which to keep old emails. As
+ before, first you mark emails for deletion. When <sync-mailbox> is called
+ the emails are moved to the trash folder.
+
+ The '$trash' path can be either a full directory, or be relative to the
+ $folder variable, like the 'mailboxes' command.
+
+ > Note
+ >
+ > Emails deleted from the trash folder are gone forever.
+
+Variables
+---------
+
+ Trash Variables
+
+ | Name | Type | Default |
+ |-------|--------|---------|
+ | trash | string | (none) |
+
+Functions
+---------
+
+ Trash Functions
+
+ | Menus | Default Key | Function | Description |
+ |-------------|-------------|-------------------|-------------------------------------------------------------|
+ | index,pager | (none) | '<purge-message>' | really delete the current entry, bypassing the trash folder |
+
+See Also
+--------
+
+ * NeoMutt project
+ * folder-hook
+
+Known Bugs
+----------
+
+ None
+
+Credits
+-------
+
+ * Cedric Duval <cedricduval@free.fr>
+ * Benjamin Kuperman <kuperman@acm.org>
+ * Paul Miller <paul@voltar.org>
+ * Richard Russon <rich@flatcap.org>
+