Merge gnus-6_5.
[elisp/gnus.git-] / lisp / gnus-art.el
index 6cf74ac..0508d68 100644 (file)
@@ -1,7 +1,7 @@
 ;;; gnus-art.el --- article mode commands for Semi-gnus
 ;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
 ;;; gnus-art.el --- article mode commands for Semi-gnus
 ;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Keywords: mail, news, MIME
 
 ;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Keywords: mail, news, MIME
 
@@ -107,7 +107,7 @@ If `gnus-visible-headers' is non-nil, this variable will be ignored."
   :group 'gnus-article-hiding)
 
 (defcustom gnus-visible-headers
   :group 'gnus-article-hiding)
 
 (defcustom gnus-visible-headers
-  "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From:\\|X-Sent:"
+  "From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From:\\|X-Sent:"
   "*All headers that do not match this regexp will be hidden.
 This variable can also be a list of regexp of headers to remain visible.
 If this variable is non-nil, `gnus-ignored-headers' will be ignored."
   "*All headers that do not match this regexp will be hidden.
 This variable can also be a list of regexp of headers to remain visible.
 If this variable is non-nil, `gnus-ignored-headers' will be ignored."
@@ -130,7 +130,7 @@ this list."
   :group 'gnus-article-hiding)
 
 (defcustom gnus-boring-article-headers '(empty followup-to reply-to)
   :group 'gnus-article-hiding)
 
 (defcustom gnus-boring-article-headers '(empty followup-to reply-to)
-  "*Headers that are only to be displayed if they have interesting data.
+  "Headers that are only to be displayed if they have interesting data.
 Possible values in this list are `empty', `newsgroups', `followup-to',
 `reply-to', `date', `long-to', and `many-to'."
   :type '(set (const :tag "Headers with no content." empty)
 Possible values in this list are `empty', `newsgroups', `followup-to',
 `reply-to', `date', `long-to', and `many-to'."
   :type '(set (const :tag "Headers with no content." empty)
@@ -143,7 +143,7 @@ Possible values in this list are `empty', `newsgroups', `followup-to',
   :group 'gnus-article-hiding)
 
 (defcustom gnus-signature-separator '("^-- $" "^-- *$")
   :group 'gnus-article-hiding)
 
 (defcustom gnus-signature-separator '("^-- $" "^-- *$")
-  "*Regexp matching signature separator.
+  "Regexp matching signature separator.
 This can also be a list of regexps.  In that case, it will be checked
 from head to tail looking for a separator.  Searches will be done from
 the end of the buffer."
 This can also be a list of regexps.  In that case, it will be checked
 from head to tail looking for a separator.  Searches will be done from
 the end of the buffer."
@@ -151,7 +151,7 @@ the end of the buffer."
   :group 'gnus-article-signature)
 
 (defcustom gnus-signature-limit nil
   :group 'gnus-article-signature)
 
 (defcustom gnus-signature-limit nil
-   "*Provide a limit to what is considered a signature.
+   "Provide a limit to what is considered a signature.
 If it is a number, no signature may not be longer (in characters) than
 that number.  If it is a floating point number, no signature may be
 longer (in lines) than that number.  If it is a function, the function
 If it is a number, no signature may not be longer (in characters) than
 that number.  If it is a floating point number, no signature may be
 longer (in lines) than that number.  If it is a function, the function
@@ -165,7 +165,7 @@ regexp.  If it matches, the text in question is not a signature."
   :group 'gnus-article-signature)
 
 (defcustom gnus-hidden-properties '(invisible t intangible t)
   :group 'gnus-article-signature)
 
 (defcustom gnus-hidden-properties '(invisible t intangible t)
-  "*Property list to use for hiding text."
+  "Property list to use for hiding text."
   :type 'sexp
   :group 'gnus-article-hiding)
 
   :type 'sexp
   :group 'gnus-article-hiding)
 
@@ -178,7 +178,7 @@ asynchronously.      The compressed face will be piped to this command."
   :group 'gnus-article-washing)
 
 (defcustom gnus-article-x-face-too-ugly nil
   :group 'gnus-article-washing)
 
 (defcustom gnus-article-x-face-too-ugly nil
-  "*Regexp matching posters whose face shouldn't be shown automatically."
+  "Regexp matching posters whose face shouldn't be shown automatically."
   :type '(choice regexp (const nil))
   :group 'gnus-article-washing)
 
   :type '(choice regexp (const nil))
   :group 'gnus-article-washing)
 
@@ -199,7 +199,7 @@ asynchronously.      The compressed face will be piped to this command."
         (lambda (spec)
           (list
            (format format (car spec) (cadr spec))
         (lambda (spec)
           (list
            (format format (car spec) (cadr spec))
-           2 3 (intern (format "gnus-emphasis-%s" (caddr spec)))))
+           2 3 (intern (format "gnus-emphasis-%s" (nth 2 spec)))))
         types)))
   "*Alist that says how to fontify certain phrases.
 Each item looks like this:
         types)))
   "*Alist that says how to fontify certain phrases.
 Each item looks like this:
@@ -249,7 +249,7 @@ Esample: (_/*word*/_)."
   :group 'gnus-article-emphasis)
 
 (defcustom gnus-article-time-format "%a, %b %d %Y %T %Z"
   :group 'gnus-article-emphasis)
 
 (defcustom gnus-article-time-format "%a, %b %d %Y %T %Z"
-  "*Format for display of Date headers in article bodies.
+  "Format for display of Date headers in article bodies.
 See `format-time-string' for the possible values.
 
 The variable can also be function, which should return a complete Date
 See `format-time-string' for the possible values.
 
 The variable can also be function, which should return a complete Date
@@ -283,7 +283,7 @@ each invocation of the saving commands."
                 (sexp :tag "once" :format "%t\n" :value t)))
 
 (defcustom gnus-saved-headers gnus-visible-headers
                 (sexp :tag "once" :format "%t\n" :value t)))
 
 (defcustom gnus-saved-headers gnus-visible-headers
-  "*Headers to keep if `gnus-save-all-headers' is nil.
+  "Headers to keep if `gnus-save-all-headers' is nil.
 If `gnus-save-all-headers' is non-nil, this variable will be ignored.
 If that variable is nil, however, all headers that match this regexp
 will be kept while the rest will be deleted before saving."
 If `gnus-save-all-headers' is non-nil, this variable will be ignored.
 If that variable is nil, however, all headers that match this regexp
 will be kept while the rest will be deleted before saving."
@@ -291,7 +291,7 @@ will be kept while the rest will be deleted before saving."
   :type 'regexp)
 
 (defcustom gnus-default-article-saver 'gnus-summary-save-in-rmail
   :type 'regexp)
 
 (defcustom gnus-default-article-saver 'gnus-summary-save-in-rmail
-  "*A function to save articles in your favourite format.
+  "A function to save articles in your favourite format.
 The function must be interactively callable (in other words, it must
 be an Emacs command).
 
 The function must be interactively callable (in other words, it must
 be an Emacs command).
 
@@ -312,25 +312,25 @@ Gnus provides the following functions:
                (function-item gnus-summary-write-to-file)))
 
 (defcustom gnus-rmail-save-name 'gnus-plain-save-name
                (function-item gnus-summary-write-to-file)))
 
 (defcustom gnus-rmail-save-name 'gnus-plain-save-name
-  "*A function generating a file name to save articles in Rmail format.
+  "A function generating a file name to save articles in Rmail format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE."
   :group 'gnus-article-saving
   :type 'function)
 
 (defcustom gnus-mail-save-name 'gnus-plain-save-name
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE."
   :group 'gnus-article-saving
   :type 'function)
 
 (defcustom gnus-mail-save-name 'gnus-plain-save-name
-  "*A function generating a file name to save articles in Unix mail format.
+  "A function generating a file name to save articles in Unix mail format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE."
   :group 'gnus-article-saving
   :type 'function)
 
 (defcustom gnus-folder-save-name 'gnus-folder-save-name
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE."
   :group 'gnus-article-saving
   :type 'function)
 
 (defcustom gnus-folder-save-name 'gnus-folder-save-name
-  "*A function generating a file name to save articles in MH folder.
+  "A function generating a file name to save articles in MH folder.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER."
   :group 'gnus-article-saving
   :type 'function)
 
 (defcustom gnus-file-save-name 'gnus-numeric-save-name
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER."
   :group 'gnus-article-saving
   :type 'function)
 
 (defcustom gnus-file-save-name 'gnus-numeric-save-name
-  "*A function generating a file name to save articles in article format.
+  "A function generating a file name to save articles in article format.
 The function is called with NEWSGROUP, HEADERS, and optional
 LAST-FILE."
   :group 'gnus-article-saving
 The function is called with NEWSGROUP, HEADERS, and optional
 LAST-FILE."
   :group 'gnus-article-saving
@@ -369,7 +369,7 @@ be used as possible file names."
   :type 'boolean)
 
 (defcustom gnus-show-mime-method 'gnus-article-preview-mime-message
   :type 'boolean)
 
 (defcustom gnus-show-mime-method 'gnus-article-preview-mime-message
-  "*Function to process a MIME message.
+  "Function to process a MIME message.
 The function is called from the article buffer."
   :group 'gnus-article-mime
   :type 'function)
 The function is called from the article buffer."
   :group 'gnus-article-mime
   :type 'function)
@@ -415,7 +415,7 @@ If you want to run a special decoding program like nkf, use this hook."
   :group 'gnus-article-various)
 
 (defcustom gnus-article-button-face 'bold
   :group 'gnus-article-various)
 
 (defcustom gnus-article-button-face 'bold
-  "*Face used for highlighting buttons in the article buffer.
+  "Face used for highlighting buttons in the article buffer.
 
 An article button is a piece of text that you can activate by pressing
 `RET' or `mouse-2' above it."
 
 An article button is a piece of text that you can activate by pressing
 `RET' or `mouse-2' above it."
@@ -423,7 +423,7 @@ An article button is a piece of text that you can activate by pressing
   :group 'gnus-article-buttons)
 
 (defcustom gnus-article-mouse-face 'highlight
   :group 'gnus-article-buttons)
 
 (defcustom gnus-article-mouse-face 'highlight
-  "*Face used for mouse highlighting in the article buffer.
+  "Face used for mouse highlighting in the article buffer.
 
 Article buttons will be displayed in this face when the cursor is
 above them."
 
 Article buttons will be displayed in this face when the cursor is
 above them."
@@ -431,7 +431,7 @@ above them."
   :group 'gnus-article-buttons)
 
 (defcustom gnus-signature-face 'gnus-signature-face
   :group 'gnus-article-buttons)
 
 (defcustom gnus-signature-face 'gnus-signature-face
-  "*Face used for highlighting a signature in the article buffer.
+  "Face used for highlighting a signature in the article buffer.
 Obsolete; use the face `gnus-signature-face' for customizations instead."
   :type 'face
   :group 'gnus-article-highlight
 Obsolete; use the face `gnus-signature-face' for customizations instead."
   :type 'face
   :group 'gnus-article-highlight
@@ -641,6 +641,7 @@ always hide."
       (save-excursion
        (save-restriction
          (let ((buffer-read-only nil)
       (save-excursion
        (save-restriction
          (let ((buffer-read-only nil)
+               (case-fold-search t)
                (props (nconc (list 'article-type 'headers)
                              gnus-hidden-properties))
                (max (1+ (length gnus-sorted-header-list)))
                (props (nconc (list 'article-type 'headers)
                              gnus-hidden-properties))
                (max (1+ (length gnus-sorted-header-list)))
@@ -1382,13 +1383,14 @@ function and want to see what the date was before converting."
 
 (defun article-update-date-lapsed ()
   "Function to be run from a timer to update the lapsed time line."
 
 (defun article-update-date-lapsed ()
   "Function to be run from a timer to update the lapsed time line."
-  (save-excursion
-    (ignore-errors
-      (when (gnus-buffer-live-p gnus-article-buffer)
-       (set-buffer gnus-article-buffer)
-       (goto-char (point-min))
-       (when (re-search-forward "^X-Sent:" nil t)
-         (article-date-lapsed t))))))
+  (let (deactivate-mark)
+    (save-excursion
+      (ignore-errors
+        (when (gnus-buffer-live-p gnus-article-buffer)
+          (set-buffer gnus-article-buffer)
+          (goto-char (point-min))
+          (when (re-search-forward "^X-Sent:" nil t)
+            (article-date-lapsed t)))))))
 
 (defun gnus-start-date-timer (&optional n)
   "Start a timer to update the X-Sent header in the article buffers.
 
 (defun gnus-start-date-timer (&optional n)
   "Start a timer to update the X-Sent header in the article buffers.
@@ -1583,7 +1585,6 @@ This format is defined by the `gnus-article-time-format' variable."
   "Append this article to Rmail file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory'."
   "Append this article to Rmail file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory'."
-  (interactive)
   (setq filename (gnus-read-save-file-name
                  "Save %s in rmail file:" filename
                  gnus-rmail-save-name gnus-newsgroup-name
   (setq filename (gnus-read-save-file-name
                  "Save %s in rmail file:" filename
                  gnus-rmail-save-name gnus-newsgroup-name
@@ -1599,7 +1600,6 @@ Directory to save to is default to `gnus-article-save-directory'."
   "Append this article to Unix mail file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory'."
   "Append this article to Unix mail file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory'."
-  (interactive)
   (setq filename (gnus-read-save-file-name
                  "Save %s in Unix mail file:" filename
                  gnus-mail-save-name gnus-newsgroup-name
   (setq filename (gnus-read-save-file-name
                  "Save %s in Unix mail file:" filename
                  gnus-mail-save-name gnus-newsgroup-name
@@ -1618,7 +1618,6 @@ Directory to save to is default to `gnus-article-save-directory'."
   "Append this article to file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory'."
   "Append this article to file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory'."
-  (interactive)
   (setq filename (gnus-read-save-file-name
                  "Save %s in file:" filename
                  gnus-file-save-name gnus-newsgroup-name
   (setq filename (gnus-read-save-file-name
                  "Save %s in file:" filename
                  gnus-file-save-name gnus-newsgroup-name
@@ -1637,14 +1636,12 @@ Directory to save to is default to `gnus-article-save-directory'."
   "Write this article to a file.
 Optional argument FILENAME specifies file name.
 The directory to save in defaults to `gnus-article-save-directory'."
   "Write this article to a file.
 Optional argument FILENAME specifies file name.
 The directory to save in defaults to `gnus-article-save-directory'."
-  (interactive)
   (gnus-summary-save-in-file nil t))
 
 (defun gnus-summary-save-body-in-file (&optional filename)
   "Append this article body to a file.
 Optional argument FILENAME specifies file name.
 The directory to save in defaults to `gnus-article-save-directory'."
   (gnus-summary-save-in-file nil t))
 
 (defun gnus-summary-save-body-in-file (&optional filename)
   "Append this article body to a file.
 Optional argument FILENAME specifies file name.
 The directory to save in defaults to `gnus-article-save-directory'."
-  (interactive)
   (setq filename (gnus-read-save-file-name
                  "Save %s body in file:" filename
                  gnus-file-save-name gnus-newsgroup-name
   (setq filename (gnus-read-save-file-name
                  "Save %s body in file:" filename
                  gnus-file-save-name gnus-newsgroup-name
@@ -1661,7 +1658,6 @@ The directory to save in defaults to `gnus-article-save-directory'."
 
 (defun gnus-summary-save-in-pipe (&optional command)
   "Pipe this article to subprocess."
 
 (defun gnus-summary-save-in-pipe (&optional command)
   "Pipe this article to subprocess."
-  (interactive)
   (setq command
        (cond ((eq command 'default)
               gnus-last-shell-command)
   (setq command
        (cond ((eq command 'default)
               gnus-last-shell-command)
@@ -1775,8 +1771,6 @@ If variable `gnus-use-long-file-name' is non-nil, it is
      (article-fill . gnus-article-word-wrap)
      article-remove-cr
      article-display-x-face
      (article-fill . gnus-article-word-wrap)
      article-remove-cr
      article-display-x-face
-     article-de-quoted-unreadable
-     article-mime-decode-quoted-printable
      article-hide-pgp
      article-hide-pem
      article-hide-signature
      article-hide-pgp
      article-hide-pem
      article-hide-signature
@@ -1850,12 +1844,9 @@ If variable `gnus-use-long-file-name' is non-nil, it is
        ["Hide citation" gnus-article-hide-citation t]
        ["Treat overstrike" gnus-article-treat-overstrike t]
        ["Remove carriage return" gnus-article-remove-cr t]
        ["Hide citation" gnus-article-hide-citation t]
        ["Treat overstrike" gnus-article-treat-overstrike t]
        ["Remove carriage return" gnus-article-remove-cr t]
-       ["Remove quoted-unreadable" gnus-article-de-quoted-unreadable t]))
+       ))
 
 
-    (when nil
-      (when (boundp 'gnus-summary-article-menu)
-       (define-key gnus-article-mode-map [menu-bar commands]
-         (cons "Commands" gnus-summary-article-menu))))
+    ;; Note "Commands" menu is defined in gnus-sum.el for consistency
 
     (when (boundp 'gnus-summary-post-menu)
       (define-key gnus-article-mode-map [menu-bar post]
 
     (when (boundp 'gnus-summary-post-menu)
       (define-key gnus-article-mode-map [menu-bar post]
@@ -1881,7 +1872,6 @@ commands:
   (interactive)
   (when (gnus-visual-p 'article-menu 'menu)
     (gnus-article-make-menu-bar))
   (interactive)
   (when (gnus-visual-p 'article-menu 'menu)
     (gnus-article-make-menu-bar))
-  (kill-all-local-variables)
   (gnus-simplify-mode-line)
   (setq mode-name "Article")
   (setq major-mode 'gnus-article-mode)
   (gnus-simplify-mode-line)
   (setq mode-name "Article")
   (setq major-mode 'gnus-article-mode)
@@ -1891,9 +1881,9 @@ commands:
   (use-local-map gnus-article-mode-map)
   (gnus-update-format-specifications nil 'article-mode)
   (set (make-local-variable 'page-delimiter) gnus-page-delimiter)
   (use-local-map gnus-article-mode-map)
   (gnus-update-format-specifications nil 'article-mode)
   (set (make-local-variable 'page-delimiter) gnus-page-delimiter)
-  (set (make-local-variable 'gnus-page-broken) nil)
-  (set (make-local-variable 'gnus-button-marker-list) nil)
-  (set (make-local-variable 'gnus-article-current-summary) nil)
+  (make-local-variable 'gnus-page-broken) 
+  (make-local-variable 'gnus-button-marker-list) 
+  (make-local-variable 'gnus-article-current-summary) 
   (gnus-set-default-directory)
   (buffer-disable-undo (current-buffer))
   (setq buffer-read-only t)
   (gnus-set-default-directory)
   (buffer-disable-undo (current-buffer))
   (setq buffer-read-only t)
@@ -1957,6 +1947,7 @@ commands:
 
 ;;; @@ article filters
 ;;;
 
 ;;; @@ article filters
 ;;;
+
 (defun gnus-article-preview-mime-message ()
   (make-local-variable 'mime-button-mother-dispatcher)
   (setq mime-button-mother-dispatcher
 (defun gnus-article-preview-mime-message ()
   (make-local-variable 'mime-button-mother-dispatcher)
   (setq mime-button-mother-dispatcher
@@ -1967,16 +1958,14 @@ commands:
            default-mime-charset))
        )
     (save-excursion
            default-mime-charset))
        )
     (save-excursion
-      (mime-view-mode nil nil nil gnus-original-article-buffer
-                     gnus-article-buffer
-                     gnus-article-mode-map)
+      (mime-view-buffer gnus-original-article-buffer gnus-article-buffer
+                       nil gnus-article-mode-map)
       ))
   (run-hooks 'gnus-mime-article-prepare-hook)
   )
 
 (defun gnus-article-decode-encoded-word ()
       ))
   (run-hooks 'gnus-mime-article-prepare-hook)
   )
 
 (defun gnus-article-decode-encoded-word ()
-  "Header filter for gnus-article-mode.
-It is registered to variable `mime-view-content-header-filter-alist'."
+  "Header filter for gnus-article-mode."
   (let ((charset (save-excursion
                   (set-buffer gnus-summary-buffer)
                   default-mime-charset)))
   (let ((charset (save-excursion
                   (set-buffer gnus-summary-buffer)
                   default-mime-charset)))
@@ -2027,10 +2016,14 @@ If ALL-HEADERS is non-nil, no headers are hidden."
                      (cons gnus-newsgroup-name article))
                (set-buffer gnus-summary-buffer)
                (setq gnus-current-article article)
                      (cons gnus-newsgroup-name article))
                (set-buffer gnus-summary-buffer)
                (setq gnus-current-article article)
-               (gnus-summary-mark-article article gnus-canceled-mark))
-             (unless (memq article gnus-newsgroup-sparse)
-               (gnus-error
-                1 "No such article (may have expired or been canceled)")))
+               (if (eq (gnus-article-mark article) gnus-undownloaded-mark)
+                   (progn
+                     (gnus-summary-set-agent-mark article)
+                     (message "Message marked for downloading"))
+                 (gnus-summary-mark-article article gnus-canceled-mark)
+                 (unless (memq article gnus-newsgroup-sparse)
+                   (gnus-error 1 
+                    "No such article (may have expired or been canceled)")))))
          (if (or (eq result 'pseudo) (eq result 'nneething))
              (progn
                (save-excursion
          (if (or (eq result 'pseudo) (eq result 'nneething))
              (progn
                (save-excursion
@@ -2296,60 +2289,68 @@ Argument LINES specifies lines to be scrolled down."
   "Read a summary buffer key sequence and execute it from the article buffer."
   (interactive "P")
   (let ((nosaves
   "Read a summary buffer key sequence and execute it from the article buffer."
   (interactive "P")
   (let ((nosaves
-        '("q" "Q"  "c" "r" "R" "\C-c\C-f" "m"  "a" "f" "F"
-          "Zc" "ZC" "ZE" "ZQ" "ZZ" "Zn" "ZR" "ZG" "ZN" "ZP"
-          "=" "^" "\M-^" "|"))
-       (nosave-but-article
-        '("A\r"))
-       (nosave-in-article
-        '("\C-d"))
+         '("q" "Q"  "c" "r" "R" "\C-c\C-f" "m"  "a" "f" "F"
+           "Zc" "ZC" "ZE" "ZQ" "ZZ" "Zn" "ZR" "ZG" "ZN" "ZP"
+           "=" "^" "\M-^" "|"))
+        (nosave-but-article
+         '("A\r"))
+        (nosave-in-article
+         '("\C-d"))
         (up-to-top
          '("n" "Gn" "p" "Gp"))
         (up-to-top
          '("n" "Gn" "p" "Gp"))
-       keys)
+        keys new-sum-point)
     (save-excursion
       (set-buffer gnus-article-current-summary)
       (let (gnus-pick-mode)
     (save-excursion
       (set-buffer gnus-article-current-summary)
       (let (gnus-pick-mode)
-       (push (or key last-command-event) unread-command-events)
-       (setq keys (read-key-sequence nil))))
+        (push (or key last-command-event) unread-command-events)
+        (setq keys (read-key-sequence nil))))
     (message "")
 
     (if (or (member keys nosaves)
     (message "")
 
     (if (or (member keys nosaves)
-           (member keys nosave-but-article)
-           (member keys nosave-in-article))
-       (let (func)
-         (save-window-excursion
-           (pop-to-buffer gnus-article-current-summary 'norecord)
-           ;; We disable the pick minor mode commands.
-           (let (gnus-pick-mode)
-             (setq func (lookup-key (current-local-map) keys))))
-         (if (not func)
-             (ding)
-           (unless (member keys nosave-in-article)
-             (set-buffer gnus-article-current-summary))
-           (call-interactively func))
-         (when (member keys nosave-but-article)
-           (pop-to-buffer gnus-article-buffer 'norecord)))
+            (member keys nosave-but-article)
+            (member keys nosave-in-article))
+        (let (func)
+          (save-window-excursion
+            (pop-to-buffer gnus-article-current-summary 'norecord)
+            ;; We disable the pick minor mode commands.
+            (let (gnus-pick-mode)
+              (setq func (lookup-key (current-local-map) keys))))
+          (if (not func)
+              (ding)
+            (unless (member keys nosave-in-article)
+              (set-buffer gnus-article-current-summary))
+            (call-interactively func)
+            (setq new-sum-point (point)))
+          (when (member keys nosave-but-article)
+            (pop-to-buffer gnus-article-buffer 'norecord)))
       ;; These commands should restore window configuration.
       (let ((obuf (current-buffer))
       ;; These commands should restore window configuration.
       (let ((obuf (current-buffer))
-           (owin (current-window-configuration))
-           (opoint (point))
-           func in-buffer)
-       (if not-restore-window
-           (pop-to-buffer gnus-article-current-summary 'norecord)
-         (switch-to-buffer gnus-article-current-summary 'norecord))
-       (setq in-buffer (current-buffer))
-       ;; We disable the pick minor mode commands.
-       (if (setq func (let (gnus-pick-mode)
-                        (lookup-key (current-local-map) keys)))
-           (call-interactively func)
-         (ding))
-       (when (eq in-buffer (current-buffer))
-         (set-buffer obuf)
-         (unless not-restore-window
-           (set-window-configuration owin))
-          (unless (member keys up-to-top)
+            (owin (current-window-configuration))
+            (opoint (point))
+            (summary gnus-article-current-summary)
+            func in-buffer selected)
+        (if not-restore-window
+            (pop-to-buffer summary 'norecord)
+          (switch-to-buffer summary 'norecord))
+        (setq in-buffer (current-buffer))
+        ;; We disable the pick minor mode commands.
+        (if (setq func (let (gnus-pick-mode)
+                         (lookup-key (current-local-map) keys)))
+            (progn
+              (call-interactively func)
+              (setq new-sum-point (point)))
+          (ding))
+        (when (eq in-buffer (current-buffer))
+          (setq selected (gnus-summary-select-article))
+          (set-buffer obuf)
+          (unless not-restore-window
+            (set-window-configuration owin))
+          (unless (or (not (eq selected 'old)) (member keys up-to-top))
             (set-window-point (get-buffer-window (current-buffer))
             (set-window-point (get-buffer-window (current-buffer))
-                              opoint)))))))
+                              opoint))
+          (let ((win (get-buffer-window gnus-article-current-summary)))
+            (when win
+              (set-window-point win new-sum-point))))))))
 
 (defun gnus-article-hide (&optional arg force)
   "Hide all the gruft in the current article.
 
 (defun gnus-article-hide (&optional arg force)
   "Hide all the gruft in the current article.
@@ -2395,7 +2396,7 @@ If given a prefix, show the hidden text instead."
          (when (and (numberp article)
                     gnus-summary-buffer
                     (get-buffer gnus-summary-buffer)
          (when (and (numberp article)
                     gnus-summary-buffer
                     (get-buffer gnus-summary-buffer)
-                    (buffer-name (get-buffer gnus-summary-buffer)))
+                    (gnus-buffer-exists-p gnus-summary-buffer))
            (save-excursion
              (set-buffer gnus-summary-buffer)
              (let ((header (gnus-summary-article-header article)))
            (save-excursion
              (set-buffer gnus-summary-buffer)
              (let ((header (gnus-summary-article-header article)))
@@ -2419,8 +2420,8 @@ If given a prefix, show the hidden text instead."
 
                (let ((method (gnus-find-method-for-group
                               gnus-newsgroup-name)))
 
                (let ((method (gnus-find-method-for-group
                               gnus-newsgroup-name)))
-                 (if (not (eq (car method) 'nneething))
-                     ()
+                 (when (and (eq (car method) 'nneething)
+                            (vectorp header))
                    (let ((dir (concat (file-name-as-directory (nth 1 method))
                                       (mail-header-subject header))))
                      (when (file-directory-p dir)
                    (let ((dir (concat (file-name-as-directory (nth 1 method))
                                       (mail-header-subject header))))
                      (when (file-directory-p dir)
@@ -2432,7 +2433,7 @@ If given a prefix, show the hidden text instead."
           ((and (numberp article)
                 gnus-summary-buffer
                 (get-buffer gnus-summary-buffer)
           ((and (numberp article)
                 gnus-summary-buffer
                 (get-buffer gnus-summary-buffer)
-                (buffer-name (get-buffer gnus-summary-buffer))
+                (gnus-buffer-exists-p gnus-summary-buffer)
                 (eq (cdr (save-excursion
                            (set-buffer gnus-summary-buffer)
                            (assq article gnus-newsgroup-reads)))
                 (eq (cdr (save-excursion
                            (set-buffer gnus-summary-buffer)
                            (assq article gnus-newsgroup-reads)))
@@ -2489,7 +2490,7 @@ If given a prefix, show the hidden text instead."
                        (buffer-name (get-buffer gnus-article-buffer))))
        (save-excursion
          (if (get-buffer gnus-original-article-buffer)
                        (buffer-name (get-buffer gnus-article-buffer))))
        (save-excursion
          (if (get-buffer gnus-original-article-buffer)
-             (set-buffer (get-buffer gnus-original-article-buffer))
+             (set-buffer gnus-original-article-buffer)
            (set-buffer (get-buffer-create gnus-original-article-buffer))
            (buffer-disable-undo (current-buffer))
            (setq major-mode 'gnus-original-article-mode)
            (set-buffer (get-buffer-create gnus-original-article-buffer))
            (buffer-disable-undo (current-buffer))
            (setq major-mode 'gnus-original-article-mode)
@@ -2517,7 +2518,7 @@ If given a prefix, show the hidden text instead."
 ;;;
 
 (defcustom gnus-article-edit-mode-hook nil
 ;;;
 
 (defcustom gnus-article-edit-mode-hook nil
-  "*Hook run in article edit mode buffers."
+  "Hook run in article edit mode buffers."
   :group 'gnus-article-various
   :type 'hook)
 
   :group 'gnus-article-various
   :type 'hook)
 
@@ -2542,7 +2543,6 @@ This is an extended text-mode.
 
 \\{gnus-article-edit-mode-map}"
   (interactive)
 
 \\{gnus-article-edit-mode-map}"
   (interactive)
-  (kill-all-local-variables)
   (setq major-mode 'gnus-article-edit-mode)
   (setq mode-name "Article Edit")
   (use-local-map gnus-article-edit-mode-map)
   (setq major-mode 'gnus-article-edit-mode)
   (setq mode-name "Article Edit")
   (use-local-map gnus-article-edit-mode-map)
@@ -2667,20 +2667,22 @@ groups."
 ;;; Internal Variables:
 
 (defcustom gnus-button-url-regexp "\\b\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)"
 ;;; Internal Variables:
 
 (defcustom gnus-button-url-regexp "\\b\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)"
-  "*Regular expression that matches URLs."
+  "Regular expression that matches URLs."
   :group 'gnus-article-buttons
   :type 'regexp)
 
 (defcustom gnus-button-alist
   :group 'gnus-article-buttons
   :type 'regexp)
 
 (defcustom gnus-button-alist
-  `(("<\\(url: ?\\)?news:\\([^>\n\t ]*@[^>\n\t ]*\\)>" 0 t
+  `(("<\\(url:[>\n\t ]*?\\)?news:[>\n\t ]*\\([^>\n\t ]*@[^>\n\t ]*\\)>" 0 t
      gnus-button-message-id 2)
     ("\\bnews:\\([^>\n\t ]*@[^>\n\t ]*\\)" 0 t gnus-button-message-id 1)
      gnus-button-message-id 2)
     ("\\bnews:\\([^>\n\t ]*@[^>\n\t ]*\\)" 0 t gnus-button-message-id 1)
-    ("\\(\\b<\\(url: ?\\)?news:\\(//\\)?\\([^>\n\t ]*\\)>\\)" 1 t
+    ("\\(\\b<\\(url:[>\n\t ]*\\)?news:[>\n\t ]*\\(//\\)?\\([^>\n\t ]*\\)>\\)"
+     1 t
      gnus-button-fetch-group 4)
     ("\\bnews:\\(//\\)?\\([^'\">\n\t ]+\\)" 0 t gnus-button-fetch-group 2)
     ("\\bin\\( +article\\| +message\\)? +\\(<\\([^\n @<>]+@[^\n @<>]+\\)>\\)" 2
      t gnus-button-message-id 3)
     ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 0 t gnus-url-mailto 2)
      gnus-button-fetch-group 4)
     ("\\bnews:\\(//\\)?\\([^'\">\n\t ]+\\)" 0 t gnus-button-fetch-group 2)
     ("\\bin\\( +article\\| +message\\)? +\\(<\\([^\n @<>]+@[^\n @<>]+\\)>\\)" 2
      t gnus-button-message-id 3)
     ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 0 t gnus-url-mailto 2)
+    ("mailto:\\([a-zA-Z.-@_+0-9%]+\\)" 0 t gnus-url-mailto 2)
     ("\\bmailto:\\([^ \n\t]+\\)" 0 t gnus-url-mailto 1)
     ;; This is how URLs _should_ be embedded in text...
     ("<URL: *\\([^>]*\\)>" 0 t gnus-button-embedded-url 1)
     ("\\bmailto:\\([^ \n\t]+\\)" 0 t gnus-url-mailto 1)
     ;; This is how URLs _should_ be embedded in text...
     ("<URL: *\\([^>]*\\)>" 0 t gnus-button-embedded-url 1)
@@ -3233,14 +3235,17 @@ forbidden in URL encoding."
 ;;; @ for mime-view
 ;;;
 
 ;;; @ for mime-view
 ;;;
 
-(defun gnus-content-header-filter ()
-  "Header filter for mime-view.
-It is registered to variable `mime-view-content-header-filter-alist'."
-  (eword-decode-header default-mime-charset))
+(defun gnus-article-header-presentation-method (entity situation)
+  (mime-insert-decoded-header entity nil nil default-mime-charset)
+  )
+
+(set-alist 'mime-header-presentation-method-alist
+          'gnus-original-article-mode
+          #'gnus-article-header-presentation-method)
 
 
-(defun mime-view-quitting-method-for-gnus ()
+(defun mime-preview-quitting-method-for-gnus ()
   (if (not gnus-show-mime)
   (if (not gnus-show-mime)
-      (mime-view-kill-buffer))
+      (mime-preview-kill-buffer))
   (delete-other-windows)
   (gnus-article-show-summary)
   (if (or (not gnus-show-mime)
   (delete-other-windows)
   (gnus-article-show-summary)
   (if (or (not gnus-show-mime)
@@ -3248,21 +3253,27 @@ It is registered to variable `mime-view-content-header-filter-alist'."
       (gnus-summary-select-article nil t)
     ))
 
       (gnus-summary-select-article nil t)
     ))
 
-(set-alist 'mime-view-content-header-filter-alist
-          'gnus-original-article-mode
-          (function gnus-content-header-filter))
-
-(set-alist 'mime-text-decoder-alist
-          'gnus-original-article-mode
-          (function mime-text-decode-buffer))
+(set-alist 'mime-raw-representation-type-alist
+          'gnus-original-article-mode 'binary)
 
 
-(set-alist 'mime-view-quitting-method-alist
+(set-alist 'mime-preview-quitting-method-alist
           'gnus-original-article-mode
           'gnus-original-article-mode
-          (function mime-view-quitting-method-for-gnus))
+          #'mime-preview-quitting-method-for-gnus)
 
 (set-alist 'mime-view-show-summary-method
           'gnus-original-article-mode
 
 (set-alist 'mime-view-show-summary-method
           'gnus-original-article-mode
-          (function mime-view-quitting-method-for-gnus))
+          #'mime-preview-quitting-method-for-gnus)
+
+(defun gnus-following-method (buf)
+  (set-buffer buf)
+  (message-followup)
+  (message-yank-original)
+  (kill-buffer buf)
+  (goto-char (point-min))
+  )
+
+(set-alist 'mime-preview-following-method-alist
+          'gnus-original-article-mode #'gnus-following-method)
 
 
 ;;; @ end
 
 
 ;;; @ end