Commit 1d41321a authored by Kevin J. McCarthy's avatar Kevin J. McCarthy

Display matching new messages in a thread-limited index.

Previously, the index performed pattern matching first, and then
resorted new mail.  The problem was that thread-limiting patterns,
e.g. ~(pattern), require threading data to properly match against the
new messages.

We already save new messages for the purposes of uncollapsing threads.
To keep the code cleaner, split off update_index() into
update_index_threaded()/unthreaded().  Then for threaded mode, save
the new messages first.  We can then sort (before pattern matching),
and use the save_new array to pattern match the new messages
afterwards.

The $uncollapse_new loop was unnecessarily performing a n^2 search.
Simplify to just iteratate over the save_new instead.
parent f0772c95
Pipeline #26199463 passed with stages
in 15 minutes and 8 seconds
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment