From: Kevin McCarthy Date: Sat, 30 Jul 2016 18:11:07 +0000 (-0700) Subject: Add unread and total message count format strings to $folder_format. X-Git-Tag: neomutt-20160822~67 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=422c9919005574d035b29c664e5e631a3a06c041;p=neomutt 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. --- diff --git a/browser.c b/browser.c index a491e2e9c..15eccc553 100644 --- a/browser.c +++ b/browser.c @@ -259,25 +259,42 @@ folder_format_str (char *dest, size_t destlen, size_t col, int cols, char op, co else mutt_format_s (dest, destlen, fmt, ""); break; - - case 'N': -#ifdef USE_IMAP - if (mx_is_imap (folder->ff->desc)) + + case 'm': + if (!optional) { - if (!optional) - { - snprintf (tmp, sizeof (tmp), "%%%sd", fmt); - snprintf (dest, destlen, tmp, folder->ff->new); - } - else if (!folder->ff->new) - optional = 0; - break; + 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, ""); } -#endif + else if (!folder->ff->msg_count) + optional = 0; + break; + + case 'N': 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 @@ folder_format_str (char *dest, size_t destlen, size_t col, int cols, char op, co } 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 @@ static void add_folder (MUTTMENU *m, struct browser_state *state, (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 @@ static int examine_directory (MUTTMENU *menu, struct browser_state *state, 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 @@ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state) 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 @@ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state) 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 @@ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state) 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 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files, int *num 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 --git a/browser.h b/browser.h index fa8726731..67e62eaee 100644 --- a/browser.h +++ b/browser.h @@ -31,14 +31,18 @@ struct folder_file 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 @@ struct browser_state unsigned unmarked : 1; #endif }; - -struct mailbox_state -{ - unsigned int new; - unsigned int old; - unsigned int messages; -}; #endif /* _BROWSER_H */ diff --git a/imap/browse.c b/imap/browse.c index e9b9b7450..acda9f94a 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -27,6 +27,7 @@ #include #include "mutt.h" +#include "buffy.h" #include "imap_private.h" /* -- forward declarations -- */ @@ -208,42 +209,6 @@ int imap_browse (char* path, struct browser_state* state) 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 @@ static void imap_add_folder (char delim, char *folder, int noselect, 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 @@ static void imap_add_folder (char delim, char *folder, int noselect, (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 --git a/imap/imap.h b/imap/imap.h index 891cc0bf8..442b284ca 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -52,7 +52,6 @@ extern struct mx_ops mx_imap_ops; /* 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 --git a/init.h b/init.h index 02073557e..5de0c191e 100644 --- a/init.h +++ b/init.h @@ -812,7 +812,9 @@ struct option_t MuttVars[] = { ** .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 @@ struct option_t MuttVars[] = { ** .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 }, /*