From 50954c4ab74084815513ce8262946ab71e680e33 Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Fri, 14 Apr 2023 15:57:07 -0700 Subject: [PATCH] Fix behavior for sort=reverse-threads. When uncollapsing, _mutt_traverse_thread() returns the virtual number of the root message in the thread. directly sets menu->current to this value to cause the cursor to be on the *first* message of the thread (which isn't the same as the root message when sort=reverse-threads). finds the corresponding message by searching for it after re-indexing. However, when collapsing, _mutt_traverse_thread() had code to try and find the *first* message in the thread and return that virtual number. then did the same trick, because the old first message is now the new root message for sort=reverse-threads. However, that cleverness caused a bug for - it can't use that virtual number directly, and it can't "find" the message at the index after reindexing. To fix this, remove the cleverness from _mutt_traverse_thread() when collapsing. Return the virtual number of the root. Add searching behavior for to fix its behavior. --- curs_main.c | 21 ++++++++++++++++++++- thread.c | 9 +-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/curs_main.c b/curs_main.c index 43d50ace..71a4e06e 100644 --- a/curs_main.c +++ b/curs_main.c @@ -2071,6 +2071,11 @@ int mutt_index_menu (void) if (CURHDR->collapsed) { + /* Note this returns the *old* virtual index of the root message. + * + * For sort=reverse-threads this trick allows uncollapsing a + * single thread to position on the first (not root) message + * in the thread */ menu->current = mutt_uncollapse_thread (Context, CURHDR); mutt_set_virtual (Context); if (option (OPTUNCOLLAPSEJUMP)) @@ -2078,8 +2083,22 @@ int mutt_index_menu (void) } else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR)) { - menu->current = mutt_collapse_thread (Context, CURHDR); + HEADER *base; + int final; + /* This also returns the *old* virtual index of the root, but now + * we have to find the new position of the root, which isn't + * the same for sort=reverse-threads. */ + final = mutt_collapse_thread (Context, CURHDR); + base = Context->hdrs[Context->v2r[final]]; mutt_set_virtual (Context); + for (j = 0; j < Context->vcount; j++) + { + if (Context->hdrs[Context->v2r[j]]->index == base->index) + { + menu->current = j; + break; + } + } } else { diff --git a/thread.c b/thread.c index ddd1c7c1..86c051fe 100644 --- a/thread.c +++ b/thread.c @@ -1321,7 +1321,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 final; int num_hidden = 0, new = 0, old = 0; int min_unread_msgno = INT_MAX, min_unread = cur->virtual; #define CHECK_LIMIT (!ctx->pattern || cur->limited) @@ -1340,7 +1340,6 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) while (!thread->message) thread = thread->child; cur = thread->message; - minmsgno = cur->msgno; if (!cur->read && CHECK_LIMIT) { @@ -1401,12 +1400,6 @@ int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag) final = roothdr->virtual; } - if (reverse && (flag & MUTT_THREAD_COLLAPSE) && (cur->msgno < minmsgno) && CHECK_LIMIT) - { - minmsgno = cur->msgno; - final = cur->virtual; - } - if (flag & MUTT_THREAD_COLLAPSE) { if (cur != roothdr) -- 2.38.5