Example:

set collapse_flagged=no
set collapse_unread=no
folder-hook . 'push <collapse-all>'

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 49d5d7e..d6341e8 100644
--- a/curs_main.c
+++ b/curs_main.c
@@ -107,6 +107,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))
 
 extern size_t UngetCount;
 
@@ -1839,14 +1844,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;
        }
 
@@ -1871,8 +1876,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;
 
@@ -1890,9 +1897,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 e38c10d..ae8a881 100644
--- a/init.h
+++ b/init.h
@@ -3260,6 +3260,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 d5ffc63..af6699e 100644
--- a/mutt.h
+++ b/mutt.h
@@ -166,6 +166,7 @@ typedef enum
 #define M_THREAD_GET_HIDDEN    (1<<2)
 #define M_THREAD_UNREAD                (1<<3)
 #define M_THREAD_NEXT_UNREAD   (1<<4)
+#define M_THREAD_FLAGGED       (1<<5)
 
 enum
 {
@@ -333,6 +334,7 @@ enum
   OPTCHECKMBOXSIZE,
   OPTCHECKNEW,
   OPTCOLLAPSEUNREAD,
+  OPTCOLLAPSEFLAGGED,
   OPTCONFIRMAPPEND,
   OPTCONFIRMCREATE,
   OPTDELETEUNTAG,
diff --git a/protos.h b/protos.h
index fe69fad..f3c9f84 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,M_THREAD_UNCOLLAPSE)
 #define mutt_get_hidden(x,y)_mutt_traverse_thread (x,y,M_THREAD_GET_HIDDEN) 
 #define mutt_thread_contains_unread(x,y) _mutt_traverse_thread 
(x,y,M_THREAD_UNREAD)
+#define mutt_thread_contains_flagged(x,y) _mutt_traverse_thread 
(x,y,M_THREAD_FLAGGED)
 #define mutt_thread_next_unread(x,y) 
_mutt_traverse_thread(x,y,M_THREAD_NEXT_UNREAD)
 int _mutt_traverse_thread (CONTEXT *ctx, HEADER *hdr, int flag);
 
diff --git a/thread.c b/thread.c
index de1d16b..36bf654 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 & M_THREAD_NEXT_UNREAD)
       return (min_unread);
+    else if (flag & M_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 & M_THREAD_NEXT_UNREAD)
     return (min_unread);
+  else if (flag & M_THREAD_FLAGGED)
+    return (flagged);
 
   return (0);
 #undef CHECK_LIMIT
-- 
1.7.10.4

Reply via email to