Merge pull request #16805 from rnhmjoj/mutt

mutt: 1.6.0 -> 1.6.2

joachifm 99039235 9aa3e78a

+40 -46
pkgs/applications/networking/mailreaders/mutt/default.nix
···
{ 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
}:
-
assert headerCache -> gdbm != null;
-
assert sslSupport -> openssl != null;
-
assert saslSupport -> cyrus_sasl != null;
-
assert gpgmeSupport -> gpgme != null;
-
let
-
version = "1.6.0";
-
in
stdenv.mkDerivation rec {
-
name = "mutt${stdenv.lib.optionalString withSidebar "-with-sidebar"}-${version}";
src = fetchurl {
-
url = "http://ftp.mutt.org/pub/mutt/mutt-${version}.tar.gz";
-
sha256 = "06bc2drbgalkk68rzg7hq2v5m5qgjxff5357wg0419dpi8ivdbr9";
};
-
buildInputs = with stdenv.lib;
[ ncurses which perl ]
-
++ optional headerCache gdbm
-
++ optional sslSupport openssl
-
++ optional saslSupport cyrus_sasl
-
++ optional gpgmeSupport gpgme;
-
-
nativeBuildInputs = stdenv.lib.optional withSidebar autoreconfHook;
configureFlags = [
-
"--with-mailpath=" "--enable-smtp"
# Look in $PATH at runtime, instead of hardcoding /usr/bin/sendmail
"ac_cv_path_SENDMAIL=sendmail"
···
# 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")
-
];
-
# 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
-
];
-
meta = with stdenv.lib; {
description = "A small but very powerful text-based mail client";
homepage = http://www.mutt.org;
-
license = stdenv.lib.licenses.gpl2Plus;
platforms = platforms.unix;
-
maintainers = with maintainers; [ the-kenny ];
};
}
···
{ stdenv, fetchurl, ncurses, which, perl, autoreconfHook
, gdbm ? null
, openssl ? null
, cyrus_sasl ? null
, gpgme ? null
+
, 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;
+
+
with stdenv.lib;
stdenv.mkDerivation rec {
+
name = "mutt-${version}";
+
version = "1.6.2";
src = fetchurl {
+
url = "http://ftp.mutt.org/pub/mutt/${name}.tar.gz";
+
sha256 = "13hxmji7v9m2agmvzrs7gzx8s3c9jiwrv7pbkr7z1kc6ckq2xl65";
};
+
buildInputs =
[ ncurses which perl ]
+
++ optional headerCache gdbm
+
++ optional sslSupport openssl
+
++ optional saslSupport cyrus_sasl
+
++ optional gpgmeSupport gpgme
+
++ optional withSidebar autoreconfHook;
configureFlags = [
+
(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"
···
# This allows calls with "-d N", that output debug info into ~/.muttdebug*
"--enable-debug"
# 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"
+
] ++ optional sslSupport "--with-ssl"
+
++ optional saslSupport "--with-sasl";
+
patches =
+
optional withTrash ./trash.patch ++
+
optional withSidebar ./sidebar.patch;
+
meta = {
description = "A small but very powerful text-based mail client";
homepage = http://www.mutt.org;
+
license = licenses.gpl2Plus;
platforms = platforms.unix;
+
maintainers = with maintainers; [ the-kenny rnhmjoj ];
};
}
-40
pkgs/applications/networking/mailreaders/mutt/sidebar-compose.patch
···
-
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);
···
-38
pkgs/applications/networking/mailreaders/mutt/sidebar-delimnullwide.patch
···
-
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;
···
-98
pkgs/applications/networking/mailreaders/mutt/sidebar-dotpathsep.patch
···
-
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,
···
-97
pkgs/applications/networking/mailreaders/mutt/sidebar-new.patch
···
-
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
-
···
-198
pkgs/applications/networking/mailreaders/mutt/sidebar-newonly.patch
···
-
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 ) {
···
-132
pkgs/applications/networking/mailreaders/mutt/sidebar-utf8.patch
···
-
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])
···
+3788 -815
pkgs/applications/networking/mailreaders/mutt/sidebar.patch
···
-
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 mutt_idna.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 */
···
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 ();
···
clrtoeol ();
if ((WithCrypto & APPLICATION_PGP)
-
@@ -162,7 +162,7 @@ static void redraw_crypt_lines (HEADER *msg)
&& (msg->security & ENCRYPT)
&& SmimeCryptAlg
&& *SmimeCryptAlg) {
···
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>";
···
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);
···
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);
···
mutt_paddstr (W, fcc);
if (WithCrypto)
-
@@ -266,7 +266,7 @@ static void draw_envelope (HEADER *msg, char *fcc)
#endif
SETCOLOR (MT_COLOR_STATUS);
···
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);
···
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);
···
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))
···
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;
···
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);
···
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;
}
···
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));
···
}
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);
···
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);
···
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))
···
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
···
* 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 {
···
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 -urN mutt-1.6.1/buffy.c mutt-1.6.1-sidebar/buffy.c
+
--- mutt-1.6.1/buffy.c 2016-06-12 18:43:00.397447512 +0100
+
+++ mutt-1.6.1-sidebar/buffy.c 2016-06-12 18:43:03.951502935 +0100
+
@@ -27,6 +27,10 @@
+
#include "mutt_curses.h"
+
+#ifdef USE_SIDEBAR
+
+#include "sidebar.h"
+
+#endif
+
+
#ifdef USE_IMAP
+
#include "imap.h"
+
#endif
+
@@ -196,9 +200,17 @@
+
static BUFFY *buffy_new (const char *path)
{
+
BUFFY* buffy;
+
+#ifdef USE_SIDEBAR
+
+ char rp[PATH_MAX] = "";
+
+ char *r = NULL;
+
+#endif
+
+
buffy = (BUFFY *) safe_calloc (1, sizeof (BUFFY));
+
strfcpy (buffy->path, path, sizeof (buffy->path));
+
+#ifdef USE_SIDEBAR
+
+ r = realpath (path, rp);
+
+ strfcpy (buffy->realpath, r ? rp : path, sizeof (buffy->realpath));
+
+#endif
+
buffy->next = NULL;
+
buffy->magic = 0;
+
+
@@ -215,7 +227,10 @@
+
BUFFY **tmp,*tmp1;
+
char buf[_POSIX_PATH_MAX];
+
struct stat sb;
+
- char f1[PATH_MAX], f2[PATH_MAX];
+
+ char f1[PATH_MAX];
+
+#ifndef USE_SIDEBAR
+
+ char f2[PATH_MAX];
+
+#endif
+
char *p, *q;
+
+
while (MoreArgs (s))
+
@@ -228,6 +243,9 @@
+
for (tmp = &Incoming; *tmp;)
+
{
+
tmp1=(*tmp)->next;
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_notify_mailbox (*tmp, 0);
+
+#endif
+
buffy_free (tmp);
+
*tmp=tmp1;
+
}
+
@@ -243,8 +261,13 @@
+
p = realpath (buf, f1);
+
for (tmp = &Incoming; *tmp; tmp = &((*tmp)->next))
+
{
+
+#ifdef USE_SIDEBAR
+
+ q = (*tmp)->realpath;
+
+ if (mutt_strcmp (p ? p : buf, q) == 0)
+
+#else
+
q = realpath ((*tmp)->path, f2);
+
if (mutt_strcmp (p ? p : buf, q ? q : (*tmp)->path) == 0)
+
+#endif
+
{
+
dprint(3,(debugfile,"mailbox '%s' already registered as '%s'\n", buf, (*tmp)->path));
+
break;
+
@@ -256,14 +279,21 @@
+
if(*tmp)
+
{
+
tmp1=(*tmp)->next;
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_notify_mailbox (*tmp, 0);
+
+#endif
+
buffy_free (tmp);
+
*tmp=tmp1;
+
}
+
continue;
+
}
+
+
- if (!*tmp)
+
+ if (!*tmp) {
+
*tmp = buffy_new (buf);
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_notify_mailbox (*tmp, 1);
+
+#endif
+
+ }
+
+
(*tmp)->new = 0;
+
(*tmp)->notified = 1;
+
@@ -306,6 +336,13 @@
+
return 0;
}
+
+#ifdef USE_SIDEBAR
+
+ if (option (OPTSIDEBAR) && mailbox->msg_unread > 0) {
+
+ mailbox->new = 1;
+
+ return 1;
+
+ }
+
+#endif
+
+
+
if ((dirp = opendir (path)) == NULL)
+
{
+
mailbox->magic = 0;
+
@@ -357,6 +394,93 @@
return 0;
}
+
+
+#ifdef USE_SIDEBAR
+
+/**
+
+ * buffy_maildir_update_dir - Update counts for one directory
+
+ * @mailbox: BUFFY representing a maildir mailbox
+
+ * @dir: Which directory to search
+
+ *
+
+ * Look through one directory of a maildir mailbox. The directory could
+
+ * be either "new" or "cur".
+
+ *
+
+ * Count how many new, or flagged, messages there are.
+
+ */
+
+static void
+
+buffy_maildir_update_dir (BUFFY *mailbox, const char *dir)
+{
+
+ char path[_POSIX_PATH_MAX] = "";
+
+ DIR *dirp = NULL;
+
+ struct dirent *de = NULL;
+
+ char *p = NULL;
+
+ int read;
+
+
+ snprintf (path, sizeof (path), "%s/%s", mailbox->path, dir);
+
+
+ dirp = opendir (path);
+
+ if (!dirp)
+
+ {
+ mailbox->magic = 0;
+ return;
+
+ }
+
+
+ while ((de = readdir (dirp)) != NULL)
+ {
+ if (*de->d_name == '.')
+ continue;
+
+
+ /* Matches maildir_parse_flags logic */
+
+ read = 0;
+
+ mailbox->msg_count++;
+
+ p = strstr (de->d_name, ":2,");
+
+ if (p)
+
+ {
+
+ p += 3;
+
+ if (strchr (p, 'S'))
+
+ read = 1;
+
+ if (strchr (p, 'F'))
+
+ mailbox->msg_flagged++;
+
+ }
+
+ if (!read) {
+ mailbox->msg_unread++;
+ }
+ }
+
+ closedir (dirp);
+
+}
+
+
+/**
+
+ * buffy_maildir_update - Update messages counts for a maildir mailbox
+
+ * @mailbox: BUFFY representing a maildir mailbox
+
+ *
+
+ * Open a mailbox directories and update our record of how many new, or
+
+ * flagged, messages there are.
+
+ */
+
+void
+
+buffy_maildir_update (BUFFY *mailbox)
+
+{
+
+ if (!option (OPTSIDEBAR))
+
+ return;
+
+
+ mailbox->msg_count = 0;
+
+ mailbox->msg_unread = 0;
+
+ mailbox->msg_flagged = 0;
+
+
+
+ buffy_maildir_update_dir (mailbox, "new");
+
+ if (mailbox->msg_count) {
+
+ mailbox->new = 1;
+
+ }
+
+ buffy_maildir_update_dir (mailbox, "cur");
+
+
+
+ mailbox->sb_last_checked = time (NULL);
+
+
+
+ /* make sure the updates are actually put on screen */
+
+ if (SidebarWidth)
+
+ mutt_sb_draw();
+}
+
+
+
+#endif
+
/* returns 1 if mailbox has new mail */
static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb)
{
+
@@ -368,7 +491,11 @@
+
else
+
statcheck = sb->st_mtime > sb->st_atime
+
|| (mailbox->newly_created && sb->st_ctime == sb->st_mtime && sb->st_ctime == sb->st_atime);
+
+#ifdef USE_SIDEBAR
+
+ if ((!option (OPTSIDEBAR) && statcheck) || (option (OPTSIDEBAR) && mailbox->msg_unread > 0))
+
+#else
+
if (statcheck)
+
+#endif
+
{
+
if (!option(OPTMAILCHECKRECENT) || sb->st_mtime > mailbox->last_visited)
+
{
+
@@ -388,6 +515,42 @@
return rc;
}
+
+#ifdef USE_SIDEBAR
+
+/**
+
+ * buffy_mbox_update - Update messages counts for an mbox mailbox
+
+ * @mailbox: BUFFY representing an mbox mailbox
+
+ * @sb: stat(2) infomation about the mailbox file
+
+ *
+
+ * Open a mbox file and update our record of how many new, or flagged,
+
+ * messages there are. If the mailbox hasn't changed since the last call,
+
+ * the function does nothing.
+
+ */
+
+void
+
+buffy_mbox_update (BUFFY *mailbox, struct stat *sb)
+{
+ CONTEXT *ctx = NULL;
+
+
+ if (!option (OPTSIDEBAR))
+
+ return;
+
+ if ((mailbox->sb_last_checked > sb->st_mtime) && (mailbox->msg_count != 0))
+
+ return; /* no check necessary */
+
+
+
+ ctx = mx_open_mailbox (mailbox->path, M_READONLY | M_QUIET | M_NOSORT | M_PEEK, NULL);
+
+ if (ctx)
+ {
+
+ mailbox->msg_count = ctx->msgcount;
+
+ mailbox->msg_unread = ctx->unread;
+
+ mailbox->msg_flagged = ctx->flagged;
+
+ mailbox->sb_last_checked = time (NULL);
+
+ mx_close_mailbox (ctx, 0);
+ }
+
+
+
+ /* make sure the updates are actually put on screen */
+
+ if (SidebarWidth)
+
+ mutt_sb_draw();
+}
+
+#endif
+
int mutt_buffy_check (int force)
{
BUFFY *tmp;
+
@@ -461,16 +623,25 @@
{
case M_MBOX:
case M_MMDF:
+
+#ifdef USE_SIDEBAR
+
+ buffy_mbox_update (tmp, &sb);
+
+#endif
if (buffy_mbox_hasnew (tmp, &sb) > 0)
BuffyCount++;
break;
case M_MAILDIR:
+
+#ifdef USE_SIDEBAR
+ buffy_maildir_update (tmp);
+
+#endif
if (buffy_maildir_hasnew (tmp) > 0)
BuffyCount++;
break;
case M_MH:
+
+#ifdef USE_SIDEBAR
+
+ mh_buffy_update (tmp);
+
+#endif
mh_buffy(tmp);
if (tmp->new)
BuffyCount++;
+
diff -urN mutt-1.6.1/buffy.h mutt-1.6.1-sidebar/buffy.h
+
--- mutt-1.6.1/buffy.h 2016-06-12 18:43:00.397447512 +0100
+
+++ mutt-1.6.1-sidebar/buffy.h 2016-06-12 18:43:03.951502935 +0100
+
@@ -16,6 +16,9 @@
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
*/
+
+
+#ifndef _BUFFY_H
+
+#define _BUFFY_H
+
+
+
/*parameter to mutt_parse_mailboxes*/
+
#define M_MAILBOXES 1
+
#define M_UNMAILBOXES 2
+
@@ -23,13 +26,28 @@
+
typedef struct buffy_t
+
{
char path[_POSIX_PATH_MAX];
+
+#ifdef USE_SIDEBAR
+
+ char realpath[_POSIX_PATH_MAX];
+
+#endif
off_t size;
struct buffy_t *next;
+
+#ifdef USE_SIDEBAR
+ struct buffy_t *prev;
+
+#endif
short new; /* mailbox has new mail */
+
+#ifdef USE_SIDEBAR
+
+ int msg_count; /* total number of messages */
+ int msg_unread; /* number of unread messages */
+ int msg_flagged; /* number of flagged messages */
+
+ short is_hidden; /* is hidden from the sidebar */
+
+#endif
short notified; /* user has been notified */
short magic; /* mailbox type */
short newly_created; /* mbox or mmdf just popped into existence */
+
time_t last_visited; /* time of last exit from this mailbox */
+
+#ifdef USE_SIDEBAR
+
+ time_t sb_last_checked; /* time of last buffy check from sidebar */
+
+#endif
+
}
+
BUFFY;
+
+
@@ -49,3 +67,5 @@
+
void mutt_buffy_setnotified (const char *path);
+
+
void mh_buffy (BUFFY *);
+
+
+
+#endif /* _BUFFY_H */
+
diff -urN mutt-1.6.1/color.c mutt-1.6.1-sidebar/color.c
+
--- mutt-1.6.1/color.c 2016-06-12 18:43:00.397447512 +0100
+
+++ mutt-1.6.1-sidebar/color.c 2016-06-12 18:43:03.951502935 +0100
+
@@ -94,6 +94,14 @@
{ "underline", MT_COLOR_UNDERLINE },
{ "index", MT_COLOR_INDEX },
{ "prompt", MT_COLOR_PROMPT },
+
+#ifdef USE_SIDEBAR
+
+ { "sidebar_divider", MT_COLOR_DIVIDER },
+
+ { "sidebar_flagged", MT_COLOR_FLAGGED },
+
+ { "sidebar_highlight",MT_COLOR_HIGHLIGHT },
+
+ { "sidebar_indicator",MT_COLOR_SB_INDICATOR },
+ { "sidebar_new", MT_COLOR_NEW },
+
+ { "sidebar_spoolfile",MT_COLOR_SB_SPOOLFILE },
+
+#endif
{ NULL, 0 }
};
+
@@ -146,6 +154,9 @@
+
ColorDefs[MT_COLOR_INDICATOR] = A_REVERSE;
+
ColorDefs[MT_COLOR_SEARCH] = A_REVERSE;
+
ColorDefs[MT_COLOR_MARKERS] = A_REVERSE;
+
+#ifdef USE_SIDEBAR
+
+ ColorDefs[MT_COLOR_HIGHLIGHT] = A_UNDERLINE;
+
+#endif
+
/* special meaning: toggle the relevant attribute */
+
ColorDefs[MT_COLOR_BOLD] = 0;
+
ColorDefs[MT_COLOR_UNDERLINE] = 0;
+
diff -urN mutt-1.6.1/compose.c mutt-1.6.1-sidebar/compose.c
+
--- mutt-1.6.1/compose.c 2016-06-12 18:43:00.398447528 +0100
+
+++ mutt-1.6.1-sidebar/compose.c 2016-06-12 18:43:03.952502951 +0100
+
@@ -32,6 +32,9 @@
+
#include "mailbox.h"
+
#include "sort.h"
+
#include "charset.h"
+
+#ifdef USE_SIDEBAR
+
+#include "sidebar.h"
+
+#endif
+
+
#ifdef MIXMASTER
+
#include "remailer.h"
+
@@ -72,7 +75,7 @@
#define HDR_XOFFSET 10
#define TITLE_FMT "%10s" /* Used for Prompts, which are ASCII */
···
static const char * const Prompts[] =
{
+
@@ -110,7 +113,7 @@
static void redraw_crypt_lines (HEADER *msg)
{
- mvaddstr (HDR_CRYPT, 0, "Security: ");
+
+ mvprintw (HDR_CRYPT, SidebarWidth, TITLE_FMT, "Security: ");
if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0)
{
+
@@ -145,16 +148,16 @@
addstr (_(" (OppEnc mode)"));
clrtoeol ();
···
clrtoeol ();
if ((WithCrypto & APPLICATION_PGP)
+
&& (msg->security & APPLICATION_PGP) && (msg->security & SIGN))
+
- printw ("%s%s", _(" sign as: "), PgpSignAs ? PgpSignAs : _("<default>"));
+
+ printw (TITLE_FMT "%s", _("sign as: "), PgpSignAs ? PgpSignAs : _("<default>"));
+
+
if ((WithCrypto & APPLICATION_SMIME)
+
&& (msg->security & APPLICATION_SMIME) && (msg->security & SIGN)) {
+
- printw ("%s%s", _(" sign as: "), SmimeDefaultKey ? SmimeDefaultKey : _("<default>"));
+
+ printw (TITLE_FMT "%s", _("sign as: "), SmimeDefaultKey ? SmimeDefaultKey : _("<default>"));
+
}
+
+
if ((WithCrypto & APPLICATION_SMIME)
+
@@ -162,7 +165,7 @@
&& (msg->security & ENCRYPT)
&& SmimeCryptAlg
&& *SmimeCryptAlg) {
···
NONULL(SmimeCryptAlg));
}
}
+
@@ -175,7 +178,8 @@
int c;
char *t;
- mvaddstr (HDR_MIX, 0, " Mix: ");
+
+ /* L10N: "Mix" refers to the MixMaster chain for anonymous email */
+
+ mvprintw (HDR_MIX, SidebarWidth, TITLE_FMT, _("Mix: "));
if (!chain)
{
+
@@ -190,7 +194,7 @@
if (t && t[0] == '0' && t[1] == '\0')
t = "<random>";
···
break;
addstr (NONULL(t));
+
@@ -242,20 +246,23 @@
buf[0] = 0;
rfc822_write_address (buf, sizeof (buf), addr, 1);
···
mutt_paddstr (W, buf);
}
+
static void draw_envelope (HEADER *msg, char *fcc)
+
{
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_draw();
+
+#endif
+
draw_envelope_addr (HDR_FROM, msg->env->from);
draw_envelope_addr (HDR_TO, msg->env->to);
draw_envelope_addr (HDR_CC, msg->env->cc);
draw_envelope_addr (HDR_BCC, msg->env->bcc);
···
mutt_paddstr (W, fcc);
if (WithCrypto)
+
@@ -266,7 +273,7 @@
#endif
SETCOLOR (MT_COLOR_STATUS);
···
clrtoeol ();
NORMAL_COLOR;
+
@@ -302,7 +309,7 @@
/* 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;
+
@@ -515,7 +522,7 @@
+
menu->tag = mutt_tag_attach;
+
menu->data = idx;
+
menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, ComposeHelp);
+
-
+
+
+
while (loop)
+
{
+
switch (op = mutt_menuLoop (menu))
+
@@ -564,7 +571,7 @@
if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0)
{
mutt_str_replace (&msg->env->subject, buf);
···
if (msg->env->subject)
mutt_paddstr (W, msg->env->subject);
else
+
@@ -582,7 +589,7 @@
{
strfcpy (fcc, buf, fcclen);
mutt_pretty_mailbox (fcc, fcclen);
···
mutt_paddstr (W, fcc);
fccSet = 1;
}
+
diff -urN mutt-1.6.1/configure.ac mutt-1.6.1-sidebar/configure.ac
+
--- mutt-1.6.1/configure.ac 2016-06-12 18:43:00.398447528 +0100
+
+++ mutt-1.6.1-sidebar/configure.ac 2016-06-12 18:43:03.952502951 +0100
+
@@ -175,6 +175,14 @@
+
SMIMEAUX_TARGET="smime_keys"
+
fi
+
+
+AC_ARG_ENABLE(sidebar, AC_HELP_STRING([--enable-sidebar], [Enable Sidebar support]),
+
+[ if test x$enableval = xyes ; then
+
+ AC_DEFINE(USE_SIDEBAR, 1, [Define if you want support for the sidebar.])
+
+ OPS="$OPS \$(srcdir)/OPS.SIDEBAR"
+
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS sidebar.o"
+
+ fi
+
+])
+
+
+
AC_ARG_WITH(mixmaster, AS_HELP_STRING([--with-mixmaster@<:@=PATH@:>@],[Include Mixmaster support]),
+
[if test "$withval" != no
+
then
+
diff -urN mutt-1.6.1/copy.c mutt-1.6.1-sidebar/copy.c
+
--- mutt-1.6.1/copy.c 2016-06-12 18:43:00.398447528 +0100
+
+++ mutt-1.6.1-sidebar/copy.c 2016-06-12 18:43:03.952502951 +0100
+
@@ -288,7 +288,8 @@
+
if (flags & (CH_DECODE|CH_PREFIX))
+
{
+
if (mutt_write_one_header (out, 0, headers[x],
+
- flags & CH_PREFIX ? prefix : 0, mutt_term_width (Wrap), flags) == -1)
+
+ flags & CH_PREFIX ? prefix : 0,
+
+ mutt_term_width (Wrap), flags) == -1)
+
{
+
error = TRUE;
+
break;
+
diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-sidebar/curs_main.c
+
--- mutt-1.6.1/curs_main.c 2016-06-12 18:43:00.399447544 +0100
+
+++ mutt-1.6.1-sidebar/curs_main.c 2016-06-12 18:43:03.953502966 +0100
+
@@ -26,8 +26,13 @@
#include "mailbox.h"
#include "mapping.h"
#include "sort.h"
+#include "buffy.h"
#include "mx.h"
+
+
+#ifdef USE_SIDEBAR
+#include "sidebar.h"
+
+#endif
+
+
#ifdef USE_POP
#include "pop.h"
+
#endif
+
@@ -595,21 +600,39 @@
menu->redraw |= REDRAW_STATUS;
if (do_buffy_notify)
{
- if (mutt_buffy_notify () && option (OPTBEEPNEW))
- beep ();
+
+ if (mutt_buffy_notify())
+ {
+
+ menu->redraw |= REDRAW_STATUS;
+ if (option (OPTBEEPNEW))
+
+ beep();
+ }
}
else
do_buffy_notify = 1;
+
}
+
+
+#ifdef USE_SIDEBAR
+
+ if (option (OPTSIDEBAR))
+
+ menu->redraw |= REDRAW_SIDEBAR;
+
+#endif
+
+
+
if (op != -1)
+
mutt_curs_set (0);
+
if (menu->redraw & REDRAW_FULL)
{
menu_redraw_full (menu);
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_draw();
+
+#endif
mutt_show_error ();
}
+
+#ifdef USE_SIDEBAR
+
+ else if (menu->redraw & REDRAW_SIDEBAR) {
+
+ mutt_sb_draw();
+
+ menu->redraw &= ~REDRAW_SIDEBAR;
+
+ }
+
+#endif
+
if (menu->menu == MENU_MAIN)
+
{
+
@@ -630,9 +653,20 @@
if (menu->redraw & REDRAW_STATUS)
{
+
+#ifdef USE_SIDEBAR
+
+ /* Temporarily lie about the sidebar width */
+
+ short sw = SidebarWidth;
+
+ SidebarWidth = 0;
+
+#endif
menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
+
+#ifdef USE_SIDEBAR
+
+ SidebarWidth = sw; /* Restore the sidebar width */
+
+#endif
move (option (OPTSTATUSONTOP) ? 0 : LINES-2, 0);
SETCOLOR (MT_COLOR_STATUS);
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_set_buffystats (Context);
+
+#endif
mutt_paddstr (COLS, buf);
NORMAL_COLOR;
menu->redraw &= ~REDRAW_STATUS;
+
@@ -652,7 +686,7 @@
menu->oldcurrent = -1;
if (option (OPTARROWCURSOR))
···
else if (option (OPTBRAILLEFRIENDLY))
move (menu->current - menu->top + menu->offset, 0);
else
+
@@ -1091,6 +1125,9 @@
+
break;
+
+
CHECK_MSGCOUNT;
+
+#ifdef USE_SIDEBAR
+
+ CHECK_VISIBLE;
+
+#endif
+
CHECK_READONLY;
+
{
+
int oldvcount = Context->vcount;
+
@@ -1150,6 +1187,9 @@
menu->redraw = REDRAW_FULL;
break;
+
+#ifdef USE_SIDEBAR
+ case OP_SIDEBAR_OPEN:
+
+#endif
case OP_MAIN_CHANGE_FOLDER:
case OP_MAIN_NEXT_UNREAD_MAILBOX:
+
@@ -1181,6 +1221,14 @@
{
mutt_buffy (buf, sizeof (buf));
+
+#ifdef USE_SIDEBAR
+
+ if (op == OP_SIDEBAR_OPEN) {
+
+ const char *path = mutt_sb_get_highlight();
+
+ if (!path)
+
+ break;
+
+ strncpy (buf, path, sizeof (buf));
+
+ } else
+
+#endif
+
if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
{
if (menu->menu == MENU_PAGER)
+
@@ -1199,6 +1247,9 @@
}
mutt_expand_path (buf, sizeof (buf));
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_set_open_buffy (buf);
+
+#endif
if (mx_get_magic (buf) <= 0)
{
mutt_error (_("%s is not a mailbox."), buf);
+
@@ -2310,6 +2361,21 @@
mutt_what_key();
break;
+
+#ifdef USE_SIDEBAR
+ case OP_SIDEBAR_NEXT:
+
+ case OP_SIDEBAR_NEXT_NEW:
+
+ case OP_SIDEBAR_PAGE_DOWN:
+
+ case OP_SIDEBAR_PAGE_UP:
+ case OP_SIDEBAR_PREV:
+
+ case OP_SIDEBAR_PREV_NEW:
+
+ mutt_sb_change_mailbox (op);
+ break;
+
+
+
+ case OP_SIDEBAR_TOGGLE_VISIBLE:
+
+ toggle_option (OPTSIDEBAR);
+
+ menu->redraw = REDRAW_FULL;
+
+ break;
+
+#endif
default:
if (menu->menu == MENU_MAIN)
km_error_key (MENU_MAIN);
+
diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-sidebar/doc/manual.xml.head
+
--- mutt-1.6.1/doc/manual.xml.head 2016-06-12 18:43:00.402447590 +0100
+
+++ mutt-1.6.1-sidebar/doc/manual.xml.head 2016-06-12 18:43:03.955502998 +0100
+
@@ -405,6 +405,623 @@
+
+
</sect2>
+
+
+<sect2 id="intro-sidebar">
+
+ <title>Sidebar</title>
+
+ <para>
+
+ The Sidebar shows a list of all your mailboxes. The list can be
+
+ turned on and off, it can be themed and the list style can be
+
+ configured.
+
+ </para>
+
+ <para>
+
+ This part of the manual is suitable for beginners.
+
+ If you already know Mutt you could skip ahead to the main
+
+ <link linkend="sidebar">Sidebar guide</link>.
+
+ If you just want to get started, you could use the sample
+
+ <link linkend="sidebar-muttrc">Sidebar muttrc</link>.
+
+ </para>
+
+ <para>
+
+ This version of Sidebar is based on Terry Chan's
+
+ <ulink url="http://www.lunar-linux.org/mutt-sidebar/">2015-11-11 release</ulink>.
+
+ It contains many
+
+ <emphasis role="bold"><link linkend="intro-sidebar-features">new features</link></emphasis>,
+
+ lots of
+
+ <emphasis role="bold"><link linkend="intro-sidebar-bugfixes">bugfixes</link></emphasis>
+
+ and a generous helping of
+
+ <emphasis role="bold">new documentation</emphasis> which you are already reading.
+
+ </para>
+
+ <para>
+
+ To check if Mutt supports <quote>Sidebar</quote>, look for the string
+
+ <literal>+USE_SIDEBAR</literal> in the mutt version.
+
+ </para>
+
+<screen>
+
+mutt -v
+
+</screen>
+
+ <para>
+
+ <emphasis role="bold">Let's turn on the Sidebar:</emphasis>
+
+ </para>
+
+ <screen>set sidebar_visible</screen>
+
+ <para>
+
+ You will see something like this.
+
+ A list of mailboxes on the left.
+
+ A list of emails, from the selected mailbox, on the right.
+
+ </para>
+
+<screen>
+
+<emphasis role="indicator">Fruit [1] 3/8</emphasis>| 1 + Jan 24 Rhys Lee (192) Yew
+
+Animals [1] 2/6| 2 + Feb 11 Grace Hall (167) Ilama
+
+Cars 4| 3 Feb 23 Aimee Scott (450) Nectarine
+
+Seas 1/7| 4 ! Feb 28 Summer Jackson (264) Lemon
+
+ | 5 Mar 07 Callum Harrison (464) Raspberry
+
+ |<emphasis role="indicator"> 6 N + Mar 24 Samuel Harris (353) Tangerine </emphasis>
+
+ | 7 N + Sep 05 Sofia Graham (335) Cherry
+
+ | 8 N Sep 16 Ewan Brown (105) Ugli
+
+ |
+
+ |
+
+</screen>
+
+<para>
+
+ This user has four mailboxes: <quote>Fruit</quote>,
+
+ <quote>Cars</quote>, <quote>Animals</quote> and
+
+ <quote>Seas</quote>.
+
+</para>
+
+<para>
+
+ The current, open, mailbox is <quote>Fruit</quote>. We can
+
+ also see information about the other mailboxes. For example:
+
+ The <quote>Animals</quote> mailbox contains, 1 flagged email, 2
+
+ new emails out of a total of 6 emails.
+
+</para>
+
+ <sect3 id="intro-sidebar-navigation">
+
+ <title>Navigation</title>
+
+ <para>
+
+ The Sidebar adds some new <link linkend="sidebar-functions">functions</link>
+
+ to Mutt.
+
+ </para>
+
+ <para>
+
+ The user pressed the <quote>c</quote> key to
+
+ <literal>&lt;change-folder&gt;</literal> to the
+
+ <quote>Animals</quote> mailbox. The Sidebar automatically
+
+ updated the indicator to match.
+
+ </para>
+
+<screen>
+
+Fruit [1] 3/8| 1 Jan 03 Tia Gibson (362) Caiman
+
+<emphasis role="indicator">Animals [1] 2/6</emphasis>| 2 + Jan 22 Rhys Lee ( 48) Dolphin
+
+Cars 4| 3 ! Aug 16 Ewan Brown (333) Hummingbird
+
+Seas 1/7| 4 Sep 25 Grace Hall ( 27) Capybara
+
+ |<emphasis role="indicator"> 5 N + Nov 12 Evelyn Rogers (453) Tapir </emphasis>
+
+ | 6 N + Nov 16 Callum Harrison (498) Hedgehog
+
+ |
+
+ |
+
+ |
+
+ |
+
+</screen>
+
+ <para>
+
+ Let's map some functions:
+
+ </para>
+
+<screen>
+
+bind index,pager \CP sidebar-prev <emphasis role="comment"># Ctrl-Shift-P - Previous Mailbox</emphasis>
+
+bind index,pager \CN sidebar-next <emphasis role="comment"># Ctrl-Shift-N - Next Mailbox</emphasis>
+
+bind index,pager \CO sidebar-open <emphasis role="comment"># Ctrl-Shift-O - Open Highlighted Mailbox</emphasis>
+
+</screen>
+
+ <para>
+
+ Press <quote>Ctrl-Shift-N</quote> (Next mailbox) twice will
+
+ move the Sidebar <emphasis role="bold">highlight</emphasis> to
+
+ down to the <quote>Seas</quote> mailbox.
+
+ </para>
+
+<screen>
+
+Fruit [1] 3/8| 1 Jan 03 Tia Gibson (362) Caiman
+
+<emphasis role="indicator">Animals [1] 2/6</emphasis>| 2 + Jan 22 Rhys Lee ( 48) Dolphin
+
+Cars 4| 3 ! Aug 16 Ewan Brown (333) Hummingbird
+
+<emphasis role="highlight">Seas 1/7</emphasis>| 4 Sep 25 Grace Hall ( 27) Capybara
+
+ |<emphasis role="indicator"> 5 N + Nov 12 Evelyn Rogers (453) Tapir </emphasis>
+
+ | 6 N + Nov 16 Callum Harrison (498) Hedgehog
+
+ |
+
+ |
+
+ |
+
+ |
+
+</screen>
+
+ <note>
+
+ Functions <literal>&lt;sidebar-next&gt;</literal> and
+
+ <literal>&lt;sidebar-prev&gt;</literal> move the Sidebar
+
+ <emphasis role="bold">highlight</emphasis>.
+
+ They <emphasis role="bold">do not</emphasis> change the open
+
+ mailbox.
+
+ </note>
+
+ <para>
+
+ Press <quote>Ctrl-Shift-O</quote>
+
+ (<literal>&lt;sidebar-open&gt;</literal>)
+
+ to open the highlighted mailbox.
+
+ </para>
+
+<screen>
+
+Fruit [1] 3/8| 1 ! Mar 07 Finley Jones (139) Molucca Sea
+
+Animals [1] 2/6| 2 + Mar 24 Summer Jackson ( 25) Arafura Sea
+
+Cars 4| 3 + Feb 28 Imogen Baker (193) Pechora Sea
+
+<emphasis role="indicator">Seas 1/7</emphasis>|<emphasis role="indicator"> 4 N + Feb 23 Isla Hussain (348) Balearic Sea </emphasis>
+
+ |
+
+ |
+
+ |
+
+ |
+
+ |
+
+ |
+
+</screen>
+
+ </sect3>
+
+ <sect3 id="intro-sidebar-features">
+
+ <title>Features</title>
+
+ <para>
+
+ The Sidebar shows a list of mailboxes in a panel.
+
+ <para>
+
+ </para>
+
+ Everything about the Sidebar can be configured.
+
+ </para>
+
+ <itemizedlist>
+
+ <title><link linkend="intro-sidebar-basics">State of the Sidebar</link></title>
+
+ <listitem><para>Visibility</para></listitem>
+
+ <listitem><para>Width</para></listitem>
+
+ </itemizedlist>
+
+ <itemizedlist>
+
+ <title><link linkend="intro-sidebar-limit">Which mailboxes are displayed</link></title>
+
+ <listitem><para>Display all</para></listitem>
+
+ <listitem><para>Limit to mailboxes with new mail</para></listitem>
+
+ <listitem><para>Whitelist mailboxes to display always</para></listitem>
+
+ </itemizedlist>
+
+ <itemizedlist>
+
+ <title><link linkend="sidebar-sort">The order in which mailboxes are displayed</link></title>
+
+ <title></title>
+
+ <listitem><para>Unsorted (order of mailboxes commands)</para></listitem>
+
+ <listitem><para>Sorted alphabetically</para></listitem>
+
+ <listitem><para>Sorted by number of new mails</para></listitem>
+
+ </itemizedlist>
+
+ <itemizedlist>
+
+ <title><link linkend="intro-sidebar-colors">Color</link></title>
+
+ <listitem><para>Sidebar indicators and divider</para></listitem>
+
+ <listitem><para>Mailboxes depending on their type</para></listitem>
+
+ <listitem><para>Mailboxes depending on their contents</para></listitem>
+
+ </itemizedlist>
+
+ <itemizedlist>
+
+ <title><link linkend="sidebar-functions">Key bindings</link></title>
+
+ <listitem><para>Hide/Unhide the Sidebar</para></listitem>
+
+ <listitem><para>Select previous/next mailbox</para></listitem>
+
+ <listitem><para>Select previous/next mailbox with new mail</para></listitem>
+
+ <listitem><para>Page up/down through a list of mailboxes</para></listitem>
+
+ </itemizedlist>
+
+ <itemizedlist>
+
+ <title>Misc</title>
+
+ <listitem><para><link linkend="intro-sidebar-format">Formatting string for mailbox</link></para></listitem>
+
+ <listitem><para><link linkend="sidebar-next-new-wrap">Wraparound searching</link></para></listitem>
+
+ <listitem><para><link linkend="intro-sidebar-abbrev">Flexible mailbox abbreviations</link></para></listitem>
+
+ <listitem><para>Support for Unicode mailbox names (utf-8)</para></listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3 id="intro-sidebar-display">
+
+ <title>Display</title>
+
+ <para>
+
+ Everything about the Sidebar can be configured.
+
+ </para>
+
+ <itemizedlist>
+
+ <title>For a quick reference:</title>
+
+ <listitem><para><link linkend="sidebar-variables">Sidebar variables to set</link> </para></listitem>
+
+ <listitem><para><link linkend="sidebar-colors">Sidebar colors to apply</link></para></listitem>
+
+ <listitem><para><link linkend="sidebar-sort">Sidebar sort methods</link></para></listitem>
+
+ </itemizedlist>
+
+ <sect4 id="intro-sidebar-basics">
+
+ <title>Sidebar Basics</title>
+
+ <para>
+
+ The most important variable is <literal>$sidebar_visible</literal>.
+
+ You can set this in your <quote>muttrc</quote>, or bind a key to the
+
+ function <literal>&lt;sidebar-toggle-visible&gt;</literal>.
+
+ </para>
+
+<screen>
+
+set sidebar_visible <emphasis role="comment"># Make the Sidebar visible by default</emphasis>
+
+bind index,pager B sidebar-toggle-visible <emphasis role="comment"># Use 'B' to switch the Sidebar on and off</emphasis>
+
+</screen>
+
+ <para>
+
+ Next, decide how wide you want the Sidebar to be. 25
+
+ characters might be enough for the mailbox name and some numbers.
+
+ Remember, you can hide/show the Sidebar at the press of button.
+
+ </para>
+
+ <para>
+
+ Finally, you might want to change the divider character.
+
+ By default, Sidebar draws an ASCII line between it and the Index panel
+
+ If your terminal supports it, you can use a Unicode line-drawing character.
+
+ </para>
+
+<screen>
+
+set sidebar_width = 25 <emphasis role="comment"># Plenty of space</emphasis>
+
+set sidebar_divider_char = '│' <emphasis role="comment"># Pretty line-drawing character</emphasis>
+
+</screen>
+
+ </sect4>
+
+ <sect4 id="intro-sidebar-format">
+
+ <title>Sidebar Format String</title>
+
+ <para>
+
+ <literal>$sidebar_format</literal> allows you to customize the Sidebar display.
+
+ For an introduction, read <link linkend="index-format">format strings</link>
+
+ including the section about <link linkend="formatstrings-conditionals">conditionals</link>.
+
+ </para>
+
+ <para>
+
+ The default value is <literal>%B%?F? [%F]?%* %?N?%N/?%S</literal>
+
+ </para>
+
+ <itemizedlist>
+
+ <title>Which breaks down as:</title>
+
+ <listitem><para><literal>%B</literal> - Mailbox name</para></listitem>
+
+ <listitem><para><literal>%?F? [%F]?</literal> - If flagged emails <literal>[%F]</literal>, otherwise nothing</para></listitem>
+
+ <listitem><para><literal>%* </literal> - Pad with spaces</para></listitem>
+
+ <listitem><para><literal>%?N?%N/?</literal> - If new emails <literal>%N/</literal>, otherwise nothing</para></listitem>
+
+ <listitem><para><literal>%S</literal> - Total number of emails</para></listitem>
+
+ </itemizedlist>
+
+ <table>
+
+ <title>sidebar_format</title>
+
+ <tgroup cols="3">
+
+ <thead>
+
+ <row>
+
+ <entry>Format</entry>
+
+ <entry>Notes</entry>
+
+ <entry>Description</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry>%B</entry>
+
+ <entry></entry>
+
+ <entry>Name of the mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%S</entry>
+
+ <entry>*</entry>
+
+ <entry>Size of mailbox (total number of messages)</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%N</entry>
+
+ <entry>*</entry>
+
+ <entry>Number of New messages in the mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%F</entry>
+
+ <entry>*</entry>
+
+ <entry>Number of Flagged messages in the mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%!</entry>
+
+ <entry></entry>
+
+ <entry>
+
+ <quote>!</quote>: one flagged message;
+
+ <quote>!!</quote>: two flagged messages;
+
+ <quote>n!</quote>: n flagged messages (for n &gt; 2).
+
+ Otherwise prints nothing.
+
+ </entry>
+
+ </row>
+
+ <row>
+
+ <entry>%d</entry>
+
+ <entry>* ‡</entry>
+
+ <entry>Number of deleted messages</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%L</entry>
+
+ <entry>* ‡</entry>
+
+ <entry>Number of messages after limiting</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%t</entry>
+
+ <entry>* ‡</entry>
+
+ <entry>Number of tagged messages</entry>
+
+ </row>
+
+ <row>
+
+ <entry>%&gt;X</entry>
+
+ <entry></entry>
+
+ <entry>Right justify the rest of the string and pad with <quote>X</quote></entry>
+
+ </row>
+
+ <row>
+
+ <entry>%|X</entry>
+
+ <entry></entry>
+
+ <entry>Pad to the end of the line with
+
+ <quote>X</quote></entry>
+
+ </row>
+
+ <row>
+
+ <entry>%*X</entry>
+
+ <entry></entry>
+
+ <entry>Soft-fill with character <quote>X</quote>as pad</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ <para>
+
+ * = Can be optionally printed if nonzero
+
+ </para>
+
+ <para>
+
+ ‡ = Only applicable to the current folder
+
+ </para>
+
+ <para>
+
+ Here are some examples.
+
+ They show the number of (F)lagged, (N)ew and (S)ize.
+
+ </para>
+
+ <table>
+
+ <title>sidebar_format</title>
+
+ <tgroup cols="2">
+
+ <thead>
+
+ <row>
+
+ <entry>Format</entry>
+
+ <entry>Example</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry><literal>%B%?F? [%F]?%* %?N?%N/?%S</literal></entry>
+
+ <entry><screen>mailbox [F] N/S</screen></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>%B%* %F:%N:%S</literal></entry>
+
+ <entry><screen>mailbox F:N:S</screen></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>%B %?N?(%N)?%* %S</literal></entry>
+
+ <entry><screen>mailbox (N) S</screen></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>%B%* ?F?%F/?%N</literal></entry>
+
+ <entry><screen>mailbox F/S</screen></entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect4>
+
+ <sect4 id="intro-sidebar-abbrev">
+
+ <title>Abbreviating Mailbox Names</title>
+
+ <para>
+
+ <literal>$sidebar_delim_chars</literal> tells Sidebar
+
+ how to split up mailbox paths. For local directories
+
+ use <quote>/</quote>; for IMAP folders use <quote>.</quote>
+
+ </para>
+
+ <sect5 id="intro-sidebar-abbrev-ex1">
+
+ <title>Example 1</title>
+
+ <para>
+
+ This example works well if your mailboxes have unique names
+
+ after the last separator.
+
+ </para>
+
+ <para>
+
+ Add some mailboxes of diffent depths.
+
+ </para>
+
+<screen>
+
+set folder="~/mail"
+
+mailboxes =fruit/apple =fruit/banana =fruit/cherry
+
+mailboxes =water/sea/sicily =water/sea/archipelago =water/sea/sibuyan
+
+mailboxes =water/ocean/atlantic =water/ocean/pacific =water/ocean/arctic
+
+</screen>
+
+ <para>
+
+ Shorten the names:
+
+ </para>
+
+<screen>
+
+set sidebar_short_path <emphasis role="comment"># Shorten mailbox names</emphasis>
+
+set sidebar_delim_chars="/" <emphasis role="comment"># Delete everything up to the last / character</emphasis>
+
+</screen>
+
+ <para>
+
+ The screenshot below shows what the Sidebar would look like
+
+ before and after shortening.
+
+ </para>
+
+<screen>
+
+|fruit/apple |apple
+
+|fruit/banana |banana
+
+|fruit/cherry |cherry
+
+|water/sea/sicily |sicily
+
+|water/sea/archipelago |archipelago
+
+|water/sea/sibuyan |sibuyan
+
+|water/ocean/atlantic |atlantic
+
+|water/ocean/pacific |pacific
+
+|water/ocean/arctic |arctic
+
+</screen>
+
+ </sect5>
+
+ <sect5 id="intro-sidebar-abbrev-ex2">
+
+ <title>Example 2</title>
+
+ <para>
+
+ This example works well if you have lots of mailboxes which are arranged
+
+ in a tree.
+
+ </para>
+
+ <para>
+
+ Add some mailboxes of diffent depths.
+
+ </para>
+
+<screen>
+
+set folder="~/mail"
+
+mailboxes =fruit
+
+mailboxes =fruit/apple =fruit/banana =fruit/cherry
+
+mailboxes =water
+
+mailboxes =water/sea
+
+mailboxes =water/sea/sicily =water/sea/archipelago =water/sea/sibuyan
+
+mailboxes =water/ocean
+
+mailboxes =water/ocean/atlantic =water/ocean/pacific =water/ocean/arctic
+
+</screen>
+
+ <para>
+
+ Shorten the names:
+
+ </para>
+
+<screen>
+
+set sidebar_short_path <emphasis role="comment"># Shorten mailbox names</emphasis>
+
+set sidebar_delim_chars="/" <emphasis role="comment"># Delete everything up to the last / character</emphasis>
+
+set sidebar_folder_indent <emphasis role="comment"># Indent folders whose names we've shortened</emphasis>
+
+set sidebar_indent_string=" " <emphasis role="comment"># Indent with two spaces</emphasis>
+
+</screen>
+
+ <para>
+
+ The screenshot below shows what the Sidebar would look like
+
+ before and after shortening.
+
+ </para>
+
+<screen>
+
+|fruit |fruit
+
+|fruit/apple | apple
+
+|fruit/banana | banana
+
+|fruit/cherry | cherry
+
+|water |water
+
+|water/sea | sea
+
+|water/sea/sicily | sicily
+
+|water/sea/archipelago | archipelago
+
+|water/sea/sibuyan | sibuyan
+
+|water/ocean | ocean
+
+|water/ocean/atlantic | atlantic
+
+|water/ocean/pacific | pacific
+
+|water/ocean/arctic | arctic
+
+</screen>
+
+ <para>
+
+ Sometimes, it will be necessary to add mailboxes, that you
+
+ don't use, to fill in part of the tree. This will trade
+
+ vertical space for horizonal space (but it looks good).
+
+ </para>
+
+ </sect5>
+
+ </sect4>
+
+ <sect4 id="intro-sidebar-limit">
+
+ <title>Limiting the Number of Mailboxes</title>
+
+ <para>
+
+ If you have a lot of mailboxes, sometimes it can be useful to hide
+
+ the ones you aren't using. <literal>$sidebar_new_mail_only</literal>
+
+ tells Sidebar to only show mailboxes that contain new, or flagged, email.
+
+ </para>
+
+ <para>
+
+ If you want some mailboxes to be always visible, then use the
+
+ <literal>sidebar_whitelist</literal> command. It takes a list of
+
+ mailboxes as parameters.
+
+ </para>
+
+<screen>
+
+set sidebar_new_mail_only <emphasis role="comment"># Only mailboxes with new/flagged email</emphasis>
+
+sidebar_whitelist fruit fruit/apple <emphasis role="comment"># Always display these two mailboxes</emphasis>
+
+</screen>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3 id="intro-sidebar-colors">
+
+ <title>Colors</title>
+
+ <para>
+
+ Here is a sample color scheme:
+
+ </para>
+
+<screen>
+
+color sidebar_indicator default color17 <emphasis role="comment"># Dark blue background</emphasis>
+
+color sidebar_highlight white color238 <emphasis role="comment"># Grey background</emphasis>
+
+color sidebar_spoolfile yellow default <emphasis role="comment"># Yellow</emphasis>
+
+color sidebar_new green default <emphasis role="comment"># Green</emphasis>
+
+color sidebar_flagged red default <emphasis role="comment"># Red</emphasis>
+
+color sidebar_divider color8 default <emphasis role="comment"># Dark grey</emphasis>
+
+</screen>
+
+ <para>
+
+ There is a priority order when coloring Sidebar mailboxes.
+
+ e.g. If a mailbox has new mail it will have the
+
+ <literal>sidebar_new</literal> color, even if it also contains
+
+ flagged mails.
+
+ </para>
+
+ <table id="table-intro-sidebar-colors">
+
+ <title>Sidebar Color Priority</title>
+
+ <tgroup cols="3">
+
+ <thead>
+
+ <row>
+
+ <entry>Priority</entry>
+
+ <entry>Color</entry>
+
+ <entry>Description</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry>Highest</entry>
+
+ <entry><literal>sidebar_indicator</literal></entry>
+
+ <entry>Mailbox is open</entry>
+
+ </row>
+
+ <row>
+
+ <entry></entry>
+
+ <entry><literal>sidebar_highlight</literal></entry>
+
+ <entry>Mailbox is highlighed</entry>
+
+ </row>
+
+ <row>
+
+ <entry></entry>
+
+ <entry><literal>sidebar_spoolfile</literal></entry>
+
+ <entry>Mailbox is the spoolfile (receives incoming mail)</entry>
+
+ </row>
+
+ <row>
+
+ <entry></entry>
+
+ <entry><literal>sidebar_new</literal></entry>
+
+ <entry>Mailbox contains new mail</entry>
+
+ </row>
+
+ <row>
+
+ <entry></entry>
+
+ <entry><literal>sidebar_flagged</literal></entry>
+
+ <entry>Mailbox contains flagged mail</entry>
+
+ </row>
+
+ <row>
+
+ <entry>Lowest</entry>
+
+ <entry>(None)</entry>
+
+ <entry>Mailbox does not match above</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect3>
+
+ <sect3 id="intro-sidebar-bugfixes">
+
+ <title>Bug-fixes</title>
+
+ <para>
+
+ If you haven't used Sidebar before, you can ignore this section.
+
+ </para>
+
+ <para>
+
+ These bugs have been fixed since the previous Sidebar release: 2015-11-11.
+
+ </para>
+
+ <itemizedlist>
+
+ <listitem><para>Fix bug when starting in compose mode</para></listitem>
+
+ <listitem><para>Fix bug with empty sidebar_divider_char string</para></listitem>
+
+ <listitem><para>Fix bug with header wrapping</para></listitem>
+
+ <listitem><para>Correctly handle utf8 character sequences</para></listitem>
+
+ <listitem><para>Fix a bug in mh_buffy_update</para></listitem>
+
+ <listitem><para>Fix refresh -- time overflowed short</para></listitem>
+
+ <listitem><para>Protect against empty format strings</para></listitem>
+
+ <listitem><para>Limit Sidebar width to COLS</para></listitem>
+
+ <listitem><para>Handle unmailboxes * safely</para></listitem>
+
+ <listitem><para>Refresh Sidebar after timeout</para></listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3 id="intro-sidebar-config-changes">
+
+ <title>Config Changes</title>
+
+ <para>
+
+ If you haven't used Sidebar before, you can ignore this section.
+
+ </para>
+
+ <para>
+
+ Some of the Sidebar config has been changed to make its meaning clearer.
+
+ These changes have been made since the previous Sidebar release: 2015-11-11.
+
+ </para>
+
+ <table id="table-intro-sidebar-config-changes">
+
+ <title>Config Changes</title>
+
+ <tgroup cols="2">
+
+ <thead>
+
+ <row>
+
+ <entry>Old Name</entry>
+
+ <entry>New Name</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry><literal>$sidebar_delim</literal></entry>
+
+ <entry><literal>$sidebar_divider_char</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>$sidebar_folderindent</literal></entry>
+
+ <entry><literal>$sidebar_folder_indent</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>$sidebar_indentstr</literal></entry>
+
+ <entry><literal>$sidebar_indent_string</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>$sidebar_newmail_only</literal></entry>
+
+ <entry><literal>$sidebar_new_mail_only</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>$sidebar_refresh</literal></entry>
+
+ <entry><literal>$sidebar_refresh_time</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>$sidebar_shortpath</literal></entry>
+
+ <entry><literal>$sidebar_short_path</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>$sidebar_sort</literal></entry>
+
+ <entry><literal>$sidebar_sort_method</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>&lt;sidebar-scroll-down&gt;</literal></entry>
+
+ <entry><literal>&lt;sidebar-page-down&gt;</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>&lt;sidebar-scroll-up&gt;</literal></entry>
+
+ <entry><literal>&lt;sidebar-page-up&gt;</literal></entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect3>
+
+</sect2>
+
+
+
<sect2 id="intro-help">
+
<title>Help</title>
+
+
@@ -6773,6 +7390,17 @@
+
</para>
+
+
<para>
+
+Mutt will set the <literal>COLUMNS</literal> environment variable to
+
+the width of the pager. Some programs make use of this environment
+
+variable automatically. Others provide a command line argument that
+
+can use this to set the output width:
+
+</para>
+
+
+
+<screen>
+
+text/html; lynx -dump -width ${COLUMNS:-80} %s; copiousoutput
+
+</screen>
+
+
+
+<para>
+
Note that when using the built-in pager, <emphasis>only</emphasis>
+
entries with this flag will be considered a handler for a MIME type
+
&mdash; all other entries will be ignored.
+
@@ -7467,6 +8095,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 +8719,469 @@
+
+
</sect1>
+
+
+<sect1 id="sidebar">
+
+ <title>Sidebar Patch</title>
+
+ <subtitle>Overview of mailboxes</subtitle>
+
+
+
+ <sect2 id="sidebar-patch">
+
+ <title>Patch</title>
+
+
+
+ <para>
+
+ To check if Mutt supports <quote>Sidebar</quote>, look for
+
+ <quote>+USE_SIDEBAR</quote> in the mutt version.
+
+ See: <xref linkend="compile-time-features"/>.
+
+ </para>
+
+
+
+ <itemizedlist>
+
+ <title>Dependencies:</title>
+
+ <listitem><para>mutt-1.6.1</para></listitem>
+
+ </itemizedlist>
+
+
+
+ <para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-intro">
+
+ <title>Introduction</title>
+
+
+
+ <para>
+
+ The Sidebar shows a list of all your mailboxes. The list can be
+
+ turned on and off, it can be themed and the list style can be
+
+ configured.
+
+ </para>
+
+
+
+ <para>
+
+ This part of the manual is a reference guide.
+
+ If you want a simple introduction with examples see the
+
+ <link linkend="intro-sidebar">Sidebar Howto</link>.
+
+ If you just want to get started, you could use the sample
+
+ <link linkend="sidebar-muttrc">Sidebar muttrc</link>.
+
+ </para>
+
+
+
+ <para>
+
+ This version of Sidebar is based on Terry Chan's
+
+ <ulink url="http://www.lunar-linux.org/mutt-sidebar/">2015-11-11 release</ulink>.
+
+ It contains many
+
+ <emphasis role="bold"><link linkend="intro-sidebar-features">new features</link></emphasis>,
+
+ lots of
+
+ <emphasis role="bold"><link linkend="intro-sidebar-bugfixes">bugfixes</link></emphasis>.
+
+ </para>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-variables">
+
+ <title>Variables</title>
+
+
+
+ <table id="table-sidebar-variables">
+
+ <title>Sidebar Variables</title>
+
+ <tgroup cols="3">
+
+ <thead>
+
+ <row>
+
+ <entry>Name</entry>
+
+ <entry>Type</entry>
+
+ <entry>Default</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry><literal>sidebar_delim_chars</literal></entry>
+
+ <entry>string</entry>
+
+ <entry><literal>/.</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_divider_char</literal></entry>
+
+ <entry>string</entry>
+
+ <entry><literal>|</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_folder_indent</literal></entry>
+
+ <entry>boolean</entry>
+
+ <entry><literal>no</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_format</literal></entry>
+
+ <entry>string</entry>
+
+ <entry><literal>%B%?F? [%F]?%* %?N?%N/?%S</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_indent_string</literal></entry>
+
+ <entry>string</entry>
+
+ <entry><literal>&nbsp;&nbsp;</literal> (two spaces)</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_new_mail_only</literal></entry>
+
+ <entry>boolean</entry>
+
+ <entry><literal>no</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_next_new_wrap</literal></entry>
+
+ <entry>boolean</entry>
+
+ <entry><literal>no</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_refresh_time</literal></entry>
+
+ <entry>number</entry>
+
+ <entry><literal>60</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_short_path</literal></entry>
+
+ <entry>boolean</entry>
+
+ <entry><literal>no</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_sort_method</literal></entry>
+
+ <entry>enum</entry>
+
+ <entry><literal>SORT_ORDER</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_visible</literal></entry>
+
+ <entry>boolean</entry>
+
+ <entry><literal>no</literal></entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_whitelist</literal></entry>
+
+ <entry>list</entry>
+
+ <entry>(empty)</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_width</literal></entry>
+
+ <entry>number</entry>
+
+ <entry><literal>20</literal></entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-functions">
+
+ <title>Functions</title>
+
+
+
+ <para>
+
+ Sidebar adds the following functions to Mutt.
+
+ By default, none of them are bound to keys.
+
+ </para>
+
+
+
+ <table id="table-sidebar-functions">
+
+ <title>Sidebar Functions</title>
+
+ <tgroup cols="3">
+
+ <thead>
+
+ <row>
+
+ <entry>Menus</entry>
+
+ <entry>Function</entry>
+
+ <entry>Description</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-next&gt;</literal></entry>
+
+ <entry>Move the highlight to next mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-next-new&gt;</literal></entry>
+
+ <entry>Move the highlight to next mailbox with new mail</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-open&gt;</literal></entry>
+
+ <entry>Open highlighted mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-page-down&gt;</literal></entry>
+
+ <entry>Scroll the Sidebar down 1 page</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-page-up&gt;</literal></entry>
+
+ <entry>Scroll the Sidebar up 1 page</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-prev&gt;</literal></entry>
+
+ <entry>Move the highlight to previous mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-prev-new&gt;</literal></entry>
+
+ <entry>Move the highlight to previous mailbox with new mail</entry>
+
+ </row>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry><literal>&lt;sidebar-toggle-visible&gt;</literal></entry>
+
+ <entry>Make the Sidebar (in)visible</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-commands">
+
+ <title>Commands</title>
+
+ <cmdsynopsis>
+
+ <command>sidebar_whitelist</command>
+
+ <arg choice="plain">
+
+ <replaceable class="parameter">mailbox</replaceable>
+
+ </arg>
+
+ <arg choice="opt" rep="repeat">
+
+ <replaceable class="parameter">mailbox</replaceable>
+
+ </arg>
+
+ </cmdsynopsis>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-colors">
+
+ <title>Colors</title>
+
+
+
+ <table id="table-sidebar-colors">
+
+ <title>Sidebar Colors</title>
+
+ <tgroup cols="3">
+
+ <thead>
+
+ <row>
+
+ <entry>Name</entry>
+
+ <entry>Default Color</entry>
+
+ <entry>Description</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry><literal>sidebar_divider</literal></entry>
+
+ <entry>default</entry>
+
+ <entry>The dividing line between the Sidebar and the Index/Pager panels</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_flagged</literal></entry>
+
+ <entry>default</entry>
+
+ <entry>Mailboxes containing flagged mail</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_highlight</literal></entry>
+
+ <entry>underline</entry>
+
+ <entry>Cursor to select a mailbox</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_indicator</literal></entry>
+
+ <entry>mutt <literal>indicator</literal></entry>
+
+ <entry>The mailbox open in the Index panel</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_new</literal></entry>
+
+ <entry>default</entry>
+
+ <entry>Mailboxes containing new mail</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>sidebar_spoolfile</literal></entry>
+
+ <entry>default</entry>
+
+ <entry>Mailbox that receives incoming mail</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+
+
+ If the <literal>sidebar_indicator</literal> color isn't set, then the default Mutt
+
+ indicator color will be used (the color used in the index panel).
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-sort">
+
+ <title>Sort</title>
+
+
+
+ <table id="table-sidebar-sort">
+
+ <title>Sidebar Sort</title>
+
+ <tgroup cols="2">
+
+ <thead>
+
+ <row>
+
+ <entry>Sort</entry>
+
+ <entry>Description</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry><literal>alpha</literal></entry>
+
+ <entry>Alphabetically by path</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>count</literal></entry>
+
+ <entry>Total number of messages</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>flagged</literal></entry>
+
+ <entry>Number of flagged messages</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>name</literal></entry>
+
+ <entry>Alphabetically by path</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>new</literal></entry>
+
+ <entry>Number of new messages</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>path</literal></entry>
+
+ <entry>Alphabetically by path</entry>
+
+ </row>
+
+ <row>
+
+ <entry><literal>unsorted</literal></entry>
+
+ <entry>Do not resort the paths</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-muttrc">
+
+ <title>Muttrc</title>
+
+<screen>
+
+<emphasis role="comment"># This is a complete list of sidebar-related configuration.
+
+
+
+# --------------------------------------------------------------------------
+
+# VARIABLES - shown with their default values
+
+# --------------------------------------------------------------------------
+
+
+
+# Should the Sidebar be shown?</emphasis>
+
+set sidebar_visible = no
+
+
+
+<emphasis role="comment"># How wide should the Sidebar be in screen columns?
+
+# Note: Some characters, e.g. Chinese, take up two columns each.</emphasis>
+
+set sidebar_width = 20
+
+
+
+<emphasis role="comment"># Should the mailbox paths be abbreviated?</emphasis>
+
+set sidebar_short_path = no
+
+
+
+<emphasis role="comment"># When abbreviating mailbox path names, use any of these characters as path
+
+# separators. Only the part after the last separators will be shown.
+
+# For file folders '/' is good. For IMAP folders, often '.' is useful.</emphasis>
+
+set sidebar_delim_chars = '/.'
+
+
+
+<emphasis role="comment"># If the mailbox path is abbreviated, should it be indented?</emphasis>
+
+set sidebar_folder_indent = no
+
+
+
+<emphasis role="comment"># Indent mailbox paths with this string.</emphasis>
+
+set sidebar_indent_string = ' '
+
+
+
+<emphasis role="comment"># Make the Sidebar only display mailboxes that contain new, or flagged,
+
+# mail.</emphasis>
+
+set sidebar_new_mail_only = no
+
+
+
+<emphasis role="comment"># Any mailboxes that are whitelisted will always be visible, even if the
+
+# sidebar_new_mail_only option is enabled.</emphasis>
+
+sidebar_whitelist '/home/user/mailbox1'
+
+sidebar_whitelist '/home/user/mailbox2'
+
+
+
+<emphasis role="comment"># When searching for mailboxes containing new mail, should the search wrap
+
+# around when it reaches the end of the list?</emphasis>
+
+set sidebar_next_new_wrap = no
+
+
+
+<emphasis role="comment"># The character to use as the divider between the Sidebar and the other Mutt
+
+# panels.
+
+# Note: Only the first character of this string is used.</emphasis>
+
+set sidebar_divider_char = '|'
+
+
+
+<emphasis role="comment"># Display the Sidebar mailboxes using this format string.</emphasis>
+
+set sidebar_format = '%B%?F? [%F]?%* %?N?%N/?%S'
+
+
+
+<emphasis role="comment"># Sidebar will not refresh its list of mailboxes any more frequently than
+
+# this number of seconds. This will help reduce disk/network traffic.</emphasis>
+
+set sidebar_refresh_time = 60
+
+
+
+<emphasis role="comment"># Sort the mailboxes in the Sidebar using this method:
+
+# count - total number of messages
+
+# flagged - number of flagged messages
+
+# new - number of new messages
+
+# path - mailbox path
+
+# unsorted - do not sort the mailboxes</emphasis>
+
+set sidebar_sort_method = 'unsorted'
+
+
+
+<emphasis role="comment"># --------------------------------------------------------------------------
+
+# FUNCTIONS - shown with an example mapping
+
+# --------------------------------------------------------------------------
+
+
+
+# Move the highlight to the previous mailbox</emphasis>
+
+bind index,pager \Cp sidebar-prev
+
+
+
+<emphasis role="comment"># Move the highlight to the next mailbox</emphasis>
+
+bind index,pager \Cn sidebar-next
+
+
+
+<emphasis role="comment"># Open the highlighted mailbox</emphasis>
+
+bind index,pager \Co sidebar-open
+
+
+
+<emphasis role="comment"># Move the highlight to the previous page
+
+# This is useful if you have a LOT of mailboxes.</emphasis>
+
+bind index,pager &lt;F3&gt; sidebar-page-up
+
+
+
+<emphasis role="comment"># Move the highlight to the next page
+
+# This is useful if you have a LOT of mailboxes.</emphasis>
+
+bind index,pager &lt;F4&gt; sidebar-page-down
+
+
+
+<emphasis role="comment"># Move the highlight to the previous mailbox containing new, or flagged,
+
+# mail.</emphasis>
+
+bind index,pager &lt;F5&gt; sidebar-prev-new
+
+
+
+<emphasis role="comment"># Move the highlight to the next mailbox containing new, or flagged, mail.</emphasis>
+
+bind index,pager &lt;F6&gt; sidebar-next-new
+
+
+
+<emphasis role="comment"># Toggle the visibility of the Sidebar.</emphasis>
+
+bind index,pager B sidebar-toggle-visible
+
+
+
+<emphasis role="comment"># --------------------------------------------------------------------------
+
+# COLORS - some unpleasant examples are given
+
+# --------------------------------------------------------------------------
+
+# Note: All color operations are of the form:
+
+# color OBJECT FOREGROUND BACKGROUND
+
+
+
+# Color of the current, open, mailbox
+
+# Note: This is a general Mutt option which colors all selected items.</emphasis>
+
+color indicator cyan black
+
+
+
+<emphasis role="comment"># Color of the highlighted, but not open, mailbox.</emphasis>
+
+color sidebar_highlight black color8
+
+
+
+<emphasis role="comment"># Color of the divider separating the Sidebar from Mutt panels</emphasis>
+
+color sidebar_divider color8 black
+
+
+
+<emphasis role="comment"># Color to give mailboxes containing flagged mail</emphasis>
+
+color sidebar_flagged red black
+
+
+
+<emphasis role="comment"># Color to give mailboxes containing new mail</emphasis>
+
+color sidebar_new green black
+
+
+
+<emphasis role="comment"># --------------------------------------------------------------------------
+
+
+
+# vim: syntax=muttrc</emphasis>
+
+</screen>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-see-also">
+
+ <title>See Also</title>
+
+
+
+ <itemizedlist>
+
+ <listitem><para><link linkend="regexp">Regular Expressions</link></para></listitem>
+
+ <listitem><para><link linkend="patterns">Patterns</link></para></listitem>
+
+ <listitem><para><link linkend="color">Color command</link></para></listitem>
+
+ <listitem><para><link linkend="notmuch">notmuch patch</link></para></listitem>
+
+ </itemizedlist>
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-known-bugs">
+
+ <title>Known Bugs</title>
+
+ Unsorted isn't
+
+ </sect2>
+
+
+
+ <sect2 id="sidebar-credits">
+
+ <title>Credits</title>
+
+ <itemizedlist>
+
+ <listitem><para>Justin Hibbits <email>jrh29@po.cwru.edu</email></para></listitem>
+
+ <listitem><para>Thomer M. Gil <email>mutt@thomer.com</email></para></listitem>
+
+ <listitem><para>David Sterba <email>dsterba@suse.cz</email></para></listitem>
+
+ <listitem><para>Evgeni Golov <email>evgeni@debian.org</email></para></listitem>
+
+ <listitem><para>Fabian Groffen <email>grobian@gentoo.org</email></para></listitem>
+
+ <listitem><para>Jason DeTiberus <email>jdetiber@redhat.com</email></para></listitem>
+
+ <listitem><para>Stefan Assmann <email>sassmann@kpanic.de</email></para></listitem>
+
+ <listitem><para>Steve Kemp <email>steve@steve.org.uk</email></para></listitem>
+
+ <listitem><para>Terry Chan <email>tchan@lunar-linux.org</email></para></listitem>
+
+ <listitem><para>Tyler Earnest <email>tylere@rne.st</email></para></listitem>
+
+ <listitem><para>Richard Russon <email>rich@flatcap.org</email></para></listitem>
+
+ </itemizedlist>
+
+ </sect2>
+
+</sect1>
+
+
+
</chapter>
+
+
<chapter id="security">
+
@@ -9237,6 +10338,17 @@
+
+
<listitem>
+
<cmdsynopsis>
+
+<command><link linkend="sidebar-whitelist">sidebar_whitelist</link></command>
+
+<arg choice="plain">
+
+<replaceable class="parameter">item</replaceable>
+
+</arg>
+
+<arg choice="plain">
+
+<replaceable class="parameter">command</replaceable>
+
+</arg>
+
+</cmdsynopsis>
+
+</listitem>
+
+<listitem>
+
+<cmdsynopsis>
+
<command><link linkend="source">source</link></command>
+
<arg choice="plain">
+
<replaceable class="parameter">filename</replaceable>
+
diff -urN mutt-1.6.1/doc/mutt.css mutt-1.6.1-sidebar/doc/mutt.css
+
--- mutt-1.6.1/doc/mutt.css 2016-06-12 18:43:00.402447590 +0100
+
+++ mutt-1.6.1-sidebar/doc/mutt.css 2016-06-12 18:43:03.811500752 +0100
+
@@ -9,17 +9,24 @@
+
div.table-contents table th, div.informaltable table th {
+
font-family:sans-serif;
+
background:#d0d0d0;
+
- font-weight:normal;
+
+ font-weight:bold;
+
vertical-align:top;
+
}
+
-div.cmdsynopsis { border-left:1px solid #707070; padding-left:5px; }
+
+div.cmdsynopsis { border-left:1px solid #707070; padding-left: 1em; }
+
li div.cmdsynopsis { border-left:none; padding-left:0px; }
+
-pre.screen, div.note { background:#f0f0f0; border:1px solid #c0c0c0; padding:5px; margin-left:2%; margin-right:2%; }
+
+li p { margin: 0; }
+
+pre.screen, div.note { border:1px solid #c0c0c0; margin-left:2%; margin-right:2%; }
+
+pre.screen { color: #ffffff; background:#000000; padding: 0.5em; }
+
+div.note { background:#ffff80; padding: 0.5em; }
+
div.example p.title { margin-left:2%; }
+
div.note h3 { font-size:small; font-style:italic; font-variant: small-caps; }
+
div.note h3:after { content: ":" }
+
div.note { margin-bottom: 5px; }
+
-.command { font-family: monospace; font-weight: normal; }
+
+div.literallayout, .command { font-family: monospace; font-weight: normal; }
+
.command strong { font-weight: normal; }
+
tr { vertical-align: top; }
+
-.comment { color:#707070; }
+
+.comment { color:#00c000; }
+
+code.literal { background: #f0f0f0; color: #000000; }
+
+span.indicator { background: #000060; color: #ffffff; }
+
+span.highlight { background: #404040; color: #ffffff; }
+
+span.reverse { background: #ffffff; color: #000000; }
+
diff -urN mutt-1.6.1/doc/muttrc.sidebar mutt-1.6.1-sidebar/doc/muttrc.sidebar
+
--- mutt-1.6.1/doc/muttrc.sidebar 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-sidebar/doc/muttrc.sidebar 2016-06-12 18:43:03.812500768 +0100
+
@@ -0,0 +1,116 @@
+
+# This is a complete list of sidebar-related configuration.
+
+
+
+# --------------------------------------------------------------------------
+
+# VARIABLES - shown with their default values
+
+# --------------------------------------------------------------------------
+
+
+
+# Should the Sidebar be shown?
+
+set sidebar_visible = no
+
+
+
+# How wide should the Sidebar be in screen columns?
+
+# Note: Some characters, e.g. Chinese, take up two columns each.
+
+set sidebar_width = 20
+
+
+
+# Should the mailbox paths be abbreviated?
+
+set sidebar_short_path = no
+
+
+
+# When abbreviating mailbox path names, use any of these characters as path
+
+# separators. Only the part after the last separators will be shown.
+
+# For file folders '/' is good. For IMAP folders, often '.' is useful.
+
+set sidebar_delim_chars = '/.'
+
+
+
+# If the mailbox path is abbreviated, should it be indented?
+
+set sidebar_folder_indent = no
+
+
+
+# Indent mailbox paths with this string.
+
+set sidebar_indent_string = ' '
+
+
+
+# Make the Sidebar only display mailboxes that contain new, or flagged,
+
+# mail.
+
+set sidebar_new_mail_only = no
+
+
+
+# Any mailboxes that are whitelisted will always be visible, even if the
+
+# sidebar_new_mail_only option is enabled.
+
+sidebar_whitelist '/home/user/mailbox1'
+
+sidebar_whitelist '/home/user/mailbox2'
+
+
+
+# When searching for mailboxes containing new mail, should the search wrap
+
+# around when it reaches the end of the list?
+
+set sidebar_next_new_wrap = no
+
+
+
+# The character to use as the divider between the Sidebar and the other Mutt
+
+# panels.
+
+# Note: Only the first character of this string is used.
+
+set sidebar_divider_char = '|'
+
+
+
+# Display the Sidebar mailboxes using this format string.
+
+set sidebar_format = '%B%?F? [%F]?%* %?N?%N/?%S'
+
+
+
+# Sidebar will not refresh its list of mailboxes any more frequently than
+
+# this number of seconds. This will help reduce disk/network traffic.
+
+set sidebar_refresh_time = 60
+
+
+
+# Sort the mailboxes in the Sidebar using this method:
+
+# count - total number of messages
+
+# flagged - number of flagged messages
+
+# new - number of new messages
+
+# path - mailbox path
+
+# unsorted - do not sort the mailboxes
+
+set sidebar_sort_method = 'unsorted'
+
+
+
+# --------------------------------------------------------------------------
+
+# FUNCTIONS - shown with an example mapping
+
+# --------------------------------------------------------------------------
+
+
+
+# Move the highlight to the previous mailbox
+
+bind index,pager \Cp sidebar-prev
+
+
+
+# Move the highlight to the next mailbox
+
+bind index,pager \Cn sidebar-next
+
+
+
+# Open the highlighted mailbox
+
+bind index,pager \Co sidebar-open
+
+
+
+# Move the highlight to the previous page
+
+# This is useful if you have a LOT of mailboxes.
+
+bind index,pager <F3> sidebar-page-up
+
+
+
+# Move the highlight to the next page
+
+# This is useful if you have a LOT of mailboxes.
+
+bind index,pager <F4> sidebar-page-down
+
+
+
+# Move the highlight to the previous mailbox containing new, or flagged,
+
+# mail.
+
+bind index,pager <F5> sidebar-prev-new
+
+
+
+# Move the highlight to the next mailbox containing new, or flagged, mail.
+
+bind index,pager <F6> sidebar-next-new
+
+
+
+# Toggle the visibility of the Sidebar.
+
+bind index,pager B sidebar-toggle-visible
+
+
+
+# --------------------------------------------------------------------------
+
+# COLORS - some unpleasant examples are given
+
+# --------------------------------------------------------------------------
+
+# Note: All color operations are of the form:
+
+# color OBJECT FOREGROUND BACKGROUND
+
+
+
+# Color of the current, open, mailbox
+
+# Note: This is a general Mutt option which colors all selected items.
+
+color indicator cyan black
+
+
+
+# Color of the highlighted, but not open, mailbox.
+
+color sidebar_highlight black color8
+
+
+
+# Color of the divider separating the Sidebar from Mutt panels
+
+color sidebar_divider color8 black
+
+
+
+# Color to give mailboxes containing flagged mail
+
+color sidebar_flagged red black
+
+
+
+# Color to give mailboxes containing new mail
+
+color sidebar_new green black
+
+
+
+# --------------------------------------------------------------------------
+
+
+
+# vim: syntax=muttrc
+
diff -urN mutt-1.6.1/doc/vimrc.sidebar mutt-1.6.1-sidebar/doc/vimrc.sidebar
+
--- mutt-1.6.1/doc/vimrc.sidebar 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-sidebar/doc/vimrc.sidebar 2016-06-12 18:43:03.813500783 +0100
+
@@ -0,0 +1,35 @@
+
+" Vim syntax file for the mutt sidebar patch
+
+
+
+syntax keyword muttrcVarBool skipwhite contained sidebar_folder_indent nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+syntax keyword muttrcVarBool skipwhite contained sidebar_new_mail_only nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+syntax keyword muttrcVarBool skipwhite contained sidebar_next_new_wrap nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+syntax keyword muttrcVarBool skipwhite contained sidebar_short_path nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+syntax keyword muttrcVarBool skipwhite contained sidebar_visible nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+
+
+syntax keyword muttrcVarNum skipwhite contained sidebar_refresh_time nextgroup=muttrcSetNumAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+syntax keyword muttrcVarNum skipwhite contained sidebar_width nextgroup=muttrcSetNumAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
+
+
+
+syntax keyword muttrcVarStr contained skipwhite sidebar_divider_char nextgroup=muttrcVarEqualsIdxFmt
+
+syntax keyword muttrcVarStr contained skipwhite sidebar_delim_chars nextgroup=muttrcVarEqualsIdxFmt
+
+syntax keyword muttrcVarStr contained skipwhite sidebar_format nextgroup=muttrcVarEqualsIdxFmt
+
+syntax keyword muttrcVarStr contained skipwhite sidebar_indent_string nextgroup=muttrcVarEqualsIdxFmt
+
+syntax keyword muttrcVarStr contained skipwhite sidebar_sort_method nextgroup=muttrcVarEqualsIdxFmt
+
+
+
+syntax keyword muttrcCommand sidebar_whitelist
+
+
+
+syntax match muttrcFunction contained "\<sidebar-next\>"
+
+syntax match muttrcFunction contained "\<sidebar-next-new\>"
+
+syntax match muttrcFunction contained "\<sidebar-open\>"
+
+syntax match muttrcFunction contained "\<sidebar-page-down\>"
+
+syntax match muttrcFunction contained "\<sidebar-page-up\>"
+
+syntax match muttrcFunction contained "\<sidebar-prev\>"
+
+syntax match muttrcFunction contained "\<sidebar-prev-new\>"
+
+syntax match muttrcFunction contained "\<sidebar-toggle-visible\>"
+
+
+
+syntax keyword muttrcColorField contained sidebar_divider
+
+syntax keyword muttrcColorField contained sidebar_flagged
+
+syntax keyword muttrcColorField contained sidebar_highlight
+
+syntax keyword muttrcColorField contained sidebar_indicator
+
+syntax keyword muttrcColorField contained sidebar_new
+
+
+
+" vim: syntax=vim
+
diff -urN mutt-1.6.1/filter.c mutt-1.6.1-sidebar/filter.c
+
--- mutt-1.6.1/filter.c 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-sidebar/filter.c 2016-06-12 18:43:03.835501127 +0100
+
@@ -21,6 +21,7 @@
+
#endif
#include "mutt.h"
+
+#include "mutt_curses.h"
+
+
#include <unistd.h>
+
#include <stdlib.h>
+
@@ -34,6 +35,7 @@
+
int fdin, int fdout, int fderr)
+
{
+
int pin[2], pout[2], perr[2], thepid;
+
+ char columns[11];
+
+
if (in)
+
{
+
@@ -117,6 +119,9 @@
+
close (fderr);
+
}
+
+
+ snprintf (columns, sizeof (columns), "%d", COLS - SidebarWidth);
+
+ setenv ("COLUMNS", columns, 1);
+
+
+
execl (EXECSHELL, "sh", "-c", cmd, NULL);
+
_exit (127);
+
}
+
diff -urN mutt-1.6.1/flags.c mutt-1.6.1-sidebar/flags.c
+
--- mutt-1.6.1/flags.c 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-sidebar/flags.c 2016-06-12 18:43:03.956503013 +0100
+
@@ -25,6 +25,10 @@
#include "sort.h"
#include "mx.h"
+
+
+#ifdef USE_SIDEBAR
+#include "sidebar.h"
+
+#endif
+
+
void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
{
+
int changed = h->changed;
+
@@ -263,6 +267,9 @@
*/
if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged))
h->searched = 0;
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_draw();
+
+#endif
}
void mutt_tag_set_flag (int flag, int bf)
+
diff -urN mutt-1.6.1/functions.h mutt-1.6.1-sidebar/functions.h
+
--- mutt-1.6.1/functions.h 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-sidebar/functions.h 2016-06-12 18:43:03.956503013 +0100
+
@@ -168,6 +168,16 @@
+
{ "decrypt-copy", OP_DECRYPT_COPY, NULL },
{ "decrypt-save", OP_DECRYPT_SAVE, NULL },
+
+#ifdef USE_SIDEBAR
+
+ { "sidebar-next", OP_SIDEBAR_NEXT, NULL },
+
+ { "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL },
+
+ { "sidebar-open", OP_SIDEBAR_OPEN, NULL },
+
+ { "sidebar-page-down", OP_SIDEBAR_PAGE_DOWN, NULL },
+
+ { "sidebar-page-up", OP_SIDEBAR_PAGE_UP, NULL },
+
+ { "sidebar-prev", OP_SIDEBAR_PREV, NULL },
+
+ { "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL },
+
+ { "sidebar-toggle-visible", OP_SIDEBAR_TOGGLE_VISIBLE, NULL },
+
+#endif
{ NULL, 0, NULL }
};
+
@@ -272,6 +282,17 @@
{ "what-key", OP_WHAT_KEY, NULL },
+
+#ifdef USE_SIDEBAR
+
+ { "sidebar-next", OP_SIDEBAR_NEXT, NULL },
+
+ { "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL },
+
+ { "sidebar-open", OP_SIDEBAR_OPEN, NULL },
+
+ { "sidebar-page-down", OP_SIDEBAR_PAGE_DOWN, NULL },
+
+ { "sidebar-page-up", OP_SIDEBAR_PAGE_UP, NULL },
+
+ { "sidebar-prev", OP_SIDEBAR_PREV, NULL },
+
+ { "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL },
+
+ { "sidebar-toggle-visible", OP_SIDEBAR_TOGGLE_VISIBLE, NULL },
+
+#endif
+
+
{ NULL, 0, NULL }
};
+
diff -urN mutt-1.6.1/globals.h mutt-1.6.1-sidebar/globals.h
+
--- mutt-1.6.1/globals.h 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-sidebar/globals.h 2016-06-12 18:43:03.956503013 +0100
+
@@ -118,6 +118,12 @@
WHERE char *SendCharset;
WHERE char *Sendmail;
WHERE char *Shell;
+
+#ifdef USE_SIDEBAR
+
+WHERE char *SidebarDelimChars;
+
+WHERE char *SidebarDividerChar;
+
+WHERE char *SidebarFormat;
+
+WHERE char *SidebarIndentString;
+
+#endif
WHERE char *Signature;
WHERE char *SimpleSearch;
#if USE_SMTP
+
@@ -214,6 +220,14 @@
WHERE short ScoreThresholdRead;
WHERE short ScoreThresholdFlag;
+
+/* This isn't excluded from the build because it's too entwined in the code.
+
+ * For now. */
+WHERE short SidebarWidth;
+
+#ifdef USE_SIDEBAR
+
+WHERE short SidebarRefreshTime;
+
+WHERE LIST *SidebarWhitelist INITVAL(0);
+
+#endif
+
+
#ifdef USE_IMAP
WHERE short ImapKeepalive;
WHERE short ImapPipelineDepth;
+
diff -urN mutt-1.6.1/imap/command.c mutt-1.6.1-sidebar/imap/command.c
+
--- mutt-1.6.1/imap/command.c 2016-06-12 18:43:00.405447637 +0100
+
+++ mutt-1.6.1-sidebar/imap/command.c 2016-06-12 18:43:03.839501189 +0100
+
@@ -1016,6 +1016,14 @@
opened */
status->uidnext = oldun;
+
+#ifdef USE_SIDEBAR
+
+ /* Make the sidebar show the correct numbers */
+
+ if (status->messages) {
+
+ inc->msg_count = status->messages;
+
+ inc->msg_unread = status->unseen;
+
+ }
+
+#endif
+
FREE (&value);
return;
}
+
diff -urN mutt-1.6.1/imap/imap.c mutt-1.6.1-sidebar/imap/imap.c
+
--- mutt-1.6.1/imap/imap.c 2016-06-12 18:43:00.405447637 +0100
+
+++ mutt-1.6.1-sidebar/imap/imap.c 2016-06-12 18:43:03.958503044 +0100
+
@@ -1535,7 +1535,11 @@
+
imap_munge_mbox_name (idata, munged, sizeof (munged), name);
snprintf (command, sizeof (command),
+
+#ifdef USE_SIDEBAR
+ "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT MESSAGES)", munged);
+
+#else
+
"STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
+
+#endif
if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0)
{
+
diff -urN mutt-1.6.1/init.c mutt-1.6.1-sidebar/init.c
+
--- mutt-1.6.1/init.c 2016-06-12 18:43:00.406447652 +0100
+
+++ mutt-1.6.1-sidebar/init.c 2016-06-12 18:43:03.959503060 +0100
+
@@ -2173,6 +2173,9 @@
+
case DT_SORT_AUX:
+
map = SortAuxMethods;
+
break;
+
+ case DT_SORT_SIDEBAR:
+
+ map = SortSidebarMethods;
+
+ break;
+
default:
+
map = SortMethods;
+
break;
+
diff -urN mutt-1.6.1/init.h mutt-1.6.1-sidebar/init.h
+
--- mutt-1.6.1/init.h 2016-06-12 18:43:00.408447684 +0100
+
+++ mutt-1.6.1-sidebar/init.h 2016-06-12 18:43:03.960503075 +0100
+
@@ -42,11 +42,12 @@
+
#define DTYPE(x) ((x) & DT_MASK)
+
+
/* subtypes */
+
-#define DT_SUBTYPE_MASK 0xf0
+
+#define DT_SUBTYPE_MASK 0xff0
+
#define DT_SORT_ALIAS 0x10
+
#define DT_SORT_BROWSER 0x20
+
#define DT_SORT_KEYS 0x40
+
#define DT_SORT_AUX 0x80
+
+#define DT_SORT_SIDEBAR 0x100
+
+
/* flags to parse_set() */
+
#define M_SET_INV (1<<0) /* default is to invert all vars */
+
@@ -2665,6 +2666,147 @@
+
** Command to use when spawning a subshell. By default, the user's login
+
** shell from \fC/etc/passwd\fP is used.
*/
+
+#ifdef USE_SIDEBAR
+
+ { "sidebar_divider_char", DT_STR, R_BOTH, UL &SidebarDividerChar, UL "|" },
+
+ /*
+
+ ** .pp
+
+ ** This specifies the characters to be drawn between the sidebar (when
+
+ ** visible) and the other Mutt panels. ASCII and Unicode line-drawing
+
+ ** characters are supported.
+
+ */
+
+ { "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.
+
+ ** .pp
+
+ ** Local mail is often arranged in directories: `dir1/dir2/mailbox'.
+
+ ** .ts
+
+ ** set sidebar_delim_chars='/'
+
+ ** .te
+
+ ** .pp
+
+ ** IMAP mailboxes are often named: `folder1.folder2.mailbox'.
+
+ ** .ts
+
+ ** set sidebar_delim_chars='.'
+
+ ** .te
+
+ ** .pp
+
+ ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_folder_indent, $$sidebar_indent_string.
+
+ */
+
+ { "sidebar_folder_indent", DT_BOOL, R_BOTH, OPTSIDEBARFOLDERINDENT, 0 },
+
+ /*
+
+ ** .pp
+
+ ** Set this to indent mailboxes in the sidebar.
+
+ ** .pp
+
+ ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_indent_string, $$sidebar_delim_chars.
+
+ */
+
+ { "sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%?F? [%F]?%* %?N?%N/?%S" },
+
+ /*
+
+ ** .pp
+
+ ** This variable allows you to customize the sidebar display. This string is
+
+ ** similar to $$index_format, but has its own set of \fCprintf(3)\fP-like
+
+ ** sequences:
+
+ ** .dl
+
+ ** .dt %B .dd Name of the mailbox
+
+ ** .dt %S .dd * Size of mailbox (total number of messages)
+
+ ** .dt %N .dd * Number of New messages in the mailbox
+
+ ** .dt %F .dd * Number of Flagged messages in the mailbox
+
+ ** .dt %! .dd ``!'' : one flagged message;
+
+ ** ``!!'' : two flagged messages;
+
+ ** ``n!'' : n flagged messages (for n > 2).
+
+ ** Otherwise prints nothing.
+
+ ** .dt %d .dd * @ Number of deleted messages
+
+ ** .dt %L .dd * @ Number of messages after limiting
+
+ ** .dt %t .dd * @ Number of tagged messages
+
+ ** .dt %>X .dd right justify the rest of the string and pad with ``X''
+
+ ** .dt %|X .dd pad to the end of the line with ``X''
+
+ ** .dt %*X .dd soft-fill with character ``X'' as pad
+
+ ** .de
+
+ ** .pp
+
+ ** * = Can be optionally printed if nonzero
+
+ ** @ = Only applicable to the current folder
+
+ */
+
+ { "sidebar_indent_string", DT_STR, R_BOTH, UL &SidebarIndentString, UL " " },
+ /*
+ ** .pp
+
+ ** This specifies the string that is used to indent mailboxes in the sidebar.
+
+ ** It defaults to two spaces.
+
+ ** .pp
+
+ ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_folder_indent, $$sidebar_delim_chars.
+ */
+
+ { "sidebar_new_mail_only", DT_BOOL, R_BOTH, OPTSIDEBARNEWMAILONLY, 0 },
+ /*
+ ** .pp
+
+ ** When set, the sidebar will only display mailboxes containing new, or
+
+ ** flagged, mail.
+
+ ** .pp
+
+ ** \fBSee also:\fP $sidebar_whitelist.
+ */
+
+ { "sidebar_next_new_wrap", DT_BOOL, R_BOTH, UL OPTSIDEBARNEXTNEWWRAP, 0 },
+ /*
+ ** .pp
+
+ ** When set, the \fC<sidebar-next-new>\fP command will not stop and the end of
+
+ ** the list of mailboxes, but wrap around to the beginning. The
+
+ ** \fC<sidebar-prev-new>\fP command is similarly affected, wrapping around to
+
+ ** the end of the list.
+
+ */
+
+ { "sidebar_refresh_time", DT_NUM, R_BOTH, UL &SidebarRefreshTime, 60 },
+
+ /*
+
+ ** .pp
+
+ ** Set sidebar_refresh_time to the minimum number of seconds between refreshes.
+
+ ** This will reduce network traffic.
+
+ ** .pp
+
+ ** \fBNote:\fP Set to 0 to disable refreshing.
+
+ */
+
+ { "sidebar_short_path", DT_BOOL, R_BOTH, OPTSIDEBARSHORTPATH, 0 },
+
+ /*
+
+ ** .pp
+
+ ** By default the sidebar will show the mailbox's path, relative to the
+
+ ** $$folder variable. Setting \fCsidebar_shortpath=yes\fP will shorten the
+
+ ** names relative to the previous name. Here's an example:
+
+ ** .dl
+
+ ** .dt \fBshortpath=no\fP .dd \fBshortpath=yes\fP .dd \fBshortpath=yes, folderindent=yes, indentstr=".."\fP
+
+ ** .dt \fCfruit\fP .dd \fCfruit\fP .dd \fCfruit\fP
+
+ ** .dt \fCfruit.apple\fP .dd \fCapple\fP .dd \fC..apple\fP
+
+ ** .dt \fCfruit.banana\fP .dd \fCbanana\fP .dd \fC..banana\fP
+
+ ** .dt \fCfruit.cherry\fP .dd \fCcherry\fP .dd \fC..cherry\fP
+
+ ** .de
+
+ ** .pp
+
+ ** \fBSee also:\fP $$sidebar_delim_chars, $$sidebar_folder_indent, $$sidebar_indent_string.
+
+ */
+
+ { "sidebar_sort_method", DT_SORT|DT_SORT_SIDEBAR, R_NONE, UL &SidebarSortMethod, SORT_ORDER },
+
+ /*
+
+ ** .pp
+
+ ** Specifies how to sort entries in the file browser. By default, the
+
+ ** entries are sorted alphabetically. Valid values:
+
+ ** .il
+
+ ** .dd alpha (alphabetically)
+
+ ** .dd count (all message count)
+
+ ** .dd date
+
+ ** .dd desc (description)
+
+ ** .dd new (new message count)
+
+ ** .dd size
+
+ ** .dd unsorted
+
+ ** .ie
+
+ ** .pp
+
+ ** You may optionally use the ``reverse-'' prefix to specify reverse sorting
+
+ ** order (example: ``\fCset sort_browser=reverse-date\fP'').
+
+ */
+
+ { "sidebar_visible", DT_BOOL, R_BOTH, OPTSIDEBAR, 0 },
+
+ /*
+
+ ** .pp
+
+ ** This specifies whether or not to show sidebar. The sidebar shows a list of
+
+ ** all your mailboxes.
+
+ ** .pp
+
+ ** \fBSee also:\fP $$sidebar_format, $$sidebar_width
+ */
+ { "sidebar_width", DT_NUM, R_BOTH, UL &SidebarWidth, 0 },
+ /*
+ ** .pp
+
+ ** This controls the width of the sidebar. It is measured in screen columns.
+
+ ** For example: sidebar_width=20 could display 20 ASCII characters, or 10
+
+ ** Chinese characters.
+ */
+
+#endif
+
{ "sig_dashes", DT_BOOL, R_NONE, OPTSIGDASHES, 1 },
/*
** .pp
+
@@ -3652,6 +3794,19 @@
+
{ NULL, 0 }
+
};
+
+
+const struct mapping_t SortSidebarMethods[] = {
+
+ { "alpha", SORT_PATH },
+
+ { "count", SORT_COUNT },
+
+ { "desc", SORT_DESC },
+
+ { "flagged", SORT_FLAGGED },
+
+ { "mailbox-order", SORT_ORDER },
+
+ { "name", SORT_PATH },
+
+ { "new", SORT_COUNT_NEW },
+
+ { "path", SORT_PATH },
+
+ { "unsorted", SORT_ORDER },
+
+ { NULL, 0 }
+
+};
+
+
+
+
/* functions used to parse commands in a rc file */
+
+
@@ -3741,6 +3896,9 @@
+
{ "send-hook", mutt_parse_hook, M_SENDHOOK },
+
{ "send2-hook", mutt_parse_hook, M_SEND2HOOK },
+
{ "set", parse_set, 0 },
+
+#ifdef USE_SIDEBAR
+
+ { "sidebar_whitelist",parse_list, UL &SidebarWhitelist },
+
+#endif
+
{ "source", parse_source, 0 },
+
{ "spam", parse_spam_list, M_SPAM },
+
{ "nospam", parse_spam_list, M_NOSPAM },
+
diff -urN mutt-1.6.1/keymap.c mutt-1.6.1-sidebar/keymap.c
+
--- mutt-1.6.1/keymap.c 2016-06-12 18:43:00.408447684 +0100
+
+++ mutt-1.6.1-sidebar/keymap.c 2016-06-12 18:43:03.960503075 +0100
+
@@ -453,6 +453,9 @@
+
}
+
#endif
+
+
+ /* update sidebar stats */
+
+ mutt_buffy_check(0);
+
+
+
timeout (i * 1000);
+
tmp = mutt_getch();
+
timeout (-1);
+
diff -urN mutt-1.6.1/mailbox.h mutt-1.6.1-sidebar/mailbox.h
+
--- mutt-1.6.1/mailbox.h 2016-06-12 18:43:00.408447684 +0100
+
+++ mutt-1.6.1-sidebar/mailbox.h 2016-06-12 18:43:03.960503075 +0100
+
@@ -27,6 +27,9 @@
#define M_NEWFOLDER (1<<4) /* create a new folder - same as M_APPEND, but uses
* safe_fopen() for mbox-style folders.
*/
+
+#ifdef USE_SIDEBAR
+#define M_PEEK (1<<5) /* revert atime back after taking a look (if applicable) */
+
+#endif
/* mx_open_new_message() */
#define M_ADD_FROM (1<<0) /* add a From_ line */
+
diff -urN mutt-1.6.1/main.c mutt-1.6.1-sidebar/main.c
+
--- mutt-1.6.1/main.c 2016-06-12 18:43:00.409447699 +0100
+
+++ mutt-1.6.1-sidebar/main.c 2016-06-12 18:43:03.961503091 +0100
+
@@ -31,6 +31,9 @@
+
#include "url.h"
+
#include "mutt_crypt.h"
+
#include "mutt_idna.h"
+
+#ifdef USE_SIDEBAR
+
+#include "sidebar.h"
+
+#endif
+
+
#ifdef USE_SASL
+
#include "mutt_sasl.h"
+
@@ -485,6 +488,12 @@
+
"-USE_HCACHE "
+
#endif
+
+
+#ifdef USE_SIDEBAR
+
+ "+USE_SIDEBAR "
+
+#else
+
+ "-USE_SIDEBAR "
+
+#endif
+
+
+
);
+
+
#ifdef ISPELL
+
@@ -557,7 +566,11 @@
+
+
int main (int argc, char **argv)
+
{
+
+#ifdef USE_SIDEBAR
+
+ char folder[PATH_MAX] = "";
+
+#else
+
char folder[_POSIX_PATH_MAX] = "";
+
+#endif
+
char *subject = NULL;
+
char *includeFile = NULL;
+
char *draftFile = NULL;
+
@@ -828,6 +841,9 @@
+
clear ();
+
mutt_error = mutt_curses_error;
+
mutt_message = mutt_curses_message;
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_init();
+
+#endif
+
}
+
+
/* Create the Maildir directory if it doesn't exist. */
+
@@ -1184,6 +1200,15 @@
+
strfcpy (folder, NONULL(Spoolfile), sizeof (folder));
+
mutt_expand_path (folder, sizeof (folder));
+
+
+#ifdef USE_SIDEBAR
+
+ {
+
+ char tmpfolder[PATH_MAX] = "";
+
+ strfcpy (tmpfolder, folder, sizeof (tmpfolder));
+
+ if (!realpath (tmpfolder, folder))
+
+ strfcpy (folder, tmpfolder, sizeof (tmpfolder));
+
+ }
+
+#endif
+
+
+
mutt_str_replace (&CurrentFolder, folder);
+
mutt_str_replace (&LastFolder, folder);
+
+
@@ -1206,6 +1231,9 @@
+
if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
+
|| !explicit_folder)
+
{
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_set_open_buffy (folder);
+
+#endif
+
mutt_index_menu ();
+
if (Context)
+
FREE (&Context);
+
diff -urN mutt-1.6.1/Makefile.am mutt-1.6.1-sidebar/Makefile.am
+
--- mutt-1.6.1/Makefile.am 2016-06-12 18:43:00.389447388 +0100
+
+++ mutt-1.6.1-sidebar/Makefile.am 2016-06-12 18:43:03.944502826 +0100
+
@@ -56,7 +56,7 @@
+
mutt_idna.c mutt_sasl.c mutt_socket.c mutt_ssl.c mutt_ssl_gnutls.c \
+
mutt_tunnel.c pgp.c pgpinvoke.c pgpkey.c pgplib.c pgpmicalg.c \
+
pgppacket.c pop.c pop_auth.c pop_lib.c remailer.c resize.c sha1.c \
+
- smime.c smtp.c utf8.c wcwidth.c \
+
+ sidebar.c smime.c smtp.c utf8.c wcwidth.c \
+
bcache.h browser.h hcache.h mbyte.h mutt_idna.h remailer.h url.h
+
+
EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP OPS.CRYPT OPS.SMIME TODO UPDATING \
+
@@ -71,7 +71,7 @@
+
mbyte.h lib.h extlib.c pgpewrap.c smime_keys.pl pgplib.h \
+
README.SSL smime.h group.h \
+
muttbug pgppacket.h depcomp ascii.h BEWARE PATCHES patchlist.sh \
+
- ChangeLog mkchangelog.sh mutt_idna.h \
+
+ ChangeLog mkchangelog.sh mutt_idna.h sidebar.h OPS.sidebar \
+
snprintf.c regex.c crypt-gpgme.h hcachever.sh.in sys_socket.h \
+
txt2c.c txt2c.sh version.sh check_sec.sh
+
+
@@ -129,9 +129,9 @@
+
keymap_defs.h: $(OPS) $(srcdir)/gen_defs
+
$(srcdir)/gen_defs $(OPS) > keymap_defs.h
+
+
-keymap_alldefs.h: $(srcdir)/OPS $(srcdir)/OPS.PGP $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME $(srcdir)/gen_defs
+
+keymap_alldefs.h: $(srcdir)/OPS $(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.PGP $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME $(srcdir)/gen_defs
+
rm -f $@
+
- $(srcdir)/gen_defs $(srcdir)/OPS $(srcdir)/OPS.PGP \
+
+ $(srcdir)/gen_defs $(srcdir)/OPS $(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.PGP \
+
$(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME \
+
> keymap_alldefs.h
+
+
diff -urN mutt-1.6.1/mbox.c mutt-1.6.1-sidebar/mbox.c
+
--- mutt-1.6.1/mbox.c 2016-06-12 18:43:00.409447699 +0100
+
+++ mutt-1.6.1-sidebar/mbox.c 2016-06-12 18:43:03.961503091 +0100
+
@@ -100,6 +100,9 @@
mutt_perror (ctx->path);
return (-1);
}
+
+#ifdef USE_SIDEBAR
+ ctx->atime = sb.st_atime;
+
+#endif
ctx->mtime = sb.st_mtime;
ctx->size = sb.st_size;
+
@@ -251,6 +254,9 @@
ctx->size = sb.st_size;
ctx->mtime = sb.st_mtime;
+
+#ifdef USE_SIDEBAR
+ ctx->atime = sb.st_atime;
+
+#endif
#ifdef NFS_ATTRIBUTE_HACK
if (sb.st_mtime > sb.st_atime)
+
diff -urN mutt-1.6.1/menu.c mutt-1.6.1-sidebar/menu.c
+
--- mutt-1.6.1/menu.c 2016-06-12 18:43:00.409447699 +0100
+
+++ mutt-1.6.1-sidebar/menu.c 2016-06-12 18:43:03.961503091 +0100
+
@@ -24,6 +24,9 @@
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "mbyte.h"
+
+#ifdef USE_SIDEBAR
+#include "sidebar.h"
+
+#endif
+
char* SearchBuffers[MENU_MAX];
+
@@ -184,7 +187,7 @@
{
char *scratch = safe_strdup (s);
int shift = option (OPTARROWCURSOR) ? 3 : 0;
···
mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1);
s[n - 1] = 0;
+
@@ -237,6 +240,9 @@
int do_color;
int attr;
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_draw();
+
+#endif
for (i = menu->top; i < menu->top + menu->pagelen; i++)
{
if (i < menu->max)
+
@@ -247,7 +253,7 @@
menu_pad_string (buf, sizeof (buf));
ATTRSET(attr);
···
do_color = 1;
if (i == menu->current)
+
@@ -270,7 +276,11 @@
else
{
NORMAL_COLOR;
+
+#ifdef USE_SIDEBAR
+ CLEARLINE_WIN(i - menu->top + menu->offset);
+
+#else
+
CLEARLINE(i - menu->top + menu->offset);
+
+#endif
}
}
NORMAL_COLOR;
+
@@ -287,7 +297,7 @@
return;
}
···
ATTRSET(menu->color (menu->oldcurrent));
if (option (OPTARROWCURSOR))
+
@@ -299,13 +309,13 @@
{
menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
menu_pad_string (buf, sizeof (buf));
···
}
else
{
+
@@ -318,7 +328,7 @@
menu_make_entry (buf, sizeof (buf), menu, menu->current);
menu_pad_string (buf, sizeof (buf));
SETCOLOR(MT_COLOR_INDICATOR);
···
print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0);
}
menu->redraw &= REDRAW_STATUS;
+
@@ -330,7 +340,7 @@
char buf[LONG_STRING];
int attr = menu->color (menu->current);
···
menu_make_entry (buf, sizeof (buf), menu, menu->current);
menu_pad_string (buf, sizeof (buf));
+
@@ -873,7 +883,7 @@
if (option (OPTARROWCURSOR))
···
else if (option (OPTBRAILLEFRIENDLY))
move (menu->current - menu->top + menu->offset, 0);
else
+
diff -urN mutt-1.6.1/mh.c mutt-1.6.1-sidebar/mh.c
+
--- mutt-1.6.1/mh.c 2016-06-12 18:43:00.410447715 +0100
+
+++ mutt-1.6.1-sidebar/mh.c 2016-06-12 18:43:03.962503107 +0100
+
@@ -295,6 +295,48 @@
mhs_free_sequences (&mhs);
}
+
+#ifdef USE_SIDEBAR
+
+/**
+
+ * mh_buffy_update - Update messages counts for an mh mailbox
+
+ * @mailbox: BUFFY representing a maildir mailbox
+
+ *
+
+ * Read through an mh mailbox and count messages. Save the number of new,
+
+ * flagged messages and a timestamp for now.
+
+ */
+
+void
+
+mh_buffy_update (BUFFY *mailbox)
+{
+ int i;
+ struct mh_sequences mhs;
+
+
+
+ if (!mailbox)
+
+ return;
+
+
+
+ if (!option (OPTSIDEBAR))
+
+ return;
+
+
+ memset (&mhs, 0, sizeof (mhs));
+
+
+ if (mh_read_sequences (&mhs, mailbox->path) < 0)
+ return;
+
+
+ mailbox->msg_count = 0;
+
+ mailbox->msg_unread = 0;
+
+ mailbox->msg_flagged = 0;
+
+
+ for (i = 0; i <= mhs.max; i++)
+
+ {
+
+ mailbox->msg_count++;
+
+ if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN)
+
+ mailbox->msg_unread++;
+
+ if (mhs_check (&mhs, i) & MH_SEQ_FLAGGED)
+
+ mailbox->msg_flagged++;
+ }
+ mhs_free_sequences (&mhs);
+
+ mailbox->sb_last_checked = time (NULL);
+}
+
+#endif
+
static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
{
int fd;
+
diff -urN mutt-1.6.1/mutt_curses.h mutt-1.6.1-sidebar/mutt_curses.h
+
--- mutt-1.6.1/mutt_curses.h 2016-06-12 18:43:00.410447715 +0100
+
+++ mutt-1.6.1-sidebar/mutt_curses.h 2016-06-12 18:43:03.962503107 +0100
+
@@ -64,6 +64,9 @@
+
#undef lines
+
#endif /* lines */
+
+
+#ifdef USE_SIDEBAR
+
+#define CLEARLINE_WIN(x) move (x,SidebarWidth), clrtoeol()
+
+#endif
+
#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)
+
@@ -124,6 +127,14 @@
+
MT_COLOR_UNDERLINE,
+
MT_COLOR_INDEX,
+
MT_COLOR_PROMPT,
+
+#ifdef USE_SIDEBAR
+
+ MT_COLOR_DIVIDER,
+
+ MT_COLOR_FLAGGED,
+
+ MT_COLOR_HIGHLIGHT,
+
+ MT_COLOR_NEW,
+
+ MT_COLOR_SB_INDICATOR,
+
+ MT_COLOR_SB_SPOOLFILE,
+
+#endif
+
MT_COLOR_MAX
+
};
+
+
@@ -163,12 +174,16 @@
+
+
static inline int mutt_term_width(short wrap)
+
{
+
+ int cols = COLS;
+
+#ifdef USE_SIDEBAR
+
+ cols -= SidebarWidth;
+
+#endif
+
if (wrap < 0)
+
- return COLS > -wrap ? COLS + wrap : COLS;
+
+ return cols > -wrap ? cols + wrap : cols;
+
else if (wrap)
+
- return wrap < COLS ? wrap : COLS;
+
+ return wrap < cols ? wrap : cols;
+
else
+
- return COLS;
+
+ return cols;
+
}
+
+
extern int *ColorQuote;
+
diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-sidebar/mutt.h
+
--- mutt-1.6.1/mutt.h 2016-06-12 18:43:00.410447715 +0100
+
+++ mutt-1.6.1-sidebar/mutt.h 2016-06-12 18:43:03.962503107 +0100
+
@@ -428,6 +428,13 @@
OPTSAVEEMPTY,
OPTSAVENAME,
OPTSCORE,
+
+#ifdef USE_SIDEBAR
+ OPTSIDEBAR,
+
+ OPTSIDEBARFOLDERINDENT,
+
+ OPTSIDEBARNEWMAILONLY,
+
+ OPTSIDEBARNEXTNEWWRAP,
+
+ OPTSIDEBARSHORTPATH,
+
+#endif
OPTSIGDASHES,
OPTSIGONTOP,
OPTSORTRE,
+
@@ -872,6 +879,9 @@
{
char *path;
FILE *fp;
+
+#ifdef USE_SIDEBAR
+ time_t atime;
+
+#endif
time_t mtime;
off_t size;
off_t vsize;
+
@@ -906,6 +916,9 @@
unsigned int quiet : 1; /* inhibit status messages? */
unsigned int collapsed : 1; /* are all threads collapsed? */
unsigned int closing : 1; /* mailbox is being closed */
+
+#ifdef USE_SIDEBAR
+ unsigned int peekonly : 1; /* just taking a glance, revert atime */
+
+#endif
/* driver hooks */
void *data; /* driver specific data */
+
diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-sidebar/muttlib.c
+
--- mutt-1.6.1/muttlib.c 2016-06-12 18:43:00.411447731 +0100
+
+++ mutt-1.6.1-sidebar/muttlib.c 2016-06-12 18:43:03.963503122 +0100
+
@@ -1282,7 +1282,7 @@
pl = pw = 1;
/* see if there's room to add content, else ignore */
+
- if ((col < COLS && wlen < destlen) || soft)
+
+ if ((col < (COLS - SidebarWidth) && (wlen < destlen)) || soft)
{
int pad;
+
+
@@ -1293,7 +1293,7 @@
+
+
/* 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 - col - wid) / pw;
+ pad = (COLS - SidebarWidth - col - wid) / pw;
+
if (pad > 0 && wlen + (pad * pl) + len > destlen)
+
pad = ((signed)(destlen - wlen - len)) / pl;
+
if (pad > 0)
+
@@ -1312,13 +1312,13 @@
+
/* \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-offset, &wid);
+
+ len = mutt_wstr_trunc (buf, destlen, COLS - offset - SidebarWidth, &wid);
+
/* truncate left so that right part fits completely in */
+
wlen = mutt_wstr_trunc (dest, destlen - len, col + pad*pw -offset, &col);
+
wptr = dest + wlen;
+
}
+
if (len + wlen > destlen)
+
- len = mutt_wstr_trunc (buf, destlen - wlen, COLS - col, NULL);
+ len = mutt_wstr_trunc (buf, destlen - wlen, COLS - SidebarWidth - col, NULL);
+
memcpy (wptr, buf, len);
+
wptr += len;
+
wlen += len;
+
diff -urN mutt-1.6.1/mutt_menu.h mutt-1.6.1-sidebar/mutt_menu.h
+
--- mutt-1.6.1/mutt_menu.h 2016-06-12 18:43:00.410447715 +0100
+
+++ mutt-1.6.1-sidebar/mutt_menu.h 2016-06-12 18:43:03.962503107 +0100
+
@@ -34,6 +34,9 @@
+
#define REDRAW_FULL (1<<5)
+
#define REDRAW_BODY (1<<6)
+
#define REDRAW_SIGWINCH (1<<7)
+
+#ifdef USE_SIDEBAR
+
+#define REDRAW_SIDEBAR (1<<8)
+
+#endif
+
+
#define M_MODEFMT "-- Mutt: %s"
+
+
diff -urN mutt-1.6.1/mx.c mutt-1.6.1-sidebar/mx.c
+
--- mutt-1.6.1/mx.c 2016-06-12 18:43:00.411447731 +0100
+
+++ mutt-1.6.1-sidebar/mx.c 2016-06-12 18:43:03.963503122 +0100
+
@@ -29,6 +29,9 @@
+
#include "copy.h"
+
#include "keymap.h"
+
#include "url.h"
+
+#ifdef USE_SIDEBAR
+
+#include "sidebar.h"
+
+#endif
+
+
#ifdef USE_IMAP
+
#include "imap.h"
+
@@ -580,6 +583,7 @@
* M_APPEND open mailbox for appending
* M_READONLY open mailbox in read-only mode
* M_QUIET only print error messages
···
* ctx if non-null, context struct to use
*/
CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
+
@@ -602,6 +606,10 @@
ctx->quiet = 1;
if (flags & M_READONLY)
ctx->readonly = 1;
+
+#ifdef USE_SIDEBAR
+ if (flags & M_PEEK)
+ ctx->peekonly = 1;
+
+#endif
if (flags & (M_APPEND|M_NEWFOLDER))
{
+
@@ -705,8 +713,21 @@
if(!ctx)
return;
+
+
+#ifdef USE_SIDEBAR
+ /* fix up the times so buffy won't get confused */
+
+ struct utimbuf ut;
+
+ 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 */
+
+#ifdef USE_SIDEBAR
+
+ if (!ctx->peekonly)
+
+#endif
+
mutt_buffy_setnotified(ctx->path);
+
+
if (ctx->mx_close)
+
@@ -812,6 +833,12 @@
+
if (!ctx->hdrs[i]->deleted && ctx->hdrs[i]->read
+
&& !(ctx->hdrs[i]->flagged && option (OPTKEEPFLAGGED)))
+
read_msgs++;
+
+#ifdef USE_SIDEBAR
+
+ if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->read)
+
+ ctx->unread--;
+
+ if (ctx->hdrs[i]->deleted && ctx->hdrs[i]->flagged)
+
+ ctx->flagged--;
+
+#endif
+
}
+
+
if (read_msgs && quadoption (OPT_MOVE) != M_NO)
+
@@ -981,6 +1008,11 @@
+
!mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
+
mx_unlink_empty (ctx->path);
+
+
+#ifdef USE_SIDEBAR
+
+ ctx->msgcount -= ctx->deleted;
+
+ mutt_sb_set_buffystats (ctx);
+
+#endif
+
+
+
mx_fastclose_mailbox (ctx);
+
+
return 0;
+
diff -urN mutt-1.6.1/mx.h mutt-1.6.1-sidebar/mx.h
+
--- mutt-1.6.1/mx.h 2016-06-12 18:43:00.411447731 +0100
+
+++ mutt-1.6.1-sidebar/mx.h 2016-06-12 18:43:03.963503122 +0100
+
@@ -26,6 +26,7 @@
+
#define _MX_H
+
+
#include "mailbox.h"
+
+#include "buffy.h"
+
+
/* supported mailbox formats */
+
enum
+
@@ -57,6 +58,9 @@
int mh_read_dir (CONTEXT *, const char *);
int mh_sync_mailbox (CONTEXT *, int *);
int mh_check_mailbox (CONTEXT *, int *);
+
+#ifdef USE_SIDEBAR
+
+void mh_buffy_update (BUFFY *mailbox);
+
+#endif
int mh_check_empty (const char *);
int maildir_read_dir (CONTEXT *);
+
diff -urN mutt-1.6.1/OPS.SIDEBAR mutt-1.6.1-sidebar/OPS.SIDEBAR
+
--- mutt-1.6.1/OPS.SIDEBAR 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-sidebar/OPS.SIDEBAR 2016-06-12 18:43:03.944502826 +0100
+
@@ -0,0 +1,8 @@
+
+OP_SIDEBAR_NEXT "Move the highlight to next mailbox"
+
+OP_SIDEBAR_NEXT_NEW "Move the highlight to next mailbox with new mail"
+
+OP_SIDEBAR_OPEN "Open highlighted mailbox"
+
+OP_SIDEBAR_PAGE_DOWN "Scroll the Sidebar down 1 page"
+
+OP_SIDEBAR_PAGE_UP "Scroll the Sidebar up 1 page"
+
+OP_SIDEBAR_PREV "Move the highlight to previous mailbox"
+
+OP_SIDEBAR_PREV_NEW "Move the highlight to previous mailbox with new mail"
+
+OP_SIDEBAR_TOGGLE_VISIBLE "Make the Sidebar (in)visible"
+
diff -urN mutt-1.6.1/pager.c mutt-1.6.1-sidebar/pager.c
+
--- mutt-1.6.1/pager.c 2016-06-12 18:43:00.412447746 +0100
+
+++ mutt-1.6.1-sidebar/pager.c 2016-06-12 18:43:03.964503138 +0100
+
@@ -29,6 +29,9 @@
#include "pager.h"
#include "attach.h"
#include "mbyte.h"
+
+#ifdef USE_SIDEBAR
+#include "sidebar.h"
+
+#endif
#include "mutt_crypt.h"
+
@@ -1491,7 +1494,7 @@
+
* a newline (grr!).
+
*/
+
#ifndef USE_SLANG_CURSES
+
- if (col < COLS)
+
+ if (col < (COLS - SidebarWidth))
+
#endif
+
addch ('\n');
+
@@ -1573,6 +1576,7 @@
+
+
int bodyoffset = 1; /* offset of first line of real text */
+
int statusoffset = 0; /* offset for the status bar */
+
+ int statuswidth = COLS;
+
int helpoffset = LINES - 2; /* offset for the help bar. */
+
int bodylen = LINES - 2 - bodyoffset; /* length of displayable area */
+
+
@@ -1747,7 +1751,7 @@
if ((redraw & REDRAW_BODY) || topline != oldtopline)
{
do {
···
curline = oldtopline = topline;
lines = 0;
force_redraw = 0;
+
@@ -1760,6 +1764,9 @@
&QuoteList, &q_level, &force_redraw, &SearchRE) > 0)
lines++;
curline++;
+
+#ifdef USE_SIDEBAR
+
+ move (lines + bodyoffset, SidebarWidth);
+
+#endif
}
last_offset = lineInfo[curline].offset;
} while (force_redraw);
+
@@ -1772,6 +1779,9 @@
addch ('~');
addch ('\n');
lines++;
+
+#ifdef USE_SIDEBAR
+
+ move (lines + bodyoffset, SidebarWidth);
+
+#endif
}
NORMAL_COLOR;
+
@@ -1789,29 +1799,49 @@
+
hfi.ctx = Context;
+
hfi.pager_progress = pager_progress_str;
+
+
+#ifdef USE_SIDEBAR
+
+ statuswidth = COLS;
+
+ if (option (OPTSTATUSONTOP) && (PagerIndexLines > 0))
+
+ statuswidth -= SidebarWidth;
+
+#endif
+
+
+
if (last_pos < sb.st_size - 1)
+
snprintf(pager_progress_str, sizeof(pager_progress_str), OFF_T_FMT "%%", (100 * last_offset / sb.st_size));
+
else
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);
+
+#ifdef USE_SIDEBAR
+
+ short sw = SidebarWidth;
+
+ if (option (OPTSTATUSONTOP) && PagerIndexLines > 0) {
+
+ CLEARLINE_WIN (statusoffset);
+
+ } else {
+
+ CLEARLINE (statusoffset);
+
+ /* Temporarily lie about the sidebar width */
+
+ SidebarWidth = 0;
+
+ }
+
+#endif
if (IsHeader (extra) || IsMsgAttach (extra))
{
- size_t l1 = COLS * MB_LEN_MAX;
+
+ size_t l1 = statuswidth * 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 (statuswidth, buffer);
}
else
{
char bn[STRING];
snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
- mutt_paddstr (COLS, bn);
+
+ mutt_paddstr (statuswidth, bn);
}
+
+#ifdef USE_SIDEBAR
+
+ if (!option (OPTSTATUSONTOP) || PagerIndexLines == 0)
+
+ SidebarWidth = sw; /* Restore the sidebar width */
+
+#endif
NORMAL_COLOR;
if (option(OPTTSENABLED) && TSSupported)
+
{
+
@@ -1827,16 +1857,26 @@
/* redraw the pager_index indicator, because the
* flags for this message might have changed. */
menu_redraw_current (index);
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_draw();
+
+#endif
/* 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)),
+
+ (option(OPTSTATUSONTOP) ? 0: SidebarWidth));
SETCOLOR (MT_COLOR_STATUS);
- mutt_paddstr (COLS, buffer);
+
+ mutt_paddstr (COLS - (option(OPTSTATUSONTOP) ? 0 : SidebarWidth), buffer);
NORMAL_COLOR;
}
+
+#ifdef USE_SIDEBAR
+ /* if we're not using the index, update every time */
+
+ if (index == 0)
+
+ mutt_sb_draw();
+
+#endif
+
redraw = 0;
if (option(OPTBRAILLEFRIENDLY)) {
+
@@ -2498,8 +2538,12 @@
+
ch = 0;
+
}
+
+
- if (option (OPTFORCEREDRAWPAGER))
+
+ if (option (OPTFORCEREDRAWPAGER)) {
+
redraw = REDRAW_FULL;
+
+#ifdef USE_SIDEBAR
+
+ mutt_sb_draw();
+
+#endif
+
+ }
+
unset_option (OPTFORCEREDRAWINDEX);
+
unset_option (OPTFORCEREDRAWPAGER);
+
break;
+
@@ -2777,6 +2821,22 @@
mutt_what_key ();
break;
+
+#ifdef USE_SIDEBAR
+ case OP_SIDEBAR_NEXT:
+
+ case OP_SIDEBAR_NEXT_NEW:
+
+ case OP_SIDEBAR_PAGE_DOWN:
+
+ case OP_SIDEBAR_PAGE_UP:
+ case OP_SIDEBAR_PREV:
+
+ case OP_SIDEBAR_PREV_NEW:
+
+ mutt_sb_change_mailbox (ch);
+
+ break;
+
+
+
+ case OP_SIDEBAR_TOGGLE_VISIBLE:
+
+ toggle_option (OPTSIDEBAR);
+
+ redraw = REDRAW_FULL;
+
+ break;
+
+#endif
+
default:
ch = -1;
break;
+
diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-sidebar/PATCHES
+
--- mutt-1.6.1/PATCHES 2016-06-12 18:43:00.395447481 +0100
+
+++ mutt-1.6.1-sidebar/PATCHES 2016-06-12 18:43:03.949502904 +0100
+
@@ -0,0 +1 @@
+
+patch-sidebar-neo-20160612
+
diff -urN mutt-1.6.1/README.sidebar mutt-1.6.1-sidebar/README.sidebar
+
--- mutt-1.6.1/README.sidebar 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-sidebar/README.sidebar 2016-06-12 18:43:03.792500456 +0100
+
@@ -0,0 +1,145 @@
+
+Sidebar Patch
+
+=============
+
+
+
+ Overview of mailboxes
+
+
+
+ NOTES:
+
+
+
+ If you haven't used the sidebar before, you might like to read the
+
+ Sidebar Introduction:
+
+
+
+ http://www.neomutt.org/sidebar-intro.html
+
+
+
+ If you have used an older version of the Sidebar, please note that some
+
+ of the configuration has changed.
+
+
+
+ http://www.neomutt.org/sidebar-intro.html#intro-sidebar-config-changes
+
+
+
+Patch
+
+-----
+
+
+
+ To check if Mutt supports "Sidebar", look for "+USE_SIDEBAR" in the mutt
+
+ version.
+
+
+
+ Dependencies
+
+ * mutt-1.6.1
+
+
+
+Introduction
+
+------------
+
+
+
+ The Sidebar shows a list of all your mailboxes. The list can be turned on
+
+ and off, it can be themed and the list style can be configured.
+
+
+
+ This part of the manual is a reference guide. If you want a simple
+
+ introduction with examples see the Sidebar Howto. If you just want to get
+
+ started, you could use the sample Sidebar muttrc.
+
+
+
+ This version of Sidebar is based on Terry Chan's [2015-11-11
+
+ release](http://www.lunar-linux.org/mutt-sidebar/). It contains many new
+
+ features, lots of bugfixes.
+
+
+
+Variables
+
+---------
+
+
+
+ Sidebar Variables
+
+
+
+ | Name | Type | Default |
+
+ |-------------------------|---------|-----------------------------|
+
+ | 'sidebar_delim_chars' | string | '/.' |
+
+ | 'sidebar_divider_char' | string | '|' |
+
+ | 'sidebar_folder_indent' | boolean | 'no' |
+
+ | 'sidebar_format' | string | '%B%?F? [%F]?%* %?N?%N/?%S' |
+
+ | 'sidebar_indent_string' | string | '  ' (two spaces) |
+
+ | 'sidebar_new_mail_only' | boolean | 'no' |
+
+ | 'sidebar_next_new_wrap' | boolean | 'no' |
+
+ | 'sidebar_refresh_time' | number | '60' |
+
+ | 'sidebar_short_path' | boolean | 'no' |
+
+ | 'sidebar_sort_method' | enum | 'SORT_ORDER' |
+
+ | 'sidebar_visible' | boolean | 'no' |
+
+ | 'sidebar_whitelist' | list | (empty) |
+
+ | 'sidebar_width' | number | '20' |
+
+
+
+Functions
+
+---------
+
+
+
+ Sidebar Functions
+
+
+
+ Sidebar adds the following functions to Mutt. By default, none of them are
+
+ bound to keys.
+
+
+
+ | Menus | Function | Description |
+
+ |-------------|----------------------------|------------------------------------------------------|
+
+ | index,pager | '<sidebar-next>' | Move the highlight to next mailbox |
+
+ | index,pager | '<sidebar-next-new>' | Move the highlight to next mailbox with new mail |
+
+ | index,pager | '<sidebar-open>' | Open highlighted mailbox |
+
+ | index,pager | '<sidebar-page-down>' | Scroll the Sidebar down 1 page |
+
+ | index,pager | '<sidebar-page-up>' | Scroll the Sidebar up 1 page |
+
+ | index,pager | '<sidebar-prev>' | Move the highlight to previous mailbox |
+
+ | index,pager | '<sidebar-prev-new>' | Move the highlight to previous mailbox with new mail |
+
+ | index,pager | '<sidebar-toggle-visible>' | Make the Sidebar (in)visible |
+
+
+
+Commands
+
+--------
+
+
+
+ sidebar_whitelist mailbox [ mailbox... ]
+
+
+
+Colors
+
+------
+
+
+
+ Sidebar Colors
+
+
+
+ | Name | Default Color | Description |
+
+ |---------------------|------------------|------------------------------------------------------------------|
+
+ | 'sidebar_divider' | default | The dividing line between the Sidebar and the Index/Pager panels |
+
+ | 'sidebar_flagged' | default | Mailboxes containing flagged mail |
+
+ | 'sidebar_highlight' | underline | Cursor to select a mailbox |
+
+ | 'sidebar_indicator' | mutt 'indicator' | The mailbox open in the Index panel |
+
+ | 'sidebar_new' | default | Mailboxes containing new mail |
+
+ | 'sidebar_spoolfile' | default | Mailbox that receives incoming mail |
+
+
+
+ If the sidebar_indicator color isn't set, then the default Mutt indicator
+
+ color will be used (the color used in the index panel).
+
+
+
+Sort
+
+----
+
+
+
+ Sidebar Sort
+
+
+
+ | Sort | Description |
+
+ |------------|----------------------------|
+
+ | 'alpha' | Alphabetically by path |
+
+ | 'count' | Total number of messages |
+
+ | 'flagged' | Number of flagged messages |
+
+ | 'name' | Alphabetically by path |
+
+ | 'new' | Number of new messages |
+
+ | 'path' | Alphabetically by path |
+
+ | 'unsorted' | Do not resort the paths |
+
+
+
+See Also
+
+--------
+
+
+
+ * Regular Expressions
+
+ * Patterns
+
+ * Color command
+
+ * notmuch patch
+
+
+
+Known Bugs
+
+----------
+
+
+
+ Unsorted isn't
+
+
+
+Credits
+
+-------
+
+
+
+ * Justin Hibbits <jrh29@po.cwru.edu>
+
+ * Thomer M. Gil <mutt@thomer.com>
+
+ * David Sterba <dsterba@suse.cz>
+
+ * Evgeni Golov <evgeni@debian.org>
+
+ * Fabian Groffen <grobian@gentoo.org>
+
+ * Jason DeTiberus <jdetiber@redhat.com>
+
+ * Stefan Assmann <sassmann@kpanic.de>
+
+ * Steve Kemp <steve@steve.org.uk>
+
+ * Terry Chan <tchan@lunar-linux.org>
+
+ * Tyler Earnest <tylere@rne.st>
+
+ * Richard Russon <rich@flatcap.org>
+
+
+
diff -urN mutt-1.6.1/sidebar.c mutt-1.6.1-sidebar/sidebar.c
+
--- mutt-1.6.1/sidebar.c 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-sidebar/sidebar.c 2016-06-14 18:46:00.000000000 +0100
+
@@ -0,0 +1,1090 @@
+
+/* Copyright (C) 2004 Justin Hibbits <jrh29@po.cwru.edu>
+ * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
+
+ * Copyright (C) 2015-2016 Richard Russon <rich@flatcap.org>
+
+ *
+ * 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 "buffy.h"
+#include "keymap.h"
+
+#include "mutt_curses.h"
+
+#include "mutt_menu.h"
+
+#include "sort.h"
+
+
+/* Previous values for some sidebar config */
+
+static short OldVisible; /* sidebar_visible */
+
+static short OldWidth; /* sidebar_width */
+
+static short PreviousSort; /* sidebar_sort_method */
+
+static time_t LastRefresh; /* Time of last refresh */
+
+
+
+/* Keep track of various BUFFYs */
+
+static BUFFY *TopBuffy; /* First mailbox visible in sidebar */
+
+static BUFFY *OpnBuffy; /* Current (open) mailbox */
+
+static BUFFY *HilBuffy; /* Highlighted mailbox */
+
+static BUFFY *BotBuffy; /* Last mailbox visible in sidebar */
+
+static BUFFY *Outgoing; /* Last mailbox in the linked list */
+
+
+
+/**
+
+ * struct sidebar_entry - Info about folders in the sidebar
+
+ *
+
+ * Used in the mutt_FormatString callback
+
+ */
+
+struct sidebar_entry
+
+{
+
+ char box[STRING];
+
+ BUFFY *buffy;
+
+};
+
+
+
+
+/**
+
+ * find_next_new - Find the next folder that contains new mail
+
+ * @wrap: Wrap around to the beginning if the end is reached
+
+ *
+
+ * Search down the list of mail folders for one containing new mail.
+
+ *
+
+ * Returns:
+
+ * BUFFY*: Success
+
+ * NULL: Failure
+
+ */
+
+static BUFFY *find_next_new (int wrap)
+{
+
+ BUFFY *b = HilBuffy;
+
+ if (!b)
+
+ return NULL;
+
+
+
+ do
+
+ {
+
+ b = b->next;
+
+ if (!b && wrap)
+
+ b = Incoming;
+
+ if (!b || (b == HilBuffy))
+
+ break;
+
+ if (b->msg_unread > 0)
+
+ return b;
+
+ } while (b);
+
+
+
+ return NULL;
+}
+
+
+/**
+
+ * find_prev_new - Find the previous folder that contains new mail
+
+ * @wrap: Wrap around to the beginning if the end is reached
+
+ *
+
+ * Search up the list of mail folders for one containing new mail.
+
+ *
+
+ * Returns:
+
+ * BUFFY*: Success
+
+ * NULL: Failure
+
+ */
+
+static BUFFY *find_prev_new (int wrap)
+{
+
+ BUFFY *b = HilBuffy;
+
+ if (!b)
+
+ return NULL;
+
+
+ do
+
+ {
+
+ b = b->prev;
+
+ if (!b && wrap)
+
+ b = Outgoing;
+
+ if (!b || (b == HilBuffy))
+
+ break;
+
+ if (b->msg_unread > 0)
+
+ return b;
+
+ } while (b);
+
+
+ return NULL;
+}
+
+
+/**
+
+ * cb_format_str - Create the string to show in the sidebar
+
+ * @dest: Buffer in which to save string
+
+ * @destlen: Buffer length
+
+ * @col: Starting column, UNUSED
+
+ * @op: printf-like operator, e.g. 'B'
+
+ * @src: printf-like format string
+
+ * @prefix: Field formatting string, UNUSED
+
+ * @ifstring: If condition is met, display this string
+
+ * @elsestring: Otherwise, display this string
+
+ * @data: Pointer to our sidebar_entry
+
+ * @flags: Format flags, e.g. M_FORMAT_OPTIONAL
+
+ *
+
+ * cb_format_str is a callback function for mutt_FormatString. It understands
+
+ * five operators. '%B' : Mailbox name, '%F' : Number of flagged messages,
+
+ * '%N' : Number of new messages, '%S' : Size (total number of messages),
+
+ * '%!' : Icon denoting number of flagged messages.
+
+ *
+
+ * Returns: src (unchanged)
+
+ */
+
+static const char *cb_format_str(char *dest, size_t destlen, size_t col, char op,
+
+ const char *src, const char *prefix, const char *ifstring,
+
+ const char *elsestring, unsigned long data, format_flag flags)
+{
+
+ struct sidebar_entry *sbe = (struct sidebar_entry *) data;
+
+ unsigned int optional;
+
+ char fmt[STRING];
+
+
+
+ if (!sbe || !dest)
+
+ return src;
+
+
+
+ dest[0] = 0; /* Just in case there's nothing to do */
+
+
+
+ BUFFY *b = sbe->buffy;
+
+ if (!b)
+
+ return src;
+
+
+
+ int c = Context && (mutt_strcmp (Context->path, b->path) == 0);
+
+
+
+ optional = flags & M_FORMAT_OPTIONAL;
+
+
+
+ switch (op)
+
+ {
+
+ case 'B':
+
+ mutt_format_s (dest, destlen, prefix, sbe->box);
+
+ break;
+
+
+
+ case 'd':
+
+ if (!optional)
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+
+ snprintf (dest, destlen, fmt, c ? Context->deleted : 0);
+
+ }
+
+ else if ((c && Context->deleted == 0) || !c)
+
+ optional = 0;
+
+ break;
+
+
+ case 'F':
+
+ if (!optional)
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+
+ snprintf (dest, destlen, fmt, b->msg_flagged);
+
+ }
+
+ else if (b->msg_flagged == 0)
+
+ optional = 0;
+
+ break;
+
+
+ case 'L':
+
+ if (!optional)
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+
+ snprintf (dest, destlen, fmt, c ? Context->vcount : b->msg_count);
+
+ }
+
+ else if ((c && Context->vcount == b->msg_count) || !c)
+
+ optional = 0;
+
+ break;
+
+
+
+ case 'N':
+
+ if (!optional)
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+
+ snprintf (dest, destlen, fmt, b->msg_unread);
+
+ }
+
+ else if (b->msg_unread == 0)
+
+ optional = 0;
+
+ break;
+
+
+
+ case 'S':
+
+ if (!optional)
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+
+ snprintf (dest, destlen, fmt, b->msg_count);
+
+ }
+
+ else if (b->msg_count == 0)
+
+ optional = 0;
+
+ break;
+
+
+
+ case 't':
+
+ if (!optional)
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+
+ snprintf (dest, destlen, fmt, c ? Context->tagged : 0);
+
+ }
+
+ else if ((c && Context->tagged == 0) || !c)
+
+ optional = 0;
+
+ break;
+
+
+
+ case '!':
+
+ if (b->msg_flagged == 0)
+
+ mutt_format_s (dest, destlen, prefix, "");
+
+ else if (b->msg_flagged == 1)
+
+ mutt_format_s (dest, destlen, prefix, "!");
+
+ else if (b->msg_flagged == 2)
+
+ mutt_format_s (dest, destlen, prefix, "!!");
+
+ else
+
+ {
+
+ snprintf (fmt, sizeof (fmt), "%d!", b->msg_flagged);
+
+ mutt_format_s (dest, destlen, prefix, fmt);
+
+ }
+
+ break;
+
+ }
+
+
+
+ if (optional)
+
+ mutt_FormatString (dest, destlen, col, ifstring, cb_format_str, (unsigned long) sbe, flags);
+
+ else if (flags & M_FORMAT_OPTIONAL)
+
+ mutt_FormatString (dest, destlen, col, elsestring, cb_format_str, (unsigned long) sbe, flags);
+
+
+
+ /* We return the format string, unchanged */
+
+ return src;
+}
+
+
+/**
+
+ * make_sidebar_entry - Turn mailbox data into a sidebar string
+
+ * @buf: Buffer in which to save string
+
+ * @buflen: Buffer length
+
+ * @width: Desired width in screen cells
+
+ * @box: Mailbox name
+
+ * @size: Size (total number of messages)
+
+ * @new: Number of new messages
+
+ * @flagged: Number of flagged messages
+
+ *
+
+ * Take all the relevant mailbox data and the desired screen width and then get
+
+ * mutt_FormatString to do the actual work. mutt_FormatString will callback to
+
+ * us using cb_format_str() for the sidebar specific formatting characters.
+
+ */
+
+static void make_sidebar_entry (char *buf, unsigned int buflen, int width, char *box,
+
+ BUFFY *b)
+{
+
+ struct sidebar_entry sbe;
+
+
+ if (!buf || !box || !b)
+ return;
+
+
+ sbe.buffy = b;
+
+ strfcpy (sbe.box, box, sizeof (sbe.box));
+
+
+
+ /* Temporarily lie about the screen width */
+
+ int oc = COLS;
+
+ COLS = width + SidebarWidth;
+
+ mutt_FormatString (buf, buflen, 0, NONULL(SidebarFormat), cb_format_str, (unsigned long) &sbe, 0);
+
+ COLS = oc;
+
+
+
+ /* Force string to be exactly the right width */
+
+ int w = mutt_strwidth (buf);
+
+ int s = strlen (buf);
+
+ width = MIN(buflen, width);
+
+ if (w < width)
+
+ {
+
+ /* Pad with spaces */
+
+ memset (buf + s, ' ', width - w);
+
+ buf[s + width - w] = 0;
+
+ }
+
+ else if (w > width)
+
+ {
+
+ /* Truncate to fit */
+
+ int len = mutt_wstr_trunc (buf, buflen, width, NULL);
+
+ buf[len] = 0;
+
+ }
+
+}
+
+
+
+/**
+
+ * cb_qsort_buffy - qsort callback to sort BUFFYs
+
+ * @a: First BUFFY to compare
+
+ * @b: Second BUFFY to compare
+
+ *
+
+ * Compare the paths of two BUFFYs taking the locale into account.
+
+ *
+
+ * Returns:
+
+ * -1: a precedes b
+
+ * 0: a and b are identical
+
+ * 1: b precedes a
+
+ */
+
+static int cb_qsort_buffy (const void *a, const void *b)
+
+{
+
+ const BUFFY *b1 = *(const BUFFY **) a;
+
+ const BUFFY *b2 = *(const BUFFY **) b;
+
+
+
+ /* Special case -- move hidden BUFFYs to the end */
+
+ if (b1->is_hidden != b2->is_hidden)
+
+ {
+
+ if (b1->is_hidden)
+
+ return 1;
+
+ else
+
+ return -1;
+
+ }
+
+
+
+ int result = 0;
+
+
+
+ switch ((SidebarSortMethod & SORT_MASK))
+
+ {
+
+ case SORT_COUNT:
+
+ result = (b2->msg_count - b1->msg_count);
+ break;
+
+ case SORT_COUNT_NEW:
+
+ result = (b2->msg_unread - b1->msg_unread);
+
+ break;
+
+ case SORT_FLAGGED:
+
+ result = (b2->msg_flagged - b1->msg_flagged);
+
+ break;
+
+ case SORT_PATH:
+
+ result = mutt_strcasecmp (b1->path, b2->path);
+
+ break;
+
+ }
+
+
+
+ if (SidebarSortMethod & SORT_REVERSE)
+
+ result = -result;
+
+
+
+ return result;
+
+}
+
+
+
+/**
+
+ * buffy_going - Prevent our pointers becoming invalid
+
+ * @b: BUFFY about to be deleted
+
+ *
+
+ * If we receive a delete-notification for a BUFFY, we need to change any
+
+ * pointers we have to reference a different BUFFY, or set them to NULL.
+
+ *
+
+ * We don't update the prev/next pointers, they'll be fixed on the next
+
+ * call to prepare_sidebar().
+
+ *
+
+ * Returns:
+
+ * A valid alternative BUFFY, or NULL
+
+ */
+
+static BUFFY *buffy_going (const BUFFY *b)
+
+{
+
+ if (!b)
+
+ return NULL;
+
+
+
+ if (b->prev)
+
+ {
+
+ b->prev->next = NULL;
+
+ }
+
+
+
+ if (b->next)
+
+ {
+
+ b->next->prev = NULL;
+
+ return b->next;
+
+ }
+
+
+
+ return b->prev;
+
+}
+
+
+
+/**
+
+ * update_buffy_visibility - Should a BUFFY be displayed in the sidebar
+
+ * @arr: array of BUFFYs
+
+ * @arr_len: number of BUFFYs in array
+
+ *
+
+ * For each BUFFY in the array, check whether we should display it.
+
+ * This is determined by several criteria. If the BUFFY:
+
+ * is the currently open mailbox
+
+ * is the currently highlighted mailbox
+
+ * has unread messages
+
+ * has flagged messages
+
+ * is whitelisted
+
+ */
+
+static void update_buffy_visibility (BUFFY **arr, int arr_len)
+
+{
+
+ if (!arr)
+
+ return;
+
+
+
+ short new_only = option (OPTSIDEBARNEWMAILONLY);
+
+
+
+ BUFFY *b;
+
+ int i;
+
+ for (i = 0; i < arr_len; i++)
+
+ {
+
+ b = arr[i];
+
+
+
+ b->is_hidden = 0;
+
+
+
+ if (!new_only)
+
+ continue;
+
+
+
+ if ((b == OpnBuffy) || (b->msg_unread > 0) ||
+
+ (b == HilBuffy) || (b->msg_flagged > 0))
+
+ continue;
+
+
+
+ if (Context && (strcmp (b->path, Context->path) == 0))
+
+ /* Spool directory */
+
+ continue;
+
+
+
+ if (mutt_find_list (SidebarWhitelist, b->path))
+
+ /* Explicitly asked to be visible */
+
+ continue;
+
+
+
+ b->is_hidden = 1;
+
+ }
+
+}
+
+
+
+/**
+
+ * sort_buffy_array - Sort an array of BUFFY pointers
+
+ * @arr: array of BUFFYs
+
+ * @arr_len: number of BUFFYs in array
+
+ *
+
+ * Sort an array of BUFFY pointers according to the current sort config
+
+ * option "sidebar_sort_method". This calls qsort to do the work which calls our
+
+ * callback function "cb_qsort_buffy".
+
+ *
+
+ * Once sorted, the prev/next links will be reconstructed.
+
+ */
+
+static void sort_buffy_array (BUFFY **arr, int arr_len)
+
+{
+
+ if (!arr)
+
+ return;
+
+
+
+ /* These are the only sort methods we understand */
+
+ short ssm = (SidebarSortMethod & SORT_MASK);
+
+ if ((ssm == SORT_COUNT) ||
+
+ (ssm == SORT_COUNT_NEW) ||
+
+ (ssm == SORT_DESC) ||
+
+ (ssm == SORT_FLAGGED) ||
+
+ (ssm == SORT_PATH))
+
+ qsort (arr, arr_len, sizeof (*arr), cb_qsort_buffy);
+
+
+
+ int i;
+
+ for (i = 0; i < (arr_len - 1); i++)
+
+ arr[i]->next = arr[i + 1];
+
+ arr[arr_len - 1]->next = NULL;
+
+
+
+ for (i = 1; i < arr_len; i++)
+
+ arr[i]->prev = arr[i - 1];
+
+ arr[0]->prev = NULL;
+
+}
+
+
+
+/**
+
+ * prepare_sidebar - Prepare the list of BUFFYs for the sidebar display
+
+ * @page_size: The number of lines on a page
+
+ *
+
+ * Before painting the sidebar, we count the BUFFYs, determine which are
+
+ * visible, sort them and set up our page pointers.
+
+ *
+
+ * This is a lot of work to do each refresh, but there are many things that
+
+ * can change outside of the sidebar that we don't hear about.
+
+ *
+
+ * Returns:
+
+ * 0: No, don't draw the sidebar
+
+ * 1: Yes, draw the sidebar
+
+ */
+
+static int prepare_sidebar (int page_size)
+
+{
+
+ BUFFY *b = Incoming;
+
+ if (!b)
+
+ return 0;
+
+
+
+ int count = 0;
+
+ for (; b; b = b->next)
+
+ count++;
+
+
+
+ BUFFY **arr = safe_malloc (count * sizeof (*arr));
+
+
+
+ int i = 0;
+
+ for (b = Incoming; b; b = b->next, i++)
+
+ arr[i] = b;
+
+
+
+ update_buffy_visibility (arr, count);
+
+ sort_buffy_array (arr, count);
+
+
+
+ Incoming = arr[0];
+
+
+
+ int top_index = 0;
+
+ int opn_index = -1;
+
+ int hil_index = -1;
+
+ int bot_index = -1;
+
+
+
+ for (i = 0; i < count; i++)
+
+ {
+
+ if (OpnBuffy == arr[i])
+
+ opn_index = i;
+
+ if (HilBuffy == arr[i])
+
+ hil_index = i;
+
+ }
+
+
+
+ if (!HilBuffy || (SidebarSortMethod != PreviousSort))
+
+ {
+
+ if (OpnBuffy)
+
+ {
+
+ HilBuffy = OpnBuffy;
+
+ hil_index = opn_index;
+ }
+
+ else
+
+ {
+
+ HilBuffy = arr[0];
+
+ hil_index = 0;
+
+ }
+
+ }
+
+ if (TopBuffy)
+
+ top_index = (hil_index / page_size) * page_size;
+
+ else
+
+ top_index = hil_index;
+
+ TopBuffy = arr[top_index];
+
+
+ bot_index = top_index + page_size - 1;
+
+ if (bot_index > (count - 1))
+
+ bot_index = count - 1;
+
+ BotBuffy = arr[bot_index];
+
+
+
+ Outgoing = arr[count - 1];
+
+
+
+ PreviousSort = SidebarSortMethod;
+
+ FREE (&arr);
+
+ return 1;
+
+}
+
+
+
+/**
+
+ * visible - Should we display the sidebar?
+
+ *
+
+ * After validating the config options "sidebar_visible" and "sidebar_width",
+
+ * determine whether we should should display the sidebar.
+
+ *
+
+ * When not visible, set the global SidebarWidth to 0.
+
+ *
+
+ * Returns:
+
+ * Boolean
+
+ */
+
+static short
+
+visible (void)
+
+{
+
+ short new_visible = option (OPTSIDEBAR);
+
+ short new_width = SidebarWidth;
+
+
+
+ if (OldWidth != new_width)
+
+ {
+
+ if (new_width > 0)
+
+ {
+
+ OldWidth = new_width;
+
+ }
+
+ }
+
+
+
+ if (OldVisible != new_visible)
+
+ {
+
+ if (new_visible)
+
+ {
+
+ set_option (OPTSIDEBAR);
+
+ }
+ else
+
+ {
+
+ unset_option (OPTSIDEBAR);
+
+ }
+
+ OldVisible = new_visible;
+
+ }
+
+ else if (new_width == 0)
+
+ {
+
+ unset_option (OPTSIDEBAR);
+
+ OldVisible = 0;
+
+ }
+
+
+
+ if (!option (OPTSIDEBAR))
+
+ {
+
+ SidebarWidth = 0;
+
+ }
+
+ else if (new_width == 0)
+
+ {
+
+ SidebarWidth = OldWidth;
+
+ }
+
+ else
+
+ {
+
+ SidebarWidth = new_width;
+ }
+
+
+
+ return new_visible;
+}
+
+
+/**
+
+ * draw_divider - Draw a line between the sidebar and the rest of mutt
+
+ * @first_row: Screen line to start (0-based)
+
+ * @num_rows: Number of rows to fill
+
+ *
+
+ * Draw a divider using characters from the config option "sidebar_divider_char".
+
+ * This can be an ASCII or Unicode character. First we calculate this
+
+ * characters' width in screen columns, then subtract that from the config
+
+ * option "sidebar_width".
+
+ *
+
+ * Returns:
+
+ * -1: Error: bad character, etc
+
+ * 0: Error: 0 width character
+
+ * n: Success: character occupies n screen columns
+
+ */
+
+static int draw_divider (int first_row, int num_rows)
+
+{
+
+ /* Calculate the width of the delimiter in screen cells */
+
+ int delim_len = mutt_strwidth (SidebarDividerChar);
+
+
+
+ if (delim_len < 1)
+
+ return delim_len;
+
+
+
+ if ((SidebarWidth + delim_len) > (COLS + 1))
+
+ return 0;
+
+
+
+ if (delim_len > SidebarWidth)
+
+ return -1;
+
+
+
+ SETCOLOR(MT_COLOR_DIVIDER);
+
+
+
+ int i;
+
+ for (i = 0; i < num_rows; i++)
+
+ {
+
+ move (first_row + i, SidebarWidth - delim_len);
+
+ addstr (NONULL(SidebarDividerChar));
+
+ }
+
+
+
+ return delim_len;
+
+}
+
+
+
+/**
+
+ * fill_empty_space - Wipe the remaining Sidebar space
+
+ * @first_row: Screen line to start (0-based)
+
+ * @num_rows: Number of rows to fill
+
+ * @width: Width of the Sidebar (minus the divider)
+
+ *
+
+ * Write spaces over the area the sidebar isn't using.
+
+ */
+
+static void fill_empty_space (int first_row, int num_rows, int width)
+
+{
+
+ /* Fill the remaining rows with blank space */
+
+ SETCOLOR(MT_COLOR_NORMAL);
+
+
+ int r;
+
+ for (r = 0; r < num_rows; r++)
+
+ {
+
+ int i = 0;
+
+ move (first_row + r, 0);
+
+ for (; i < width; i++)
+
+ addch (' ');
+
+ }
+
+}
+
+
+
+/**
+
+ * draw_sidebar - Write out a list of mailboxes, on the left
+
+ * @first_row: Screen line to start (0-based)
+
+ * @num_rows: Number of rows to fill
+
+ * @div_width: Width in screen characters taken by the divider
+
+ *
+
+ * Display a list of mailboxes in a panel on the left. What's displayed will
+
+ * depend on our index markers: TopBuffy, OpnBuffy, HilBuffy, BotBuffy.
+
+ * On the first run they'll be NULL, so we display the top of Mutt's list
+
+ * (Incoming).
+
+ *
+
+ * TopBuffy - first visible mailbox
+
+ * BotBuffy - last visible mailbox
+
+ * OpnBuffy - mailbox shown in Mutt's Index Panel
+
+ * HilBuffy - Unselected mailbox (the paging follows this)
+
+ *
+
+ * The entries are formatted using "sidebar_format" and may be abbreviated:
+
+ * "sidebar_short_path", indented: "sidebar_folder_indent",
+
+ * "sidebar_indent_string" and sorted: "sidebar_sort_method". Finally, they're
+
+ * trimmed to fit the available space.
+
+ */
+
+static void draw_sidebar (int first_row, int num_rows, int div_width)
+
+{
+
+ BUFFY *b = TopBuffy;
+
+ if (!b)
+
+ return;
+
+
+ int w = MIN(COLS, (SidebarWidth - div_width));
+
+ int row = 0;
+
+ for (b = TopBuffy; b && (row < num_rows); b = b->next)
+
+ {
+
+ if (b->is_hidden)
+
+ continue;
+
+
+ if (b == OpnBuffy)
+
+ {
+
+ if ((ColorDefs[MT_COLOR_SB_INDICATOR] != 0))
+
+ SETCOLOR(MT_COLOR_SB_INDICATOR);
+
+ else
+
+ SETCOLOR(MT_COLOR_INDICATOR);
+
+ }
+
+ else if (b == HilBuffy)
+
+ SETCOLOR(MT_COLOR_HIGHLIGHT);
+
+ else if ((ColorDefs[MT_COLOR_SB_SPOOLFILE] != 0) &&
+
+ (mutt_strcmp (b->path, Spoolfile) == 0))
+
+ SETCOLOR(MT_COLOR_SB_SPOOLFILE);
+
+ else if (b->msg_unread > 0)
+
+ SETCOLOR(MT_COLOR_NEW);
+
+ else if (b->msg_flagged > 0)
+
+ SETCOLOR(MT_COLOR_FLAGGED);
+
+ else
+
+ SETCOLOR(MT_COLOR_NORMAL);
+
+
+
+ move (first_row + row, 0);
+
+ if (Context && Context->path &&
+
+ (!strcmp (b->path, Context->path)||
+
+ !strcmp (b->realpath, Context->path)))
+
+ {
+
+ b->msg_unread = Context->unread;
+
+ b->msg_count = Context->msgcount;
+
+ b->msg_flagged = Context->flagged;
+
+ }
+
+
+
+ /* compute length of Maildir without trailing separator */
+
+ size_t maildirlen = strlen (Maildir);
+
+ if (SidebarDelimChars && strchr (SidebarDelimChars, Maildir[maildirlen - 1]))
+
+ maildirlen--;
+
+
+
+ /* check whether Maildir is a prefix of the current folder's path */
+
+ short maildir_is_prefix = 0;
+
+ if ((strlen (b->path) > maildirlen) && (strncmp (Maildir, b->path, maildirlen) == 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;
+
+ int i;
+
+ if (option (OPTSIDEBARSHORTPATH))
+
+ {
+
+ /* disregard a trailing separator, so strlen() - 2 */
+
+ sidebar_folder_name = b->path;
+
+ for (i = strlen (sidebar_folder_name) - 2; i >= 0; i--)
+
+ {
+
+ if (SidebarDelimChars &&
+
+ strchr (SidebarDelimChars, sidebar_folder_name[i]))
+
+ {
+
+ sidebar_folder_name += (i + 1);
+
+ break;
+ }
+
+ }
+
+ }
+
+ else
+
+ sidebar_folder_name = b->path + maildir_is_prefix * (maildirlen + 1);
+
+
+ if (maildir_is_prefix && option (OPTSIDEBARFOLDERINDENT))
+
+ {
+
+ const char *tmp_folder_name;
+
+ int lastsep = 0;
+
+ tmp_folder_name = b->path + maildirlen + 1;
+
+ int tmplen = (int) strlen (tmp_folder_name) - 1;
+
+ for (i = 0; i < tmplen; i++)
+
+ {
+
+ if (SidebarDelimChars && strchr (SidebarDelimChars, tmp_folder_name[i]))
+
+ {
+
+ sidebar_folder_depth++;
+
+ lastsep = i + 1;
+ }
+
+ }
+
+ if (sidebar_folder_depth > 0)
+
+ {
+
+ if (option (OPTSIDEBARSHORTPATH))
+
+ tmp_folder_name += lastsep; /* basename */
+
+ sidebar_folder_name = malloc (strlen (tmp_folder_name) + sidebar_folder_depth*strlen (NONULL(SidebarIndentString)) + 1);
+
+ sidebar_folder_name[0]=0;
+
+ for (i=0; i < sidebar_folder_depth; i++)
+
+ strncat (sidebar_folder_name, NONULL(SidebarIndentString), strlen (NONULL(SidebarIndentString)));
+
+ strncat (sidebar_folder_name, tmp_folder_name, strlen (tmp_folder_name));
+
+ }
+
+ }
+
+ char str[STRING];
+
+ make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, b);
+
+ printw ("%s", str);
+
+ if (sidebar_folder_depth > 0)
+
+ FREE (&sidebar_folder_name);
+
+ row++;
+
+ }
+
+
+ fill_empty_space (first_row + row, num_rows - row, w);
+
+}
+
+
+
+/**
+
+ * mutt_sb_init - Set some default values for the sidebar.
+
+ */
+
+void
+
+mutt_sb_init (void)
+
+{
+
+ OldVisible = option (OPTSIDEBAR);
+
+ if (SidebarWidth > 0)
+
+ {
+
+ OldWidth = SidebarWidth;
+
+ }
+
+ else
+
+ {
+
+ OldWidth = 20;
+
+ if (OldVisible)
+
+ {
+
+ SidebarWidth = OldWidth;
+ }
+
+ }
+
+}
+
+
+/**
+
+ * mutt_sb_draw - Completely redraw the sidebar
+
+ *
+
+ * Completely refresh the sidebar region. First draw the divider; then, for
+
+ * each BUFFY, call make_sidebar_entry; finally blank out any remaining space.
+
+ */
+
+void mutt_sb_draw (void)
+
+{
+
+ if (!visible())
+
+ return;
+
+
+ /* XXX - if transitioning from invisible to visible */
+
+ /* if (OldVisible == 0) */
+
+ /* mutt_buffy_check (1); we probably have bad or no numbers */
+
+
+ int x = getcurx (stdscr);
+
+ int y = getcury (stdscr);
+
+
+ int first_row = 0;
+
+ int num_rows = LINES - 2;
+
+
+ if (option (OPTHELP) || option (OPTSTATUSONTOP))
+
+ first_row++;
+
+
+ if (option (OPTHELP))
+
+ num_rows--;
+
+
+
+ int div_width = draw_divider (first_row, num_rows);
+
+ if (div_width < 0)
+
+ return;
+
+
+ if (!Incoming)
+
+ {
+
+ int w = MIN(COLS, (SidebarWidth - div_width));
+
+ fill_empty_space (first_row, num_rows, w);
+
+ return;
+
+ }
+
+
+
+ if (!prepare_sidebar (num_rows))
+
+ return;
+
+
+
+ draw_sidebar (first_row, num_rows, div_width);
+
+ move (y, x);
+
+}
+
+
+
+/**
+
+ * mutt_sb_should_refresh - Check if the sidebar is due to be refreshed
+
+ *
+
+ * The "sidebar_refresh_time" config option allows the user to limit the frequency
+
+ * with which the sidebar is refreshed.
+
+ *
+
+ * Returns:
+
+ * 1 Yes, refresh is due
+
+ * 0 No, refresh happened recently
+
+ */
+
+int mutt_sb_should_refresh (void)
+
+{
+
+ if (!option (OPTSIDEBAR))
+
+ return 0;
+
+
+
+ if (SidebarRefreshTime == 0)
+
+ return 0;
+
+
+
+ time_t diff = (time (NULL) - LastRefresh);
+
+
+
+ return (diff >= SidebarRefreshTime);
+
+}
+
+
+/**
+
+ * mutt_sb_change_mailbox - Change the selected mailbox
+
+ * @op: Operation code
+
+ *
+
+ * Change the selected mailbox, e.g. "Next mailbox", "Previous Mailbox
+
+ * with new mail". The operations are listed OPS.SIDEBAR which is built
+
+ * into an enum in keymap_defs.h.
+
+ *
+
+ * If the operation is successful, HilBuffy will be set to the new mailbox.
+
+ * This function only *selects* the mailbox, doesn't *open* it.
+
+ *
+
+ * Allowed values are: OP_SIDEBAR_NEXT, OP_SIDEBAR_NEXT_NEW,
+
+ * OP_SIDEBAR_PAGE_DOWN, OP_SIDEBAR_PAGE_UP, OP_SIDEBAR_PREV,
+
+ * OP_SIDEBAR_PREV_NEW.
+
+ */
+
+void mutt_sb_change_mailbox (int op)
+
+{
+
+ BUFFY *b;
+
+ if (!HilBuffy) /* It'll get reset on the next draw */
+
+ return;
+
+
+
+ switch (op)
+
+ {
+
+ case OP_SIDEBAR_NEXT:
+
+ if (!HilBuffy->next)
+
+ return;
+
+ if (HilBuffy->next->is_hidden)
+
+ return;
+
+ HilBuffy = HilBuffy->next;
+
+ break;
+
+ case OP_SIDEBAR_NEXT_NEW:
+
+ b = find_next_new (option (OPTSIDEBARNEXTNEWWRAP));
+
+ if (!b)
+
+ return;
+
+ else
+
+ HilBuffy = b;
+
+ break;
+
+ case OP_SIDEBAR_PAGE_DOWN:
+
+ HilBuffy = BotBuffy;
+
+ if (HilBuffy->next)
+
+ HilBuffy = HilBuffy->next;
+
+ break;
+
+ case OP_SIDEBAR_PAGE_UP:
+
+ HilBuffy = TopBuffy;
+
+ if (HilBuffy != Incoming)
+
+ HilBuffy = HilBuffy->prev;
+
+ break;
+
+ case OP_SIDEBAR_PREV:
+
+ if (!HilBuffy->prev)
+
+ return;
+
+ if (HilBuffy->prev->is_hidden) /* Can't happen, we've sorted the hidden to the end */
+
+ return;
+
+ HilBuffy = HilBuffy->prev;
+
+ break;
+
+ case OP_SIDEBAR_PREV_NEW:
+
+ b = find_prev_new (option (OPTSIDEBARNEXTNEWWRAP));
+
+ if (!b)
+
+ return;
+
+ else
+
+ HilBuffy = b;
+
+ break;
+
+ default:
+
+ return;
+
+ }
+
+
+
+ /* We can change folder even if the sidebar is hidden */
+
+ if (option (OPTSIDEBAR))
+
+ mutt_sb_draw();
+
+}
+
+
+
+/**
+
+ * mutt_sb_set_buffystats - Update the BUFFY's message counts from the CONTEXT
+
+ * @ctx: A mailbox CONTEXT
+
+ *
+
+ * Given a mailbox CONTEXT, find a matching mailbox BUFFY and copy the message
+
+ * counts into it.
+
+ */
+
+void mutt_sb_set_buffystats (const CONTEXT *ctx)
+
+{
+
+ /* Even if the sidebar's hidden,
+
+ * we should take note of the new data. */
+
+ BUFFY *b = Incoming;
+
+ if (!ctx || !b)
+
+ return;
+
+
+ for (; b; b = b->next)
+
+ {
+
+ if (!strcmp (b->path, ctx->path) ||
+
+ !strcmp (b->realpath, ctx->path))
+
+ {
+
+ b->msg_unread = ctx->unread;
+
+ b->msg_count = ctx->msgcount;
+
+ b->msg_flagged = ctx->flagged;
+
+ break;
+
+ }
+
+ }
+}
+
+
+/**
+
+ * mutt_sb_get_highlight - Get the BUFFY that's highlighted in the sidebar
+
+ *
+
+ * Get the path of the mailbox that's highlighted in the sidebar.
+
+ *
+
+ * Returns:
+
+ * Mailbox path
+
+ */
+
+const char *mutt_sb_get_highlight (void)
+
+{
+
+ if (!HilBuffy)
+
+ return NULL;
+
+
+ return HilBuffy->path;
+
+}
+
+
+
+/**
+
+ * mutt_sb_set_open_buffy - Set the OpnBuffy based on a mailbox path
+
+ * @path: Mailbox path
+
+ *
+
+ * Search through the list of mailboxes. If a BUFFY has a matching path, set
+
+ * OpnBuffy to it.
+
+ */
+
+BUFFY *mutt_sb_set_open_buffy (const char *path)
+{
+
+ /* Even if the sidebar is hidden */
+
+
+
+ BUFFY *b = Incoming;
+
+
+
+ if (!path || !b)
+
+ return NULL;
+
+
+
+ OpnBuffy = NULL;
+
+
+
+ for (; b; b = b->next)
+
+ {
+
+ if (!strcmp (b->path, path) ||
+
+ !strcmp (b->realpath, path))
+
+ {
+
+ OpnBuffy = b;
+
+ HilBuffy = b;
+
+ break;
+
+ }
+
+ }
+
+
+
+ return OpnBuffy;
+}
+
+
+/**
+
+ * mutt_sb_set_update_time - Note the time that the sidebar was updated
+
+ *
+
+ * Update the timestamp representing the last sidebar update. If the user
+
+ * configures "sidebar_refresh_time", this will help to reduce traffic.
+
+ */
+
+void mutt_sb_set_update_time (void)
+{
+
+ /* XXX - should this be public? */
+
+
+ LastRefresh = time (NULL);
+}
+
+
+/**
+
+ * mutt_sb_notify_mailbox - The state of a BUFFY is about to change
+
+ *
+
+ * We receive a notification:
+
+ * After a new BUFFY has been created
+
+ * Before a BUFFY is deleted
+
+ *
+
+ * Before a deletion, check that our pointers won't be invalidated.
+
+ */
+
+void mutt_sb_notify_mailbox (BUFFY *b, int created)
+
+{
+
+ if (!b)
+
+ return;
+
+
+
+ /* Any new/deleted mailboxes will cause a refresh. As long as
+
+ * they're valid, our pointers will be updated in prepare_sidebar() */
+
+
+
+ if (created)
+
+ {
+
+ if (!TopBuffy)
+
+ TopBuffy = b;
+
+ if (!HilBuffy)
+
+ HilBuffy = b;
+
+ if (!BotBuffy)
+
+ BotBuffy = b;
+
+ if (!Outgoing)
+
+ Outgoing = b;
+
+ if (!OpnBuffy && Context)
+
+ {
+
+ /* This might happen if the user "unmailboxes *", then
+
+ * "mailboxes" our current mailbox back again */
+
+ if (mutt_strcmp (b->path, Context->path) == 0)
+
+ OpnBuffy = b;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ BUFFY *replacement = buffy_going (b);
+
+ if (TopBuffy == b)
+
+ TopBuffy = replacement;
+
+ if (OpnBuffy == b)
+
+ OpnBuffy = NULL;
+
+ if (HilBuffy == b)
+
+ HilBuffy = replacement;
+
+ if (BotBuffy == b)
+
+ BotBuffy = replacement;
+
+ if (Outgoing == b)
+
+ Outgoing = replacement;
+
+ }
+
+}
+
diff -urN mutt-1.6.1/sidebar.h mutt-1.6.1-sidebar/sidebar.h
+
--- mutt-1.6.1/sidebar.h 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-sidebar/sidebar.h 2016-06-12 18:43:03.967503185 +0100
@@ -0,0 +1,36 @@
+
+/* Copyright (C) 2004 Justin Hibbits <jrh29@po.cwru.edu>
+ * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
+
+ * Copyright (C) 2015-2016 Richard Russon <rich@flatcap.org>
+
+ *
+ * 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
+
+
+#include "mutt.h"
+
+#include "buffy.h"
+
+
+void mutt_sb_change_mailbox (int op);
+
+void mutt_sb_draw (void);
+
+const char * mutt_sb_get_highlight (void);
+
+void mutt_sb_init (void);
+
+void mutt_sb_notify_mailbox (BUFFY *b, int created);
+
+void mutt_sb_set_buffystats (const CONTEXT *ctx);
+
+BUFFY * mutt_sb_set_open_buffy (const char *path);
+
+void mutt_sb_set_update_time (void);
+
+int mutt_sb_should_refresh (void);
+
+#endif /* SIDEBAR_H */
+
diff -urN mutt-1.6.1/sort.h mutt-1.6.1-sidebar/sort.h
+
--- mutt-1.6.1/sort.h 2016-06-12 18:43:00.415447793 +0100
+
+++ mutt-1.6.1-sidebar/sort.h 2016-06-12 18:43:03.968503200 +0100
+
@@ -31,6 +31,12 @@
+
#define SORT_KEYID 12
+
#define SORT_TRUST 13
+
#define SORT_SPAM 14
+
+#define SORT_COUNT 15
+
+#define SORT_COUNT_NEW 16
+
+#define SORT_DESC 17
+
+#define SORT_FLAGGED 18
+
+#define SORT_PATH 19
+
+
+
/* dgc: Sort & SortAux are shorts, so I'm bumping these bitflags up from
+
* bits 4 & 5 to bits 8 & 9 to make room for more sort keys in the future. */
+
#define SORT_MASK 0xff
+
@@ -50,6 +56,7 @@
+
WHERE short Sort INITVAL (SORT_DATE);
+
WHERE short SortAux INITVAL (SORT_DATE); /* auxiliary sorting method */
+
WHERE short SortAlias INITVAL (SORT_ALIAS);
+
+WHERE short SidebarSortMethod INITVAL (SORT_ORDER);
+
+
/* FIXME: This one does not belong to here */
+
WHERE short PgpSortKeys INITVAL (SORT_ADDRESS);
-316
pkgs/applications/networking/mailreaders/mutt/trash-folder.patch
···
-
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
···
···
+
diff -urN mutt-1.6.1/commands.c mutt-1.6.1-trash/commands.c
+
--- mutt-1.6.1/commands.c 2016-06-12 18:43:00.397447512 +0100
+
+++ mutt-1.6.1-trash/commands.c 2016-06-12 18:43:04.892517610 +0100
+
@@ -720,6 +720,7 @@
+
if (option (OPTDELETEUNTAG))
+
mutt_set_flag (Context, h, M_TAG, 0);
+
}
+
+ mutt_set_flag (Context, h, M_APPENDED, 1);
+
+
return 0;
+
}
+
diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-trash/curs_main.c
+
--- mutt-1.6.1/curs_main.c 2016-06-12 18:43:00.399447544 +0100
+
+++ mutt-1.6.1-trash/curs_main.c 2016-06-12 18:43:04.895517656 +0100
+
@@ -1919,6 +1919,7 @@
+
MAYBE_REDRAW (menu->redraw);
+
break;
+
+
+ case OP_PURGE_MESSAGE:
+
case OP_DELETE:
+
+
CHECK_MSGCOUNT;
+
@@ -1930,6 +1931,7 @@
+
if (tag)
+
{
+
mutt_tag_set_flag (M_DELETE, 1);
+
+ mutt_tag_set_flag (M_PURGED, (op != OP_PURGE_MESSAGE) ? 0 : 1);
+
if (option (OPTDELETEUNTAG))
+
mutt_tag_set_flag (M_TAG, 0);
+
menu->redraw = REDRAW_INDEX;
+
@@ -1937,6 +1939,8 @@
+
else
+
{
+
mutt_set_flag (Context, CURHDR, M_DELETE, 1);
+
+ mutt_set_flag (Context, CURHDR, M_PURGED,
+
+ (op != OP_PURGE_MESSAGE) ? 0 : 1);
+
if (option (OPTDELETEUNTAG))
+
mutt_set_flag (Context, CURHDR, M_TAG, 0);
+
if (option (OPTRESOLVE))
+
@@ -2242,11 +2246,13 @@
+
if (tag)
+
{
+
mutt_tag_set_flag (M_DELETE, 0);
+
+ mutt_tag_set_flag (M_PURGED, 0);
+
menu->redraw = REDRAW_INDEX;
+
}
+
else
+
{
+
mutt_set_flag (Context, CURHDR, M_DELETE, 0);
+
+ mutt_set_flag (Context, CURHDR, M_PURGED, 0);
+
if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
+
{
+
menu->current++;
+
@@ -2268,9 +2274,11 @@
+
CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
+
+
rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
+
- op == OP_UNDELETE_THREAD ? 0 : 1);
+
+ op == OP_UNDELETE_THREAD ? 0 : 1)
+
+ + mutt_thread_set_flag (CURHDR, M_PURGED, 0,
+
+ (op == OP_UNDELETE_THREAD) ? 0 : 1);
+
+
- if (rc != -1)
+
+ if (rc > -1)
+
{
+
if (option (OPTRESOLVE))
+
{
+
diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-trash/doc/manual.xml.head
+
--- mutt-1.6.1/doc/manual.xml.head 2016-06-12 18:43:00.402447590 +0100
+
+++ mutt-1.6.1-trash/doc/manual.xml.head 2016-06-12 18:43:04.901517750 +0100
+
@@ -7467,6 +7467,16 @@
+
+
</sect2>
+
+
+<sect2 id="mutt-patches">
+
+<title>Mutt Patches</title>
+
+<para>
+
+Mutt may also be <quote>patched</quote> to support smaller features.
+
+These patches should add a free-form string to the end Mutt's version string.
+
+Running <literal>mutt -v</literal> might show:
+
+<screen>patch-1.6.1.sidebar.20160502</screen>
+
+</para>
+
+</sect2>
+
+
+
<sect2 id="url-syntax">
+
<title>URL Syntax</title>
+
+
@@ -8081,6 +8091,175 @@
+
+
</sect1>
+
+
+<sect1 id="trash-folder">
+
+ <title>Trash Folder Patch</title>
+
+ <subtitle>Automatically move "deleted" emails to a trash bin</subtitle>
+
+
+
+ <sect2 id="trash-folder-patch">
+
+ <title>Patch</title>
+
+
+
+ <para>
+
+ To check if Mutt supports <quote>Trash Folder</quote>, look for
+
+ <quote>patch-trash</quote> in the mutt version.
+
+ See: <xref linkend="mutt-patches"/>.
+
+ </para>
+
+
+
+ If IMAP is enabled, this patch will use it
+
+
+
+ <itemizedlist>
+
+ <title>Dependencies:</title>
+
+ <listitem><para>mutt-1.6.1</para></listitem>
+
+ <listitem><para>IMAP support</para></listitem>
+
+ </itemizedlist>
+
+
+
+ <para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-intro">
+
+ <title>Introduction</title>
+
+
+
+ <para>
+
+ In Mutt, when you <quote>delete</quote> an email it is first marked
+
+ deleted. The email isn't really gone until
+
+ <link linkend="index-map">&lt;sync-mailbox&gt;</link> is called.
+
+ This happens when the user leaves the folder, or the function is called
+
+ manually.
+
+ </para>
+
+
+
+ <para>
+
+ After <literal>&lt;sync-mailbox&gt;</literal> has been called the email is gone forever.
+
+ </para>
+
+
+
+ <para>
+
+ The <link linkend="trash">$trash</link> variable defines a folder in
+
+ which to keep old emails. As before, first you mark emails for
+
+ deletion. When &lt;sync-mailbox&gt; is called the emails are moved to
+
+ the trash folder.
+
+ </para>
+
+
+
+ <para>
+
+ The <literal>$trash</literal> path can be either a full directory,
+
+ or be relative to the <link linkend="folder">$folder</link>
+
+ variable, like the <literal>mailboxes</literal> command.
+
+ </para>
+
+
+
+ <note>
+
+ Emails deleted from the trash folder are gone forever.
+
+ </note>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-variables">
+
+ <title>Variables</title>
+
+ <table id="table-trash-variables">
+
+ <title>Trash Variables</title>
+
+ <tgroup cols="3">
+
+ <thead>
+
+ <row>
+
+ <entry>Name</entry>
+
+ <entry>Type</entry>
+
+ <entry>Default</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry>trash</entry>
+
+ <entry>string</entry>
+
+ <entry>(none)</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-functions">
+
+ <title>Functions</title>
+
+ <table id="table-trash-functions">
+
+ <title>Trash Functions</title>
+
+ <tgroup cols="4">
+
+ <thead>
+
+ <row>
+
+ <entry>Menus</entry>
+
+ <entry>Default Key</entry>
+
+ <entry>Function</entry>
+
+ <entry>Description</entry>
+
+ </row>
+
+ </thead>
+
+ <tbody>
+
+ <row>
+
+ <entry>index,pager</entry>
+
+ <entry>(none)</entry>
+
+ <entry><literal>&lt;purge-message&gt;</literal></entry>
+
+ <entry>really delete the current entry, bypassing the trash folder</entry>
+
+ </row>
+
+ </tbody>
+
+ </tgroup>
+
+ </table>
+
+ </sect2>
+
+
+
+<!--
+
+ <sect2 id="trash-folder-commands">
+
+ <title>Commands</title>
+
+ <para>None</para>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-colors">
+
+ <title>Colors</title>
+
+ <para>None</para>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-sort">
+
+ <title>Sort</title>
+
+ <para>None</para>
+
+ </sect2>
+
+-->
+
+
+
+ <sect2 id="trash-folder-muttrc">
+
+ <title>Muttrc</title>
+
+<screen>
+
+<emphasis role="comment"># Example Mutt config file for the 'trash' feature.
+
+
+
+# This feature defines a new 'trash' folder.
+
+# When mail is deleted it will be moved to this folder.
+
+
+
+# Folder in which to put deleted emails</emphasis>
+
+set trash='+Trash'
+
+set trash='/home/flatcap/Mail/Trash'
+
+
+
+<emphasis role="comment"># The default delete key 'd' will move an email to the 'trash' folder
+
+# Bind 'D' to REALLY delete an email</emphasis>
+
+bind index D purge-message
+
+
+
+<emphasis role="comment"># Note: Deleting emails from the 'trash' folder will REALLY delete them.
+
+
+
+# vim: syntax=muttrc</emphasis>
+
+</screen>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-see-also">
+
+ <title>See Also</title>
+
+
+
+ <itemizedlist>
+
+ <listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+
+ <listitem><para><link linkend="folder-hook">folder-hook</link></para></listitem>
+
+ </itemizedlist>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-known-bugs">
+
+ <title>Known Bugs</title>
+
+ <para>None</para>
+
+ </sect2>
+
+
+
+ <sect2 id="trash-folder-credits">
+
+ <title>Credits</title>
+
+ <itemizedlist>
+
+ <listitem><para>Cedric Duval <email>cedricduval@free.fr</email></para></listitem>
+
+ <listitem><para>Benjamin Kuperman <email>kuperman@acm.org</email></para></listitem>
+
+ <listitem><para>Paul Miller <email>paul@voltar.org</email></para></listitem>
+
+ <listitem><para>Richard Russon <email>rich@flatcap.org</email></para></listitem>
+
+ </itemizedlist>
+
+ </sect2>
+
+</sect1>
+
+
+
</chapter>
+
+
<chapter id="security">
+
diff -urN mutt-1.6.1/doc/muttrc.trash mutt-1.6.1-trash/doc/muttrc.trash
+
--- mutt-1.6.1/doc/muttrc.trash 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-trash/doc/muttrc.trash 2016-06-12 18:43:04.768515676 +0100
+
@@ -0,0 +1,16 @@
+
+# Example Mutt config file for the 'trash' feature.
+
+
+
+# This feature defines a new 'trash' folder.
+
+# When mail is deleted it will be moved to this folder.
+
+
+
+# Folder in which to put deleted emails
+
+set trash='+Trash'
+
+set trash='/home/flatcap/Mail/Trash'
+
+
+
+# The default delete key 'd' will move an email to the 'trash' folder
+
+# Bind 'D' to REALLY delete an email
+
+bind index D purge-message
+
+
+
+# Note: Deleting emails from the 'trash' folder will REALLY delete them.
+
+
+
+# vim: syntax=muttrc
+
diff -urN mutt-1.6.1/doc/vimrc.trash mutt-1.6.1-trash/doc/vimrc.trash
+
--- mutt-1.6.1/doc/vimrc.trash 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-trash/doc/vimrc.trash 2016-06-12 18:43:04.769515692 +0100
+
@@ -0,0 +1,7 @@
+
+" Vim syntax file for the mutt trash patch
+
+
+
+syntax keyword muttrcVarStr contained skipwhite trash nextgroup=muttrcVarEqualsIdxFmt
+
+
+
+syntax match muttrcFunction contained "\<purge-message\>"
+
+
+
+" vim: syntax=vim
+
diff -urN mutt-1.6.1/flags.c mutt-1.6.1-trash/flags.c
+
--- mutt-1.6.1/flags.c 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-trash/flags.c 2016-06-12 18:43:04.902517766 +0100
+
@@ -65,7 +65,13 @@
+
{
+
h->deleted = 0;
+
update = 1;
+
- if (upd_ctx) ctx->deleted--;
+
+ if (upd_ctx) {
+
+ ctx->deleted--;
+
+ if (h->appended) {
+
+ ctx->appended--;
+
+ }
+
+ }
+
+ h->appended = 0; /* when undeleting, also reset the appended flag */
+
#ifdef USE_IMAP
+
/* see my comment above */
+
if (ctx->magic == M_IMAP)
+
@@ -87,6 +93,27 @@
+
}
+
break;
+
+
+ case M_APPENDED:
+
+ if (bf) {
+
+ if (!h->appended) {
+
+ h->appended = 1;
+
+ if (upd_ctx) {
+
+ ctx->appended++;
+
+ }
+
+ }
+
+ }
+
+ break;
+
+
+
+ case M_PURGED:
+
+ if (bf) {
+
+ if (!h->purged) {
+
+ h->purged = 1;
+
+ }
+
+ } else if (h->purged) {
+
+ h->purged = 0;
+
+ }
+
+ break;
+
+
+
case M_NEW:
+
+
if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
+
diff -urN mutt-1.6.1/functions.h mutt-1.6.1-trash/functions.h
+
--- mutt-1.6.1/functions.h 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-trash/functions.h 2016-06-12 18:43:04.902517766 +0100
+
@@ -121,6 +121,7 @@
+
{ "toggle-write", OP_TOGGLE_WRITE, "%" },
+
{ "next-thread", OP_MAIN_NEXT_THREAD, "\016" },
+
{ "next-subthread", OP_MAIN_NEXT_SUBTHREAD, "\033n" },
+
+ { "purge-message", OP_PURGE_MESSAGE, NULL },
+
{ "query", OP_QUERY, "Q" },
+
{ "quit", OP_QUIT, "q" },
+
{ "reply", OP_REPLY, "r" },
+
@@ -213,6 +214,7 @@
+
{ "print-message", OP_PRINT, "p" },
+
{ "previous-thread", OP_MAIN_PREV_THREAD, "\020" },
+
{ "previous-subthread",OP_MAIN_PREV_SUBTHREAD, "\033p" },
+
+ { "purge-message", OP_PURGE_MESSAGE, NULL },
+
{ "quit", OP_QUIT, "Q" },
+
{ "exit", OP_EXIT, "q" },
+
{ "reply", OP_REPLY, "r" },
+
diff -urN mutt-1.6.1/globals.h mutt-1.6.1-trash/globals.h
+
--- mutt-1.6.1/globals.h 2016-06-12 18:43:00.403447606 +0100
+
+++ mutt-1.6.1-trash/globals.h 2016-06-12 18:43:04.903517781 +0100
+
@@ -141,6 +141,7 @@
+
WHERE char *Status;
+
WHERE char *Tempdir;
+
WHERE char *Tochars;
+
+WHERE char *TrashPath;
+
WHERE char *TSStatusFormat;
+
WHERE char *TSIconFormat;
+
WHERE short TSSupported;
+
diff -urN mutt-1.6.1/imap/imap.c mutt-1.6.1-trash/imap/imap.c
+
--- mutt-1.6.1/imap/imap.c 2016-06-12 18:43:00.405447637 +0100
+
+++ mutt-1.6.1-trash/imap/imap.c 2016-06-12 18:43:04.905517812 +0100
+
@@ -888,6 +888,12 @@
+
if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
+
match = invert ^ hdrs[n]->deleted;
+
break;
+
+ case M_EXPIRED: /* imap_fast_trash version of M_DELETED */
+
+ if (hdrs[n]->purged)
+
+ break;
+
+ if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
+
+ match = invert ^ (hdrs[n]->deleted && !hdrs[n]->appended);
+
+ break;
+
case M_FLAG:
+
if (hdrs[n]->flagged != HEADER_DATA(hdrs[n])->flagged)
+
match = invert ^ hdrs[n]->flagged;
+
@@ -2038,3 +2044,53 @@
+
+
return -1;
+
}
+
+
+
+/**
+
+ * imap_fast_trash - XXX
+
+ */
+
+int
+
+imap_fast_trash (void)
+
+{
+
+ if ((Context->magic == M_IMAP) && mx_is_imap (TrashPath)) {
+
+ IMAP_MBOX mx;
+
+ IMAP_DATA *idata = (IMAP_DATA *) Context->data;
+
+ char mbox[LONG_STRING];
+
+ char mmbox[LONG_STRING];
+
+ int rc;
+
+ dprint (1, (debugfile, "[itf] trashcan seems to be on imap.\n"));
+
+
+
+ if (imap_parse_path (TrashPath, &mx) == 0) {
+
+ if (mutt_account_match (&(idata->conn->account), &(mx.account))) {
+
+ dprint (1, (debugfile, "[itf] trashcan seems to be on the same account.\n"));
+
+
+
+ imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
+
+ if (!*mbox)
+
+ strfcpy (mbox, "INBOX", sizeof (mbox));
+
+ imap_munge_mbox_name (idata, mmbox, sizeof (mmbox), mbox);
+
+
+
+ rc = imap_exec_msgset (idata, "UID COPY", mmbox, M_EXPIRED, 0, 0);
+
+ if (rc == 0) {
+
+ dprint (1, (debugfile, "imap_copy_messages: No messages del-tagged\n"));
+
+ rc = -1;
+
+ goto old_way;
+
+ } else if (rc < 0) {
+
+ dprint (1, (debugfile, "could not queue copy\n"));
+
+ goto old_way;
+
+ } else {
+
+ mutt_message (_("Copying %d messages to %s..."), rc, mbox);
+
+ return 0;
+
+ }
+
+ } else {
+
+ dprint (1, (debugfile, "[itf] trashcan seems to be on a different account.\n"));
+
+ }
+
+old_way:
+
+ FREE(&mx.mbox); /* we probably only need to free this when the parse works */
+
+ } else {
+
+ dprint (1, (debugfile, "[itf] failed to parse TrashPath.\n"));
+
+ }
+
+
+
+ dprint (1, (debugfile, "[itf] giving up and trying old fasioned way.\n"));
+
+ }
+
+
+
+ return 1;
+
+}
+
diff -urN mutt-1.6.1/imap/imap.h mutt-1.6.1-trash/imap/imap.h
+
--- mutt-1.6.1/imap/imap.h 2016-06-12 18:43:00.405447637 +0100
+
+++ mutt-1.6.1-trash/imap/imap.h 2016-06-12 18:43:04.774515769 +0100
+
@@ -72,4 +72,7 @@
+
+
int imap_account_match (const ACCOUNT* a1, const ACCOUNT* a2);
+
+
+/* trash */
+
+int imap_fast_trash (void);
+
+
+
#endif
+
diff -urN mutt-1.6.1/imap/message.c mutt-1.6.1-trash/imap/message.c
+
--- mutt-1.6.1/imap/message.c 2016-06-12 18:43:00.406447652 +0100
+
+++ mutt-1.6.1-trash/imap/message.c 2016-06-12 18:43:04.906517828 +0100
+
@@ -886,6 +886,7 @@
+
if (ctx->hdrs[n]->tagged)
+
{
+
mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1);
+
+ mutt_set_flag (ctx, ctx->hdrs[n], M_APPENDED, 1);
+
if (option (OPTDELETEUNTAG))
+
mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0);
+
}
+
@@ -893,6 +894,7 @@
+
else
+
{
+
mutt_set_flag (ctx, h, M_DELETE, 1);
+
+ mutt_set_flag (ctx, h, M_APPENDED, 1);
+
if (option (OPTDELETEUNTAG))
+
mutt_set_flag (ctx, h, M_TAG, 0);
+
}
+
diff -urN mutt-1.6.1/init.h mutt-1.6.1-trash/init.h
+
--- mutt-1.6.1/init.h 2016-06-12 18:43:00.408447684 +0100
+
+++ mutt-1.6.1-trash/init.h 2016-06-12 18:43:04.909517875 +0100
+
@@ -3419,6 +3419,16 @@
+
** provided that ``$$ts_enabled'' has been set. This string is identical in
+
** formatting to the one used by ``$$status_format''.
+
*/
+
+ { "trash", DT_PATH, R_NONE, UL &TrashPath, 0 },
+
+ /*
+
+ ** .pp
+
+ ** If set, this variable specifies the path of the trash folder where the
+
+ ** mails marked for deletion will be moved, instead of being irremediably
+
+ ** purged.
+
+ ** .pp
+
+ ** NOTE: When you delete a message in the trash folder, it is really
+
+ ** deleted, so that you have a way to clean the trash.
+
+ */
+
#ifdef USE_SOCKET
+
{ "tunnel", DT_STR, R_NONE, UL &Tunnel, UL 0 },
+
/*
+
diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-trash/mutt.h
+
--- mutt-1.6.1/mutt.h 2016-06-12 18:43:00.410447715 +0100
+
+++ mutt-1.6.1-trash/mutt.h 2016-06-12 18:43:04.912517922 +0100
+
@@ -182,6 +182,8 @@
+
M_DELETE,
+
M_UNDELETE,
+
M_DELETED,
+
+ M_APPENDED,
+
+ M_PURGED,
+
M_FLAG,
+
M_TAG,
+
M_UNTAG,
+
@@ -719,6 +721,8 @@
+
unsigned int mime : 1; /* has a MIME-Version header? */
+
unsigned int flagged : 1; /* marked important? */
+
unsigned int tagged : 1;
+
+ unsigned int appended : 1; /* has been saved */
+
+ unsigned int purged : 1; /* bypassing the trash folder */
+
unsigned int deleted : 1;
+
unsigned int changed : 1;
+
unsigned int attach_del : 1; /* has an attachment marked for deletion */
+
@@ -891,6 +895,7 @@
+
int new; /* how many new messages? */
+
int unread; /* how many unread messages? */
+
int deleted; /* how many deleted messages */
+
+ int appended; /* how many saved messages? */
+
int flagged; /* how many flagged messages */
+
int msgnotreadyet; /* which msg "new" in pager, -1 if none */
+
+
diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-trash/muttlib.c
+
--- mutt-1.6.1/muttlib.c 2016-06-12 18:43:00.411447731 +0100
+
+++ mutt-1.6.1-trash/muttlib.c 2016-06-12 18:43:04.913517937 +0100
+
@@ -1511,7 +1511,9 @@
+
+
if (magic > 0 && !mx_access (s, W_OK))
+
{
+
- if (option (OPTCONFIRMAPPEND))
+
+ if (option (OPTCONFIRMAPPEND) &&
+
+ (!TrashPath || (mutt_strcmp (s, TrashPath) != 0)))
+
+ /* if we're appending to the trash, there's no point in asking */
+
{
+
snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
+
if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
+
diff -urN mutt-1.6.1/mx.c mutt-1.6.1-trash/mx.c
+
--- mutt-1.6.1/mx.c 2016-06-12 18:43:00.411447731 +0100
+
+++ mutt-1.6.1-trash/mx.c 2016-06-12 18:43:04.914517953 +0100
+
@@ -776,6 +776,62 @@
+
return rc;
+
}
+
+
+/**
+
+ * trash_append - XXX
+
+ *
+
+ * move deleted mails to the trash folder
+
+ */
+
+static int trash_append (CONTEXT *ctx)
+
+{
+
+ CONTEXT *ctx_trash;
+
+ int i = 0;
+
+ struct stat st, stc;
+
+
+
+ if (!TrashPath || !ctx->deleted ||
+
+ ((ctx->magic == M_MAILDIR) && option (OPTMAILDIRTRASH))) {
+
+ return 0;
+
+ }
+
+
+
+ for (; i < ctx->msgcount && (!ctx->hdrs[i]->deleted || ctx->hdrs[i]->appended); i++);
+
+ /* nothing */
+
+
+
+ if (i == ctx->msgcount)
+
+ return 0; /* nothing to be done */
+
+
+
+ if (mutt_save_confirm (TrashPath, &st) != 0) {
+
+ mutt_error _("message(s) not deleted");
+
+ return -1;
+
+ }
+
+
+
+ if (lstat (ctx->path, &stc) == 0 && stc.st_ino == st.st_ino
+
+ && stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev) {
+
+ return 0; /* we are in the trash folder: simple sync */
+
+ }
+
+
+
+#ifdef USE_IMAP
+
+ if (!imap_fast_trash())
+
+ return 0;
+
+#endif
+
+
+
+ if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL) {
+
+ for (i = 0 ; i < ctx->msgcount ; i++) {
+
+ if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->appended
+
+ && !ctx->hdrs[i]->purged
+
+ && mutt_append_message (ctx_trash, ctx, ctx->hdrs[i], 0, 0) == -1) {
+
+ mx_close_mailbox (ctx_trash, NULL);
+
+ return -1;
+
+ }
+
+ }
+
+
+
+ mx_close_mailbox (ctx_trash, NULL);
+
+ } else {
+
+ mutt_error _("Can't open trash folder");
+
+ return -1;
+
+ }
+
+
+
+ return 0;
+
+}
+
+
+
/* save changes and close mailbox */
+
int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
+
{
+
@@ -912,6 +968,7 @@
+
if (mutt_append_message (&f, ctx, ctx->hdrs[i], 0, CH_UPDATE_LEN) == 0)
+
{
+
mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, 1);
+
+ mutt_set_flag (ctx, ctx->hdrs[i], M_APPENDED, 1);
+
}
+
else
+
{
+
@@ -936,6 +993,14 @@
+
return 0;
+
}
+
+
+ /* copy mails to the trash before expunging */
+
+ if (purge && ctx->deleted && mutt_strcmp (ctx->path, TrashPath)) {
+
+ if (trash_append (ctx) != 0) {
+
+ ctx->closing = 0;
+
+ return -1;
+
+ }
+
+ }
+
+
+
#ifdef USE_IMAP
+
/* allow IMAP to preserve the deleted flag across sessions */
+
if (ctx->magic == M_IMAP)
+
@@ -1140,6 +1205,12 @@
+
msgcount = ctx->msgcount;
+
deleted = ctx->deleted;
+
+
+ if (purge && ctx->deleted && mutt_strcmp (ctx->path, TrashPath)) {
+
+ if (trash_append (ctx) == -1) {
+
+ return -1;
+
+ }
+
+ }
+
+
+
#ifdef USE_IMAP
+
if (ctx->magic == M_IMAP)
+
rc = imap_sync_mailbox (ctx, purge, index_hint);
+
diff -urN mutt-1.6.1/OPS mutt-1.6.1-trash/OPS
+
--- mutt-1.6.1/OPS 2016-06-12 18:43:00.389447388 +0100
+
+++ mutt-1.6.1-trash/OPS 2016-06-12 18:43:04.883517469 +0100
+
@@ -142,6 +142,7 @@
+
OP_PREV_LINE "scroll up one line"
+
OP_PREV_PAGE "move to the previous page"
+
OP_PRINT "print the current entry"
+
+OP_PURGE_MESSAGE "really delete the current entry, bypassing the trash folder"
+
OP_QUERY "query external program for addresses"
+
OP_QUERY_APPEND "append new query results to current results"
+
OP_QUIT "save changes to mailbox and quit"
+
diff -urN mutt-1.6.1/pager.c mutt-1.6.1-trash/pager.c
+
--- mutt-1.6.1/pager.c 2016-06-12 18:43:00.412447746 +0100
+
+++ mutt-1.6.1-trash/pager.c 2016-06-12 18:43:04.915517968 +0100
+
@@ -2351,6 +2351,7 @@
+
MAYBE_REDRAW (redraw);
+
break;
+
+
+ case OP_PURGE_MESSAGE:
+
case OP_DELETE:
+
CHECK_MODE(IsHeader (extra));
+
CHECK_READONLY;
+
@@ -2358,6 +2359,8 @@
+
CHECK_ACL(M_ACL_DELETE, _("Cannot delete message"));
+
+
mutt_set_flag (Context, extra->hdr, M_DELETE, 1);
+
+ mutt_set_flag (Context, extra->hdr, M_PURGED,
+
+ ch != OP_PURGE_MESSAGE ? 0 : 1);
+
if (option (OPTDELETEUNTAG))
+
mutt_set_flag (Context, extra->hdr, M_TAG, 0);
+
redraw = REDRAW_STATUS | REDRAW_INDEX;
+
@@ -2688,6 +2691,7 @@
+
CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message"));
+
+
mutt_set_flag (Context, extra->hdr, M_DELETE, 0);
+
+ mutt_set_flag (Context, extra->hdr, M_PURGED, 0);
+
redraw = REDRAW_STATUS | REDRAW_INDEX;
+
if (option (OPTRESOLVE))
+
{
+
@@ -2704,9 +2708,11 @@
+
CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
+
+
r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0,
+
+ ch == OP_UNDELETE_THREAD ? 0 : 1)
+
+ + mutt_thread_set_flag (extra->hdr, M_PURGED, 0,
+
ch == OP_UNDELETE_THREAD ? 0 : 1);
+
+
- if (r != -1)
+
+ if (r > -1)
+
{
+
if (option (OPTRESOLVE))
+
{
+
diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-trash/PATCHES
+
--- mutt-1.6.1/PATCHES 2016-06-12 18:43:00.395447481 +0100
+
+++ mutt-1.6.1-trash/PATCHES 2016-06-12 18:43:04.889517563 +0100
+
@@ -0,0 +1 @@
+
+patch-trash-neo-20160612
+
diff -urN mutt-1.6.1/pattern.c mutt-1.6.1-trash/pattern.c
+
--- mutt-1.6.1/pattern.c 2016-06-12 18:43:00.413447762 +0100
+
+++ mutt-1.6.1-trash/pattern.c 2016-06-12 18:43:04.916517984 +0100
+
@@ -1367,8 +1367,9 @@
+
{
+
switch (op)
+
{
+
- case M_DELETE:
+
case M_UNDELETE:
+
+ mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_PURGED, 0);
+
+ case M_DELETE:
+
mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_DELETE,
+
(op == M_DELETE));
+
break;
+
diff -urN mutt-1.6.1/postpone.c mutt-1.6.1-trash/postpone.c
+
--- mutt-1.6.1/postpone.c 2016-06-12 18:43:00.414447777 +0100
+
+++ mutt-1.6.1-trash/postpone.c 2016-06-12 18:43:04.917518000 +0100
+
@@ -277,6 +277,9 @@
+
/* finished with this message, so delete it. */
+
mutt_set_flag (PostContext, h, M_DELETE, 1);
+
+
+ /* and consider it saved, so that it won't be moved to the trash folder */
+
+ mutt_set_flag (PostContext, h, M_APPENDED, 1);
+
+
+
/* update the count for the status display */
+
PostCount = PostContext->msgcount - PostContext->deleted;
+
+
diff -urN mutt-1.6.1/README.trash mutt-1.6.1-trash/README.trash
+
--- mutt-1.6.1/README.trash 1970-01-01 01:00:00.000000000 +0100
+
+++ mutt-1.6.1-trash/README.trash 2016-06-12 18:43:04.748515364 +0100
+
@@ -0,0 +1,74 @@
+
+Trash Folder Patch
+
+==================
+
+
+
+ Automatically move "deleted" emails to a trash bin
+
+
+
+Patch
+
+-----
+
+
+
+ To check if Mutt supports "Trash Folder", look for "patch-trash" in the
+
+ mutt version.
+
+
+
+ If IMAP is enabled, this patch will use it
+
+
+
+ Dependencies
+
+ * mutt-1.6.1
+
+ * IMAP support
+
+
+
+Introduction
+
+------------
+
+
+
+ In Mutt, when you "delete" an email it is first marked deleted. The email
+
+ isn't really gone until <sync-mailbox> is called. This happens when the
+
+ user leaves the folder, or the function is called manually.
+
+
+
+ After '<sync-mailbox>' has been called the email is gone forever.
+
+
+
+ The $trash variable defines a folder in which to keep old emails. As
+
+ before, first you mark emails for deletion. When <sync-mailbox> is called
+
+ the emails are moved to the trash folder.
+
+
+
+ The '$trash' path can be either a full directory, or be relative to the
+
+ $folder variable, like the 'mailboxes' command.
+
+
+
+ > Note
+
+ >
+
+ > Emails deleted from the trash folder are gone forever.
+
+
+
+Variables
+
+---------
+
+
+
+ Trash Variables
+
+
+
+ | Name | Type | Default |
+
+ |-------|--------|---------|
+
+ | trash | string | (none) |
+
+
+
+Functions
+
+---------
+
+
+
+ Trash Functions
+
+
+
+ | Menus | Default Key | Function | Description |
+
+ |-------------|-------------|-------------------|-------------------------------------------------------------|
+
+ | index,pager | (none) | '<purge-message>' | really delete the current entry, bypassing the trash folder |
+
+
+
+See Also
+
+--------
+
+
+
+ * NeoMutt project
+
+ * folder-hook
+
+
+
+Known Bugs
+
+----------
+
+
+
+ None
+
+
+
+Credits
+
+-------
+
+
+
+ * Cedric Duval <cedricduval@free.fr>
+
+ * Benjamin Kuperman <kuperman@acm.org>
+
+ * Paul Miller <paul@voltar.org>
+
+ * Richard Russon <rich@flatcap.org>
+
+