Check SEMI-0.118.2 (Otomaru) or later.
[elisp/gnus.git-] / lisp / gnus-sum.el
index e6cfd03..6159182 100644 (file)
@@ -1,8 +1,9 @@
-;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996,97 Free Software Foundation, Inc.
+;;; gnus-sum.el --- summary mode commands for Semi-gnus
+;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
-;; Keywords: news
+;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;; Keywords: mail, news, MIME
 
 ;; This file is part of GNU Emacs.
 
 (require 'gnus-range)
 (require 'gnus-int)
 (require 'gnus-undo)
+(require 'std11)
+(require 'mime-view)
+
+(or (string< "1" eword-decode-version)
+    (error "Please install latest SEMI."))
+
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
+(autoload 'gnus-set-summary-default-charset "gnus-i18n" nil t)
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
@@ -121,7 +129,7 @@ comparing subjects."
                 (sexp :menu-tag "on" t)))
 
 (defcustom gnus-simplify-subject-functions nil
-  "List of functions taking a string argument that simplify subjects.
+  "*List of functions taking a string argument that simplify subjects.
 The functions are applied recursively."
   :group 'gnus-thread
   :type '(repeat (list function)))
@@ -145,7 +153,7 @@ non-nil and non-`some', fill in all gaps that Gnus manages to guess."
 
 (defcustom gnus-summary-thread-gathering-function
   'gnus-gather-threads-by-subject
-  "Function used for gathering loose threads.
+  "*Function used for gathering loose threads.
 There are two pre-defined functions: `gnus-gather-threads-by-subject',
 which only takes Subjects into consideration; and
 `gnus-gather-threads-by-references', which compared the References
@@ -322,7 +330,7 @@ variable."
   :group 'gnus-article-various
   :type 'boolean)
 
-(defcustom gnus-show-mime nil
+(defcustom gnus-show-mime t
   "*If non-nil, do mime processing of articles.
 The articles will simply be fed to the function given by
 `gnus-show-mime-method'."
@@ -572,14 +580,14 @@ Some functions you can use are `+', `max', or `min'."
   :type 'function)
 
 (defcustom gnus-summary-expunge-below nil
-  "All articles that have a score less than this variable will be expunged.
+  "*All articles that have a score less than this variable will be expunged.
 This variable is local to the summary buffers."
   :group 'gnus-score-default
   :type '(choice (const :tag "off" nil)
                 integer))
 
 (defcustom gnus-thread-expunge-below nil
-  "All threads that have a total score less than this variable will be expunged.
+  "*All threads that have a total score less than this variable will be expunged.
 See `gnus-thread-score-function' for en explanation of what a
 \"thread score\" is.
 
@@ -657,18 +665,24 @@ is not run if `gnus-visual' is nil."
   :type 'hook)
 
 ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
-(defcustom gnus-structured-field-decoder 'identity
-  "Function to decode non-ASCII characters in structured field for summary."
+(defcustom gnus-structured-field-decoder
+  #'eword-decode-and-unfold-structured-field
+  "*Function to decode non-ASCII characters in structured field for summary."
   :group 'gnus-various
   :type 'function)
 
-(defcustom gnus-unstructured-field-decoder 'identity
-  "Function to decode non-ASCII characters in unstructured field for summary."
+(defcustom gnus-unstructured-field-decoder
+  (function
+   (lambda (string)
+     (eword-decode-unstructured-field-body
+      (std11-unfold-string string) 'must-unfold)
+     ))
+  "*Function to decode non-ASCII characters in unstructured field for summary."
   :group 'gnus-various
   :type 'function)
 
 (defcustom gnus-parse-headers-hook
-  (list 'gnus-hack-decode-rfc1522 'gnus-decode-rfc1522)
+  '(gnus-set-summary-default-charset)
   "*A hook called before parsing the headers."
   :group 'gnus-various
   :type 'hook)
@@ -707,7 +721,7 @@ automatically when it is selected."
   :type 'hook)
 
 (defcustom gnus-summary-selected-face 'gnus-summary-selected-face
-  "Face used for highlighting the current article in the summary buffer."
+  "*Face used for highlighting the current article in the summary buffer."
   :group 'gnus-summary-visual
   :type 'face)
 
@@ -744,7 +758,7 @@ automatically when it is selected."
      . gnus-summary-low-read-face)
     (t
      . gnus-summary-normal-read-face))
-  "Controls the highlighting of summary buffer lines.
+  "*Controls the highlighting of summary buffer lines.
 
 A list of (FORM . FACE) pairs.  When deciding how a a particular
 summary line should be displayed, each form is evaluated.  The content
@@ -762,7 +776,7 @@ mark:    The articles mark."
                       face)))
 
 (defcustom gnus-alter-header-function nil
-  "Function called to allow alteration of article header structures.
+  "*Function called to allow alteration of article header structures.
 The function is called with one parameter, the article header vector,
 which it may alter in any way.")
 
@@ -1128,6 +1142,7 @@ increase the score of each group you read."
     [delete] gnus-summary-prev-page
     [backspace] gnus-summary-prev-page
     "\r" gnus-summary-scroll-up
+    "\e\r" gnus-summary-scroll-down
     "n" gnus-summary-next-unread-article
     "p" gnus-summary-prev-unread-article
     "N" gnus-summary-next-article
@@ -1209,9 +1224,11 @@ increase the score of each group you read."
     "t" gnus-article-hide-headers
     "g" gnus-summary-show-article
     "l" gnus-summary-goto-last-article
+    "v" gnus-summary-preview-mime-message
     "\C-c\C-v\C-v" gnus-uu-decode-uu-view
     "\C-d" gnus-summary-enter-digest-group
     "\M-\C-d" gnus-summary-read-document
+    "\M-\C-e" gnus-summary-edit-parameters
     "\C-c\C-b" gnus-bug
     "*" gnus-cache-enter-article
     "\M-*" gnus-cache-remove-article
@@ -1383,6 +1400,7 @@ increase the score of each group you read."
     "l" gnus-article-date-local
     "e" gnus-article-date-lapsed
     "o" gnus-article-date-original
+    "i" gnus-article-date-iso8601
     "s" gnus-article-date-user)
 
   (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
@@ -1584,6 +1602,7 @@ increase the score of each group you read."
        ["Citation" gnus-article-highlight-citation t])
        ("Date"
        ["Local" gnus-article-date-local t]
+       ["ISO8601" gnus-article-date-iso8601 t]
        ["UT" gnus-article-date-ut t]
        ["Original" gnus-article-date-original t]
        ["Lapsed" gnus-article-date-lapsed t]
@@ -1813,6 +1832,7 @@ increase the score of each group you read."
         'request-expire-articles gnus-newsgroup-name)]
        ["Edit local kill file" gnus-summary-edit-local-kill t]
        ["Edit main kill file" gnus-summary-edit-global-kill t]
+       ["Edit group parameters" gnus-summary-edit-parameters t]
        ("Exit"
        ["Catchup and exit" gnus-summary-catchup-and-exit t]
        ["Catchup all and exit" gnus-summary-catchup-and-exit t]
@@ -1825,7 +1845,7 @@ increase the score of each group you read."
        ["Rescan group" gnus-summary-rescan-group t]
        ["Update dribble" gnus-summary-save-newsrc t])))
 
-    (run-hooks 'gnus-summary-menu-hook)))
+    (gnus-run-hooks 'gnus-summary-menu-hook)))
 
 (defun gnus-score-set-default (var value)
   "A version of set that updates the GNU Emacs menu-bar."
@@ -1960,7 +1980,7 @@ The following commands are available:
   (add-hook 'post-command-hook 'gnus-clear-inboxes-moved nil t)
   (make-local-hook 'pre-command-hook)
   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
-  (run-hooks 'gnus-summary-mode-hook)
+  (gnus-run-hooks 'gnus-summary-mode-hook)
   (gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
   (gnus-update-summary-mark-positions))
 
@@ -2171,10 +2191,12 @@ article number."
         (gnus-summary-last-subject))))
 
 (defmacro gnus-summary-article-header (&optional number)
+  "Return the header of article NUMBER."
   `(gnus-data-header (gnus-data-find
                      ,(or number '(gnus-summary-article-number)))))
 
 (defmacro gnus-summary-thread-level (&optional number)
+  "Return the level of thread that starts with article NUMBER."
   `(if (and (eq gnus-summary-make-false-root 'dummy)
            (get-text-property (point) 'gnus-intangible))
        0
@@ -2182,10 +2204,12 @@ article number."
                       ,(or number '(gnus-summary-article-number))))))
 
 (defmacro gnus-summary-article-mark (&optional number)
+  "Return the mark of article NUMBER."
   `(gnus-data-mark (gnus-data-find
                    ,(or number '(gnus-summary-article-number)))))
 
 (defmacro gnus-summary-article-pos (&optional number)
+  "Return the position of the line of article NUMBER."
   `(gnus-data-pos (gnus-data-find
                   ,(or number '(gnus-summary-article-number)))))
 
@@ -2208,6 +2232,7 @@ article number."
        gnus-summary-default-score 0))
 
 (defun gnus-summary-article-children (&optional number)
+  "Return a list of article numbers that are children of article NUMBER."
   (let* ((data (gnus-data-find-list (or number (gnus-summary-article-number))))
         (level (gnus-data-level (car data)))
         l children)
@@ -2219,6 +2244,7 @@ article number."
     (nreverse children)))
 
 (defun gnus-summary-article-parent (&optional number)
+  "Return the article number of the parent of article NUMBER."
   (let* ((data (gnus-data-find-list (or number (gnus-summary-article-number))
                                    (gnus-data-list t)))
         (level (gnus-data-level (car data))))
@@ -2243,6 +2269,11 @@ This is all marks except unread, ticked, dormant, and expirable."
           (= mark gnus-expirable-mark))))
 
 (defmacro gnus-article-mark (number)
+  "Return the MARK of article NUMBER.
+This macro should only be used when computing the mark the \"first\"
+time; i.e., when generating the summary lines.  After that,
+`gnus-summary-article-mark' should be used to examine the
+marks of articles."
   `(cond
     ((memq ,number gnus-newsgroup-unsendable) gnus-unsendable-mark)
     ((memq ,number gnus-newsgroup-undownloaded) gnus-undownloaded-mark)
@@ -2496,7 +2527,7 @@ This is all marks except unread, ticked, dormant, and expirable."
      'gnus-number gnus-tmp-number)
     (when (gnus-visual-p 'summary-highlight 'highlight)
       (forward-line -1)
-      (run-hooks 'gnus-summary-update-hook)
+      (gnus-run-hooks 'gnus-summary-update-hook)
       (forward-line 1))))
 
 (defun gnus-summary-update-line (&optional dont-update)
@@ -2528,7 +2559,7 @@ This is all marks except unread, ticked, dormant, and expirable."
         'score))
       ;; Do visual highlighting.
       (when (gnus-visual-p 'summary-highlight 'highlight)
-       (run-hooks 'gnus-summary-update-hook)))))
+       (gnus-run-hooks 'gnus-summary-update-hook)))))
 
 (defvar gnus-tmp-new-adopts nil)
 
@@ -2659,7 +2690,7 @@ If NO-DISPLAY, don't generate a summary buffer."
            (gnus-copy-sequence
             (gnus-active gnus-newsgroup-name)))
       ;; You can change the summary buffer in some way with this hook.
-      (run-hooks 'gnus-select-group-hook)
+      (gnus-run-hooks 'gnus-select-group-hook)
       ;; Set any local variables in the group parameters.
       (gnus-summary-set-local-parameters gnus-newsgroup-name)
       (gnus-update-format-specifications
@@ -2697,7 +2728,7 @@ If NO-DISPLAY, don't generate a summary buffer."
              ((and gnus-newsgroup-scored show-all)
               (gnus-summary-limit-include-expunged t))))
       ;; Function `gnus-apply-kill-file' must be called in this hook.
-      (run-hooks 'gnus-apply-kill-hook)
+      (gnus-run-hooks 'gnus-apply-kill-hook)
       (if (and (zerop (buffer-size))
               (not no-display))
          (progn
@@ -2741,7 +2772,7 @@ If NO-DISPLAY, don't generate a summary buffer."
            (select-window owin)))
        ;; Mark this buffer as "prepared".
        (setq gnus-newsgroup-prepared t)
-       (run-hooks 'gnus-summary-prepared-hook)
+       (gnus-run-hooks 'gnus-summary-prepared-hook)
        t)))))
 
 (defun gnus-summary-prepare ()
@@ -2751,7 +2782,7 @@ If NO-DISPLAY, don't generate a summary buffer."
     (erase-buffer)
     (setq gnus-newsgroup-data nil
          gnus-newsgroup-data-reverse nil)
-    (run-hooks 'gnus-summary-generate-hook)
+    (gnus-run-hooks 'gnus-summary-generate-hook)
     ;; Generate the buffer, either with threads or without.
     (when gnus-newsgroup-headers
       (gnus-summary-prepare-threads
@@ -2765,7 +2796,7 @@ If NO-DISPLAY, don't generate a summary buffer."
     (setq gnus-newsgroup-data (nreverse gnus-newsgroup-data))
     ;; Call hooks for modifying summary buffer.
     (goto-char (point-min))
-    (run-hooks 'gnus-summary-prepare-hook)))
+    (gnus-run-hooks 'gnus-summary-prepare-hook)))
 
 (defsubst gnus-general-simplify-subject (subject)
   "Simply subject by the same rules as gnus-gather-threads-by-subject."
@@ -3691,7 +3722,7 @@ or a straight list of headers."
             'gnus-number number)
            (when gnus-visual-p
              (forward-line -1)
-             (run-hooks 'gnus-summary-update-hook)
+             (gnus-run-hooks 'gnus-summary-update-hook)
              (forward-line 1))
 
            (setq gnus-tmp-prev-subject subject)))
@@ -4282,7 +4313,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
       (set-buffer nntp-server-buffer)
       ;; Translate all TAB characters into SPACE characters.
       (subst-char-in-region (point-min) (point-max) ?\t ?  t)
-      (run-hooks 'gnus-parse-headers-hook)
+      (gnus-run-hooks 'gnus-parse-headers-hook)
       (let ((case-fold-search t)
            in-reply-to header p lines)
        (goto-char (point-min))
@@ -4313,7 +4344,6 @@ The resulting hash table is returned, or nil if no Xrefs were found."
            (progn
              (goto-char p)
              (if (search-forward "\nsubject: " nil t)
-                 ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
                  (funcall
                   gnus-unstructured-field-decoder (nnheader-header-value))
                "(none)"))
@@ -4321,7 +4351,6 @@ The resulting hash table is returned, or nil if no Xrefs were found."
            (progn
              (goto-char p)
              (if (search-forward "\nfrom: " nil t)
-                 ;; 1997/5/4 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
                  (funcall
                   gnus-structured-field-decoder (nnheader-header-value))
                "(nobody)"))
@@ -4485,7 +4514,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                         (setq ref
                               (buffer-substring
                                (1+ (point))
-                               (search-backward "<" beg t)))
+                               (or (search-backward "<" beg t) beg)))
                       (setq ref nil))
                     (goto-char beg))
                   (gnus-nov-field))    ; refs
@@ -4553,7 +4582,7 @@ list of headers that match SEQUENCE (see `nntp-retrieve-headers')."
     (save-excursion
       (set-buffer nntp-server-buffer)
       ;; Allow the user to mangle the headers before parsing them.
-      (run-hooks 'gnus-parse-headers-hook)
+      (gnus-run-hooks 'gnus-parse-headers-hook)
       (goto-char (point-min))
       (while (not (eobp))
        (condition-case ()
@@ -4661,44 +4690,47 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
   "Return a list of articles to be worked upon.         The prefix argument,
 the list of process marked articles, and the current article will be
 taken into consideration."
-  (cond
-   (n
-    ;; A numerical prefix has been given.
-    (setq n (prefix-numeric-value n))
-    (let ((backward (< n 0))
-         (n (abs (prefix-numeric-value n)))
-         articles article)
-      (save-excursion
-       (while
-           (and (> n 0)
-                (push (setq article (gnus-summary-article-number))
-                      articles)
-                (if backward
-                    (gnus-summary-find-prev nil article)
-                  (gnus-summary-find-next nil article)))
-         (decf n)))
-      (nreverse articles)))
-   ((gnus-region-active-p)
-    ;; Work on the region between point and mark.
-    (let ((max (max (point) (mark)))
-         articles article)
-      (save-excursion
-       (goto-char (min (point) (mark)))
-       (while
-           (and
-            (push (setq article (gnus-summary-article-number)) articles)
-            (gnus-summary-find-next nil article)
-            (< (point) max)))
-       (nreverse articles))))
-   (gnus-newsgroup-processable
-    ;; There are process-marked articles present.
-    ;; Save current state.
-    (gnus-summary-save-process-mark)
-    ;; Return the list.
-    (reverse gnus-newsgroup-processable))
-   (t
-    ;; Just return the current article.
-    (list (gnus-summary-article-number)))))
+  (save-excursion
+    (set-buffer gnus-summary-buffer)
+    (cond
+     (n
+      ;; A numerical prefix has been given.
+      (setq n (prefix-numeric-value n))
+      (let ((backward (< n 0))
+           (n (abs (prefix-numeric-value n)))
+           articles article)
+       (save-excursion
+         (while
+             (and (> n 0)
+                  (push (setq article (gnus-summary-article-number))
+                        articles)
+                  (if backward
+                      (gnus-summary-find-prev nil article)
+                    (gnus-summary-find-next nil article)))
+           (decf n)))
+       (nreverse articles)))
+     ((and (gnus-region-active-p) (mark))
+      (message "region active")
+      ;; Work on the region between point and mark.
+      (let ((max (max (point) (mark)))
+           articles article)
+       (save-excursion
+         (goto-char (min (point) (mark)))
+         (while
+             (and
+              (push (setq article (gnus-summary-article-number)) articles)
+              (gnus-summary-find-next nil article)
+              (< (point) max)))
+         (nreverse articles))))
+     (gnus-newsgroup-processable
+      ;; There are process-marked articles present.
+      ;; Save current state.
+      (gnus-summary-save-process-mark)
+      ;; Return the list.
+      (reverse gnus-newsgroup-processable))
+     (t
+      ;; Just return the current article.
+      (list (gnus-summary-article-number))))))
 
 (defun gnus-summary-save-process-mark ()
   "Push the current set of process marked articles on the stack."
@@ -5053,7 +5085,7 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
         (mode major-mode)
          (group-point nil)
         (buf (current-buffer)))
-    (run-hooks 'gnus-summary-prepare-exit-hook)
+    (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)
@@ -5066,9 +5098,11 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
       (gnus-dup-enter-articles))
     (when gnus-use-trees
       (gnus-tree-close group))
+    ;; Remove entries for this group.
+    (nnmail-purge-split-history group)
     ;; Make all changes in this group permanent.
     (unless quit-config
-      (run-hooks 'gnus-exit-group-hook)
+      (gnus-run-hooks 'gnus-exit-group-hook)
       (gnus-summary-update-info)
       ;; Do adaptive scoring, and possibly save score files.
       (when gnus-newsgroup-adaptive
@@ -5080,7 +5114,7 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
     (set-buffer gnus-group-buffer)
     (unless quit-config
       (gnus-group-jump-to-group group))
-    (run-hooks 'gnus-summary-exit-hook)
+    (gnus-run-hooks 'gnus-summary-exit-hook)
     (unless (or quit-config
                ;; If this group has disappeared from the summary
                ;; buffer, don't skip forwards.
@@ -5192,6 +5226,28 @@ which existed when entering the ephemeral is reset."
       (gnus-summary-recenter)
       (gnus-summary-position-point))))
 
+(defun gnus-summary-preview-mime-message (arg)
+  "MIME decode and play this message."
+  (interactive "P")
+  (let ((gnus-break-pages nil))
+    (gnus-summary-select-article t t)
+    )
+  (pop-to-buffer gnus-original-article-buffer t)
+  (let (buffer-read-only)
+    (if (text-property-any (point-min) (point-max) 'invisible t)
+       (remove-text-properties (point-min) (point-max)
+                               gnus-hidden-properties)
+      ))
+  (mime-view-mode nil nil nil gnus-original-article-buffer
+                 gnus-article-buffer)
+  )
+
+(defun gnus-summary-scroll-down ()
+  "Scroll down one line current article."
+  (interactive)
+  (gnus-summary-scroll-up -1)
+  )
+
 ;;; Dead summaries.
 
 (defvar gnus-dead-summary-mode-map nil)
@@ -5340,7 +5396,7 @@ previous group instead."
            (when (gnus-buffer-live-p current-buffer)
              (set-buffer current-buffer)
              (gnus-summary-exit))
-           (run-hooks 'gnus-group-no-more-groups-hook))
+           (gnus-run-hooks 'gnus-group-no-more-groups-hook))
        ;; We try to enter the target group.
        (gnus-group-jump-to-group target-group)
        (let ((unreads (gnus-group-group-unread)))
@@ -5468,7 +5524,7 @@ Given a prefix, will force an `article' buffer configuration."
        (if gnus-summary-display-article-function
            (funcall gnus-summary-display-article-function article all-header)
          (gnus-article-prepare article all-header))
-      (run-hooks 'gnus-select-article-hook)
+      (gnus-run-hooks 'gnus-select-article-hook)
       (when (and gnus-current-article
                 (not (zerop gnus-current-article)))
        (gnus-summary-goto-subject gnus-current-article))
@@ -5846,7 +5902,7 @@ If ALL-HEADERS is non-nil, no header lines are hidden."
   (interactive)
   (prog1
       (when gnus-last-article
-       (gnus-summary-goto-article gnus-last-article))
+       (gnus-summary-goto-article gnus-last-article nil t))
     (gnus-summary-position-point)))
 
 (defun gnus-summary-pop-article (number)
@@ -6421,6 +6477,10 @@ or `gnus-select-method', no matter what backend the article comes from."
              (gnus-summary-select-article nil nil nil number)
            (gnus-message 3 "Couldn't fetch article %s" message-id))))))))
 
+(defun gnus-summary-edit-parameters ()
+  "Edit the group parameters of the current group."
+  (gnus-group-edit-group gnus-newsgroup-name 'params))
+
 (defun gnus-summary-enter-digest-group (&optional force)
   "Enter an nndoc group based on the current article.
 If FORCE, force a digest interpretation.  If not, try
@@ -6709,8 +6769,8 @@ that name.  If FILENAME is a number, prompt the user for the name of the file
 to save in."
   (interactive (list (ps-print-preprint current-prefix-arg)
                     current-prefix-arg))
-  (dolist (nbr (gnus-summary-work-articles n))
-    (gnus-summary-select-article 'all nil 'pseudo nbr)
+  (dolist (article (gnus-summary-work-articles n))
+    (gnus-summary-select-article nil nil 'pseudo article)
     (gnus-eval-in-buffer-window gnus-article-buffer
       (let ((buffer (generate-new-buffer " *print*")))
        (unwind-protect
@@ -6729,7 +6789,7 @@ to save in."
                      "/pagenumberstring load" 
                      (concat "("
                              (mail-header-date gnus-current-headers) ")"))))
-               (run-hooks 'gnus-ps-print-hook)
+               (gnus-run-hooks 'gnus-ps-print-hook)
                (ps-print-buffer-with-faces filename)))
          (kill-buffer buffer))))))
 
@@ -6788,7 +6848,7 @@ If ARG is a negative number, hide the unwanted header lines."
        (setq e (1- (or (search-forward "\n\n" nil t) (point-max)))))
       (insert-buffer-substring gnus-original-article-buffer 1 e)
       (let ((article-inhibit-hiding t))
-       (run-hooks 'gnus-article-display-hook))
+       (gnus-run-hooks 'gnus-article-display-hook))
       (when (or (not hidden) (and (numberp arg) (< arg 0)))
        (gnus-article-hide-headers)))))
 
@@ -7033,6 +7093,9 @@ and `request-accept' functions."
              (gnus-request-replace-article
               article gnus-newsgroup-name (current-buffer)))))
 
+       ;;;!!!Why is this necessary?
+       (set-buffer gnus-summary-buffer)
+       
        (gnus-summary-goto-subject article)
        (when (eq action 'move)
          (gnus-summary-mark-article article gnus-canceled-mark))))
@@ -7063,7 +7126,7 @@ re-spool using this method."
   (gnus-summary-move-article n nil nil 'crosspost))
 
 (defcustom gnus-summary-respool-default-method nil
-  "Default method for respooling an article.
+  "*Default method for respooling an article.
 If nil, use to the current newsgroup method."
   :type `(choice (gnus-select-method :value (nnml ""))
                 (const nil))
@@ -7173,7 +7236,7 @@ This will be the case if the article has both been mailed and posted."
                            ;; We need to update the info for
                            ;; this group for `gnus-list-of-read-articles'
                            ;; to give us the right answer.
-                           (run-hooks 'gnus-exit-group-hook)
+                           (gnus-run-hooks 'gnus-exit-group-hook)
                            (gnus-summary-update-info)
                            (gnus-list-of-read-articles gnus-newsgroup-name))
                        (setq gnus-newsgroup-expirable
@@ -7187,13 +7250,14 @@ This will be the case if the article has both been mailed and posted."
        ;; through the expiry process.
        (gnus-message 6 "Expiring articles...")
        ;; The list of articles that weren't expired is returned.
-       (if expiry-wait
-           (let ((nnmail-expiry-wait-function nil)
-                 (nnmail-expiry-wait expiry-wait))
-             (setq es (gnus-request-expire-articles
-                       expirable gnus-newsgroup-name)))
-         (setq es (gnus-request-expire-articles
-                   expirable gnus-newsgroup-name)))
+       (save-excursion
+         (if expiry-wait
+             (let ((nnmail-expiry-wait-function nil)
+                   (nnmail-expiry-wait expiry-wait))
+               (setq es (gnus-request-expire-articles
+                         expirable gnus-newsgroup-name)))
+           (setq es (gnus-request-expire-articles
+                     expirable gnus-newsgroup-name))))
        (unless total
          (setq gnus-newsgroup-expirable es))
        ;; We go through the old list of expirable, and mark all
@@ -7213,10 +7277,10 @@ This will be the case if the article has both been mailed and posted."
 This means that *all* articles that are marked as expirable will be
 deleted forever, right now."
   (interactive)
-  (or gnus-expert-user
-      (gnus-yes-or-no-p
-       "Are you really, really, really sure you want to delete all these messages? ")
-      (error "Phew!"))
+  (unless gnus-expert-user
+    (gnus-yes-or-no-p
+     "Are you really, really, really sure you want to delete all these messages? ")
+    (error "Phew!"))
   (gnus-summary-expire-articles t))
 
 ;; Suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.
@@ -7329,14 +7393,14 @@ groups."
     (unless no-highlight
       (save-excursion
        (set-buffer gnus-article-buffer)
-       (run-hooks 'gnus-article-display-hook)
+       (gnus-run-hooks 'gnus-article-display-hook)
        (set-buffer gnus-original-article-buffer)
        (gnus-request-article
         (cdr gnus-article-current)
         (car gnus-article-current) (current-buffer))))
     ;; Prettify the summary buffer line.
     (when (gnus-visual-p 'summary-highlight 'highlight)
-      (run-hooks 'gnus-visual-mark-article-hook))))
+      (gnus-run-hooks 'gnus-visual-mark-article-hook))))
 
 (defun gnus-summary-edit-wash (key)
   "Perform editing command in the article buffer."
@@ -7616,38 +7680,41 @@ returned."
 
 (defun gnus-summary-mark-article-as-unread (mark)
   "Mark the current article quickly as unread with MARK."
-  (let ((article (gnus-summary-article-number)))
-    (if (<= article 0)
-       (progn
-         (gnus-error 1 "Can't mark negative article numbers")
-         nil)
-      (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
-      (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
-      (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
-      (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
-      (cond ((= mark gnus-ticked-mark)
-            (push article gnus-newsgroup-marked))
-           ((= mark gnus-dormant-mark)
-            (push article gnus-newsgroup-dormant))
-           (t
-            (push article gnus-newsgroup-unreads)))
-      (setq gnus-newsgroup-reads
-           (delq (assq article gnus-newsgroup-reads)
-                 gnus-newsgroup-reads))
-
-      ;; See whether the article is to be put in the cache.
-      (and gnus-use-cache
-          (vectorp (gnus-summary-article-header article))
-          (save-excursion
-            (gnus-cache-possibly-enter-article
-             gnus-newsgroup-name article
-             (gnus-summary-article-header article)
-             (= mark gnus-ticked-mark)
-             (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
-
-      ;; Fix the mark.
-      (gnus-summary-update-mark mark 'unread)
-      t)))
+  (let* ((article (gnus-summary-article-number))
+        (old-mark (gnus-summary-article-mark article)))
+    (if (eq mark old-mark)
+       t
+      (if (<= article 0)
+         (progn
+           (gnus-error 1 "Can't mark negative article numbers")
+           nil)
+       (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+       (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
+       (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
+       (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
+       (cond ((= mark gnus-ticked-mark)
+              (push article gnus-newsgroup-marked))
+             ((= mark gnus-dormant-mark)
+              (push article gnus-newsgroup-dormant))
+             (t
+              (push article gnus-newsgroup-unreads)))
+       (setq gnus-newsgroup-reads
+             (delq (assq article gnus-newsgroup-reads)
+                   gnus-newsgroup-reads))
+
+       ;; See whether the article is to be put in the cache.
+       (and gnus-use-cache
+            (vectorp (gnus-summary-article-header article))
+            (save-excursion
+              (gnus-cache-possibly-enter-article
+               gnus-newsgroup-name article
+               (gnus-summary-article-header article)
+               (= mark gnus-ticked-mark)
+               (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
+
+       ;; Fix the mark.
+       (gnus-summary-update-mark mark 'unread)
+       t))))
 
 (defun gnus-summary-mark-article (&optional article mark no-expire)
   "Mark ARTICLE with MARK.  MARK can be any character.
@@ -7711,7 +7778,7 @@ marked."
         (t gnus-unread-mark))
    'replied)
   (when (gnus-visual-p 'summary-highlight 'highlight)
-    (run-hooks 'gnus-summary-update-hook))
+    (gnus-run-hooks 'gnus-summary-update-hook))
   t)
 
 (defun gnus-summary-update-mark (mark type)
@@ -7746,7 +7813,8 @@ marked."
     (push (cons article mark) gnus-newsgroup-reads)
     ;; Possibly remove from cache, if that is used.
     (when gnus-use-cache
-      (gnus-cache-enter-remove-article article))))
+      (gnus-cache-enter-remove-article article))
+    t))
 
 (defun gnus-mark-article-as-unread (article &optional mark)
   "Enter ARTICLE in the pertinent lists and remove it from others."
@@ -8663,7 +8731,7 @@ save those articles instead."
   (cond ((assq 'execute props)
         (gnus-execute-command (cdr (assq 'execute props)))))
   (let ((gnus-current-article (gnus-summary-article-number)))
-    (run-hooks 'gnus-mark-article-hook)))
+    (gnus-run-hooks 'gnus-mark-article-hook)))
 
 (defun gnus-execute-command (command &optional automatic)
   (save-excursion
@@ -8912,6 +8980,33 @@ save those articles instead."
         (lambda (buf) (switch-to-buffer buf) (gnus-summary-exit))
         buffers)))))
 
+
+;;; @ for mime-partial
+;;;
+
+(defun gnus-mime-partial-preview-function ()
+  (gnus-summary-preview-mime-message (gnus-summary-article-number))
+  )
+
+(autoload 'mime-combine-message/partials-automatically
+  "mime-partial"
+  "Internal method to combine message/partial messages automatically.")
+
+(set-atype 'mime-acting-condition
+          '((type . "message/partial")
+            (method . mime-combine-message/partials-automatically)
+            (major-mode . gnus-original-article-mode)
+            (summary-buffer-exp . gnus-summary-buffer)
+            ))
+
+(set-alist 'mime-view-partial-message-method-alist
+          'gnus-original-article-mode
+          'gnus-mime-partial-preview-function)
+
+
+;;; @ end
+;;;
+
 (gnus-ems-redefine)
 
 (provide 'gnus-sum)