From 8ea755c230eb70b705f15778fceabdc7ad5b2aae Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 21 Aug 2016 10:21:58 +0200 Subject: [PATCH 4/5] Make it possible to collapse all thread expect for a few matching some citeria Example: set collapse_flagged=no set collapse_unread=no folder-hook . 'push ' collapse everything expect flagged and unread threads. --- curs_main.c | 17 +++++++++++++---- init.h | 6 ++++++ mutt.h | 2 ++ protos.h | 1 + thread.c | 16 +++++++++++++++- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/curs_main.c b/curs_main.c index 0613268..07c957b 100644 --- a/curs_main.c +++ b/curs_main.c @@ -113,6 +113,11 @@ static const char *No_visible = N_("No visible messages."); #define CURHDR Context->hdrs[Context->v2r[menu->current]] #define OLDHDR Context->hdrs[Context->v2r[menu->oldcurrent]] #define UNREAD(h) mutt_thread_contains_unread (Context, h) +#define FLAGGED(h) mutt_thread_contains_flagged (Context, h) + +#define CHECK_IF_TO_COLLAPSE(header) \ + ((option (OPTCOLLAPSEUNREAD) || !UNREAD (header)) && \ + (option (OPTCOLLAPSEFLAGGED) || FLAGGED(header) == 0)) /* de facto standard escapes for tsl/fsl */ static char *tsl = "\033]0;"; @@ -1965,14 +1970,14 @@ int mutt_index_menu (void) if (option (OPTUNCOLLAPSEJUMP)) menu->current = mutt_thread_next_unread (Context, CURHDR); } - else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR)) + else if CHECK_IF_TO_COLLAPSE(CURHDR) { menu->current = mutt_collapse_thread (Context, CURHDR); mutt_set_virtual (Context); } else { - mutt_error _("Thread contains unread messages."); + mutt_error _("Thread contains unread or flagged messages."); break; } @@ -1997,8 +2002,10 @@ int mutt_index_menu (void) if (CURHDR->collapsed) final = mutt_uncollapse_thread (Context, CURHDR); - else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR)) + else if CHECK_IF_TO_COLLAPSE(CURHDR) + { final = mutt_collapse_thread (Context, CURHDR); + } else final = CURHDR->virtual; @@ -2016,9 +2023,11 @@ int mutt_index_menu (void) { if (h->collapsed) mutt_uncollapse_thread (Context, h); - else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (h)) + else if CHECK_IF_TO_COLLAPSE(h) + { mutt_collapse_thread (Context, h); } + } top = top->next; } diff --git a/init.h b/init.h index 381e43f..8ebc621 100644 --- a/init.h +++ b/init.h @@ -3616,6 +3616,12 @@ struct option_t MuttVars[] = { ** tunnel commands per connection. */ #endif + { "collapse_flagged", DT_BOOL, R_NONE, OPTCOLLAPSEFLAGGED, 1 }, + /* + ** .pp + ** When \fIunset\fP, Mutt will not collapse a thread if it contains any + ** flagged messages. + */ { "uncollapse_jump", DT_BOOL, R_NONE, OPTUNCOLLAPSEJUMP, 0 }, /* ** .pp diff --git a/mutt.h b/mutt.h index 1575d5d..ffa44a1 100644 --- a/mutt.h +++ b/mutt.h @@ -163,6 +163,7 @@ typedef enum #define MUTT_THREAD_GET_HIDDEN (1<<2) #define MUTT_THREAD_UNREAD (1<<3) #define MUTT_THREAD_NEXT_UNREAD (1<<4) +#define MUTT_THREAD_FLAGGED (1<<5) enum { @@ -338,6 +339,7 @@ enum OPTCHECKMBOXSIZE, OPTCHECKNEW, OPTCOLLAPSEUNREAD, + OPTCOLLAPSEFLAGGED, OPTCONFIRMAPPEND, OPTCONFIRMCREATE, OPTDELETEUNTAG, diff --git a/protos.h b/protos.h index 91a134b..45667cd 100644 --- a/protos.h +++ b/protos.h @@ -62,6 +62,7 @@ int _mutt_aside_thread (HEADER *, short, short); #define mutt_uncollapse_thread(x,y) _mutt_traverse_thread (x,y,MUTT_THREAD_UNCOLLAPSE) #define mutt_get_hidden(x,y)_mutt_traverse_thread (x,y,MUTT_THREAD_GET_HIDDEN) #define mutt_thread_contains_unread(x,y) _mutt_traverse_thread (x,y,MUTT_THREAD_UNREAD) +#define mutt_thread_contains_flagged(x,y) _mutt_traverse_thread (x,y,MUTT_THREAD_FLAGGED) #define mutt_thread_next_unread(x,y) _mutt_traverse_thread(x,y,MUTT_THREAD_NEXT_UNREAD) int _mutt_traverse_thread (CONTEXT *ctx, HEADER *hdr, int flag); diff --git a/thread.c b/thread.c index cf77bdb..d429c0f 100644 --- a/thread.c +++ b/thread.c @@ -1129,7 +1129,7 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) THREAD *thread, *top; HEADER *roothdr = NULL; int final, reverse = (Sort & SORT_REVERSE), minmsgno; - int num_hidden = 0, new = 0, old = 0; + int num_hidden = 0, new = 0, old = 0, flagged = 0; int min_unread_msgno = INT_MAX, min_unread = cur->virtual; #define CHECK_LIMIT (!ctx->pattern || cur->limited) @@ -1162,6 +1162,11 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) } } + if (cur->flagged && CHECK_LIMIT) + { + flagged = 1; + } + if (cur->virtual == -1 && CHECK_LIMIT) num_hidden++; @@ -1188,6 +1193,8 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) return (num_hidden); else if (flag & MUTT_THREAD_NEXT_UNREAD) return (min_unread); + else if (flag & MUTT_THREAD_FLAGGED) + return (flagged); } FOREVER @@ -1239,6 +1246,11 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) } } + if (cur->flagged && CHECK_LIMIT) + { + flagged = 1; + } + if (cur->virtual == -1 && CHECK_LIMIT) num_hidden++; } @@ -1274,6 +1286,8 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) return (num_hidden+1); else if (flag & MUTT_THREAD_NEXT_UNREAD) return (min_unread); + else if (flag & MUTT_THREAD_FLAGGED) + return (flagged); return (0); #undef CHECK_LIMIT -- 2.1.4