On Tue, Jul 03, 2018 at 10:06:43AM -0700, Kevin J. McCarthy wrote:
> On Tue, Jul 03, 2018 at 01:34:40AM +0200, Vincent Lefevre wrote:
> > I sometimes use a limited view with: ~(~asome_address)
> > 
> > But in such a case, incoming messages that match this pattern are
> > not included in this limited view. Is this a bug or a feature with
> > particular patterns?
> 
> It's probably some technical difficulty.  I'll try to poke around and
> see if I can figure out why.

This patch is "work in progress", but you are welcome to try it out.

The difficulty was in the update_index() function, where it applied the
limit first and then sorted.  For ~(pattern) we need thread information
for the new messages, requiring an initial sort, and then a pattern match.

Unfortunately, one more call to sort is needed to properly set virtual
numbers and redraw the tree.  This will only be done when a limit is in
effect through.

Again, this is WIP - I need to test and clean it up still.

-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
From f299c358752bc48a85b3827bb845ffaf4822c06b Mon Sep 17 00:00:00 2001
From: Kevin McCarthy <ke...@8t8.us>
Date: Thu, 19 Jul 2018 20:28:38 -0700
Subject: [PATCH] Improve update_index when a thread-limiting pattern is in
 effect.

Split off a different function when the index is sorted by thread.  In
order for thread-patterns (e.g. ~(pattern)) to show matching new
messages, they need to be threaded first.

The save_new was previously used only for uncollapsing threads, but we
can use it to pattern match after the sort, so move it in front.

After we apply the pattern on new messages, the virtual numbers and
tree need to be redrawn, so call sort a second time.

The uncollapse_new was unnecessarily performing a n^2 search.  Simplify
to just iteratate over the save_new instead.
---
 curs_main.c | 133 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 85 insertions(+), 48 deletions(-)

diff --git a/curs_main.c b/curs_main.c
index 703a0660..12a2eaf2 100644
--- a/curs_main.c
+++ b/curs_main.c
@@ -351,62 +351,53 @@ static int mx_toggle_write (CONTEXT *ctx)
   return 0;
 }
 
-static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
-			  int oldcount, int index_hint)
+static void update_index_threaded (CONTEXT *ctx, int check, int oldcount)
 {
-  /* store pointers to the newly added messages */
-  HEADER  **save_new = NULL;
+  HEADER **save_new = NULL;
   int j;
 
-  /* take note of the current message */
-  if (oldcount)
+  /* save the list of new messages */
+  if ((check != MUTT_REOPENED) && oldcount &&
+      (ctx->pattern || option (OPTUNCOLLAPSENEW)))
   {
-    if (menu->current < ctx->vcount)
-      menu->oldcurrent = index_hint;
-    else
-      oldcount = 0; /* invalid message number! */
+    save_new = (HEADER **) safe_malloc (sizeof (HEADER *) * (ctx->msgcount - oldcount));
+    for (j = oldcount; j < ctx->msgcount; j++)
+      save_new[j-oldcount] = ctx->hdrs[j];
   }
 
-  /* We are in a limited view. Check if the new message(s) satisfy
-   * the limit criteria. If they do, set their virtual msgno so that
-   * they will be visible in the limited view */
+  /* Sort first to thread the new messages, because some patterns
+   * require the threading information.
+   *
+   * If the mailbox was reopened, need to rethread from scratch. */
+  mutt_sort_headers (ctx, (check == MUTT_REOPENED));
+
   if (ctx->pattern)
   {
-#define THIS_BODY ctx->hdrs[j]->content
     for (j = (check == MUTT_REOPENED) ? 0 : oldcount; j < ctx->msgcount; j++)
     {
-      if (!j)
-	ctx->vcount = 0;
+      HEADER *h;
+
+      if ((check != MUTT_REOPENED) && oldcount)
+        h = save_new[j-oldcount];
+      else
+        h = ctx->hdrs[j];
 
       if (mutt_pattern_exec (ctx->limit_pattern,
 			     MUTT_MATCH_FULL_ADDRESS,
-			     ctx, ctx->hdrs[j], NULL))
+			     ctx, h, NULL))
       {
-	assert (ctx->vcount < ctx->msgcount);
-	ctx->hdrs[j]->virtual = ctx->vcount;
-	ctx->v2r[ctx->vcount] = j;
-	ctx->hdrs[j]->limited = 1;
-	ctx->vcount++;
-	ctx->vsize += THIS_BODY->length + THIS_BODY->offset - THIS_BODY->hdr_offset;
+        /* virtual will get properly set by mutt_set_virtual(), which
+         * is called by mutt_sort_headers() just below. */
+        h->virtual = 1;
+        h->limited = 1;
       }
     }
-#undef THIS_BODY
-  }
-
-  /* save the list of new messages */
-  if (option(OPTUNCOLLAPSENEW) && oldcount && check != MUTT_REOPENED
-      && ((Sort & SORT_MASK) == SORT_THREADS))
-  {
-    save_new = (HEADER **) safe_malloc (sizeof (HEADER *) * (ctx->msgcount - oldcount));
-    for (j = oldcount; j < ctx->msgcount; j++)
-      save_new[j-oldcount] = ctx->hdrs[j];
+    /* Need a second sort to set virtual numbers and redraw the tree */
+    mutt_sort_headers (ctx, 0);
   }
 
-  /* if the mailbox was reopened, need to rethread from scratch */
-  mutt_sort_headers (ctx, (check == MUTT_REOPENED));
-
   /* uncollapse threads with new mail */
-  if (option(OPTUNCOLLAPSENEW) && ((Sort & SORT_MASK) == SORT_THREADS))
+  if (option(OPTUNCOLLAPSENEW))
   {
     if (check == MUTT_REOPENED)
     {
@@ -425,21 +416,68 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
     else if (oldcount)
     {
       for (j = 0; j < ctx->msgcount - oldcount; j++)
-      {
-	int k;
+        if (!ctx->pattern || save_new[j]->limited)
+          mutt_uncollapse_thread (ctx, save_new[j]);
+      mutt_set_virtual (ctx);
+    }
+  }
 
-	for (k = 0; k < ctx->msgcount; k++)
-	{
-	  HEADER *h = ctx->hdrs[k];
-	  if (h == save_new[j] && (!ctx->pattern || h->limited))
-	    mutt_uncollapse_thread (ctx, h);
-	}
+  FREE (&save_new);
+}
+
+static void update_index_unthreaded (CONTEXT *ctx, int check, int oldcount)
+{
+  int j;
+
+  /* We are in a limited view. Check if the new message(s) satisfy
+   * the limit criteria. If they do, set their virtual msgno so that
+   * they will be visible in the limited view */
+  if (ctx->pattern)
+  {
+#define THIS_BODY ctx->hdrs[j]->content
+    for (j = (check == MUTT_REOPENED) ? 0 : oldcount; j < ctx->msgcount; j++)
+    {
+      if (!j)
+	ctx->vcount = 0;
+
+      if (mutt_pattern_exec (ctx->limit_pattern,
+			     MUTT_MATCH_FULL_ADDRESS,
+			     ctx, ctx->hdrs[j], NULL))
+      {
+	assert (ctx->vcount < ctx->msgcount);
+	ctx->hdrs[j]->virtual = ctx->vcount;
+	ctx->v2r[ctx->vcount] = j;
+	ctx->hdrs[j]->limited = 1;
+	ctx->vcount++;
+	ctx->vsize += THIS_BODY->length + THIS_BODY->offset - THIS_BODY->hdr_offset;
       }
-      FREE (&save_new);
-      mutt_set_virtual (ctx);
     }
+#undef THIS_BODY
   }
 
+  /* if the mailbox was reopened, need to rethread from scratch */
+  mutt_sort_headers (ctx, (check == MUTT_REOPENED));
+}
+
+static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
+			  int oldcount, int index_hint)
+{
+  int j;
+
+  /* take note of the current message */
+  if (oldcount)
+  {
+    if (menu->current < ctx->vcount)
+      menu->oldcurrent = index_hint;
+    else
+      oldcount = 0; /* invalid message number! */
+  }
+
+  if ((Sort & SORT_MASK) == SORT_THREADS)
+    update_index_threaded (ctx, check, oldcount);
+  else
+    update_index_unthreaded (ctx, check, oldcount);
+
   menu->current = -1;
   if (oldcount)
   {
@@ -456,7 +494,6 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
 
   if (menu->current < 0)
     menu->current = ci_first_message ();
-
 }
 
 static void resort_index (MUTTMENU *menu)
-- 
2.18.0

Attachment: signature.asc
Description: PGP signature

Reply via email to