]> git.llucax.com Git - software/mutt-debian.git/blobdiff - curs_main.c
Update and enable NNTP patch
[software/mutt-debian.git] / curs_main.c
index e39c8d01776909482c8b97ac4d1c32ca439b9864..dd2ac3986a634bd8573026c75d297650fe98b54f 100644 (file)
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
- * 
+ * Copyright (C) 1996-2000,2002 Michael R. Elkins <me@mutt.org>
+ *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
- * 
+ *
  *     This program is distributed in the hope that it will be useful,
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *     GNU General Public License for more details.
- * 
+ *
  *     You should have received a copy of the GNU General Public License
  *     along with this program; if not, write to the Free Software
  *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */ 
+ */
 
 #if HAVE_CONFIG_H
 # include "config.h"
 #include "mutt.h"
 #include "mutt_curses.h"
 #include "mutt_menu.h"
-#include "attach.h"
 #include "mailbox.h"
 #include "mapping.h"
 #include "sort.h"
-#include "buffy.h"
 #include "mx.h"
 
 #ifdef USE_POP
@@ -83,7 +81,7 @@ static const char *No_visible = N_("No visible messages.");
                mutt_error _(No_visible); \
                break; \
        }
-    
+
 
 #define CHECK_READONLY if (Context->readonly) \
                        { \
@@ -274,7 +272,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
   /* store pointers to the newly added messages */
   HEADER  **save_new = NULL;
   int j;
-  
+
   /* take note of the current message */
   if (oldcount)
   {
@@ -283,7 +281,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
     else
       oldcount = 0; /* invalid message number! */
   }
-  
+
   /* 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 */
@@ -296,7 +294,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
        ctx->vcount = 0;
 
       if (mutt_pattern_exec (ctx->limit_pattern,
-                            M_MATCH_FULL_ADDRESS, 
+                            M_MATCH_FULL_ADDRESS,
                             ctx, ctx->hdrs[j]))
       {
        assert (ctx->vcount < ctx->msgcount);
@@ -309,7 +307,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
     }
 #undef THIS_BODY
   }
-    
+
   /* save the list of new messages */
   if (oldcount && check != M_REOPENED
       && ((Sort & SORT_MASK) == SORT_THREADS))
@@ -318,7 +316,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
     for (j = oldcount; j < ctx->msgcount; j++)
       save_new[j-oldcount] = ctx->hdrs[j];
   }
-  
+
   /* if the mailbox was reopened, need to rethread from scratch */
   mutt_sort_headers (ctx, (check == M_REOPENED));
 
@@ -328,9 +326,9 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
     if (check == M_REOPENED)
     {
       THREAD *h, *j;
-      
+
       ctx->collapsed = 0;
-      
+
       for (h = ctx->tree; h; h = h->next)
       {
        for (j = h; !j->message; j = j->child)
@@ -344,7 +342,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
       for (j = 0; j < ctx->msgcount - oldcount; j++)
       {
        int k;
-       
+
        for (k = 0; k < ctx->msgcount; k++)
        {
          HEADER *h = ctx->hdrs[k];
@@ -356,7 +354,7 @@ static void update_index (MUTTMENU *menu, CONTEXT *ctx, int check,
       mutt_set_virtual (ctx);
     }
   }
-  
+
   menu->current = -1;
   if (oldcount)
   {
@@ -370,10 +368,10 @@ 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)
@@ -393,17 +391,17 @@ static void resort_index (MUTTMENU *menu)
       break;
     }
   }
-  
+
   if ((Sort & SORT_MASK) == SORT_THREADS && menu->current < 0)
     menu->current = mutt_parent_message (Context, current);
-  
+
   if (menu->current < 0)
     menu->current = ci_first_message ();
-  
+
   menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
 }
 
-struct mapping_t IndexHelp[] = {
+static struct mapping_t IndexHelp[] = {
   { N_("Quit"),  OP_QUIT },
   { N_("Del"),   OP_DELETE },
   { N_("Undel"), OP_UNDELETE },
@@ -412,7 +410,7 @@ struct mapping_t IndexHelp[] = {
   { N_("Reply"), OP_REPLY },
   { N_("Group"), OP_GROUP_REPLY },
   { N_("Help"),  OP_HELP },
-  { NULL }
+  { NULL,       0 }
 };
 
 /* This function handles the message index window as well as commands returned
@@ -434,33 +432,32 @@ int mutt_index_menu (void)
   int do_buffy_notify = 1;
   int close = 0; /* did we OP_QUIT or OP_EXIT out of this menu? */
   int attach_msg = option(OPTATTACHMSG);
-  
-  menu = mutt_new_menu ();
-  menu->menu = MENU_MAIN;
+
+  menu = mutt_new_menu (MENU_MAIN);
   menu->offset = 1;
   menu->pagelen = LINES - 3;
   menu->make_entry = index_make_entry;
   menu->color = index_color;
   menu->current = ci_first_message ();
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, IndexHelp);
-  
-  if (!attach_msg) 
+
+  if (!attach_msg)
     mutt_buffy_check(1); /* force the buffy check after we enter the folder */
 
   FOREVER
   {
     tag = 0; /* clear the tag-prefix */
 
-    menu->max = Context ? Context->vcount : 0;
-    oldcount = Context ? Context->msgcount : 0;
-
     /* check if we need to resort the index because just about
      * any 'op' below could do mutt_enter_command(), either here or
      * from any new menu launched, and change $sort/$sort_aux
      */
-    if (option (OPTNEEDRESORT) && Context && Context->msgcount)
+    if (option (OPTNEEDRESORT) && Context && Context->msgcount && menu->current >= 0)
       resort_index (menu);
-    
+
+    menu->max = Context ? Context->vcount : 0;
+    oldcount = Context ? Context->msgcount : 0;
+
     if (option (OPTREDRAWTREE) && Context && Context->msgcount && (Sort & SORT_MASK) == SORT_THREADS)
     {
       mutt_draw_tree (Context);
@@ -476,10 +473,6 @@ int mutt_index_menu (void)
        * modified underneath us.)
        */
 
-#ifdef USE_IMAP
-      imap_allow_reopen (Context);
-#endif
-    
       index_hint = (Context->vcount && menu->current >= 0 && menu->current < Context->vcount) ? CURHDR->index : 0;
 
       if ((check = mx_check_mailbox (Context, &index_hint, 0)) < 0)
@@ -496,7 +489,7 @@ int mutt_index_menu (void)
       else if (check == M_NEW_MAIL || check == M_REOPENED || check == M_FLAGS)
       {
        update_index (menu, Context, check, oldcount, index_hint);
-       
+
        /* notify the user of new mail */
        if (check == M_REOPENED)
          mutt_error _("Mailbox was externally modified.  Flags may be wrong.");
@@ -510,19 +503,14 @@ int mutt_index_menu (void)
 
        /* avoid the message being overwritten by buffy */
        do_buffy_notify = 0;
-       
+
        menu->redraw = REDRAW_FULL;
        menu->max = Context->vcount;
-       
+
        set_option (OPTSEARCHINVALID);
       }
     }
 
-#ifdef USE_IMAP
-    imap_keepalive ();
-    imap_disallow_reopen (Context);
-#endif
-
     if (!attach_msg)
     {
      /* check for new mail in the incoming folders */
@@ -564,7 +552,7 @@ int mutt_index_menu (void)
          menu_redraw_current (menu);
       }
 
-      if (menu->redraw & REDRAW_STATUS) 
+      if (menu->redraw & REDRAW_STATUS)
       {
        menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
        CLEARLINE (option (OPTSTATUSONTOP) ? 0 : LINES-2);
@@ -614,9 +602,9 @@ int mutt_index_menu (void)
 
       if (op == -1)
        continue; /* either user abort or timeout */
-      
+
       mutt_curs_set (1);
-      
+
       /* special handling for the tag-prefix function */
       if (op == OP_TAG_PREFIX)
       {
@@ -690,7 +678,7 @@ int mutt_index_menu (void)
        menu->oldcurrent = menu->current;
       else
        menu->oldcurrent = -1;
-      
+
       mutt_curs_set (1);       /* fallback from the pager */
     }
 
@@ -754,13 +742,12 @@ int mutt_index_menu (void)
            || !buf[0])
          break;
 
-       if (! isdigit ((unsigned char) buf[0]))
+       if (mutt_atoi (buf, &i) < 0)
        {
          mutt_error _("Argument must be a message number.");
          break;
        }
 
-       i = atoi (buf);
        if (i > 0 && i <= Context->msgcount)
        {
          for (j = i-1; j < Context->msgcount; j++)
@@ -868,7 +855,7 @@ int mutt_index_menu (void)
        }
         if (Context->pattern)
          mutt_message _("To view all messages, limit to \"all\".");
-       break;    
+       break;
 
       case OP_QUIT:
 
@@ -882,7 +869,7 @@ int mutt_index_menu (void)
        if (query_quadoption (OPT_QUIT, _("Quit Mutt?")) == M_YES)
        {
          int check;
-         
+
          oldcount = Context ? Context->msgcount : 0;
 
          if (!Context || (check = mx_close_mailbox (Context, &index_hint)) == 0)
@@ -927,6 +914,11 @@ int mutt_index_menu (void)
            resort_index (menu);
            set_option (OPTSEARCHINVALID);
          }
+         if (menu->menu == MENU_PAGER)
+         {
+           op = OP_DISPLAY_MESSAGE;
+           continue;
+         }
          menu->redraw |= REDRAW_STATUS;
        }
        break;
@@ -996,8 +988,25 @@ int mutt_index_menu (void)
        if (Context && Context->magic == M_IMAP)
          imap_check_mailbox (Context, &index_hint, 1);
         break;
+
+      case OP_MAIN_IMAP_LOGOUT_ALL:
+       if (Context && Context->magic == M_IMAP)
+       {
+         if (mx_close_mailbox (Context, &index_hint) != 0)
+         {
+           set_option (OPTSEARCHINVALID);
+           menu->redraw = REDRAW_FULL;
+           break;
+         }
+         FREE (&Context);
+       }
+       imap_logout_all();
+       mutt_message _("Logged out of IMAP servers.");
+       set_option (OPTSEARCHINVALID);
+       menu->redraw = REDRAW_FULL;
+       break;
 #endif
-      
+
       case OP_MAIN_SYNC_FOLDER:
 
        if (Context && !Context->msgcount)
@@ -1009,28 +1018,36 @@ int mutt_index_menu (void)
        {
          int oldvcount = Context->vcount;
          int oldcount  = Context->msgcount;
-         int dcount = 0;
-         int check;
-
-         /* calculate the number of messages _above_ the cursor,
-          * so we can keep the cursor on the current message
-          */ 
-         for (j = 0; j <= menu->current; j++)
-         {
-           if (Context->hdrs[Context->v2r[j]]->deleted)
-             dcount++;
-         }
+         int check, newidx;
+         HEADER *newhdr = NULL;
+
+         /* threads may be reordered, so figure out what header the cursor
+          * should be on. #3092 */
+         newidx = menu->current;
+         if (CURHDR->deleted)
+           newidx = ci_next_undeleted (menu->current);
+         if (newidx < 0)
+           newidx = ci_previous_undeleted (menu->current);
+         if (newidx >= 0)
+           newhdr = Context->hdrs[Context->v2r[newidx]];
 
          if ((check = mx_sync_mailbox (Context, &index_hint)) == 0)
          {
-           if (Context->vcount != oldvcount)
-             menu->current -= dcount;
+           if (newhdr && Context->vcount != oldvcount)
+             for (j = 0; j < Context->vcount; j++)
+             {
+               if (Context->hdrs[Context->v2r[j]] == newhdr)
+               {
+                 menu->current = j;
+                 break;
+               }
+             }
            set_option (OPTSEARCHINVALID);
          }
          else if (check == M_NEW_MAIL || check == M_REOPENED)
            update_index (menu, Context, check, oldcount, index_hint);
 
-         /* 
+         /*
           * do a sanity check even if mx_sync_mailbox failed.
           */
 
@@ -1054,7 +1071,7 @@ int mutt_index_menu (void)
 
       case OP_MAIN_CHANGE_FOLDER:
       case OP_MAIN_NEXT_UNREAD_MAILBOX:
-      
+
        if (attach_msg)
          op = OP_MAIN_CHANGE_FOLDER_READONLY;
 
@@ -1071,7 +1088,7 @@ int mutt_index_menu (void)
        if ((op == OP_MAIN_NEXT_UNREAD_MAILBOX) && Context && Context->path)
        {
          strfcpy (buf, Context->path, sizeof (buf));
-         mutt_pretty_mailbox (buf);
+         mutt_pretty_mailbox (buf, sizeof (buf));
          mutt_buffy (buf, sizeof (buf));
          if (!buf[0])
          {
@@ -1108,6 +1125,10 @@ int mutt_index_menu (void)
        }
        mutt_str_replace (&CurrentFolder, buf);
 
+       /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
+       if (Context && !Context->path)
+         FREE (&Context);
+
         if (Context)
         {
          int check;
@@ -1119,7 +1140,7 @@ int mutt_index_menu (void)
          {
            if (check == M_NEW_MAIL || check == M_REOPENED)
              update_index (menu, Context, check, oldcount, index_hint);
-               
+
            set_option (OPTSEARCHINVALID);
            menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
            break;
@@ -1128,7 +1149,7 @@ int mutt_index_menu (void)
        }
 
         mutt_sleep (0);
-      
+
        /* Set CurrentMenu to MENU_MAIN before executing any folder
         * hooks so that all the index menu functions are available to
         * the exec command.
@@ -1137,7 +1158,7 @@ int mutt_index_menu (void)
        CurrentMenu = MENU_MAIN;
        mutt_folder_hook (buf);
 
-       if ((Context = mx_open_mailbox (buf, 
+       if ((Context = mx_open_mailbox (buf,
                                        (option (OPTREADONLY) || op == OP_MAIN_CHANGE_FOLDER_READONLY) ?
                                        M_READONLY : 0, NULL)) != NULL)
        {
@@ -1174,8 +1195,8 @@ int mutt_index_menu (void)
          if (option (OPTUNCOLLAPSEJUMP))
            menu->current = mutt_thread_next_unread (Context, CURHDR);
        }
-       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))) 
+
+       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
        if ((op = mutt_display_message (CURHDR)) == -1)
        {
@@ -1197,7 +1218,7 @@ int mutt_index_menu (void)
        }
 
        if ((menu->menu == MENU_MAIN)
-           && (query_quadoption (OPT_QUIT, 
+           && (query_quadoption (OPT_QUIT,
                                  _("Exit Mutt without saving?")) == M_YES))
        {
          if (Context)
@@ -1217,7 +1238,7 @@ int mutt_index_menu (void)
 
         if ((Sort & SORT_MASK) != SORT_THREADS)
          mutt_error _("Threading is not enabled.");
-       else
+       else if (CURHDR->env->in_reply_to || CURHDR->env->references)
        {
          {
            HEADER *oldcur = CURHDR;
@@ -1238,8 +1259,10 @@ int mutt_index_menu (void)
          else
            menu->redraw |= REDRAW_INDEX;
        }
+       else
+         mutt_error _("Thread cannot be broken, message is not part of a thread");
 
-         break;
+       break;
 
       case OP_MAIN_LINK_THREADS:
 
@@ -1254,7 +1277,7 @@ int mutt_index_menu (void)
          mutt_error _("No Message-ID: header available to link thread");
        else if (!tag && (!Context->last_tag || !Context->last_tag->tagged))
          mutt_error _("First, please tag a message to be linked here");
-       else 
+       else
        {
          HEADER *oldcur = CURHDR;
 
@@ -1263,7 +1286,7 @@ int mutt_index_menu (void)
          {
            mutt_sort_headers (Context, 1);
            menu->current = oldcur->virtual;
-           
+
            Context->changed = 1;
            mutt_message _("Threads linked");
          }
@@ -1388,7 +1411,7 @@ int mutt_index_menu (void)
       case OP_DECRYPT_COPY:
       case OP_DECRYPT_SAVE:
         if (!WithCrypto)
-          break;   
+          break;
         /* fall thru */
       case OP_COPY_MESSAGE:
       case OP_SAVE:
@@ -1433,7 +1456,7 @@ int mutt_index_menu (void)
       {
        int first_unread = -1;
        int first_new    = -1;
-       
+
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
 
@@ -1441,7 +1464,7 @@ int mutt_index_menu (void)
        menu->current = -1;
        for (j = 0; j != Context->vcount; j++)
        {
-#define CURHDRi Context->hdrs[Context->v2r[i]] 
+#define CURHDRi Context->hdrs[Context->v2r[i]]
          if (op == OP_MAIN_NEXT_NEW || op == OP_MAIN_NEXT_UNREAD || op == OP_MAIN_NEXT_NEW_THEN_UNREAD)
          {
            i++;
@@ -1475,7 +1498,7 @@ int mutt_index_menu (void)
            if ((!CURHDRi->old) && first_new == -1)
              first_new = i;
          }
-         
+
          if ((op == OP_MAIN_NEXT_UNREAD || op == OP_MAIN_PREV_UNREAD) &&
              first_unread != -1)
            break;
@@ -1486,7 +1509,7 @@ int mutt_index_menu (void)
        }
 #undef CURHDRi
        if ((op == OP_MAIN_NEXT_NEW || op == OP_MAIN_PREV_NEW ||
-            op == OP_MAIN_NEXT_NEW_THEN_UNREAD || op == OP_MAIN_PREV_NEW_THEN_UNREAD) 
+            op == OP_MAIN_NEXT_NEW_THEN_UNREAD || op == OP_MAIN_PREV_NEW_THEN_UNREAD)
            && first_new != -1)
          menu->current = first_new;
        else if ((op == OP_MAIN_NEXT_UNREAD || op == OP_MAIN_PREV_UNREAD ||
@@ -1614,7 +1637,7 @@ int mutt_index_menu (void)
          case OP_MAIN_NEXT_SUBTHREAD:
            menu->current = mutt_next_subthread (CURHDR);
            break;
-           
+
          case OP_MAIN_PREV_THREAD:
            menu->current = mutt_previous_thread (CURHDR);
            break;
@@ -1696,7 +1719,7 @@ int mutt_index_menu (void)
          mutt_error _("Threading is not enabled.");
          break;
        }
-      
+
        if (CURHDR->collapsed)
        {
          menu->current = mutt_uncollapse_thread (Context, CURHDR);
@@ -1733,16 +1756,16 @@ int mutt_index_menu (void)
          HEADER *h, *base;
          THREAD *thread, *top;
          int final;
-         
+
          if (CURHDR->collapsed)
            final = mutt_uncollapse_thread (Context, CURHDR);
          else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR))
            final = mutt_collapse_thread (Context, CURHDR);
          else
            final = CURHDR->virtual;
-         
+
          base = Context->hdrs[Context->v2r[final]];
-         
+
          top = Context->tree;
          Context->collapsed = !Context->collapsed;
          while ((thread = top) != NULL)
@@ -1760,7 +1783,7 @@ int mutt_index_menu (void)
            }
            top = top->next;
          }
-         
+
          mutt_set_virtual (Context);
          for (j = 0; j < Context->vcount; j++)
          {
@@ -1770,11 +1793,11 @@ int mutt_index_menu (void)
              break;
            }
          }
-         
+
          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        }
        break;
-      
+
       /* --------------------------------------------------------------------
        * These functions are invoked directly from the internal-pager
        */
@@ -1854,7 +1877,7 @@ int mutt_index_menu (void)
        if (rc != -1)
        {
          if (option (OPTDELETEUNTAG))
-           mutt_thread_set_flag (CURHDR, M_TAG, 0, 
+           mutt_thread_set_flag (CURHDR, M_TAG, 0,
                                  op == OP_DELETE_THREAD ? 0 : 1);
          if (option (OPTRESOLVE))
            if ((menu->current = ci_next_undeleted (menu->current)) == -1)
@@ -1889,7 +1912,7 @@ int mutt_index_menu (void)
        CHECK_ATTACH;
        CHECK_ACL(M_ACL_INSERT, _("edit message"));
 
-       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))) 
+       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
         mutt_edit_message (Context, tag ? NULL : CURHDR);
        menu->redraw = REDRAW_FULL;
@@ -1901,7 +1924,7 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_ATTACH;
-       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))) 
+       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
        ci_send_message (SENDFORWARD, NULL, NULL, Context, tag ? NULL : CURHDR);
        menu->redraw = REDRAW_FULL;
@@ -1917,7 +1940,7 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_ATTACH;
-       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))) 
+       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
        ci_send_message (SENDREPLY|SENDGROUPREPLY, NULL, NULL, Context, tag ? NULL : CURHDR);
        menu->redraw = REDRAW_FULL;
@@ -1928,7 +1951,7 @@ int mutt_index_menu (void)
        CHECK_ATTACH;
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
-       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))) 
+       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
        ci_send_message (SENDREPLY|SENDLISTREPLY, NULL, NULL, Context, tag ? NULL : CURHDR);
        menu->redraw = REDRAW_FULL;
@@ -1949,7 +1972,7 @@ int mutt_index_menu (void)
        menu->redraw = REDRAW_FULL;
        break;
 
-      
+
       case OP_EXTRACT_KEYS:
         if (!WithCrypto)
           break;
@@ -1963,11 +1986,11 @@ int mutt_index_menu (void)
       case OP_CHECK_TRADITIONAL:
         if (!(WithCrypto & APPLICATION_PGP))
           break;
-        CHECK_MSGCOUNT; 
+        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
-        if (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)) 
+        if (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
-      
+
         if (menu->menu == MENU_PAGER)
         {
          op = OP_DISPLAY_MESSAGE;
@@ -2027,9 +2050,14 @@ int mutt_index_menu (void)
        {
          if (option (OPTRESOLVE))
          {
-           if ((menu->current = (op == OP_MAIN_READ_THREAD ? 
+           if ((menu->current = (op == OP_MAIN_READ_THREAD ?
                                  mutt_next_thread (CURHDR) : mutt_next_subthread (CURHDR))) == -1)
              menu->current = menu->oldcurrent;
+           else if (menu->menu == MENU_PAGER)
+           {
+             op = OP_DISPLAY_MESSAGE;
+             continue;
+           }
          }
          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        }
@@ -2043,11 +2071,11 @@ int mutt_index_menu (void)
        break;
 
       case OP_RESEND:
-      
+
         CHECK_ATTACH;
         CHECK_MSGCOUNT;
         CHECK_VISIBLE;
-      
+
         if (tag)
         {
          for (j = 0; j < Context->vcount; j++)
@@ -2058,16 +2086,16 @@ int mutt_index_menu (void)
        }
         else
          mutt_resend_message (NULL, Context, CURHDR);
-      
+
         menu->redraw = REDRAW_FULL;
         break;
-      
+
       case OP_REPLY:
 
        CHECK_ATTACH;
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
-       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))) 
+       if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
          mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
        ci_send_message (SENDREPLY, NULL, NULL, Context, tag ? NULL : CURHDR);
        menu->redraw = REDRAW_FULL;
@@ -2086,7 +2114,7 @@ int mutt_index_menu (void)
         CHECK_VISIBLE;
        rc = mutt_thread_set_flag (CURHDR, M_TAG, !CURHDR->tagged,
                                   op == OP_TAG_THREAD ? 0 : 1);
-       
+
        if (rc != -1)
        {
          if (option (OPTRESOLVE))
@@ -2109,7 +2137,7 @@ int mutt_index_menu (void)
         CHECK_VISIBLE;
        CHECK_READONLY;
        CHECK_ACL(M_ACL_DELETE, _("undelete message"));
-       
+
        if (tag)
        {
          mutt_tag_set_flag (M_DELETE, 0);
@@ -2207,7 +2235,7 @@ void mutt_set_header_color (CONTEXT *ctx, HEADER *curhdr)
 
   if (!curhdr)
     return;
-  
+
   for (color = ColorIndexList; color; color = color->next)
    if (mutt_pattern_exec (color->color_pattern, M_MATCH_FULL_ADDRESS, ctx, curhdr))
    {