]> git.llucax.com Git - software/mutt-debian.git/blob - debian/patches/mutt-patched/sidebar
584138-mx_update_context-segfault.patch: fix a segfault due to holes in IMAP headers...
[software/mutt-debian.git] / debian / patches / mutt-patched / sidebar
1 This is the sidebar patch.
2
3 When enabled, mutt will show a list of mailboxes with (new) message counts in a
4 separate column on the left side of the screen.
5
6 As this feature is still considered to be unstable, this patch is only applied
7 in the "mutt-patched" package.
8
9 * Configuration variables:
10
11   sidebar_delim (string, default "|")
12
13     This specifies the delimiter between the sidebar (if visible) and 
14     other screens.
15
16   sidebar_visible (boolean, default no)
17
18     This specifies whether or not to show sidebar (left-side list of folders).
19
20   sidebar_width (integer, default 0)
21 -
22     The width of the sidebar.
23
24 * Patch source:
25   - http://www.lunar-linux.org/index.php?page=mutt-sidebar
26   - http://lunar-linux.org/~tchan/mutt/patch-1.5.19.sidebar.20090522.txt
27
28 * Changes made:
29   - 2008-08-02 myon: Refreshed patch using quilt push -f to remove hunks we do
30     not need (Makefile.in).
31
32 --- a/Makefile.am
33 +++ b/Makefile.am
34 @@ -32,6 +32,7 @@
35         rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
36         score.c send.c sendlib.c signal.c sort.c \
37         status.c system.c thread.c charset.c history.c lib.c \
38 +       sidebar.c \
39         muttlib.c editmsg.c mbyte.c \
40         url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c
41  
42 --- a/OPS
43 +++ b/OPS
44 @@ -180,3 +180,8 @@
45  OP_MAIN_SHOW_LIMIT "show currently active limit pattern"
46  OP_MAIN_COLLAPSE_THREAD "collapse/uncollapse current thread"
47  OP_MAIN_COLLAPSE_ALL "collapse/uncollapse all threads"
48 +OP_SIDEBAR_SCROLL_UP "scroll the mailbox pane up 1 page"
49 +OP_SIDEBAR_SCROLL_DOWN "scroll the mailbox pane down 1 page"
50 +OP_SIDEBAR_NEXT "go down to next mailbox"
51 +OP_SIDEBAR_PREV "go to previous mailbox"
52 +OP_SIDEBAR_OPEN "open hilighted mailbox"
53 --- a/buffy.c
54 +++ b/buffy.c
55 @@ -340,6 +340,68 @@
56    return rc;
57  }
58  
59 +/* update message counts for the sidebar */
60 +void buffy_maildir_update (BUFFY* mailbox)
61 +{
62 +  char path[_POSIX_PATH_MAX];
63 +  DIR *dirp;
64 +  struct dirent *de;
65 +  char *p;
66 +
67 +  mailbox->msgcount = 0;
68 +  mailbox->msg_unread = 0;
69 +  mailbox->msg_flagged = 0;
70 +
71 +  snprintf (path, sizeof (path), "%s/new", mailbox->path);
72 +        
73 +  if ((dirp = opendir (path)) == NULL)
74 +  {   
75 +    mailbox->magic = 0;
76 +    return;
77 +  } 
78 +      
79 +  while ((de = readdir (dirp)) != NULL)
80 +  {
81 +    if (*de->d_name == '.')
82 +      continue;
83 +
84 +    if (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')) {
85 +      mailbox->new = 1;
86 +      mailbox->msgcount++;
87 +      mailbox->msg_unread++;
88 +    }
89 +  }
90 +
91 +  closedir (dirp);
92 +  snprintf (path, sizeof (path), "%s/cur", mailbox->path);
93 +        
94 +  if ((dirp = opendir (path)) == NULL)
95 +  {   
96 +    mailbox->magic = 0;
97 +    return;
98 +  } 
99 +      
100 +  while ((de = readdir (dirp)) != NULL)
101 +  {
102 +    if (*de->d_name == '.')
103 +      continue;
104 +
105 +    if (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')) {
106 +      mailbox->msgcount++;
107 +      if ((p = strstr (de->d_name, ":2,"))) {
108 +        if (!strchr (p + 3, 'T')) {
109 +          if (!strchr (p + 3, 'S'))
110 +            mailbox->msg_unread++;
111 +          if (strchr(p + 3, 'F'))
112 +            mailbox->msg_flagged++;
113 +        }
114 +      }
115 +    }
116 +  }
117 +
118 +  closedir (dirp);
119 +}
120 +
121  /* returns 1 if mailbox has new mail */ 
122  static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb)
123  {
124 @@ -371,6 +433,20 @@
125    return rc;
126  }
127  
128 +/* update message counts for the sidebar */
129 +void buffy_mbox_update (BUFFY* mailbox)
130 +{
131 +  CONTEXT *ctx = NULL;
132 +
133 +  ctx = mx_open_mailbox(mailbox->path, M_READONLY | M_QUIET | M_NOSORT | M_PEEK, NULL);
134 +  if(ctx)
135 +  {
136 +    mailbox->msgcount = ctx->msgcount;
137 +    mailbox->msg_unread = ctx->unread;
138 +    mx_close_mailbox(ctx, 0);
139 +  }
140 +}
141 +
142  int mutt_buffy_check (int force)
143  {
144    BUFFY *tmp;
145 @@ -444,16 +520,19 @@
146        {
147        case M_MBOX:
148        case M_MMDF:
149 +       buffy_mbox_update (tmp);
150         if (buffy_mbox_hasnew (tmp, &sb) > 0)
151           BuffyCount++;
152         break;
153  
154        case M_MAILDIR:
155 +       buffy_maildir_update (tmp);
156         if (buffy_maildir_hasnew (tmp) > 0)
157           BuffyCount++;
158         break;
159  
160        case M_MH:
161 +       mh_buffy_update (tmp->path, &tmp->msgcount, &tmp->msg_unread, &tmp->msg_flagged);
162         if ((tmp->new = mh_buffy (tmp->path)) > 0)
163           BuffyCount++;
164         break;
165 --- a/buffy.h
166 +++ b/buffy.h
167 @@ -25,7 +25,11 @@
168    char path[_POSIX_PATH_MAX];
169    off_t size;
170    struct buffy_t *next;
171 +  struct buffy_t *prev;
172    short new;                   /* mailbox has new mail */
173 +  int msgcount;                        /* total number of messages */
174 +  int msg_unread;              /* number of unread messages */
175 +  int msg_flagged;             /* number of flagged messages */
176    short notified;              /* user has been notified */
177    short magic;                 /* mailbox type */
178    short newly_created;         /* mbox or mmdf just popped into existence */
179 --- a/color.c
180 +++ b/color.c
181 @@ -93,6 +93,8 @@
182    { "bold",            MT_COLOR_BOLD },
183    { "underline",       MT_COLOR_UNDERLINE },
184    { "index",           MT_COLOR_INDEX },
185 +  { "sidebar_new",     MT_COLOR_NEW },
186 +  { "sidebar_flagged", MT_COLOR_FLAGGED },
187    { NULL,              0 }
188  };
189  
190 --- a/compose.c
191 +++ b/compose.c
192 @@ -72,7 +72,7 @@
193  
194  #define HDR_XOFFSET 10
195  #define TITLE_FMT "%10s" /* Used for Prompts, which are ASCII */
196 -#define W (COLS - HDR_XOFFSET)
197 +#define W (COLS - HDR_XOFFSET - SidebarWidth)
198  
199  static char *Prompts[] =
200  {
201 @@ -112,7 +112,7 @@
202  {
203    int off = 0;
204  
205 -  mvaddstr (HDR_CRYPT, 0, "Security: ");
206 +  mvaddstr (HDR_CRYPT, SidebarWidth, "Security: ");
207  
208    if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0)
209    {
210 @@ -144,7 +144,7 @@
211    }
212  
213    clrtoeol ();
214 -  move (HDR_CRYPTINFO, 0);
215 +  move (HDR_CRYPTINFO, SidebarWidth);
216    clrtoeol ();
217  
218    if ((WithCrypto & APPLICATION_PGP)
219 @@ -161,7 +161,7 @@
220        && (msg->security & ENCRYPT)
221        && SmimeCryptAlg
222        && *SmimeCryptAlg) {
223 -      mvprintw (HDR_CRYPTINFO, 40, "%s%s", _("Encrypt with: "),
224 +      mvprintw (HDR_CRYPTINFO, SidebarWidth + 40, "%s%s", _("Encrypt with: "),
225                 NONULL(SmimeCryptAlg));
226        off = 20;
227    }
228 @@ -175,7 +175,7 @@
229    int c;
230    char *t;
231  
232 -  mvaddstr (HDR_MIX, 0,     "     Mix: ");
233 +  mvaddstr (HDR_MIX, SidebarWidth,     "     Mix: ");
234  
235    if (!chain)
236    {
237 @@ -190,7 +190,7 @@
238      if (t && t[0] == '0' && t[1] == '\0')
239        t = "<random>";
240      
241 -    if (c + mutt_strlen (t) + 2 >= COLS)
242 +    if (c + mutt_strlen (t) + 2 >= COLS - SidebarWidth)
243        break;
244  
245      addstr (NONULL(t));
246 @@ -242,7 +242,7 @@
247  
248    buf[0] = 0;
249    rfc822_write_address (buf, sizeof (buf), addr, 1);
250 -  mvprintw (line, 0, TITLE_FMT, Prompts[line - 1]);
251 +  mvprintw (line, SidebarWidth, TITLE_FMT, Prompts[line - 1]);
252    mutt_paddstr (W, buf);
253  }
254  
255 @@ -252,10 +252,10 @@
256    draw_envelope_addr (HDR_TO, msg->env->to);
257    draw_envelope_addr (HDR_CC, msg->env->cc);
258    draw_envelope_addr (HDR_BCC, msg->env->bcc);
259 -  mvprintw (HDR_SUBJECT, 0, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
260 +  mvprintw (HDR_SUBJECT, SidebarWidth, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
261    mutt_paddstr (W, NONULL (msg->env->subject));
262    draw_envelope_addr (HDR_REPLYTO, msg->env->reply_to);
263 -  mvprintw (HDR_FCC, 0, TITLE_FMT, Prompts[HDR_FCC - 1]);
264 +  mvprintw (HDR_FCC, SidebarWidth, TITLE_FMT, Prompts[HDR_FCC - 1]);
265    mutt_paddstr (W, fcc);
266  
267    if (WithCrypto)
268 @@ -266,7 +266,7 @@
269  #endif
270  
271    SETCOLOR (MT_COLOR_STATUS);
272 -  mvaddstr (HDR_ATTACH - 1, 0, _("-- Attachments"));
273 +  mvaddstr (HDR_ATTACH - 1, SidebarWidth, _("-- Attachments"));
274    BKGDSET (MT_COLOR_STATUS);
275    clrtoeol ();
276  
277 @@ -304,7 +304,7 @@
278    /* redraw the expanded list so the user can see the result */
279    buf[0] = 0;
280    rfc822_write_address (buf, sizeof (buf), *addr, 1);
281 -  move (line, HDR_XOFFSET);
282 +  move (line, HDR_XOFFSET+SidebarWidth);
283    mutt_paddstr (W, buf);
284    
285    return 0;
286 @@ -549,7 +549,7 @@
287         if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0)
288         {
289           mutt_str_replace (&msg->env->subject, buf);
290 -         move (HDR_SUBJECT, HDR_XOFFSET);
291 +         move (HDR_SUBJECT, HDR_XOFFSET + SidebarWidth);
292           clrtoeol ();
293           if (msg->env->subject)
294             mutt_paddstr (W, msg->env->subject);
295 @@ -566,7 +566,7 @@
296         {
297           strfcpy (fcc, buf, fcclen);
298           mutt_pretty_mailbox (fcc, fcclen);
299 -         move (HDR_FCC, HDR_XOFFSET);
300 +         move (HDR_FCC, HDR_XOFFSET + SidebarWidth);
301           mutt_paddstr (W, fcc);
302           fccSet = 1;
303         }
304 --- a/curs_main.c
305 +++ b/curs_main.c
306 @@ -26,7 +26,9 @@
307  #include "mailbox.h"
308  #include "mapping.h"
309  #include "sort.h"
310 +#include "buffy.h"
311  #include "mx.h"
312 +#include "sidebar.h"
313  
314  #ifdef USE_POP
315  #include "pop.h"
316 @@ -532,8 +534,12 @@
317         menu->redraw |= REDRAW_STATUS;
318       if (do_buffy_notify)
319       {
320 -       if (mutt_buffy_notify () && option (OPTBEEPNEW))
321 -       beep ();
322 +       if (mutt_buffy_notify ())
323 +       {
324 +         menu->redraw |= REDRAW_FULL;
325 +         if (option (OPTBEEPNEW))
326 +           beep ();
327 +       }
328       }
329       else
330         do_buffy_notify = 1;
331 @@ -545,6 +551,7 @@
332      if (menu->redraw & REDRAW_FULL)
333      {
334        menu_redraw_full (menu);
335 +      draw_sidebar(menu->menu);
336        mutt_show_error ();
337      }
338  
339 @@ -567,10 +574,13 @@
340  
341        if (menu->redraw & REDRAW_STATUS)
342        {
343 +        DrawFullLine = 1;
344         menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
345 +        DrawFullLine = 0;
346         CLEARLINE (option (OPTSTATUSONTOP) ? 0 : LINES-2);
347         SETCOLOR (MT_COLOR_STATUS);
348          BKGDSET (MT_COLOR_STATUS);
349 +        set_buffystats(Context);
350         mutt_paddstr (COLS, buf);
351         SETCOLOR (MT_COLOR_NORMAL);
352          BKGDSET (MT_COLOR_NORMAL);
353 @@ -591,7 +601,7 @@
354         menu->oldcurrent = -1;
355  
356        if (option (OPTARROWCURSOR))
357 -       move (menu->current - menu->top + menu->offset, 2);
358 +       move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
359        else if (option (OPTBRAILLEFRIENDLY))
360         move (menu->current - menu->top + menu->offset, 0);
361        else
362 @@ -1089,6 +1099,7 @@
363           menu->redraw = REDRAW_FULL;
364         break;
365  
366 +      case OP_SIDEBAR_OPEN:
367        case OP_MAIN_CHANGE_FOLDER:
368        case OP_MAIN_NEXT_UNREAD_MAILBOX:
369  
370 @@ -1120,7 +1131,11 @@
371         {
372           mutt_buffy (buf, sizeof (buf));
373  
374 -         if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
375 +          if ( op == OP_SIDEBAR_OPEN ) {
376 +              if(!CurBuffy)
377 +                break;
378 +            strncpy( buf, CurBuffy->path, sizeof(buf) );  
379 +           } else if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
380           {
381             if (menu->menu == MENU_PAGER)
382             {
383 @@ -1138,6 +1153,7 @@
384         }
385  
386         mutt_expand_path (buf, sizeof (buf));
387 +        set_curbuffy(buf);
388         if (mx_get_magic (buf) <= 0)
389         {
390           mutt_error (_("%s is not a mailbox."), buf);
391 @@ -2241,6 +2257,12 @@
392         mutt_what_key();
393         break;
394  
395 +      case OP_SIDEBAR_SCROLL_UP:
396 +      case OP_SIDEBAR_SCROLL_DOWN:
397 +      case OP_SIDEBAR_NEXT:
398 +      case OP_SIDEBAR_PREV:
399 +        scroll_sidebar(op, menu->menu);
400 +        break;
401        default:
402         if (menu->menu == MENU_MAIN)
403           km_error_key (MENU_MAIN);
404 --- a/flags.c
405 +++ b/flags.c
406 @@ -22,8 +22,10 @@
407  
408  #include "mutt.h"
409  #include "mutt_curses.h"
410 +#include "mutt_menu.h"
411  #include "sort.h"
412  #include "mx.h"
413 +#include "sidebar.h"
414  
415  void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
416  {
417 @@ -290,6 +292,7 @@
418     */
419    if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged))
420      h->searched = 0;
421 +       draw_sidebar(0);
422  }
423  
424  void mutt_tag_set_flag (int flag, int bf)
425 --- a/functions.h
426 +++ b/functions.h
427 @@ -170,6 +170,11 @@
428    { "decrypt-save",            OP_DECRYPT_SAVE,                NULL },
429  
430  
431 + { "sidebar-scroll-up",        OP_SIDEBAR_SCROLL_UP, NULL },
432 + { "sidebar-scroll-down",      OP_SIDEBAR_SCROLL_DOWN, NULL },
433 + { "sidebar-next",             OP_SIDEBAR_NEXT, NULL },
434 + { "sidebar-prev",             OP_SIDEBAR_PREV, NULL },
435 + { "sidebar-open",             OP_SIDEBAR_OPEN, NULL },
436    { NULL,                      0,                              NULL }
437  };
438  
439 @@ -274,6 +279,11 @@
440  
441    { "what-key",                OP_WHAT_KEY,            NULL },
442  
443 +  { "sidebar-scroll-up",       OP_SIDEBAR_SCROLL_UP, NULL },
444 +  { "sidebar-scroll-down",     OP_SIDEBAR_SCROLL_DOWN, NULL },
445 +  { "sidebar-next",    OP_SIDEBAR_NEXT, NULL },
446 +  { "sidebar-prev",    OP_SIDEBAR_PREV, NULL },
447 +  { "sidebar-open", OP_SIDEBAR_OPEN, NULL },
448    { NULL,              0,                              NULL }
449  };
450  
451 --- a/globals.h
452 +++ b/globals.h
453 @@ -117,6 +117,7 @@
454  WHERE char *SendCharset;
455  WHERE char *Sendmail;
456  WHERE char *Shell;
457 +WHERE char *SidebarDelim;
458  WHERE char *Signature;
459  WHERE char *SimpleSearch;
460  #if USE_SMTP
461 @@ -210,6 +211,9 @@
462  WHERE short ScoreThresholdRead;
463  WHERE short ScoreThresholdFlag;
464  
465 +WHERE struct buffy_t *CurBuffy INITVAL(0);
466 +WHERE short DrawFullLine INITVAL(0);
467 +WHERE short SidebarWidth;
468  #ifdef USE_IMAP
469  WHERE short ImapKeepalive;
470  WHERE short ImapPipelineDepth;
471 --- a/imap/command.c
472 +++ b/imap/command.c
473 @@ -1011,6 +1011,13 @@
474              opened */
475           status->uidnext = oldun;
476  
477 +        /* Added to make the sidebar show the correct numbers */
478 +        if (status->messages)
479 +        {
480 +          inc->msgcount = status->messages;
481 +          inc->msg_unread = status->unseen;
482 +        }
483 +
484          FREE (&value);
485          return;
486        }
487 --- a/imap/imap.c
488 +++ b/imap/imap.c
489 @@ -1527,7 +1527,7 @@
490  
491      imap_munge_mbox_name (munged, sizeof (munged), name);
492      snprintf (command, sizeof (command),
493 -             "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
494 +             "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT MESSAGES)", munged);
495  
496      if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0)
497      {
498 --- a/init.h
499 +++ b/init.h
500 @@ -1965,6 +1965,22 @@
501    ** not used.
502    ** (PGP only)
503    */
504 +  {"sidebar_delim", DT_STR, R_BOTH, UL &SidebarDelim, "|"},
505 +  /*
506 +  ** .pp
507 +  ** This specifies the delimiter between the sidebar (if visible) and 
508 +  ** other screens.
509 +  */
510 +  { "sidebar_visible", DT_BOOL, R_BOTH, OPTSIDEBAR, 0 },
511 +  /*
512 +  ** .pp
513 +  ** This specifies whether or not to show sidebar (left-side list of folders).
514 +  */
515 +  { "sidebar_width", DT_NUM, R_BOTH, UL &SidebarWidth, 0 },
516 +  /*
517 +  ** .pp
518 +  ** The width of the sidebar.
519 +  */
520    { "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
521    /*
522    ** .pp
523 --- a/mailbox.h
524 +++ b/mailbox.h
525 @@ -27,6 +27,7 @@
526  #define M_NEWFOLDER    (1<<4) /* create a new folder - same as M_APPEND, but uses
527                                 * safe_fopen() for mbox-style folders.
528                                 */
529 +#define M_PEEK         (1<<5) /* revert atime back after taking a look (if applicable) */
530  
531  /* mx_open_new_message() */
532  #define M_ADD_FROM     1       /* add a From_ line */
533 --- a/mbox.c
534 +++ b/mbox.c
535 @@ -104,6 +104,7 @@
536      mutt_perror (ctx->path);
537      return (-1);
538    }
539 +  ctx->atime = sb.st_atime;
540    ctx->mtime = sb.st_mtime;
541    ctx->size = sb.st_size;
542  
543 @@ -255,6 +256,7 @@
544  
545    ctx->size = sb.st_size;
546    ctx->mtime = sb.st_mtime;
547 +  ctx->atime = sb.st_atime;
548  
549  #ifdef NFS_ATTRIBUTE_HACK
550    if (sb.st_mtime > sb.st_atime)
551 --- a/menu.c
552 +++ b/menu.c
553 @@ -24,6 +24,7 @@
554  #include "mutt_curses.h"
555  #include "mutt_menu.h"
556  #include "mbyte.h"
557 +#include "sidebar.h"
558  
559  #include <string.h>
560  #include <stdlib.h>
561 @@ -156,7 +157,7 @@
562  {
563    char *scratch = safe_strdup (s);
564    int shift = option (OPTARROWCURSOR) ? 3 : 0;
565 -  int cols = COLS - shift;
566 +  int cols = COLS - shift - SidebarWidth;
567  
568    mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1);
569    s[n - 1] = 0;
570 @@ -207,6 +208,7 @@
571    char buf[LONG_STRING];
572    int i;
573  
574 +  draw_sidebar(1);
575    for (i = menu->top; i < menu->top + menu->pagelen; i++)
576    {
577      if (i < menu->max)
578 @@ -217,7 +219,7 @@
579        if (option (OPTARROWCURSOR))
580        {
581          attrset (menu->color (i));
582 -       CLEARLINE (i - menu->top + menu->offset);
583 +       CLEARLINE_WIN (i - menu->top + menu->offset);
584  
585         if (i == menu->current)
586         {
587 @@ -246,14 +248,14 @@
588           BKGDSET (MT_COLOR_INDICATOR);
589         }
590  
591 -       CLEARLINE (i - menu->top + menu->offset);
592 +       CLEARLINE_WIN (i - menu->top + menu->offset);
593         print_enriched_string (menu->color(i), (unsigned char *) buf, i != menu->current);
594          SETCOLOR (MT_COLOR_NORMAL);
595          BKGDSET (MT_COLOR_NORMAL);
596        }
597      }
598      else
599 -      CLEARLINE (i - menu->top + menu->offset);
600 +      CLEARLINE_WIN (i - menu->top + menu->offset);
601    }
602    menu->redraw = 0;
603  }
604 @@ -268,7 +270,7 @@
605      return;
606    }
607    
608 -  move (menu->oldcurrent + menu->offset - menu->top, 0);
609 +  move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth);
610    SETCOLOR (MT_COLOR_NORMAL);
611    BKGDSET (MT_COLOR_NORMAL);
612  
613 @@ -283,13 +285,13 @@
614        clrtoeol ();
615        menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
616        menu_pad_string (buf, sizeof (buf));
617 -      move (menu->oldcurrent + menu->offset - menu->top, 3);
618 +      move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth + 3);
619        print_enriched_string (menu->color(menu->oldcurrent), (unsigned char *) buf, 1);
620        SETCOLOR (MT_COLOR_NORMAL);
621      }
622  
623      /* now draw it in the new location */
624 -    move (menu->current + menu->offset - menu->top, 0);
625 +    move (menu->current + menu->offset - menu->top, SidebarWidth);
626      attrset (menu->color (menu->current));
627      ADDCOLOR (MT_COLOR_INDICATOR);
628      addstr ("->");
629 @@ -310,7 +312,7 @@
630      attrset (menu->color (menu->current));
631      ADDCOLOR (MT_COLOR_INDICATOR);
632      BKGDSET (MT_COLOR_INDICATOR);
633 -    CLEARLINE (menu->current - menu->top + menu->offset);
634 +    CLEARLINE_WIN (menu->current - menu->top + menu->offset);
635      print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0);
636      SETCOLOR (MT_COLOR_NORMAL);
637      BKGDSET (MT_COLOR_NORMAL);
638 @@ -322,7 +324,7 @@
639  {
640    char buf[LONG_STRING];
641    
642 -  move (menu->current + menu->offset - menu->top, 0);
643 +  move (menu->current + menu->offset - menu->top, SidebarWidth);
644    menu_make_entry (buf, sizeof (buf), menu, menu->current);
645    menu_pad_string (buf, sizeof (buf));
646  
647 @@ -884,7 +886,7 @@
648      
649      
650      if (option (OPTARROWCURSOR))
651 -      move (menu->current - menu->top + menu->offset, 2);
652 +      move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
653      else if (option (OPTBRAILLEFRIENDLY))
654        move (menu->current - menu->top + menu->offset, 0);
655      else
656 --- a/mh.c
657 +++ b/mh.c
658 @@ -235,13 +235,37 @@
659  
660    if (mh_read_sequences (&mhs, path) < 0)
661      return 0;
662 +
663    for (i = 0; !r && i <= mhs.max; i++)
664 -    if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN)
665 +    if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN) {
666        r = 1;
667 +    }
668    mhs_free_sequences (&mhs);
669    return r;
670  }
671  
672 +void mh_buffy_update (const char *path, int *msgcount, int *msg_unread, int *msg_flagged)
673 +{
674 +  int i;
675 +  struct mh_sequences mhs;
676 +  memset (&mhs, 0, sizeof (mhs));
677 +
678 +  if (mh_read_sequences (&mhs, path) < 0)
679 +    return;
680 +
681 +  msgcount = 0;
682 +  msg_unread = 0;
683 +  msg_flagged = 0;
684 +  for (i = 0; i <= mhs.max; i++)
685 +    msgcount++;
686 +    if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN) {
687 +      msg_unread++;
688 +    }
689 +    if (mhs_check (&mhs, i) & MH_SEQ_FLAGGED)
690 +      msg_flagged++;
691 +  mhs_free_sequences (&mhs);
692 +}
693 +
694  static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
695  {
696    int fd;
697 --- a/mutt.h
698 +++ b/mutt.h
699 @@ -431,6 +431,7 @@
700    OPTSAVEEMPTY,
701    OPTSAVENAME,
702    OPTSCORE,
703 +  OPTSIDEBAR,
704    OPTSIGDASHES,
705    OPTSIGONTOP,
706    OPTSORTRE,
707 @@ -874,6 +875,7 @@
708  {
709    char *path;
710    FILE *fp;
711 +  time_t atime;
712    time_t mtime;
713    off_t size;
714    off_t vsize;
715 @@ -914,6 +916,7 @@
716    unsigned int quiet : 1;      /* inhibit status messages? */
717    unsigned int collapsed : 1;   /* are all threads collapsed? */
718    unsigned int closing : 1;    /* mailbox is being closed */
719 +  unsigned int peekonly : 1;   /* just taking a glance, revert atime */
720  
721    /* driver hooks */
722    void *data;                  /* driver specific data */
723 --- a/mutt_curses.h
724 +++ b/mutt_curses.h
725 @@ -64,6 +64,7 @@
726  #undef lines
727  #endif /* lines */
728  
729 +#define CLEARLINE_WIN(x) move(x,SidebarWidth), clrtoeol()
730  #define CLEARLINE(x) move(x,0), clrtoeol()
731  #define CENTERLINE(x,y) move(y, (COLS-strlen(x))/2), addstr(x)
732  #define BEEP() do { if (option (OPTBEEP)) beep(); } while (0)
733 @@ -126,6 +127,8 @@
734    MT_COLOR_BOLD,
735    MT_COLOR_UNDERLINE,
736    MT_COLOR_INDEX,
737 +  MT_COLOR_NEW,
738 +  MT_COLOR_FLAGGED,
739    MT_COLOR_MAX
740  };
741  
742 --- a/muttlib.c
743 +++ b/muttlib.c
744 @@ -1286,6 +1286,8 @@
745           pl = pw = 1;
746  
747         /* see if there's room to add content, else ignore */
748 +        if ( DrawFullLine )
749 +        {
750         if ((col < COLS && wlen < destlen) || soft)
751         {
752           int pad;
753 @@ -1329,6 +1331,52 @@
754           col += wid;
755           src += pl;
756         }
757 +        }
758 +        else
759 +        {
760 +       if ((col < COLS-SidebarWidth && wlen < destlen) || soft)
761 +        {
762 +         int pad;
763 +
764 +         /* get contents after padding */
765 +         mutt_FormatString (buf, sizeof (buf), 0, src + pl, callback, data, flags);
766 +         len = mutt_strlen (buf);
767 +         wid = mutt_strwidth (buf);
768 +
769 +         /* try to consume as many columns as we can, if we don't have
770 +          * memory for that, use as much memory as possible */
771 +         pad = (COLS - SidebarWidth - col - wid) / pw;
772 +         if (pad > 0 && wlen + (pad * pl) + len > destlen)
773 +           pad = ((signed)(destlen - wlen - len)) / pl;
774 +         if (pad > 0)
775 +         {
776 +           while (pad--)
777 +           {
778 +             memcpy (wptr, src, pl);
779 +             wptr += pl;
780 +             wlen += pl;
781 +             col += pw;
782 +           }
783 +         }
784 +         else if (soft && pad < 0)
785 +         {
786 +           /* \0-terminate dest for length computation in mutt_wstr_trunc() */
787 +           *wptr = 0;
788 +           /* make sure right part is at most as wide as display */
789 +           len = mutt_wstr_trunc (buf, destlen, COLS, &wid);
790 +           /* truncate left so that right part fits completely in */
791 +           wlen = mutt_wstr_trunc (dest, destlen - len, col + pad, &col);
792 +           wptr = dest + wlen;
793 +         }
794 +         if (len + wlen > destlen)
795 +           len = mutt_wstr_trunc (buf, destlen - wlen, COLS - SidebarWidth - col, NULL);
796 +         memcpy (wptr, buf, len);
797 +         wptr += len;
798 +         wlen += len;
799 +         col += wid;
800 +         src += pl;
801 +       }
802 +        }
803         break; /* skip rest of input */
804        }
805        else if (ch == '|')
806 --- a/mx.c
807 +++ b/mx.c
808 @@ -595,6 +595,7 @@
809   *             M_APPEND        open mailbox for appending
810   *             M_READONLY      open mailbox in read-only mode
811   *             M_QUIET         only print error messages
812 + *             M_PEEK          revert atime where applicable
813   *     ctx     if non-null, context struct to use
814   */
815  CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
816 @@ -617,6 +618,8 @@
817      ctx->quiet = 1;
818    if (flags & M_READONLY)
819      ctx->readonly = 1;
820 +  if (flags & M_PEEK)
821 +    ctx->peekonly = 1;
822  
823    if (flags & (M_APPEND|M_NEWFOLDER))
824    {
825 @@ -721,9 +724,21 @@
826  void mx_fastclose_mailbox (CONTEXT *ctx)
827  {
828    int i;
829 +#ifndef BUFFY_SIZE
830 +  struct utimbuf ut;
831 +#endif
832  
833    if(!ctx) 
834      return;
835 +#ifndef BUFFY_SIZE
836 +  /* fix up the times so buffy won't get confused */
837 +  if (ctx->peekonly && ctx->path && ctx->mtime > ctx->atime)
838 +  {
839 +    ut.actime = ctx->atime;
840 +    ut.modtime = ctx->mtime;
841 +    utime (ctx->path, &ut); 
842 +  }
843 +#endif
844  
845    /* never announce that a mailbox we've just left has new mail. #3290
846     * XXX: really belongs in mx_close_mailbox, but this is a nice hook point */
847 --- a/mx.h
848 +++ b/mx.h
849 @@ -61,6 +61,7 @@
850  int mh_sync_mailbox (CONTEXT *, int *);
851  int mh_check_mailbox (CONTEXT *, int *);
852  int mh_buffy (const char *);
853 +void mh_buffy_update (const char *, int *, int *, int *);
854  int mh_check_empty (const char *);
855  
856  int maildir_read_dir (CONTEXT *);
857 --- a/pager.c
858 +++ b/pager.c
859 @@ -29,6 +29,7 @@
860  #include "pager.h"
861  #include "attach.h"
862  #include "mbyte.h"
863 +#include "sidebar.h"
864  
865  #include "mutt_crypt.h"
866  
867 @@ -1095,6 +1096,7 @@
868    wchar_t wc;
869    mbstate_t mbstate;
870    int wrap_cols = mutt_term_width ((flags & M_PAGER_NOWRAP) ? 0 : Wrap);
871 +  wrap_cols -= SidebarWidth;
872  
873    if (check_attachment_marker ((char *)buf) == 0)
874      wrap_cols = COLS;
875 @@ -1745,7 +1747,7 @@
876      if ((redraw & REDRAW_BODY) || topline != oldtopline)
877      {
878        do {
879 -       move (bodyoffset, 0);
880 +       move (bodyoffset, SidebarWidth);
881         curline = oldtopline = topline;
882         lines = 0;
883         force_redraw = 0;
884 @@ -1758,6 +1760,7 @@
885                             &QuoteList, &q_level, &force_redraw, &SearchRE) > 0)
886             lines++;
887           curline++;
888 +         move(lines + bodyoffset, SidebarWidth);
889         }
890         last_offset = lineInfo[curline].offset;
891        } while (force_redraw);
892 @@ -1771,6 +1774,7 @@
893           addch ('~');
894         addch ('\n');
895         lines++;
896 +       move(lines + bodyoffset, SidebarWidth);
897        }
898        /* We are going to update the pager status bar, so it isn't
899         * necessary to reset to normal color now. */
900 @@ -1794,21 +1798,21 @@
901        /* print out the pager status bar */
902        SETCOLOR (MT_COLOR_STATUS);
903        BKGDSET (MT_COLOR_STATUS);
904 -      CLEARLINE (statusoffset);
905 +      CLEARLINE_WIN (statusoffset);
906  
907        if (IsHeader (extra) || IsMsgAttach (extra))
908        {
909 -       size_t l1 = COLS * MB_LEN_MAX;
910 +       size_t l1 = (COLS-SidebarWidth) * MB_LEN_MAX;
911         size_t l2 = sizeof (buffer);
912         hfi.hdr = (IsHeader (extra)) ? extra->hdr : extra->bdy->hdr;
913         mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
914 -       mutt_paddstr (COLS, buffer);
915 +       mutt_paddstr (COLS-SidebarWidth, buffer);
916        }
917        else
918        {
919         char bn[STRING];
920         snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
921 -       mutt_paddstr (COLS, bn);
922 +       mutt_paddstr (COLS-SidebarWidth, bn);
923        }
924        BKGDSET (MT_COLOR_NORMAL);
925        SETCOLOR (MT_COLOR_NORMAL);
926 @@ -1826,18 +1830,23 @@
927        /* redraw the pager_index indicator, because the
928         * flags for this message might have changed. */
929        menu_redraw_current (index);
930 +      draw_sidebar(MENU_PAGER);
931  
932        /* print out the index status bar */
933        menu_status_line (buffer, sizeof (buffer), index, NONULL(Status));
934   
935 -      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), 0);
936 +      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), SidebarWidth);
937        SETCOLOR (MT_COLOR_STATUS);
938        BKGDSET (MT_COLOR_STATUS);
939 -      mutt_paddstr (COLS, buffer);
940 +      mutt_paddstr (COLS-SidebarWidth, buffer);
941        SETCOLOR (MT_COLOR_NORMAL);
942        BKGDSET (MT_COLOR_NORMAL);
943      }
944  
945 +    /* if we're not using the index, update every time */
946 +    if ( index == 0 )
947 +      draw_sidebar(MENU_PAGER);
948 +
949      redraw = 0;
950  
951      if (option(OPTBRAILLEFRIENDLY)) {
952 @@ -2769,6 +2778,13 @@
953         mutt_what_key ();
954         break;
955  
956 +      case OP_SIDEBAR_SCROLL_UP:
957 +      case OP_SIDEBAR_SCROLL_DOWN:
958 +      case OP_SIDEBAR_NEXT:
959 +      case OP_SIDEBAR_PREV:
960 +       scroll_sidebar(ch, MENU_PAGER);
961 +       break;
962 +
963        default:
964         ch = -1;
965         break;
966 --- /dev/null
967 +++ b/sidebar.c
968 @@ -0,0 +1,336 @@
969 +/*
970 + * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
971 + * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
972 + * 
973 + *     This program is free software; you can redistribute it and/or modify
974 + *     it under the terms of the GNU General Public License as published by
975 + *     the Free Software Foundation; either version 2 of the License, or
976 + *     (at your option) any later version.
977 + * 
978 + *     This program is distributed in the hope that it will be useful,
979 + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
980 + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
981 + *     GNU General Public License for more details.
982 + * 
983 + *     You should have received a copy of the GNU General Public License
984 + *     along with this program; if not, write to the Free Software
985 + *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
986 + */ 
987 +
988 +
989 +#if HAVE_CONFIG_H
990 +# include "config.h"
991 +#endif
992 +
993 +#include "mutt.h"
994 +#include "mutt_menu.h"
995 +#include "mutt_curses.h"
996 +#include "sidebar.h"
997 +#include "buffy.h"
998 +#include <libgen.h>
999 +#include "keymap.h"
1000 +#include <stdbool.h>
1001 +
1002 +/*BUFFY *CurBuffy = 0;*/
1003 +static BUFFY *TopBuffy = 0;
1004 +static BUFFY *BottomBuffy = 0;
1005 +static int known_lines = 0;
1006 +
1007 +static int quick_log10(int n)
1008 +{
1009 +        char string[32];
1010 +        sprintf(string, "%d", n);
1011 +        return strlen(string);
1012 +}
1013 +
1014 +void calc_boundaries (int menu)
1015 +{
1016 +       BUFFY *tmp = Incoming;
1017 +
1018 +       if ( known_lines != LINES ) {
1019 +               TopBuffy = BottomBuffy = 0;
1020 +               known_lines = LINES;
1021 +       }
1022 +       for ( ; tmp->next != 0; tmp = tmp->next )
1023 +               tmp->next->prev = tmp;
1024 +
1025 +       if ( TopBuffy == 0 && BottomBuffy == 0 )
1026 +               TopBuffy = Incoming;
1027 +       if ( BottomBuffy == 0 ) {
1028 +               int count = LINES - 2 - (menu != MENU_PAGER || option(OPTSTATUSONTOP));
1029 +               BottomBuffy = TopBuffy;
1030 +               while ( --count && BottomBuffy->next )
1031 +                       BottomBuffy = BottomBuffy->next;
1032 +       }
1033 +       else if ( TopBuffy == CurBuffy->next ) {
1034 +               int count = LINES - 2 - (menu != MENU_PAGER);
1035 +               BottomBuffy = CurBuffy;
1036 +               tmp = BottomBuffy;
1037 +               while ( --count && tmp->prev)
1038 +                       tmp = tmp->prev;
1039 +               TopBuffy = tmp;
1040 +       }
1041 +       else if ( BottomBuffy == CurBuffy->prev ) {
1042 +               int count = LINES - 2 - (menu != MENU_PAGER);
1043 +               TopBuffy = CurBuffy;
1044 +               tmp = TopBuffy;
1045 +               while ( --count && tmp->next )
1046 +                       tmp = tmp->next;
1047 +               BottomBuffy = tmp;
1048 +       }
1049 +}
1050 +
1051 +char *make_sidebar_entry(char *box, int size, int new, int flagged)
1052 +{
1053 +       static char *entry = 0;
1054 +       char *c;
1055 +       int i = 0;
1056 +       int delim_len = strlen(SidebarDelim);
1057 +
1058 +       c = realloc(entry, SidebarWidth - delim_len + 2);
1059 +       if ( c ) entry = c;
1060 +       entry[SidebarWidth - delim_len + 1] = 0;
1061 +       for (; i < SidebarWidth - delim_len + 1; entry[i++] = ' ' );
1062 +       i = strlen(box);
1063 +       strncpy( entry, box, i < (SidebarWidth - delim_len + 1) ? i : (SidebarWidth - delim_len + 1) );
1064 +
1065 +        if (size == -1)
1066 +                sprintf(entry + SidebarWidth - delim_len - 3, "?");
1067 +        else if ( new ) {
1068 +          if (flagged > 0) {
1069 +              sprintf(
1070 +                       entry + SidebarWidth - delim_len - 5 - quick_log10(size) - quick_log10(new) - quick_log10(flagged),
1071 +                       "% d(%d)[%d]", size, new, flagged);
1072 +          } else {
1073 +              sprintf(
1074 +                      entry + SidebarWidth - delim_len - 3 - quick_log10(size) - quick_log10(new),
1075 +                      "% d(%d)", size, new);
1076 +          }
1077 +        } else if (flagged > 0) {
1078 +              sprintf( entry + SidebarWidth - delim_len - 3 - quick_log10(size) - quick_log10(flagged), "% d[%d]", size, flagged);
1079 +        } else {
1080 +              sprintf( entry + SidebarWidth - delim_len - 1 - quick_log10(size), "% d", size);
1081 +        }
1082 +       return entry;
1083 +}
1084 +
1085 +void set_curbuffy(char buf[LONG_STRING])
1086 +{
1087 +  BUFFY* tmp = CurBuffy = Incoming;
1088 +
1089 +  if (!Incoming)
1090 +    return;
1091 +
1092 +  while(1) {
1093 +    if(!strcmp(tmp->path, buf)) {
1094 +      CurBuffy = tmp;
1095 +      break;
1096 +    }
1097 +
1098 +    if(tmp->next)
1099 +      tmp = tmp->next;
1100 +    else
1101 +      break;
1102 +  }
1103 +}
1104 +
1105 +int draw_sidebar(int menu) {
1106 +
1107 +       int lines = option(OPTHELP) ? 1 : 0;
1108 +    lines += option(OPTSTATUSONTOP) ? 1 : 0;
1109 +
1110 +       BUFFY *tmp;
1111 +#ifndef USE_SLANG_CURSES
1112 +        attr_t attrs;
1113 +#endif
1114 +        short delim_len = strlen(SidebarDelim);
1115 +        short color_pair;
1116 +
1117 +        static bool initialized = false;
1118 +        static int prev_show_value;
1119 +        static short saveSidebarWidth;
1120 +
1121 +        /* initialize first time */
1122 +        if(!initialized) {
1123 +                prev_show_value = option(OPTSIDEBAR);
1124 +                saveSidebarWidth = SidebarWidth;
1125 +                if(!option(OPTSIDEBAR)) SidebarWidth = 0;
1126 +                initialized = true;
1127 +        }
1128 +
1129 +        /* save or restore the value SidebarWidth */
1130 +        if(prev_show_value != option(OPTSIDEBAR)) {
1131 +                if(prev_show_value && !option(OPTSIDEBAR)) {
1132 +                        saveSidebarWidth = SidebarWidth;
1133 +                        SidebarWidth = 0;
1134 +                } else if(!prev_show_value && option(OPTSIDEBAR)) {
1135 +                        SidebarWidth = saveSidebarWidth;
1136 +                }
1137 +                prev_show_value = option(OPTSIDEBAR);
1138 +        }
1139 +
1140 +
1141 +//     if ( SidebarWidth == 0 ) return 0;
1142 +       if (SidebarWidth > 0 && option (OPTSIDEBAR)
1143 +           && delim_len >= SidebarWidth) {
1144 +         unset_option (OPTSIDEBAR);
1145 +         /* saveSidebarWidth = SidebarWidth; */
1146 +         if (saveSidebarWidth > delim_len) {
1147 +           SidebarWidth = saveSidebarWidth;
1148 +           mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
1149 +           sleep (2);
1150 +         } else {
1151 +           SidebarWidth = 0;
1152 +           mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar. Please set your sidebar_width to a sane value."));
1153 +           sleep (4); /* the advise to set a sane value should be seen long enough */
1154 +         }
1155 +         saveSidebarWidth = 0;
1156 +         return (0);
1157 +       }
1158 +
1159 +    if ( SidebarWidth == 0 || !option(OPTSIDEBAR)) {
1160 +      if (SidebarWidth > 0) {
1161 +        saveSidebarWidth = SidebarWidth;
1162 +        SidebarWidth = 0;
1163 +      }
1164 +      unset_option(OPTSIDEBAR);
1165 +      return 0;
1166 +    }
1167 +
1168 +        /* get attributes for divider */
1169 +       SETCOLOR(MT_COLOR_STATUS);
1170 +#ifndef USE_SLANG_CURSES
1171 +        attr_get(&attrs, &color_pair, 0);
1172 +#else
1173 +        color_pair = attr_get();
1174 +#endif
1175 +       SETCOLOR(MT_COLOR_NORMAL);
1176 +
1177 +       /* draw the divider */
1178 +
1179 +       for ( ; lines < LINES-1-(menu != MENU_PAGER || option(OPTSTATUSONTOP)); lines++ ) {
1180 +               move(lines, SidebarWidth - delim_len);
1181 +               addstr(NONULL(SidebarDelim));
1182 +#ifndef USE_SLANG_CURSES
1183 +                mvchgat(lines, SidebarWidth - delim_len, delim_len, 0, color_pair, NULL);
1184 +#endif
1185 +       }
1186 +
1187 +       if ( Incoming == 0 ) return 0;
1188 +       lines = option(OPTHELP) ? 1 : 0; /* go back to the top */
1189 +    lines += option(OPTSTATUSONTOP) ? 1 : 0;
1190 +
1191 +       if ( known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0 ) 
1192 +               calc_boundaries(menu);
1193 +       if ( CurBuffy == 0 ) CurBuffy = Incoming;
1194 +
1195 +       tmp = TopBuffy;
1196 +
1197 +       SETCOLOR(MT_COLOR_NORMAL);
1198 +
1199 +       for ( ; tmp && lines < LINES-1 - (menu != MENU_PAGER || option(OPTSTATUSONTOP)); tmp = tmp->next ) {
1200 +               if ( tmp == CurBuffy )
1201 +                       SETCOLOR(MT_COLOR_INDICATOR);
1202 +               else if ( tmp->msg_unread > 0 )
1203 +                       SETCOLOR(MT_COLOR_NEW);
1204 +               else if ( tmp->msg_flagged > 0 )
1205 +                       SETCOLOR(MT_COLOR_FLAGGED);
1206 +               else
1207 +                       SETCOLOR(MT_COLOR_NORMAL);
1208 +
1209 +               move( lines, 0 );
1210 +               if ( Context && !strcmp( tmp->path, Context->path ) ) {
1211 +                       tmp->msg_unread = Context->unread;
1212 +                       tmp->msgcount = Context->msgcount;
1213 +                       tmp->msg_flagged = Context->flagged;
1214 +               }
1215 +               // check whether Maildir is a prefix of the current folder's path
1216 +               short maildir_is_prefix = 0;
1217 +               if ( (strlen(tmp->path) > strlen(Maildir)) &&
1218 +                       (strncmp(Maildir, tmp->path, strlen(Maildir)) == 0) )
1219 +                       maildir_is_prefix = 1;
1220 +               // calculate depth of current folder and generate its display name with indented spaces
1221 +               int sidebar_folder_depth = 0;
1222 +               char *sidebar_folder_name;
1223 +               sidebar_folder_name = basename(tmp->path);
1224 +               if ( maildir_is_prefix ) {
1225 +                       char *tmp_folder_name;
1226 +                       int i;
1227 +                       tmp_folder_name = tmp->path + strlen(Maildir);
1228 +                       for (i = 0; i < strlen(tmp->path) - strlen(Maildir); i++) {
1229 +                               if (tmp_folder_name[i] == '/') sidebar_folder_depth++;
1230 +                       }   
1231 +                       if (sidebar_folder_depth > 0) {
1232 +                               sidebar_folder_name = malloc(strlen(basename(tmp->path)) + sidebar_folder_depth + 1);
1233 +                               for (i=0; i < sidebar_folder_depth; i++)
1234 +                                       sidebar_folder_name[i]=' ';
1235 +                               sidebar_folder_name[i]=0;
1236 +                               strncat(sidebar_folder_name, basename(tmp->path), strlen(basename(tmp->path)) + sidebar_folder_depth);
1237 +                       }
1238 +               }
1239 +               printw( "%.*s", SidebarWidth - delim_len + 1,
1240 +                       make_sidebar_entry(sidebar_folder_name, tmp->msgcount,
1241 +                       tmp->msg_unread, tmp->msg_flagged));
1242 +               if (sidebar_folder_depth > 0)
1243 +                       free(sidebar_folder_name);
1244 +               lines++;
1245 +       }
1246 +       SETCOLOR(MT_COLOR_NORMAL);
1247 +       for ( ; lines < LINES-1 - (menu != MENU_PAGER || option(OPTSTATUSONTOP)); lines++ ) {
1248 +               int i = 0;
1249 +               move( lines, 0 );
1250 +               for ( ; i < SidebarWidth - delim_len; i++ )
1251 +                       addch(' ');
1252 +       }
1253 +       return 0;
1254 +}
1255 +
1256 +
1257 +void set_buffystats(CONTEXT* Context)
1258 +{
1259 +        BUFFY *tmp = Incoming;
1260 +        while(tmp) {
1261 +                if(Context && !strcmp(tmp->path, Context->path)) {
1262 +                       tmp->msg_unread = Context->unread;
1263 +                       tmp->msgcount = Context->msgcount;
1264 +                        break;
1265 +                }
1266 +                tmp = tmp->next;
1267 +        }
1268 +}
1269 +
1270 +void scroll_sidebar(int op, int menu)
1271 +{
1272 +        if(!SidebarWidth) return;
1273 +        if(!CurBuffy) return;
1274 +
1275 +       switch (op) {
1276 +               case OP_SIDEBAR_NEXT:
1277 +                       if ( CurBuffy->next == NULL ) return;
1278 +                       CurBuffy = CurBuffy->next;
1279 +                       break;
1280 +               case OP_SIDEBAR_PREV:
1281 +                       if ( CurBuffy->prev == NULL ) return;
1282 +                       CurBuffy = CurBuffy->prev;
1283 +                       break;
1284 +               case OP_SIDEBAR_SCROLL_UP:
1285 +                       CurBuffy = TopBuffy;
1286 +                       if ( CurBuffy != Incoming ) {
1287 +                               calc_boundaries(menu);
1288 +                               CurBuffy = CurBuffy->prev;
1289 +                       }
1290 +                       break;
1291 +               case OP_SIDEBAR_SCROLL_DOWN:
1292 +                       CurBuffy = BottomBuffy;
1293 +                       if ( CurBuffy->next ) {
1294 +                               calc_boundaries(menu);
1295 +                               CurBuffy = CurBuffy->next;
1296 +                       }
1297 +                       break;
1298 +               default:
1299 +                       return;
1300 +       }
1301 +       calc_boundaries(menu);
1302 +       draw_sidebar(menu);
1303 +}
1304 +
1305 --- /dev/null
1306 +++ b/sidebar.h
1307 @@ -0,0 +1,36 @@
1308 +/*
1309 + * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
1310 + * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
1311 + * 
1312 + *     This program is free software; you can redistribute it and/or modify
1313 + *     it under the terms of the GNU General Public License as published by
1314 + *     the Free Software Foundation; either version 2 of the License, or
1315 + *     (at your option) any later version.
1316 + * 
1317 + *     This program is distributed in the hope that it will be useful,
1318 + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
1319 + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1320 + *     GNU General Public License for more details.
1321 + * 
1322 + *     You should have received a copy of the GNU General Public License
1323 + *     along with this program; if not, write to the Free Software
1324 + *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
1325 + */ 
1326 +
1327 +#ifndef SIDEBAR_H
1328 +#define SIDEBAR_H
1329 +
1330 +struct MBOX_LIST {
1331 +       char *path;
1332 +       int msgcount;
1333 +       int new;
1334 +} MBLIST;
1335 +
1336 +/* parameter is whether or not to go to the status line */
1337 +/* used for omitting the last | that covers up the status bar in the index */
1338 +int draw_sidebar(int);
1339 +void scroll_sidebar(int, int);
1340 +void set_curbuffy(char*);
1341 +void set_buffystats(CONTEXT*);
1342 +
1343 +#endif /* SIDEBAR_H */