mutt stable branch with some hacks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+95 -74
+60 -27
browser.c
··· 259 259 else 260 260 mutt_format_s (dest, destlen, fmt, ""); 261 261 break; 262 - 263 - case 'N': 264 - #ifdef USE_IMAP 265 - if (mx_is_imap (folder->ff->desc)) 262 + 263 + case 'm': 264 + if (!optional) 266 265 { 267 - if (!optional) 268 - { 269 - snprintf (tmp, sizeof (tmp), "%%%sd", fmt); 270 - snprintf (dest, destlen, tmp, folder->ff->new); 271 - } 272 - else if (!folder->ff->new) 273 - optional = 0; 274 - break; 266 + if (folder->ff->has_buffy) 267 + { 268 + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); 269 + snprintf (dest, destlen, tmp, folder->ff->msg_count); 270 + } 271 + else 272 + mutt_format_s (dest, destlen, fmt, ""); 275 273 } 276 - #endif 274 + else if (!folder->ff->msg_count) 275 + optional = 0; 276 + break; 277 + 278 + case 'N': 277 279 snprintf (tmp, sizeof (tmp), "%%%sc", fmt); 278 280 snprintf (dest, destlen, tmp, folder->ff->new ? 'N' : ' '); 279 281 break; 280 - 282 + 283 + case 'n': 284 + if (!optional) 285 + { 286 + if (folder->ff->has_buffy) 287 + { 288 + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); 289 + snprintf (dest, destlen, tmp, folder->ff->msg_unread); 290 + } 291 + else 292 + mutt_format_s (dest, destlen, fmt, ""); 293 + } 294 + else if (!folder->ff->msg_unread) 295 + optional = 0; 296 + break; 297 + 281 298 case 's': 282 299 if (folder->ff->local) 283 300 { ··· 324 341 } 325 342 326 343 static void add_folder (MUTTMENU *m, struct browser_state *state, 327 - const char *name, const struct stat *s, unsigned int new) 344 + const char *name, const struct stat *s, BUFFY *b) 328 345 { 329 346 if (state->entrylen == state->entrymax) 330 347 { ··· 348 365 349 366 (state->entry)[state->entrylen].local = 1; 350 367 } 351 - else 352 - (state->entry)[state->entrylen].local = 0; 368 + 369 + if (b) 370 + { 371 + (state->entry)[state->entrylen].has_buffy = 1; 372 + (state->entry)[state->entrylen].new = b->new; 373 + (state->entry)[state->entrylen].msg_count = b->msg_count; 374 + (state->entry)[state->entrylen].msg_unread = b->msg_unread; 375 + } 353 376 354 - (state->entry)[state->entrylen].new = new; 355 377 (state->entry)[state->entrylen].name = safe_strdup (name); 356 378 (state->entry)[state->entrylen].desc = safe_strdup (name); 357 379 #ifdef USE_IMAP ··· 435 457 tmp = Incoming; 436 458 while (tmp && mutt_strcmp (buffer, tmp->path)) 437 459 tmp = tmp->next; 438 - add_folder (menu, state, de->d_name, &s, (tmp) ? tmp->new : 0); 460 + if (tmp && Context && 461 + !mutt_strcmp (tmp->realpath, Context->realpath)) 462 + { 463 + tmp->msg_count = Context->msgcount; 464 + tmp->msg_unread = Context->unread; 465 + } 466 + add_folder (menu, state, de->d_name, &s, tmp); 439 467 } 440 468 closedir (dp); 441 469 browser_sort (state); ··· 447 475 struct stat s; 448 476 char buffer[LONG_STRING]; 449 477 BUFFY *tmp = Incoming; 450 - #ifdef USE_IMAP 451 - struct mailbox_state mbox; 452 - #endif 453 478 454 479 if (!Incoming) 455 480 return (-1); ··· 459 484 460 485 do 461 486 { 487 + if (Context && 488 + !mutt_strcmp (tmp->realpath, Context->realpath)) 489 + { 490 + tmp->msg_count = Context->msgcount; 491 + tmp->msg_unread = Context->unread; 492 + } 493 + 462 494 #ifdef USE_IMAP 463 495 if (mx_is_imap (tmp->path)) 464 496 { 465 - imap_mailbox_state (tmp->path, &mbox); 466 - add_folder (menu, state, tmp->path, NULL, mbox.new); 497 + add_folder (menu, state, tmp->path, NULL, tmp); 467 498 continue; 468 499 } 469 500 #endif 470 501 #ifdef USE_POP 471 502 if (mx_is_pop (tmp->path)) 472 503 { 473 - add_folder (menu, state, tmp->path, NULL, tmp->new); 504 + add_folder (menu, state, tmp->path, NULL, tmp); 474 505 continue; 475 506 } 476 507 #endif ··· 495 526 if (st2.st_mtime > s.st_mtime) 496 527 s.st_mtime = st2.st_mtime; 497 528 } 498 - 529 + 499 530 strfcpy (buffer, NONULL(tmp->path), sizeof (buffer)); 500 531 mutt_pretty_mailbox (buffer, sizeof (buffer)); 501 532 502 - add_folder (menu, state, buffer, &s, tmp->new); 533 + add_folder (menu, state, buffer, &s, tmp); 503 534 } 504 535 while ((tmp = tmp->next)); 505 536 browser_sort (state); ··· 978 1009 if (nentry+1 < state.entrylen) 979 1010 memmove (state.entry + nentry, state.entry + nentry + 1, 980 1011 sizeof (struct folder_file) * (state.entrylen - (nentry+1))); 1012 + memset (&state.entry[state.entrylen - 1], 0, 1013 + sizeof (struct folder_file)); 981 1014 state.entrylen--; 982 1015 mutt_message _("Mailbox deleted."); 983 1016 init_menu (&state, menu, title, sizeof (title), buffy);
+6 -9
browser.h
··· 31 31 char *name; 32 32 char *desc; 33 33 34 - unsigned int new; 34 + short new; /* true if mailbox has "new mail" */ 35 + int msg_count; /* total number of messages */ 36 + int msg_unread; /* number of unread messages */ 37 + 35 38 #ifdef USE_IMAP 36 39 char delim; 37 - 40 + 38 41 unsigned imap : 1; 39 42 unsigned selectable : 1; 40 43 unsigned inferiors : 1; 41 44 #endif 45 + unsigned has_buffy : 1; 42 46 unsigned local : 1; /* folder is on local filesystem */ 43 47 unsigned tagged : 1; 44 48 }; ··· 55 59 unsigned marked : 1; 56 60 unsigned unmarked : 1; 57 61 #endif 58 - }; 59 - 60 - struct mailbox_state 61 - { 62 - unsigned int new; 63 - unsigned int old; 64 - unsigned int messages; 65 62 }; 66 63 #endif /* _BROWSER_H */
+20 -36
imap/browse.c
··· 27 27 #include <ctype.h> 28 28 29 29 #include "mutt.h" 30 + #include "buffy.h" 30 31 #include "imap_private.h" 31 32 32 33 /* -- forward declarations -- */ ··· 208 209 return -1; 209 210 } 210 211 211 - int imap_mailbox_state (const char* path, struct mailbox_state* state) 212 - { 213 - IMAP_DATA* idata; 214 - IMAP_MBOX mx; 215 - IMAP_STATUS* status; 216 - 217 - memset (state, 0, sizeof (*state)); 218 - if (imap_parse_path (path, &mx) < 0) 219 - { 220 - dprint (1, (debugfile, "imap_mailbox_state: bad path %s\n", path)); 221 - return -1; 222 - } 223 - if (!(idata = imap_conn_find (&mx.account, MUTT_IMAP_CONN_NONEW))) 224 - { 225 - dprint (2, (debugfile, "imap_mailbox_state: no open connection for %s\n", 226 - path)); 227 - FREE (&mx.mbox); 228 - return -1; 229 - } 230 - 231 - if (idata->ctx && !imap_mxcmp(mx.mbox, idata->mailbox)) 232 - { 233 - state->new = idata->ctx->new; 234 - state->messages = idata->ctx->msgcount; 235 - } 236 - else if ((status = imap_mboxcache_get (idata, mx.mbox, 0))) 237 - { 238 - state->new = status->unseen; 239 - state->messages = status->messages; 240 - } 241 - 242 - FREE (&mx.mbox); 243 - 244 - return 0; 245 - } 246 - 247 212 /* imap_mailbox_create: Prompt for a new mailbox name, and try to create it */ 248 213 int imap_mailbox_create (const char* folder) 249 214 { ··· 409 374 char tmp[LONG_STRING]; 410 375 char relpath[LONG_STRING]; 411 376 IMAP_MBOX mx; 377 + BUFFY *b; 412 378 413 379 if (imap_parse_path (state->folder, &mx)) 414 380 return; ··· 458 424 (state->entry)[state->entrylen].delim = delim; 459 425 (state->entry)[state->entrylen].selectable = !noselect; 460 426 (state->entry)[state->entrylen].inferiors = !noinferiors; 427 + 428 + b = Incoming; 429 + while (b && mutt_strcmp (tmp, b->path)) 430 + b = b->next; 431 + if (b) 432 + { 433 + if (Context && 434 + !mutt_strcmp (b->realpath, Context->realpath)) 435 + { 436 + b->msg_count = Context->msgcount; 437 + b->msg_unread = Context->unread; 438 + } 439 + (state->entry)[state->entrylen].has_buffy = 1; 440 + (state->entry)[state->entrylen].new = b->new; 441 + (state->entry)[state->entrylen].msg_count = b->msg_count; 442 + (state->entry)[state->entrylen].msg_unread = b->msg_unread; 443 + } 444 + 461 445 (state->entrylen)++; 462 446 463 447 FREE (&mx.mbox);
-1
imap/imap.h
··· 52 52 53 53 /* browse.c */ 54 54 int imap_browse (char* path, struct browser_state* state); 55 - int imap_mailbox_state (const char* path, struct mailbox_state* state); 56 55 int imap_mailbox_create (const char* folder); 57 56 int imap_mailbox_rename (const char* mailbox); 58 57
+9 -1
init.h
··· 812 812 ** .dt %F .dd file permissions 813 813 ** .dt %g .dd group name (or numeric gid, if missing) 814 814 ** .dt %l .dd number of hard links 815 - ** .dt %N .dd N if folder has new mail, blank otherwise 815 + ** .dt %m .dd number of messages in the mailbox * 816 + ** .dt %n .dd number of unread messages in the mailbox * 817 + ** .dt %N .dd N if mailbox has new mail, blank otherwise 816 818 ** .dt %s .dd size in bytes 817 819 ** .dt %t .dd ``*'' if the file is tagged, blank otherwise 818 820 ** .dt %u .dd owner name (or numeric uid, if missing) ··· 822 824 ** .de 823 825 ** .pp 824 826 ** For an explanation of ``soft-fill'', see the $$index_format documentation. 827 + ** .pp 828 + ** * = can be optionally printed if nonzero 829 + ** .pp 830 + ** %m, %n, and %N only work for monitored mailboxes. 831 + ** %m requires $$mail_check_stats to be set. 832 + ** %n requires $$mail_check_stats to be set (except for IMAP mailboxes). 825 833 */ 826 834 { "followup_to", DT_BOOL, R_NONE, OPTFOLLOWUPTO, 1 }, 827 835 /*