changeset: 6744:27b77b5c97cf
user:      Kevin McCarthy <[email protected]>
date:      Sat Jul 30 11:11:07 2016 -0700
link:      http://dev.mutt.org/hg/mutt/rev/27b77b5c97cf

Add unread and total message count format strings to $folder_format.

%n will show the unread message count in the mailbox.  %m will show
total message count.  Except for %n with IMAP, these both require
$mail_check_stats to be set, which puts these counts inside BUFFY.

Since the imap_mboxcache is never fresher than the value in BUFFY,
remove the special imap_mailbox_state() call.  Instead, just update
from the current Context for all mailboxes.

Remove the logic that overrode the %N format string to show unread
count for IMAP mailboxes.  If they want to see unread count, they will
have to change the $folder_format.

Although it doesn't look possible to reuse browser_state.entry slots,
change the OP_DELETE_MAILBOX to memset(0) the deleted slot.  Then, we
can change to logic in add_folder() so it doesn't need to zero-out
unset values.

diffs (326 lines):

diff -r 4f4c258ab95c -r 27b77b5c97cf browser.c
--- a/browser.c Mon Jul 25 12:25:23 2016 -0700
+++ b/browser.c Sat Jul 30 11:11:07 2016 -0700
@@ -259,25 +259,42 @@
       else
        mutt_format_s (dest, destlen, fmt, "");
       break;
-      
+
+    case 'm':
+      if (!optional)
+      {
+        if (folder->ff->has_buffy)
+        {
+          snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
+          snprintf (dest, destlen, tmp, folder->ff->msg_count);
+        }
+        else
+          mutt_format_s (dest, destlen, fmt, "");
+      }
+      else if (!folder->ff->msg_count)
+        optional = 0;
+      break;
+
     case 'N':
-#ifdef USE_IMAP
-      if (mx_is_imap (folder->ff->desc))
-      {
-       if (!optional)
-       {
-         snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
-         snprintf (dest, destlen, tmp, folder->ff->new);
-       }
-       else if (!folder->ff->new)
-         optional = 0;
-       break;
-      }
-#endif
       snprintf (tmp, sizeof (tmp), "%%%sc", fmt);
       snprintf (dest, destlen, tmp, folder->ff->new ? 'N' : ' ');
       break;
-      
+
+    case 'n':
+      if (!optional)
+      {
+        if (folder->ff->has_buffy)
+        {
+          snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
+          snprintf (dest, destlen, tmp, folder->ff->msg_unread);
+        }
+        else
+          mutt_format_s (dest, destlen, fmt, "");
+      }
+      else if (!folder->ff->msg_unread)
+        optional = 0;
+      break;
+
     case 's':
       if (folder->ff->local)
       {
@@ -324,7 +341,7 @@
 }
 
 static void add_folder (MUTTMENU *m, struct browser_state *state,
-                       const char *name, const struct stat *s, unsigned int 
new)
+                       const char *name, const struct stat *s, BUFFY *b)
 {
   if (state->entrylen == state->entrymax)
   {
@@ -348,10 +365,15 @@
     
     (state->entry)[state->entrylen].local = 1;
   }
-  else
-    (state->entry)[state->entrylen].local = 0;
 
-  (state->entry)[state->entrylen].new = new;
+  if (b)
+  {
+    (state->entry)[state->entrylen].has_buffy = 1;
+    (state->entry)[state->entrylen].new = b->new;
+    (state->entry)[state->entrylen].msg_count = b->msg_count;
+    (state->entry)[state->entrylen].msg_unread = b->msg_unread;
+  }
+
   (state->entry)[state->entrylen].name = safe_strdup (name);
   (state->entry)[state->entrylen].desc = safe_strdup (name);
 #ifdef USE_IMAP
@@ -435,7 +457,13 @@
     tmp = Incoming;
     while (tmp && mutt_strcmp (buffer, tmp->path))
       tmp = tmp->next;
-    add_folder (menu, state, de->d_name, &s, (tmp) ? tmp->new : 0);
+    if (tmp && Context &&
+        !mutt_strcmp (tmp->realpath, Context->realpath))
+    {
+      tmp->msg_count = Context->msgcount;
+      tmp->msg_unread = Context->unread;
+    }
+    add_folder (menu, state, de->d_name, &s, tmp);
   }
   closedir (dp);  
   browser_sort (state);
@@ -447,9 +475,6 @@
   struct stat s;
   char buffer[LONG_STRING];
   BUFFY *tmp = Incoming;
-#ifdef USE_IMAP
-  struct mailbox_state mbox;
-#endif
 
   if (!Incoming)
     return (-1);
@@ -459,18 +484,24 @@
 
   do
   {
+    if (Context &&
+        !mutt_strcmp (tmp->realpath, Context->realpath))
+    {
+      tmp->msg_count = Context->msgcount;
+      tmp->msg_unread = Context->unread;
+    }
+
 #ifdef USE_IMAP
     if (mx_is_imap (tmp->path))
     {
-      imap_mailbox_state (tmp->path, &mbox);
-      add_folder (menu, state, tmp->path, NULL, mbox.new);
+      add_folder (menu, state, tmp->path, NULL, tmp);
       continue;
     }
 #endif
 #ifdef USE_POP
     if (mx_is_pop (tmp->path))
     {
-      add_folder (menu, state, tmp->path, NULL, tmp->new);
+      add_folder (menu, state, tmp->path, NULL, tmp);
       continue;
     }
 #endif
@@ -495,11 +526,11 @@
       if (st2.st_mtime > s.st_mtime)
        s.st_mtime = st2.st_mtime;
     }
-    
+
     strfcpy (buffer, NONULL(tmp->path), sizeof (buffer));
     mutt_pretty_mailbox (buffer, sizeof (buffer));
 
-    add_folder (menu, state, buffer, &s, tmp->new);
+    add_folder (menu, state, buffer, &s, tmp);
   }
   while ((tmp = tmp->next));
   browser_sort (state);
@@ -978,6 +1009,8 @@
              if (nentry+1 < state.entrylen)
                memmove (state.entry + nentry, state.entry + nentry + 1,
                   sizeof (struct folder_file) * (state.entrylen - (nentry+1)));
+              memset (&state.entry[state.entrylen - 1], 0,
+                      sizeof (struct folder_file));
              state.entrylen--;
              mutt_message _("Mailbox deleted.");
              init_menu (&state, menu, title, sizeof (title), buffy);
diff -r 4f4c258ab95c -r 27b77b5c97cf browser.h
--- a/browser.h Mon Jul 25 12:25:23 2016 -0700
+++ b/browser.h Sat Jul 30 11:11:07 2016 -0700
@@ -31,14 +31,18 @@
   char *name;
   char *desc;
 
-  unsigned int new;
+  short new;               /* true if mailbox has "new mail" */
+  int msg_count;           /* total number of messages */
+  int msg_unread;          /* number of unread messages */
+
 #ifdef USE_IMAP
   char delim;
-  
+
   unsigned imap : 1;
   unsigned selectable : 1;
   unsigned inferiors : 1;
 #endif
+  unsigned has_buffy : 1;
   unsigned local : 1; /* folder is on local filesystem */
   unsigned tagged : 1;
 };
@@ -56,11 +60,4 @@
   unsigned unmarked : 1;
 #endif
 };
-
-struct mailbox_state
-{
-  unsigned int new;
-  unsigned int old;
-  unsigned int messages;
-};
 #endif /* _BROWSER_H */
diff -r 4f4c258ab95c -r 27b77b5c97cf imap/browse.c
--- a/imap/browse.c     Mon Jul 25 12:25:23 2016 -0700
+++ b/imap/browse.c     Sat Jul 30 11:11:07 2016 -0700
@@ -27,6 +27,7 @@
 #include <ctype.h>
 
 #include "mutt.h"
+#include "buffy.h"
 #include "imap_private.h"
 
 /* -- forward declarations -- */
@@ -208,42 +209,6 @@
   return -1;
 }
 
-int imap_mailbox_state (const char* path, struct mailbox_state* state)
-{
-  IMAP_DATA* idata;
-  IMAP_MBOX mx;
-  IMAP_STATUS* status;
-
-  memset (state, 0, sizeof (*state));
-  if (imap_parse_path (path, &mx) < 0)
-  {
-    dprint (1, (debugfile, "imap_mailbox_state: bad path %s\n", path));
-    return -1;
-  }
-  if (!(idata = imap_conn_find (&mx.account, MUTT_IMAP_CONN_NONEW)))
-  {
-    dprint (2, (debugfile, "imap_mailbox_state: no open connection for %s\n",
-               path));
-    FREE (&mx.mbox);
-    return -1;
-  }
-
-  if (idata->ctx && !imap_mxcmp(mx.mbox, idata->mailbox))
-  {
-    state->new = idata->ctx->new;
-    state->messages = idata->ctx->msgcount;
-  }
-  else if ((status = imap_mboxcache_get (idata, mx.mbox, 0)))
-  {
-    state->new = status->unseen;
-    state->messages = status->messages;
-  }
-
-  FREE (&mx.mbox);
-
-  return 0;
-}
-
 /* imap_mailbox_create: Prompt for a new mailbox name, and try to create it */
 int imap_mailbox_create (const char* folder)
 {
@@ -409,6 +374,7 @@
   char tmp[LONG_STRING];
   char relpath[LONG_STRING];
   IMAP_MBOX mx;
+  BUFFY *b;
 
   if (imap_parse_path (state->folder, &mx))
     return;
@@ -458,6 +424,24 @@
   (state->entry)[state->entrylen].delim = delim;
   (state->entry)[state->entrylen].selectable = !noselect;
   (state->entry)[state->entrylen].inferiors = !noinferiors;
+
+  b = Incoming;
+  while (b && mutt_strcmp (tmp, b->path))
+    b = b->next;
+  if (b)
+  {
+    if (Context &&
+        !mutt_strcmp (b->realpath, Context->realpath))
+    {
+      b->msg_count = Context->msgcount;
+      b->msg_unread = Context->unread;
+    }
+    (state->entry)[state->entrylen].has_buffy = 1;
+    (state->entry)[state->entrylen].new = b->new;
+    (state->entry)[state->entrylen].msg_count = b->msg_count;
+    (state->entry)[state->entrylen].msg_unread = b->msg_unread;
+  }
+
   (state->entrylen)++;
 
   FREE (&mx.mbox);
diff -r 4f4c258ab95c -r 27b77b5c97cf imap/imap.h
--- a/imap/imap.h       Mon Jul 25 12:25:23 2016 -0700
+++ b/imap/imap.h       Sat Jul 30 11:11:07 2016 -0700
@@ -52,7 +52,6 @@
 
 /* browse.c */
 int imap_browse (char* path, struct browser_state* state);
-int imap_mailbox_state (const char* path, struct mailbox_state* state);
 int imap_mailbox_create (const char* folder);
 int imap_mailbox_rename (const char* mailbox);
 
diff -r 4f4c258ab95c -r 27b77b5c97cf init.h
--- a/init.h    Mon Jul 25 12:25:23 2016 -0700
+++ b/init.h    Sat Jul 30 11:11:07 2016 -0700
@@ -812,7 +812,9 @@
   ** .dt %F  .dd file permissions
   ** .dt %g  .dd group name (or numeric gid, if missing)
   ** .dt %l  .dd number of hard links
-  ** .dt %N  .dd N if folder has new mail, blank otherwise
+  ** .dt %m  .dd number of messages in the mailbox *
+  ** .dt %n  .dd number of unread messages in the mailbox *
+  ** .dt %N  .dd N if mailbox has new mail, blank otherwise
   ** .dt %s  .dd size in bytes
   ** .dt %t  .dd ``*'' if the file is tagged, blank otherwise
   ** .dt %u  .dd owner name (or numeric uid, if missing)
@@ -822,6 +824,12 @@
   ** .de
   ** .pp
   ** For an explanation of ``soft-fill'', see the $$index_format documentation.
+  ** .pp
+  ** * = can be optionally printed if nonzero
+  ** .pp
+  ** %m, %n, and %N only work for monitored mailboxes.
+  ** %m requires $$mail_check_stats to be set.
+  ** %n requires $$mail_check_stats to be set (except for IMAP mailboxes).
   */
   { "followup_to",     DT_BOOL, R_NONE, OPTFOLLOWUPTO, 1 },
   /*

Reply via email to