diff options
author | Johannes Frankenau | 2016-05-19 20:26:32 +0200 |
---|---|---|
committer | Johannes Frankenau | 2016-05-19 20:26:32 +0200 |
commit | 3d86c55b30334efc5b70054590332ca1abdf72e9 (patch) | |
tree | 01e85204b20c65b8b557c59f2380a535546ba327 /sidebar.patch | |
parent | d76fa438b22aef0ccde36342da0c8759281aad18 (diff) | |
download | aur-3d86c55b30334efc5b70054590332ca1abdf72e9.tar.gz |
Update to 1.6.1 and use patches from NeoMutt
Diffstat (limited to 'sidebar.patch')
-rw-r--r-- | sidebar.patch | 4758 |
1 files changed, 3518 insertions, 1240 deletions
diff --git a/sidebar.patch b/sidebar.patch index 54bb94eb4320..6371a66d774c 100644 --- a/sidebar.patch +++ b/sidebar.patch @@ -1,406 +1,393 @@ -From: Antonio Radici <antonio@debian.org> -Date: Sat, 19 Sep 2015 13:19:55 +0200 -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_folderindent (boolean, default no) - - Should folders be indented in the sidebar. - - sidebar_format (string, default "%B%?F? [%F]?%* %?N?%N/?%4S") - - Format string for the sidebar. The sequences `%N', `%F' and `%S' - will be replaced by the number of new or flagged messages or the total - size of them mailbox. `%B' will be replaced with the name of the mailbox. - The `%!' sequence will be expanded to `!' if there is one flagged message; - to `!!' if there are two flagged messages; and to `n!' for n flagged - messages, n>2. - - sidebar_indentstr (string, default " ") - - This specifies the string that is used to indent items - with sidebar_folderindent= yes - - sidebar_shortpath (boolean, default no) - - Should the sidebar shorten the path showed. - - sidebar_sort (boolean, default no) - - This specifies whether or not to sort the sidebar alphabetically. - - 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/mutt-sidebar/ - - http://lunar-linux.org/~tchan/mutt/patch-1.5.24.sidebar.20151111.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 - - - 2015-12-24 evgeni: refresh sidebar patch to the 20151111 version - -Signed-off-by: Evgeni Golov <evgeni@debian.org> -Signed-off-by: Matteo F. Vescovi <mfv@debian.org> ---- - Makefile.am | 1 + - OPS | 5 + - buffy.c | 152 ++++++++++++++++++++- - buffy.h | 6 + - color.c | 2 + - compose.c | 26 ++-- - configure.ac | 2 + - curs_main.c | 37 +++++- - doc/Muttrc | 20 +++ - flags.c | 3 + - functions.h | 10 ++ - globals.h | 6 + - handler.c | 30 ++++- - imap/command.c | 7 + - imap/imap.c | 2 +- - init.h | 48 +++++++ - mailbox.h | 1 + - main.c | 11 +- - mbox.c | 2 + - menu.c | 20 +-- - mh.c | 26 ++++ - mutt.h | 6 + - mutt_curses.h | 3 + - mutt_menu.h | 1 + - muttlib.c | 48 +++++++ - mx.c | 24 +++- - mx.h | 1 + - pager.c | 42 +++++- - pattern.c | 38 ++++++ - protos.h | 7 + - sidebar.c | 410 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - sidebar.h | 36 +++++ - 32 files changed, 992 insertions(+), 41 deletions(-) - create mode 100644 sidebar.c - create mode 100644 sidebar.h - -diff --git a/Makefile.am b/Makefile.am -index 9475381..c593f4f 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 c713d16..d34e6f5 100644 ---- a/buffy.c -+++ b/buffy.c -@@ -161,6 +161,49 @@ void mutt_buffy_cleanup (const char *buf, struct stat *st) - } - } +diff -urN mutt-1.6.1/buffy.c mutt-1.6.1-sidebar/buffy.c +--- mutt-1.6.1/buffy.c 2016-05-02 03:02:12.397171385 +0100 ++++ mutt-1.6.1-sidebar/buffy.c 2016-05-02 03:02:15.009212943 +0100 +@@ -27,6 +27,10 @@ -+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; -+} + #include "mutt_curses.h" + ++#ifdef USE_SIDEBAR ++#include "sidebar.h" ++#endif + - BUFFY *mutt_find_mailbox (const char *path) - { - BUFFY *tmp = NULL; -@@ -196,9 +239,13 @@ void mutt_update_mailbox (BUFFY * b) + #ifdef USE_IMAP + #include "imap.h" + #endif +@@ -196,9 +200,17 @@ static BUFFY *buffy_new (const char *path) { BUFFY* buffy; -+ char rp[PATH_MAX]; -+ char *r; ++#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)); -+ r = realpath(path, rp); ++#ifdef USE_SIDEBAR ++ r = realpath (path, rp); + strfcpy (buffy->realpath, r ? rp : path, sizeof (buffy->realpath)); ++#endif buffy->next = NULL; buffy->magic = 0; -@@ -243,8 +290,8 @@ int mutt_parse_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER *e +@@ -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 ++ 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)) { -- q = realpath ((*tmp)->path, f2); -- if (mutt_strcmp (p ? p : buf, q ? q : (*tmp)->path) == 0) ++#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; -@@ -282,6 +329,7 @@ int mutt_parse_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER *e - else - (*tmp)->size = 0; - } -+ Incoming = buffy_sort(Incoming); - return 0; - } +@@ -256,14 +279,21 @@ + if(*tmp) + { + tmp1=(*tmp)->next; ++#ifdef USE_SIDEBAR ++ sb_notify_mailbox (*tmp, 0); ++#endif + buffy_free (tmp); + *tmp=tmp1; + } + continue; + } + +- if (!*tmp) ++ if (!*tmp) { + *tmp = buffy_new (buf); ++#ifdef USE_SIDEBAR ++ sb_notify_mailbox (*tmp, 1); ++#endif ++ } -@@ -306,6 +354,11 @@ static int buffy_maildir_dir_hasnew(BUFFY* mailbox, const char *dir_name) + (*tmp)->new = 0; + (*tmp)->notified = 1; +@@ -306,6 +336,13 @@ return 0; } -+ if (option(OPTSIDEBAR) && mailbox->msg_unread > 0) { -+ mailbox->new = 1; -+ return 1; ++#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 +410,73 @@ static int buffy_maildir_hasnew (BUFFY* mailbox) +@@ -357,6 +394,89 @@ return 0; } -+ -+ /* update message counts for the sidebar */ -+void buffy_maildir_update (BUFFY* mailbox) ++ ++#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; -+ struct dirent *de; -+ char *p; -+ -+ if(!option(OPTSIDEBAR)) -+ return; -+ -+ 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++; -+ } -+ } -+ } -+ } ++ 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++; ++ } ++ } + -+ mailbox->sb_last_checked = time(NULL); -+ closedir (dirp); ++ 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 */ ++ sb_draw(); ++} ++ ++#endif ++ /* returns 1 if mailbox has new mail */ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb) { -@@ -368,7 +488,7 @@ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb) +@@ -368,7 +488,11 @@ else statcheck = sb->st_mtime > sb->st_atime || (mailbox->newly_created && sb->st_ctime == sb->st_mtime && sb->st_ctime == sb->st_atime); -- if (statcheck) -+ if ((!option(OPTSIDEBAR) && statcheck) || (option(OPTSIDEBAR) && mailbox->msg_unread > 0)) ++#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 +508,27 @@ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb) +@@ -388,6 +512,40 @@ return rc; } -+/* update message counts for the sidebar */ -+void buffy_mbox_update (BUFFY* mailbox, struct stat *sb) ++#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->msgcount != 0) -+ return; /* no check necessary */ -+ -+ 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; -+ mailbox->msg_flagged = ctx->flagged; -+ mailbox->sb_last_checked = time(NULL); -+ mx_close_mailbox(ctx, 0); -+ } ++ 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 */ ++ sb_draw(); +} ++#endif + int mutt_buffy_check (int force) { BUFFY *tmp; -@@ -461,17 +602,20 @@ int mutt_buffy_check (int force) +@@ -428,6 +586,9 @@ + contex_sb.st_ino=0; + } + ++#ifdef USE_SIDEBAR ++ int should_refresh = sb_should_refresh(); ++#endif + for (tmp = Incoming; tmp; tmp = tmp->next) + { + if (tmp->magic != M_IMAP) +@@ -461,16 +622,30 @@ { case M_MBOX: case M_MMDF: -+ buffy_mbox_update (tmp, &sb); ++#ifdef USE_SIDEBAR ++ if (should_refresh) ++ buffy_mbox_update (tmp, &sb); ++#endif if (buffy_mbox_hasnew (tmp, &sb) > 0) BuffyCount++; break; case M_MAILDIR: -+ buffy_maildir_update (tmp); ++#ifdef USE_SIDEBAR ++ if (should_refresh) ++ buffy_maildir_update (tmp); ++#endif if (buffy_maildir_hasnew (tmp) > 0) BuffyCount++; break; case M_MH: -- mh_buffy(tmp); -+ mh_buffy_update (tmp->path, &tmp->msgcount, &tmp->msg_unread, &tmp->msg_flagged, &tmp->sb_last_checked); -+ mh_buffy(tmp); ++#ifdef USE_SIDEBAR ++ if (sb_should_refresh()) { ++ mh_buffy_update (tmp); ++ sb_set_update_time(); ++ } ++#endif + mh_buffy(tmp); if (tmp->new) BuffyCount++; - break; -diff --git a/buffy.h b/buffy.h -index 9aa8e51..03c37df 100644 ---- a/buffy.h -+++ b/buffy.h -@@ -23,13 +23,19 @@ +@@ -485,6 +660,10 @@ + else if (!tmp->notified) + BuffyNotify++; + } ++#ifdef USE_SIDEBAR ++ if (should_refresh) ++ sb_set_update_time(); ++#endif + + BuffyDoneTime = BuffyTime; + return (BuffyCount); +diff -urN mutt-1.6.1/buffy.h mutt-1.6.1-sidebar/buffy.h +--- mutt-1.6.1/buffy.h 2016-05-02 03:02:12.397171385 +0100 ++++ mutt-1.6.1-sidebar/buffy.h 2016-05-02 03:02:15.010212959 +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 */ -+ int msgcount; /* total number of messages */ ++#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 */ -+ time_t sb_last_checked; /* time of last buffy check from sidebar */ ++#ifdef USE_SIDEBAR ++ time_t sb_last_checked; /* time of last buffy check from sidebar */ ++#endif } BUFFY; -diff --git a/color.c b/color.c -index 6e29603..3731c37 100644 ---- a/color.c -+++ b/color.c -@@ -94,6 +94,8 @@ static const struct mapping_t Fields[] = +@@ -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-05-02 03:02:12.397171385 +0100 ++++ mutt-1.6.1-sidebar/color.c 2016-05-02 03:02:15.010212959 +0100 +@@ -94,6 +94,14 @@ { "underline", MT_COLOR_UNDERLINE }, { "index", MT_COLOR_INDEX }, { "prompt", MT_COLOR_PROMPT }, -+ { "sidebar_new", MT_COLOR_NEW }, ++#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 } }; -diff --git a/compose.c b/compose.c -index 6af817f..7ff2996 100644 ---- a/compose.c -+++ b/compose.c -@@ -72,7 +72,7 @@ enum +@@ -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-05-02 03:02:12.398171401 +0100 ++++ mutt-1.6.1-sidebar/compose.c 2016-05-02 03:02:15.010212959 +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 */ @@ -409,16 +396,16 @@ index 6af817f..7ff2996 100644 static const char * const Prompts[] = { -@@ -110,7 +110,7 @@ static void snd_entry (char *b, size_t blen, MUTTMENU *menu, int num) +@@ -110,7 +113,7 @@ static void redraw_crypt_lines (HEADER *msg) { - mvaddstr (HDR_CRYPT, 0, "Security: "); -+ mvaddstr (HDR_CRYPT, SidebarWidth, "Security: "); ++ mvprintw (HDR_CRYPT, SidebarWidth, TITLE_FMT, "Security: "); if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0) { -@@ -145,7 +145,7 @@ static void redraw_crypt_lines (HEADER *msg) +@@ -145,7 +148,7 @@ addstr (_(" (OppEnc mode)")); clrtoeol (); @@ -427,7 +414,7 @@ index 6af817f..7ff2996 100644 clrtoeol (); if ((WithCrypto & APPLICATION_PGP) -@@ -162,7 +162,7 @@ static void redraw_crypt_lines (HEADER *msg) +@@ -162,7 +165,7 @@ && (msg->security & ENCRYPT) && SmimeCryptAlg && *SmimeCryptAlg) { @@ -436,16 +423,16 @@ index 6af817f..7ff2996 100644 NONULL(SmimeCryptAlg)); } } -@@ -175,7 +175,7 @@ static void redraw_mix_line (LIST *chain) +@@ -175,7 +178,7 @@ int c; char *t; - mvaddstr (HDR_MIX, 0, " Mix: "); -+ mvaddstr (HDR_MIX, SidebarWidth, " Mix: "); ++ mvprintw (HDR_MIX, SidebarWidth, TITLE_FMT, "Mix: "); if (!chain) { -@@ -190,7 +190,7 @@ static void redraw_mix_line (LIST *chain) +@@ -190,7 +193,7 @@ if (t && t[0] == '0' && t[1] == '\0') t = "<random>"; @@ -454,7 +441,7 @@ index 6af817f..7ff2996 100644 break; addstr (NONULL(t)); -@@ -242,7 +242,7 @@ static void draw_envelope_addr (int line, ADDRESS *addr) +@@ -242,20 +245,23 @@ buf[0] = 0; rfc822_write_address (buf, sizeof (buf), addr, 1); @@ -463,7 +450,12 @@ index 6af817f..7ff2996 100644 mutt_paddstr (W, buf); } -@@ -252,10 +252,10 @@ static void draw_envelope (HEADER *msg, char *fcc) + static void draw_envelope (HEADER *msg, char *fcc) + { ++#ifdef USE_SIDEBAR ++ 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); @@ -476,7 +468,7 @@ index 6af817f..7ff2996 100644 mutt_paddstr (W, fcc); if (WithCrypto) -@@ -266,7 +266,7 @@ static void draw_envelope (HEADER *msg, char *fcc) +@@ -266,7 +272,7 @@ #endif SETCOLOR (MT_COLOR_STATUS); @@ -485,16 +477,16 @@ index 6af817f..7ff2996 100644 clrtoeol (); NORMAL_COLOR; -@@ -302,7 +302,7 @@ static int edit_address_list (int line, ADDRESS **addr) +@@ -302,7 +308,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); ++ move (line, HDR_XOFFSET + SidebarWidth); mutt_paddstr (W, buf); return 0; -@@ -564,7 +564,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */ +@@ -564,7 +570,7 @@ if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0) { mutt_str_replace (&msg->env->subject, buf); @@ -503,7 +495,7 @@ index 6af817f..7ff2996 100644 if (msg->env->subject) mutt_paddstr (W, msg->env->subject); else -@@ -582,7 +582,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */ +@@ -582,7 +588,7 @@ { strfcpy (fcc, buf, fcclen); mutt_pretty_mailbox (fcc, fcclen); @@ -512,52 +504,75 @@ index 6af817f..7ff2996 100644 mutt_paddstr (W, fcc); fccSet = 1; } -diff --git a/configure.ac b/configure.ac -index 6c579dd..8c833fa 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1306,6 +1306,8 @@ if test $mutt_cv_langinfo_yesexpr = yes; then - AC_DEFINE(HAVE_LANGINFO_YESEXPR,1,[ Define if you have <langinfo.h> and nl_langinfo(YESEXPR). ]) +diff -urN mutt-1.6.1/configure.ac mutt-1.6.1-sidebar/configure.ac +--- mutt-1.6.1/configure.ac 2016-05-02 03:02:12.398171401 +0100 ++++ mutt-1.6.1-sidebar/configure.ac 2016-05-02 03:02:15.011212974 +0100 +@@ -175,6 +175,15 @@ + SMIMEAUX_TARGET="smime_keys" fi -+AC_CHECK_FUNCS(fmemopen open_memstream) ++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" ++ need_sidebar="yes" ++ fi ++]) ++AM_CONDITIONAL(BUILD_SIDEBAR, test x$need_sidebar = xyes) + - dnl Documentation tools - have_openjade="no" - AC_PATH_PROG([OSPCAT], [ospcat], [none]) -diff --git a/curs_main.c b/curs_main.c -index f418f67..7583eba 100644 ---- a/curs_main.c -+++ b/curs_main.c -@@ -26,7 +26,9 @@ + 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-05-02 03:02:12.398171401 +0100 ++++ mutt-1.6.1-sidebar/copy.c 2016-05-02 03:02:15.011212974 +0100 +@@ -288,7 +288,7 @@ + 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) - SidebarWidth, 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-05-02 03:02:12.400171433 +0100 ++++ mutt-1.6.1-sidebar/curs_main.c 2016-05-02 03:02:15.012212990 +0100 +@@ -26,8 +26,13 @@ #include "mailbox.h" #include "mapping.h" #include "sort.h" +#include "buffy.h" #include "mx.h" -+#include "sidebar.h" ++#ifdef USE_SIDEBAR ++#include "sidebar.h" ++#endif ++ #ifdef USE_POP #include "pop.h" -@@ -672,20 +674,31 @@ int mutt_index_menu (void) + #endif +@@ -595,21 +600,39 @@ menu->redraw |= REDRAW_STATUS; if (do_buffy_notify) { - if (mutt_buffy_notify () && option (OPTBEEPNEW)) - beep (); -+ if (mutt_buffy_notify ()) ++ if (mutt_buffy_notify()) + { + menu->redraw |= REDRAW_STATUS; + if (option (OPTBEEPNEW)) -+ beep (); ++ beep(); + } } else do_buffy_notify = 1; } -+ if(option(OPTSIDEBAR)) ++#ifdef USE_SIDEBAR ++ if (option (OPTSIDEBAR)) + menu->redraw |= REDRAW_SIDEBAR; ++#endif + if (op != -1) mutt_curs_set (0); @@ -565,28 +580,42 @@ index f418f67..7583eba 100644 if (menu->redraw & REDRAW_FULL) { menu_redraw_full (menu); -+ draw_sidebar(menu->menu); ++#ifdef USE_SIDEBAR ++ sb_draw(); ++#endif mutt_show_error (); -+ } else if(menu->redraw & REDRAW_SIDEBAR) { -+ draw_sidebar(menu->menu); -+ menu->redraw &= ~REDRAW_SIDEBAR; } ++#ifdef USE_SIDEBAR ++ else if (menu->redraw & REDRAW_SIDEBAR) { ++ sb_draw(); ++ menu->redraw &= ~REDRAW_SIDEBAR; ++ } ++#endif if (menu->menu == MENU_MAIN) -@@ -707,9 +720,12 @@ int mutt_index_menu (void) + { +@@ -630,9 +653,20 @@ if (menu->redraw & REDRAW_STATUS) { -+ DrawFullLine = 1; ++#ifdef USE_SIDEBAR ++ /* Temporarily lie about the sidebar width */ ++ short sw = SidebarWidth; ++ SidebarWidth = 0; ++#endif menu_status_line (buf, sizeof (buf), menu, NONULL (Status)); -+ DrawFullLine = 0; ++#ifdef USE_SIDEBAR ++ SidebarWidth = sw; /* Restore the sidebar width */ ++#endif move (option (OPTSTATUSONTOP) ? 0 : LINES-2, 0); SETCOLOR (MT_COLOR_STATUS); -+ set_buffystats(Context); ++#ifdef USE_SIDEBAR ++ sb_set_buffystats (Context); ++#endif mutt_paddstr (COLS, buf); NORMAL_COLOR; menu->redraw &= ~REDRAW_STATUS; -@@ -729,7 +745,7 @@ int mutt_index_menu (void) +@@ -652,7 +686,7 @@ menu->oldcurrent = -1; if (option (OPTARROWCURSOR)) @@ -595,411 +624,1846 @@ index f418f67..7583eba 100644 else if (option (OPTBRAILLEFRIENDLY)) move (menu->current - menu->top + menu->offset, 0); else -@@ -1170,6 +1186,7 @@ int mutt_index_menu (void) +@@ -1091,6 +1125,9 @@ break; CHECK_MSGCOUNT; -+ CHECK_VISIBLE; ++#ifdef USE_SIDEBAR ++ CHECK_VISIBLE; ++#endif CHECK_READONLY; { int oldvcount = Context->vcount; -@@ -1229,6 +1246,7 @@ int mutt_index_menu (void) +@@ -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: -@@ -1260,7 +1278,11 @@ int mutt_index_menu (void) +@@ -1181,6 +1221,14 @@ { 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) ++#ifdef USE_SIDEBAR ++ if (op == OP_SIDEBAR_OPEN) { ++ const char *path = 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) - { -@@ -1278,6 +1300,7 @@ int mutt_index_menu (void) +@@ -1199,6 +1247,9 @@ } mutt_expand_path (buf, sizeof (buf)); -+ set_curbuffy(buf); ++#ifdef USE_SIDEBAR ++ sb_set_open_buffy (buf); ++#endif if (mx_get_magic (buf) <= 0) { mutt_error (_("%s is not a mailbox."), buf); -@@ -2402,6 +2425,12 @@ int mutt_index_menu (void) +@@ -2310,6 +2361,21 @@ mutt_what_key(); break; -+ case OP_SIDEBAR_SCROLL_UP: -+ case OP_SIDEBAR_SCROLL_DOWN: ++#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: -+ scroll_sidebar(op, menu->menu); ++ case OP_SIDEBAR_PREV_NEW: ++ 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 --git a/doc/Muttrc b/doc/Muttrc -index c8689d0..01272c7 100644 ---- a/doc/Muttrc -+++ b/doc/Muttrc -@@ -657,6 +657,26 @@ attachments -I message/external-body - # $crypt_autosign, $crypt_replysign and $smime_is_default. - # - # -+# set sidebar_visible=no -+# -+# Name: sidebar_visible -+# Type: boolean -+# Default: no -+# -+# -+# This specifies whether or not to show sidebar (left-side list of folders). -+# -+# -+# set sidebar_width=0 -+# -+# Name: sidebar_width -+# Type: number -+# Default: 0 -+# -+# -+# The width of the sidebar. -+# -+# - # set crypt_autosign=no - # - # Name: crypt_autosign -diff --git a/flags.c b/flags.c -index 5309bb7..8776b18 100644 ---- a/flags.c -+++ b/flags.c -@@ -22,8 +22,10 @@ - - #include "mutt.h" - #include "mutt_curses.h" -+#include "mutt_menu.h" +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-05-02 03:02:12.402171465 +0100 ++++ mutt-1.6.1-sidebar/doc/manual.xml.head 2016-05-02 03:02:15.014213022 +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><change-folder></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><sidebar-next></literal> and ++ <literal><sidebar-prev></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><sidebar-open></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><sidebar-toggle-visible></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 > 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>%>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><sidebar-scroll-down></literal></entry> ++ <entry><literal><sidebar-page-down></literal></entry> ++ </row> ++ <row> ++ <entry><literal><sidebar-scroll-up></literal></entry> ++ <entry><literal><sidebar-page-up></literal></entry> ++ </row> ++ </tbody> ++ </tgroup> ++ </table> ++ </sect3> ++</sect2> ++ + <sect2 id="intro-help"> + <title>Help</title> + +@@ -8081,6 +8698,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.5.24</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> </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><sidebar-next></literal></entry> ++ <entry>Move the highlight to next mailbox</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-next-new></literal></entry> ++ <entry>Move the highlight to next mailbox with new mail</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-open></literal></entry> ++ <entry>Open highlighted mailbox</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-page-down></literal></entry> ++ <entry>Scroll the Sidebar down 1 page</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-page-up></literal></entry> ++ <entry>Scroll the Sidebar up 1 page</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-prev></literal></entry> ++ <entry>Move the highlight to previous mailbox</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-prev-new></literal></entry> ++ <entry>Move the highlight to previous mailbox with new mail</entry> ++ </row> ++ <row> ++ <entry>index,pager</entry> ++ <entry><literal><sidebar-toggle-visible></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 <F3> 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 <F4> sidebar-page-down ++ ++<emphasis role="comment"># Move the highlight to the previous mailbox containing new, or flagged, ++# mail.</emphasis> ++bind index,pager <F5> sidebar-prev-new ++ ++<emphasis role="comment"># Move the highlight to the next mailbox containing new, or flagged, mail.</emphasis> ++bind index,pager <F6> 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 +10317,17 @@ + + <listitem> + <cmdsynopsis> ++<command>sidebar_whitelist</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/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-05-02 03:02:14.932211718 +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-05-02 03:02:14.933211733 +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/flags.c mutt-1.6.1-sidebar/flags.c +--- mutt-1.6.1/flags.c 2016-05-02 03:02:12.403171480 +0100 ++++ mutt-1.6.1-sidebar/flags.c 2016-05-02 03:02:15.015213038 +0100 +@@ -25,6 +25,10 @@ #include "sort.h" #include "mx.h" -+#include "sidebar.h" ++#ifdef USE_SIDEBAR ++#include "sidebar.h" ++#endif ++ 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) + 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; -+ draw_sidebar(0); ++#ifdef USE_SIDEBAR ++ sb_draw(); ++#endif } 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 */ +diff -urN mutt-1.6.1/functions.h mutt-1.6.1-sidebar/functions.h +--- mutt-1.6.1/functions.h 2016-05-02 03:02:12.403171480 +0100 ++++ mutt-1.6.1-sidebar/functions.h 2016-05-02 03:02:15.015213038 +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 -+ { "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 */ +@@ -272,6 +282,17 @@ { "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 }, ++#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 --git a/globals.h b/globals.h -index 241758d..92de9db 100644 ---- a/globals.h -+++ b/globals.h -@@ -118,6 +118,9 @@ WHERE short SearchContext; +diff -urN mutt-1.6.1/globals.h mutt-1.6.1-sidebar/globals.h +--- mutt-1.6.1/globals.h 2016-05-02 03:02:12.403171480 +0100 ++++ mutt-1.6.1-sidebar/globals.h 2016-05-02 03:02:15.015213038 +0100 +@@ -118,6 +118,12 @@ WHERE char *SendCharset; WHERE char *Sendmail; WHERE char *Shell; -+WHERE char *SidebarDelim; ++#ifdef USE_SIDEBAR ++WHERE char *SidebarDelimChars; ++WHERE char *SidebarDividerChar; +WHERE char *SidebarFormat; -+WHERE char *SidebarIndentStr; ++WHERE char *SidebarIndentString; ++#endif WHERE char *Signature; WHERE char *SimpleSearch; #if USE_SMTP -@@ -215,6 +218,9 @@ WHERE short ScoreThresholdDelete; +@@ -214,6 +220,14 @@ WHERE short ScoreThresholdRead; WHERE short ScoreThresholdFlag; -+WHERE struct buffy_t *CurBuffy INITVAL(0); -+WHERE short DrawFullLine INITVAL(0); ++/* 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 --git a/handler.c b/handler.c -index 4944d49..d7fde34 100644 ---- a/handler.c -+++ b/handler.c -@@ -1603,6 +1603,11 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla - - fseeko (s->fpin, b->offset, 0); - -+#ifdef HAVE_FMEMOPEN -+ char *temp; -+ size_t tempsize; -+#endif -+ - /* see if we need to decode this part before processing it */ - if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE || - b->encoding == ENCUUENCODED || plaintext || -@@ -1618,6 +1623,14 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla - { - /* decode to a tempfile, saving the original destination */ - fp = s->fpout; -+#ifdef HAVE_FMEMOPEN -+ if ((s->fpout = open_memstream(&temp, &tempsize)) == NULL) -+ { -+ mutt_error _("Unable to open memory stream!"); -+ dprint (1, (debugfile, "Can't open memory stream.\n")); -+ return -1; -+ } -+#else - mutt_mktemp (tempfile, sizeof (tempfile)); - if ((s->fpout = safe_fopen (tempfile, "w")) == NULL) - { -@@ -1625,6 +1638,7 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla - dprint (1, (debugfile, "Can't open %s.\n", tempfile)); - return -1; - } -+#endif - /* decoding the attachment changes the size and offset, so save a copy - * of the "real" values now, and restore them after processing - */ -@@ -1653,9 +1667,19 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla - /* restore final destination and substitute the tempfile for input */ - s->fpout = fp; - fp = s->fpin; -+#ifdef HAVE_FMEMOPEN -+ if(tempsize) -+ s->fpin = fmemopen(temp, tempsize, "r"); -+ else /* fmemopen cannot handle zero-length buffers */ -+ s->fpin = safe_fopen ("/dev/null", "r"); -+ if(s->fpin == NULL) { -+ mutt_perror("failed to re-open memstream!"); -+ return (-1); -+ } -+#else - s->fpin = fopen (tempfile, "r"); - unlink (tempfile); -- -+#endif - /* restore the prefix */ - s->prefix = savePrefix; - } -@@ -1680,6 +1704,10 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla - - /* restore the original source stream */ - safe_fclose (&s->fpin); -+#ifdef HAVE_FMEMOPEN -+ if(tempsize) -+ FREE(&temp); -+#endif - s->fpin = fp; - } - } -diff --git a/imap/command.c b/imap/command.c -index d99a99a..5068fca 100644 ---- a/imap/command.c -+++ b/imap/command.c -@@ -1016,6 +1016,13 @@ static void cmd_parse_status (IMAP_DATA* idata, char* s) +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-05-02 03:02:12.404171496 +0100 ++++ mutt-1.6.1-sidebar/imap/command.c 2016-05-02 03:02:14.939211829 +0100 +@@ -1016,6 +1016,14 @@ 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; -+ } ++#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 --git a/imap/imap.c b/imap/imap.c -index a8476a4..5dab152 100644 ---- a/imap/imap.c -+++ b/imap/imap.c -@@ -1541,7 +1541,7 @@ int imap_buffy_check (int force) +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-05-02 03:02:12.404171496 +0100 ++++ mutt-1.6.1-sidebar/imap/imap.c 2016-05-02 03:02:15.016213054 +0100 +@@ -1535,7 +1535,11 @@ imap_munge_mbox_name (idata, munged, sizeof (munged), name); snprintf (command, sizeof (command), -- "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged); ++#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 --git a/init.h b/init.h -index 246020b..2e7371c 100644 ---- a/init.h -+++ b/init.h -@@ -2061,6 +2061,54 @@ struct option_t MuttVars[] = { - ** not used. - ** (PGP only) +diff -urN mutt-1.6.1/init.c mutt-1.6.1-sidebar/init.c +--- mutt-1.6.1/init.c 2016-05-02 03:02:12.405171512 +0100 ++++ mutt-1.6.1-sidebar/init.c 2016-05-02 03:02:15.017213070 +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-05-02 03:02:12.407171544 +0100 ++++ mutt-1.6.1-sidebar/init.h 2016-05-02 03:02:15.018213086 +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,146 @@ + ** Command to use when spawning a subshell. By default, the user's login + ** shell from \fC/etc/passwd\fP is used. */ -+ {"sidebar_delim", DT_STR, R_BOTH, UL &SidebarDelim, UL "|"}, ++#ifdef USE_SIDEBAR ++ { "sidebar_divider_char", DT_STR, R_BOTH, UL &SidebarDividerChar, UL "|" }, + /* + ** .pp -+ ** This specifies the delimiter between the sidebar (if visible) and -+ ** other screens. ++ ** 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_indentstr", DT_STR, R_BOTH, UL &SidebarIndentStr, UL " "}, ++ { "sidebar_delim_chars", DT_STR, R_NONE, UL &SidebarDelimChars, UL "/." }, + /* + ** .pp -+ ** This specifies the string that is used to indent items -+ ** with sidebar_folderindent= yes ++ ** 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 ++ ** 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_visible", DT_BOOL, R_BOTH, OPTSIDEBAR, 0 }, ++ { "sidebar_folder_indent", DT_BOOL, R_BOTH, OPTSIDEBARFOLDERINDENT, 0 }, + /* + ** .pp -+ ** This specifies whether or not to show sidebar (left-side list of folders). ++ ** Set this to indent mailboxes in the sidebar. ++ ** .pp ++ ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_indent_string, $$sidebar_delim_chars. + */ -+ { "sidebar_sort", DT_BOOL, R_BOTH, OPTSIDEBARSORT, 0 }, ++ { "sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%?F? [%F]?%* %?N?%N/?%S" }, + /* + ** .pp -+ ** This specifies whether or not to sort the sidebar alphabetically. ++ ** 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_width", DT_NUM, R_BOTH, UL &SidebarWidth, 0 }, ++ { "sidebar_indent_string", DT_STR, R_BOTH, UL &SidebarIndentString, UL " " }, + /* + ** .pp -+ ** The width of the sidebar. ++ ** 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_shortpath", DT_BOOL, R_BOTH, OPTSIDEBARSHORTPATH, 0 }, ++ { "sidebar_new_mail_only", DT_BOOL, R_BOTH, OPTSIDEBARNEWMAILONLY, 0 }, + /* + ** .pp -+ ** Should the sidebar shorten the path showed. ++ ** When set, the sidebar will only display mailboxes containing new, or ++ ** flagged, mail. ++ ** .pp ++ ** \fBSee also:\fP $sidebar_whitelist. + */ -+ {"sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%?F? [%F]?%* %?N?%N/?%4S"}, ++ { "sidebar_next_new_wrap", DT_BOOL, R_BOTH, UL OPTSIDEBARNEXTNEWWRAP, 0 }, + /* + ** .pp -+ ** Format string for the sidebar. The sequences `%N', `%F' and `%S' -+ ** will be replaced by the number of new or flagged messages or the total -+ ** size of them mailbox. `%B' will be replaced with the name of the mailbox. -+ ** The `%!' sequence will be expanded to `!' if there is one flagged message; -+ ** to `!!' if there are two flagged messages; and to `n!' for n flagged -+ ** messages, n>2. ++ ** 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_folderindent", DT_BOOL, R_BOTH, OPTSIDEBARFOLDERINDENT, 0 }, ++ { "sidebar_refresh_time", DT_NUM, R_BOTH, UL &SidebarRefreshTime, 60 }, + /* + ** .pp -+ ** Should folders be indented in the sidebar. ++ ** Set sidebar_refresh_time to the minimum number of seconds between refreshes. ++ ** This will reduced network traffic. ++ ** .pp ++ ** \fBNote:\fP Set to 0 to disable refreshing. + */ -+ - { "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0}, ++ { "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 -diff --git a/mailbox.h b/mailbox.h -index 2b2c9a1..000503d 100644 ---- a/mailbox.h -+++ b/mailbox.h -@@ -27,6 +27,7 @@ +@@ -3652,6 +3793,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 +3895,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-05-02 03:02:12.407171544 +0100 ++++ mutt-1.6.1-sidebar/keymap.c 2016-05-02 03:02:14.946211940 +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-05-02 03:02:12.407171544 +0100 ++++ mutt-1.6.1-sidebar/mailbox.h 2016-05-02 03:02:15.018213086 +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 --git a/main.c b/main.c -index 0b60d85..0e11dc5 100644 ---- a/main.c -+++ b/main.c -@@ -50,6 +50,7 @@ - #include <unistd.h> - #include <errno.h> - #include <sys/stat.h> -+#include <limits.h> - #include <sys/utsname.h> - - #ifdef HAVE_GETOPT_H -@@ -563,7 +564,7 @@ init_extended_keys(); +diff -urN mutt-1.6.1/main.c mutt-1.6.1-sidebar/main.c +--- mutt-1.6.1/main.c 2016-05-02 03:02:12.408171560 +0100 ++++ mutt-1.6.1-sidebar/main.c 2016-05-02 03:02:15.018213086 +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) { -- char folder[_POSIX_PATH_MAX] = ""; ++#ifdef USE_SIDEBAR + char folder[PATH_MAX] = ""; ++#else + char folder[_POSIX_PATH_MAX] = ""; ++#endif char *subject = NULL; char *includeFile = NULL; char *draftFile = NULL; -@@ -1204,6 +1205,13 @@ int main (int argc, char **argv) +@@ -828,6 +841,9 @@ + clear (); + mutt_error = mutt_curses_error; + mutt_message = mutt_curses_message; ++#ifdef USE_SIDEBAR ++ 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]; ++ char tmpfolder[PATH_MAX] = ""; + strfcpy (tmpfolder, folder, sizeof (tmpfolder)); -+ if(!realpath(tmpfolder, folder)) -+ strfcpy (folder, tmpfolder, sizeof (tmpfolder)); ++ if (!realpath (tmpfolder, folder)) ++ strfcpy (folder, tmpfolder, sizeof (tmpfolder)); + } ++#endif + mutt_str_replace (&CurrentFolder, folder); mutt_str_replace (&LastFolder, folder); -@@ -1226,6 +1234,7 @@ int main (int argc, char **argv) +@@ -1206,6 +1231,9 @@ if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL)) || !explicit_folder) { -+ set_curbuffy(folder); ++#ifdef USE_SIDEBAR ++ sb_set_open_buffy (folder); ++#endif mutt_index_menu (); if (Context) FREE (&Context); -diff --git a/mbox.c b/mbox.c -index 9ff8512..e2818a5 100644 ---- a/mbox.c -+++ b/mbox.c -@@ -104,6 +104,7 @@ int mmdf_parse_mailbox (CONTEXT *ctx) +diff -urN mutt-1.6.1/Makefile.am mutt-1.6.1-sidebar/Makefile.am +--- mutt-1.6.1/Makefile.am 2016-05-02 03:02:12.392171305 +0100 ++++ mutt-1.6.1-sidebar/Makefile.am 2016-05-02 03:02:15.005212879 +0100 +@@ -77,6 +77,12 @@ + + EXTRA_SCRIPTS = smime_keys + ++if BUILD_SIDEBAR ++mutt_SOURCES += sidebar.c sidebar.h ++endif ++ ++EXTRA_DIST += OPS.SIDEBAR ++ + mutt_dotlock_SOURCES = mutt_dotlock.c + mutt_dotlock_LDADD = $(LIBOBJS) + mutt_dotlock_DEPENDENCIES = $(LIBOBJS) +@@ -129,10 +135,10 @@ + 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)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME \ ++ $(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME \ + > keymap_alldefs.h + + reldate.h: $(srcdir)/ChangeLog +diff -urN mutt-1.6.1/mbox.c mutt-1.6.1-sidebar/mbox.c +--- mutt-1.6.1/mbox.c 2016-05-02 03:02:12.408171560 +0100 ++++ mutt-1.6.1-sidebar/mbox.c 2016-05-02 03:02:14.948211972 +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; -@@ -255,6 +256,7 @@ int mbox_parse_mailbox (CONTEXT *ctx) +@@ -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 --git a/menu.c b/menu.c -index 4b13e7c..379b94c 100644 ---- a/menu.c -+++ b/menu.c -@@ -24,6 +24,7 @@ +diff -urN mutt-1.6.1/menu.c mutt-1.6.1-sidebar/menu.c +--- mutt-1.6.1/menu.c 2016-05-02 03:02:12.408171560 +0100 ++++ mutt-1.6.1-sidebar/menu.c 2016-05-02 03:02:15.019213102 +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 +185,7 @@ static void menu_pad_string (char *s, size_t n) +@@ -184,7 +187,7 @@ { char *scratch = safe_strdup (s); int shift = option (OPTARROWCURSOR) ? 3 : 0; @@ -1008,15 +2472,17 @@ index 4b13e7c..379b94c 100644 mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1); s[n - 1] = 0; -@@ -237,6 +238,7 @@ void menu_redraw_index (MUTTMENU *menu) +@@ -237,6 +240,9 @@ int do_color; int attr; -+ draw_sidebar(1); ++#ifdef USE_SIDEBAR ++ sb_draw(); ++#endif for (i = menu->top; i < menu->top + menu->pagelen; i++) { if (i < menu->max) -@@ -247,7 +249,7 @@ void menu_redraw_index (MUTTMENU *menu) +@@ -247,7 +253,7 @@ menu_pad_string (buf, sizeof (buf)); ATTRSET(attr); @@ -1025,16 +2491,19 @@ index 4b13e7c..379b94c 100644 do_color = 1; if (i == menu->current) -@@ -270,7 +272,7 @@ void menu_redraw_index (MUTTMENU *menu) +@@ -270,7 +276,11 @@ else { NORMAL_COLOR; -- CLEARLINE(i - menu->top + menu->offset); -+ CLEARLINE_WIN (i - menu->top + menu->offset); ++#ifdef USE_SIDEBAR ++ CLEARLINE_WIN(i - menu->top + menu->offset); ++#else + CLEARLINE(i - menu->top + menu->offset); ++#endif } } NORMAL_COLOR; -@@ -287,7 +289,7 @@ void menu_redraw_motion (MUTTMENU *menu) +@@ -287,7 +297,7 @@ return; } @@ -1043,7 +2512,7 @@ index 4b13e7c..379b94c 100644 ATTRSET(menu->color (menu->oldcurrent)); if (option (OPTARROWCURSOR)) -@@ -299,13 +301,13 @@ void menu_redraw_motion (MUTTMENU *menu) +@@ -299,13 +309,13 @@ { menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent); menu_pad_string (buf, sizeof (buf)); @@ -1059,7 +2528,7 @@ index 4b13e7c..379b94c 100644 } else { -@@ -318,7 +320,7 @@ void menu_redraw_motion (MUTTMENU *menu) +@@ -318,7 +328,7 @@ menu_make_entry (buf, sizeof (buf), menu, menu->current); menu_pad_string (buf, sizeof (buf)); SETCOLOR(MT_COLOR_INDICATOR); @@ -1068,7 +2537,7 @@ index 4b13e7c..379b94c 100644 print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0); } menu->redraw &= REDRAW_STATUS; -@@ -330,7 +332,7 @@ void menu_redraw_current (MUTTMENU *menu) +@@ -330,7 +340,7 @@ char buf[LONG_STRING]; int attr = menu->color (menu->current); @@ -1077,7 +2546,7 @@ index 4b13e7c..379b94c 100644 menu_make_entry (buf, sizeof (buf), menu, menu->current); menu_pad_string (buf, sizeof (buf)); -@@ -882,7 +884,7 @@ int mutt_menuLoop (MUTTMENU *menu) +@@ -873,7 +883,7 @@ if (option (OPTARROWCURSOR)) @@ -1086,178 +2555,188 @@ index 4b13e7c..379b94c 100644 else if (option (OPTBRAILLEFRIENDLY)) move (menu->current - menu->top + menu->offset, 0); else -diff --git a/mh.c b/mh.c -index bc87660..3121fca 100644 ---- a/mh.c -+++ b/mh.c -@@ -295,6 +295,32 @@ void mh_buffy(BUFFY *b) +diff -urN mutt-1.6.1/mh.c mutt-1.6.1-sidebar/mh.c +--- mutt-1.6.1/mh.c 2016-05-02 03:02:12.409171576 +0100 ++++ mutt-1.6.1-sidebar/mh.c 2016-05-02 03:02:15.019213102 +0100 +@@ -295,6 +295,49 @@ mhs_free_sequences (&mhs); } -+void mh_buffy_update (const char *path, int *msgcount, int *msg_unread, int *msg_flagged, time_t *sb_last_checked) ++#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; -+ memset (&mhs, 0, sizeof (mhs)); -+ -+ if(!option(OPTSIDEBAR)) -+ return; -+ -+ 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); -+ *sb_last_checked = time(NULL); ++ if (!mailbox) ++ return; ++ ++ if (!option (OPTSIDEBAR)) ++ return; ++ ++ struct mh_sequences mhs; ++ 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; ++ ++ int i; ++ 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 --git a/mutt.h b/mutt.h -index 26f260e..91e58e9 100644 ---- a/mutt.h -+++ b/mutt.h -@@ -441,6 +441,10 @@ enum +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-05-02 03:02:12.409171576 +0100 ++++ mutt-1.6.1-sidebar/mutt_curses.h 2016-05-02 03:02:15.019213102 +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 + }; + +diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-sidebar/mutt.h +--- mutt-1.6.1/mutt.h 2016-05-02 03:02:12.409171576 +0100 ++++ mutt-1.6.1-sidebar/mutt.h 2016-05-02 03:02:15.019213102 +0100 +@@ -428,6 +428,13 @@ OPTSAVEEMPTY, OPTSAVENAME, OPTSCORE, ++#ifdef USE_SIDEBAR + OPTSIDEBAR, -+ OPTSIDEBARSHORTPATH, -+ OPTSIDEBARSORT, + OPTSIDEBARFOLDERINDENT, ++ OPTSIDEBARNEWMAILONLY, ++ OPTSIDEBARNEXTNEWWRAP, ++ OPTSIDEBARSHORTPATH, ++#endif OPTSIGDASHES, OPTSIGONTOP, OPTSORTRE, -@@ -887,6 +891,7 @@ typedef struct _context +@@ -872,6 +879,9 @@ { char *path; FILE *fp; ++#ifdef USE_SIDEBAR + time_t atime; ++#endif time_t mtime; off_t size; off_t vsize; -@@ -927,6 +932,7 @@ typedef struct _context +@@ -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 --git a/mutt_curses.h b/mutt_curses.h -index 93d9aea..888aa1c 100644 ---- a/mutt_curses.h -+++ b/mutt_curses.h -@@ -64,6 +64,7 @@ - #undef lines - #endif /* lines */ +diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-sidebar/muttlib.c +--- mutt-1.6.1/muttlib.c 2016-05-02 03:02:12.410171592 +0100 ++++ mutt-1.6.1-sidebar/muttlib.c 2016-05-02 03:02:15.020213118 +0100 +@@ -1282,7 +1282,7 @@ + pl = pw = 1; -+#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) -@@ -124,6 +125,8 @@ enum - MT_COLOR_UNDERLINE, - MT_COLOR_INDEX, - MT_COLOR_PROMPT, -+ MT_COLOR_NEW, -+ MT_COLOR_FLAGGED, - MT_COLOR_MAX - }; + /* 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 @@ -diff --git a/mutt_menu.h b/mutt_menu.h -index bbcd722..4999748 100644 ---- a/mutt_menu.h -+++ b/mutt_menu.h -@@ -34,6 +34,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-05-02 03:02:12.409171576 +0100 ++++ mutt-1.6.1-sidebar/mutt_menu.h 2016-05-02 03:02:15.019213102 +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 --git a/muttlib.c b/muttlib.c -index 53cb4a3..3c4e768 100644 ---- a/muttlib.c -+++ b/muttlib.c -@@ -1282,6 +1282,8 @@ void mutt_FormatString (char *dest, /* output buffer */ - pl = pw = 1; +diff -urN mutt-1.6.1/mx.c mutt-1.6.1-sidebar/mx.c +--- mutt-1.6.1/mx.c 2016-05-02 03:02:12.410171592 +0100 ++++ mutt-1.6.1-sidebar/mx.c 2016-05-02 03:02:15.020213118 +0100 +@@ -29,6 +29,9 @@ + #include "copy.h" + #include "keymap.h" + #include "url.h" ++#ifdef USE_SIDEBAR ++#include "sidebar.h" ++#endif - /* see if there's room to add content, else ignore */ -+ if ( DrawFullLine ) -+ { - if ((col < COLS && wlen < destlen) || soft) - { - int pad; -@@ -1325,6 +1327,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 be2d0e9..16fcdf4 100644 ---- a/mx.c -+++ b/mx.c -@@ -595,6 +595,7 @@ static int mx_open_mailbox_append (CONTEXT *ctx, int flags) + #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 @@ -1265,104 +2744,137 @@ index be2d0e9..16fcdf4 100644 * 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) +@@ -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)) { -@@ -721,13 +724,26 @@ 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 - +@@ -705,8 +713,21 @@ if(!ctx) return; -+#ifndef BUFFY_SIZE + ++#ifdef USE_SIDEBAR + /* fix up the times so buffy won't get confused */ -+ if (ctx->peekonly && ctx->path && ctx->mtime > ctx->atime) -+ { -+ ut.actime = ctx->atime; ++ struct utimbuf ut; ++ if (ctx->peekonly && ctx->path && (ctx->mtime > ctx->atime)) { ++ ut.actime = ctx->atime; + ut.modtime = ctx->mtime; -+ utime (ctx->path, &ut); ++ 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 */ -- mutt_buffy_setnotified(ctx->path); -+ if(!ctx->peekonly) -+ mutt_buffy_setnotified(ctx->path); ++#ifdef USE_SIDEBAR ++ if (!ctx->peekonly) ++#endif + mutt_buffy_setnotified(ctx->path); if (ctx->mx_close) - ctx->mx_close (ctx); -@@ -739,6 +755,8 @@ void mx_fastclose_mailbox (CONTEXT *ctx) +@@ -719,6 +740,10 @@ mutt_clear_threads (ctx); for (i = 0; i < ctx->msgcount; i++) mutt_free_header (&ctx->hdrs[i]); ++#ifdef USE_SIDEBAR + ctx->msgcount -= ctx->deleted; -+ set_buffystats(ctx); ++ sb_set_buffystats (ctx); ++#endif FREE (&ctx->hdrs); FREE (&ctx->v2r); - #ifdef USE_COMPRESSED -@@ -895,6 +913,10 @@ int mx_close_mailbox (CONTEXT *ctx, int *index_hint) + FREE (&ctx->path); +@@ -812,6 +837,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) -diff --git a/mx.h b/mx.h -index d926cf6..ab398cb 100644 ---- a/mx.h -+++ b/mx.h -@@ -60,6 +60,7 @@ void mbox_reset_atime (CONTEXT *, struct stat *); +diff -urN mutt-1.6.1/mx.h mutt-1.6.1-sidebar/mx.h +--- mutt-1.6.1/mx.h 2016-05-02 03:02:12.410171592 +0100 ++++ mutt-1.6.1-sidebar/mx.h 2016-05-02 03:02:15.020213118 +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 *); -+void mh_buffy_update (const char *, int *, int *, int *, time_t *); ++#ifdef USE_SIDEBAR ++void mh_buffy_update (BUFFY *mailbox); ++#endif int mh_check_empty (const char *); int maildir_read_dir (CONTEXT *); -diff --git a/pager.c b/pager.c -index b9f72c2..676fd39 100644 ---- a/pager.c -+++ b/pager.c -@@ -29,6 +29,7 @@ +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-05-02 03:02:15.005212879 +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-05-02 03:02:12.411171608 +0100 ++++ mutt-1.6.1-sidebar/pager.c 2016-05-02 03:02:15.021213134 +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" -@@ -1096,6 +1097,7 @@ static int format_line (struct line_t **lineInfo, int n, unsigned char *buf, +@@ -1096,6 +1099,9 @@ wchar_t wc; mbstate_t mbstate; int wrap_cols = mutt_term_width ((flags & M_PAGER_NOWRAP) ? 0 : Wrap); ++#ifdef USE_SIDEBAR + wrap_cols -= SidebarWidth; ++#endif if (check_attachment_marker ((char *)buf) == 0) wrap_cols = COLS; -@@ -1573,6 +1575,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra) +@@ -1491,7 +1497,7 @@ + * a newline (grr!). + */ + #ifndef USE_SLANG_CURSES +- if (col < COLS) ++ if (col < (COLS - SidebarWidth)) + #endif + addch ('\n'); + +@@ -1573,6 +1579,7 @@ int bodyoffset = 1; /* offset of first line of real text */ int statusoffset = 0; /* offset for the status bar */ -+ int statuswidth; ++ int statuswidth = COLS; int helpoffset = LINES - 2; /* offset for the help bar. */ int bodylen = LINES - 2 - bodyoffset; /* length of displayable area */ -@@ -1747,7 +1750,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra) +@@ -1747,7 +1754,7 @@ if ((redraw & REDRAW_BODY) || topline != oldtopline) { do { @@ -1371,27 +2883,35 @@ index b9f72c2..676fd39 100644 curline = oldtopline = topline; lines = 0; force_redraw = 0; -@@ -1760,6 +1763,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra) +@@ -1760,6 +1767,9 @@ &QuoteList, &q_level, &force_redraw, &SearchRE) > 0) lines++; curline++; -+ move(lines + bodyoffset, SidebarWidth); ++#ifdef USE_SIDEBAR ++ move (lines + bodyoffset, SidebarWidth); ++#endif } last_offset = lineInfo[curline].offset; } while (force_redraw); -@@ -1772,6 +1776,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra) +@@ -1772,6 +1782,9 @@ addch ('~'); addch ('\n'); lines++; -+ move(lines + bodyoffset, SidebarWidth); ++#ifdef USE_SIDEBAR ++ move (lines + bodyoffset, SidebarWidth); ++#endif } NORMAL_COLOR; -@@ -1789,29 +1794,39 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra) +@@ -1789,29 +1802,49 @@ hfi.ctx = Context; hfi.pager_progress = pager_progress_str; -+ statuswidth = COLS - (option(OPTSTATUSONTOP) && PagerIndexLines > 0 ? SidebarWidth : 0); ++#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)); @@ -1402,12 +2922,16 @@ index b9f72c2..676fd39 100644 - move (statusoffset, 0); + move (statusoffset, SidebarWidth); SETCOLOR (MT_COLOR_STATUS); -+ if(option(OPTSTATUSONTOP) && PagerIndexLines > 0) { -+ CLEARLINE_WIN (statusoffset); ++#ifdef USE_SIDEBAR ++ short sw = SidebarWidth; ++ if (option (OPTSTATUSONTOP) && PagerIndexLines > 0) { ++ CLEARLINE_WIN (statusoffset); + } else { -+ CLEARLINE (statusoffset); -+ DrawFullLine = 1; /* for mutt_make_string_info */ ++ CLEARLINE (statusoffset); ++ /* Temporarily lie about the sidebar width */ ++ SidebarWidth = 0; + } ++#endif if (IsHeader (extra) || IsMsgAttach (extra)) { @@ -1426,16 +2950,20 @@ index b9f72c2..676fd39 100644 - mutt_paddstr (COLS, bn); + mutt_paddstr (statuswidth, bn); } -+ if(!option(OPTSTATUSONTOP) || PagerIndexLines == 0) -+ DrawFullLine = 0; /* reset */ ++#ifdef USE_SIDEBAR ++ if (!option (OPTSTATUSONTOP) || PagerIndexLines == 0) ++ SidebarWidth = sw; /* Restore the sidebar width */ ++#endif NORMAL_COLOR; if (option(OPTTSENABLED) && TSSupported) { -@@ -1827,16 +1842,22 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra) +@@ -1827,16 +1860,26 @@ /* redraw the pager_index indicator, because the * flags for this message might have changed. */ menu_redraw_current (index); -+ draw_sidebar(MENU_PAGER); ++#ifdef USE_SIDEBAR ++ sb_draw(); ++#endif /* print out the index status bar */ menu_status_line (buffer, sizeof (buffer), index, NONULL(Status)); @@ -1449,590 +2977,1340 @@ index b9f72c2..676fd39 100644 NORMAL_COLOR; } ++#ifdef USE_SIDEBAR + /* if we're not using the index, update every time */ -+ if ( index == 0 ) -+ draw_sidebar(MENU_PAGER); ++ if (index == 0) ++ sb_draw(); ++#endif + redraw = 0; if (option(OPTBRAILLEFRIENDLY)) { -@@ -2783,6 +2804,13 @@ search_next: +@@ -2498,8 +2541,12 @@ + ch = 0; + } + +- if (option (OPTFORCEREDRAWPAGER)) ++ if (option (OPTFORCEREDRAWPAGER)) { + redraw = REDRAW_FULL; ++#ifdef USE_SIDEBAR ++ sb_draw(); ++#endif ++ } + unset_option (OPTFORCEREDRAWINDEX); + unset_option (OPTFORCEREDRAWPAGER); + break; +@@ -2777,6 +2824,22 @@ mutt_what_key (); break; -+ case OP_SIDEBAR_SCROLL_UP: -+ case OP_SIDEBAR_SCROLL_DOWN: ++#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: -+ scroll_sidebar(ch, MENU_PAGER); -+ break; ++ case OP_SIDEBAR_PREV_NEW: ++ sb_change_mailbox (ch); ++ break; ++ ++ case OP_SIDEBAR_TOGGLE_VISIBLE: ++ toggle_option (OPTSIDEBAR); ++ redraw = REDRAW_FULL; ++ break; ++#endif + default: ch = -1; break; -diff --git a/pattern.c b/pattern.c -index aeef591..406fd84 100644 ---- a/pattern.c -+++ b/pattern.c -@@ -154,6 +154,10 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno) - HEADER *h = ctx->hdrs[msgno]; - char *buf; - size_t blen; -+#ifdef HAVE_FMEMOPEN -+ char *temp; -+ size_t tempsize; -+#endif - - if ((msg = mx_open_message (ctx, msgno)) != NULL) - { -@@ -163,12 +167,20 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno) - memset (&s, 0, sizeof (s)); - s.fpin = msg->fp; - s.flags = M_CHARCONV; -+#ifdef HAVE_FMEMOPEN -+ if((s.fpout = open_memstream(&temp, &tempsize)) == NULL) -+ { -+ mutt_perror ("Error opening memstream"); -+ return (0); -+ } -+#else - mutt_mktemp (tempfile, sizeof (tempfile)); - if ((s.fpout = safe_fopen (tempfile, "w+")) == NULL) - { - mutt_perror (tempfile); - return (0); - } -+#endif - - if (pat->op != M_BODY) - mutt_copy_header (msg->fp, h, s.fpout, CH_FROM | CH_DECODE, NULL); -@@ -184,7 +196,11 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno) - if (s.fpout) - { - safe_fclose (&s.fpout); -+#ifdef HAVE_FMEMOPEN -+ FREE(&temp); -+#else - unlink (tempfile); -+#endif - } - return (0); - } -@@ -193,11 +209,28 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno) - mutt_body_handler (h->content, &s); - } - -+#ifdef HAVE_FMEMOPEN -+ fclose(s.fpout); -+ lng = tempsize; -+ -+ if(tempsize) { -+ if ((fp = fmemopen(temp, tempsize, "r")) == NULL) { -+ mutt_perror ("Error re-opening memstream"); -+ return (0); -+ } -+ } else { /* fmemopen cannot handle empty buffers */ -+ if ((fp = safe_fopen ("/dev/null", "r")) == NULL) { -+ mutt_perror ("Error opening /dev/null"); -+ return (0); -+ } -+ } -+#else - fp = s.fpout; - fflush (fp); - fseek (fp, 0, 0); - fstat (fileno (fp), &st); - lng = (long) st.st_size; -+#endif - } - else - { -@@ -244,7 +277,12 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno) - if (option (OPTTHOROUGHSRC)) - { - safe_fclose (&fp); -+#ifdef HAVE_FMEMOPEN -+ if(tempsize) -+ FREE (&temp); -+#else - unlink (tempfile); -+#endif - } - } - -diff --git a/protos.h b/protos.h -index 98a207a..5c83f82 100644 ---- a/protos.h -+++ b/protos.h -@@ -36,6 +36,13 @@ struct hdr_format_info - const char *pager_progress; - }; - -+struct sidebar_entry { -+ char box[SHORT_STRING]; -+ unsigned int size; -+ unsigned int new; -+ unsigned int flagged; -+}; +diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-sidebar/PATCHES +--- mutt-1.6.1/PATCHES 2016-05-02 03:02:12.396171369 +0100 ++++ mutt-1.6.1-sidebar/PATCHES 2016-05-02 03:02:15.008212927 +0100 +@@ -0,0 +1 @@ ++patch-sidebar-neo-20160502 +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-05-02 03:02:15.008212927 +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.5.24 ++ ++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 + - void mutt_make_string_info (char *, size_t, const char *, struct hdr_format_info *, format_flag); - - int mutt_extract_token (BUFFER *, BUFFER *, int); -diff --git a/sidebar.c b/sidebar.c -new file mode 100644 -index 0000000..e9d9eba ---- /dev/null -+++ b/sidebar.c -@@ -0,0 +1,410 @@ -+/* -+ * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu> ++ 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-05-02 03:02:15.023213165 +0100 +@@ -0,0 +1,1069 @@ ++/* 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 "mutt_menu.h" -+#include "mutt_curses.h" -+#include "sidebar.h" +#include "buffy.h" -+#include <libgen.h> +#include "keymap.h" -+#include <stdbool.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[SHORT_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); + -+/*BUFFY *CurBuffy = 0;*/ -+static BUFFY *TopBuffy = 0; -+static BUFFY *BottomBuffy = 0; -+static int known_lines = 0; ++ return NULL; ++} + -+void calc_boundaries() { ++/** ++ * 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; + -+ BUFFY *tmp = Incoming; ++ do { ++ b = b->prev; ++ if (!b && wrap) { ++ b = Outgoing; ++ } ++ if (!b || (b == HilBuffy)) { ++ break; ++ } ++ if (b->msg_unread > 0) { ++ return b; ++ } ++ } while (b); + -+ int count = LINES - 2 - (option(OPTHELP) ? 1 : 0); ++ return NULL; ++} + -+ if ( known_lines != LINES ) { -+ TopBuffy = BottomBuffy = 0; -+ known_lines = LINES; ++/** ++ * 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[SHORT_STRING], buf[SHORT_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 (buf, sizeof (buf), "%d!", b->msg_flagged); ++ mutt_format_s (dest, destlen, prefix, buf); ++ } ++ 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; ++ strncpy (sbe.box, box, sizeof (sbe.box) - 1); ++ ++ int box_len = strlen (box); ++ sbe.box[box_len] = '\0'; ++ ++ /* 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); ++ 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; + } -+ for ( ; tmp->next != 0; tmp = tmp->next ) -+ tmp->next->prev = tmp; -+ -+ if ( TopBuffy == 0 && BottomBuffy == 0 ) -+ TopBuffy = Incoming; -+ if ( BottomBuffy == 0 ) { -+ BottomBuffy = TopBuffy; -+ while ( --count && BottomBuffy->next ) -+ BottomBuffy = BottomBuffy->next; ++ ++ 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; + } -+ else if ( TopBuffy == CurBuffy->next ) { -+ BottomBuffy = CurBuffy; -+ tmp = BottomBuffy; -+ while ( --count && tmp->prev) -+ tmp = tmp->prev; -+ TopBuffy = tmp; ++ ++ 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; + } -+ else if ( BottomBuffy == CurBuffy->prev ) { -+ TopBuffy = CurBuffy; -+ tmp = TopBuffy; -+ while ( --count && tmp->next ) -+ tmp = tmp->next; -+ BottomBuffy = tmp; ++ ++ if (b->next) { ++ b->next->prev = NULL; ++ return b->next; + } ++ ++ return b->prev; +} + -+static const char * -+sidebar_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) ++/** ++ * 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) +{ -+/* casting from unsigned long - srsly?! */ -+struct sidebar_entry *sbe = (struct sidebar_entry *) data; -+unsigned int optional; -+char fmt[SHORT_STRING], buf[SHORT_STRING]; -+ -+optional = flags & M_FORMAT_OPTIONAL; -+ -+switch(op) { -+ case 'F': -+ if(!optional) { -+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix); -+ snprintf (dest, destlen, fmt, sbe->flagged); -+ } else if(sbe->flagged == 0) { -+ optional = 0; ++ 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; + } -+ break; -+ -+ case '!': -+ if(sbe->flagged == 0) -+ mutt_format_s(dest, destlen, prefix, ""); -+ if(sbe->flagged == 1) -+ mutt_format_s(dest, destlen, prefix, "!"); -+ if(sbe->flagged == 2) -+ mutt_format_s(dest, destlen, prefix, "!!"); -+ if(sbe->flagged > 2) { -+ snprintf (buf, sizeof (buf), "%d!", sbe->flagged); -+ mutt_format_s(dest, destlen, prefix, buf); ++ ++ if (Context && (strcmp (b->path, Context->path) == 0)) { ++ /* Spool directory */ ++ continue; + } -+ break; -+ -+ case 'S': -+ if(!optional) { -+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix); -+ snprintf (dest, destlen, fmt, sbe->size); -+ } else if (sbe->size == 0) { -+ optional = 0; -+ } -+ break; -+ -+ case 'N': -+ if(!optional) { -+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix); -+ snprintf (dest, destlen, fmt, sbe->new); -+ } else if(sbe->new == 0) { -+ optional = 0; ++ ++ if (mutt_find_list (SidebarWhitelist, b->path)) { ++ /* Explicitly asked to be visible */ ++ continue; + } -+ break; + -+ case 'B': -+ mutt_format_s(dest, destlen, prefix, sbe->box); -+ break; ++ b->is_hidden = 1; + } ++} + -+ if(optional) -+ mutt_FormatString (dest, destlen, col, ifstring, sidebar_format_str, (unsigned long) sbe, flags); -+ else if (flags & M_FORMAT_OPTIONAL) -+ mutt_FormatString (dest, destlen, col, elsestring, sidebar_format_str, (unsigned long) sbe, flags); ++/** ++ * 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; + -+ return (src); ++ for (i = 1; i < arr_len; i++) { ++ arr[i]->prev = arr[i - 1]; ++ } ++ arr[0]->prev = NULL; +} + -+char *make_sidebar_entry(char *box, unsigned int size, unsigned int new, unsigned int flagged) { -+ static char *entry = 0; -+ struct sidebar_entry sbe; -+ int SBvisual; ++/** ++ * 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)); ++ if (!arr) ++ return 0; + -+ SBvisual = SidebarWidth - strlen(SidebarDelim); -+ if (SBvisual < 1) -+ return NULL; ++ int i = 0; ++ for (b = Incoming; b; b = b->next, i++) { ++ arr[i] = b; ++ } + -+ sbe.new = new; -+ sbe.flagged = flagged; -+ sbe.size = size; -+ strncpy(sbe.box, box, 31); ++ update_buffy_visibility (arr, count); ++ sort_buffy_array (arr, count); + -+ safe_realloc(&entry, SBvisual + 2); -+ entry[SBvisual + 1] = '\0'; ++ Incoming = arr[0]; + -+ mutt_FormatString (entry, SBvisual+1, 0, SidebarFormat, sidebar_format_str, (unsigned long) &sbe, 0); ++ int top_index = 0; ++ int opn_index = -1; ++ int hil_index = -1; ++ int bot_index = -1; + -+ return entry; ++ 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; +} + -+void set_curbuffy(char buf[LONG_STRING]) ++/** ++ * 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) +{ -+ BUFFY* tmp = CurBuffy = Incoming; ++ short new_visible = option (OPTSIDEBAR); ++ short new_width = SidebarWidth; + -+ if (!Incoming) -+ return; ++ if (OldWidth != new_width) { ++ if (new_width > 0) { ++ OldWidth = new_width; ++ } ++ } + -+ while(1) { -+ if(!strcmp(tmp->path, buf) || !strcmp(tmp->realpath, buf)) { -+ CurBuffy = tmp; -+ break; -+ } ++ 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(tmp->next) -+ tmp = tmp->next; -+ else -+ break; -+ } ++ if (!option (OPTSIDEBAR)) { ++ SidebarWidth = 0; ++ } else if (new_width == 0) { ++ SidebarWidth = OldWidth; ++ } else { ++ SidebarWidth = new_width; ++ } ++ ++ return new_visible; +} + -+int draw_sidebar(int menu) { -+ -+ 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; -+ int lines = 0; -+ int SidebarHeight; -+ -+ if(option(OPTSTATUSONTOP) || option(OPTHELP)) -+ lines++; /* either one will occupy the first line */ -+ -+ /* 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)) { -+ mutt_buffy_check(1); /* we probably have bad or no numbers */ -+ 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); -+ } ++/** ++ * 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 ( SidebarWidth == 0 || !option(OPTSIDEBAR)) { -+ if (SidebarWidth > 0) { -+ saveSidebarWidth = SidebarWidth; -+ SidebarWidth = 0; -+ } -+ unset_option(OPTSIDEBAR); -+ return 0; -+ } ++ if (delim_len < 1) ++ return delim_len; + -+ /* 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); ++ if ((SidebarWidth + delim_len) > (COLS + 1)) ++ return 0; + -+ /* draw the divider */ ++ if (delim_len > SidebarWidth) ++ return -1; + -+ SidebarHeight = LINES - 1; -+ if(option(OPTHELP) || !option(OPTSTATUSONTOP)) -+ SidebarHeight--; ++ SETCOLOR(MT_COLOR_DIVIDER); + -+ for ( ; lines < SidebarHeight; 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 ++ int i; ++ for (i = 0; i < num_rows; i++) { ++ move (first_row + i, SidebarWidth - delim_len); ++ addstr (NONULL(SidebarDividerChar)); + } + -+ if ( Incoming == 0 ) return 0; -+ lines = 0; -+ if(option(OPTSTATUSONTOP) || option(OPTHELP)) -+ lines++; /* either one will occupy the first line */ ++ return delim_len; ++} + -+ if ( known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0 ) -+ calc_boundaries(menu); -+ if ( CurBuffy == 0 ) CurBuffy = Incoming; ++/** ++ * 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); + -+ tmp = TopBuffy; ++ int r; ++ for (r = 0; r < num_rows; r++) { ++ int i = 0; ++ move (first_row + r, 0); ++ for (; i < width; i++) ++ addch (' '); ++ } ++} + -+ SETCOLOR(MT_COLOR_NORMAL); ++/** ++ * 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; + -+ for ( ; tmp && lines < SidebarHeight; tmp = tmp->next ) { -+ if ( tmp == CurBuffy ) -+ SETCOLOR(MT_COLOR_INDICATOR); -+ else if ( tmp->msg_unread > 0 ) ++ 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 ( tmp->msg_flagged > 0 ) -+ SETCOLOR(MT_COLOR_FLAGGED); -+ else ++ } 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; ++ } + -+ move( lines, 0 ); -+ if ( Context && Context->path && -+ (!strcmp(tmp->path, Context->path)|| -+ !strcmp(tmp->realpath, Context->path)) ) { -+ tmp->msg_unread = Context->unread; -+ tmp->msgcount = Context->msgcount; -+ tmp->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(tmp->path) > strlen(Maildir)) && -+ (strncmp(Maildir, tmp->path, strlen(Maildir)) == 0) ) -+ maildir_is_prefix = 1; ++ 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; -+ sidebar_folder_name = option(OPTSIDEBARSHORTPATH) ? mutt_basename(tmp->path) : tmp->path + maildir_is_prefix*(strlen(Maildir) + 1); -+ if ( maildir_is_prefix && option(OPTSIDEBARFOLDERINDENT) ) { -+ char *tmp_folder_name; -+ int i; -+ tmp_folder_name = tmp->path + strlen(Maildir) + 1; -+ for (i = 0; i < strlen(tmp->path) - strlen(Maildir); i++) { -+ if (tmp_folder_name[i] == '/' || tmp_folder_name[i] == '.') sidebar_folder_depth++; -+ } ++ 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 = strrchr(tmp->path, '.'); -+ if (tmp_folder_name == NULL) -+ tmp_folder_name = mutt_basename(tmp->path); -+ else -+ tmp_folder_name++; -+ } -+ else -+ tmp_folder_name = tmp->path + strlen(Maildir) + 1; -+ sidebar_folder_name = malloc(strlen(tmp_folder_name) + sidebar_folder_depth*strlen(NONULL(SidebarIndentStr)) + 1); ++ 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(SidebarIndentStr), strlen(NONULL(SidebarIndentStr))); -+ strncat(sidebar_folder_name, tmp_folder_name, strlen(tmp_folder_name)); ++ strncat (sidebar_folder_name, NONULL(SidebarIndentString), strlen (NONULL(SidebarIndentString))); ++ strncat (sidebar_folder_name, tmp_folder_name, strlen (tmp_folder_name)); + } + } -+ printw( "%.*s", SidebarWidth - delim_len + 1, -+ make_sidebar_entry(sidebar_folder_name, tmp->msgcount, -+ tmp->msg_unread, tmp->msg_flagged)); ++ char str[SHORT_STRING]; ++ make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, b); ++ printw ("%s", str); + if (sidebar_folder_depth > 0) -+ free(sidebar_folder_name); -+ lines++; ++ free (sidebar_folder_name); ++ row++; + } -+ SETCOLOR(MT_COLOR_NORMAL); -+ for ( ; lines < SidebarHeight; lines++ ) { -+ int i = 0; -+ move( lines, 0 ); -+ for ( ; i < SidebarWidth - delim_len; i++ ) -+ addch(' '); ++ ++ fill_empty_space (first_row + row, num_rows - row, w); ++} ++ ++ ++/** ++ * sb_init - Set some default values for the sidebar. ++ */ ++void ++sb_init (void) ++{ ++ OldVisible = option (OPTSIDEBAR); ++ if (SidebarWidth > 0) { ++ OldWidth = SidebarWidth; ++ } else { ++ OldWidth = 20; ++ if (OldVisible) { ++ SidebarWidth = OldWidth; ++ } + } -+ return 0; +} + ++/** ++ * 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 ++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 first_row = 0; ++ int num_rows = LINES - 2; ++ ++ if (option (OPTHELP) || option (OPTSTATUSONTOP)) ++ first_row++; ++ ++ if (option (OPTHELP)) ++ num_rows--; + -+void set_buffystats(CONTEXT* Context) ++ 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); ++} ++ ++/** ++ * 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 ++sb_should_refresh (void) +{ -+ BUFFY *tmp = Incoming; -+ while(tmp) { -+ if(Context && (!strcmp(tmp->path, Context->path) || -+ !strcmp(tmp->realpath, Context->path))) { -+ tmp->msg_unread = Context->unread; -+ tmp->msgcount = Context->msgcount; -+ tmp->msg_flagged = Context->flagged; -+ break; -+ } -+ tmp = tmp->next; -+ } ++ if (!option (OPTSIDEBAR)) ++ return 0; ++ ++ if (SidebarRefreshTime == 0) ++ return 0; ++ ++ time_t diff = (time (NULL) - LastRefresh); ++ ++ return (diff >= SidebarRefreshTime); +} + -+void scroll_sidebar(int op, int menu) ++/** ++ * 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 ++sb_change_mailbox (int op) +{ -+ if(!SidebarWidth) return; -+ if(!CurBuffy) return; ++ BUFFY *b; ++ if (!HilBuffy) /* It'll get reset on the next draw */ ++ return; + + switch (op) { + case OP_SIDEBAR_NEXT: -+ if ( CurBuffy->next == NULL ) return; -+ CurBuffy = CurBuffy->next; ++ if (!HilBuffy->next) ++ return; ++ if (HilBuffy->next->is_hidden) ++ return; ++ HilBuffy = HilBuffy->next; + break; -+ case OP_SIDEBAR_PREV: -+ if ( CurBuffy->prev == NULL ) return; -+ CurBuffy = CurBuffy->prev; ++ 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_SCROLL_UP: -+ CurBuffy = TopBuffy; -+ if ( CurBuffy != Incoming ) { -+ calc_boundaries(menu); -+ CurBuffy = CurBuffy->prev; ++ case OP_SIDEBAR_PAGE_UP: ++ HilBuffy = TopBuffy; ++ if (HilBuffy != Incoming) { ++ HilBuffy = HilBuffy->prev; + } + break; -+ case OP_SIDEBAR_SCROLL_DOWN: -+ CurBuffy = BottomBuffy; -+ if ( CurBuffy->next ) { -+ calc_boundaries(menu); -+ CurBuffy = CurBuffy->next; ++ 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; + } -+ calc_boundaries(menu); -+ draw_sidebar(menu); ++ ++ /* We can change folder even if the sidebar is hidden */ ++ if (option (OPTSIDEBAR)) ++ sb_draw(); ++} ++ ++/** ++ * 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 ++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; ++ } ++ } ++} ++ ++/** ++ * 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 * ++sb_get_highlight (void) ++{ ++ if (!HilBuffy) ++ return NULL; ++ ++ return HilBuffy->path; +} + -diff --git a/sidebar.h b/sidebar.h -new file mode 100644 -index 0000000..d195f11 ---- /dev/null -+++ b/sidebar.h ++/** ++ * 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 * ++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; ++} ++ ++/** ++ * 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 ++sb_set_update_time (void) ++{ ++ /* XXX - should this be public? */ ++ ++ LastRefresh = time (NULL); ++} ++ ++/** ++ * 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 ++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 { ++ if (TopBuffy == b) ++ TopBuffy = buffy_going (TopBuffy); ++ if (OpnBuffy == b) ++ OpnBuffy = buffy_going (OpnBuffy); ++ if (HilBuffy == b) ++ HilBuffy = buffy_going (HilBuffy); ++ if (BotBuffy == b) ++ BotBuffy = buffy_going (BotBuffy); ++ if (Outgoing == b) ++ Outgoing = buffy_going (Outgoing); ++ } ++} +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-05-02 03:02:15.023213165 +0100 @@ -0,0 +1,36 @@ -+/* -+ * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu> ++/* 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 + -+struct MBOX_LIST { -+ char *path; -+ int msgcount; -+ int new; -+} MBLIST; ++#include "mutt.h" ++#include "buffy.h" + -+/* 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*); ++void sb_change_mailbox (int op); ++void sb_draw (void); ++const char * sb_get_highlight (void); ++void sb_init (void); ++void sb_notify_mailbox (BUFFY *b, int created); ++void sb_set_buffystats (const CONTEXT *ctx); ++BUFFY * sb_set_open_buffy (const char *path); ++void sb_set_update_time (void); ++int 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-05-02 03:02:12.440172071 +0100 ++++ mutt-1.6.1-sidebar/sort.h 2016-05-02 03:02:15.023213165 +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); |