From: Kevin McCarthy Date: Wed, 19 Oct 2016 20:21:16 +0000 (-0700) Subject: Add root-message function to jump to root message in thread. X-Git-Tag: mutt-1-8-rel~115 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2256f55ab4e65f011cd53786255aa9b1c0f1a9d1;p=mutt Add root-message function to jump to root message in thread. This seems like a useful feature that was brought up for discussion on mutt-users. Proposed solutions involved collapsing/uncollapsing threads, but it's not hard to modify the mutt_parent_message() function to return the root instead. --- diff --git a/OPS b/OPS index 02cea8e1..ed15b49e 100644 --- a/OPS +++ b/OPS @@ -124,6 +124,7 @@ OP_MAIN_PREV_NEW_THEN_UNREAD "jump to the previous new or unread message" OP_MAIN_PREV_UNREAD "jump to the previous unread message" OP_MAIN_READ_THREAD "mark the current thread as read" OP_MAIN_READ_SUBTHREAD "mark the current subthread as read" +OP_MAIN_ROOT_MESSAGE "jump to root message in thread" OP_MAIN_SET_FLAG "set a status flag on a message" OP_MAIN_SYNC_FOLDER "save changes to mailbox" OP_MAIN_TAG_PATTERN "tag messages matching a pattern" diff --git a/curs_main.c b/curs_main.c index 8e0f52ad..3793eccc 100644 --- a/curs_main.c +++ b/curs_main.c @@ -474,7 +474,7 @@ static void resort_index (MUTTMENU *menu) } if ((Sort & SORT_MASK) == SORT_THREADS && menu->current < 0) - menu->current = mutt_parent_message (Context, current); + menu->current = mutt_parent_message (Context, current, 0); if (menu->current < 0) menu->current = ci_first_message (); @@ -1791,12 +1791,14 @@ int mutt_index_menu (void) menu->redraw = REDRAW_MOTION; break; + case OP_MAIN_ROOT_MESSAGE: case OP_MAIN_PARENT_MESSAGE: CHECK_MSGCOUNT; CHECK_VISIBLE; - if ((menu->current = mutt_parent_message (Context, CURHDR)) < 0) + if ((menu->current = mutt_parent_message (Context, CURHDR, + op == OP_MAIN_ROOT_MESSAGE)) < 0) { menu->current = menu->oldcurrent; } diff --git a/functions.h b/functions.h index abc06ca0..4f04251e 100644 --- a/functions.h +++ b/functions.h @@ -160,6 +160,7 @@ const struct binding_t OpMain[] = { /* map: index */ { "next-unread", OP_MAIN_NEXT_UNREAD, NULL }, { "previous-unread", OP_MAIN_PREV_UNREAD, NULL }, { "parent-message", OP_MAIN_PARENT_MESSAGE, "P" }, + { "root-message", OP_MAIN_ROOT_MESSAGE, NULL }, { "extract-keys", OP_EXTRACT_KEYS, "\013" }, @@ -271,6 +272,7 @@ const struct binding_t OpPager[] = { /* map: pager */ { "previous-line", OP_PREV_LINE, NULL }, { "bottom", OP_PAGER_BOTTOM, NULL }, { "parent-message", OP_MAIN_PARENT_MESSAGE, "P" }, + { "root-message", OP_MAIN_ROOT_MESSAGE, NULL }, diff --git a/protos.h b/protos.h index 19d64003..def09ea5 100644 --- a/protos.h +++ b/protos.h @@ -298,7 +298,7 @@ int mutt_fetch_recips (ENVELOPE *out, ENVELOPE *in, int flags); int mutt_chscmp (const char *s, const char *chs); #define mutt_is_utf8(a) mutt_chscmp (a, "utf-8") #define mutt_is_us_ascii(a) mutt_chscmp (a, "us-ascii") -int mutt_parent_message (CONTEXT *, HEADER *); +int mutt_parent_message (CONTEXT *, HEADER *, int); int mutt_prepare_template(FILE*, CONTEXT *, HEADER *, HEADER *, short); int mutt_resend_message (FILE *, CONTEXT *, HEADER *); #define mutt_enter_fname(A,B,C,D,E) _mutt_enter_fname(A,B,C,D,E,0,NULL,NULL) diff --git a/thread.c b/thread.c index cf77bdb7..2e247c09 100644 --- a/thread.c +++ b/thread.c @@ -1074,9 +1074,10 @@ int _mutt_aside_thread (HEADER *hdr, short dir, short subthreads) return (tmp->virtual); } -int mutt_parent_message (CONTEXT *ctx, HEADER *hdr) +int mutt_parent_message (CONTEXT *ctx, HEADER *hdr, int find_root) { THREAD *thread; + HEADER *parent = NULL; if ((Sort & SORT_MASK) != SORT_THREADS) { @@ -1084,22 +1085,34 @@ int mutt_parent_message (CONTEXT *ctx, HEADER *hdr) return (hdr->virtual); } + /* Root may be the current message */ + if (find_root) + parent = hdr; + for (thread = hdr->thread->parent; thread; thread = thread->parent) { if ((hdr = thread->message) != NULL) { - if (VISIBLE (hdr, ctx)) - return (hdr->virtual); - else - { - mutt_error _("Parent message is not visible in this limited view."); - return (-1); - } + parent = hdr; + if (!find_root) + break; } } - - mutt_error _("Parent message is not available."); - return (-1); + + if (!parent) + { + mutt_error _("Parent message is not available."); + return (-1); + } + if (!VISIBLE (parent, ctx)) + { + if (find_root) + mutt_error _("Root message is not visible in this limited view."); + else + mutt_error _("Parent message is not visible in this limited view."); + return (-1); + } + return (parent->virtual); } void mutt_set_virtual (CONTEXT *ctx)