2001-08-01 10:00:00 ShengHuo ZHU <zsh@cs.rochester.edu>
[gnus] / lisp / gnus-sum.el
index 999e3b0..2613302 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 (require 'gnus-undo)
 (require 'gnus-util)
 (require 'mm-decode)
+;; Recursive :-(.
+;; (require 'gnus-art)
+(require 'nnoo)
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
+(autoload 'gnus-cache-write-active "gnus-cache")
+(autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
+(autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
+(autoload 'mm-uu-dissect "mm-uu")
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
@@ -192,6 +199,20 @@ If this variable is nil, scoring will be disabled."
   :type '(choice (const :tag "disable")
                 integer))
 
+(defcustom gnus-summary-default-high-score 0
+  "*Default threshold for a high scored article.
+An article will be highlighted as high scored if its score is greater
+than this score."
+  :group 'gnus-score-default
+  :type 'integer)
+
+(defcustom gnus-summary-default-low-score 0
+  "*Default threshold for a low scored article.
+An article will be highlighted as low scored if its score is smaller
+than this score."
+  :group 'gnus-score-default
+  :type 'integer)
+
 (defcustom gnus-summary-zcore-fuzz 0
   "*Fuzziness factor for the zcore in the summary buffer.
 Articles with scores closer than this to `gnus-summary-default-score'
@@ -345,13 +366,15 @@ variable."
 
 (defcustom gnus-move-split-methods nil
   "*Variable used to suggest where articles are to be moved to.
-It uses the same syntax as the `gnus-split-methods' variable."
+It uses the same syntax as the `gnus-split-methods' variable.
+However, whereas `gnus-split-methods' specifies file names as targets,
+this variable specifies group names."
   :group 'gnus-summary-mail
   :type '(repeat (choice (list :value (fun) function)
                         (cons :value ("" "") regexp (repeat string))
                         (sexp :value nil))))
 
-(defcustom gnus-unread-mark ?  ;Whitespace
+(defcustom gnus-unread-mark ?           ;Whitespace
   "*Mark used for unread articles."
   :group 'gnus-summary-marks
   :type 'character)
@@ -387,7 +410,7 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :type 'character)
 
 (defcustom gnus-souped-mark ?F
-  "*Mark used for killed articles."
+  "*Mark used for souped articles."
   :group 'gnus-summary-marks
   :type 'character)
 
@@ -411,6 +434,11 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-marks
   :type 'character)
 
+(defcustom gnus-forwarded-mark ?O
+  "*Mark used for articles that have been forwarded."
+  :group 'gnus-summary-marks
+  :type 'character)
+
 (defcustom gnus-cached-mark ?*
   "*Mark used for articles that are in the cache."
   :group 'gnus-summary-marks
@@ -421,6 +449,11 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-marks
   :type 'character)
 
+(defcustom gnus-no-mark ?               ;Whitespace
+  "*Mark used for articles that have no other secondary mark."
+  :group 'gnus-summary-marks
+  :type 'character)
+
 (defcustom gnus-ancient-mark ?O
   "*Mark used for ancient articles."
   :group 'gnus-summary-marks
@@ -466,7 +499,7 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-marks
   :type 'character)
 
-(defcustom gnus-empty-thread-mark ?  ;Whitespace
+(defcustom gnus-empty-thread-mark ?     ;Whitespace
   "*There is no thread under the article."
   :group 'gnus-summary-marks
   :type 'character)
@@ -486,11 +519,13 @@ It uses the same syntax as the `gnus-split-methods' variable."
        gnus-low-score-mark gnus-ancient-mark gnus-read-mark
        gnus-souped-mark gnus-duplicate-mark)
   "*The list of marks converted into expiration if a group is auto-expirable."
+  :version "21.1"
   :group 'gnus-summary
   :type '(repeat character))
 
 (defcustom gnus-inhibit-user-auto-expire t
   "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
+  :version "21.1"
   :group 'gnus-summary
   :type 'boolean)
 
@@ -551,6 +586,7 @@ with some simple extensions:
 (defcustom gnus-list-identifiers nil
   "Regexp that matches list identifiers to be removed from subject.
 This can also be a list of regexps."
+  :version "21.1"
   :group 'gnus-summary-format
   :group 'gnus-article-hiding
   :type '(choice (const :tag "none" nil)
@@ -566,7 +602,22 @@ score file."
 
 (defcustom gnus-article-sort-functions '(gnus-article-sort-by-number)
   "*List of functions used for sorting articles in the summary buffer.
-This variable is only used when not using a threaded display."
+
+Each function takes two articles and returns non-nil if the first
+article should be sorted before the other.  If you use more than one
+function, the primary sort function should be the last.  You should
+probably always include `gnus-article-sort-by-number' in the list of
+sorting functions -- preferably first.  Also note that sorting by date
+is often much slower than sorting by number, and the sorting order is
+very similar.  (Sorting by date means sorting by the time the message
+was sent, sorting by number means sorting by arrival time.)
+
+Ready-made functions include `gnus-article-sort-by-number',
+`gnus-article-sort-by-author', `gnus-article-sort-by-subject',
+`gnus-article-sort-by-date' and `gnus-article-sort-by-score'.
+
+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)
                         (function-item gnus-article-sort-by-author)
@@ -579,16 +630,22 @@ This variable is only used when not using a threaded display."
   "*List of functions used for sorting threads in the summary buffer.
 By default, threads are sorted by article number.
 
-Each function takes two threads and return non-nil if the first thread
-should be sorted before the other.  If you use more than one function,
-the primary sort function should be the last.  You should probably
-always include `gnus-thread-sort-by-number' in the list of sorting
-functions -- preferably first.
+Each function takes two threads and returns non-nil if the first
+thread should be sorted before the other.  If you use more than one
+function, the primary sort function should be the last.  You should
+probably always include `gnus-thread-sort-by-number' in the list of
+sorting functions -- preferably first.  Also note that sorting by date
+is often much slower than sorting by number, and the sorting order is
+very similar.  (Sorting by date means sorting by the time the message
+was sent, sorting by number means sorting by arrival time.)
 
 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' and
-`gnus-thread-sort-by-total-score' (see `gnus-thread-score-function')."
+`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)
                         (function-item gnus-thread-sort-by-author)
@@ -629,9 +686,17 @@ This variable is local to the summary buffers."
 (defcustom gnus-summary-mode-hook nil
   "*A hook for Gnus summary mode.
 This hook is run before any variables are set in the summary buffer."
+  :options '(turn-on-gnus-mailing-list-mode)
   :group 'gnus-summary-various
   :type 'hook)
 
+;; Extracted from gnus-xmas-redefine in order to preserve user settings
+(when (featurep 'xemacs)
+  (add-hook 'gnus-summary-mode-hook 'gnus-xmas-summary-menu-add)
+  (add-hook 'gnus-summary-mode-hook 'gnus-xmas-setup-summary-toolbar)
+  (add-hook 'gnus-summary-mode-hook
+           'gnus-xmas-switch-horizontal-scrollbar-off))
+
 (defcustom gnus-summary-menu-hook nil
   "*Hook run after the creation of the summary mode menu."
   :group 'gnus-summary-visual
@@ -732,6 +797,14 @@ automatically when it is selected."
   :group 'gnus-summary
   :type 'hook)
 
+(defcustom gnus-summary-display-arrow
+  (and (fboundp 'display-graphic-p)
+       (display-graphic-p))
+  "*If non-nil, display an arrow highlighting the current article."
+  :version "21.1"
+  :group 'gnus-summary
+  :type 'boolean)
+
 (defcustom gnus-summary-selected-face 'gnus-summary-selected-face
   "Face used for highlighting the current article in the summary buffer."
   :group 'gnus-summary-visual
@@ -740,40 +813,43 @@ automatically when it is selected."
 (defcustom gnus-summary-highlight
   '(((= mark gnus-canceled-mark)
      . gnus-summary-cancelled-face)
-    ((and (> score default)
+    ((and (> score default-high)
          (or (= mark gnus-dormant-mark)
              (= mark gnus-ticked-mark)))
      . gnus-summary-high-ticked-face)
-    ((and (< score default)
+    ((and (< score default-low)
          (or (= mark gnus-dormant-mark)
              (= mark gnus-ticked-mark)))
      . gnus-summary-low-ticked-face)
     ((or (= mark gnus-dormant-mark)
         (= mark gnus-ticked-mark))
      . gnus-summary-normal-ticked-face)
-    ((and (> score default) (= mark gnus-ancient-mark))
+    ((and (> score default-high) (= mark gnus-ancient-mark))
      . gnus-summary-high-ancient-face)
-    ((and (< score default) (= mark gnus-ancient-mark))
+    ((and (< score default-low) (= mark gnus-ancient-mark))
      . gnus-summary-low-ancient-face)
     ((= mark gnus-ancient-mark)
      . gnus-summary-normal-ancient-face)
-    ((and (> score default) (= mark gnus-unread-mark))
+    ((and (> score default-high) (= mark gnus-unread-mark))
      . gnus-summary-high-unread-face)
-    ((and (< score default) (= mark gnus-unread-mark))
+    ((and (< score default-low) (= mark gnus-unread-mark))
      . gnus-summary-low-unread-face)
     ((= mark gnus-unread-mark)
      . gnus-summary-normal-unread-face)
-    ((and (> score default) (memq mark (list gnus-downloadable-mark
-                                            gnus-undownloaded-mark)))
+    ((and (> score default-high) (memq mark (list gnus-downloadable-mark
+                                                 gnus-undownloaded-mark)))
      . gnus-summary-high-unread-face)
-    ((and (< score default) (memq mark (list gnus-downloadable-mark
-                                            gnus-undownloaded-mark)))
+    ((and (< score default-low) (memq mark (list gnus-downloadable-mark
+                                                gnus-undownloaded-mark)))
      . gnus-summary-low-unread-face)
-    ((memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
+    ((and (memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
+         (memq article gnus-newsgroup-unreads))
      . gnus-summary-normal-unread-face)
-    ((> score default)
+    ((memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
+     . gnus-summary-normal-read-face)
+    ((> score default-high)
      . gnus-summary-high-read-face)
-    ((< score default)
+    ((< score default-low)
      . gnus-summary-low-read-face)
     (t
      . gnus-summary-normal-read-face))
@@ -786,10 +862,12 @@ how those summary lines are displayed, by editing the face field.
 
 You can use the following variables in the FORM field.
 
-score:   The articles score
-default: The default article score.
-below:   The score below which articles are automatically marked as read.
-mark:    The articles mark."
+score:        The article's score
+default:      The default article score.
+default-high: The default score for high scored articles.
+default-low:  The default score for low scored articles.
+below:        The score below which articles are automatically marked as read.
+mark:         The articles mark."
   :group 'gnus-summary-visual
   :type '(repeat (cons (sexp :tag "Form" nil)
                       face)))
@@ -804,53 +882,53 @@ which it may alter in any way.")
 
 (defcustom gnus-extra-headers nil
   "*Extra headers to parse."
+  :version "21.1"
   :group 'gnus-summary
   :type '(repeat symbol))
 
 (defcustom gnus-ignored-from-addresses
   (and user-mail-address (regexp-quote user-mail-address))
   "*Regexp of From headers that may be suppressed in favor of To headers."
+  :version "21.1"
   :group 'gnus-summary
   :type 'regexp)
 
-(defcustom gnus-group-charset-alist
-  '(("^hk\\>\\|^tw\\>\\|\\<big5\\>" cn-big5)
-    ("^cn\\>\\|\\<chinese\\>" cn-gb-2312)
-    ("^fj\\>\\|^japan\\>" iso-2022-jp-2)
-    ("^tnn\\>\\|^pin\\>\\|^sci.lang.japan" iso-2022-7bit)
-    ("^relcom\\>" koi8-r)
-    ("^fido7\\>" koi8-r)
-    ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2)
-    ("^israel\\>" iso-8859-1)
-    ("^han\\>" euc-kr)
-    ("^alt.chinese.text.big5\\>" chinese-big5)
-    ("^soc.culture.vietnamese\\>" vietnamese-viqr)
-    ("^\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)
-    (".*" iso-8859-1))
-  "Alist of regexps (to match group names) and default charsets to be used when reading."
-  :type '(repeat (list (regexp :tag "Group")
-                      (symbol :tag "Charset")))
-  :group 'gnus-charset)
-
 (defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
   "List of charsets that should be ignored.
 When these charsets are used in the \"charset\" parameter, the
 default charset will be used instead."
+  :version "21.1"
   :type '(repeat symbol)
   :group 'gnus-charset)
 
-(defcustom gnus-group-ignored-charsets-alist
-  '(("alt\\.chinese\\.text" iso-8859-1))
-  "Alist of regexps (to match group names) and charsets that should be ignored.
+(gnus-define-group-parameter
+ ignored-charsets
+ :type list
+ :function-document
+ "Return the ignored charsets of GROUP."
+ :variable gnus-group-ignored-charsets-alist
+ :variable-default
+ '(("alt\\.chinese\\.text" iso-8859-1))
+ :variable-document
+ "Alist of regexps (to match group names) and charsets that should be ignored.
 When these charsets are used in the \"charset\" parameter, the
 default charset will be used instead."
-  :type '(repeat (cons (regexp :tag "Group")
-                      (repeat symbol)))
-  :group 'gnus-charset)
+ :variable-group gnus-charset
+ :variable-type '(repeat (cons (regexp :tag "Group")
+                              (repeat symbol)))
+ :parameter-type '(choice :tag "Ignored charsets"
+                         :value nil
+                         (repeat (symbol)))
+ :parameter-document       "\
+List of charsets that should be ignored.
+
+When these charsets are used in the \"charset\" parameter, the
+default charset will be used instead.")
 
 (defcustom gnus-group-highlight-words-alist nil
   "Alist of group regexps and highlight regexps.
 This variable uses the same syntax as `gnus-emphasis-alist'."
+  :version "21.1"
   :type '(repeat (cons (regexp :tag "Group")
                       (repeat (list (regexp :tag "Highlight regexp")
                                     (number :tag "Group for entire word" 0)
@@ -865,18 +943,20 @@ This variable uses the same syntax as `gnus-emphasis-alist'."
 The article will be shown with the charset corresponding to the
 numbered argument.
 For example: ((1 . cn-gb-2312) (2 . big5))."
+  :version "21.1"
   :type '(repeat (cons (number :tag "Argument" 1)
                       (symbol :tag "Charset")))
   :group 'gnus-charset)
 
 (defcustom gnus-preserve-marks t
   "Whether marks are preserved when moving, copying and respooling messages."
+  :version "21.1"
   :type 'boolean
   :group 'gnus-summary-marks)
 
 (defcustom gnus-alter-articles-to-read-function nil
   "Function to be called to alter the list of articles to be selected."
-  :type 'function
+  :type '(choice (const nil) function)
   :group 'gnus-summary)
 
 (defcustom gnus-orphan-score nil
@@ -893,10 +973,27 @@ when prompting the user for which type of files to save."
   :type 'regexp)
 
 
+(defcustom gnus-summary-save-parts-default-mime "image/.*"
+  "*A regexp to match MIME parts when saving multiple parts of a message
+with gnus-summary-save-parts (X m). This regexp will be used by default
+when prompting the user for which type of files to save."
+  :group 'gnus-summary
+  :type 'regexp)
+
+(defcustom gnus-read-all-available-headers nil
+  "Whether Gnus should parse all headers made available to it.
+This is mostly relevant for slow backends where the user may
+wish to widen the summary buffer to include all headers
+that were fetched.  Say, for nnultimate groups."
+  :group 'gnus-summary
+  :type '(choice boolean regexp))
+
 ;;; Internal variables
 
 (defvar gnus-article-mime-handles nil)
 (defvar gnus-article-decoded-p nil)
+(defvar gnus-article-charset nil)
+(defvar gnus-article-ignored-charsets nil)
 (defvar gnus-scores-exclude-files nil)
 (defvar gnus-page-broken nil)
 (defvar gnus-inhibit-mime-unbuttonizing nil)
@@ -913,6 +1010,9 @@ when prompting the user for which type of files to save."
 (defvar gnus-summary-save-parts-type-history nil)
 (defvar gnus-summary-save-parts-last-directory nil)
 
+(defvar gnus-summary-save-parts-type-history nil)
+(defvar gnus-summary-save-parts-last-directory nil)
+
 ;; Avoid highlighting in kill files.
 (defvar gnus-summary-inhibit-highlight nil)
 (defvar gnus-newsgroup-selected-overlay nil)
@@ -946,7 +1046,7 @@ when prompting the user for which type of files to save."
     (?M ,(macroexpand '(mail-header-id gnus-tmp-header)) ?s)
     (?r ,(macroexpand '(mail-header-references gnus-tmp-header)) ?s)
     (?c (or (mail-header-chars gnus-tmp-header) 0) ?d)
-    (?L gnus-tmp-lines ?d)
+    (?L gnus-tmp-lines ?s)
     (?I gnus-tmp-indentation ?s)
     (?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s)
     (?R gnus-tmp-replied ?c)
@@ -967,7 +1067,8 @@ when prompting the user for which type of files to save."
         (and (boundp 'thread) (car thread)) gnus-tmp-level t)
        ?c)
     (?u gnus-tmp-user-defined ?s)
-    (?P (gnus-pick-line-number) ?d))
+    (?P (gnus-pick-line-number) ?d)
+    (?B gnus-tmp-thread-tree-header-string ?s))
   "An alist of format specifications that can appear in summary lines.
 These are paired with what variables they correspond with, along with
 the type of the variable (string, integer, character, etc).")
@@ -1043,6 +1144,9 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-replied nil
   "List of articles that have been replied to in the current newsgroup.")
 
+(defvar gnus-newsgroup-forwarded nil
+  "List of articles that have been forwarded in the current newsgroup.")
+
 (defvar gnus-newsgroup-expirable nil
   "List of articles in the current newsgroup that can be expired.")
 
@@ -1090,6 +1194,8 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-ephemeral-charset nil)
 (defvar gnus-newsgroup-ephemeral-ignored-charsets nil)
 
+(defvar gnus-article-before-search nil)
+
 (defconst gnus-summary-local-variables
   '(gnus-newsgroup-name
     gnus-newsgroup-begin gnus-newsgroup-end
@@ -1098,7 +1204,8 @@ the type of the variable (string, integer, character, etc).")
     gnus-newsgroup-auto-expire gnus-newsgroup-unreads
     gnus-newsgroup-unselected gnus-newsgroup-marked
     gnus-newsgroup-reads gnus-newsgroup-saved
-    gnus-newsgroup-replied gnus-newsgroup-expirable
+    gnus-newsgroup-replied gnus-newsgroup-forwarded
+    gnus-newsgroup-expirable
     gnus-newsgroup-processable gnus-newsgroup-killed
     gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
     gnus-newsgroup-unsendable
@@ -1126,8 +1233,11 @@ the type of the variable (string, integer, character, etc).")
     gnus-newsgroup-charset)
   "Variables that are buffer-local to the summary buffers.")
 
+(defvar gnus-newsgroup-variables nil
+  "Variables that have separate values in the newsgroups.")
+
 ;; Byte-compiler warning.
-(defvar gnus-article-mode-map)
+(eval-when-compile (defvar gnus-article-mode-map))
 
 ;; MIME stuff.
 
@@ -1160,7 +1270,7 @@ For example:
                         (string-match (car x) gnus-newsgroup-name))
                    (nconc gnus-decode-encoded-word-methods-cache
                           (list (cdr x))))))
-         gnus-decode-encoded-word-methods))
+           gnus-decode-encoded-word-methods))
   (let ((xlist gnus-decode-encoded-word-methods-cache))
     (pop xlist)
     (while xlist
@@ -1175,8 +1285,8 @@ For example:
     ;; Multiple spaces.
     (while (string-match "[ \t][ \t]+" mystr)
       (setq mystr (concat (substring mystr 0 (match-beginning 0))
-                          " "
-                          (substring mystr (match-end 0)))))
+                         " "
+                         (substring mystr (match-end 0)))))
     ;; Leading spaces.
     (when (string-match "^[ \t]+" mystr)
       (setq mystr (substring mystr (match-end 0))))
@@ -1187,7 +1297,7 @@ For example:
 
 (defsubst gnus-simplify-subject-re (subject)
   "Remove \"Re:\" from subject lines."
-  (if (string-match "^[Rr][Ee]: *" subject)
+  (if (string-match message-subject-re-regexp subject)
       (substring subject (match-end 0))
     subject))
 
@@ -1300,6 +1410,8 @@ increase the score of each group you read."
 
 (put 'gnus-summary-mode 'mode-class 'special)
 
+(defvar gnus-article-commands-menu)
+
 (when t
   ;; Non-orthogonal keys
 
@@ -1364,6 +1476,7 @@ increase the score of each group you read."
     "\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
+    "\C-c\C-s\C-o" gnus-summary-sort-by-original
     "=" gnus-summary-expand-window
     "\C-x\C-s" gnus-summary-reselect-current-group
     "\M-g" gnus-summary-rescan-group
@@ -1433,6 +1546,7 @@ increase the score of each group you read."
     "S" gnus-summary-limit-include-expunged
     "C" gnus-summary-catchup
     "H" gnus-summary-catchup-to-here
+    "h" gnus-summary-catchup-from-here
     "\C-c" gnus-summary-catchup-all
     "k" gnus-summary-kill-same-subject-and-select
     "K" gnus-summary-kill-same-subject
@@ -1462,7 +1576,9 @@ increase the score of each group you read."
     "x" gnus-summary-limit-to-extra
     "E" gnus-summary-limit-include-expunged
     "c" gnus-summary-limit-exclude-childless-dormant
-    "C" gnus-summary-limit-mark-excluded-as-read)
+    "C" gnus-summary-limit-mark-excluded-as-read
+    "o" gnus-summary-insert-old-articles
+    "N" gnus-summary-insert-new-articles)
 
   (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
     "n" gnus-summary-next-unread-article
@@ -1536,6 +1652,7 @@ increase the score of each group you read."
     "g" gnus-summary-show-article
     "s" gnus-summary-isearch-article
     "P" gnus-summary-print-article
+    "M" gnus-mailing-list-insinuate
     "t" gnus-article-babel)
 
   (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
@@ -1551,12 +1668,14 @@ increase the score of each group you read."
     "6" gnus-article-de-base64-unreadable
     "Z" gnus-article-decode-HZ
     "h" gnus-article-wash-html
+    "s" gnus-summary-force-verify-and-decrypt
     "f" gnus-article-display-x-face
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
     "t" gnus-summary-toggle-header
     "v" gnus-summary-verbose-headers
-    "H" gnus-article-strip-headers-in-body
+    "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
+    "p" gnus-article-verify-x-pgp-sig
     "d" gnus-article-treat-dumbquotes)
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
@@ -1588,6 +1707,7 @@ increase the score of each group you read."
     "z" gnus-article-date-ut
     "u" gnus-article-date-ut
     "l" gnus-article-date-local
+    "p" gnus-article-date-english
     "e" gnus-article-date-lapsed
     "o" gnus-article-date-original
     "i" gnus-article-date-iso8601
@@ -1600,7 +1720,8 @@ increase the score of each group you read."
     "a" gnus-article-strip-blank-lines
     "A" gnus-article-strip-all-blank-lines
     "s" gnus-article-strip-leading-space
-    "e" gnus-article-strip-trailing-space)
+    "e" gnus-article-strip-trailing-space
+    "w" gnus-article-remove-leading-whitespace)
 
   (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
     "v" gnus-version
@@ -1623,6 +1744,7 @@ increase the score of each group you read."
     "q" gnus-summary-respool-query
     "t" gnus-summary-respool-trace
     "i" gnus-summary-import-article
+    "I" gnus-summary-create-article
     "p" gnus-summary-article-posted-p)
 
   (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
@@ -1643,332 +1765,437 @@ increase the score of each group you read."
     "v" gnus-article-view-part
     "o" gnus-article-save-part
     "c" gnus-article-copy-part
+    "C" gnus-article-view-part-as-charset
     "e" gnus-article-externalize-part
+    "E" gnus-article-encrypt-body
     "i" gnus-article-inline-part
     "|" gnus-article-pipe-part))
 
+(defvar gnus-article-post-menu nil)
+
 (defun gnus-summary-make-menu-bar ()
   (gnus-turn-off-edit-menu 'summary)
 
   (unless (boundp 'gnus-summary-misc-menu)
 
     (easy-menu-define
-     gnus-summary-kill-menu gnus-summary-mode-map ""
-     (cons
-      "Score"
-      (nconc
-       (list
-       ["Enter score..." gnus-summary-score-entry t]
-       ["Customize" gnus-score-customize t])
-       (gnus-make-score-map 'increase)
-       (gnus-make-score-map 'lower)
-       '(("Mark"
-         ["Kill below" gnus-summary-kill-below t]
-         ["Mark above" gnus-summary-mark-above t]
-         ["Tick above" gnus-summary-tick-above t]
-         ["Clear above" gnus-summary-clear-above t])
-        ["Current score" gnus-summary-current-score t]
-        ["Set score" gnus-summary-set-score t]
-        ["Switch current score file..." gnus-score-change-score-file t]
-        ["Set mark below..." gnus-score-set-mark-below t]
-        ["Set expunge below..." gnus-score-set-expunge-below t]
-        ["Edit current score file" gnus-score-edit-current-scores t]
-        ["Edit score file" gnus-score-edit-file t]
-        ["Trace score" gnus-score-find-trace t]
-        ["Find words" gnus-score-find-favourite-words t]
-        ["Rescore buffer" gnus-summary-rescore t]
-        ["Increase score..." gnus-summary-increase-score t]
-        ["Lower score..." gnus-summary-lower-score t]))))
-
-    ;; Define both the Article menu in the summary buffer and the equivalent
+      gnus-summary-kill-menu gnus-summary-mode-map ""
+      (cons
+       "Score"
+       (nconc
+       (list
+        ["Customize" gnus-score-customize t])
+       (gnus-make-score-map 'increase)
+       (gnus-make-score-map 'lower)
+       '(("Mark"
+          ["Kill below" gnus-summary-kill-below t]
+          ["Mark above" gnus-summary-mark-above t]
+          ["Tick above" gnus-summary-tick-above t]
+          ["Clear above" gnus-summary-clear-above t])
+         ["Current score" gnus-summary-current-score t]
+         ["Set score" gnus-summary-set-score t]
+         ["Switch current score file..." gnus-score-change-score-file t]
+         ["Set mark below..." gnus-score-set-mark-below t]
+         ["Set expunge below..." gnus-score-set-expunge-below t]
+         ["Edit current score file" gnus-score-edit-current-scores t]
+         ["Edit score file" gnus-score-edit-file t]
+         ["Trace score" gnus-score-find-trace t]
+         ["Find words" gnus-score-find-favourite-words t]
+         ["Rescore buffer" gnus-summary-rescore t]
+         ["Increase score..." gnus-summary-increase-score t]
+         ["Lower score..." gnus-summary-lower-score t]))))
+
+;; Define both the Article menu in the summary buffer and the equivalent
     ;; Commands menu in the article buffer here for consistency.
     (let ((innards
-           '(("Hide"
-              ["All" gnus-article-hide t]
-              ["Headers" gnus-article-hide-headers t]
-              ["Signature" gnus-article-hide-signature t]
-              ["Citation" gnus-article-hide-citation t]
+          `(("Hide"
+             ["All" gnus-article-hide t]
+             ["Headers" gnus-article-hide-headers t]
+             ["Signature" gnus-article-hide-signature t]
+             ["Citation" gnus-article-hide-citation t]
              ["List identifiers" gnus-article-hide-list-identifiers t]
-              ["PGP" gnus-article-hide-pgp t]
+             ["PGP" gnus-article-hide-pgp t]
              ["Banner" gnus-article-strip-banner t]
-              ["Boring headers" gnus-article-hide-boring-headers t])
-             ("Highlight"
-              ["All" gnus-article-highlight t]
-              ["Headers" gnus-article-highlight-headers t]
-              ["Signature" gnus-article-highlight-signature t]
-              ["Citation" gnus-article-highlight-citation t])
+             ["Boring headers" gnus-article-hide-boring-headers t])
+            ("Highlight"
+             ["All" gnus-article-highlight t]
+             ["Headers" gnus-article-highlight-headers t]
+             ["Signature" gnus-article-highlight-signature t]
+             ["Citation" gnus-article-highlight-citation t])
             ("MIME"
              ["Words" gnus-article-decode-mime-words t]
              ["Charset" gnus-article-decode-charset t]
              ["QP" gnus-article-de-quoted-unreadable t]
              ["Base64" gnus-article-de-base64-unreadable t]
-             ["View all" gnus-mime-view-all-parts 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]
-              ["User-defined" gnus-article-date-user t])
-             ("Washing"
-              ("Remove Blanks"
-               ["Leading" gnus-article-strip-leading-blank-lines t]
-               ["Multiple" gnus-article-strip-multiple-blank-lines t]
-               ["Trailing" gnus-article-remove-trailing-blank-lines t]
-               ["All of the above" gnus-article-strip-blank-lines t]
-               ["All" gnus-article-strip-all-blank-lines t]
-               ["Leading space" gnus-article-strip-leading-space t]
-              ["Trailing space" gnus-article-strip-trailing-space t])
-              ["Overstrike" gnus-article-treat-overstrike t]
-              ["Dumb quotes" gnus-article-treat-dumbquotes t]
-              ["Emphasis" gnus-article-emphasize t]
-              ["Word wrap" gnus-article-fill-cited-article t]
+             ["View all" gnus-mime-view-all-parts t]
+             ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
+             ["Encrypt body" gnus-article-encrypt-body 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]
+             ["User-defined" gnus-article-date-user t])
+            ("Washing"
+             ("Remove Blanks"
+              ["Leading" gnus-article-strip-leading-blank-lines t]
+              ["Multiple" gnus-article-strip-multiple-blank-lines t]
+              ["Trailing" gnus-article-remove-trailing-blank-lines t]
+              ["All of the above" gnus-article-strip-blank-lines t]
+              ["All" gnus-article-strip-all-blank-lines t]
+              ["Leading space" gnus-article-strip-leading-space t]
+              ["Trailing space" gnus-article-strip-trailing-space t]
+              ["Leading space in headers"
+               gnus-article-remove-leading-whitespace t])
+             ["Overstrike" gnus-article-treat-overstrike t]
+             ["Dumb quotes" gnus-article-treat-dumbquotes t]
+             ["Emphasis" gnus-article-emphasize t]
+             ["Word wrap" gnus-article-fill-cited-article t]
              ["Fill long lines" gnus-article-fill-long-lines t]
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
-              ["CR" gnus-article-remove-cr t]
-              ["Show X-Face" gnus-article-display-x-face t]
-              ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
-              ["Base64" gnus-article-de-base64-unreadable t]
-              ["Rot 13" gnus-summary-caesar-message t]
-              ["Unix pipe" gnus-summary-pipe-message t]
-              ["Add buttons" gnus-article-add-buttons t]
-              ["Add buttons to head" gnus-article-add-buttons-to-head t]
-              ["Stop page breaking" gnus-summary-stop-page-breaking t]
-              ["Verbose header" gnus-summary-verbose-headers t]
-              ["Toggle header" gnus-summary-toggle-header t]
+             ["CR" gnus-article-remove-cr t]
+             ["Show X-Face" gnus-article-display-x-face t]
+             ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
+             ["Base64" gnus-article-de-base64-unreadable t]
+             ["Rot 13" gnus-summary-caesar-message
+              ,@(if (featurep 'xemacs) '(t)
+                  '(:help "\"Caesar rotate\" article by 13"))]
+             ["Unix pipe" gnus-summary-pipe-message t]
+             ["Add buttons" gnus-article-add-buttons t]
+             ["Add buttons to head" gnus-article-add-buttons-to-head t]
+             ["Stop page breaking" gnus-summary-stop-page-breaking t]
+             ["Verbose header" gnus-summary-verbose-headers t]
+             ["Toggle header" gnus-summary-toggle-header t]
              ["Html" gnus-article-wash-html t]
+             ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["HZ" gnus-article-decode-HZ t])
-             ("Output"
-              ["Save in default format" gnus-summary-save-article t]
-              ["Save in file" gnus-summary-save-article-file t]
-              ["Save in Unix mail format" gnus-summary-save-article-mail t]
-              ["Save in MH folder" gnus-summary-save-article-folder t]
-              ["Save in VM folder" gnus-summary-save-article-vm t]
-              ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
-              ["Save body in file" gnus-summary-save-article-body-file t]
-              ["Pipe through a filter" gnus-summary-pipe-output t]
-              ["Add to SOUP packet" gnus-soup-add-article t]
-              ["Print" gnus-summary-print-article t])
-             ("Backend"
-              ["Respool article..." gnus-summary-respool-article t]
-              ["Move article..." gnus-summary-move-article
-               (gnus-check-backend-function
-                'request-move-article gnus-newsgroup-name)]
-              ["Copy article..." gnus-summary-copy-article t]
-              ["Crosspost article..." gnus-summary-crosspost-article
-               (gnus-check-backend-function
-                'request-replace-article gnus-newsgroup-name)]
-              ["Import file..." gnus-summary-import-article t]
-              ["Check if posted" gnus-summary-article-posted-p t]
-              ["Edit article" gnus-summary-edit-article
-               (not (gnus-group-read-only-p))]
-              ["Delete article" gnus-summary-delete-article
-               (gnus-check-backend-function
-                'request-expire-articles gnus-newsgroup-name)]
-              ["Query respool" gnus-summary-respool-query t]
+            ("Output"
+             ["Save in default format" gnus-summary-save-article
+              ,@(if (featurep 'xemacs) '(t)
+                  '(:help "Save article using default method"))]
+             ["Save in file" gnus-summary-save-article-file
+              ,@(if (featurep 'xemacs) '(t)
+                  '(:help "Save article in file"))]
+             ["Save in Unix mail format" gnus-summary-save-article-mail t]
+             ["Save in MH folder" gnus-summary-save-article-folder t]
+             ["Save in VM folder" gnus-summary-save-article-vm t]
+             ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
+             ["Save body in file" gnus-summary-save-article-body-file t]
+             ["Pipe through a filter" gnus-summary-pipe-output t]
+             ["Add to SOUP packet" gnus-soup-add-article t]
+             ["Print" gnus-summary-print-article t])
+            ("Backend"
+             ["Respool article..." gnus-summary-respool-article t]
+             ["Move article..." gnus-summary-move-article
+              (gnus-check-backend-function
+               'request-move-article gnus-newsgroup-name)]
+             ["Copy article..." gnus-summary-copy-article t]
+             ["Crosspost article..." gnus-summary-crosspost-article
+              (gnus-check-backend-function
+               'request-replace-article gnus-newsgroup-name)]
+             ["Import file..." gnus-summary-import-article t]
+             ["Create article..." gnus-summary-create-article t]
+             ["Check if posted" gnus-summary-article-posted-p t]
+             ["Edit article" gnus-summary-edit-article
+              (not (gnus-group-read-only-p))]
+             ["Delete article" gnus-summary-delete-article
+              (gnus-check-backend-function
+               'request-expire-articles gnus-newsgroup-name)]
+             ["Query respool" gnus-summary-respool-query t]
              ["Trace respool" gnus-summary-respool-trace t]
-              ["Delete expirable articles" gnus-summary-expire-articles-now
-               (gnus-check-backend-function
-                'request-expire-articles gnus-newsgroup-name)])
-             ("Extract"
-              ["Uudecode" gnus-uu-decode-uu t]
-              ["Uudecode and save" gnus-uu-decode-uu-and-save t]
-              ["Unshar" gnus-uu-decode-unshar t]
-              ["Unshar and save" gnus-uu-decode-unshar-and-save t]
-              ["Save" gnus-uu-decode-save t]
-              ["Binhex" gnus-uu-decode-binhex t]
-              ["Postscript" gnus-uu-decode-postscript t])
-             ("Cache"
-              ["Enter article" gnus-cache-enter-article t]
-              ["Remove article" gnus-cache-remove-article t])
+             ["Delete expirable articles" gnus-summary-expire-articles-now
+              (gnus-check-backend-function
+               'request-expire-articles gnus-newsgroup-name)])
+            ("Extract"
+             ["Uudecode" gnus-uu-decode-uu
+              ,@(if (featurep 'xemacs) '(t)
+                  '(:help "Decode uuencoded article(s)"))]
+             ["Uudecode and save" gnus-uu-decode-uu-and-save t]
+             ["Unshar" gnus-uu-decode-unshar t]
+             ["Unshar and save" gnus-uu-decode-unshar-and-save t]
+             ["Save" gnus-uu-decode-save t]
+             ["Binhex" gnus-uu-decode-binhex t]
+             ["Postscript" gnus-uu-decode-postscript t])
+            ("Cache"
+             ["Enter article" gnus-cache-enter-article t]
+             ["Remove article" gnus-cache-remove-article t])
             ["Translate" gnus-article-babel t]
-             ["Select article buffer" gnus-summary-select-article-buffer 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]
-             ["End of the article" gnus-summary-end-of-article t]
-             ["Fetch parent of article" gnus-summary-refer-parent-article t]
-             ["Fetch referenced articles" gnus-summary-refer-references t]
-             ["Fetch current thread" gnus-summary-refer-thread t]
-             ["Fetch article with id..." gnus-summary-refer-article t]
-             ["Redisplay" gnus-summary-show-article t])))
-      (easy-menu-define
-       gnus-summary-article-menu gnus-summary-mode-map ""
-       (cons "Article" innards))
-
+            ["Select article buffer" gnus-summary-select-article-buffer 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]
+            ["End of the article" gnus-summary-end-of-article t]
+            ["Fetch parent of article" gnus-summary-refer-parent-article t]
+            ["Fetch referenced articles" gnus-summary-refer-references t]
+            ["Fetch current thread" gnus-summary-refer-thread t]
+            ["Fetch article with id..." gnus-summary-refer-article t]
+            ["Setup Mailing List Params" gnus-mailing-list-insinuate t]
+            ["Redisplay" gnus-summary-show-article t]
+            ["Raw article" gnus-summary-show-raw-article t])))
       (easy-menu-define
-       gnus-article-commands-menu gnus-article-mode-map ""
-       (cons "Commands" innards)))
+       gnus-summary-article-menu gnus-summary-mode-map ""
+       (cons "Article" innards))
+
+      (if (not (keymapp gnus-summary-article-menu))
+         (easy-menu-define
+           gnus-article-commands-menu gnus-article-mode-map ""
+           (cons "Commands" innards))
+       ;; in Emacs, don't share menu.
+       (setq gnus-article-commands-menu
+             (copy-keymap gnus-summary-article-menu))
+       (define-key gnus-article-mode-map [menu-bar commands]
+         (cons "Commands" gnus-article-commands-menu))))
 
     (easy-menu-define
-     gnus-summary-thread-menu gnus-summary-mode-map ""
-     '("Threads"
-       ["Toggle threading" gnus-summary-toggle-threads t]
-       ["Hide threads" gnus-summary-hide-all-threads t]
-       ["Show threads" gnus-summary-show-all-threads t]
-       ["Hide thread" gnus-summary-hide-thread t]
-       ["Show thread" gnus-summary-show-thread t]
-       ["Go to next thread" gnus-summary-next-thread t]
-       ["Go to previous thread" gnus-summary-prev-thread t]
-       ["Go down thread" gnus-summary-down-thread t]
-       ["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]
-       ["Lower thread score" gnus-summary-lower-thread t]
-       ["Raise thread score" gnus-summary-raise-thread t]
-       ["Rethread current" gnus-summary-rethread-current t]))
+      gnus-summary-thread-menu gnus-summary-mode-map ""
+      '("Threads"
+       ["Toggle threading" gnus-summary-toggle-threads t]
+       ["Hide threads" gnus-summary-hide-all-threads t]
+       ["Show threads" gnus-summary-show-all-threads t]
+       ["Hide thread" gnus-summary-hide-thread t]
+       ["Show thread" gnus-summary-show-thread t]
+       ["Go to next thread" gnus-summary-next-thread t]
+       ["Go to previous thread" gnus-summary-prev-thread t]
+       ["Go down thread" gnus-summary-down-thread t]
+       ["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]
+       ["Lower thread score" gnus-summary-lower-thread t]
+       ["Raise thread score" gnus-summary-raise-thread t]
+       ["Rethread current" gnus-summary-rethread-current t]))
 
     (easy-menu-define
-     gnus-summary-post-menu gnus-summary-mode-map ""
-     '("Post"
-       ["Post an article" gnus-summary-post-news t]
-       ["Followup" gnus-summary-followup t]
-       ["Followup and yank" gnus-summary-followup-with-original t]
-       ["Supersede article" gnus-summary-supersede-article t]
-       ["Cancel article" gnus-summary-cancel-article t]
-       ["Reply" gnus-summary-reply t]
-       ["Reply and yank" gnus-summary-reply-with-original t]
-       ["Wide reply" gnus-summary-wide-reply t]
-       ["Wide reply and yank" gnus-summary-wide-reply-with-original t]
-       ["Mail forward" gnus-summary-mail-forward t]
-       ["Post forward" gnus-summary-post-forward t]
-       ["Digest and mail" gnus-uu-digest-mail-forward t]
-       ["Digest and post" gnus-uu-digest-post-forward t]
-       ["Resend message" gnus-summary-resend-message t]
-       ["Send bounced mail" gnus-summary-resend-bounced-mail t]
-       ["Send a mail" gnus-summary-mail-other-window t]
-       ["Uuencode and post" gnus-uu-post-news t]
-       ["Followup via news" gnus-summary-followup-to-mail t]
-       ["Followup via news and yank"
-       gnus-summary-followup-to-mail-with-original t]
-       ;;("Draft"
-       ;;["Send" gnus-summary-send-draft t]
-       ;;["Send bounced" gnus-resend-bounced-mail t])
-       ))
+      gnus-summary-post-menu gnus-summary-mode-map ""
+      `("Post"
+       ["Post an article" gnus-summary-post-news
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post an article"))]
+       ["Followup" gnus-summary-followup
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post followup to this article"))]
+       ["Followup and yank" gnus-summary-followup-with-original
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post followup to this article, quoting its contents"))]
+       ["Supersede article" gnus-summary-supersede-article t]
+       ["Cancel article" gnus-summary-cancel-article
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Cancel an article you posted"))]
+       ["Reply" gnus-summary-reply t]
+       ["Reply and yank" gnus-summary-reply-with-original t]
+       ["Wide reply" gnus-summary-wide-reply t]
+       ["Wide reply and yank" gnus-summary-wide-reply-with-original
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Mail a reply, quoting this article"))]
+       ["Mail forward" gnus-summary-mail-forward t]
+       ["Post forward" gnus-summary-post-forward t]
+       ["Digest and mail" gnus-uu-digest-mail-forward t]
+       ["Digest and post" gnus-uu-digest-post-forward t]
+       ["Resend message" gnus-summary-resend-message t]
+       ["Send bounced mail" gnus-summary-resend-bounced-mail t]
+       ["Send a mail" gnus-summary-mail-other-window t]
+       ["Uuencode and post" gnus-uu-post-news
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post a uuencoded article"))]
+       ["Followup via news" gnus-summary-followup-to-mail t]
+       ["Followup via news and yank"
+        gnus-summary-followup-to-mail-with-original t]
+       ;;("Draft"
+       ;;["Send" gnus-summary-send-draft t]
+       ;;["Send bounced" gnus-resend-bounced-mail t])
+       ))
+
+    (cond
+     ((not (keymapp gnus-summary-post-menu))
+      (setq gnus-article-post-menu gnus-summary-post-menu))
+     ((not gnus-article-post-menu)
+      ;; Don't share post menu.
+ &