emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/lisp/gnus/gnus-sum.el,v


From: Miles Bader
Subject: [Emacs-diffs] Changes to emacs/lisp/gnus/gnus-sum.el,v
Date: Sun, 28 Oct 2007 09:19:17 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Miles Bader <miles>     07/10/28 09:18:40

Index: lisp/gnus/gnus-sum.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/gnus/gnus-sum.el,v
retrieving revision 1.106
retrieving revision 1.107
diff -u -b -r1.106 -r1.107
--- lisp/gnus/gnus-sum.el       18 Oct 2007 21:07:57 -0000      1.106
+++ lisp/gnus/gnus-sum.el       28 Oct 2007 09:18:31 -0000      1.107
@@ -62,19 +62,31 @@
   :group 'gnus-summary-exit
   :type 'boolean)
 
+(defcustom gnus-summary-next-group-on-exit t
+  "If non-nil, go to the next unread newsgroup on summary exit.
+See `gnus-group-goto-unread'."
+  :link '(custom-manual "(gnus)Group Maneuvering")
+  :group 'gnus-summary-exit
+  :version "23.0" ;; No Gnus
+  :type 'boolean)
+
 (defcustom gnus-fetch-old-headers nil
   "*Non-nil means that Gnus will try to build threads by grabbing old headers.
-If an unread article in the group refers to an older, already read (or
-just marked as read) article, the old article will not normally be
-displayed in the Summary buffer.  If this variable is t, Gnus
-will attempt to grab the headers to the old articles, and thereby
-build complete threads.  If it has the value `some', only enough
-headers to connect otherwise loose threads will be displayed.  This
-variable can also be a number.  In that case, no more than that number
-of old headers will be fetched.  If it has the value `invisible', all
+If an unread article in the group refers to an older, already
+read (or just marked as read) article, the old article will not
+normally be displayed in the Summary buffer.  If this variable is
+t, Gnus will attempt to grab the headers to the old articles, and
+thereby build complete threads.  If it has the value `some', all
+old headers will be fetched but only enough headers to connect
+otherwise loose threads will be displayed.  This variable can
+also be a number.  In that case, no more than that number of old
+headers will be fetched.  If it has the value `invisible', all
 old headers will be fetched, but none will be displayed.
 
-The server has to support NOV for any of this to work."
+The server has to support NOV for any of this to work.
+
+This feature can seriously impact performance it ignores all
+locally cached header entries."
   :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const :tag "on" t)
@@ -83,7 +95,7 @@
                 number
                 (sexp :menu-tag "other" t)))
 
-(defcustom gnus-refer-thread-limit 200
+(defcustom gnus-refer-thread-limit 500
   "*The number of old headers to fetch when doing 
\\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
 If t, fetch all the available old headers."
   :group 'gnus-thread
@@ -366,6 +378,28 @@
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
+(defcustom gnus-auto-select-on-ephemeral-exit 'next-noselect
+  "What article should be selected after exiting an ephemeral group.
+Valid values include:
+
+`next'
+  Select the next article.
+`next-unread'
+  Select the next unread article.
+`next-noselect'
+  Move the cursor to the next article.  This is the default.
+`next-unread-noselect'
+  Move the cursor to the next unread article.
+
+If it has any other value or there is no next (unread) article, the
+article selected before entering to the ephemeral group will appear."
+  :version "23.0" ;; No Gnus
+  :group 'gnus-summary-maneuvering
+  :type '(choice :format "%{%t%}:\n %[Value Menu%] %v"
+                (const next) (const next-unread)
+                (const next-noselect) (const next-unread-noselect)
+                (sexp :tag "other" :value nil)))
+
 (defcustom gnus-auto-goto-ignores 'unfetched
   "*Says how to handle unfetched articles when maneuvering.
 
@@ -391,7 +425,7 @@
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
-(defcustom gnus-auto-center-summary t
+(defcustom gnus-auto-center-summary 2
   "*If non-nil, always center the current summary buffer.
 In particular, if `vertical' do only vertical recentering.  If non-nil
 and non-`vertical', do both horizontal and vertical recentering."
@@ -438,6 +472,13 @@
                         (cons :value ("" "") regexp (repeat string))
                         (sexp :value nil))))
 
+(defcustom gnus-move-group-prefix-function 'gnus-group-real-prefix
+  "Function used to compute default prefix for article move/copy/etc prompts.
+The function should take one argument, a group name, and return a
+string with the suggested prefix."
+  :group 'gnus-summary-mail
+  :type 'function)
+
 ;; FIXME: Although the custom type is `character' for the following variables,
 ;; using multibyte characters (Latin-1, UTF-8) doesn't work.  -- rs
 
@@ -697,6 +738,40 @@
   :group 'gnus-score-default
   :type 'integer)
 
+(defun gnus-widget-reversible-match (widget value)
+  "Ignoring WIDGET, convert VALUE to internal form.
+VALUE should have the form `FOO' or `(not FOO)', where FOO is an symbol."
+  ;; (debug value)
+  (or (symbolp value)
+      (and (listp value)
+           (eq (length value) 2)
+           (eq (nth 0 value) 'not)
+           (symbolp (nth 1 value)))))
+
+(defun gnus-widget-reversible-to-internal (widget value)
+  "Ignoring WIDGET, convert VALUE to internal form.
+VALUE should have the form `FOO' or `(not FOO)', where FOO is an atom.
+FOO is converted to (FOO nil) and (not FOO) is converted to (FOO t)."
+  ;; (debug value)
+  (if (atom value)
+      (list value nil)
+    (list (nth 1 value) t)))
+
+(defun gnus-widget-reversible-to-external (widget value)
+  "Ignoring WIDGET, convert VALUE to external form.
+VALUE should have the form `(FOO nil)' or `(FOO t)', where FOO is an atom.
+\(FOO  nil) is converted to FOO and (FOO t) is converted to (not FOO)."
+  ;; (debug value)
+  (if (nth 1 value)
+      (list 'not (nth 0 value))
+    (nth 0 value)))
+
+(define-widget 'gnus-widget-reversible 'group
+  "A `group' that convert values."
+  :match 'gnus-widget-reversible-match
+  :value-to-internal 'gnus-widget-reversible-to-internal
+  :value-to-external 'gnus-widget-reversible-to-external)
+
 (defcustom gnus-article-sort-functions '(gnus-article-sort-by-number)
   "*List of functions used for sorting articles in the summary buffer.
 
@@ -709,6 +784,9 @@
 very similar.  (Sorting by date means sorting by the time the message
 was sent, sorting by number means sorting by arrival time.)
 
+Each item can also be a list `(not F)' where F is a function;
+this reverses the sort order.
+
 Ready-made functions include `gnus-article-sort-by-number',
 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
 `gnus-article-sort-by-date', `gnus-article-sort-by-random'
@@ -717,13 +795,16 @@
 When threading is turned on, the variable `gnus-thread-sort-functions'
 controls how articles are sorted."
   :group 'gnus-summary-sort
-  :type '(repeat (choice (function-item gnus-article-sort-by-number)
+  :type '(repeat (gnus-widget-reversible
+                  (choice (function-item gnus-article-sort-by-number)
                         (function-item gnus-article-sort-by-author)
                         (function-item gnus-article-sort-by-subject)
                         (function-item gnus-article-sort-by-date)
                         (function-item gnus-article-sort-by-score)
                         (function-item gnus-article-sort-by-random)
-                        (function :tag "other"))))
+                          (function :tag "other"))
+                  (boolean :tag "Reverse order"))))
+
 
 (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
   "*List of functions used for sorting threads in the summary buffer.
@@ -738,25 +819,34 @@
 very similar.  (Sorting by date means sorting by the time the message
 was sent, sorting by number means sorting by arrival time.)
 
+Each list item can also be a list `(not F)' where F is a
+function; this specifies reversed sort order.
+
 Ready-made functions include `gnus-thread-sort-by-number',
-`gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
-`gnus-thread-sort-by-date', `gnus-thread-sort-by-score',
-`gnus-thread-sort-by-most-recent-number',
-`gnus-thread-sort-by-most-recent-date',
-`gnus-thread-sort-by-random', and
-`gnus-thread-sort-by-total-score' (see `gnus-thread-score-function').
+`gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
+`gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
+`gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
+`gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
+and `gnus-thread-sort-by-total-score' (see
+`gnus-thread-score-function').
 
 When threading is turned off, the variable
 `gnus-article-sort-functions' controls how articles are sorted."
   :group 'gnus-summary-sort
-  :type '(repeat (choice (function-item gnus-thread-sort-by-number)
+  :type '(repeat
+          (gnus-widget-reversible
+           (choice (function-item gnus-thread-sort-by-number)
                         (function-item gnus-thread-sort-by-author)
+                   (function-item gnus-thread-sort-by-recipient)
                         (function-item gnus-thread-sort-by-subject)
                         (function-item gnus-thread-sort-by-date)
                         (function-item gnus-thread-sort-by-score)
-                        (function-item gnus-thread-sort-by-total-score)
+                   (function-item gnus-thread-sort-by-most-recent-number)
+                   (function-item gnus-thread-sort-by-most-recent-date)
                         (function-item gnus-thread-sort-by-random)
-                        (function :tag "other"))))
+                   (function-item gnus-thread-sort-by-total-score)
+                   (function :tag "other"))
+           (boolean :tag "Reverse order"))))
 
 (defcustom gnus-thread-score-function '+
   "*Function used for calculating the total score of a thread.
@@ -1016,10 +1106,29 @@
   (and user-mail-address
        (not (string= user-mail-address ""))
        (regexp-quote user-mail-address))
-  "*Regexp of From headers that may be suppressed in favor of To headers."
+  "*From headers that may be suppressed in favor of To headers.
+This can be a regexp or a list of regexps."
   :version "21.1"
   :group 'gnus-summary
-  :type 'regexp)
+  :type '(choice regexp
+                (repeat :tag "Regexp List" regexp)))
+
+(defsubst gnus-ignored-from-addresses ()
+  (gmm-regexp-concat gnus-ignored-from-addresses))
+
+(defcustom gnus-summary-to-prefix "-> "
+  "*String prefixed to the To field in the summary line when
+using `gnus-ignored-from-addresses'."
+  :version "22.1"
+  :group 'gnus-summary
+  :type 'string)
+
+(defcustom gnus-summary-newsgroup-prefix "=> "
+  "*String prefixed to the Newsgroup field in the summary
+line when using `gnus-ignored-from-addresses'."
+  :version "22.1"
+  :group 'gnus-summary
+  :type 'string)
 
 (defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
   "List of charsets that should be ignored.
@@ -1127,12 +1236,12 @@
   :group 'gnus-summary
   :type 'string)
 
-(defcustom gnus-article-loose-mime nil
+(defcustom gnus-article-loose-mime t
   "If non-nil, don't require MIME-Version header.
 Some brain-damaged MUA/MTA, e.g. Lotus Domino 5.0.6 clients, does not
 supply the MIME-Version header or deliberately strip it from the mail.
-Set it to non-nil, Gnus will treat some articles as MIME even if
-the MIME-Version header is missed."
+If non-nil (the default), Gnus will treat some articles as MIME
+even if the MIME-Version header is missing."
   :version "22.1"
   :type 'boolean
   :group 'gnus-article-mime)
@@ -1214,7 +1323,6 @@
     (?\< (make-string (max 0 (- 20 gnus-tmp-level)) ? ) ?s)
     (?i gnus-tmp-score ?d)
     (?z gnus-tmp-score-char ?c)
-    (?l (bbb-grouplens-score gnus-tmp-header) ?s)
     (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d)
     (?U gnus-tmp-unread ?c)
     (?f (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header gnus-tmp-from)
@@ -1463,7 +1571,6 @@
         nil
       (load "gnus-sum.el" t t t))
     (require 'gnus)
-    (require 'gnus-agent)
     (require 'gnus-art)))
 
 ;; MIME stuff.
@@ -1490,19 +1597,15 @@
               (eq gnus-newsgroup-name
                   (car gnus-decode-encoded-word-methods-cache)))
     (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
-    (mapcar (lambda (x)
-             (if (symbolp x)
-                 (nconc gnus-decode-encoded-word-methods-cache (list x))
+    (dolist (method gnus-decode-encoded-word-methods)
+      (if (symbolp method)
+         (nconc gnus-decode-encoded-word-methods-cache (list method))
                (if (and gnus-newsgroup-name
-                        (string-match (car x) gnus-newsgroup-name))
+                (string-match (car method) gnus-newsgroup-name))
                    (nconc gnus-decode-encoded-word-methods-cache
-                          (list (cdr x))))))
-           gnus-decode-encoded-word-methods))
-  (let ((xlist gnus-decode-encoded-word-methods-cache))
-    (pop xlist)
-    (while xlist
-      (setq string (funcall (pop xlist) string))))
-  string)
+                  (list (cdr method)))))))
+  (dolist (method (cdr gnus-decode-encoded-word-methods-cache) string)
+    (setq string (funcall method string))))
 
 ;; Subject simplification.
 
@@ -1574,7 +1677,7 @@
       (setq modified-tick (buffer-modified-tick))
       (cond
        ((listp gnus-simplify-subject-fuzzy-regexp)
-       (mapcar 'gnus-simplify-buffer-fuzzy-step
+       (mapc 'gnus-simplify-buffer-fuzzy-step
                gnus-simplify-subject-fuzzy-regexp))
        (gnus-simplify-subject-fuzzy-regexp
        (gnus-simplify-buffer-fuzzy-step gnus-simplify-subject-fuzzy-regexp)))
@@ -1612,7 +1715,7 @@
    ((eq gnus-summary-gather-subject-limit 'fuzzy)
     (gnus-simplify-subject-fuzzy subject))
    ((numberp gnus-summary-gather-subject-limit)
-    (gnus-limit-string (gnus-simplify-subject-re subject)
+    (truncate-string-to-width (gnus-simplify-subject-re subject)
                       gnus-summary-gather-subject-limit))
    (t
     subject)))
@@ -1665,6 +1768,8 @@
   "," gnus-summary-best-unread-article
   "\M-s" gnus-summary-search-article-forward
   "\M-r" gnus-summary-search-article-backward
+  "\M-S" gnus-summary-repeat-search-article-forward
+  "\M-R" gnus-summary-repeat-search-article-backward
   "<" gnus-summary-beginning-of-article
   ">" gnus-summary-end-of-article
   "j" gnus-summary-goto-article
@@ -1704,6 +1809,7 @@
   "\C-c\C-s\C-l" gnus-summary-sort-by-lines
   "\C-c\C-s\C-c" gnus-summary-sort-by-chars
   "\C-c\C-s\C-a" gnus-summary-sort-by-author
+  "\C-c\C-s\C-t" gnus-summary-sort-by-recipient
   "\C-c\C-s\C-s" gnus-summary-sort-by-subject
   "\C-c\C-s\C-d" gnus-summary-sort-by-date
   "\C-c\C-s\C-i" gnus-summary-sort-by-score
@@ -1795,6 +1901,8 @@
 (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
   "/" gnus-summary-limit-to-subject
   "n" gnus-summary-limit-to-articles
+  "b" gnus-summary-limit-to-bodies
+  "h" gnus-summary-limit-to-headers
   "w" gnus-summary-pop-limit
   "s" gnus-summary-limit-to-subject
   "a" gnus-summary-limit-to-author
@@ -1814,7 +1922,11 @@
   "c" gnus-summary-limit-exclude-childless-dormant
   "C" gnus-summary-limit-mark-excluded-as-read
   "o" gnus-summary-insert-old-articles
-  "N" gnus-summary-insert-new-articles)
+  "N" gnus-summary-insert-new-articles
+  "S" gnus-summary-limit-to-singletons
+  "r" gnus-summary-limit-to-replied
+  "R" gnus-summary-limit-to-recipient
+  "A" gnus-summary-limit-to-address)
 
 (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
   "n" gnus-summary-next-unread-article
@@ -1834,11 +1946,13 @@
 
 (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
   "k" gnus-summary-kill-thread
+  "E" gnus-summary-expire-thread
   "l" gnus-summary-lower-thread
   "i" gnus-summary-raise-thread
   "T" gnus-summary-toggle-threads
   "t" gnus-summary-rethread-current
   "^" gnus-summary-reparent-thread
+  "\M-^" gnus-summary-reparent-children
   "s" gnus-summary-show-thread
   "S" gnus-summary-show-all-threads
   "h" gnus-summary-hide-thread
@@ -1854,7 +1968,8 @@
 (gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
   "g" gnus-summary-prepare
   "c" gnus-summary-insert-cached-articles
-  "d" gnus-summary-insert-dormant-articles)
+  "d" gnus-summary-insert-dormant-articles
+  "t" gnus-summary-insert-ticked-articles)
 
 (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
   "c" gnus-summary-catchup-and-exit
@@ -1863,6 +1978,7 @@
   "Q" gnus-summary-exit
   "Z" gnus-summary-exit
   "n" gnus-summary-catchup-and-goto-next-group
+  "p" gnus-summary-catchup-and-goto-prev-group
   "R" gnus-summary-reselect-current-group
   "G" gnus-summary-rescan-group
   "N" gnus-summary-next-group
@@ -1889,6 +2005,7 @@
   "g" gnus-summary-show-article
   "s" gnus-summary-isearch-article
   "P" gnus-summary-print-article
+  "S" gnus-sticky-article
   "M" gnus-mailing-list-insinuate
   "t" gnus-article-babel)
 
@@ -1899,11 +2016,13 @@
   "e" gnus-article-emphasize
   "w" gnus-article-fill-cited-article
   "Q" gnus-article-fill-long-lines
+  "L" gnus-article-toggle-truncate-lines
   "C" gnus-article-capitalize-sentences
   "c" gnus-article-remove-cr
   "q" gnus-article-de-quoted-unreadable
   "6" gnus-article-de-base64-unreadable
   "Z" gnus-article-decode-HZ
+  "A" gnus-article-treat-ansi-sequences
   "h" gnus-article-wash-html
   "u" gnus-article-unsplit-urls
   "s" gnus-summary-force-verify-and-decrypt
@@ -1916,7 +2035,8 @@
   "v" gnus-summary-verbose-headers
   "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
   "p" gnus-article-verify-x-pgp-sig
-  "d" gnus-article-treat-dumbquotes)
+  "d" gnus-article-treat-dumbquotes
+  "i" gnus-summary-idna-message)
 
 (gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
   ;; mnemonic: deuglif*Y*
@@ -2028,9 +2148,15 @@
   "m" gnus-summary-repair-multipart
   "v" gnus-article-view-part
   "o" gnus-article-save-part
+  "O" gnus-article-save-part-and-strip
+  "r" gnus-article-replace-part
+  "d" gnus-article-delete-part
+  "t" gnus-article-view-part-as-type
+  "j" gnus-article-jump-to-part
   "c" gnus-article-copy-part
   "C" gnus-article-view-part-as-charset
   "e" gnus-article-view-part-externally
+  "H" gnus-article-browse-html-article
   "E" gnus-article-encrypt-body
   "i" gnus-article-inline-part
   "|" gnus-article-pipe-part)
@@ -2174,11 +2300,13 @@
               ["Repair multipart" gnus-summary-repair-multipart t]
               ["Pipe part..." gnus-article-pipe-part t]
               ["Inline part" gnus-article-inline-part t]
+              ["View part as type..." gnus-article-view-part-as-type t]
               ["Encrypt body" gnus-article-encrypt-body
                :active (not (gnus-group-read-only-p))
               ,@(if (featurep 'xemacs) nil
                   '(:help "Encrypt the message body on disk"))]
               ["View part externally" gnus-article-view-part-externally t]
+              ["View HTML parts in browser" gnus-article-browse-html-article t]
               ["View part with charset..." gnus-article-view-part-as-charset t]
               ["Copy part" gnus-article-copy-part t]
               ["Save part..." gnus-article-save-part t]
@@ -2233,6 +2361,7 @@
              ["Emphasis" gnus-article-emphasize t]
              ["Word wrap" gnus-article-fill-cited-article t]
              ["Fill long lines" gnus-article-fill-long-lines t]
+             ["Toggle truncate long lines" gnus-article-toggle-truncate-lines 
t]
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
              ["Remove CR" gnus-article-remove-cr t]
              ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
@@ -2240,6 +2369,7 @@
              ["Rot 13" gnus-summary-caesar-message
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "\"Caesar rotate\" article by 13"))]
+             ["De-IDNA" gnus-summary-idna-message t]
              ["Morse decode" gnus-summary-morse-message t]
              ["Unix pipe..." gnus-summary-pipe-message t]
              ["Add buttons" gnus-article-add-buttons t]
@@ -2253,6 +2383,7 @@
              ["Unsplit URLs" gnus-article-unsplit-urls t]
              ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["Decode HZ" gnus-article-decode-HZ t]
+             ["ANSI sequences" gnus-article-treat-ansi-sequences t]
              ("(Outlook) Deuglify"
               ["Unwrap lines" gnus-article-outlook-unwrap-lines t]
               ["Repair attribution" gnus-article-outlook-repair-attribution t]
@@ -2322,6 +2453,7 @@
              ["Remove article" gnus-cache-remove-article t])
             ["Translate" gnus-article-babel t]
             ["Select article buffer" gnus-summary-select-article-buffer t]
+            ["Make article buffer sticky" gnus-sticky-article t]
             ["Enter digest buffer" gnus-summary-enter-digest-group t]
             ["Isearch article..." gnus-summary-isearch-article t]
             ["Beginning of the article" gnus-summary-beginning-of-article t]
@@ -2362,6 +2494,7 @@
        ["Go up thread" gnus-summary-up-thread t]
        ["Top of thread" gnus-summary-top-thread t]
        ["Mark thread as read" gnus-summary-kill-thread t]
+       ["Mark thread as expired" gnus-summary-expire-thread t]
        ["Lower thread score" gnus-summary-lower-thread t]
        ["Raise thread score" gnus-summary-raise-thread t]
        ["Rethread current" gnus-summary-rethread-current t]))
@@ -2450,12 +2583,16 @@
         ["Marks..." gnus-summary-limit-to-marks t]
         ["Subject..." gnus-summary-limit-to-subject t]
         ["Author..." gnus-summary-limit-to-author t]
+        ["Recipient..." gnus-summary-limit-to-recipient t]
+        ["Address..." gnus-summary-limit-to-address t]
         ["Age..." gnus-summary-limit-to-age t]
         ["Extra..." gnus-summary-limit-to-extra t]
         ["Score..." gnus-summary-limit-to-score t]
         ["Display Predicate" gnus-summary-limit-to-display-predicate t]
         ["Unread" gnus-summary-limit-to-unread t]
         ["Unseen" gnus-summary-limit-to-unseen t]
+        ["Singletons" gnus-summary-limit-to-singletons t]
+        ["Replied" gnus-summary-limit-to-replied t]
         ["Non-dormant" gnus-summary-limit-exclude-dormant t]
         ["Next or process marked articles" gnus-summary-limit-to-articles t]
         ["Pop limit" gnus-summary-pop-limit t]
@@ -2469,6 +2606,7 @@
         ["Set mark" gnus-summary-mark-as-processable t]
         ["Remove mark" gnus-summary-unmark-as-processable t]
         ["Remove all marks" gnus-summary-unmark-all-processable t]
+        ["Invert marks" gnus-uu-invert-processable t]
         ["Mark above" gnus-uu-mark-over t]
         ["Mark series" gnus-uu-mark-series t]
         ["Mark region" gnus-uu-mark-region (gnus-mark-active-p)]
@@ -2512,6 +2650,7 @@
        ("Sort"
         ["Sort by number" gnus-summary-sort-by-number t]
         ["Sort by author" gnus-summary-sort-by-author t]
+        ["Sort by recipient" gnus-summary-sort-by-recipient t]
         ["Sort by subject" gnus-summary-sort-by-subject t]
         ["Sort by date" gnus-summary-sort-by-date t]
         ["Sort by score" gnus-summary-sort-by-score t]
@@ -2536,6 +2675,7 @@
         ["Regenerate" gnus-summary-prepare t]
         ["Insert cached articles" gnus-summary-insert-cached-articles t]
         ["Insert dormant articles" gnus-summary-insert-dormant-articles t]
+        ["Insert ticked articles" gnus-summary-insert-ticked-articles t]
         ["Toggle threading" gnus-summary-toggle-threads t])
        ["See old articles" gnus-summary-insert-old-articles t]
        ["See new articles" gnus-summary-insert-new-articles t]
@@ -2559,6 +2699,7 @@
              '(:help "Mark unread articles in this group as read, then exit"))]
         ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
         ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
+        ["Catchup and goto prev" gnus-summary-catchup-and-goto-prev-group t]
         ["Exit group" gnus-summary-exit
          ,@(if (featurep 'xemacs) '(t)
              '(:help "Exit current group, return to group selection mode"))]
@@ -2602,7 +2743,7 @@
                 (const :tag "Retro look"  gnus-summary-tool-bar-retro)
                 (repeat :tag "User defined list" gmm-tool-bar-item)
                 (symbol))
-  :version "22.1" ;; Gnus 5.10.9
+  :version "23.0" ;; No Gnus
   :initialize 'custom-initialize-default
   :set 'gnus-summary-tool-bar-update
   :group 'gnus-summary)
@@ -2653,7 +2794,7 @@
 
 See `gmm-tool-bar-from-list' for the format of the list."
   :type '(repeat gmm-tool-bar-item)
-  :version "22.1" ;; Gnus 5.10.9
+  :version "23.0" ;; No Gnus
   :initialize 'custom-initialize-default
   :set 'gnus-summary-tool-bar-update
   :group 'gnus-summary)
@@ -2688,7 +2829,7 @@
 
 See `gmm-tool-bar-from-list' for the format of the list."
   :type '(repeat gmm-tool-bar-item)
-  :version "22.1" ;; Gnus 5.10.9
+  :version "23.0" ;; No Gnus
   :initialize 'custom-initialize-default
   :set 'gnus-summary-tool-bar-update
   :group 'gnus-summary)
@@ -2699,7 +2840,7 @@
 
 See `gmm-tool-bar-from-list' for the format of the list."
   :type 'gmm-tool-bar-zap-list
-  :version "22.1" ;; Gnus 5.10.9
+  :version "23.0" ;; No Gnus
   :initialize 'custom-initialize-default
   :set 'gnus-summary-tool-bar-update
   :group 'gnus-summary)
@@ -2838,12 +2979,13 @@
 \\{gnus-summary-mode-map}"
   (interactive)
   (kill-all-local-variables)
+  (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+    (gnus-summary-make-local-variables))
+  (gnus-summary-make-local-variables)
+  (setq gnus-newsgroup-name group)
   (when (gnus-visual-p 'summary-menu 'menu)
     (gnus-summary-make-menu-bar)
     (gnus-summary-make-tool-bar))
-  (gnus-summary-make-local-variables)
-  (let ((gnus-summary-local-variables gnus-newsgroup-variables))
-    (gnus-summary-make-local-variables))
   (gnus-make-thread-indent-array)
   (gnus-simplify-mode-line)
   (setq major-mode 'gnus-summary-mode)
@@ -2851,13 +2993,13 @@
   (make-local-variable 'minor-mode-alist)
   (use-local-map gnus-summary-mode-map)
   (buffer-disable-undo)
-  (setq buffer-read-only t)            ;Disable modification
+  (setq buffer-read-only t             ;Disable modification
+       show-trailing-whitespace nil)
   (setq truncate-lines t)
   (setq selective-display t)
   (setq selective-display-ellipses t)  ;Display `...'
   (gnus-summary-set-display-table)
   (gnus-set-default-directory)
-  (setq gnus-newsgroup-name group)
   (make-local-variable 'gnus-summary-line-format)
   (make-local-variable 'gnus-summary-line-format-spec)
   (make-local-variable 'gnus-summary-dummy-line-format)
@@ -2890,9 +3032,9 @@
   (let ((locals gnus-summary-local-variables))
     (while locals
       (if (consp (car locals))
-         (and (vectorp (caar locals))
+         (and (symbolp (caar locals))
               (set (caar locals) nil))
-       (and (vectorp (car locals))
+       (and (symbolp (car locals))
             (set (car locals) nil)))
       (setq locals (cdr locals)))))
 
@@ -2966,8 +3108,7 @@
              (gnus-data-update-list odata offset)))
       ;; Find the last element in the list to be spliced into the main
        ;; list.
-       (while (cdr list)
-         (setq list (cdr list)))
+       (setq list (last list))
        (if (not data)
            (progn
              (setcdr list gnus-newsgroup-data)
@@ -3283,10 +3424,11 @@
       (gnus-summary-mode group)
       (when gnus-carpal
        (gnus-carpal-setup-buffer 'summary))
-      (unless gnus-single-article-buffer
+      (when (gnus-group-quit-config group)
+       (set (make-local-variable 'gnus-single-article-buffer) nil))
        (make-local-variable 'gnus-article-buffer)
        (make-local-variable 'gnus-article-current)
-       (make-local-variable 'gnus-original-article-buffer))
+      (make-local-variable 'gnus-original-article-buffer)
       (setq gnus-newsgroup-name group)
       ;; Set any local variables in the group parameters.
       (gnus-summary-set-local-parameters gnus-newsgroup-name)
@@ -3319,8 +3461,7 @@
            (push (eval (car locals)) vlist))
          (setq locals (cdr locals)))
        (setq vlist (nreverse vlist)))
-      (save-excursion
-       (set-buffer gnus-group-buffer)
+      (with-current-buffer gnus-group-buffer
        (setq gnus-newsgroup-name name
              gnus-newsgroup-marked marked
              gnus-newsgroup-spam-marked spam
@@ -3444,25 +3585,33 @@
 
 (defun gnus-summary-from-or-to-or-newsgroups (header gnus-tmp-from)
   (let ((mail-parse-charset gnus-newsgroup-charset)
+       (ignored-from-addresses (gnus-ignored-from-addresses))
        ; Is it really necessary to do this next part for each summary line?
        ; Luckily, doesn't seem to slow things down much.
        (mail-parse-ignored-charsets
-        (save-excursion (set-buffer gnus-summary-buffer)
+        (with-current-buffer gnus-summary-buffer
                         gnus-newsgroup-ignored-charsets)))
     (or
-     (and gnus-ignored-from-addresses
-         (string-match gnus-ignored-from-addresses gnus-tmp-from)
+     (and ignored-from-addresses
+         (string-match ignored-from-addresses gnus-tmp-from)
          (let ((extra-headers (mail-header-extra header))
                to
                newsgroups)
            (cond
             ((setq to (cdr (assq 'To extra-headers)))
-             (concat "-> "
+             (concat gnus-summary-to-prefix
                      (inline
                        (gnus-summary-extract-address-component
                         (funcall gnus-decode-encoded-address-function to)))))
-            ((setq newsgroups (cdr (assq 'Newsgroups extra-headers)))
-             (concat "=> " newsgroups)))))
+            ((setq newsgroups
+                   (or
+                    (cdr (assq 'Newsgroups extra-headers))
+                    (and
+                     (memq 'Newsgroups gnus-extra-headers)
+                      (eq (car (gnus-find-method-for-group
+                                gnus-newsgroup-name)) 'nntp)
+                     (gnus-group-real-name gnus-newsgroup-name))))
+             (concat gnus-summary-newsgroup-prefix newsgroups)))))
      (inline (gnus-summary-extract-address-component gnus-tmp-from)))))
 
 (defun gnus-summary-insert-line (gnus-tmp-header
@@ -3613,12 +3762,8 @@
 
 (defun gnus-summary-set-local-parameters (group)
   "Go through the local params of GROUP and set all variable specs in that 
list."
-  (let ((params (gnus-group-find-parameter group))
-       (vars '(quit-config))           ; Ignore quit-config.
-       elem)
-    (while params
-      (setq elem (car params)
-           params (cdr params))
+  (let ((vars '(quit-config)))          ; Ignore quit-config.
+    (dolist (elem (gnus-group-find-parameter group))
       (and (consp elem)                        ; Has to be a cons.
           (consp (cdr elem))           ; The cdr has to be a list.
           (symbolp (car elem))         ; Has to be a symbol in there.
@@ -4140,8 +4285,7 @@
          (erase-buffer)))
       (kill-buffer (current-buffer)))
     ;; Sort over trustworthiness.
-    (mapcar
-     (lambda (relation)
+    (dolist (relation (sort relations 'car-less-than-car))
        (when (gnus-dependencies-add-header
              (make-full-mail-header
               gnus-reffed-article-number
@@ -4154,7 +4298,6 @@
         (push (cons gnus-reffed-article-number gnus-sparse-mark)
               gnus-newsgroup-reads)
         (decf gnus-reffed-article-number)))
-     (sort relations 'car-less-than-car))
     (gnus-message 7 "Making sparse threads...done")))
 
 (defun gnus-build-old-threads ()
@@ -4182,13 +4325,12 @@
   "Translate STRING into something that doesn't contain weird characters."
   (mm-subst-char-in-string
    ?\r ?\-
-   (mm-subst-char-in-string
-    ?\n ?\- string)))
+   (mm-subst-char-in-string ?\n ?\- string t) t))
 
 ;; This function has to be called with point after the article number
 ;; on the beginning of the line.
 (defsubst gnus-nov-parse-line (number dependencies &optional force-new)
-  (let ((eol (gnus-point-at-eol))
+  (let ((eol (point-at-eol))
        (buffer (current-buffer))
        header references in-reply-to)
 
@@ -4213,7 +4355,7 @@
                               (setq x (nnheader-nov-field))))
                   (error x))
                 (nnheader-nov-field)   ; date
-                (nnheader-nov-read-message-id) ; id
+                (nnheader-nov-read-message-id number)  ; id
                 (setq references (nnheader-nov-field)) ; refs
                 (nnheader-nov-read-integer) ; chars
                 (nnheader-nov-read-integer) ; lines
@@ -4287,8 +4429,7 @@
            (setq article (read (current-buffer))
                  header (gnus-nov-parse-line article dependencies)))
          (when header
-           (save-excursion
-             (set-buffer gnus-summary-buffer)
+           (with-current-buffer gnus-summary-buffer
              (push header gnus-newsgroup-headers)
              (if (memq (setq article (mail-header-number header))
                        gnus-newsgroup-unselected)
@@ -4385,7 +4526,7 @@
        (setq thread (list (car (gnus-id-to-thread id))))
       ;; Get the thread this article is part of.
       (setq thread (gnus-remove-thread id)))
-    (setq old-pos (gnus-point-at-bol))
+    (setq old-pos (point-at-bol))
     (setq current (save-excursion
                    (and (re-search-backward "[\r\n]" nil t)
                         (gnus-summary-article-number))))
@@ -4567,9 +4708,9 @@
       (gnus-summary-show-thread)
       (gnus-data-remove
        number
-       (- (gnus-point-at-bol)
+       (- (point-at-bol)
          (prog1
-             (1+ (gnus-point-at-eol))
+             (1+ (point-at-eol))
            (gnus-delete-line)))))))
 
 (defun gnus-sort-threads-recursive (threads func)
@@ -4689,6 +4830,23 @@
   (gnus-article-sort-by-author
    (gnus-thread-header h1)  (gnus-thread-header h2)))
 
+(defsubst gnus-article-sort-by-recipient (h1 h2)
+  "Sort articles by recipient."
+  (gnus-string<
+   (let ((extract (funcall
+                  gnus-extract-address-components
+                  (or (cdr (assq 'To (mail-header-extra h1))) ""))))
+     (or (car extract) (cadr extract)))
+   (let ((extract (funcall
+                  gnus-extract-address-components
+                  (or (cdr (assq 'To (mail-header-extra h2))) ""))))
+     (or (car extract) (cadr extract)))))
+
+(defun gnus-thread-sort-by-recipient (h1 h2)
+  "Sort threads by root recipient."
+  (gnus-article-sort-by-recipient
+   (gnus-thread-header h1) (gnus-thread-header h2)))
+
 (defsubst gnus-article-sort-by-subject (h1 h2)
   "Sort articles by root subject."
   (gnus-string<
@@ -4809,33 +4967,39 @@
   :version "22.1"
   :type '(radio (const :format "%v  " nil) string)
   :group 'gnus-thread)
+
 (defcustom gnus-sum-thread-tree-false-root "> "
   "With %B spec, used for a false root of a thread.
 If nil, use subject instead."
   :version "22.1"
   :type '(radio (const :format "%v  " nil) string)
   :group 'gnus-thread)
+
 (defcustom gnus-sum-thread-tree-single-indent ""
   "With %B spec, used for a thread with just one message.
 If nil, use subject instead."
   :version "22.1"
   :type '(radio (const :format "%v  " nil) string)
   :group 'gnus-thread)
+
 (defcustom gnus-sum-thread-tree-vertical "| "
   "With %B spec, used for drawing a vertical line."
   :version "22.1"
   :type 'string
   :group 'gnus-thread)
+
 (defcustom gnus-sum-thread-tree-indent "  "
   "With %B spec, used for indenting."
   :version "22.1"
   :type 'string
   :group 'gnus-thread)
+
 (defcustom gnus-sum-thread-tree-leaf-with-other "+-> "
   "With %B spec, used for a leaf with brothers."
   :version "22.1"
   :type 'string
   :group 'gnus-thread)
+
 (defcustom gnus-sum-thread-tree-single-leaf "\\-> "
   "With %B spec, used for a leaf without brothers."
   :version "22.1"
@@ -5194,23 +5358,20 @@
                  gnus-list-identifiers))
        changed subject)
     (when regexp
+      (setq regexp (concat "^\\(?:R[Ee]: +\\)*\\(" regexp " *\\)"))
       (dolist (header gnus-newsgroup-headers)
        (setq subject (mail-header-subject header)
              changed nil)
-       (while (string-match
-               (concat "^\\(R[Ee]: +\\)*\\(" regexp " *\\)")
-               subject)
+       (while (string-match regexp subject)
          (setq subject
-               (concat (substring subject 0 (match-beginning 2))
+               (concat (substring subject 0 (match-beginning 1))
                        (substring subject (match-end 0)))
                changed t))
-       (when (and changed
-                  (string-match
-                   "^\\(\\(R[Ee]: +\\)+\\)R[Ee]: +" subject))
+       (when changed
+         (when (string-match "^\\(\\(?:R[Ee]: +\\)+\\)R[Ee]: +" subject)
          (setq subject
                (concat (substring subject 0 (match-beginning 1))
                        (substring subject (match-end 1)))))
-       (when changed
          (mail-header-set-subject header subject))))))
 
 (defun gnus-fetch-headers (articles)
@@ -5238,33 +5399,37 @@
   "Select newsgroup GROUP.
 If READ-ALL is non-nil, all articles in the group are selected.
 If SELECT-ARTICLES, only select those articles from GROUP."
-  (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
+  (let* ((entry (gnus-group-entry group))
         ;;!!! Dirty hack; should be removed.
         (gnus-summary-ignore-duplicates
          (if (eq (car (gnus-find-method-for-group group)) 'nnvirtual)
              t
            gnus-summary-ignore-duplicates))
         (info (nth 2 entry))
-        articles fetched-articles cached)
+        charset articles fetched-articles cached)
 
     (unless (gnus-check-server
             (set (make-local-variable 'gnus-current-select-method)
                  (gnus-find-method-for-group group)))
       (error "Couldn't open server"))
+    (setq charset (gnus-group-name-charset gnus-current-select-method group))
 
     (or (and entry (not (eq (car entry) t))) ; Either it's active...
        (gnus-activate-group group)     ; Or we can activate it...
        (progn                          ; Or we bug out.
          (when (equal major-mode 'gnus-summary-mode)
            (gnus-kill-buffer (current-buffer)))
-         (error "Couldn't activate group %s: %s"
-                (gnus-group-decoded-name group) (gnus-status-message group))))
+         (error
+          "Couldn't activate group %s: %s"
+          (mm-decode-coding-string group charset)
+          (mm-decode-coding-string (gnus-status-message group) charset))))
 
     (unless (gnus-request-group group t)
       (when (equal major-mode 'gnus-summary-mode)
        (gnus-kill-buffer (current-buffer)))
       (error "Couldn't request group %s: %s"
-            (gnus-group-decoded-name group) (gnus-status-message group)))
+              (mm-decode-coding-string group charset)
+              (mm-decode-coding-string (gnus-status-message group) charset)))
 
     (when gnus-agent
       (gnus-agent-possibly-alter-active group (gnus-active group) info)
@@ -5387,7 +5552,8 @@
       (setq gnus-newsgroup-auto-expire
            (gnus-group-auto-expirable-p group))
       ;; Set up the article buffer now, if necessary.
-      (unless gnus-single-article-buffer
+      (unless (and gnus-single-article-buffer
+                  (equal gnus-article-buffer "*Article*"))
        (gnus-article-setup-buffer))
       ;; First and last article in this newsgroup.
       (when gnus-newsgroup-headers
@@ -5521,9 +5687,7 @@
                          (read-string
                           (format
                            "How many articles from %s (%s %d): "
-                           (gnus-limit-string
                             (gnus-group-decoded-name gnus-newsgroup-name)
-                            35)
                            (if initial "max" "default")
                            number)
                           (if initial
@@ -5849,7 +6013,7 @@
 (defun gnus-mark-xrefs-as-read (from-newsgroup headers unreads)
   "Look through all the headers and mark the Xrefs as read."
   (let ((virtual (gnus-virtual-group-p from-newsgroup))
-       name entry info xref-hashtb idlist method nth4)
+       name info xref-hashtb idlist method nth4)
     (save-excursion
       (set-buffer gnus-group-buffer)
       (when (setq xref-hashtb
@@ -5860,8 +6024,7 @@
             (setq idlist (symbol-value group))
             ;; Dead groups are not updated.
             (and (prog1
-                     (setq entry (gnus-gethash name gnus-newsrc-hashtb)
-                           info (nth 2 entry))
+                     (setq info (gnus-get-info name))
                    (when (stringp (setq nth4 (gnus-info-method info)))
                      (setq nth4 (gnus-server-to-method nth4))))
                  ;; Only do the xrefs if the group has the same
@@ -5883,7 +6046,7 @@
         xref-hashtb)))))
 
 (defun gnus-compute-read-articles (group articles)
-  (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
+  (let* ((entry (gnus-group-entry group))
         (info (nth 2 entry))
         (active (gnus-active group))
         ninfo)
@@ -5920,14 +6083,13 @@
 (defun gnus-group-make-articles-read (group articles)
   "Update the info of GROUP to say that ARTICLES are read."
   (let* ((num 0)
-        (entry (gnus-gethash group gnus-newsrc-hashtb))
+        (entry (gnus-group-entry group))
         (info (nth 2 entry))
         (active (gnus-active group))
         range)
     (when entry
       (setq range (gnus-compute-read-articles group articles))
-      (save-excursion
-       (set-buffer gnus-group-buffer)
+      (with-current-buffer gnus-group-buffer
        (gnus-undo-register
          `(progn
             (gnus-info-set-marks ',info ',(gnus-info-marks info) t)
@@ -5966,9 +6128,9 @@
   (let ((cur nntp-server-buffer)
        (dependencies
         (or dependencies
-            (save-excursion (set-buffer gnus-summary-buffer)
+            (with-current-buffer gnus-summary-buffer
                             gnus-newsgroup-dependencies)))
-       headers id end ref
+       headers id end ref number
        (mail-parse-charset gnus-newsgroup-charset)
        (mail-parse-ignored-charsets
         (save-excursion (condition-case nil
@@ -6001,7 +6163,7 @@
           (vector
            ;; Number.
            (prog1
-               (read cur)
+               (setq number (read cur))
              (end-of-line)
              (setq p (point))
              (narrow-to-region (point)
@@ -6038,7 +6200,7 @@
                                             (match-end 1))
                         ;; If there was no message-id, we just fake one
                         ;; to make subsequent routines simpler.
-                        (nnheader-generate-fake-message-id))))
+                        (nnheader-generate-fake-message-id number))))
            ;; References.
            (progn
              (goto-char p)
@@ -6185,7 +6347,7 @@
 (defun gnus-article-get-xrefs ()
   "Fill in the Xref value in `gnus-current-headers', if necessary.
 This is meant to be called in `gnus-article-internal-prepare-hook'."
-  (let ((headers (save-excursion (set-buffer gnus-summary-buffer)
+  (let ((headers (with-current-buffer gnus-summary-buffer
                                 gnus-current-headers)))
     (or (not gnus-use-cross-reference)
        (not headers)
@@ -6201,7 +6363,7 @@
                           (looking-at "Xref:"))
                      (search-forward "\nXref:" nil t))
              (goto-char (1+ (match-end 0)))
-             (setq xref (buffer-substring (point) (gnus-point-at-eol)))
+             (setq xref (buffer-substring (point) (point-at-eol)))
              (mail-header-set-xref headers xref)))))))
 
 (defun gnus-summary-insert-subject (id &optional old-header use-old-header)
@@ -6229,9 +6391,9 @@
          (goto-char (gnus-data-pos d))
          (gnus-data-remove
           number
-          (- (gnus-point-at-bol)
+          (- (point-at-bol)
              (prog1
-                 (1+ (gnus-point-at-eol))
+                 (1+ (point-at-eol))
                (gnus-delete-line))))))
       ;; Remove list identifiers from subject.
       (when gnus-list-identifiers
@@ -6345,8 +6507,7 @@
 (defun gnus-summary-process-mark-set (set)
   "Make SET into the current process marked articles."
   (gnus-summary-unmark-all-processable)
-  (while set
-    (gnus-summary-set-process-mark (pop set))))
+  (mapc 'gnus-summary-set-process-mark set))
 
 ;;; Searching and stuff
 
@@ -6362,8 +6523,7 @@
 (defun gnus-summary-best-group (&optional exclude-group)
   "Find the name of the best unread group.
 If EXCLUDE-GROUP, do not go to this group."
-  (save-excursion
-    (set-buffer gnus-group-buffer)
+  (with-current-buffer gnus-group-buffer
     (save-excursion
       (gnus-group-best-unread-group exclude-group))))
 
@@ -6494,7 +6654,7 @@
                      ((< (window-height) 7) 1)
                      (t (if (numberp gnus-auto-center-summary)
                             gnus-auto-center-summary
-                          2))))
+                           (/ (1- (window-height)) 2)))))
           (height (1- (window-height)))
           (bottom (save-excursion (goto-char (point-max))
                                   (forward-line (- height))
@@ -6508,7 +6668,7 @@
        (let ((top-pos (save-excursion (forward-line (- top)) (point))))
          (if (> bottom top-pos)
              ;; Keep the second line from the top visible
-             (set-window-start window top-pos t)
+             (set-window-start window top-pos)
            ;; Try to keep the bottom line visible; if it's partially
            ;; obscured, either scroll one more line to make it fully
            ;; visible, or revert to using TOP-POS.
@@ -6552,7 +6712,8 @@
 (defun gnus-list-of-unread-articles (group)
   (let* ((read (gnus-info-read (gnus-get-info group)))
         (active (or (gnus-active group) (gnus-activate-group group)))
-        (last (cdr active))
+        (last (or (cdr active)
+                  (error "Group %s couldn't be activated " group)))
         (bottom (if gnus-newsgroup-maximum-articles
                     (max (car active)
                          (- last gnus-newsgroup-maximum-articles -1))
@@ -6752,8 +6913,7 @@
          (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
        (let ((headers gnus-newsgroup-headers))
          ;; Set the new ranges of read articles.
-         (save-excursion
-           (set-buffer gnus-group-buffer)
+         (with-current-buffer gnus-group-buffer
            (gnus-undo-force-boundary))
          (gnus-update-read-articles
           group (gnus-sorted-union
@@ -6813,8 +6973,13 @@
     (gnus-run-hooks 'gnus-summary-prepare-exit-hook)
     ;; If we have several article buffers, we kill them at exit.
     (unless gnus-single-article-buffer
-      (gnus-kill-buffer gnus-original-article-buffer)
-      (setq gnus-article-current nil))
+      (when (gnus-buffer-live-p gnus-article-buffer)
+       (with-current-buffer gnus-article-buffer
+         ;; Don't kill sticky article buffers
+         (unless (eq major-mode 'gnus-sticky-article-mode)
+           (gnus-kill-buffer gnus-article-buffer)
+           (setq gnus-article-current nil))))
+      (gnus-kill-buffer gnus-original-article-buffer))
     (when gnus-use-cache
       (gnus-cache-possibly-remove-articles)
       (gnus-cache-save-buffers))
@@ -6838,6 +7003,7 @@
       (gnus-group-jump-to-group group))
     (gnus-run-hooks 'gnus-summary-exit-hook)
     (unless (or quit-config
+               (not gnus-summary-next-group-on-exit)
                ;; If this group has disappeared from the summary
                ;; buffer, don't skip forwards.
                (not (string= group (gnus-group-group-name))))
@@ -6845,11 +7011,6 @@
     (setq group-point (point))
     (if temporary
        nil                             ;Nothing to do.
-      ;; If we have several article buffers, we kill them at exit.
-      (unless gnus-single-article-buffer
-       (gnus-kill-buffer gnus-article-buffer)
-       (gnus-kill-buffer gnus-original-article-buffer)
-       (setq gnus-article-current nil))
       (set-buffer buf)
       (if (not gnus-kill-summary-on-exit)
          (progn
@@ -6864,12 +7025,6 @@
          (gnus-summary-clear-local-variables))
        (when (get-buffer gnus-article-buffer)
          (bury-buffer gnus-article-buffer))
-       ;; We clear the global counterparts of the buffer-local
-       ;; variables as well, just to be on the safe side.
-       (set-buffer gnus-group-buffer)
-       (gnus-summary-clear-local-variables)
-       (let ((gnus-summary-local-variables gnus-newsgroup-variables))
-         (gnus-summary-clear-local-variables))
        ;; Return to group mode buffer.
        (when (eq mode 'gnus-summary-mode)
          (gnus-kill-buffer buf)))
@@ -6919,10 +7074,6 @@
        (gnus-summary-clear-local-variables)
        (let ((gnus-summary-local-variables gnus-newsgroup-variables))
          (gnus-summary-clear-local-variables))
-       (set-buffer gnus-group-buffer)
-       (gnus-summary-clear-local-variables)
-       (let ((gnus-summary-local-variables gnus-newsgroup-variables))
-         (gnus-summary-clear-local-variables))
        (gnus-kill-buffer gnus-summary-buffer))
       (unless gnus-single-article-buffer
        (setq gnus-article-current nil))
@@ -6961,19 +7112,26 @@
             (gnus-set-global-variables))))
     (if (or (eq (cdr quit-config) 'article)
            (eq (cdr quit-config) 'pick))
-       (progn
-         ;; The current article may be from the ephemeral group
-         ;; thus it is best that we reload this article
-         ;;
-         ;; If we're exiting from a large digest, this can be
-         ;; extremely slow.  So, it's better not to reload it. -- jh.
-         ;;(gnus-summary-show-article)
          (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode))
              (gnus-configure-windows 'pick 'force)
-           (gnus-configure-windows (cdr quit-config) 'force)))
+         (gnus-configure-windows (cdr quit-config) 'force))
       (gnus-configure-windows (cdr quit-config) 'force))
     (when (eq major-mode 'gnus-summary-mode)
-      (gnus-summary-next-subject 1 nil t)
+      (if (memq gnus-auto-select-on-ephemeral-exit '(next-noselect
+                                                    next-unread-noselect))
+         (when (zerop (cond ((eq gnus-auto-select-on-ephemeral-exit
+                                 'next-noselect)
+                             (gnus-summary-next-subject 1 nil t))
+                            ((eq gnus-auto-select-on-ephemeral-exit
+                                 'next-unread-noselect)
+                             (gnus-summary-next-subject 1 t t))))
+           ;; Hide the article buffer which displays the article different
+           ;; from the one that the cursor points to in the summary buffer.
+           (gnus-configure-windows 'summary 'force))
+       (cond ((eq gnus-auto-select-on-ephemeral-exit 'next)
+              (gnus-summary-next-subject 1))
+             ((eq gnus-auto-select-on-ephemeral-exit 'next-unread)
+              (gnus-summary-next-subject 1 t))))
       (gnus-summary-recenter)
       (gnus-summary-position-point))))
 
@@ -7004,7 +7162,7 @@
          (if (null arg) (not gnus-dead-summary-mode)
            (> (prefix-numeric-value arg) 0)))
     (when gnus-dead-summary-mode
-      (gnus-add-minor-mode
+      (add-minor-mode
        'gnus-dead-summary-mode " Dead" gnus-dead-summary-mode-map))))
 
 (defun gnus-deaden-summary ()
@@ -7012,8 +7170,7 @@
   ;; Kill any previous dead summary buffer.
   (when (and gnus-dead-summary
             (buffer-name gnus-dead-summary))
-    (save-excursion
-      (set-buffer gnus-dead-summary)
+    (with-current-buffer gnus-dead-summary
       (when gnus-dead-summary-mode
        (kill-buffer (current-buffer)))))
   ;; Make this the current dead summary.
@@ -7032,8 +7189,7 @@
   (save-excursion
     (when (and (buffer-name buffer)
               (not gnus-single-article-buffer))
-      (save-excursion
-       (set-buffer buffer)
+      (with-current-buffer buffer
        (gnus-kill-buffer gnus-article-buffer)
        (gnus-kill-buffer gnus-original-article-buffer)))
     (cond
@@ -7073,7 +7229,7 @@
     (when current-prefix-arg
       (completing-read
        "FAQ dir: " (and (listp gnus-group-faq-directory)
-                       (mapcar (lambda (file) (list file))
+                       (mapcar 'list
                                gnus-group-faq-directory))))))
   (let (gnus-faq-buffer)
     (when (setq gnus-faq-buffer
@@ -7287,15 +7443,15 @@
 
 (defun gnus-summary-display-article (article &optional all-header)
   "Display ARTICLE in article buffer."
-  (when (gnus-buffer-live-p gnus-article-buffer)
+  (unless (and (gnus-buffer-live-p gnus-article-buffer)
     (with-current-buffer gnus-article-buffer
-      (mm-enable-multibyte)))
+                (eq major-mode 'gnus-article-mode)))
+    (gnus-article-setup-buffer))
   (gnus-set-global-variables)
-  (when (gnus-buffer-live-p gnus-article-buffer)
     (with-current-buffer gnus-article-buffer
       (setq gnus-article-charset gnus-newsgroup-charset)
       (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)
-      (mm-enable-multibyte)))
+    (mm-enable-multibyte))
   (if (null article)
       nil
     (prog1
@@ -7402,8 +7558,7 @@
       (gnus-summary-jump-to-group gnus-newsgroup-name))
     (let ((cmd last-command-char)
          (point
-          (save-excursion
-            (set-buffer gnus-group-buffer)
+          (with-current-buffer gnus-group-buffer
             (point)))
          (group
           (if (eq gnus-keep-same-level 'best)
@@ -7456,7 +7611,7 @@
                 (format " (Type %s for %s [%s])"
                         (single-key-description cmd)
                         (gnus-group-decoded-name group)
-                        (car (gnus-gethash group gnus-newsrc-hashtb)))
+                        (gnus-group-unread group))
               (format " (Type %s to exit %s)"
                       (single-key-description cmd)
                       (gnus-group-decoded-name gnus-newsgroup-name)))))
@@ -7844,6 +7999,123 @@
         current-prefix-arg))
   (gnus-summary-limit-to-subject from "from" not-matching))
 
+(defun gnus-summary-limit-to-recipient (recipient &optional not-matching)
+  "Limit the summary buffer to articles with the given RECIPIENT.
+
+If NOT-MATCHING, exclude RECIPIENT.
+
+To and Cc headers are checked.  You need to include them in
+`nnmail-extra-headers'."
+  ;; Unlike `rmail-summary-by-recipients', doesn't include From.
+  (interactive
+   (list (read-string (format "%s recipient (regexp): "
+                             (if current-prefix-arg "Exclude" "Limit to")))
+        current-prefix-arg))
+  (when (not (equal "" recipient))
+    (prog1 (let* ((to
+                  (if (memq 'To nnmail-extra-headers)
+                      (gnus-summary-find-matching
+                       (cons 'extra 'To) recipient 'all nil nil
+                       not-matching)
+                    (gnus-message
+                     1 "`To' isn't present in `nnmail-extra-headers'")
+                    (sit-for 1)
+                    nil))
+                 (cc
+                  (if (memq 'Cc nnmail-extra-headers)
+                      (gnus-summary-find-matching
+                       (cons 'extra 'Cc) recipient 'all nil nil
+                       not-matching)
+                    (gnus-message
+                     1 "`Cc' isn't present in `nnmail-extra-headers'")
+                    (sit-for 1)
+                    nil))
+                 (articles
+                  (if not-matching
+                      ;; We need the numbers that are in both lists:
+                      (mapcar (lambda (a)
+                                (and (memq a to) a))
+                              cc)
+                    (nconc to cc))))
+            (unless articles
+              (error "Found no matches for \"%s\"" recipient))
+            (gnus-summary-limit articles))
+      (gnus-summary-position-point))))
+
+(defun gnus-summary-limit-to-address (address &optional not-matching)
+  "Limit the summary buffer to articles with the given ADDRESS.
+
+If NOT-MATCHING, exclude ADDRESS.
+
+To, Cc and From headers are checked.  You need to include `To' and `Cc'
+in `nnmail-extra-headers'."
+  (interactive
+   (list (read-string (format "%s address (regexp): "
+                             (if current-prefix-arg "Exclude" "Limit to")))
+        current-prefix-arg))
+  (when (not (equal "" address))
+    (prog1 (let* ((to
+                  (if (memq 'To nnmail-extra-headers)
+                      (gnus-summary-find-matching
+                       (cons 'extra 'To) address 'all nil nil
+                       not-matching)
+                    (gnus-message
+                     1 "`To' isn't present in `nnmail-extra-headers'")
+                    (sit-for 1)
+                    t))
+                 (cc
+                  (if (memq 'Cc nnmail-extra-headers)
+                      (gnus-summary-find-matching
+                       (cons 'extra 'Cc) address 'all nil nil
+                       not-matching)
+                    (gnus-message
+                     1 "`Cc' isn't present in `nnmail-extra-headers'")
+                    (sit-for 1)
+                    t))
+                 (from
+                  (gnus-summary-find-matching "from" address
+                                              'all nil nil not-matching))
+                 (articles
+                  (if not-matching
+                      ;; We need the numbers that are in all lists:
+                      (if (eq cc t)
+                          (if (eq to t)
+                              from
+                            (mapcar (lambda (a) (car (memq a from))) to))
+                        (if (eq to t)
+                            (mapcar (lambda (a) (car (memq a from))) cc)
+                          (mapcar (lambda (a) (car (memq a from)))
+                                  (mapcar (lambda (a) (car (memq a to)))
+                                          cc))))
+                    (nconc (if (eq to t) nil to)
+                           (if (eq cc t) nil cc)
+                           from))))
+            (unless articles
+              (error "Found no matches for \"%s\"" address))
+            (gnus-summary-limit articles))
+      (gnus-summary-position-point))))
+
+(defun gnus-summary-limit-strange-charsets-predicate (header)
+  (let ((string (concat (mail-header-subject header)
+                       (mail-header-from header)))
+       charset found)
+    (dotimes (i (1- (length string)))
+      (setq charset (format "%s" (char-charset (aref string (1+ i)))))
+      (when (string-match "unicode\\|big\\|japanese" charset)
+       (setq found t)))
+    found))
+
+(defun gnus-summary-limit-to-predicate (predicate)
+  "Limit to articles where PREDICATE returns non-nil.
+PREDICATE will be called with the header structures of the
+articles."
+  (let ((articles nil)
+       (case-fold-search t))
+    (dolist (header gnus-newsgroup-headers)
+      (when (funcall predicate header)
+       (push (mail-header-number header) articles)))
+    (gnus-summary-limit (nreverse articles))))
+
 (defun gnus-summary-limit-to-age (age &optional younger-p)
   "Limit the summary buffer to articles that are older than (or equal) AGE 
days.
 If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to
@@ -7862,10 +8134,9 @@
        (if (numberp days)
           (progn
             (setq days-got t)
-            (if (< days 0)
-                (progn
+            (when (< days 0)
                   (setq younger (not younger))
-                  (setq days (* days -1)))))
+              (setq days (* days -1))))
         (message "Please enter a number.")
         (sleep-for 1)))
      (list days younger)))
@@ -7950,6 +8221,81 @@
           gnus-duplicate-mark gnus-souped-mark)
      'reverse)))
 
+(defun gnus-summary-limit-to-headers (match &optional reverse)
+  "Limit the summary buffer to articles that have headers that match MATCH.
+If REVERSE (the prefix), limit to articles that don't match."
+  (interactive "sMatch headers (regexp): \nP")
+  (gnus-summary-limit-to-bodies match reverse t))
+
+(defun gnus-summary-limit-to-bodies (match &optional reverse headersp)
+  "Limit the summary buffer to articles that have bodies that match MATCH.
+If REVERSE (the prefix), limit to articles that don't match."
+  (interactive "sMatch body (regexp): \nP")
+  (let ((articles nil)
+       (gnus-select-article-hook nil)  ;Disable hook.
+       (gnus-article-prepare-hook nil)
+       (gnus-use-article-prefetch nil)
+       (gnus-keep-backlog nil)
+       (gnus-break-pages nil)
+       (gnus-summary-display-arrow nil)
+       (gnus-updated-mode-lines nil)
+       (gnus-auto-center-summary nil)
+       (gnus-display-mime-function nil))
+    (dolist (data gnus-newsgroup-data)
+      (let (gnus-mark-article-hook)
+       (gnus-summary-select-article t t nil (gnus-data-number data)))
+      (save-excursion
+       (set-buffer gnus-article-buffer)
+       (article-goto-body)
+       (let* ((case-fold-search t)
+              (found (if headersp
+                         (re-search-backward match nil t)
+                       (re-search-forward match nil t))))
+         (when (or (and found
+                        (not reverse))
+                   (and (not found)
+                        reverse))
+           (push (gnus-data-number data) articles)))))
+    (if (not articles)
+       (message "No messages matched")
+      (gnus-summary-limit articles)))
+  (gnus-summary-position-point))
+
+(defun gnus-summary-limit-to-singletons (&optional threadsp)
+  "Limit the summary buffer to articles that aren't part on any thread.
+If THREADSP (the prefix), limit to articles that are in threads."
+  (interactive "P")
+  (let ((articles nil)
+       thread-articles
+       threads)
+    (dolist (thread gnus-newsgroup-threads)
+      (if (stringp (car thread))
+         (dolist (thread (cdr thread))
+           (push thread threads))
+       (push thread threads)))
+    (dolist (thread threads)
+      (setq thread-articles (gnus-articles-in-thread thread))
+      (when (or (and threadsp
+                    (> (length thread-articles) 1))
+               (and (not threadsp)
+                    (= (length thread-articles) 1)))
+       (setq articles (nconc thread-articles articles))))
+    (if (not articles)
+       (message "No messages matched")
+      (gnus-summary-limit articles))
+    (gnus-summary-position-point)))
+
+(defun gnus-summary-limit-to-replied (&optional unreplied)
+  "Limit the summary buffer to replied articles.
+If UNREPLIED (the prefix), limit to unreplied articles."
+  (interactive "P")
+  (if unreplied
+      (gnus-summary-limit
+       (gnus-set-difference gnus-newsgroup-articles
+       gnus-newsgroup-replied))
+    (gnus-summary-limit gnus-newsgroup-replied))
+  (gnus-summary-position-point))
+
 (defalias 'gnus-summary-delete-marked-with 'gnus-summary-limit-exclude-marks)
 (make-obsolete 'gnus-summary-delete-marked-with
               'gnus-summary-limit-exclude-marks)
@@ -8035,6 +8381,14 @@
        (gnus-message 3 "No dormant articles for this group")
       (gnus-summary-goto-subjects gnus-newsgroup-dormant))))
 
+(defun gnus-summary-insert-ticked-articles ()
+  "Insert ticked articles for this group into the current buffer."
+  (interactive)
+  (let ((gnus-verbose (max 6 gnus-verbose)))
+    (if (not gnus-newsgroup-marked)
+       (gnus-message 3 "No ticked articles for this group")
+      (gnus-summary-goto-subjects gnus-newsgroup-marked))))
+
 (defun gnus-summary-limit-include-dormant ()
   "Display all the hidden articles that are marked as dormant.
 Note that this command only works on a subset of the articles currently
@@ -8295,13 +8649,12 @@
            (and gnus-newsgroup-display
                 (not (funcall gnus-newsgroup-display)))
            ;; Check NoCeM things.
-           (if (and gnus-use-nocem
+           (when (and gnus-use-nocem
                     (gnus-nocem-unwanted-article-p
                      (mail-header-id (car thread))))
-               (progn
                  (setq gnus-newsgroup-unreads
                        (delq number gnus-newsgroup-unreads))
-                 t))))
+             t)))
          ;; Nope, invisible article.
          0
        ;; Ok, this article is to be visible, so we add it to the limit
@@ -8513,8 +8866,7 @@
     (let* ((name (format "%s-%d"
                         (gnus-group-prefixed-name
                          gnus-newsgroup-name (list 'nndoc ""))
-                        (save-excursion
-                          (set-buffer gnus-summary-buffer)
+                        (with-current-buffer gnus-summary-buffer
                           gnus-current-article)))
           (ogroup gnus-newsgroup-name)
           (params (append (gnus-info-params (gnus-get-info ogroup))
@@ -8572,12 +8924,11 @@
 documents as newsgroups.
 Obeys the standard process/prefix convention."
   (interactive "P")
-  (let* ((articles (gnus-summary-work-articles n))
-        (ogroup gnus-newsgroup-name)
+  (let* ((ogroup gnus-newsgroup-name)
         (params (append (gnus-info-params (gnus-get-info ogroup))
                         (list (cons 'to-group ogroup))))
-        article group egroup groups vgroup)
-    (while (setq article (pop articles))
+        group egroup groups vgroup)
+    (dolist (article (gnus-summary-work-articles n))
       (setq group (format "%s-%d" gnus-newsgroup-name article))
       (gnus-summary-remove-process-mark article)
       (when (gnus-summary-display-article article)
@@ -8588,7 +8939,7 @@
            ;; the wrong guess.
            (message-narrow-to-head)
            (goto-char (point-min))
-           (delete-matching-lines "^\\(Path\\):\\|^From ")
+           (delete-matching-lines "^Path:\\|^From ")
            (widen)
            (if (setq egroup
                      (gnus-group-read-ephemeral-group
@@ -8627,6 +8978,20 @@
       (widen)
       (isearch-forward regexp-p))))
 
+(defun gnus-summary-repeat-search-article-forward ()
+  "Repeat the previous search forwards."
+  (interactive)
+  (unless gnus-last-search-regexp
+    (error "No previous search"))
+  (gnus-summary-search-article-forward gnus-last-search-regexp))
+
+(defun gnus-summary-repeat-search-article-backward ()
+  "Repeat the previous search backwards."
+  (interactive)
+  (unless gnus-last-search-regexp
+    (error "No previous search"))
+  (gnus-summary-search-article-forward gnus-last-search-regexp t))
+
 (defun gnus-summary-search-article-forward (regexp &optional backward)
   "Search for an article containing REGEXP forward.
 If BACKWARD, search backward instead."
@@ -8929,8 +9294,7 @@
           (or (cdr (assq arg gnus-summary-show-article-charset-alist))
               (mm-read-coding-system
                "View as charset: " ;; actually it is coding system.
-               (save-excursion
-                 (set-buffer gnus-article-buffer)
+               (with-current-buffer gnus-article-buffer
                  (mm-detect-coding-region (point) (point-max))))))
          (gnus-newsgroup-ignored-charsets 'gnus-all))
       (gnus-summary-select-article nil 'force)
@@ -9054,8 +9418,8 @@
 
 (defun gnus-summary-caesar-message (&optional arg)
   "Caesar rotate the current article by 13.
-The numerical prefix specifies how many places to rotate each letter
-forward."
+With a non-numerical prefix, also rotate headers.  A numerical
+prefix specifies how many places to rotate each letter forward."
   (interactive "P")
   (gnus-summary-select-article)
   (let ((mail-header-separator ""))
@@ -9064,14 +9428,38 @@
        (widen)
        (let ((start (window-start))
              buffer-read-only)
-         (message-caesar-buffer-body arg)
+         (if (equal arg '(4))
+             (message-caesar-buffer-body nil t)
+           (message-caesar-buffer-body arg))
          (set-window-start (get-buffer-window (current-buffer)) start)))))
   ;; Create buttons and stuff...
   (gnus-treat-article nil))
 
-(autoload 'unmorse-region "morse"
-  "Convert morse coded text in region to ordinary ASCII text."
-  t)
+(defun gnus-summary-idna-message (&optional arg)
+  "Decode IDNA encoded domain names in the current articles.
+IDNA encoded domain names looks like `xn--bar'.  If a string
+remain unencoded after running this function, it is likely an
+invalid IDNA string (`xn--bar' is invalid).
+
+You must have GNU Libidn (`http://www.gnu.org/software/libidn/')
+installed for this command to work."
+  (interactive "P")
+  (if (not (and (condition-case nil (require 'idna)
+                 (file-error))
+               (mm-coding-system-p 'utf-8)
+               (executable-find (symbol-value 'idna-program))))
+      (gnus-message
+       5 "GNU Libidn not installed properly (`idn' or `idna.el' missing)")
+    (gnus-summary-select-article)
+    (let ((mail-header-separator ""))
+      (gnus-eval-in-buffer-window gnus-article-buffer
+       (save-restriction
+         (widen)
+         (let ((start (window-start))
+               buffer-read-only)
+           (while (re-search-forward "\\(xn--[-0-9a-z]+\\)" nil t)
+             (replace-match (idna-to-unicode (match-string 1))))
+           (set-window-start (get-buffer-window (current-buffer)) start)))))))
 
 (defun gnus-summary-morse-message (&optional arg)
   "Morse decode the current article."
@@ -9088,7 +9476,7 @@
            (when (message-goto-body)
              (gnus-narrow-to-body))
            (goto-char (point-min))
-           (while (re-search-forward "·" (point-max) t)
+           (while (search-forward "·" (point-max) t)
              (replace-match "."))
            (unmorse-region (point-min) (point-max))
            (widen)
@@ -9141,14 +9529,16 @@
   (let ((articles (gnus-summary-work-articles n))
        (prefix (if (gnus-check-backend-function
                     'request-move-article gnus-newsgroup-name)
-                   (gnus-group-real-prefix gnus-newsgroup-name)
+                   (funcall gnus-move-group-prefix-function
+                            gnus-newsgroup-name)
                  ""))
        (names '((move "Move" "Moving")
                 (copy "Copy" "Copying")
                 (crosspost "Crosspost" "Crossposting")))
        (copy-buf (save-excursion
                    (nnheader-set-temp-buffer " *copy article*")))
-       art-group to-method new-xref article to-groups)
+       art-group to-method new-xref article to-groups
+       articles-to-update-marks encoded)
     (unless (assq action names)
       (error "Unknown action %s" action))
     ;; Read the newsgroup name.
@@ -9166,15 +9556,27 @@
                (gnus-article-prepare-hook nil)
                (gnus-mark-article-hook nil))
            (gnus-summary-select-article nil nil nil (car articles))))
-      (setq to-newsgroup
-           (gnus-read-move-group-name
+      (setq to-newsgroup (gnus-read-move-group-name
             (cadr (assq action names))
-            (symbol-value (intern (format "gnus-current-%s-group" action)))
-            articles prefix))
-      (set (intern (format "gnus-current-%s-group" action)) to-newsgroup))
+                         (symbol-value
+                          (intern (format "gnus-current-%s-group" action)))
+                         articles prefix)
+           encoded to-newsgroup
+           to-method (gnus-server-to-method (gnus-group-method to-newsgroup)))
+      (set (intern (format "gnus-current-%s-group" action))
+          (mm-decode-coding-string
+           to-newsgroup
+           (gnus-group-name-charset to-method to-newsgroup))))
+    (unless to-method
     (setq to-method (or select-method
                        (gnus-server-to-method
-                        (gnus-group-method to-newsgroup))))
+                          (gnus-group-method to-newsgroup)))))
+    (setq to-newsgroup
+         (or encoded
+             (and to-newsgroup
+                  (mm-encode-coding-string
+                   to-newsgroup
+                   (gnus-group-name-charset to-method to-newsgroup)))))
     ;; Check the method we are to move this article to...
     (unless (gnus-check-backend-function
             'request-accept-article (car to-method))
@@ -9183,7 +9585,9 @@
       (error "Can't open server %s" (car to-method)))
     (gnus-message 6 "%s to %s: %s..."
                  (caddr (assq action names))
-                 (or (car select-method) to-newsgroup) articles)
+                 (or (car select-method)
+                     (gnus-group-decoded-name to-newsgroup))
+                 articles)
     (while articles
       (setq article (pop articles))
       (setq
@@ -9193,6 +9597,11 @@
        ((eq action 'move)
         ;; Remove this article from future suppression.
         (gnus-dup-unsuppress-article article)
+        (let* ((from-method (gnus-find-method-for-group
+                             gnus-newsgroup-name))
+               (to-method (or select-method
+                              (gnus-find-method-for-group to-newsgroup)))
+               (move-is-internal (gnus-method-equal from-method to-method)))
         (gnus-request-move-article
          article                       ; Article to move
          gnus-newsgroup-name           ; From newsgroup
@@ -9201,12 +9610,17 @@
          (list 'gnus-request-accept-article
                to-newsgroup (list 'quote select-method)
                (not articles) t)       ; Accept form
-         (not articles)))              ; Only save nov last time
+           (not articles)              ; Only save nov last time
+           move-is-internal)))         ; is this move internal?
        ;; Copy the article.
        ((eq action 'copy)
         (save-excursion
           (set-buffer copy-buf)
           (when (gnus-request-article-this-buffer article gnus-newsgroup-name)
+            (save-restriction
+              (nnheader-narrow-to-headers)
+              (dolist (hdr gnus-copy-article-ignored-headers)
+                (message-remove-header hdr t)))
             (gnus-request-accept-article
              to-newsgroup select-method (not articles) t))))
        ;; Crosspost the article.
@@ -9259,9 +9673,7 @@
        (t
        (let* ((pto-group (gnus-group-prefixed-name
                           (car art-group) to-method))
-              (entry
-               (gnus-gethash pto-group gnus-newsrc-hashtb))
-              (info (nth 2 entry))
+              (info (gnus-get-info pto-group))
               (to-group (gnus-info-group info))
               to-marks)
          ;; Update the group that has been moved to.
@@ -9353,7 +9765,9 @@
        (gnus-summary-goto-subject article)
        (when (eq action 'move)
          (gnus-summary-mark-article article gnus-canceled-mark))))
-      (gnus-summary-remove-process-mark article))
+      (push article articles-to-update-marks))
+
+    (apply 'gnus-summary-remove-process-mark articles-to-update-marks)
     ;; Re-activate all groups that have been moved to.
     (save-excursion
       (set-buffer gnus-group-buffer)
@@ -9629,10 +10043,10 @@
        (unless (memq (car articles) not-deleted)
          (gnus-summary-mark-article (car articles) gnus-canceled-mark))
        (let* ((article (car articles))
-              (id (mail-header-id (gnus-data-header
-                                   (assoc article (gnus-data-list nil))))))
+              (ghead  (gnus-data-header
+                                   (assoc article (gnus-data-list nil)))))
          (run-hook-with-args 'gnus-summary-article-delete-hook
-                             'delete id gnus-newsgroup-name nil
+                             'delete ghead gnus-newsgroup-name nil
                              nil))
        (setq articles (cdr articles)))
       (when not-deleted
@@ -9705,7 +10119,16 @@
                  (message-options message-options)
                  (message-options-set-recipient)
                  (mail-parse-ignored-charsets
-                  ',gnus-newsgroup-ignored-charsets))
+                  ',gnus-newsgroup-ignored-charsets)
+                 (rfc2047-header-encoding-alist
+                  ',(let ((charset (gnus-group-name-charset
+                                    (gnus-find-method-for-group
+                                     gnus-newsgroup-name)
+                                    gnus-newsgroup-name)))
+                      (append (list (cons "Newsgroups" charset)
+                                    (cons "Followup-To" charset)
+                                    (cons "Xref" charset))
+                              rfc2047-header-encoding-alist))))
              ,(if (not raw) '(progn
                                (mml-to-mime)
                                (mml-destroy-buffers)
@@ -10013,8 +10436,7 @@
   ;; (article-number . line-number-in-body).
   (push
    (cons article
-        (save-excursion
-          (set-buffer gnus-article-buffer)
+        (with-current-buffer gnus-article-buffer
           (count-lines
            (min (point)
                 (save-excursion
@@ -10051,13 +10473,15 @@
     (gnus-summary-goto-subject article)
     (gnus-summary-update-secondary-mark article)))
 
-(defun gnus-summary-remove-process-mark (article)
-  "Remove the process mark from ARTICLE and update the summary line."
+(defun gnus-summary-remove-process-mark (&rest articles)
+  "Remove the process mark from ARTICLES and update the summary line."
+  (dolist (article articles)
   (setq gnus-newsgroup-processable (delq article gnus-newsgroup-processable))
   (when (gnus-summary-goto-subject article)
     (gnus-summary-show-thread)
     (gnus-summary-goto-subject article)
     (gnus-summary-update-secondary-mark article)))
+  t)
 
 (defun gnus-summary-set-saved-mark (article)
   "Set the process mark on ARTICLE and update the summary line."
@@ -10258,7 +10682,7 @@
 (defun gnus-summary-update-mark (mark type)
   (let ((forward (cdr (assq type gnus-summary-mark-positions)))
        (buffer-read-only nil))
-    (re-search-backward "[\n\r]" (gnus-point-at-bol) 'move-to-limit)
+    (re-search-backward "[\n\r]" (point-at-bol) 'move-to-limit)
     (when forward
       (when (looking-at "\r")
        (incf forward))
@@ -10501,9 +10925,8 @@
        (goto-char (point-min))
        (push gnus-newsgroup-limit gnus-newsgroup-limits)
        (setq gnus-newsgroup-limit (copy-sequence gnus-newsgroup-limit))
-       (mapcar (lambda (x) (push (mail-header-number x)
-                                 gnus-newsgroup-limit))
-               headers)
+       (dolist (x headers)
+         (push (mail-header-number x) gnus-newsgroup-limit))
        (gnus-summary-prepare-unthreaded (nreverse headers))
        (goto-char (point-min))
        (gnus-summary-position-point)
@@ -10628,6 +11051,15 @@
     (gnus-summary-catchup all))
   (gnus-summary-next-group))
 
+(defun gnus-summary-catchup-and-goto-prev-group (&optional all)
+  "Mark all articles in this group as read and select the previous group.
+If given a prefix, mark all articles, unread as well as ticked, as
+read."
+  (interactive "P")
+  (save-excursion
+    (gnus-summary-catchup all))
+  (gnus-summary-next-group nil nil t))
+
 ;;;
 ;;; with article
 ;;;
@@ -10720,23 +11152,33 @@
     (error "The current newsgroup does not support article editing"))
   (unless (<= (length gnus-newsgroup-processable) 1)
     (error "No more than one article may be marked"))
-  (save-window-excursion
-    (let ((gnus-article-buffer " *reparent*")
-         (current-article (gnus-summary-article-number))
+  (let ((child (gnus-summary-article-number))
          ;; First grab the marked article, otherwise one line up.
-         (parent-article (if (not (null gnus-newsgroup-processable))
+       (parent (if (not (null gnus-newsgroup-processable))
                              (car gnus-newsgroup-processable)
                            (save-excursion
                              (if (eq (forward-line -1) 0)
                                  (gnus-summary-article-number)
                                (error "Beginning of summary buffer"))))))
-      (unless (not (eq current-article parent-article))
+    (gnus-summary-reparent-children parent (list child))))
+
+(defun gnus-summary-reparent-children (parent children)
+  "Make PARENT the parent of CHILDREN.
+When called interactively, PARENT is the current article and CHILDREN
+are the process-marked articles."
+  (interactive
+   (list (gnus-summary-article-number)
+        (gnus-summary-work-articles nil)))
+  (dolist (child children)
+    (save-window-excursion
+      (let ((gnus-article-buffer " *reparent*"))
+       (unless (not (eq parent child))
        (error "An article may not be self-referential"))
       (let ((message-id (mail-header-id
-                        (gnus-summary-article-header parent-article))))
+                          (gnus-summary-article-header parent))))
        (unless (and message-id (not (equal message-id "")))
          (error "No message-id in desired parent"))
-       (gnus-with-article current-article
+         (gnus-with-article child
          (save-restriction
            (goto-char (point-min))
            (message-narrow-to-head)
@@ -10749,12 +11191,12 @@
              (insert "References: " message-id "\n"))))
        (set-buffer gnus-summary-buffer)
        (gnus-summary-unmark-all-processable)
-       (gnus-summary-update-article current-article)
-       (if (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
+         (gnus-summary-update-article child)
+         (when (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
            (gnus-summary-update-secondary-mark (cdr gnus-article-current)))
        (gnus-summary-rethread-current)
        (gnus-message 3 "Article %d is now the child of article %d"
-                     current-article parent-article)))))
+                       child parent))))))
 
 (defun gnus-summary-toggle-threads (&optional arg)
   "Toggle showing conversation threads.
@@ -10783,7 +11225,7 @@
   (interactive)
   (let ((buffer-read-only nil)
        (orig (point))
-       (end (gnus-point-at-eol))
+       (end (point-at-eol))
        ;; Leave point at bol
        (beg (progn (beginning-of-line) (point))))
     (prog1
@@ -10947,14 +11389,21 @@
   (while (gnus-summary-go-up-thread))
   (gnus-summary-article-number))
 
+(defun gnus-summary-expire-thread ()
+  "Mark articles under current thread as expired."
+  (interactive)
+  (gnus-summary-kill-thread 0))
+
 (defun gnus-summary-kill-thread (&optional unmark)
   "Mark articles under current thread as read.
 If the prefix argument is positive, remove any kinds of marks.
+If the prefix argument is zero, mark thread as expired.
 If the prefix argument is negative, tick articles instead."
   (interactive "P")
   (when unmark
     (setq unmark (prefix-numeric-value unmark)))
-  (let ((articles (gnus-summary-articles-in-thread)))
+  (let ((articles (gnus-summary-articles-in-thread))
+       (hide (or (null unmark) (= unmark 0))))
     (save-excursion
       ;; Expand the thread.
       (gnus-summary-show-thread)
@@ -10965,15 +11414,17 @@
               (gnus-summary-mark-article-as-read gnus-killed-mark))
              ((> unmark 0)
               (gnus-summary-mark-article-as-unread gnus-unread-mark))
+             ((= unmark 0)
+              (gnus-summary-mark-article-as-unread gnus-expirable-mark))
              (t
               (gnus-summary-mark-article-as-unread gnus-ticked-mark)))
        (setq articles (cdr articles))))
-    ;; Hide killed subtrees.
-    (and (null unmark)
+    ;; Hide killed subtrees when hide is true.
+    (and hide
         gnus-thread-hide-killed
         (gnus-summary-hide-thread))
-    ;; If marked as read, go to next unread subject.
-    (when (null unmark)
+    ;; If hide is t, go to next unread subject.
+    (when hide
       ;; Go to next unread subject.
       (gnus-summary-next-subject 1 t)))
   (gnus-set-mode-line 'summary))
@@ -10999,6 +11450,13 @@
   (interactive "P")
   (gnus-summary-sort 'author reverse))
 
+(defun gnus-summary-sort-by-recipient (&optional reverse)
+  "Sort the summary buffer by recipient name alphabetically.
+If `case-fold-search' is non-nil, case of letters is ignored.
+Argument REVERSE means reverse order."
+  (interactive "P")
+  (gnus-summary-sort 'recipient reverse))
+
 (defun gnus-summary-sort-by-subject (&optional reverse)
   "Sort the summary buffer by subject alphabetically.  `Re:'s are ignored.
 If `case-fold-search' is non-nil, case of letters is ignored.
@@ -11287,46 +11745,51 @@
                      (format "these %d articles" (length articles))
                    "this article")))
         (to-newsgroup
+         (let (active group)
+           (when (or (null split-name) (= 1 (length split-name)))
+             (setq active (gnus-make-hashtable (length gnus-active-hashtb)))
+             (mapatoms (lambda (symbol)
+                         (setq group (symbol-name symbol))
+                         (when (string-match "[^\000-\177]" group)
+                           (setq group (gnus-group-decoded-name group)))
+                         (set (intern group active) group))
+                       gnus-active-hashtb))
          (cond
           ((null split-name)
            (gnus-completing-read-with-default
-            default prom
-            gnus-active-hashtb
-            'gnus-valid-move-group-p
-            nil prefix
+              default prom active 'gnus-valid-move-group-p nil prefix
             'gnus-group-history))
           ((= 1 (length split-name))
            (gnus-completing-read-with-default
-            (car split-name) prom
-            gnus-active-hashtb
-            'gnus-valid-move-group-p
-            nil nil
+              (car split-name) prom active 'gnus-valid-move-group-p nil nil
             'gnus-group-history))
           (t
            (gnus-completing-read-with-default
-            nil prom
-            (mapcar (lambda (el) (list el))
-                    (nreverse split-name))
-            nil nil nil
-            'gnus-group-history))))
-        (to-method (gnus-server-to-method (gnus-group-method to-newsgroup))))
+              nil prom (mapcar 'list (nreverse split-name)) nil nil nil
+              'gnus-group-history)))))
+        (to-method (gnus-server-to-method (gnus-group-method to-newsgroup)))
+        encoded)
     (when to-newsgroup
       (if (or (string= to-newsgroup "")
              (string= to-newsgroup prefix))
          (setq to-newsgroup default))
       (unless to-newsgroup
        (error "No group name entered"))
-      (or (gnus-active to-newsgroup)
-         (gnus-activate-group to-newsgroup nil nil to-method)
+      (setq encoded (mm-encode-coding-string
+                    to-newsgroup
+                    (gnus-group-name-charset to-method to-newsgroup)))
+      (or (gnus-active encoded)
+         (gnus-activate-group encoded nil nil to-method)
          (if (gnus-y-or-n-p (format "No such group: %s.  Create it? "
                                     to-newsgroup))
-             (or (and (gnus-request-create-group to-newsgroup to-method)
-                      (gnus-activate-group
-                       to-newsgroup nil nil to-method)
-                      (gnus-subscribe-group to-newsgroup))
+             (or (and (gnus-request-create-group encoded to-method)
+                      (gnus-activate-group encoded nil nil to-method)
+                      (gnus-subscribe-group encoded))
                  (error "Couldn't create group %s" to-newsgroup)))
-         (error "No such group: %s" to-newsgroup)))
-    to-newsgroup))
+         (error "No such group: %s" to-newsgroup))
+      encoded)))
+
+(defvar gnus-summary-save-parts-counter)
 
 (defun gnus-summary-save-parts (type dir n &optional reverse)
   "Save parts matching TYPE to DIR.
@@ -11350,7 +11813,8 @@
       (let ((handles (or gnus-article-mime-handles
                         (mm-dissect-buffer nil gnus-article-loose-mime)
                         (and gnus-article-emulate-mime
-                             (mm-uu-dissect)))))
+                             (mm-uu-dissect))))
+           (gnus-summary-save-parts-counter 1))
        (when handles
          (gnus-summary-save-parts-1 type dir handles reverse)
          (unless gnus-article-mime-handles ;; Don't destroy this case.
@@ -11372,10 +11836,11 @@
                       (mm-handle-disposition handle) 'filename)
                      (mail-content-type-get
                       (mm-handle-type handle) 'name)
-                     (concat gnus-newsgroup-name
-                             "." (number-to-string
-                                  (cdr gnus-article-current))))))
+                     (format "%s.%d.%d" gnus-newsgroup-name
+                             (cdr gnus-article-current)
+                             gnus-summary-save-parts-counter))))
                   dir)))
+       (incf gnus-summary-save-parts-counter)
        (unless (file-exists-p file)
          (mm-save-part-to-file handle file))))))
 
@@ -11414,7 +11879,7 @@
                                (lambda (f)
                                  (if (equal f " ")
                                      f
-                                   (mm-quote-arg f)))
+                                   (shell-quote-argument f)))
                                files " ")))))
          (setq ps (cdr ps)))))
     (if (and gnus-view-pseudos (not not-view))
@@ -11530,11 +11995,14 @@
            ()                          ; Malformed head.
          (unless (gnus-summary-article-sparse-p (mail-header-number header))
            (when (and (stringp id)
+                      (or
                       (not (string= (gnus-group-real-name group)
-                                    (car where))))
-             ;; If we fetched by Message-ID and the article came
-             ;; from a different group, we fudge some bogus article
-             ;; numbers for this article.
+                                     (car where)))
+                       (not (gnus-server-equal gnus-override-method
+                                               (gnus-group-method group)))))
+             ;; If we fetched by Message-ID and the article came from
+             ;; a different group (or server), we fudge some bogus
+             ;; article numbers for this article.
              (mail-header-set-number header gnus-reffed-article-number))
            (save-excursion
              (set-buffer gnus-summary-buffer)
@@ -11566,8 +12034,8 @@
   ;; Added by Per Abrahamsen <address@hidden>.
   (when gnus-summary-selected-face
     (save-excursion
-      (let* ((beg (gnus-point-at-bol))
-            (end (gnus-point-at-eol))
+      (let* ((beg (point-at-bol))
+            (end (point-at-eol))
             ;; Fix by Mike Dugan <address@hidden>.
             (from (if (get-text-property beg gnus-mouse-face-prop)
                       beg
@@ -11616,7 +12084,7 @@
 
 (defun gnus-summary-highlight-line ()
   "Highlight current line according to `gnus-summary-highlight'."
-  (let* ((beg (gnus-point-at-bol))
+  (let* ((beg (point-at-bol))
         (article (or (gnus-summary-article-number) gnus-current-article))
         (score (or (cdr (assq article
                               gnus-newsgroup-scored))
@@ -11632,7 +12100,7 @@
     (let ((face (funcall (gnus-summary-highlight-line-0))))
       (unless (eq face (get-text-property beg 'face))
        (gnus-put-text-property-excluding-characters-with-faces
-        beg (gnus-point-at-eol) 'face
+        beg (point-at-eol) 'face
         (setq face (if (boundp face) (symbol-value face) face)))
        (when gnus-summary-highlight-line-function
          (funcall gnus-summary-highlight-line-function article face))))))
@@ -11640,9 +12108,8 @@
 (defun gnus-update-read-articles (group unread &optional compute)
   "Update the list of read articles in GROUP.
 UNREAD is a sorted list."
-  (let* ((active (or gnus-newsgroup-active (gnus-active group)))
-        (entry (gnus-gethash group gnus-newsrc-hashtb))
-        (info (nth 2 entry))
+  (let ((active (or gnus-newsgroup-active (gnus-active group)))
+       (info (gnus-get-info group))
         (prev 1)
         read)
     (if (or (not info) (not active))
@@ -11712,8 +12179,7 @@
     (dolist (buffer (buffer-list))
       (when (and (setq buffer (buffer-name buffer))
                 (string-match "Summary" buffer)
-                (save-excursion
-                  (set-buffer buffer)
+                (with-current-buffer buffer
                   ;; We check that this is, indeed, a summary buffer.
                   (and (eq major-mode 'gnus-summary-mode)
                        ;; Also make sure this isn't bogus.
@@ -11774,7 +12240,7 @@
     (insert "Mime-Version: 1.0\n")
     (widen)
     (when (search-forward "\n--" nil t)
-      (let ((separator (buffer-substring (point) (gnus-point-at-eol))))
+      (let ((separator (buffer-substring (point) (point-at-eol))))
        (message-narrow-to-head)
        (message-remove-header "Content-Type")
        (goto-char (point-max))
@@ -11885,12 +12351,24 @@
     (when gnus-suppress-duplicates
       (gnus-dup-suppress-articles))
 
-    ;; We might want to build some more threads first.
-    (when (and gnus-fetch-old-headers
+    (if (and gnus-fetch-old-headers
               (eq gnus-headers-retrieved-by 'nov))
+       ;; We might want to build some more threads first.
       (if (eq gnus-fetch-old-headers 'invisible)
          (gnus-build-all-threads)
-       (gnus-build-old-threads)))
+         (gnus-build-old-threads))
+      ;; Mark the inserted articles that are unread as unread.
+      (setq gnus-newsgroup-unreads
+           (gnus-sorted-nunion
+            gnus-newsgroup-unreads
+            (gnus-sorted-nintersection
+             (gnus-list-of-unread-articles gnus-newsgroup-name)
+             articles)))
+      ;; Mark the inserted articles as selected so that the information
+      ;; of the marks having been changed by a user may be updated when
+      ;; exiting this group.  See `gnus-summary-update-info'.
+      (dolist (art articles)
+       (setq gnus-newsgroup-unselected (delq art gnus-newsgroup-unselected))))
     ;; Let the Gnus agent mark articles as read.
     (when gnus-agent
       (gnus-agent-get-undownloaded-list))
@@ -11950,8 +12428,7 @@
                      (read-string
                       (format
                        "How many articles from %s (%s %d): "
-                       (gnus-limit-string
-                        (gnus-group-decoded-name gnus-newsgroup-name) 35)
+                       (gnus-group-decoded-name gnus-newsgroup-name)
                        (if initial "max" "default")
                        len)
                       (if initial
@@ -11994,7 +12471,7 @@
          (push i new)
          (decf i))
        (if (not new)
-           (message "No gnus is bad news.")
+           (message "No gnus is bad news")
          (gnus-summary-insert-articles new)
          (setq gnus-newsgroup-unreads
                (gnus-sorted-nunion gnus-newsgroup-unreads new))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]