mutt: 1.6.0 -> 1.6.2
This commit is contained in:
parent
599cf0fe50
commit
8745e47909
10 changed files with 4652 additions and 1807 deletions
|
@ -1,43 +1,51 @@
|
|||
{ stdenv, fetchurl, ncurses, which, perl, autoreconfHook
|
||||
, sslSupport ? true
|
||||
, imapSupport ? true
|
||||
, headerCache ? true
|
||||
, saslSupport ? true
|
||||
, gpgmeSupport ? true
|
||||
, gdbm ? null
|
||||
, openssl ? null
|
||||
, cyrus_sasl ? null
|
||||
, gpgme ? null
|
||||
, withSidebar ? false
|
||||
, aclocal ? null
|
||||
, headerCache ? true
|
||||
, sslSupport ? true
|
||||
, saslSupport ? true
|
||||
, gpgmeSupport ? true
|
||||
, imapSupport ? true
|
||||
, withSidebar ? false
|
||||
, withTrash ? false
|
||||
}:
|
||||
|
||||
assert headerCache -> gdbm != null;
|
||||
assert sslSupport -> openssl != null;
|
||||
assert saslSupport -> cyrus_sasl != null;
|
||||
assert gpgmeSupport -> gpgme != null;
|
||||
assert headerCache -> gdbm != null;
|
||||
assert sslSupport -> openssl != null;
|
||||
assert saslSupport -> cyrus_sasl != null;
|
||||
assert gpgmeSupport -> gpgme != null;
|
||||
|
||||
with stdenv.lib;
|
||||
|
||||
let
|
||||
version = "1.6.0";
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
name = "mutt${stdenv.lib.optionalString withSidebar "-with-sidebar"}-${version}";
|
||||
name = "mutt-${version}";
|
||||
version = "1.6.2";
|
||||
|
||||
src = fetchurl {
|
||||
url = "http://ftp.mutt.org/pub/mutt/mutt-${version}.tar.gz";
|
||||
sha256 = "06bc2drbgalkk68rzg7hq2v5m5qgjxff5357wg0419dpi8ivdbr9";
|
||||
url = "http://ftp.mutt.org/pub/mutt/${name}.tar.gz";
|
||||
sha256 = "13hxmji7v9m2agmvzrs7gzx8s3c9jiwrv7pbkr7z1kc6ckq2xl65";
|
||||
};
|
||||
|
||||
buildInputs = with stdenv.lib;
|
||||
buildInputs =
|
||||
[ ncurses which perl ]
|
||||
++ optional headerCache gdbm
|
||||
++ optional sslSupport openssl
|
||||
++ optional saslSupport cyrus_sasl
|
||||
++ optional gpgmeSupport gpgme;
|
||||
|
||||
nativeBuildInputs = stdenv.lib.optional withSidebar autoreconfHook;
|
||||
++ optional headerCache gdbm
|
||||
++ optional sslSupport openssl
|
||||
++ optional saslSupport cyrus_sasl
|
||||
++ optional gpgmeSupport gpgme
|
||||
++ optional withSidebar autoreconfHook;
|
||||
|
||||
configureFlags = [
|
||||
"--with-mailpath=" "--enable-smtp"
|
||||
(enableFeature headerCache "hcache")
|
||||
(enableFeature gpgmeSupport "gpgme")
|
||||
(enableFeature imapSupport "imap")
|
||||
(enableFeature withSidebar "sidebar")
|
||||
"--enable-smtp"
|
||||
"--enable-pop"
|
||||
"--enable-imap"
|
||||
"--with-mailpath="
|
||||
|
||||
# Look in $PATH at runtime, instead of hardcoding /usr/bin/sendmail
|
||||
"ac_cv_path_SENDMAIL=sendmail"
|
||||
|
@ -45,36 +53,22 @@ stdenv.mkDerivation rec {
|
|||
# This allows calls with "-d N", that output debug info into ~/.muttdebug*
|
||||
"--enable-debug"
|
||||
|
||||
"--enable-pop" "--enable-imap"
|
||||
|
||||
# The next allows building mutt without having anything setgid
|
||||
# set by the installer, and removing the need for the group 'mail'
|
||||
# I set the value 'mailbox' because it is a default in the configure script
|
||||
"--with-homespool=mailbox"
|
||||
(if headerCache then "--enable-hcache" else "--disable-hcache")
|
||||
(if sslSupport then "--with-ssl" else "--without-ssl")
|
||||
(if imapSupport then "--enable-imap" else "--disable-imap")
|
||||
(if saslSupport then "--with-sasl" else "--without-sasl")
|
||||
(if gpgmeSupport then "--enable-gpgme" else "--disable-gpgme")
|
||||
];
|
||||
] ++ optional sslSupport "--with-ssl"
|
||||
++ optional saslSupport "--with-sasl";
|
||||
|
||||
# Adding the sidebar
|
||||
patches = stdenv.lib.optional withSidebar [
|
||||
./trash-folder.patch
|
||||
./sidebar.patch
|
||||
./sidebar-dotpathsep.patch
|
||||
./sidebar-utf8.patch
|
||||
./sidebar-newonly.patch
|
||||
./sidebar-delimnullwide.patch
|
||||
./sidebar-compose.patch
|
||||
./sidebar-new.patch
|
||||
];
|
||||
patches =
|
||||
optional withTrash ./trash.patch ++
|
||||
optional withSidebar ./sidebar.patch;
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
meta = {
|
||||
description = "A small but very powerful text-based mail client";
|
||||
homepage = http://www.mutt.org;
|
||||
license = stdenv.lib.licenses.gpl2Plus;
|
||||
license = licenses.gpl2Plus;
|
||||
platforms = platforms.unix;
|
||||
maintainers = with maintainers; [ the-kenny ];
|
||||
maintainers = with maintainers; [ the-kenny rnhmjoj ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
From: Evgeni Golov <evgeni@debian.org>
|
||||
Date: Fri, 14 Mar 2014 08:54:47 +0100
|
||||
Subject: sidebar-compose
|
||||
|
||||
draw_sidebar sets SidebarWidth to 0 when sidebar_visible is false.
|
||||
However, if you start mutt in compose mode, draw_sidebar won't be
|
||||
called until the next redraw and your header lines will be off by
|
||||
the width of the sidebar, even when you did not want a sidebar at
|
||||
all.
|
||||
|
||||
Can be tested with:
|
||||
HOME=/ LC_ALL=C mutt -e 'unset sidebar_visible' -s test recipient
|
||||
|
||||
Closes: #502627
|
||||
|
||||
Gbp-Pq: Topic mutt-patched
|
||||
---
|
||||
compose.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/compose.c b/compose.c
|
||||
index b63695f..0fa6df2 100644
|
||||
--- a/compose.c
|
||||
+++ b/compose.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "mailbox.h"
|
||||
#include "sort.h"
|
||||
#include "charset.h"
|
||||
+#include "sidebar.h"
|
||||
|
||||
#ifdef MIXMASTER
|
||||
#include "remailer.h"
|
||||
@@ -248,6 +249,7 @@ static void draw_envelope_addr (int line, ADDRESS *addr)
|
||||
|
||||
static void draw_envelope (HEADER *msg, char *fcc)
|
||||
{
|
||||
+ draw_sidebar (MENU_COMPOSE);
|
||||
draw_envelope_addr (HDR_FROM, msg->env->from);
|
||||
draw_envelope_addr (HDR_TO, msg->env->to);
|
||||
draw_envelope_addr (HDR_CC, msg->env->cc);
|
|
@ -1,38 +0,0 @@
|
|||
From: Evgeni Golov <sargentd@die-welt.net>
|
||||
Date: Wed, 5 Mar 2014 17:46:07 +0100
|
||||
Subject: sidebar-delimnullwide
|
||||
|
||||
SidebarDelim can be NULL and strlen(NULL) is a bad idea, as it will segfault.
|
||||
Wrap it with NONULL().
|
||||
|
||||
While at it, change strlen to mbstowcs for better utf8 support.
|
||||
|
||||
Closes: #696145, #663883
|
||||
|
||||
Gbp-Pq: Topic mutt-patched
|
||||
---
|
||||
sidebar.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sidebar.c b/sidebar.c
|
||||
index 51a25ca..c3ea338 100644
|
||||
--- a/sidebar.c
|
||||
+++ b/sidebar.c
|
||||
@@ -88,7 +88,7 @@ char *make_sidebar_entry(char *box, int size, int new, int flagged)
|
||||
int box_len, box_bytes;
|
||||
int int_len;
|
||||
int right_offset = 0;
|
||||
- int delim_len = strlen(SidebarDelim);
|
||||
+ int delim_len = mbstowcs(NULL, NONULL(SidebarDelim), 0);
|
||||
static char *entry;
|
||||
|
||||
right_width = left_width = 0;
|
||||
@@ -178,7 +178,7 @@ int draw_sidebar(int menu) {
|
||||
#ifndef USE_SLANG_CURSES
|
||||
attr_t attrs;
|
||||
#endif
|
||||
- short delim_len = strlen(SidebarDelim);
|
||||
+ short delim_len = mbstowcs(NULL, NONULL(SidebarDelim), 0);
|
||||
short color_pair;
|
||||
|
||||
static bool initialized = false;
|
|
@ -1,98 +0,0 @@
|
|||
From: Fabian Groffen <grobian@gentoo.org>
|
||||
Date: Tue, 4 Mar 2014 21:12:15 +0100
|
||||
Subject: sidebar-dotpathsep
|
||||
|
||||
Make path separators for sidebar folders configurable.
|
||||
|
||||
When using IMAP, a '.' is often used as path separator, hence make the
|
||||
path separators configurable through sidebar_delim_chars variable.
|
||||
It defaults to "/." to work for both mboxes as well as IMAP folders. It
|
||||
can be set to only "/" or "." or whichever character desired as needed.
|
||||
|
||||
Gbp-Pq: Topic mutt-patched
|
||||
---
|
||||
globals.h | 1 +
|
||||
init.h | 8 ++++++++
|
||||
sidebar.c | 31 ++++++++++++++++++++++++-------
|
||||
3 files changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/globals.h b/globals.h
|
||||
index 004c795..602f932 100644
|
||||
--- a/globals.h
|
||||
+++ b/globals.h
|
||||
@@ -119,6 +119,7 @@ WHERE char *SendCharset;
|
||||
WHERE char *Sendmail;
|
||||
WHERE char *Shell;
|
||||
WHERE char *SidebarDelim;
|
||||
+WHERE char *SidebarDelimChars INITVAL (NULL);
|
||||
WHERE char *Signature;
|
||||
WHERE char *SimpleSearch;
|
||||
#if USE_SMTP
|
||||
diff --git a/init.h b/init.h
|
||||
index c664e5f..166671b 100644
|
||||
--- a/init.h
|
||||
+++ b/init.h
|
||||
@@ -2051,6 +2051,14 @@ struct option_t MuttVars[] = {
|
||||
** .pp
|
||||
** The width of the sidebar.
|
||||
*/
|
||||
+ { "sidebar_delim_chars", DT_STR, R_NONE, UL &SidebarDelimChars, UL "/." },
|
||||
+ /*
|
||||
+ ** .pp
|
||||
+ ** This contains the list of characters which you would like to treat
|
||||
+ ** as folder separators for displaying paths in the sidebar. If
|
||||
+ ** you're not using IMAP folders, you probably prefer setting this to "/"
|
||||
+ ** alone.
|
||||
+ */
|
||||
{ "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
|
||||
/*
|
||||
** .pp
|
||||
diff --git a/sidebar.c b/sidebar.c
|
||||
index 6098c2a..4356ffc 100644
|
||||
--- a/sidebar.c
|
||||
+++ b/sidebar.c
|
||||
@@ -249,20 +249,37 @@ int draw_sidebar(int menu) {
|
||||
// calculate depth of current folder and generate its display name with indented spaces
|
||||
int sidebar_folder_depth = 0;
|
||||
char *sidebar_folder_name;
|
||||
- sidebar_folder_name = basename(tmp->path);
|
||||
+ int i;
|
||||
+ sidebar_folder_name = tmp->path;
|
||||
+ /* disregard a trailing separator, so strlen() - 2
|
||||
+ * https://bugs.gentoo.org/show_bug.cgi?id=373197#c16 */
|
||||
+ for (i = strlen(sidebar_folder_name) - 2; i >= 0; i--) {
|
||||
+ if (SidebarDelimChars &&
|
||||
+ strchr(SidebarDelimChars, sidebar_folder_name[i]))
|
||||
+ {
|
||||
+ sidebar_folder_name += i + 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
if ( maildir_is_prefix ) {
|
||||
char *tmp_folder_name;
|
||||
- int i;
|
||||
+ int lastsep = 0;
|
||||
tmp_folder_name = tmp->path + strlen(Maildir);
|
||||
- for (i = 0; i < strlen(tmp->path) - strlen(Maildir); i++) {
|
||||
- if (tmp_folder_name[i] == '/') sidebar_folder_depth++;
|
||||
- }
|
||||
+ for (i = 0; i < strlen(tmp_folder_name) - 1; i++) {
|
||||
+ if (SidebarDelimChars &&
|
||||
+ strchr(SidebarDelimChars, tmp_folder_name[i]))
|
||||
+ {
|
||||
+ sidebar_folder_depth++;
|
||||
+ lastsep = i + 1;
|
||||
+ }
|
||||
+ }
|
||||
if (sidebar_folder_depth > 0) {
|
||||
- sidebar_folder_name = malloc(strlen(basename(tmp->path)) + sidebar_folder_depth + 1);
|
||||
+ tmp_folder_name += lastsep; /* basename */
|
||||
+ sidebar_folder_name = malloc(strlen(tmp_folder_name) + sidebar_folder_depth + 1);
|
||||
for (i=0; i < sidebar_folder_depth; i++)
|
||||
sidebar_folder_name[i]=' ';
|
||||
sidebar_folder_name[i]=0;
|
||||
- strncat(sidebar_folder_name, basename(tmp->path), strlen(basename(tmp->path)) + sidebar_folder_depth);
|
||||
+ strncat(sidebar_folder_name, tmp_folder_name, strlen(tmp_folder_name) + sidebar_folder_depth);
|
||||
}
|
||||
}
|
||||
printw( "%.*s", SidebarWidth - delim_len + 1,
|
|
@ -1,97 +0,0 @@
|
|||
From 355399bde98203af59d20821f9e840fc056bd383 Mon Sep 17 00:00:00 2001
|
||||
From: Julius Haertl <jus@bitgrid.net>
|
||||
Date: Tue, 9 Sep 2014 22:31:49 +0200
|
||||
Subject: Patch for sidebar iteration functionality
|
||||
|
||||
sidebar-new will move the selected folder to the next with new messages.
|
||||
If the end is reached, it will start at the top.
|
||||
|
||||
Useful macros would be:
|
||||
|
||||
macro index <esc>a "<sidebar-new><sidebar-open>"
|
||||
macro pager <esc>a "<exit><sidebar-new><sidebar-open>"
|
||||
---
|
||||
OPS | 1 +
|
||||
curs_main.c | 1 +
|
||||
functions.h | 2 ++
|
||||
pager.c | 1 +
|
||||
sidebar.c | 10 ++++++++++
|
||||
5 files changed, 15 insertions(+)
|
||||
|
||||
diff --git a/OPS b/OPS
|
||||
index 1ed9c96..3ffb82a 100644
|
||||
--- a/OPS
|
||||
+++ b/OPS
|
||||
@@ -187,3 +187,4 @@ OP_SIDEBAR_PREV "go to previous mailbox"
|
||||
OP_SIDEBAR_OPEN "open hilighted mailbox"
|
||||
OP_SIDEBAR_NEXT_NEW "go down to next mailbox with new mail"
|
||||
OP_SIDEBAR_PREV_NEW "go to previous mailbox with new mail"
|
||||
+OP_SIDEBAR_NEW "iterate though mailboxes with new mail"
|
||||
diff --git a/curs_main.c b/curs_main.c
|
||||
index acb106d..2e35f90 100644
|
||||
--- a/curs_main.c
|
||||
+++ b/curs_main.c
|
||||
@@ -2328,6 +2328,7 @@ int mutt_index_menu (void)
|
||||
case OP_SIDEBAR_PREV:
|
||||
case OP_SIDEBAR_NEXT_NEW:
|
||||
case OP_SIDEBAR_PREV_NEW:
|
||||
+ case OP_SIDEBAR_NEW:
|
||||
scroll_sidebar(op, menu->menu);
|
||||
break;
|
||||
default:
|
||||
diff --git a/functions.h b/functions.h
|
||||
index 363b4d5..1485080 100644
|
||||
--- a/functions.h
|
||||
+++ b/functions.h
|
||||
@@ -176,6 +176,7 @@ const struct binding_t OpMain[] = { /* map: index */
|
||||
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
|
||||
{ "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
|
||||
{ "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
|
||||
+ { "sidebar-new", OP_SIDEBAR_NEW, NULL },
|
||||
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
@@ -287,6 +288,7 @@ const struct binding_t OpPager[] = { /* map: pager */
|
||||
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
|
||||
{ "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
|
||||
{ "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
|
||||
+ { "sidebar-new", OP_SIDEBAR_NEW, NULL },
|
||||
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
diff --git a/pager.c b/pager.c
|
||||
index 8d64fe1..696e55c 100644
|
||||
--- a/pager.c
|
||||
+++ b/pager.c
|
||||
@@ -2791,6 +2791,7 @@ search_next:
|
||||
case OP_SIDEBAR_PREV:
|
||||
case OP_SIDEBAR_NEXT_NEW:
|
||||
case OP_SIDEBAR_PREV_NEW:
|
||||
+ case OP_SIDEBAR_NEW:
|
||||
scroll_sidebar(ch, MENU_PAGER);
|
||||
break;
|
||||
|
||||
diff --git a/sidebar.c b/sidebar.c
|
||||
index c3ea338..eb8ecd2 100644
|
||||
--- a/sidebar.c
|
||||
+++ b/sidebar.c
|
||||
@@ -429,6 +429,16 @@ void scroll_sidebar(int op, int menu)
|
||||
CurBuffy = CurBuffy->next;
|
||||
}
|
||||
break;
|
||||
+ case OP_SIDEBAR_NEW:
|
||||
+ if ( (tmp = exist_next_new()) == NULL)
|
||||
+ tmp = TopBuffy;
|
||||
+ if ( tmp->msg_unread == 0 ) {
|
||||
+ CurBuffy = tmp;
|
||||
+ tmp = exist_next_new();
|
||||
+ }
|
||||
+ if ( tmp != NULL )
|
||||
+ CurBuffy = tmp;
|
||||
+ break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.6.0.rc0.2.g7662973.dirty
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
From: Steve Kemp <steve@steve.org.uk>
|
||||
Date: Tue, 4 Mar 2014 22:07:06 +0100
|
||||
Subject: sidebar-newonly
|
||||
|
||||
patches written by Steve Kemp, it adds two new functionalities to the sidebar,
|
||||
so only the mailbox with new messages will be shown (and/or) selected
|
||||
See Debian bug http://bugs.debian.org/532510
|
||||
|
||||
Gbp-Pq: Topic mutt-patched
|
||||
---
|
||||
OPS | 2 ++
|
||||
curs_main.c | 2 ++
|
||||
functions.h | 4 ++++
|
||||
init.h | 5 +++++
|
||||
mutt.h | 2 ++
|
||||
pager.c | 2 ++
|
||||
sidebar.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
7 files changed, 70 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/OPS b/OPS
|
||||
index b036db9..1ed9c96 100644
|
||||
--- a/OPS
|
||||
+++ b/OPS
|
||||
@@ -185,3 +185,5 @@ OP_SIDEBAR_SCROLL_DOWN "scroll the mailbox pane down 1 page"
|
||||
OP_SIDEBAR_NEXT "go down to next mailbox"
|
||||
OP_SIDEBAR_PREV "go to previous mailbox"
|
||||
OP_SIDEBAR_OPEN "open hilighted mailbox"
|
||||
+OP_SIDEBAR_NEXT_NEW "go down to next mailbox with new mail"
|
||||
+OP_SIDEBAR_PREV_NEW "go to previous mailbox with new mail"
|
||||
diff --git a/curs_main.c b/curs_main.c
|
||||
index ea530a6..acb106d 100644
|
||||
--- a/curs_main.c
|
||||
+++ b/curs_main.c
|
||||
@@ -2326,6 +2326,8 @@ int mutt_index_menu (void)
|
||||
case OP_SIDEBAR_SCROLL_DOWN:
|
||||
case OP_SIDEBAR_NEXT:
|
||||
case OP_SIDEBAR_PREV:
|
||||
+ case OP_SIDEBAR_NEXT_NEW:
|
||||
+ case OP_SIDEBAR_PREV_NEW:
|
||||
scroll_sidebar(op, menu->menu);
|
||||
break;
|
||||
default:
|
||||
diff --git a/functions.h b/functions.h
|
||||
index ef8937a..363b4d5 100644
|
||||
--- a/functions.h
|
||||
+++ b/functions.h
|
||||
@@ -174,6 +174,8 @@ const struct binding_t OpMain[] = { /* map: index */
|
||||
{ "sidebar-scroll-down", OP_SIDEBAR_SCROLL_DOWN, NULL },
|
||||
{ "sidebar-next", OP_SIDEBAR_NEXT, NULL },
|
||||
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
|
||||
+ { "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
|
||||
+ { "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
|
||||
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
@@ -283,6 +285,8 @@ const struct binding_t OpPager[] = { /* map: pager */
|
||||
{ "sidebar-scroll-down", OP_SIDEBAR_SCROLL_DOWN, NULL },
|
||||
{ "sidebar-next", OP_SIDEBAR_NEXT, NULL },
|
||||
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
|
||||
+ { "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
|
||||
+ { "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
|
||||
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
diff --git a/init.h b/init.h
|
||||
index 166671b..a5d4238 100644
|
||||
--- a/init.h
|
||||
+++ b/init.h
|
||||
@@ -2059,6 +2059,11 @@ struct option_t MuttVars[] = {
|
||||
** you're not using IMAP folders, you probably prefer setting this to "/"
|
||||
** alone.
|
||||
*/
|
||||
+ {"sidebar_newmail_only", DT_BOOL, R_BOTH, OPTSIDEBARNEWMAILONLY, 0 },
|
||||
+ /*
|
||||
+ ** .pp
|
||||
+ ** Show only new mail in the sidebar.
|
||||
+ */
|
||||
{ "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
|
||||
/*
|
||||
** .pp
|
||||
diff --git a/mutt.h b/mutt.h
|
||||
index 5f25406..d73e514 100644
|
||||
--- a/mutt.h
|
||||
+++ b/mutt.h
|
||||
@@ -529,6 +529,8 @@ enum
|
||||
OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
|
||||
OPTUNBUFFEREDINPUT, /* (pseudo) don't use key buffer */
|
||||
|
||||
+ OPTSIDEBARNEWMAILONLY,
|
||||
+
|
||||
OPTMAX
|
||||
};
|
||||
|
||||
diff --git a/pager.c b/pager.c
|
||||
index 5cfcb75..8d64fe1 100644
|
||||
--- a/pager.c
|
||||
+++ b/pager.c
|
||||
@@ -2789,6 +2789,8 @@ search_next:
|
||||
case OP_SIDEBAR_SCROLL_DOWN:
|
||||
case OP_SIDEBAR_NEXT:
|
||||
case OP_SIDEBAR_PREV:
|
||||
+ case OP_SIDEBAR_NEXT_NEW:
|
||||
+ case OP_SIDEBAR_PREV_NEW:
|
||||
scroll_sidebar(ch, MENU_PAGER);
|
||||
break;
|
||||
|
||||
diff --git a/sidebar.c b/sidebar.c
|
||||
index 8f58f85..51a25ca 100644
|
||||
--- a/sidebar.c
|
||||
+++ b/sidebar.c
|
||||
@@ -269,8 +269,21 @@ int draw_sidebar(int menu) {
|
||||
SETCOLOR(MT_COLOR_NEW);
|
||||
else if ( tmp->msg_flagged > 0 )
|
||||
SETCOLOR(MT_COLOR_FLAGGED);
|
||||
- else
|
||||
- SETCOLOR(MT_COLOR_NORMAL);
|
||||
+ else {
|
||||
+ /* make sure the path is either:
|
||||
+ 1. Containing new mail.
|
||||
+ 2. The inbox.
|
||||
+ 3. The current box.
|
||||
+ */
|
||||
+ if ((option (OPTSIDEBARNEWMAILONLY)) &&
|
||||
+ ( (tmp->msg_unread <= 0) &&
|
||||
+ ( tmp != Incoming ) &&
|
||||
+ Context &&
|
||||
+ ( strcmp( tmp->path, Context->path ) != 0 ) ) )
|
||||
+ continue;
|
||||
+ else
|
||||
+ SETCOLOR(MT_COLOR_NORMAL);
|
||||
+ }
|
||||
|
||||
move( lines, 0 );
|
||||
if ( Context && !strcmp( tmp->path, Context->path ) ) {
|
||||
@@ -336,6 +349,29 @@ int draw_sidebar(int menu) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+BUFFY * exist_next_new()
|
||||
+{
|
||||
+ BUFFY *tmp = CurBuffy;
|
||||
+ if(tmp == NULL) return NULL;
|
||||
+ while (tmp->next != NULL)
|
||||
+ {
|
||||
+ tmp = tmp->next;
|
||||
+ if(tmp->msg_unread) return tmp;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+BUFFY * exist_prev_new()
|
||||
+{
|
||||
+ BUFFY *tmp = CurBuffy;
|
||||
+ if(tmp == NULL) return NULL;
|
||||
+ while (tmp->prev != NULL)
|
||||
+ {
|
||||
+ tmp = tmp->prev;
|
||||
+ if(tmp->msg_unread) return tmp;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
|
||||
void set_buffystats(CONTEXT* Context)
|
||||
{
|
||||
@@ -352,18 +388,33 @@ void set_buffystats(CONTEXT* Context)
|
||||
|
||||
void scroll_sidebar(int op, int menu)
|
||||
{
|
||||
+ BUFFY *tmp;
|
||||
if(!SidebarWidth) return;
|
||||
if(!CurBuffy) return;
|
||||
|
||||
switch (op) {
|
||||
case OP_SIDEBAR_NEXT:
|
||||
+ if (!option (OPTSIDEBARNEWMAILONLY)) {
|
||||
if ( CurBuffy->next == NULL ) return;
|
||||
CurBuffy = CurBuffy->next;
|
||||
break;
|
||||
+ }
|
||||
+ case OP_SIDEBAR_NEXT_NEW:
|
||||
+ if ( (tmp = exist_next_new()) == NULL)
|
||||
+ return;
|
||||
+ else CurBuffy = tmp;
|
||||
+ break;
|
||||
case OP_SIDEBAR_PREV:
|
||||
+ if (!option (OPTSIDEBARNEWMAILONLY)) {
|
||||
if ( CurBuffy->prev == NULL ) return;
|
||||
CurBuffy = CurBuffy->prev;
|
||||
break;
|
||||
+ }
|
||||
+ case OP_SIDEBAR_PREV_NEW:
|
||||
+ if ( (tmp = exist_prev_new()) == NULL)
|
||||
+ return;
|
||||
+ else CurBuffy = tmp;
|
||||
+ break;
|
||||
case OP_SIDEBAR_SCROLL_UP:
|
||||
CurBuffy = TopBuffy;
|
||||
if ( CurBuffy != Incoming ) {
|
|
@ -1,132 +0,0 @@
|
|||
From: Antonio Radici <antonio@debian.org>
|
||||
Date: Tue, 4 Mar 2014 15:39:14 +0100
|
||||
Subject: sidebar-utf8
|
||||
|
||||
This patch fixes a problem with utf-8 strings and the sidebar,
|
||||
it rewrites entirely make_sidebar_entry so it also fixes some
|
||||
segfaults due to misallocations and overflows.
|
||||
|
||||
See:
|
||||
http://bugs.debian.org/584581
|
||||
http://bugs.debian.org/603287
|
||||
|
||||
Gbp-Pq: Topic mutt-patched
|
||||
---
|
||||
sidebar.c | 97 +++++++++++++++++++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 67 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/sidebar.c b/sidebar.c
|
||||
index 4356ffc..8f58f85 100644
|
||||
--- a/sidebar.c
|
||||
+++ b/sidebar.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <libgen.h>
|
||||
#include "keymap.h"
|
||||
#include <stdbool.h>
|
||||
+#include <wchar.h>
|
||||
|
||||
/*BUFFY *CurBuffy = 0;*/
|
||||
static BUFFY *TopBuffy = 0;
|
||||
@@ -82,36 +83,72 @@ void calc_boundaries (int menu)
|
||||
|
||||
char *make_sidebar_entry(char *box, int size, int new, int flagged)
|
||||
{
|
||||
- static char *entry = 0;
|
||||
- char *c;
|
||||
- int i = 0;
|
||||
- int delim_len = strlen(SidebarDelim);
|
||||
-
|
||||
- c = realloc(entry, SidebarWidth - delim_len + 2);
|
||||
- if ( c ) entry = c;
|
||||
- entry[SidebarWidth - delim_len + 1] = 0;
|
||||
- for (; i < SidebarWidth - delim_len + 1; entry[i++] = ' ' );
|
||||
- i = strlen(box);
|
||||
- strncpy( entry, box, i < (SidebarWidth - delim_len + 1) ? i : (SidebarWidth - delim_len + 1) );
|
||||
-
|
||||
- if (size == -1)
|
||||
- sprintf(entry + SidebarWidth - delim_len - 3, "?");
|
||||
- else if ( new ) {
|
||||
- if (flagged > 0) {
|
||||
- sprintf(
|
||||
- entry + SidebarWidth - delim_len - 5 - quick_log10(size) - quick_log10(new) - quick_log10(flagged),
|
||||
- "% d(%d)[%d]", size, new, flagged);
|
||||
- } else {
|
||||
- sprintf(
|
||||
- entry + SidebarWidth - delim_len - 3 - quick_log10(size) - quick_log10(new),
|
||||
- "% d(%d)", size, new);
|
||||
- }
|
||||
- } else if (flagged > 0) {
|
||||
- sprintf( entry + SidebarWidth - delim_len - 3 - quick_log10(size) - quick_log10(flagged), "% d[%d]", size, flagged);
|
||||
- } else {
|
||||
- sprintf( entry + SidebarWidth - delim_len - 1 - quick_log10(size), "% d", size);
|
||||
- }
|
||||
- return entry;
|
||||
+ char int_store[20]; // up to 64 bits integers
|
||||
+ int right_width, left_width;
|
||||
+ int box_len, box_bytes;
|
||||
+ int int_len;
|
||||
+ int right_offset = 0;
|
||||
+ int delim_len = strlen(SidebarDelim);
|
||||
+ static char *entry;
|
||||
+
|
||||
+ right_width = left_width = 0;
|
||||
+ box_len = box_bytes = 0;
|
||||
+
|
||||
+ // allocate an entry big enough to contain SidebarWidth wide chars
|
||||
+ entry = malloc((SidebarWidth*4)+1); // TODO: error check
|
||||
+
|
||||
+ // determine the right space (i.e.: how big are the numbers that we want to print)
|
||||
+ if ( size > 0 ) {
|
||||
+ int_len = snprintf(int_store, sizeof(int_store), "%d", size);
|
||||
+ right_width += int_len;
|
||||
+ } else {
|
||||
+ right_width = 1; // to represent 0
|
||||
+ }
|
||||
+ if ( new > 0 ) {
|
||||
+ int_len = snprintf(int_store, sizeof(int_store), "%d", new);
|
||||
+ right_width += int_len + 2; // 2 is for ()
|
||||
+ }
|
||||
+ if ( flagged > 0 ) {
|
||||
+ int_len = snprintf(int_store, sizeof(int_store), "%d", flagged);
|
||||
+ right_width += int_len + 2; // 2 is for []
|
||||
+ }
|
||||
+
|
||||
+ // determine how much space we have for *box and its padding (if any)
|
||||
+ left_width = SidebarWidth - right_width - 1 - delim_len; // 1 is for the space
|
||||
+ //fprintf(stdout, "left_width: %d right_width: %d\n", left_width, right_width);
|
||||
+ // right side overflow case
|
||||
+ if ( left_width <= 0 ) {
|
||||
+ snprintf(entry, SidebarWidth*4, "%-*.*s ...", SidebarWidth-4-delim_len, SidebarWidth-4-delim_len, box);
|
||||
+ return entry;
|
||||
+ }
|
||||
+ right_width -= delim_len;
|
||||
+
|
||||
+ // to support utf-8 chars we need to add enough space padding in case there
|
||||
+ // are less chars than bytes in *box
|
||||
+ box_len = mbstowcs(NULL, box, 0);
|
||||
+ box_bytes = strlen(box);
|
||||
+ // debug
|
||||
+ //fprintf(stdout, "box_len: %d box_bytes: %d (diff: %d)\n", box_len, box_bytes, (box_bytes-box_len));
|
||||
+ // if there is less string than the space we allow, then we will add the
|
||||
+ // spaces
|
||||
+ if ( box_len != -1 && box_len < left_width ) {
|
||||
+ left_width += (box_bytes - box_len);
|
||||
+ }
|
||||
+ // otherwise sprintf will truncate the string for us (therefore, no else case)
|
||||
+
|
||||
+ // print the sidebar entry (without new and flagged messages, at the moment)
|
||||
+ //fprintf(stdout, "left_width: %d right_width: %d\n", left_width, right_width);
|
||||
+ right_offset = snprintf(entry, SidebarWidth*4, "%-*.*s %d", left_width, left_width, box, size);
|
||||
+
|
||||
+ // then pad new and flagged messages if any
|
||||
+ if ( new > 0 ) {
|
||||
+ right_offset += snprintf(entry+right_offset, SidebarWidth*4-right_offset, "(%d)", new);
|
||||
+ }
|
||||
+ if ( flagged > 0 ) {
|
||||
+ right_offset += snprintf(entry+right_offset, SidebarWidth*4-right_offset, "[%d]", flagged);
|
||||
+ }
|
||||
+
|
||||
+ return entry;
|
||||
}
|
||||
|
||||
void set_curbuffy(char buf[LONG_STRING])
|
File diff suppressed because it is too large
Load diff
|
@ -1,316 +0,0 @@
|
|||
From: Cedric Duval <cedricduval@free.fr>
|
||||
Date: Thu, 27 Feb 2014 12:27:41 +0100
|
||||
Subject: trash-folder
|
||||
|
||||
With this patch, if the trash variable is set to a path (unset by default), the
|
||||
deleted mails will be moved to a trash folder instead of being irremediably
|
||||
purged when syncing the mailbox.
|
||||
|
||||
For instance, set trash="~/Mail/trash" will cause every deleted mail to go to
|
||||
this folder.
|
||||
|
||||
Note that the append to the trash folder doesn't occur until the resync is
|
||||
done. This allows you to change your mind and undo deletes, and thus the moves
|
||||
to the trash folder are unnecessary.
|
||||
|
||||
Notes
|
||||
|
||||
* You might also want to have a look at the purge message feature below
|
||||
which is related to this patch.
|
||||
* IMAP is now supported. To retain the previous behavior, add this to your
|
||||
muttrc:
|
||||
folder-hook ^imap:// 'unset trash'
|
||||
|
||||
FAQ
|
||||
|
||||
Every once in a while, someone asks what are the advantages of this patch over
|
||||
a macro based solution. Here's an attempt to answer this question:
|
||||
|
||||
* The folder history doesn't clutter up with unwanted trash entries.
|
||||
* Delayed move to the trash allows to change one's mind.
|
||||
* No need to treat the case of "normal folders" and trash folders
|
||||
separately with folder-hooks, and to create two sets of macros (one for
|
||||
the index, one for the pager).
|
||||
* Works not only with delete-message, but also with every deletion
|
||||
functions like delete-pattern, delete-thread or delete-subthread.
|
||||
|
||||
To sum up, it's more integrated and transparent to the user.
|
||||
|
||||
* Patch last synced with upstream:
|
||||
- Date: 2007-02-15
|
||||
- File: http://cedricduval.free.fr/mutt/patches/download/patch-1.5.5.1.cd.trash_folder.3.4
|
||||
|
||||
* Changes made:
|
||||
- Updated to 1.5.13:
|
||||
- structure of _mutt_save_message changed (commands.c)
|
||||
- context of option (OPTCONFIRMAPPEND) changed (muttlib.c)
|
||||
- Fixed indentation of "appended" in mutt.h.
|
||||
|
||||
Signed-off-by: Matteo F. Vescovi <mfvescovi@gmail.com>
|
||||
|
||||
Gbp-Pq: Topic features
|
||||
---
|
||||
commands.c | 1 +
|
||||
flags.c | 19 +++++++++++++++++-
|
||||
globals.h | 1 +
|
||||
imap/message.c | 2 ++
|
||||
init.h | 10 ++++++++++
|
||||
mutt.h | 3 +++
|
||||
muttlib.c | 4 +++-
|
||||
mx.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
postpone.c | 3 +++
|
||||
9 files changed, 103 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/commands.c b/commands.c
|
||||
index 5dbd100..7fd014b 100644
|
||||
--- a/commands.c
|
||||
+++ b/commands.c
|
||||
@@ -720,6 +720,7 @@ int _mutt_save_message (HEADER *h, CONTEXT *ctx, int delete, int decode, int dec
|
||||
if (option (OPTDELETEUNTAG))
|
||||
mutt_set_flag (Context, h, M_TAG, 0);
|
||||
}
|
||||
+ mutt_set_flag (Context, h, M_APPENDED, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/flags.c b/flags.c
|
||||
index f0f3d81..dfa6a50 100644
|
||||
--- a/flags.c
|
||||
+++ b/flags.c
|
||||
@@ -65,7 +65,13 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
|
||||
{
|
||||
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,17 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
|
||||
}
|
||||
break;
|
||||
|
||||
+ case M_APPENDED:
|
||||
+ if (bf)
|
||||
+ {
|
||||
+ if (!h->appended)
|
||||
+ {
|
||||
+ h->appended = 1;
|
||||
+ if (upd_ctx) ctx->appended++;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
case M_NEW:
|
||||
|
||||
if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
|
||||
diff --git a/globals.h b/globals.h
|
||||
index e77030c..6a1b8da 100644
|
||||
--- a/globals.h
|
||||
+++ b/globals.h
|
||||
@@ -144,6 +144,7 @@ WHERE char *Tochars;
|
||||
WHERE char *TSStatusFormat;
|
||||
WHERE char *TSIconFormat;
|
||||
WHERE short TSSupported;
|
||||
+WHERE char *TrashPath;
|
||||
WHERE char *Username;
|
||||
WHERE char *Visual;
|
||||
|
||||
diff --git a/imap/message.c b/imap/message.c
|
||||
index 3877381..039fda6 100644
|
||||
--- a/imap/message.c
|
||||
+++ b/imap/message.c
|
||||
@@ -884,6 +884,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
|
||||
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);
|
||||
}
|
||||
@@ -891,6 +892,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
|
||||
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 --git a/init.h b/init.h
|
||||
index 6b49341..d3206f9 100644
|
||||
--- a/init.h
|
||||
+++ b/init.h
|
||||
@@ -3341,6 +3341,16 @@ struct option_t MuttVars[] = {
|
||||
** 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 --git a/mutt.h b/mutt.h
|
||||
index f8565fa..29bb6c2 100644
|
||||
--- a/mutt.h
|
||||
+++ b/mutt.h
|
||||
@@ -185,6 +185,7 @@ enum
|
||||
M_DELETE,
|
||||
M_UNDELETE,
|
||||
M_DELETED,
|
||||
+ M_APPENDED,
|
||||
M_FLAG,
|
||||
M_TAG,
|
||||
M_UNTAG,
|
||||
@@ -713,6 +714,7 @@ typedef struct header
|
||||
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 deleted : 1;
|
||||
unsigned int changed : 1;
|
||||
unsigned int attach_del : 1; /* has an attachment marked for deletion */
|
||||
@@ -885,6 +887,7 @@ typedef struct _context
|
||||
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 --git a/muttlib.c b/muttlib.c
|
||||
index 02067cc..0fd9766 100644
|
||||
--- a/muttlib.c
|
||||
+++ b/muttlib.c
|
||||
@@ -1505,7 +1505,9 @@ int mutt_save_confirm (const char *s, struct stat *st)
|
||||
|
||||
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 --git a/mx.c b/mx.c
|
||||
index 4c5cb07..c0a6d30 100644
|
||||
--- a/mx.c
|
||||
+++ b/mx.c
|
||||
@@ -776,6 +776,53 @@ static int sync_mailbox (CONTEXT *ctx, int *index_hint)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+/* 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++);
|
||||
+ 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 */
|
||||
+
|
||||
+ 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
|
||||
+ && 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 +959,7 @@ int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
|
||||
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 +984,14 @@ int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
|
||||
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)
|
||||
@@ -1133,6 +1189,12 @@ int mx_sync_mailbox (CONTEXT *ctx, int *index_hint)
|
||||
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 --git a/postpone.c b/postpone.c
|
||||
index a703161..7a4cbb1 100644
|
||||
--- a/postpone.c
|
||||
+++ b/postpone.c
|
||||
@@ -277,6 +277,9 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, char *fcc, size
|
||||
/* 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;
|
||||
|
797
pkgs/applications/networking/mailreaders/mutt/trash.patch
Normal file
797
pkgs/applications/networking/mailreaders/mutt/trash.patch
Normal file
|
@ -0,0 +1,797 @@
|
|||
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"><sync-mailbox></link> is called.
|
||||
+ This happens when the user leaves the folder, or the function is called
|
||||
+ manually.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ After <literal><sync-mailbox></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 <sync-mailbox> 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><purge-message></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>
|
||||
+
|
Loading…
Reference in a new issue