From: Kevin McCarthy Date: Fri, 20 Jul 2018 03:28:38 +0000 (-0700) Subject: Display matching new messages in a thread-limited index. X-Git-Tag: mutt-1-11-rel~114 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d41321aef89979d5c40b6772c0752ab6f3fd21a;p=mutt 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. --- 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)