summary refs log tree commit diff
path: root/pkgs/applications
diff options
context:
space:
mode:
authorMoritz Ulrich <moritz@tarn-vedra.de>2015-09-29 00:23:55 +0200
committerMoritz Ulrich <moritz@tarn-vedra.de>2015-09-29 00:23:55 +0200
commit47c92a87c8236e7a514c4e20d9c56dbda34e463d (patch)
tree40c594d68e53147d607d4f997bb173c799f08d6d /pkgs/applications
parente916273209560b302ab231606babf5ce1c481f08 (diff)
downloadnixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.tar
nixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.tar.gz
nixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.tar.bz2
nixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.tar.lz
nixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.tar.xz
nixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.tar.zst
nixlib-47c92a87c8236e7a514c4e20d9c56dbda34e463d.zip
mutt: 1.5.23 -> 1.5.24
This change uses a different patchset for mutt-with-sidebar.
Diffstat (limited to 'pkgs/applications')
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/default.nix21
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar-compose.patch40
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar-delimnullwide.patch38
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar-dotpathsep.patch98
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar-new.patch97
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar-newonly.patch198
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar-utf8.patch132
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/sidebar.patch1477
-rw-r--r--pkgs/applications/networking/mailreaders/mutt/trash-folder.patch316
9 files changed, 2409 insertions, 8 deletions
diff --git a/pkgs/applications/networking/mailreaders/mutt/default.nix b/pkgs/applications/networking/mailreaders/mutt/default.nix
index 40d302464f62..a1bfb9f854c4 100644
--- a/pkgs/applications/networking/mailreaders/mutt/default.nix
+++ b/pkgs/applications/networking/mailreaders/mutt/default.nix
@@ -17,14 +17,14 @@ assert saslSupport -> cyrus_sasl != null;
 assert gpgmeSupport -> gpgme != null;
 
 let
-  version = "1.5.23";
+  version = "1.5.24";
 in
 stdenv.mkDerivation rec {
   name = "mutt${stdenv.lib.optionalString withSidebar "-with-sidebar"}-${version}";
 
   src = fetchurl {
-    url = "mirror://sourceforge/mutt/mutt-${version}.tar.gz";
-    sha256 = "0dzx4qk50pjfsb6cs5jahng96a52k12f7pm0sc78iqdrawg71w1s";
+    url = "http://ftp.mutt.org/pub/mutt/mutt-${version}.tar.gz";
+    sha256 = "0012njrgxf1barjksqkx7ccid2l0xyikhna9mjs9vcfpbrvcm4m2";
   };
 
   buildInputs = with stdenv.lib;
@@ -59,11 +59,16 @@ stdenv.mkDerivation rec {
   ];
 
   # Adding the sidebar
-  patches = [] ++
-    (stdenv.lib.optional withSidebar (fetchurl {
-      url = http://lunar-linux.org/~tchan/mutt/patch-1.5.23.sidebar.20140412.txt;
-      sha256 = "1i2r7dj0pd1k0z3jjxn2szi6sf0k28i8dwhr4f65pn8r2lh3wisz";
-    }));
+  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
+  ];
 
   meta = with stdenv.lib; {
     description = "A small but very powerful text-based mail client";
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar-compose.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar-compose.patch
new file mode 100644
index 000000000000..90d815b841d7
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar-compose.patch
@@ -0,0 +1,40 @@
+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);
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar-delimnullwide.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar-delimnullwide.patch
new file mode 100644
index 000000000000..11d2ced5a0c0
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar-delimnullwide.patch
@@ -0,0 +1,38 @@
+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;
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar-dotpathsep.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar-dotpathsep.patch
new file mode 100644
index 000000000000..315fa1649bcf
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar-dotpathsep.patch
@@ -0,0 +1,98 @@
+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,
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar-new.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar-new.patch
new file mode 100644
index 000000000000..fb2653463611
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar-new.patch
@@ -0,0 +1,97 @@
+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
+
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar-newonly.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar-newonly.patch
new file mode 100644
index 000000000000..d206848026b6
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar-newonly.patch
@@ -0,0 +1,198 @@
+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 ) {
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar-utf8.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar-utf8.patch
new file mode 100644
index 000000000000..d67e43c24b6e
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar-utf8.patch
@@ -0,0 +1,132 @@
+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])
diff --git a/pkgs/applications/networking/mailreaders/mutt/sidebar.patch b/pkgs/applications/networking/mailreaders/mutt/sidebar.patch
new file mode 100644
index 000000000000..262e8f98a65a
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/sidebar.patch
@@ -0,0 +1,1477 @@
+From: Antonio Radici <antonio@debian.org>
+Date: Tue, 4 Mar 2014 15:21:10 +0100
+Subject: sidebar
+
+When enabled, mutt will show a list of mailboxes with (new) message counts in a
+separate column on the left side of the screen.
+
+As this feature is still considered to be unstable, this patch is only applied
+in the "mutt-patched" package.
+
+* Configuration variables:
+
+  sidebar_delim (string, default "|")
+
+    This specifies the delimiter between the sidebar (if visible) and
+    other screens.
+
+  sidebar_visible (boolean, default no)
+
+    This specifies whether or not to show sidebar (left-side list of folders).
+
+  sidebar_width (integer, default 0)
+-
+    The width of the sidebar.
+
+* Patch source:
+  - http://www.lunar-linux.org/index.php?page=mutt-sidebar
+  - http://lunar-linux.org/~tchan/mutt/patch-1.5.19.sidebar.20090522.txt
+
+* Changes made:
+  - 2008-08-02 myon: Refreshed patch using quilt push -f to remove hunks we do
+    not need (Makefile.in).
+
+  - 2014-03-04 evgeni: refresh sidebar patch with the version from OpenBSD
+    Source:
+      ftp://ftp.openbsd.org/pub/OpenBSD/distfiles/mutt/sidebar-1.5.22.diff1.gz
+
+Signed-off-by: Matteo F. Vescovi <mfvescovi@gmail.com>
+Signed-off-by: Evgeni Golov <evgeni@debian.org>
+
+Gbp-Pq: Topic mutt-patched
+---
+ Makefile.am    |   1 +
+ OPS            |   5 +
+ buffy.c        | 124 +++++++++++++++++++++
+ buffy.h        |   4 +
+ color.c        |   2 +
+ compose.c      |  26 ++---
+ curs_main.c    |  30 +++++-
+ flags.c        |   3 +
+ functions.h    |  10 ++
+ globals.h      |   4 +
+ imap/command.c |   7 ++
+ imap/imap.c    |   2 +-
+ init.h         |  21 ++++
+ mailbox.h      |   1 +
+ mbox.c         |   2 +
+ menu.c         |  20 ++--
+ mh.c           |  22 ++++
+ mutt.h         |   4 +
+ mutt_curses.h  |   3 +
+ muttlib.c      |  48 +++++++++
+ mx.c           |  15 +++
+ mx.h           |   1 +
+ pager.c        |  30 ++++--
+ sidebar.c      | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ sidebar.h      |  36 +++++++
+ 25 files changed, 720 insertions(+), 34 deletions(-)
+ create mode 100644 sidebar.c
+ create mode 100644 sidebar.h
+
+diff --git a/Makefile.am b/Makefile.am
+index 5dfeff6..cf1ac98 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -33,6 +33,7 @@ mutt_SOURCES = \
+ 	rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
+ 	score.c send.c sendlib.c signal.c sort.c \
+ 	status.c system.c thread.c charset.c history.c lib.c \
++	sidebar.c \
+ 	muttlib.c editmsg.c mbyte.c \
+ 	url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c
+ 
+diff --git a/OPS b/OPS
+index 02cea8e..b036db9 100644
+--- a/OPS
++++ b/OPS
+@@ -180,3 +180,8 @@ OP_WHAT_KEY "display the keycode for a key press"
+ OP_MAIN_SHOW_LIMIT "show currently active limit pattern"
+ OP_MAIN_COLLAPSE_THREAD "collapse/uncollapse current thread"
+ OP_MAIN_COLLAPSE_ALL "collapse/uncollapse all threads"
++OP_SIDEBAR_SCROLL_UP "scroll the mailbox pane up 1 page"
++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"
+diff --git a/buffy.c b/buffy.c
+index 12a16d1..90ca6db 100644
+--- a/buffy.c
++++ b/buffy.c
+@@ -161,6 +161,49 @@ void mutt_buffy_cleanup (const char *buf, struct stat *st)
+   }
+ }
+ 
++static int buffy_compare_name(const void *a, const void *b) {
++  const BUFFY *b1 = * (BUFFY * const *) a;
++  const BUFFY *b2 = * (BUFFY * const *) b;
++
++  return mutt_strcoll(b1->path, b2->path);
++}
++
++static BUFFY *buffy_sort(BUFFY *b)
++{
++  BUFFY *tmp = b;
++  int buffycount = 0;
++  BUFFY **ary;
++  int i;
++
++  if (!option(OPTSIDEBARSORT))
++    return b;
++
++  for (; tmp != NULL; tmp = tmp->next)
++    buffycount++;
++
++  ary = (BUFFY **) safe_calloc(buffycount, sizeof (*ary));
++
++  tmp = b;
++  for (i = 0; tmp != NULL; tmp = tmp->next, i++) {
++    ary[i] = tmp;
++  }
++
++  qsort(ary, buffycount, sizeof(*ary), buffy_compare_name);
++
++  for (i = 0; i < buffycount - 1; i++) {
++    ary[i]->next = ary[i+1];
++  }
++  ary[buffycount - 1]->next = NULL;
++  for (i = 1; i < buffycount; i++) {
++    ary[i]->prev = ary[i-1];
++  }
++  ary[0]->prev = NULL;
++
++  tmp = ary[0];
++  free(ary);
++  return tmp;
++}
++
+ BUFFY *mutt_find_mailbox (const char *path)
+ {
+   BUFFY *tmp = NULL;
+@@ -282,6 +325,7 @@ int mutt_parse_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER *e
+     else
+       (*tmp)->size = 0;
+   }
++  Incoming = buffy_sort(Incoming);
+   return 0;
+ }
+ 
+@@ -357,6 +401,69 @@ static int buffy_maildir_hasnew (BUFFY* mailbox)
+ 
+   return 0;
+ }
++
++/* update message counts for the sidebar */
++void buffy_maildir_update (BUFFY* mailbox)
++{
++  char path[_POSIX_PATH_MAX];
++  DIR *dirp;
++  struct dirent *de;
++  char *p;
++
++  mailbox->msgcount = 0;
++  mailbox->msg_unread = 0;
++  mailbox->msg_flagged = 0;
++
++  snprintf (path, sizeof (path), "%s/new", mailbox->path);
++        
++  if ((dirp = opendir (path)) == NULL)
++  {   
++    mailbox->magic = 0;
++    return;
++  } 
++      
++  while ((de = readdir (dirp)) != NULL)
++  {
++    if (*de->d_name == '.')
++      continue;
++
++    if (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')) {
++      mailbox->new = 1;
++      mailbox->msgcount++;
++      mailbox->msg_unread++;
++    }
++  }
++
++  closedir (dirp);
++  snprintf (path, sizeof (path), "%s/cur", mailbox->path);
++        
++  if ((dirp = opendir (path)) == NULL)
++  {   
++    mailbox->magic = 0;
++    return;
++  } 
++      
++  while ((de = readdir (dirp)) != NULL)
++  {
++    if (*de->d_name == '.')
++      continue;
++
++    if (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')) {
++      mailbox->msgcount++;
++      if ((p = strstr (de->d_name, ":2,"))) {
++        if (!strchr (p + 3, 'T')) {
++          if (!strchr (p + 3, 'S'))
++            mailbox->msg_unread++;
++          if (strchr(p + 3, 'F'))
++            mailbox->msg_flagged++;
++        }
++      }
++    }
++  }
++
++  closedir (dirp);
++}
++
+ /* returns 1 if mailbox has new mail */ 
+ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb)
+ {
+@@ -388,6 +495,20 @@ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb)
+   return rc;
+ }
+ 
++/* update message counts for the sidebar */
++void buffy_mbox_update (BUFFY* mailbox)
++{
++  CONTEXT *ctx = NULL;
++
++  ctx = mx_open_mailbox(mailbox->path, M_READONLY | M_QUIET | M_NOSORT | M_PEEK, NULL);
++  if(ctx)
++  {
++    mailbox->msgcount = ctx->msgcount;
++    mailbox->msg_unread = ctx->unread;
++    mx_close_mailbox(ctx, 0);
++  }
++}
++
+ int mutt_buffy_check (int force)
+ {
+   BUFFY *tmp;
+@@ -461,16 +582,19 @@ int mutt_buffy_check (int force)
+       {
+       case M_MBOX:
+       case M_MMDF:
++	buffy_mbox_update (tmp);
+ 	if (buffy_mbox_hasnew (tmp, &sb) > 0)
+ 	  BuffyCount++;
+ 	break;
+ 
+       case M_MAILDIR:
++	buffy_maildir_update (tmp);
+ 	if (buffy_maildir_hasnew (tmp) > 0)
+ 	  BuffyCount++;
+ 	break;
+ 
+       case M_MH:
++	mh_buffy_update (tmp->path, &tmp->msgcount, &tmp->msg_unread, &tmp->msg_flagged);
+ 	mh_buffy(tmp);
+ 	if (tmp->new)
+ 	  BuffyCount++;
+diff --git a/buffy.h b/buffy.h
+index f9fc55a..672d178 100644
+--- a/buffy.h
++++ b/buffy.h
+@@ -25,7 +25,11 @@ typedef struct buffy_t
+   char path[_POSIX_PATH_MAX];
+   off_t size;
+   struct buffy_t *next;
++  struct buffy_t *prev;
+   short new;			/* mailbox has new mail */
++  int msgcount;			/* total number of messages */
++  int msg_unread;		/* number of unread messages */
++  int msg_flagged;		/* number of flagged messages */
+   short notified;		/* user has been notified */
+   short magic;			/* mailbox type */
+   short newly_created;		/* mbox or mmdf just popped into existence */
+diff --git a/color.c b/color.c
+index 64a46dc..d6f9198 100644
+--- a/color.c
++++ b/color.c
+@@ -94,6 +94,8 @@ static const struct mapping_t Fields[] =
+   { "underline",	MT_COLOR_UNDERLINE },
+   { "index",		MT_COLOR_INDEX },
+   { "prompt",		MT_COLOR_PROMPT },
++  { "sidebar_new",	MT_COLOR_NEW },
++  { "sidebar_flagged",	MT_COLOR_FLAGGED },
+   { NULL,		0 }
+ };
+ 
+diff --git a/compose.c b/compose.c
+index 9d87060..b63695f 100644
+--- a/compose.c
++++ b/compose.c
+@@ -72,7 +72,7 @@ enum
+ 
+ #define HDR_XOFFSET 10
+ #define TITLE_FMT "%10s" /* Used for Prompts, which are ASCII */
+-#define W (COLS - HDR_XOFFSET)
++#define W (COLS - HDR_XOFFSET - SidebarWidth)
+ 
+ static const char * const Prompts[] =
+ {
+@@ -110,7 +110,7 @@ static void snd_entry (char *b, size_t blen, MUTTMENU *menu, int num)
+ 
+ static void redraw_crypt_lines (HEADER *msg)
+ {
+-  mvaddstr (HDR_CRYPT, 0, "Security: ");
++  mvaddstr (HDR_CRYPT, SidebarWidth, "Security: ");
+ 
+   if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0)
+   {
+@@ -145,7 +145,7 @@ static void redraw_crypt_lines (HEADER *msg)
+       addstr (_(" (OppEnc mode)"));
+ 
+   clrtoeol ();
+-  move (HDR_CRYPTINFO, 0);
++  move (HDR_CRYPTINFO, SidebarWidth);
+   clrtoeol ();
+ 
+   if ((WithCrypto & APPLICATION_PGP)
+@@ -162,7 +162,7 @@ static void redraw_crypt_lines (HEADER *msg)
+       && (msg->security & ENCRYPT)
+       && SmimeCryptAlg
+       && *SmimeCryptAlg) {
+-      mvprintw (HDR_CRYPTINFO, 40, "%s%s", _("Encrypt with: "),
++      mvprintw (HDR_CRYPTINFO, SidebarWidth + 40, "%s%s", _("Encrypt with: "),
+ 		NONULL(SmimeCryptAlg));
+   }
+ }
+@@ -175,7 +175,7 @@ static void redraw_mix_line (LIST *chain)
+   int c;
+   char *t;
+ 
+-  mvaddstr (HDR_MIX, 0,     "     Mix: ");
++  mvaddstr (HDR_MIX, SidebarWidth,     "     Mix: ");
+ 
+   if (!chain)
+   {
+@@ -190,7 +190,7 @@ static void redraw_mix_line (LIST *chain)
+     if (t && t[0] == '0' && t[1] == '\0')
+       t = "<random>";
+     
+-    if (c + mutt_strlen (t) + 2 >= COLS)
++    if (c + mutt_strlen (t) + 2 >= COLS - SidebarWidth)
+       break;
+ 
+     addstr (NONULL(t));
+@@ -242,7 +242,7 @@ static void draw_envelope_addr (int line, ADDRESS *addr)
+ 
+   buf[0] = 0;
+   rfc822_write_address (buf, sizeof (buf), addr, 1);
+-  mvprintw (line, 0, TITLE_FMT, Prompts[line - 1]);
++  mvprintw (line, SidebarWidth, TITLE_FMT, Prompts[line - 1]);
+   mutt_paddstr (W, buf);
+ }
+ 
+@@ -252,10 +252,10 @@ static void draw_envelope (HEADER *msg, char *fcc)
+   draw_envelope_addr (HDR_TO, msg->env->to);
+   draw_envelope_addr (HDR_CC, msg->env->cc);
+   draw_envelope_addr (HDR_BCC, msg->env->bcc);
+-  mvprintw (HDR_SUBJECT, 0, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
++  mvprintw (HDR_SUBJECT, SidebarWidth, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
+   mutt_paddstr (W, NONULL (msg->env->subject));
+   draw_envelope_addr (HDR_REPLYTO, msg->env->reply_to);
+-  mvprintw (HDR_FCC, 0, TITLE_FMT, Prompts[HDR_FCC - 1]);
++  mvprintw (HDR_FCC, SidebarWidth, TITLE_FMT, Prompts[HDR_FCC - 1]);
+   mutt_paddstr (W, fcc);
+ 
+   if (WithCrypto)
+@@ -266,7 +266,7 @@ static void draw_envelope (HEADER *msg, char *fcc)
+ #endif
+ 
+   SETCOLOR (MT_COLOR_STATUS);
+-  mvaddstr (HDR_ATTACH - 1, 0, _("-- Attachments"));
++  mvaddstr (HDR_ATTACH - 1, SidebarWidth, _("-- Attachments"));
+   clrtoeol ();
+ 
+   NORMAL_COLOR;
+@@ -302,7 +302,7 @@ static int edit_address_list (int line, ADDRESS **addr)
+   /* redraw the expanded list so the user can see the result */
+   buf[0] = 0;
+   rfc822_write_address (buf, sizeof (buf), *addr, 1);
+-  move (line, HDR_XOFFSET);
++  move (line, HDR_XOFFSET+SidebarWidth);
+   mutt_paddstr (W, buf);
+   
+   return 0;
+@@ -562,7 +562,7 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
+ 	if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0)
+ 	{
+ 	  mutt_str_replace (&msg->env->subject, buf);
+-	  move (HDR_SUBJECT, HDR_XOFFSET);
++	  move (HDR_SUBJECT, HDR_XOFFSET + SidebarWidth);
+ 	  if (msg->env->subject)
+ 	    mutt_paddstr (W, msg->env->subject);
+ 	  else
+@@ -580,7 +580,7 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
+ 	{
+ 	  strfcpy (fcc, buf, fcclen);
+ 	  mutt_pretty_mailbox (fcc, fcclen);
+-	  move (HDR_FCC, HDR_XOFFSET);
++	  move (HDR_FCC, HDR_XOFFSET + SidebarWidth);
+ 	  mutt_paddstr (W, fcc);
+ 	  fccSet = 1;
+ 	}
+diff --git a/curs_main.c b/curs_main.c
+index 9d718ee..ea530a6 100644
+--- a/curs_main.c
++++ b/curs_main.c
+@@ -26,7 +26,9 @@
+ #include "mailbox.h"
+ #include "mapping.h"
+ #include "sort.h"
++#include "buffy.h"
+ #include "mx.h"
++#include "sidebar.h"
+ 
+ #ifdef USE_POP
+ #include "pop.h"
+@@ -596,8 +598,12 @@ int mutt_index_menu (void)
+        menu->redraw |= REDRAW_STATUS;
+      if (do_buffy_notify)
+      {
+-       if (mutt_buffy_notify () && option (OPTBEEPNEW))
+- 	beep ();
++       if (mutt_buffy_notify ())
++       {
++         menu->redraw |= REDRAW_FULL;
++         if (option (OPTBEEPNEW))
++           beep ();
++       }
+      }
+      else
+        do_buffy_notify = 1;
+@@ -609,6 +615,7 @@ int mutt_index_menu (void)
+     if (menu->redraw & REDRAW_FULL)
+     {
+       menu_redraw_full (menu);
++      draw_sidebar(menu->menu);
+       mutt_show_error ();
+     }
+ 
+@@ -631,9 +638,12 @@ int mutt_index_menu (void)
+ 
+       if (menu->redraw & REDRAW_STATUS)
+       {
++	DrawFullLine = 1;
+ 	menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
++	DrawFullLine = 0;
+ 	move (option (OPTSTATUSONTOP) ? 0 : LINES-2, 0);
+ 	SETCOLOR (MT_COLOR_STATUS);
++	set_buffystats(Context);
+ 	mutt_paddstr (COLS, buf);
+ 	NORMAL_COLOR;
+ 	menu->redraw &= ~REDRAW_STATUS;
+@@ -653,7 +663,7 @@ int mutt_index_menu (void)
+ 	menu->oldcurrent = -1;
+ 
+       if (option (OPTARROWCURSOR))
+-	move (menu->current - menu->top + menu->offset, 2);
++	move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
+       else if (option (OPTBRAILLEFRIENDLY))
+ 	move (menu->current - menu->top + menu->offset, 0);
+       else
+@@ -1154,6 +1164,7 @@ int mutt_index_menu (void)
+ 	  menu->redraw = REDRAW_FULL;
+ 	break;
+ 
++      case OP_SIDEBAR_OPEN:
+       case OP_MAIN_CHANGE_FOLDER:
+       case OP_MAIN_NEXT_UNREAD_MAILBOX:
+ 
+@@ -1185,7 +1196,11 @@ int mutt_index_menu (void)
+ 	{
+ 	  mutt_buffy (buf, sizeof (buf));
+ 
+-	  if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
++          if ( op == OP_SIDEBAR_OPEN ) {
++              if(!CurBuffy)
++                break;
++            strncpy( buf, CurBuffy->path, sizeof(buf) );  
++	    } else if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
+ 	  {
+ 	    if (menu->menu == MENU_PAGER)
+ 	    {
+@@ -1203,6 +1218,7 @@ int mutt_index_menu (void)
+ 	}
+ 
+ 	mutt_expand_path (buf, sizeof (buf));
++        set_curbuffy(buf);
+ 	if (mx_get_magic (buf) <= 0)
+ 	{
+ 	  mutt_error (_("%s is not a mailbox."), buf);
+@@ -2306,6 +2322,12 @@ int mutt_index_menu (void)
+ 	mutt_what_key();
+ 	break;
+ 
++      case OP_SIDEBAR_SCROLL_UP:
++      case OP_SIDEBAR_SCROLL_DOWN:
++      case OP_SIDEBAR_NEXT:
++      case OP_SIDEBAR_PREV:
++        scroll_sidebar(op, menu->menu);
++        break;
+       default:
+ 	if (menu->menu == MENU_MAIN)
+ 	  km_error_key (MENU_MAIN);
+diff --git a/flags.c b/flags.c
+index 133fa35..48fb287 100644
+--- a/flags.c
++++ b/flags.c
+@@ -22,8 +22,10 @@
+ 
+ #include "mutt.h"
+ #include "mutt_curses.h"
++#include "mutt_menu.h"
+ #include "sort.h"
+ #include "mx.h"
++#include "sidebar.h"
+ 
+ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
+ {
+@@ -290,6 +292,7 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
+    */
+   if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged))
+     h->searched = 0;
++	draw_sidebar(0);
+ }
+ 
+ void mutt_tag_set_flag (int flag, int bf)
+diff --git a/functions.h b/functions.h
+index 26171a0..ef8937a 100644
+--- a/functions.h
++++ b/functions.h
+@@ -170,6 +170,11 @@ const struct binding_t OpMain[] = { /* map: index */
+   { "decrypt-save",		OP_DECRYPT_SAVE,		NULL },
+ 
+ 
++ { "sidebar-scroll-up",	OP_SIDEBAR_SCROLL_UP, NULL },
++ { "sidebar-scroll-down",	OP_SIDEBAR_SCROLL_DOWN, NULL },
++ { "sidebar-next",		OP_SIDEBAR_NEXT, NULL },
++ { "sidebar-prev",		OP_SIDEBAR_PREV, NULL },
++ { "sidebar-open",		OP_SIDEBAR_OPEN, NULL },
+   { NULL,			0,				NULL }
+ };
+ 
+@@ -274,6 +279,11 @@ const struct binding_t OpPager[] = { /* map: pager */
+ 
+   { "what-key",		OP_WHAT_KEY,		NULL },
+ 
++  { "sidebar-scroll-up",	OP_SIDEBAR_SCROLL_UP, NULL },
++  { "sidebar-scroll-down",	OP_SIDEBAR_SCROLL_DOWN, NULL },
++  { "sidebar-next",	OP_SIDEBAR_NEXT, NULL },
++  { "sidebar-prev",	OP_SIDEBAR_PREV, NULL },
++  { "sidebar-open", OP_SIDEBAR_OPEN, NULL },
+   { NULL,		0,				NULL }
+ };
+ 
+diff --git a/globals.h b/globals.h
+index 282fde3..004c795 100644
+--- a/globals.h
++++ b/globals.h
+@@ -118,6 +118,7 @@ WHERE short SearchContext;
+ WHERE char *SendCharset;
+ WHERE char *Sendmail;
+ WHERE char *Shell;
++WHERE char *SidebarDelim;
+ WHERE char *Signature;
+ WHERE char *SimpleSearch;
+ #if USE_SMTP
+@@ -214,6 +215,9 @@ WHERE short ScoreThresholdDelete;
+ WHERE short ScoreThresholdRead;
+ WHERE short ScoreThresholdFlag;
+ 
++WHERE struct buffy_t *CurBuffy INITVAL(0);
++WHERE short DrawFullLine INITVAL(0);
++WHERE short SidebarWidth;
+ #ifdef USE_IMAP
+ WHERE short ImapKeepalive;
+ WHERE short ImapPipelineDepth;
+diff --git a/imap/command.c b/imap/command.c
+index 32f8417..d68e3ab 100644
+--- a/imap/command.c
++++ b/imap/command.c
+@@ -1012,6 +1012,13 @@ static void cmd_parse_status (IMAP_DATA* idata, char* s)
+ 	     opened */
+ 	  status->uidnext = oldun;
+ 
++        /* Added to make the sidebar show the correct numbers */
++        if (status->messages)
++        {
++          inc->msgcount = status->messages;
++          inc->msg_unread = status->unseen;
++        }
++
+         FREE (&value);
+         return;
+       }
+diff --git a/imap/imap.c b/imap/imap.c
+index f476873..af3ac3d 100644
+--- a/imap/imap.c
++++ b/imap/imap.c
+@@ -1529,7 +1529,7 @@ int imap_buffy_check (int force)
+ 
+     imap_munge_mbox_name (munged, sizeof (munged), name);
+     snprintf (command, sizeof (command),
+-	      "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
++	      "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT MESSAGES)", munged);
+ 
+     if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0)
+     {
+diff --git a/init.h b/init.h
+index 35224c1..c664e5f 100644
+--- a/init.h
++++ b/init.h
+@@ -2030,6 +2030,27 @@ struct option_t MuttVars[] = {
+   ** not used.
+   ** (PGP only)
+   */
++  {"sidebar_delim", DT_STR, R_BOTH, UL &SidebarDelim, "|"},
++  /*
++  ** .pp
++  ** This specifies the delimiter between the sidebar (if visible) and 
++  ** other screens.
++  */
++  { "sidebar_visible", DT_BOOL, R_BOTH, OPTSIDEBAR, 0 },
++  /*
++  ** .pp
++  ** This specifies whether or not to show sidebar (left-side list of folders).
++  */
++  { "sidebar_sort", DT_BOOL, R_BOTH, OPTSIDEBARSORT, 0 },
++  /*
++  ** .pp
++  ** This specifies whether or not to sort the sidebar alphabetically.
++  */
++  { "sidebar_width", DT_NUM, R_BOTH, UL &SidebarWidth, 0 },
++  /*
++  ** .pp
++  ** The width of the sidebar.
++  */
+   { "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
+   /*
+   ** .pp
+diff --git a/mailbox.h b/mailbox.h
+index 2b2c9a1..000503d 100644
+--- a/mailbox.h
++++ b/mailbox.h
+@@ -27,6 +27,7 @@
+ #define M_NEWFOLDER	(1<<4) /* create a new folder - same as M_APPEND, but uses
+ 				* safe_fopen() for mbox-style folders.
+ 				*/
++#define M_PEEK		(1<<5) /* revert atime back after taking a look (if applicable) */
+ 
+ /* mx_open_new_message() */
+ #define M_ADD_FROM	(1<<0)	/* add a From_ line */
+diff --git a/mbox.c b/mbox.c
+index 6d3b6bd..fa82eb3 100644
+--- a/mbox.c
++++ b/mbox.c
+@@ -104,6 +104,7 @@ int mmdf_parse_mailbox (CONTEXT *ctx)
+     mutt_perror (ctx->path);
+     return (-1);
+   }
++  ctx->atime = sb.st_atime;
+   ctx->mtime = sb.st_mtime;
+   ctx->size = sb.st_size;
+ 
+@@ -255,6 +256,7 @@ int mbox_parse_mailbox (CONTEXT *ctx)
+ 
+   ctx->size = sb.st_size;
+   ctx->mtime = sb.st_mtime;
++  ctx->atime = sb.st_atime;
+ 
+ #ifdef NFS_ATTRIBUTE_HACK
+   if (sb.st_mtime > sb.st_atime)
+diff --git a/menu.c b/menu.c
+index 27b5f8e..bc3a02f 100644
+--- a/menu.c
++++ b/menu.c
+@@ -24,6 +24,7 @@
+ #include "mutt_curses.h"
+ #include "mutt_menu.h"
+ #include "mbyte.h"
++#include "sidebar.h"
+ 
+ extern size_t UngetCount;
+ 
+@@ -186,7 +187,7 @@ static void menu_pad_string (char *s, size_t n)
+ {
+   char *scratch = safe_strdup (s);
+   int shift = option (OPTARROWCURSOR) ? 3 : 0;
+-  int cols = COLS - shift;
++  int cols = COLS - shift - SidebarWidth;
+ 
+   mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1);
+   s[n - 1] = 0;
+@@ -239,6 +240,7 @@ void menu_redraw_index (MUTTMENU *menu)
+   int do_color;
+   int attr;
+ 
++  draw_sidebar(1);
+   for (i = menu->top; i < menu->top + menu->pagelen; i++)
+   {
+     if (i < menu->max)
+@@ -249,7 +251,7 @@ void menu_redraw_index (MUTTMENU *menu)
+       menu_pad_string (buf, sizeof (buf));
+ 
+       ATTRSET(attr);
+-      move(i - menu->top + menu->offset, 0);
++      move(i - menu->top + menu->offset, SidebarWidth);
+       do_color = 1;
+ 
+       if (i == menu->current)
+@@ -272,7 +274,7 @@ void menu_redraw_index (MUTTMENU *menu)
+     else
+     {
+       NORMAL_COLOR;
+-      CLEARLINE(i - menu->top + menu->offset);
++      CLEARLINE_WIN(i - menu->top + menu->offset);
+     }
+   }
+   NORMAL_COLOR;
+@@ -289,7 +291,7 @@ void menu_redraw_motion (MUTTMENU *menu)
+     return;
+   }
+   
+-  move (menu->oldcurrent + menu->offset - menu->top, 0);
++  move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth);
+   ATTRSET(menu->color (menu->oldcurrent));
+ 
+   if (option (OPTARROWCURSOR))
+@@ -301,13 +303,13 @@ void menu_redraw_motion (MUTTMENU *menu)
+     {
+       menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
+       menu_pad_string (buf, sizeof (buf));
+-      move (menu->oldcurrent + menu->offset - menu->top, 3);
++      move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth + 3);
+       print_enriched_string (menu->color(menu->oldcurrent), (unsigned char *) buf, 1);
+     }
+ 
+     /* now draw it in the new location */
+     SETCOLOR(MT_COLOR_INDICATOR);
+-    mvaddstr(menu->current + menu->offset - menu->top, 0, "->");
++    mvaddstr(menu->current + menu->offset - menu->top, SidebarWidth, "->");
+   }
+   else
+   {
+@@ -320,7 +322,7 @@ void menu_redraw_motion (MUTTMENU *menu)
+     menu_make_entry (buf, sizeof (buf), menu, menu->current);
+     menu_pad_string (buf, sizeof (buf));
+     SETCOLOR(MT_COLOR_INDICATOR);
+-    move(menu->current - menu->top + menu->offset, 0);
++    move(menu->current - menu->top + menu->offset, SidebarWidth);
+     print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0);
+   }
+   menu->redraw &= REDRAW_STATUS;
+@@ -332,7 +334,7 @@ void menu_redraw_current (MUTTMENU *menu)
+   char buf[LONG_STRING];
+   int attr = menu->color (menu->current);
+   
+-  move (menu->current + menu->offset - menu->top, 0);
++  move (menu->current + menu->offset - menu->top, SidebarWidth);
+   menu_make_entry (buf, sizeof (buf), menu, menu->current);
+   menu_pad_string (buf, sizeof (buf));
+ 
+@@ -881,7 +883,7 @@ int mutt_menuLoop (MUTTMENU *menu)
+     
+     
+     if (option (OPTARROWCURSOR))
+-      move (menu->current - menu->top + menu->offset, 2);
++      move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
+     else if (option (OPTBRAILLEFRIENDLY))
+       move (menu->current - menu->top + menu->offset, 0);
+     else
+diff --git a/mh.c b/mh.c
+index 63e12d2..4a84a99 100644
+--- a/mh.c
++++ b/mh.c
+@@ -295,6 +295,28 @@ void mh_buffy(BUFFY *b)
+   mhs_free_sequences (&mhs);
+ }
+ 
++void mh_buffy_update (const char *path, int *msgcount, int *msg_unread, int *msg_flagged)
++{
++  int i;
++  struct mh_sequences mhs;
++  memset (&mhs, 0, sizeof (mhs));
++
++  if (mh_read_sequences (&mhs, path) < 0)
++    return;
++
++  msgcount = 0;
++  msg_unread = 0;
++  msg_flagged = 0;
++  for (i = 0; i <= mhs.max; i++)
++    msgcount++;
++  if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN) {
++    msg_unread++;
++  }
++  if (mhs_check (&mhs, i) & MH_SEQ_FLAGGED)
++    msg_flagged++;
++  mhs_free_sequences (&mhs);
++}
++
+ static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
+ {
+   int fd;
+diff --git a/mutt.h b/mutt.h
+index 01d47de..5f25406 100644
+--- a/mutt.h
++++ b/mutt.h
+@@ -435,6 +435,8 @@ enum
+   OPTSAVEEMPTY,
+   OPTSAVENAME,
+   OPTSCORE,
++  OPTSIDEBAR,
++  OPTSIDEBARSORT,
+   OPTSIGDASHES,
+   OPTSIGONTOP,
+   OPTSORTRE,
+@@ -880,6 +882,7 @@ typedef struct _context
+ {
+   char *path;
+   FILE *fp;
++  time_t atime;
+   time_t mtime;
+   off_t size;
+   off_t vsize;
+@@ -920,6 +923,7 @@ typedef struct _context
+   unsigned int quiet : 1;	/* inhibit status messages? */
+   unsigned int collapsed : 1;   /* are all threads collapsed? */
+   unsigned int closing : 1;	/* mailbox is being closed */
++  unsigned int peekonly : 1;	/* just taking a glance, revert atime */
+ 
+   /* driver hooks */
+   void *data;			/* driver specific data */
+diff --git a/mutt_curses.h b/mutt_curses.h
+index f8bc47c..ef9884e 100644
+--- a/mutt_curses.h
++++ b/mutt_curses.h
+@@ -64,6 +64,7 @@
+ #undef lines
+ #endif /* lines */
+ 
++#define CLEARLINE_WIN(x) move(x,SidebarWidth), clrtoeol()
+ #define CLEARLINE(x) move(x,0), clrtoeol()
+ #define CENTERLINE(x,y) move(y, (COLS-strlen(x))/2), addstr(x)
+ #define BEEP() do { if (option (OPTBEEP)) beep(); } while (0)
+@@ -121,6 +122,8 @@ enum
+   MT_COLOR_UNDERLINE,
+   MT_COLOR_INDEX,
+   MT_COLOR_PROMPT,
++  MT_COLOR_NEW,
++  MT_COLOR_FLAGGED,
+   MT_COLOR_MAX
+ };
+ 
+diff --git a/muttlib.c b/muttlib.c
+index c1d565f..039e7c3 100644
+--- a/muttlib.c
++++ b/muttlib.c
+@@ -1279,6 +1279,8 @@ void mutt_FormatString (char *dest,		/* output buffer */
+ 	  pl = pw = 1;
+ 
+ 	/* see if there's room to add content, else ignore */
++        if ( DrawFullLine )
++        {
+ 	if ((col < COLS && wlen < destlen) || soft)
+ 	{
+ 	  int pad;
+@@ -1322,6 +1324,52 @@ void mutt_FormatString (char *dest,		/* output buffer */
+ 	  col += wid;
+ 	  src += pl;
+ 	}
++        }
++        else
++        {
++	if ((col < COLS-SidebarWidth && wlen < destlen) || soft)
++        {
++	  int pad;
++
++	  /* get contents after padding */
++	  mutt_FormatString (buf, sizeof (buf), 0, src + pl, callback, data, flags);
++	  len = mutt_strlen (buf);
++	  wid = mutt_strwidth (buf);
++
++	  /* try to consume as many columns as we can, if we don't have
++	   * memory for that, use as much memory as possible */
++	  pad = (COLS - SidebarWidth - col - wid) / pw;
++	  if (pad > 0 && wlen + (pad * pl) + len > destlen)
++	    pad = ((signed)(destlen - wlen - len)) / pl;
++	  if (pad > 0)
++	  {
++	    while (pad--)
++	    {
++	      memcpy (wptr, src, pl);
++	      wptr += pl;
++	      wlen += pl;
++	      col += pw;
++	    }
++	  }
++	  else if (soft && pad < 0)
++	  {
++	    /* \0-terminate dest for length computation in mutt_wstr_trunc() */
++	    *wptr = 0;
++	    /* make sure right part is at most as wide as display */
++	    len = mutt_wstr_trunc (buf, destlen, COLS, &wid);
++	    /* truncate left so that right part fits completely in */
++	    wlen = mutt_wstr_trunc (dest, destlen - len, col + pad, &col);
++	    wptr = dest + wlen;
++	  }
++	  if (len + wlen > destlen)
++	    len = mutt_wstr_trunc (buf, destlen - wlen, COLS - SidebarWidth - col, NULL);
++	  memcpy (wptr, buf, len);
++	  wptr += len;
++	  wlen += len;
++	  col += wid;
++	  src += pl;
++	}
++        }
+ 	break; /* skip rest of input */
+       }
+       else if (ch == '|')
+diff --git a/mx.c b/mx.c
+index 0a1a80e..e80b8ff 100644
+--- a/mx.c
++++ b/mx.c
+@@ -595,6 +595,7 @@ static int mx_open_mailbox_append (CONTEXT *ctx, int flags)
+  *		M_APPEND	open mailbox for appending
+  *		M_READONLY	open mailbox in read-only mode
+  *		M_QUIET		only print error messages
++ *		M_PEEK		revert atime where applicable
+  *	ctx	if non-null, context struct to use
+  */
+ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
+@@ -617,6 +618,8 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
+     ctx->quiet = 1;
+   if (flags & M_READONLY)
+     ctx->readonly = 1;
++  if (flags & M_PEEK)
++    ctx->peekonly = 1;
+ 
+   if (flags & (M_APPEND|M_NEWFOLDER))
+   {
+@@ -721,9 +724,21 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
+ void mx_fastclose_mailbox (CONTEXT *ctx)
+ {
+   int i;
++#ifndef BUFFY_SIZE
++  struct utimbuf ut;
++#endif
+ 
+   if(!ctx) 
+     return;
++#ifndef BUFFY_SIZE
++  /* fix up the times so buffy won't get confused */
++  if (ctx->peekonly && ctx->path && ctx->mtime > ctx->atime)
++  {
++    ut.actime = ctx->atime;
++    ut.modtime = ctx->mtime;
++    utime (ctx->path, &ut); 
++  }
++#endif
+ 
+   /* never announce that a mailbox we've just left has new mail. #3290
+    * XXX: really belongs in mx_close_mailbox, but this is a nice hook point */
+diff --git a/mx.h b/mx.h
+index 2ef4ec7..4aabadf 100644
+--- a/mx.h
++++ b/mx.h
+@@ -60,6 +60,7 @@ void mbox_reset_atime (CONTEXT *, struct stat *);
+ int mh_read_dir (CONTEXT *, const char *);
+ int mh_sync_mailbox (CONTEXT *, int *);
+ int mh_check_mailbox (CONTEXT *, int *);
++void mh_buffy_update (const char *, int *, int *, int *);
+ int mh_check_empty (const char *);
+ 
+ int maildir_read_dir (CONTEXT *);
+diff --git a/pager.c b/pager.c
+index c99f1e4..5cfcb75 100644
+--- a/pager.c
++++ b/pager.c
+@@ -29,6 +29,7 @@
+ #include "pager.h"
+ #include "attach.h"
+ #include "mbyte.h"
++#include "sidebar.h"
+ 
+ #include "mutt_crypt.h"
+ 
+@@ -1095,6 +1096,7 @@ static int format_line (struct line_t **lineInfo, int n, unsigned char *buf,
+   wchar_t wc;
+   mbstate_t mbstate;
+   int wrap_cols = mutt_term_width ((flags & M_PAGER_NOWRAP) ? 0 : Wrap);
++  wrap_cols -= SidebarWidth;
+ 
+   if (check_attachment_marker ((char *)buf) == 0)
+     wrap_cols = COLS;
+@@ -1746,7 +1748,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
+     if ((redraw & REDRAW_BODY) || topline != oldtopline)
+     {
+       do {
+-	move (bodyoffset, 0);
++	move (bodyoffset, SidebarWidth);
+ 	curline = oldtopline = topline;
+ 	lines = 0;
+ 	force_redraw = 0;
+@@ -1759,6 +1761,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
+ 			    &QuoteList, &q_level, &force_redraw, &SearchRE) > 0)
+ 	    lines++;
+ 	  curline++;
++  	  move(lines + bodyoffset, SidebarWidth);
+ 	}
+ 	last_offset = lineInfo[curline].offset;
+       } while (force_redraw);
+@@ -1771,6 +1774,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
+ 	  addch ('~');
+ 	addch ('\n');
+ 	lines++;
++  	move(lines + bodyoffset, SidebarWidth);
+       }
+       NORMAL_COLOR;
+ 
+@@ -1794,22 +1798,22 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
+ 	strfcpy(pager_progress_str, (topline == 0) ? "all" : "end", sizeof(pager_progress_str));
+ 
+       /* print out the pager status bar */
+-      move (statusoffset, 0);
++      move (statusoffset, SidebarWidth);
+       SETCOLOR (MT_COLOR_STATUS);
+ 
+       if (IsHeader (extra) || IsMsgAttach (extra))
+       {
+-	size_t l1 = COLS * MB_LEN_MAX;
++	size_t l1 = (COLS-SidebarWidth) * MB_LEN_MAX;
+ 	size_t l2 = sizeof (buffer);
+ 	hfi.hdr = (IsHeader (extra)) ? extra->hdr : extra->bdy->hdr;
+ 	mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
+-	mutt_paddstr (COLS, buffer);
++	mutt_paddstr (COLS-SidebarWidth, buffer);
+       }
+       else
+       {
+ 	char bn[STRING];
+ 	snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
+-	mutt_paddstr (COLS, bn);
++	mutt_paddstr (COLS-SidebarWidth, bn);
+       }
+       NORMAL_COLOR;
+       if (option(OPTTSENABLED) && TSSupported)
+@@ -1826,16 +1830,21 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
+       /* redraw the pager_index indicator, because the
+        * flags for this message might have changed. */
+       menu_redraw_current (index);
++      draw_sidebar(MENU_PAGER);
+ 
+       /* print out the index status bar */
+       menu_status_line (buffer, sizeof (buffer), index, NONULL(Status));
+  
+-      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), 0);
++      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), SidebarWidth);
+       SETCOLOR (MT_COLOR_STATUS);
+-      mutt_paddstr (COLS, buffer);
++      mutt_paddstr (COLS-SidebarWidth, buffer);
+       NORMAL_COLOR;
+     }
+ 
++    /* if we're not using the index, update every time */
++    if ( index == 0 )
++      draw_sidebar(MENU_PAGER);
++
+     redraw = 0;
+ 
+     if (option(OPTBRAILLEFRIENDLY)) {
+@@ -2776,6 +2785,13 @@ search_next:
+ 	mutt_what_key ();
+ 	break;
+ 
++      case OP_SIDEBAR_SCROLL_UP:
++      case OP_SIDEBAR_SCROLL_DOWN:
++      case OP_SIDEBAR_NEXT:
++      case OP_SIDEBAR_PREV:
++	scroll_sidebar(ch, MENU_PAGER);
++ 	break;
++
+       default:
+ 	ch = -1;
+ 	break;
+diff --git a/sidebar.c b/sidebar.c
+new file mode 100644
+index 0000000..6098c2a
+--- /dev/null
++++ b/sidebar.c
+@@ -0,0 +1,333 @@
++/*
++ * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
++ * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
++ * 
++ *     This program is free software; you can redistribute it and/or modify
++ *     it under the terms of the GNU General Public License as published by
++ *     the Free Software Foundation; either version 2 of the License, or
++ *     (at your option) any later version.
++ * 
++ *     This program is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ * 
++ *     You should have received a copy of the GNU General Public License
++ *     along with this program; if not, write to the Free Software
++ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
++ */ 
++
++
++#if HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include "mutt.h"
++#include "mutt_menu.h"
++#include "mutt_curses.h"
++#include "sidebar.h"
++#include "buffy.h"
++#include <libgen.h>
++#include "keymap.h"
++#include <stdbool.h>
++
++/*BUFFY *CurBuffy = 0;*/
++static BUFFY *TopBuffy = 0;
++static BUFFY *BottomBuffy = 0;
++static int known_lines = 0;
++
++static int quick_log10(int n)
++{
++        char string[32];
++        sprintf(string, "%d", n);
++        return strlen(string);
++}
++
++void calc_boundaries (int menu)
++{
++	BUFFY *tmp = Incoming;
++
++	if ( known_lines != LINES ) {
++		TopBuffy = BottomBuffy = 0;
++		known_lines = LINES;
++	}
++	for ( ; tmp->next != 0; tmp = tmp->next )
++		tmp->next->prev = tmp;
++
++	if ( TopBuffy == 0 && BottomBuffy == 0 )
++		TopBuffy = Incoming;
++	if ( BottomBuffy == 0 ) {
++		int count = LINES - 2 - (menu != MENU_PAGER || option(OPTSTATUSONTOP));
++		BottomBuffy = TopBuffy;
++		while ( --count && BottomBuffy->next )
++			BottomBuffy = BottomBuffy->next;
++	}
++	else if ( TopBuffy == CurBuffy->next ) {
++		int count = LINES - 2 - (menu != MENU_PAGER);
++		BottomBuffy = CurBuffy;
++		tmp = BottomBuffy;
++		while ( --count && tmp->prev)
++			tmp = tmp->prev;
++		TopBuffy = tmp;
++	}
++	else if ( BottomBuffy == CurBuffy->prev ) {
++		int count = LINES - 2 - (menu != MENU_PAGER);
++		TopBuffy = CurBuffy;
++		tmp = TopBuffy;
++		while ( --count && tmp->next )
++			tmp = tmp->next;
++		BottomBuffy = tmp;
++	}
++}
++
++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;
++}
++
++void set_curbuffy(char buf[LONG_STRING])
++{
++  BUFFY* tmp = CurBuffy = Incoming;
++
++  if (!Incoming)
++    return;
++
++  while(1) {
++    if(!strcmp(tmp->path, buf)) {
++      CurBuffy = tmp;
++      break;
++    }
++
++    if(tmp->next)
++      tmp = tmp->next;
++    else
++      break;
++  }
++}
++
++int draw_sidebar(int menu) {
++
++	int lines = option(OPTHELP) ? 1 : 0;
++	BUFFY *tmp;
++#ifndef USE_SLANG_CURSES
++        attr_t attrs;
++#endif
++        short delim_len = strlen(SidebarDelim);
++        short color_pair;
++
++        static bool initialized = false;
++        static int prev_show_value;
++        static short saveSidebarWidth;
++
++        /* initialize first time */
++        if(!initialized) {
++                prev_show_value = option(OPTSIDEBAR);
++                saveSidebarWidth = SidebarWidth;
++                if(!option(OPTSIDEBAR)) SidebarWidth = 0;
++                initialized = true;
++        }
++
++        /* save or restore the value SidebarWidth */
++        if(prev_show_value != option(OPTSIDEBAR)) {
++                if(prev_show_value && !option(OPTSIDEBAR)) {
++                        saveSidebarWidth = SidebarWidth;
++                        SidebarWidth = 0;
++                } else if(!prev_show_value && option(OPTSIDEBAR)) {
++                        SidebarWidth = saveSidebarWidth;
++                }
++                prev_show_value = option(OPTSIDEBAR);
++        }
++
++
++//	if ( SidebarWidth == 0 ) return 0;
++       if (SidebarWidth > 0 && option (OPTSIDEBAR)
++           && delim_len >= SidebarWidth) {
++         unset_option (OPTSIDEBAR);
++         /* saveSidebarWidth = SidebarWidth; */
++         if (saveSidebarWidth > delim_len) {
++           SidebarWidth = saveSidebarWidth;
++           mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
++           sleep (2);
++         } else {
++           SidebarWidth = 0;
++           mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar. Please set your sidebar_width to a sane value."));
++           sleep (4); /* the advise to set a sane value should be seen long enough */
++         }
++         saveSidebarWidth = 0;
++         return (0);
++       }
++
++    if ( SidebarWidth == 0 || !option(OPTSIDEBAR)) {
++      if (SidebarWidth > 0) {
++        saveSidebarWidth = SidebarWidth;
++        SidebarWidth = 0;
++      }
++      unset_option(OPTSIDEBAR);
++      return 0;
++    }
++
++        /* get attributes for divider */
++	SETCOLOR(MT_COLOR_STATUS);
++#ifndef USE_SLANG_CURSES
++        attr_get(&attrs, &color_pair, 0);
++#else
++        color_pair = attr_get();
++#endif
++	SETCOLOR(MT_COLOR_NORMAL);
++
++	/* draw the divider */
++
++	for ( ; lines < LINES-1-(menu != MENU_PAGER || option(OPTSTATUSONTOP)); lines++ ) {
++		move(lines, SidebarWidth - delim_len);
++		addstr(NONULL(SidebarDelim));
++#ifndef USE_SLANG_CURSES
++                mvchgat(lines, SidebarWidth - delim_len, delim_len, 0, color_pair, NULL);
++#endif
++	}
++
++	if ( Incoming == 0 ) return 0;
++	lines = option(OPTHELP) ? 1 : 0; /* go back to the top */
++
++	if ( known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0 ) 
++		calc_boundaries(menu);
++	if ( CurBuffy == 0 ) CurBuffy = Incoming;
++
++	tmp = TopBuffy;
++
++	SETCOLOR(MT_COLOR_NORMAL);
++
++	for ( ; tmp && lines < LINES-1 - (menu != MENU_PAGER || option(OPTSTATUSONTOP)); tmp = tmp->next ) {
++		if ( tmp == CurBuffy )
++			SETCOLOR(MT_COLOR_INDICATOR);
++		else if ( tmp->msg_unread > 0 )
++			SETCOLOR(MT_COLOR_NEW);
++		else if ( tmp->msg_flagged > 0 )
++		        SETCOLOR(MT_COLOR_FLAGGED);
++		else
++			SETCOLOR(MT_COLOR_NORMAL);
++
++		move( lines, 0 );
++		if ( Context && !strcmp( tmp->path, Context->path ) ) {
++			tmp->msg_unread = Context->unread;
++			tmp->msgcount = Context->msgcount;
++			tmp->msg_flagged = Context->flagged;
++		}
++		// check whether Maildir is a prefix of the current folder's path
++		short maildir_is_prefix = 0;
++		if ( (strlen(tmp->path) > strlen(Maildir)) &&
++			(strncmp(Maildir, tmp->path, strlen(Maildir)) == 0) )
++        		maildir_is_prefix = 1;
++		// 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);
++		if ( maildir_is_prefix ) {
++			char *tmp_folder_name;
++			int i;
++			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++;
++			}   
++			if (sidebar_folder_depth > 0) {
++				sidebar_folder_name = malloc(strlen(basename(tmp->path)) + 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);
++			}
++		}
++		printw( "%.*s", SidebarWidth - delim_len + 1,
++			make_sidebar_entry(sidebar_folder_name, tmp->msgcount,
++			tmp->msg_unread, tmp->msg_flagged));
++		if (sidebar_folder_depth > 0)
++		        free(sidebar_folder_name);
++		lines++;
++	}
++	SETCOLOR(MT_COLOR_NORMAL);
++	for ( ; lines < LINES-1 - (menu != MENU_PAGER || option(OPTSTATUSONTOP)); lines++ ) {
++		int i = 0;
++		move( lines, 0 );
++		for ( ; i < SidebarWidth - delim_len; i++ )
++			addch(' ');
++	}
++	return 0;
++}
++
++
++void set_buffystats(CONTEXT* Context)
++{
++        BUFFY *tmp = Incoming;
++        while(tmp) {
++                if(Context && !strcmp(tmp->path, Context->path)) {
++			tmp->msg_unread = Context->unread;
++			tmp->msgcount = Context->msgcount;
++                        break;
++                }
++                tmp = tmp->next;
++        }
++}
++
++void scroll_sidebar(int op, int menu)
++{
++        if(!SidebarWidth) return;
++        if(!CurBuffy) return;
++
++	switch (op) {
++		case OP_SIDEBAR_NEXT:
++			if ( CurBuffy->next == NULL ) return;
++			CurBuffy = CurBuffy->next;
++			break;
++		case OP_SIDEBAR_PREV:
++			if ( CurBuffy->prev == NULL ) return;
++			CurBuffy = CurBuffy->prev;
++			break;
++		case OP_SIDEBAR_SCROLL_UP:
++			CurBuffy = TopBuffy;
++			if ( CurBuffy != Incoming ) {
++				calc_boundaries(menu);
++				CurBuffy = CurBuffy->prev;
++			}
++			break;
++		case OP_SIDEBAR_SCROLL_DOWN:
++			CurBuffy = BottomBuffy;
++			if ( CurBuffy->next ) {
++				calc_boundaries(menu);
++				CurBuffy = CurBuffy->next;
++			}
++			break;
++		default:
++			return;
++	}
++	calc_boundaries(menu);
++	draw_sidebar(menu);
++}
++
+diff --git a/sidebar.h b/sidebar.h
+new file mode 100644
+index 0000000..d195f11
+--- /dev/null
++++ b/sidebar.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
++ * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
++ * 
++ *     This program is free software; you can redistribute it and/or modify
++ *     it under the terms of the GNU General Public License as published by
++ *     the Free Software Foundation; either version 2 of the License, or
++ *     (at your option) any later version.
++ * 
++ *     This program is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ * 
++ *     You should have received a copy of the GNU General Public License
++ *     along with this program; if not, write to the Free Software
++ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
++ */ 
++
++#ifndef SIDEBAR_H
++#define SIDEBAR_H
++
++struct MBOX_LIST {
++	char *path;
++	int msgcount;
++	int new;
++} MBLIST;
++
++/* parameter is whether or not to go to the status line */
++/* used for omitting the last | that covers up the status bar in the index */
++int draw_sidebar(int);
++void scroll_sidebar(int, int);
++void set_curbuffy(char*);
++void set_buffystats(CONTEXT*);
++
++#endif /* SIDEBAR_H */
diff --git a/pkgs/applications/networking/mailreaders/mutt/trash-folder.patch b/pkgs/applications/networking/mailreaders/mutt/trash-folder.patch
new file mode 100644
index 000000000000..ce47b0c30e5d
--- /dev/null
+++ b/pkgs/applications/networking/mailreaders/mutt/trash-folder.patch
@@ -0,0 +1,316 @@
+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;
+