+2003-01-15 Simon Josefsson <jas@extundo.com>
+
+ * GNUS-NEWS: Add. Fix from Reiner Steib
+ <4uce.02.r.steib@gmx.net>.
+
+2003-01-10 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * make.bat: Removed "-no-init-file" (it's the same as "-q"). Use
+ new variables EMACSBATCH and GNUS_INFO_DIR. Install gnus-?,
+ message-?, sieve and pgg (in texi). Added hint for dir entries.
+
+ * make-x.bat: Ditto.
+
+2003-01-13 Simon Josefsson <jas@extundo.com>
+
+ * GNUS-NEWS: Add smileys, Sender:, message-utils.
+ Expand anti-spam. Fixes.
+
2003-01-09 Simon Josefsson <jas@extundo.com>
* etc/gnus/preview.xpm: Add.
\f
* Changes in Oort Gnus
+** The new variable `gnus-parameters' can be used to set group parameters.
+
+Earlier this was done only via `G p' (or `G c'), which stored the
+parameters in ~/.newsrc.eld, but via this variable you can enjoy the
+powers of customize, and simplified backups since you set the variable
+in ~/.emacs instead of ~/.newsrc.eld. The variable maps regular
+expressions matching group names to group parameters, a'la:
+
+ (setq gnus-parameters
+ '(("mail\\..*"
+ (gnus-show-threads nil)
+ (gnus-use-scoring nil))
+ ("^nnimap:\\(foo.bar\\)$"
+ (to-group . "\\1"))))
+
+** Smileys (":-)", ";-)" etc) are now iconized for Emacs too.
+
+Put (setq gnus-treat-display-smileys nil) in ~/.emacs to disable it.
+
+** Gnus no longer generate the Sender: header automatically.
+
+Earlier it was generated iff the user configurable email address was
+different from the Gnus guessed default user address. As the guessing
+algorithm is rarely correct these days, and (more controversally) the
+only use of the Sender: header was to check if you are entitled to
+cancel/supersede news (which is now solved by Cancel Locks instead,
+see another entry), generation of the header has been disabled by
+default. See the variables `message-required-headers',
+`message-required-news-headers', and `message-required-mail-headers'.
+
+** Features from third party message-utils.el added to message.el.
+
+Message now asks if you wish to remove "(was: <old subject>)" from
+subject lines (see `message-subject-trailing-was-query'). C-c M-m and
+C-c M-f inserts markers indicating included text. C-c C-f a adds a
+X-No-Archive: header. C-c C-f x inserts appropriate headers and a
+note in the body for cross-postings and followups (see the variables
+`message-cross-post-*').
+
** References and X-Draft-Headers are no longer generated when you
start composing messages.
-** Improved anti-speam features.
+** Improved anti-spam features.
+
+Gnus is now able to take out spam from your mail and news streams
+using a wide variety of programs and filter rules. Among the supported
+methods are RBL blocklists, bogofilter and white/blacklists. Hooks
+for easy use of external packages such as SpamAssassin and Hashcash
+are also new.
** Easy inclusion of X-Faces headers.
((header "to" "larsi.*org")
(Organization "Somewhere, Inc."))
-The old format like the lines below is obsolete.
+The old format like the lines below is obsolete, but still accepted.
(header "to" "larsi.*org"
(Organization "Somewhere, Inc."))
The new server variables `nnml-marks-is-evil' and
`nnfolder-marks-is-evil' can be used to disable this feature.
-** The menu bar (in Group and Summary buffer) named "Misc" has been
-renamed to "Gnus".
+** The menu bar item (in Group and Summary buffer) named "Misc" has
+been renamed to "Gnus".
-** The menu bar (in Message mode) named "MML" has been renamed to
+** The menu bar item (in Message mode) named "MML" has been renamed to
"Attachments".
** gnus-group-charset-alist and gnus-group-ignored-charsets-alist.
+2003-01-21 07:15:41 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
+
+ * gnus.el: Oort Gnus v0.13 is released.
+
+2003-01-21 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-art.el (gnus-button-url-regexp): Removed |.
+
+ * message.el (message-send-hook): Doc fix.
+
+ * gnus-win.el (gnus-buffer-configuration): Display article
+ instead of article-copy when `reply'.
+
+2003-01-21 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus.el (gnus-format): Change customize group to gnus.
+ (gnus-cache): Add link.
+ (gnus-group-charter-alist): Fix docstring.
+
+2003-01-20 Jesper Harder <harder@ifa.au.dk>
+
+ * mailcap.el (mailcap-print-command): lpr-command might be
+ unbound in XEmacs.
+
+2002-01-18 Kevin Greiner <kgreiner@xpediantsolutions.com>
+
+ * gnus-agent.el (gnus-agent-regenerate-group): Added interactive form.
+
+ * gnus-sum.el (gnus-summary-update-article-line): Fixed
+ calculation of net characters added for use in the gnus-data
+ structure.
+
+2003-01-18 Kai Gro\e,A_\e(Bjohann <kai.grossjohann@uni-duisburg.de>
+
+ * nnmail.el (nnmail-process-unix-mail-format): Improve error
+ message. Suggested by Jari Aalto.
+
+2003-01-17 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-art.el (gnus-article-followup-with-original): Clean up.
+ (gnus-article-reply-with-original): Ditto.
+
+ * gnus-sum.el (gnus-summary-catchup): Make sure downloadable,
+ read articles don't become unread.
+
+2003-01-17 Simon Josefsson <jas@extundo.com>
+
+ * gnus-fun.el (gnus-x-face-from-file):
+ (gnus-face-from-file): Suggest image format in minibuffer prompt.
+
+ * gnus-fun.el (gnus-convert-image-to-x-face-command)
+ (gnus-convert-image-to-face-command): Doc fix.
+
+2003-01-17 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-fun.el (gnus-convert-face-to-png): Protect against errors.
+
+2003-01-17 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus-art.el (gnus-mime-print-part): Use mm-save-part-to-file to
+ avoid encoding problems.
+
+ * mailcap.el (mailcap-ps-command): New variable.
+ (mailcap-mime-data): Add print entry where applicable. Use
+ pdftotext on a tty.
+
+2003-01-16 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-sum.el (gnus-alter-header-function): Add type and group.
+
+2003-01-16 Simon Josefsson <jas@extundo.com>
+
+ * gnus-fun.el (gnus-convert-image-to-x-face-command)
+ (gnus-convert-image-to-face-command, gnus-x-face-from-file)
+ (gnus-face-from-file): Doc fix; don't mention image format.
+
+2003-01-16 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * spam.el (spam-get-article-as-filename): new function (unused for now)
+ (spam-get-article-as-buffer): new function
+ (spam-get-article-as-string): use spam-get-article-as-buffer
+ (spam-summary-prepare-exit): fixed bug, noticed by Malcolm Purvis
+
+2003-01-15 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-agent.el: Don't use `path'.
+ From the GNU coding standards:
+
+ Please do not use the term ``pathname'' that is used in Unix
+ documentation; use ``file name'' (two words) instead. We use
+ the term ``path'' only for search paths, which are lists of
+ directory names.
+
+ * nnsoup.el (nnsoup-file-name): Ditto.
+
+ * nnmail.el (nnmail-pathname-coding-system): Ditto.
+ (nnmail-group-pathname): Ditto.
+
+ * nnimap.el (nnimap-group-overview-filename): Ditto.
+
+ * nnheader.el (nnheader-pathname-coding-system): Ditto.
+ (nnheader-group-pathname): Ditto.
+
+ * nnfolder.el (nnfolder-group-pathname): Ditto.
+
+ * gnus.el (gnus-home-directory): Ditto.
+
+ * gnus-group.el (gnus-group-icon-list): Ditto.
+
+2003-01-16 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus-art.el (gnus-mime-print-part): Use mm-handle-media-type.
+
+ * message.el (message-mode-menu): Use it.
+ (message-mode-menu): Deactivate "Yank Original" if there's no
+ reply buffer.
+
+ * messagexmas.el (message-xmas-redefine): Redefine in XEmacs.
+
+ * message.el (message-mark-active-p): New function.
+
+2003-01-15 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * spam.el (spam-use-bogofilter-headers, spam-bogofilter-header)
+ (spam-bogofilter-database-directory): new variables
+ (spam-check-bogofilter-headers, spam-check-bogofilter)
+ (spam-bogofilter-register-with-bogofilter)
+ (spam-bogofilter-register-spam-routine)
+ (spam-bogofilter-register-ham-routine)
+ (spam-group-ham-processor-bogofilter-p): new functions for the new
+ Bogofilter interface
+ (spam-summary-prepare-exit): use the new Bogofilter functions
+ (spam-list-of-checks): added spam-use-bogofilter-headers
+ (spam-bogofilter-score): rewrote function
+ (spam-check-bogofilter): optional score parameter, uses
+ spam-check-bogofilter-headers better
+ (spam-check-bogofilter-headers): optional score parameter
+
+ * gnus.el (gnus-install-group-spam-parameters): new variable, t by
+ default, in the gnus-start customization group. Used to disable
+ the spam-*/ham-* parameters.
+ (gnus-group-ham-exit-processor-bogofilter): new ham processor
+
+2003-01-15 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus-xmas.el (gnus-xmas-redefine): Use region-exists-p in
+ XEmacs.
+
+ * gnus-ems.el (gnus-mark-active-p): do.
+
+2003-01-15 Kevin Ryde <user42@zip.com.au>
+
+ * gnus.texi (Using MIME): Mention auto-compression-mode with
+ gnus-mime-copy-part.
+
+2003-01-15 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * message.el (message-send): Don't warn about duplicates when
+ superseding.
+
+2003-01-15 Simon Josefsson <jas@extundo.com>
+
+ * nnimap.el (nnimap-split-download-body): New variable.
+ (nnimap-split-articles): Use it.
+
+2002-01-14 Kevin Greiner <kgreiner@xpediantsolutions.com>
+
+ * gnus-agent.el (gnus-agent-check-overview-buffer): This data
+ integrity checker was incorrectly flagging, and removing, articles
+ whose article number was negative.
+ (gnus-agent-fetch-group-1): When executed in the group's summary
+ buffer, refresh each downloaded line to update the status flag and
+ font. Preserve the value of gnus-newsgroup-headers so that
+ gnus-agent-fetch-articles can split the requests by size.
+ (gnus-agent-expire): Corrected day calculation for when
+ gnus-agent-expire-days contains a list.
+
+2003-01-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-audio.el (gnus-audio-au-player): Use executable-find.
+
+2003-01-13 Jhair Tocancipa Triana <jhair_tocancipa@@gmx.net>
+
+ * gnus-audio.el (gnus-audio-au-player, gnus-audio-wav-player): Use
+ /usr/bin/play as default player.
+ (gnus-audio-play): Added ARG-DESCRIPTOR to prompt for a file to play.
+
+2003-01-14 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * gnus-msg.el (gnus-inews-add-send-actions): Allow a list of
+ articles to be marked as well.
+
+2002-01-14 Kevin Greiner <kgreiner@xpediantsolutions.com>
+ * gnus-agent.el (gnus-agent-get-undownloaded-list): Include the
+ fictious headers generated by nnagent (ie. Undownloaded Article
+ ####) in the list of articles that have not been downloaded.
+
+ * gnus-int.el (): Added require declarations to resolve
+ compile-time warnings.
+ (gnus-open-server): If the server status is set to offline,
+ recursively execute gnus-open-server to open the offline backend
+ (e.g. nnagent).
+
+2003-01-14 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus-art.el (gnus-article-reply-with-original): Use
+ gnus-mark-active-p.
+ (gnus-article-followup-with-original): do.
+
+2003-01-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus-sum.el: Removed `(when t ...)' around `gnus-define-keys'.
+
+2003-01-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus-score.el (gnus-score-edit-file-at-point): New function.
+ (gnus-score-find-trace): Bind it to `e' key. Added `q' for quit.
+
+2003-01-13 Romain FRANCOISE <romain@orebokech.com>
+
+ * gnus-fun.el (gnus-x-face-from-file): Quote file name.
+ (gnus-face-from-file): Ditto.
+
+2003-01-13 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-sum.el (gnus-articles-to-read): Don't just apply
+ gnus-alter-articles-to-read-function to the unread articles.
+
+2003-01-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * deuglify.el (gnus-article-outlook-unwrap-lines)
+ (gnus-article-outlook-repair-attribution)
+ (gnus-article-outlook-rearrange-citation): New function names,
+ renamed from "gnus-outlook-" to "gnus-article-outlook-". Changed
+ doc-string.
+
+ * gnus-sum.el (gnus-summary-mode-map): Use new function names,
+ removed `W k' key binding (use `W Y f' instead).
+ (gnus-summary-make-menu-bar): Use new function names.
+
+2003-01-13 Simon Josefsson <jas@extundo.com>
+
+ * gnus-fun.el (gnus-random-x-face): Doc fix.
+ (gnus-insert-random-x-face-header): New function.
+
+2003-01-13 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus-sum.el (gnus-summary-make-menu-bar): Deactivate items if
+ mark is not active.
+
+ * gnus-msg.el (gnus-inews-do-gcc): Comment.
+
+ * gnus-ems.el (gnus-mark-active-p): New function.
+
+ * gnus-group.el (gnus-topic-mode-p): New function.
+ (gnus-group-make-menu-bar): Show more key bindings in topic mode.
+ Deactivate items if mark is not active.
+
+2003-01-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus.el (gnus-version-number): Bumped version.
+ (gnus-summary-line-format): Doc fix.
+
2003-01-12 22:02:49 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
* gnus.el: Oort Gnus v0.12 is released.
;; > verb. This sentence no verb. This sentence no verb. This
;; > sentence no verb.
;;
-;; The function `gnus-outlook-unwrap-lines' tries to recognize those
+;; The function `gnus-article-outlook-unwrap-lines' tries to recognize those
;; erroneously wrapped lines and will unwrap them. I.e. putting the
;; wrapped parts ("no" in this example) back where they belong (at the
;; end of the cited line above).
;;
;; Unwrapping "You forgot in all your sentences." would be illegal as
;; this part wasn't intended to be cited text.
-;; `gnus-outlook-unwrap-lines' will only unwrap lines if the resulting
+;; `gnus-article-outlook-unwrap-lines' will only unwrap lines if the resulting
;; citation line will be of a certain maximum length. You can control
;; this by adjusting `gnus-outlook-deuglify-unwrap-max'. Also
;; unwrapping will only be done if the line above the (possibly)
;; > Bye, John
;;
;; Repairing the attribution line will be done by function
-;; `gnus-outlook-repair-attribution' which calls other function that
+;; `gnus-article-outlook-repair-attribution which calls other function that
;; try to recognize and repair broken attribution lines. See variable
;; `gnus-outlook-deuglify-attrib-cut-regexp' for stuff that should be
;; cut off from the beginning of an attribution line and variable
;;
;; Rearranging the article so that the cited text appears above the
;; new text will be done by function
-;; `gnus-outlook-rearrange-citation'. This function calls
-;; `gnus-outlook-repair-attribution' to find and repair an attribution
+;; `gnus-article-outlook-rearrange-citation'. This function calls
+;; `gnus-article-outlook-repair-attribution to find and repair an attribution
;; line.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; To automatically invoke deuglification on every article you read,
;; put something like that in your .gnus:
;;
-;; (add-hook 'gnus-article-decode-hook 'gnus-outlook-unwrap-lines)
+;; (add-hook 'gnus-article-decode-hook 'gnus-article-outlook-unwrap-lines)
;;
;; or _one_ of the following lines:
;;
;; ;; repair broken attribution lines
-;; (add-hook 'gnus-article-decode-hook 'gnus-outlook-repair-attribution)
+;; (add-hook 'gnus-article-decode-hook 'gnus-article-outlook-repair-attribution)
;;
;; ;; repair broken attribution lines and citations
-;; (add-hook 'gnus-article-decode-hook 'gnus-outlook-rearrange-citation)
+;; (add-hook 'gnus-article-decode-hook 'gnus-article-outlook-rearrange-citation)
;;
;; Note that there always may be some false positives, so I suggest
;; using the manual invocation. After deuglification you may want to
;; -----------
;;
;; As I said before there may (or will) be a few false positives on
-;; unwrapping cited lines with `gnus-outlook-unwrap-lines'.
+;; unwrapping cited lines with `gnus-article-outlook-unwrap-lines'.
;;
-;; `gnus-outlook-repair-attribution' will only fix the first
+;; `gnus-article-outlook-repair-attribution will only fix the first
;; attribution line found in the article. Furthermore it fixed to
;; certain kinds of attributions. And there may be horribly many
;; false positives, vanishing lines and so on -- so don't trust your
;; eyes. Again I recommend manual invocation.
;;
-;; `gnus-outlook-rearrange-citation' carries all the limitations of
-;; `gnus-outlook-repair-attribution'.
+;; `gnus-article-outlook-rearrange-citation' carries all the limitations of
+;; `gnus-article-outlook-repair-attribution.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
'gnus-outlook-display-hook)))
;;;###autoload
-(defun gnus-outlook-unwrap-lines (&optional nodisplay)
+(defun gnus-article-outlook-unwrap-lines (&optional nodisplay)
"Unwrap lines that appear to be wrapped citation lines.
You can control what lines will be unwrapped by frobbing
`gnus-outlook-deuglify-unwrap-min' and `gnus-outlook-deuglify-unwrap-max',
(match-beginning 0)))))))
;;;###autoload
-(defun gnus-outlook-repair-attribution (&optional nodisplay)
+(defun gnus-article-outlook-repair-attribution (&optional nodisplay)
"Repair a broken attribution line.
If NODISPLAY is non-nil, don't redisplay the article buffer."
(interactive "P")
(unless nodisplay (gnus-outlook-display-article-buffer))
attrib-start))
-(defun gnus-outlook-rearrange-citation (&optional nodisplay)
+(defun gnus-article-outlook-rearrange-citation (&optional nodisplay)
"Repair broken citations.
If NODISPLAY is non-nil, don't redisplay the article buffer."
(interactive "P")
- (let ((attrib-start (gnus-outlook-repair-attribution 'nodisplay)))
+ (let ((attrib-start (gnus-article-outlook-repair-attribution 'nodisplay)))
;; rearrange citations if an attribution line has been recognized
(if attrib-start
(gnus-outlook-rearrange-article attrib-start)))
;;;###autoload
(defun gnus-outlook-deuglify-article (&optional nodisplay)
- "Deuglify broken Outlook (Express) articles.
-If NODISPLAY is non-nil, don't redisplay the article buffer."
+ "Full deuglify of broken Outlook (Express) articles.
+Treat dumbquotes, unwrap lines, repair attribution and rearrange citation. If
+NODISPLAY is non-nil, don't redisplay the article buffer."
(interactive "P")
;; apply treatment of dumb quotes
(gnus-article-treat-dumbquotes)
;; repair wrapped cited lines
- (gnus-outlook-unwrap-lines 'nodisplay)
- ;; repair attribution line
- (gnus-outlook-rearrange-citation 'nodisplay)
+ (gnus-article-outlook-unwrap-lines 'nodisplay)
+ ;; repair attribution line and rearrange citation.
+ (gnus-article-outlook-rearrange-citation 'nodisplay)
(unless nodisplay (gnus-outlook-display-article-buffer)))
;;;###autoload
(cadr gnus-command-method))))
(defsubst gnus-agent-directory ()
- "Path of the Gnus agent directory."
+ "The name of the Gnus agent directory."
(nnheader-concat gnus-agent-directory
(nnheader-translate-file-chars (gnus-agent-method)) "/"))
(defun gnus-agent-lib-file (file)
- "The full path of the Gnus agent library FILE."
+ "The full name of the Gnus agent library FILE."
(expand-file-name file
(file-name-as-directory
(expand-file-name "agent.lib" (gnus-agent-directory)))))
(cond ((< a h)
(pop alist)) ; ignore IDs in the alist that are not being displayed in the summary
((> a h)
- (pop headers)) ; ignore headers that are not in the alist as these should be fictious (see nnagent-retrieve-headers).
+ ;; headers that are not in the alist should be
+ ;; fictious (see nnagent-retrieve-headers); they
+ ;; imply that this article isn't in the agent.
+ (gnus-agent-append-to-list tail h)
+ (pop headers))
((cdar alist)
(pop alist)
(pop headers)
(pop alist)
(pop headers)
(gnus-agent-append-to-list tail a)))))
+
+ (while headers
+ (gnus-agent-append-to-list tail (mail-header-number (pop headers))))
(setq gnus-newsgroup-undownloaded (cdr undownloaded))))))
(defun gnus-agent-catchup ()
(delete-char 1))))))
(defun gnus-agent-group-path (group)
- "Translate GROUP into a path."
+ "Translate GROUP into a file name."
(if nnmail-use-long-file-names
(gnus-group-real-name group)
(nnheader-translate-file-chars
(gnus-message 1
"Duplicate overview line for %d" cur)
(delete-region (point) (progn (forward-line 1) (point))))
- ((< cur 0)
+ ((< cur prev-num)
(or backed-up
(setq backed-up (gnus-agent-backup-overview-buffer)))
- (gnus-message 1 "Junk article number %d" cur)
- (delete-region (point) (progn (forward-line 1) (point))))
- ((< cur prev-num)
+ (gnus-message 1 "Overview buffer not sorted!")
(sort-numeric-fields 1 (point-min) (point-max))
(goto-char (point-min))
- (setq prev-num -1)
- (or backed-up
- (setq backed-up (gnus-agent-backup-overview-buffer)))
- (gnus-message 1 "Overview buffer not sorted!"))
+ (setq prev-num -1))
(t
(setq prev-num cur)))
(forward-line 1)))))))
(setq gnus-newsgroup-dependencies
(or gnus-newsgroup-dependencies
(make-vector (length articles) 0)))
-
(setq gnus-newsgroup-headers
(or gnus-newsgroup-headers
(gnus-get-newsgroup-headers-xover articles nil nil
(let ((arts (list nil)))
(let ((arts-tail arts)
(alist (gnus-agent-load-alist group))
- (marked-articles marked-articles))
+ (marked-articles marked-articles)
+ (gnus-newsgroup-headers gnus-newsgroup-headers))
(while (setq gnus-headers (pop gnus-newsgroup-headers))
(let ((num (mail-header-number gnus-headers)))
;; Determine if this article is already in the cache
(let ((unfetched-articles (gnus-sorted-ndifference (cdr arts) fetched-articles)))
(if gnus-newsgroup-active
+ ;; Update the summary buffer
(progn
(dolist (article marked-articles)
(when (gnus-summary-goto-subject article nil t)
(gnus-summary-set-agent-mark article t)))
(dolist (article fetched-articles)
(if gnus-agent-mark-unread-after-downloaded
- (gnus-summary-mark-article article gnus-unread-mark)))
+ (gnus-summary-mark-article article gnus-unread-mark))
+ (when (gnus-summary-goto-subject article nil t)
+ (gnus-summary-update-download-mark article)))
(dolist (article unfetched-articles)
(gnus-summary-mark-article article gnus-canceled-mark)))
+
+ ;; Update the group buffer.
+
;; When some, or all, of the marked articles came
;; from the download mark. Remove that mark. I
;; didn't do this earlier as I only want to remove
(gnus-agent-directory)
(gnus-agent-group-path expiring-group) "/"))
(active
- (gnus-gethash-safe expiring-group orig)))
+ (gnus-gethash-safe expiring-group orig))
+ (day (if (numberp day)
+ day
+ (let (found
+ (days gnus-agent-expire-days))
+ (catch 'found
+ (while (and (not found)
+ days)
+ (when (eq 0 (string-match (caar days) expiring-group))
+ (throw 'found (- (time-to-days (current-time)) (cadar days))))
+ (pop days))
+ ;; No regexp matched so set a limit that will block expiration in this group
+ 0)))))
+
(when active
(gnus-agent-load-alist expiring-group)
(gnus-message 5 "Expiring articles in %s" expiring-group)
;; We now have the arrival day, so we see
;; whether it's old enough to be expired.
- ((< fetch-date
- (if (numberp day)
- day
- (let (found
- (days gnus-agent-expire-days))
- (while (and (not found)
- days)
- (when (eq 0 (string-match (caar days) expiring-group))
- (setq found (cadar days)))
- (pop days))
- found)))
+ ((< fetch-date day)
'expired)
(force
'forced)))
(defun gnus-agent-regenerate-group (group &optional reread)
"Regenerate GROUP. If REREAD is t, all articles in the .overview are marked as unread. If REREAD is not nil, downloaded articles are marked as unread."
+ (interactive (list (let ((def (or (gnus-group-group-name)
+ gnus-newsgroup-name)))
+ (let ((select (read-string (if def (concat "Group Name (" def "): ")
+ "Group Name: "))))
+ (if (and (equal "" select)
+ def)
+ def
+ select)))
+ (intern-soft (read-string "Reread (nil)? (t=>all, nil=>none, some=>all downloaded): "))))
(gnus-message 5 "Regenerating in %s" group)
(let* ((gnus-command-method (or gnus-command-method
(gnus-find-method-for-group group)))
(jka-compr-delete-temp-file err-file)))))))
(defun gnus-mime-copy-part (&optional handle)
- "Put the MIME part under point into a new buffer."
+ "Put the MIME part under point into a new buffer.
+If `auto-compression-mode' is enabled, compressed files like .gz and .bz2
+are decompressed."
(interactive)
(gnus-article-check-buffer)
(let* ((handle (or handle (get-text-property (point) 'gnus-data)))
(let* ((handle (or handle (get-text-property (point) 'gnus-data)))
(contents (and handle (mm-get-part handle)))
(file (mm-make-temp-file (expand-file-name "mm." mm-tmp-directory)))
- (printer (mailcap-mime-info (mm-handle-type handle) "print")))
+ (printer (mailcap-mime-info (mm-handle-media-type handle) "print")))
(when contents
(if printer
(unwind-protect
(progn
- (with-temp-file file
- (insert contents))
+ (mm-save-part-to-file handle file)
(call-process shell-file-name nil
(generate-new-buffer " *mm*")
nil
The text in the region will be yanked. If the region isn't active,
the entire article will be yanked."
(interactive "P")
- (let ((article (cdr gnus-article-current)) cont)
- (if (not (mark t))
+ (let ((article (cdr gnus-article-current))
+ contents)
+ (if (not (gnus-mark-active-p))
(with-current-buffer gnus-summary-buffer
(gnus-summary-reply (list (list article)) wide))
- (setq cont (buffer-substring (point) (mark t)))
+ (setq contents (buffer-substring (point) (mark t)))
;; Deactivate active regions.
(when (and (boundp 'transient-mark-mode)
transient-mark-mode)
(setq mark-active nil))
(with-current-buffer gnus-summary-buffer
(gnus-summary-reply
- (list (list article cont)) wide)))))
+ (list (list article contents)) wide)))))
(defun gnus-article-followup-with-original ()
"Compose a followup to the current article.
The text in the region will be yanked. If the region isn't active,
the entire article will be yanked."
(interactive)
- (let ((article (cdr gnus-article-current)) cont)
- (if (not (mark t))
+ (let ((article (cdr gnus-article-current))
+ contents)
+ (if (not (gnus-mark-active-p))
(with-current-buffer gnus-summary-buffer
(gnus-summary-followup (list (list article))))
- (setq cont (buffer-substring (point) (mark t)))
+ (setq contents (buffer-substring (point) (mark t)))
;; Deactivate active regions.
(when (and (boundp 'transient-mark-mode)
transient-mark-mode)
(setq mark-active nil))
(with-current-buffer gnus-summary-buffer
(gnus-summary-followup
- (list (list article cont)))))))
+ (list (list article contents)))))))
(defun gnus-article-hide (&optional arg force)
"Hide all the gruft in the current article.
(defcustom gnus-button-url-regexp
(if (string-match "[[:digit:]]" "1") ;; support POSIX?
- "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)\\(//[-a-z0-9_.]+:[0-9]*\\)?[-a-z0-9_=!?#$@~`%&*+|\\/:;.,[:word:]]+[-a-z0-9_=#$@~`%&*+|\\/[:word:]]\\)"
- "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)\\(//[-a-z0-9_.]+:[0-9]*\\)?\\([-a-z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-z0-9_=#$@~`%&*+|\\/]\\|\\w\\)\\)")
+ "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)\\(//[-a-z0-9_.]+:[0-9]*\\)?[-a-z0-9_=!?#$@~`%&*+\\/:;.,[:word:]]+[-a-z0-9_=#$@~`%&*+\\/[:word:]]\\)"
+ "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)\\(//[-a-z0-9_.]+:[0-9]*\\)?\\([-a-z0-9_=!?#$@~`%&*+\\/:;.,]\\|\\w\\)+\\([-a-z0-9_=#$@~`%&*+\\/]\\|\\w\\)\\)")
"Regular expression that matches URLs."
:group 'gnus-article-buttons
:type 'regexp)
:type '(choice directory (const nil))
:group 'gnus-audio)
-(defcustom gnus-audio-au-player "/usr/bin/showaudio"
+(defcustom gnus-audio-au-player (executable-find "play")
"Executable program for playing sun AU format sound files."
:group 'gnus-audio
:type 'string)
-(defcustom gnus-audio-wav-player "/usr/local/bin/play"
+(defcustom gnus-audio-wav-player (executable-find "play")
"Executable program for playing WAV files."
:group 'gnus-audio
:type 'string)
;;;###autoload
(defun gnus-audio-play (file)
"Play a sound FILE through the speaker."
- (interactive)
+ (interactive "fSound file name: ")
(let ((sound-file (if (file-exists-p file)
file
(expand-file-name file gnus-audio-directory))))
;;; gnus-ems.el --- functions for making Gnus work under different Emacsen
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
(boundp 'mark-active)
mark-active))
+(defun gnus-mark-active-p ()
+ "Non-nil means the mark and region are currently active in this buffer."
+ mark-active) ; aliased to region-exists-p in XEmacs.
+
(if (fboundp 'add-minor-mode)
(defalias 'gnus-add-minor-mode 'add-minor-mode)
(defun gnus-add-minor-mode (mode name map &rest rest)
:type 'string)
(defcustom gnus-convert-image-to-x-face-command "giftopnm %s | ppmnorm | pnmscale -width 48 -height 48 | ppmtopgm | pgmtopbm | pbmtoxbm | compface"
- "Command for converting a GIF to an X-Face."
+ "Command for converting an image to an X-Face.
+By default it takes a GIF filename and output the X-Face header data
+on stdout."
:group 'gnus-fun
:type 'string)
(defcustom gnus-convert-image-to-face-command "djpeg %s | ppmnorm | pnmscale -width 48 -height 48 | ppmquant %d | pnmtopng"
- "Command for converting a GIF to an X-Face."
+ "Command for converting an image to an Face.
+By default it takes a JPEG filename and output the Face header data
+on stdout."
:group 'gnus-fun
:type 'string)
;;;###autoload
(defun gnus-random-x-face ()
- "Insert a random X-Face header from `gnus-x-face-directory'."
+ "Return X-Face header data chosen randomly from `gnus-x-face-directory'."
(interactive)
(when (file-exists-p gnus-x-face-directory)
(let* ((files (directory-files gnus-x-face-directory t "\\.pbm$"))
(shell-quote-argument file)))))))
;;;###autoload
+(defun gnus-insert-random-x-face-header ()
+ "Insert a random X-Face header from `gnus-x-face-directory'."
+ (interactive)
+ (let ((data (gnus-random-x-face)))
+ (save-excursion
+ (message-goto-eoh)
+ (if data
+ (insert "X-Face: " data)
+ (message
+ "No face returned by `gnus-random-x-face'. Does %s/*.pbm exist?"
+ gnus-x-face-directory)))))
+
+;;;###autoload
(defun gnus-x-face-from-file (file)
"Insert an X-Face header based on an image file."
- (interactive "fImage file name:" )
+ (interactive "fImage file name (by default GIF): ")
(when (file-exists-p file)
(gnus-shell-command-to-string
(format gnus-convert-image-to-x-face-command
- (shell-quote-argument file)))))
+ (shell-quote-argument (expand-file-name file))))))
;;;###autoload
(defun gnus-face-from-file (file)
"Return an Face header based on an image file."
- (interactive "fImage file name:" )
+ (interactive "fImage file name (by default JPEG): ")
(when (file-exists-p file)
(let ((done nil)
(attempt "")
(setq attempt
(gnus-shell-command-to-string
(format gnus-convert-image-to-face-command
- (shell-quote-argument file)
+ (shell-quote-argument (expand-file-name file))
quant)))
(if (> (length attempt) 740)
(progn
(defun gnus-convert-face-to-png (face)
(mm-with-unibyte-buffer
(insert face)
- (base64-decode-region (point-min) (point-max))
+ (ignore-errors
+ (base64-decode-region (point-min) (point-max)))
(buffer-string)))
(defun gnus-convert-image-to-gray-x-face (file depth)
The icon from the file field after the first true form is used. You
can change how those group lines are displayed by editing the file
field. The File will either be found in the
-`gnus-group-glyph-directory' or by designating absolute path to the
+`gnus-group-glyph-directory' or by designating absolute name of the
file.
It is also possible to change and add form fields, but currently that
"\C-k" gnus-group-kill-level
"z" gnus-group-kill-all-zombies))
+(defun gnus-topic-mode-p ()
+ "Return non-nil in `gnus-topic-mode'."
+ (and (boundp 'gnus-topic-mode)
+ gnus-topic-mode))
+
(defun gnus-group-make-menu-bar ()
(gnus-turn-off-edit-menu 'group)
(unless (boundp 'gnus-group-reading-menu)
(easy-menu-define
gnus-group-reading-menu gnus-group-mode-map ""
`("Group"
- ["Read" gnus-group-read-group (gnus-group-group-name)]
- ["Select" gnus-group-select-group (gnus-group-group-name)]
+ ["Read" gnus-group-read-group
+ :included (not (gnus-topic-mode-p))
+ :active (gnus-group-group-name)]
+ ["Read " gnus-topic-read-group
+ :included (gnus-topic-mode-p)]
+ ["Select" gnus-group-select-group
+ :included (not (gnus-topic-mode-p))
+ :active (gnus-group-group-name)]
+ ["Select " gnus-topic-select-group
+ :included (gnus-topic-mode-p)]
["See old articles" (gnus-group-select-group 'all)
:keys "C-u SPC" :active (gnus-group-group-name)]
- ["Catch up" gnus-group-catchup-current :active (gnus-group-group-name)
+ ["Catch up" gnus-group-catchup-current
+ :included (not (gnus-topic-mode-p))
+ :active (gnus-group-group-name)
,@(if (featurep 'xemacs) nil
'(:help "Mark unread articles in the current group as read"))]
+ ["Catch up " gnus-topic-catchup-articles
+ :included (gnus-topic-mode-p)
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Mark unread articles in the current group or topic as read"))]
["Catch up all articles" gnus-group-catchup-current-all
(gnus-group-group-name)]
["Check for new articles" gnus-group-get-new-news-this-group
+ :included (not (gnus-topic-mode-p))
:active (gnus-group-group-name)
,@(if (featurep 'xemacs) nil
'(:help "Check for new messages in current group"))]
+ ["Check for new articles " gnus-topic-get-new-news-this-topic
+ :included (gnus-topic-mode-p)
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Check for new messages in current group or topic"))]
["Toggle subscription" gnus-group-unsubscribe-current-group
(gnus-group-group-name)]
["Kill" gnus-group-kill-group :active (gnus-group-group-name)
,@(if (featurep 'xemacs) nil
'(:help "Display description of the current group"))]
["Fetch FAQ" gnus-group-fetch-faq (gnus-group-group-name)]
- ["Fetch charter" gnus-group-fetch-charter :active (gnus-group-group-name)
+ ["Fetch charter" gnus-group-fetch-charter
+ :active (gnus-group-group-name)
,@(if (featurep 'xemacs) nil
'(:help "Display the charter of the current group"))]
- ["Fetch control message" gnus-group-fetch-control :active (gnus-group-group-name)
+ ["Fetch control message" gnus-group-fetch-control
+ :active (gnus-group-group-name)
,@(if (featurep 'xemacs) nil
'(:help "Display the archived control message for the current group"))]
;; Actually one should check, if any of the marked groups gives t for
;; (gnus-check-backend-function 'request-expire-articles ...)
- ["Expire articles" gnus-group-expire-articles
- (or (and (gnus-group-group-name)
- (gnus-check-backend-function
- 'request-expire-articles
- (gnus-group-group-name))) gnus-group-marked)]
+ ["Expire articles" gnus-group-expire-articles
+ :included (not (gnus-topic-mode-p))
+ :active (or (and (gnus-group-group-name)
+ (gnus-check-backend-function
+ 'request-expire-articles
+ (gnus-group-group-name))) gnus-group-marked)]
+ ["Expire articles " gnus-topic-expire-articles
+ :included (gnus-topic-mode-p)]
["Set group level..." gnus-group-set-current-level
(gnus-group-group-name)]
["Select quick" gnus-group-quick-select-group (gnus-group-group-name)]
["Customize" gnus-group-customize (gnus-group-group-name)]
("Edit"
["Parameters" gnus-group-edit-group-parameters
- (gnus-group-group-name)]
+ :included (not (gnus-topic-mode-p))
+ :active (gnus-group-group-name)]
+ ["Parameters " gnus-topic-edit-parameters
+ :included (gnus-topic-mode-p)]
["Select method" gnus-group-edit-group-method
(gnus-group-group-name)]
["Info" gnus-group-edit-group (gnus-group-group-name)]
["Sort by real name" gnus-group-sort-groups-by-real-name t])
("Sort process/prefixed"
["Default sort" gnus-group-sort-selected-groups
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by method" gnus-group-sort-selected-groups-by-method
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by rank" gnus-group-sort-selected-groups-by-rank
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by score" gnus-group-sort-selected-groups-by-score
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by level" gnus-group-sort-selected-groups-by-level
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by unread" gnus-group-sort-selected-groups-by-unread
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by name" gnus-group-sort-selected-groups-by-alphabet
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]
+ (not (gnus-topic-mode-p))]
["Sort by real name" gnus-group-sort-selected-groups-by-real-name
- (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))])
+ (not (gnus-topic-mode-p))])
("Mark"
["Mark group" gnus-group-mark-group
(and (gnus-group-group-name)
(memq (gnus-group-group-name) gnus-group-marked))]
["Unmark all" gnus-group-unmark-all-groups gnus-group-marked]
["Mark regexp..." gnus-group-mark-regexp t]
- ["Mark region" gnus-group-mark-region t]
+ ["Mark region" gnus-group-mark-region :active (gnus-mark-active-p)]
["Mark buffer" gnus-group-mark-buffer t]
["Execute command" gnus-group-universal-argument
(or gnus-group-marked (gnus-group-group-name))])
("Subscribe"
["Subscribe to a group..." gnus-group-unsubscribe-group t]
- ["Kill all newsgroups in region" gnus-group-kill-region t]
+ ["Kill all newsgroups in region" gnus-group-kill-region
+ :active (gnus-mark-active-p)]
["Kill all zombie groups" gnus-group-kill-all-zombies
gnus-zombie-list]
["Kill all groups on level..." gnus-group-kill-level t])
(eval-when-compile (require 'cl))
(require 'gnus)
+(require 'message)
+(require 'gnus-range)
+
+(eval-when-compile
+ (defun gnus-agent-expire (a b c)))
(defcustom gnus-open-server-hook nil
"Hook called just before opening connection to the news server."
(format "Unable to open %s:%s, go offline? "
(car gnus-command-method)
(cadr gnus-command-method)))
- 'offline
+ 'offline
'denied))
'denied)))
;; Return the result from the "open" call.
- (or (eq (cadr elem) 'offline)
- result)))))
+ (cond ((eq (cadr elem) 'offline)
+ ;; I'm avoiding infinite recursion by binding unopen
+ ;; status to denied (The logic of this routine
+ ;; guarantees that I can't get to this point with
+ ;; unopen status already bound to denied).
+ (unless (eq gnus-server-unopen-status 'denied)
+ (let ((gnus-server-unopen-status 'denied))
+ (gnus-open-server gnus-command-method)))
+ t)
+ (t
+ result))))))
(defun gnus-close-server (gnus-command-method)
"Close the connection to GNUS-COMMAND-METHOD."
`(set-window-configuration ,winconf) 'exit 'postpone 'kill)
(let ((to-be-marked (cond
(yanked yanked)
- (article (list article))
+ (article (if (listp article) article (list article)))
(t nil))))
(message-add-action
`(when (gnus-buffer-exists-p ,buffer)
group (gnus-status-message method))
(sit-for 2))
(when (and group-art
+ ;; FIXME: Should gcc-mark-as-read work when
+ ;; Gnus is not running?
(gnus-alive-p)
(or gnus-gcc-mark-as-read
gnus-inews-mark-gcc-as-read))
(require 'message)
(require 'score-mode)
+(autoload 'ffap-string-at-point "ffap")
+
(defcustom gnus-global-score-files nil
"List of global score files and directories.
Set this variable if you want to use people's score files. One entry
4 (substitute-command-keys
"\\<gnus-score-mode-map>\\[gnus-score-edit-exit] to save edits")))
+(defun gnus-score-edit-file-at-point ()
+ "Edit score file at point. Useful especially after `V t'."
+ (interactive)
+ (gnus-score-edit-file (ffap-string-at-point)))
+
(defun gnus-score-load-file (file)
;; Load score file FILE. Returns a list a retrieved score-alists.
(let* ((file (expand-file-name
1 "No score rules apply to the current article (default score %d)."
gnus-summary-default-score)
(set-buffer "*Score Trace*")
+ ;; ToDo: Use a keymap instead?
+ (local-set-key "q"
+ (lambda ()
+ (interactive)
+ (kill-buffer nil)
+ (gnus-article-show-summary)))
+ (local-set-key "e" 'gnus-score-edit-file-at-point)
(setq truncate-lines t)
(while trace
(insert (format "%S -> %s\n" (cdar trace)
;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
(autoload 'gnus-article-outlook-deuglify-article "deuglify"
"Deuglify broken Outlook (Express) articles and redisplay."
t)
-(autoload 'gnus-outlook-unwrap-lines "deuglify" nil t)
-(autoload 'gnus-outlook-repair-attribution "deuglify" nil t)
-(autoload 'gnus-outlook-rearrange-citation "deuglify" nil t)
+(autoload 'gnus-article-outlook-unwrap-lines "deuglify" nil t)
+(autoload 'gnus-article-outlook-repair-attribution "deuglify" nil t)
+(autoload 'gnus-article-outlook-rearrange-citation "deuglify" nil t)
(defcustom gnus-kill-summary-on-exit t
"*If non-nil, kill the summary buffer when you exit from it.
(defcustom gnus-alter-header-function nil
"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.")
+which it may alter in any way."
+ :type '(choice (const :tag "None" nil)
+ function)
+ :group 'gnus-summary)
(defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
"Variable that says which function should be used to decode a string with encoded words.")
(defvar gnus-article-commands-menu)
-(when t
- ;; Non-orthogonal keys
-
- (gnus-define-keys gnus-summary-mode-map
- " " gnus-summary-next-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- [backspace] gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\M-\C-n" gnus-summary-next-same-subject
- "\M-\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "." gnus-summary-first-unread-article
- "," gnus-summary-best-unread-article
- "\M-s" gnus-summary-search-article-forward
- "\M-r" gnus-summary-search-article-backward
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "j" gnus-summary-goto-article
- "^" gnus-summary-refer-parent-article
- "\M-^" gnus-summary-refer-article
- "u" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "U" gnus-summary-tick-article-backward
- "d" gnus-summary-mark-as-read-forward
- "D" gnus-summary-mark-as-read-backward
- "E" gnus-summary-mark-as-expirable
- "\M-u" gnus-summary-clear-mark-forward
- "\M-U" gnus-summary-clear-mark-backward
- "k" gnus-summary-kill-same-subject-and-select
- "\C-k" gnus-summary-kill-same-subject
- "\M-\C-k" gnus-summary-kill-thread
- "\M-\C-l" gnus-summary-lower-thread
- "e" gnus-summary-edit-article
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "\M-\C-t" gnus-summary-toggle-threads
- "\M-\C-s" gnus-summary-show-thread
- "\M-\C-h" gnus-summary-hide-thread
- "\M-\C-f" gnus-summary-next-thread
- "\M-\C-b" gnus-summary-prev-thread
- [(meta down)] gnus-summary-next-thread
- [(meta up)] gnus-summary-prev-thread
- "\M-\C-u" gnus-summary-up-thread
- "\M-\C-d" gnus-summary-down-thread
- "&" gnus-summary-execute-command
- "c" gnus-summary-catchup-and-exit
- "\C-w" gnus-summary-mark-region-as-read
- "\C-t" gnus-summary-toggle-truncation
- "?" gnus-summary-mark-as-dormant
- "\C-c\M-\C-s" gnus-summary-limit-include-expunged
- "\C-c\C-s\C-n" gnus-summary-sort-by-number
- "\C-c\C-s\C-l" gnus-summary-sort-by-lines
- "\C-c\C-s\C-c" gnus-summary-sort-by-chars
- "\C-c\C-s\C-a" gnus-summary-sort-by-author
- "\C-c\C-s\C-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
- "\C-c\C-s\C-r" gnus-summary-sort-by-random
- "=" gnus-summary-expand-window
- "\C-x\C-s" gnus-summary-reselect-current-group
- "\M-g" gnus-summary-rescan-group
- "w" gnus-summary-stop-page-breaking
- "\C-c\C-r" gnus-summary-caesar-message
- "f" gnus-summary-followup
- "F" gnus-summary-followup-with-original
- "C" gnus-summary-cancel-article
- "r" gnus-summary-reply
- "R" gnus-summary-reply-with-original
- "\C-c\C-f" gnus-summary-mail-forward
- "o" gnus-summary-save-article
- "\C-o" gnus-summary-save-article-mail
- "|" gnus-summary-pipe-output
- "\M-k" gnus-summary-edit-local-kill
- "\M-K" gnus-summary-edit-global-kill
- ;; "V" gnus-version
- "\C-c\C-d" gnus-summary-describe-group
- "q" gnus-summary-exit
- "Q" gnus-summary-exit-no-update
- "\C-c\C-i" gnus-info-find-node
- gnus-mouse-2 gnus-mouse-pick-article
- "m" gnus-summary-mail-other-window
- "a" gnus-summary-post-news
- "i" gnus-summary-news-other-window
- "x" gnus-summary-limit-to-unread
- "s" gnus-summary-isearch-article
- "t" gnus-summary-toggle-header
- "g" gnus-summary-show-article
- "l" gnus-summary-goto-last-article
- "\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
- "\M-\C-a" gnus-summary-customize-parameters
- "\C-c\C-b" gnus-bug
- "*" gnus-cache-enter-article
- "\M-*" gnus-cache-remove-article
- "\M-&" gnus-summary-universal-argument
- "\C-l" gnus-recenter
- "I" gnus-summary-increase-score
- "L" gnus-summary-lower-score
- "\M-i" gnus-symbolic-argument
- "h" gnus-summary-select-article-buffer
-
- "b" gnus-article-view-part
- "\M-t" gnus-summary-toggle-display-buttonized
-
- "V" gnus-summary-score-map
- "X" gnus-uu-extract-map
- "S" gnus-summary-send-map)
-
- ;; Sort of orthogonal keymap
- (gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
- "t" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "d" gnus-summary-mark-as-read-forward
- "r" gnus-summary-mark-as-read-forward
- "c" gnus-summary-clear-mark-forward
- " " gnus-summary-clear-mark-forward
- "e" gnus-summary-mark-as-expirable
- "x" gnus-summary-mark-as-expirable
- "?" gnus-summary-mark-as-dormant
- "b" gnus-summary-set-bookmark
- "B" gnus-summary-remove-bookmark
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "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
- "P" gnus-uu-mark-map)
-
- (gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
- "c" gnus-summary-clear-above
- "u" gnus-summary-tick-above
- "m" gnus-summary-mark-above
- "k" gnus-summary-kill-below)
-
- (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
- "/" gnus-summary-limit-to-subject
- "n" gnus-summary-limit-to-articles
- "w" gnus-summary-pop-limit
- "s" gnus-summary-limit-to-subject
- "a" gnus-summary-limit-to-author
- "u" gnus-summary-limit-to-unread
- "m" gnus-summary-limit-to-marks
- "M" gnus-summary-limit-exclude-marks
- "v" gnus-summary-limit-to-score
- "*" gnus-summary-limit-include-cached
- "D" gnus-summary-limit-include-dormant
- "T" gnus-summary-limit-include-thread
- "d" gnus-summary-limit-exclude-dormant
- "t" gnus-summary-limit-to-age
- "." gnus-summary-limit-to-unseen
- "x" gnus-summary-limit-to-extra
- "p" gnus-summary-limit-to-display-predicate
- "E" gnus-summary-limit-include-expunged
- "c" gnus-summary-limit-exclude-childless-dormant
- "C" gnus-summary-limit-mark-excluded-as-read
- "o" gnus-summary-insert-old-articles
- "N" gnus-summary-insert-new-articles)
-
- (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\C-n" gnus-summary-next-same-subject
- "\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "f" gnus-summary-first-unread-article
- "b" gnus-summary-best-unread-article
- "j" gnus-summary-goto-article
- "g" gnus-summary-goto-subject
- "l" gnus-summary-goto-last-article
- "o" gnus-summary-pop-article)
-
- (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
- "k" gnus-summary-kill-thread
- "l" gnus-summary-lower-thread
- "i" gnus-summary-raise-thread
- "T" gnus-summary-toggle-threads
- "t" gnus-summary-rethread-current
- "^" gnus-summary-reparent-thread
- "s" gnus-summary-show-thread
- "S" gnus-summary-show-all-threads
- "h" gnus-summary-hide-thread
- "H" gnus-summary-hide-all-threads
- "n" gnus-summary-next-thread
- "p" gnus-summary-prev-thread
- "u" gnus-summary-up-thread
- "o" gnus-summary-top-thread
- "d" gnus-summary-down-thread
- "#" gnus-uu-mark-thread
- "\M-#" gnus-uu-unmark-thread)
-
- (gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
- "g" gnus-summary-prepare
- "c" gnus-summary-insert-cached-articles
- "d" gnus-summary-insert-dormant-articles)
-
- (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
- "c" gnus-summary-catchup-and-exit
- "C" gnus-summary-catchup-all-and-exit
- "E" gnus-summary-exit-no-update
- "Q" gnus-summary-exit
- "Z" gnus-summary-exit
- "n" gnus-summary-catchup-and-goto-next-group
- "R" gnus-summary-reselect-current-group
- "G" gnus-summary-rescan-group
- "N" gnus-summary-next-group
- "s" gnus-summary-save-newsrc
- "P" gnus-summary-prev-group)
-
- (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
- " " gnus-summary-next-page
- "n" gnus-summary-next-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- "p" gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "b" gnus-summary-beginning-of-article
- "e" gnus-summary-end-of-article
- "^" gnus-summary-refer-parent-article
- "r" gnus-summary-refer-parent-article
- "D" gnus-summary-enter-digest-group
- "R" gnus-summary-refer-references
- "T" gnus-summary-refer-thread
- "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)
- "b" gnus-article-add-buttons
- "B" gnus-article-add-buttons-to-head
- "o" gnus-article-treat-overstrike
- "e" gnus-article-emphasize
- "w" gnus-article-fill-cited-article
- "Q" gnus-article-fill-long-lines
- "C" gnus-article-capitalize-sentences
- "c" gnus-article-remove-cr
- "q" gnus-article-de-quoted-unreadable
- "6" gnus-article-de-base64-unreadable
- "Z" gnus-article-decode-HZ
- "h" gnus-article-wash-html
- "u" gnus-article-unsplit-urls
- "s" gnus-summary-force-verify-and-decrypt
- "f" gnus-article-display-x-face
- "l" gnus-summary-stop-page-breaking
- "r" gnus-summary-caesar-message
- "m" gnus-summary-morse-message
- "t" gnus-summary-toggle-header
- "g" gnus-treat-smiley
- "v" gnus-summary-verbose-headers
- "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
- "p" gnus-article-verify-x-pgp-sig
- "d" gnus-article-treat-dumbquotes
- "k" gnus-article-outlook-deuglify-article) ;; mnemonic: outloo*k*
-
- (gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
- ;; mnemonic: deuglif*Y*
- "u" gnus-outlook-unwrap-lines
- "a" gnus-outlook-repair-attribution
- "c" gnus-outlook-rearrange-citation
- "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
-
- (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
- "a" gnus-article-hide
- "h" gnus-article-hide-headers
- "b" gnus-article-hide-boring-headers
- "s" gnus-article-hide-signature
- "c" gnus-article-hide-citation
- "C" gnus-article-hide-citation-in-followups
- "l" gnus-article-hide-list-identifiers
- "p" gnus-article-hide-pgp
- "B" gnus-article-strip-banner
- "P" gnus-article-hide-pem
- "\C-c" gnus-article-hide-citation-maybe)
-
- (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
- "a" gnus-article-highlight
- "h" gnus-article-highlight-headers
- "c" gnus-article-highlight-citation
- "s" gnus-article-highlight-signature)
-
- (gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
- "f" gnus-article-treat-fold-headers
- "u" gnus-article-treat-unfold-headers
- "n" gnus-article-treat-fold-newsgroups)
-
- (gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
- "x" gnus-article-display-x-face
- "d" gnus-article-display-face
- "s" gnus-treat-smiley
- "D" gnus-article-remove-images
- "f" gnus-treat-from-picon
- "m" gnus-treat-mail-picon
- "n" gnus-treat-newsgroups-picon)
-
- (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
- "w" gnus-article-decode-mime-words
- "c" gnus-article-decode-charset
- "v" gnus-mime-view-all-parts
- "b" gnus-article-view-part)
-
- (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
- "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
- "s" gnus-article-date-user)
-
- (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
- "t" gnus-article-remove-trailing-blank-lines
- "l" gnus-article-strip-leading-blank-lines
- "m" gnus-article-strip-multiple-blank-lines
- "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
- "w" gnus-article-remove-leading-whitespace)
-
- (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
- "v" gnus-version
- "f" gnus-summary-fetch-faq
- "d" gnus-summary-describe-group
- "h" gnus-summary-describe-briefly
- "i" gnus-info-find-node
- "c" gnus-group-fetch-charter
- "C" gnus-group-fetch-control)
-
- (gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
- "e" gnus-summary-expire-articles
- "\M-\C-e" gnus-summary-expire-articles-now
- "\177" gnus-summary-delete-article
- [delete] gnus-summary-delete-article
- [backspace] gnus-summary-delete-article
- "m" gnus-summary-move-article
- "r" gnus-summary-respool-article
- "w" gnus-summary-edit-article
- "c" gnus-summary-copy-article
- "B" gnus-summary-crosspost-article
- "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)
- "o" gnus-summary-save-article
- "m" gnus-summary-save-article-mail
- "F" gnus-summary-write-article-file
- "r" gnus-summary-save-article-rmail
- "f" gnus-summary-save-article-file
- "b" gnus-summary-save-article-body-file
- "h" gnus-summary-save-article-folder
- "v" gnus-summary-save-article-vm
- "p" gnus-summary-pipe-output
- "P" gnus-summary-muttprint
- "s" gnus-soup-add-article)
-
- (gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
- "b" gnus-summary-display-buttonized
- "m" gnus-summary-repair-multipart
- "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-view-part-externally
- "E" gnus-article-encrypt-body
- "i" gnus-article-inline-part
- "|" gnus-article-pipe-part)
-
- (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
- "p" gnus-summary-mark-as-processable
- "u" gnus-summary-unmark-as-processable
- "U" gnus-summary-unmark-all-processable
- "v" gnus-uu-mark-over
- "s" gnus-uu-mark-series
- "r" gnus-uu-mark-region
- "g" gnus-uu-unmark-region
- "R" gnus-uu-mark-by-regexp
- "G" gnus-uu-unmark-by-regexp
- "t" gnus-uu-mark-thread
- "T" gnus-uu-unmark-thread
- "a" gnus-uu-mark-all
- "b" gnus-uu-mark-buffer
- "S" gnus-uu-mark-sparse
- "k" gnus-summary-kill-process-mark
- "y" gnus-summary-yank-process-mark
- "w" gnus-summary-save-process-mark
- "i" gnus-uu-invert-processable)
-
- (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
- ;;"x" gnus-uu-extract-any
- "m" gnus-summary-save-parts
- "u" gnus-uu-decode-uu
- "U" gnus-uu-decode-uu-and-save
- "s" gnus-uu-decode-unshar
- "S" gnus-uu-decode-unshar-and-save
- "o" gnus-uu-decode-save
- "O" gnus-uu-decode-save
- "b" gnus-uu-decode-binhex
- "B" gnus-uu-decode-binhex
- "p" gnus-uu-decode-postscript
- "P" gnus-uu-decode-postscript-and-save)
-
- (gnus-define-keys
- (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
- "u" gnus-uu-decode-uu-view
- "U" gnus-uu-decode-uu-and-save-view
- "s" gnus-uu-decode-unshar-view
- "S" gnus-uu-decode-unshar-and-save-view
- "o" gnus-uu-decode-save-view
- "O" gnus-uu-decode-save-view
- "b" gnus-uu-decode-binhex-view
- "B" gnus-uu-decode-binhex-view
- "p" gnus-uu-decode-postscript-view
- "P" gnus-uu-decode-postscript-and-save-view))
+;; Non-orthogonal keys
+
+(gnus-define-keys gnus-summary-mode-map
+ " " gnus-summary-next-page
+ "\177" gnus-summary-prev-page
+ [delete] gnus-summary-prev-page
+ [backspace] gnus-summary-prev-page
+ "\r" gnus-summary-scroll-up
+ "\M-\r" gnus-summary-scroll-down
+ "n" gnus-summary-next-unread-article
+ "p" gnus-summary-prev-unread-article
+ "N" gnus-summary-next-article
+ "P" gnus-summary-prev-article
+ "\M-\C-n" gnus-summary-next-same-subject
+ "\M-\C-p" gnus-summary-prev-same-subject
+ "\M-n" gnus-summary-next-unread-subject
+ "\M-p" gnus-summary-prev-unread-subject
+ "." gnus-summary-first-unread-article
+ "," gnus-summary-best-unread-article
+ "\M-s" gnus-summary-search-article-forward
+ "\M-r" gnus-summary-search-article-backward
+ "<" gnus-summary-beginning-of-article
+ ">" gnus-summary-end-of-article
+ "j" gnus-summary-goto-article
+ "^" gnus-summary-refer-parent-article
+ "\M-^" gnus-summary-refer-article
+ "u" gnus-summary-tick-article-forward
+ "!" gnus-summary-tick-article-forward
+ "U" gnus-summary-tick-article-backward
+ "d" gnus-summary-mark-as-read-forward
+ "D" gnus-summary-mark-as-read-backward
+ "E" gnus-summary-mark-as-expirable
+ "\M-u" gnus-summary-clear-mark-forward
+ "\M-U" gnus-summary-clear-mark-backward
+ "k" gnus-summary-kill-same-subject-and-select
+ "\C-k" gnus-summary-kill-same-subject
+ "\M-\C-k" gnus-summary-kill-thread
+ "\M-\C-l" gnus-summary-lower-thread
+ "e" gnus-summary-edit-article
+ "#" gnus-summary-mark-as-processable
+ "\M-#" gnus-summary-unmark-as-processable
+ "\M-\C-t" gnus-summary-toggle-threads
+ "\M-\C-s" gnus-summary-show-thread
+ "\M-\C-h" gnus-summary-hide-thread
+ "\M-\C-f" gnus-summary-next-thread
+ "\M-\C-b" gnus-summary-prev-thread
+ [(meta down)] gnus-summary-next-thread
+ [(meta up)] gnus-summary-prev-thread
+ "\M-\C-u" gnus-summary-up-thread
+ "\M-\C-d" gnus-summary-down-thread
+ "&" gnus-summary-execute-command
+ "c" gnus-summary-catchup-and-exit
+ "\C-w" gnus-summary-mark-region-as-read
+ "\C-t" gnus-summary-toggle-truncation
+ "?" gnus-summary-mark-as-dormant
+ "\C-c\M-\C-s" gnus-summary-limit-include-expunged
+ "\C-c\C-s\C-n" gnus-summary-sort-by-number
+ "\C-c\C-s\C-l" gnus-summary-sort-by-lines
+ "\C-c\C-s\C-c" gnus-summary-sort-by-chars
+ "\C-c\C-s\C-a" gnus-summary-sort-by-author
+ "\C-c\C-s\C-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
+ "\C-c\C-s\C-r" gnus-summary-sort-by-random
+ "=" gnus-summary-expand-window
+ "\C-x\C-s" gnus-summary-reselect-current-group
+ "\M-g" gnus-summary-rescan-group
+ "w" gnus-summary-stop-page-breaking
+ "\C-c\C-r" gnus-summary-caesar-message
+ "f" gnus-summary-followup
+ "F" gnus-summary-followup-with-original
+ "C" gnus-summary-cancel-article
+ "r" gnus-summary-reply
+ "R" gnus-summary-reply-with-original
+ "\C-c\C-f" gnus-summary-mail-forward
+ "o" gnus-summary-save-article
+ "\C-o" gnus-summary-save-article-mail
+ "|" gnus-summary-pipe-output
+ "\M-k" gnus-summary-edit-local-kill
+ "\M-K" gnus-summary-edit-global-kill
+ ;; "V" gnus-version
+ "\C-c\C-d" gnus-summary-describe-group
+ "q" gnus-summary-exit
+ "Q" gnus-summary-exit-no-update
+ "\C-c\C-i" gnus-info-find-node
+ gnus-mouse-2 gnus-mouse-pick-article
+ "m" gnus-summary-mail-other-window
+ "a" gnus-summary-post-news
+ "i" gnus-summary-news-other-window
+ "x" gnus-summary-limit-to-unread
+ "s" gnus-summary-isearch-article
+ "t" gnus-summary-toggle-header
+ "g" gnus-summary-show-article
+ "l" gnus-summary-goto-last-article
+ "\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
+ "\M-\C-a" gnus-summary-customize-parameters
+ "\C-c\C-b" gnus-bug
+ "*" gnus-cache-enter-article
+ "\M-*" gnus-cache-remove-article
+ "\M-&" gnus-summary-universal-argument
+ "\C-l" gnus-recenter
+ "I" gnus-summary-increase-score
+ "L" gnus-summary-lower-score
+ "\M-i" gnus-symbolic-argument
+ "h" gnus-summary-select-article-buffer
+
+ "b" gnus-article-view-part
+ "\M-t" gnus-summary-toggle-display-buttonized
+
+ "V" gnus-summary-score-map
+ "X" gnus-uu-extract-map
+ "S" gnus-summary-send-map)
+
+;; Sort of orthogonal keymap
+(gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
+ "t" gnus-summary-tick-article-forward
+ "!" gnus-summary-tick-article-forward
+ "d" gnus-summary-mark-as-read-forward
+ "r" gnus-summary-mark-as-read-forward
+ "c" gnus-summary-clear-mark-forward
+ " " gnus-summary-clear-mark-forward
+ "e" gnus-summary-mark-as-expirable
+ "x" gnus-summary-mark-as-expirable
+ "?" gnus-summary-mark-as-dormant
+ "b" gnus-summary-set-bookmark
+ "B" gnus-summary-remove-bookmark
+ "#" gnus-summary-mark-as-processable
+ "\M-#" gnus-summary-unmark-as-processable
+ "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
+ "P" gnus-uu-mark-map)
+
+(gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
+ "c" gnus-summary-clear-above
+ "u" gnus-summary-tick-above
+ "m" gnus-summary-mark-above
+ "k" gnus-summary-kill-below)
+
+(gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
+ "/" gnus-summary-limit-to-subject
+ "n" gnus-summary-limit-to-articles
+ "w" gnus-summary-pop-limit
+ "s" gnus-summary-limit-to-subject
+ "a" gnus-summary-limit-to-author
+ "u" gnus-summary-limit-to-unread
+ "m" gnus-summary-limit-to-marks
+ "M" gnus-summary-limit-exclude-marks
+ "v" gnus-summary-limit-to-score
+ "*" gnus-summary-limit-include-cached
+ "D" gnus-summary-limit-include-dormant
+ "T" gnus-summary-limit-include-thread
+ "d" gnus-summary-limit-exclude-dormant
+ "t" gnus-summary-limit-to-age
+ "." gnus-summary-limit-to-unseen
+ "x" gnus-summary-limit-to-extra
+ "p" gnus-summary-limit-to-display-predicate
+ "E" gnus-summary-limit-include-expunged
+ "c" gnus-summary-limit-exclude-childless-dormant
+ "C" gnus-summary-limit-mark-excluded-as-read
+ "o" gnus-summary-insert-old-articles
+ "N" gnus-summary-insert-new-articles)
+
+(gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
+ "n" gnus-summary-next-unread-article
+ "p" gnus-summary-prev-unread-article
+ "N" gnus-summary-next-article
+ "P" gnus-summary-prev-article
+ "\C-n" gnus-summary-next-same-subject
+ "\C-p" gnus-summary-prev-same-subject
+ "\M-n" gnus-summary-next-unread-subject
+ "\M-p" gnus-summary-prev-unread-subject
+ "f" gnus-summary-first-unread-article
+ "b" gnus-summary-best-unread-article
+ "j" gnus-summary-goto-article
+ "g" gnus-summary-goto-subject
+ "l" gnus-summary-goto-last-article
+ "o" gnus-summary-pop-article)
+
+(gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
+ "k" gnus-summary-kill-thread
+ "l" gnus-summary-lower-thread
+ "i" gnus-summary-raise-thread
+ "T" gnus-summary-toggle-threads
+ "t" gnus-summary-rethread-current
+ "^" gnus-summary-reparent-thread
+ "s" gnus-summary-show-thread
+ "S" gnus-summary-show-all-threads
+ "h" gnus-summary-hide-thread
+ "H" gnus-summary-hide-all-threads
+ "n" gnus-summary-next-thread
+ "p" gnus-summary-prev-thread
+ "u" gnus-summary-up-thread
+ "o" gnus-summary-top-thread
+ "d" gnus-summary-down-thread
+ "#" gnus-uu-mark-thread
+ "\M-#" gnus-uu-unmark-thread)
+
+(gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
+ "g" gnus-summary-prepare
+ "c" gnus-summary-insert-cached-articles
+ "d" gnus-summary-insert-dormant-articles)
+
+(gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
+ "c" gnus-summary-catchup-and-exit
+ "C" gnus-summary-catchup-all-and-exit
+ "E" gnus-summary-exit-no-update
+ "Q" gnus-summary-exit
+ "Z" gnus-summary-exit
+ "n" gnus-summary-catchup-and-goto-next-group
+ "R" gnus-summary-reselect-current-group
+ "G" gnus-summary-rescan-group
+ "N" gnus-summary-next-group
+ "s" gnus-summary-save-newsrc
+ "P" gnus-summary-prev-group)
+
+(gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
+ " " gnus-summary-next-page
+ "n" gnus-summary-next-page
+ "\177" gnus-summary-prev-page
+ [delete] gnus-summary-prev-page
+ "p" gnus-summary-prev-page
+ "\r" gnus-summary-scroll-up
+ "\M-\r" gnus-summary-scroll-down
+ "<" gnus-summary-beginning-of-article
+ ">" gnus-summary-end-of-article
+ "b" gnus-summary-beginning-of-article
+ "e" gnus-summary-end-of-article
+ "^" gnus-summary-refer-parent-article
+ "r" gnus-summary-refer-parent-article
+ "D" gnus-summary-enter-digest-group
+ "R" gnus-summary-refer-references
+ "T" gnus-summary-refer-thread
+ "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)
+ "b" gnus-article-add-buttons
+ "B" gnus-article-add-buttons-to-head
+ "o" gnus-article-treat-overstrike
+ "e" gnus-article-emphasize
+ "w" gnus-article-fill-cited-article
+ "Q" gnus-article-fill-long-lines
+ "C" gnus-article-capitalize-sentences
+ "c" gnus-article-remove-cr
+ "q" gnus-article-de-quoted-unreadable
+ "6" gnus-article-de-base64-unreadable
+ "Z" gnus-article-decode-HZ
+ "h" gnus-article-wash-html
+ "u" gnus-article-unsplit-urls
+ "s" gnus-summary-force-verify-and-decrypt
+ "f" gnus-article-display-x-face
+ "l" gnus-summary-stop-page-breaking
+ "r" gnus-summary-caesar-message
+ "m" gnus-summary-morse-message
+ "t" gnus-summary-toggle-header
+ "g" gnus-treat-smiley
+ "v" gnus-summary-verbose-headers
+ "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
+ "p" gnus-article-verify-x-pgp-sig
+ "d" gnus-article-treat-dumbquotes)
+
+(gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
+ ;; mnemonic: deuglif*Y*
+ "u" gnus-article-outlook-unwrap-lines
+ "a" gnus-article-outlook-repair-attribution
+ "c" gnus-article-outlook-rearrange-citation
+ "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
+
+(gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
+ "a" gnus-article-hide
+ "h" gnus-article-hide-headers
+ "b" gnus-article-hide-boring-headers
+ "s" gnus-article-hide-signature
+ "c" gnus-article-hide-citation
+ "C" gnus-article-hide-citation-in-followups
+ "l" gnus-article-hide-list-identifiers
+ "p" gnus-article-hide-pgp
+ "B" gnus-article-strip-banner
+ "P" gnus-article-hide-pem
+ "\C-c" gnus-article-hide-citation-maybe)
+
+(gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
+ "a" gnus-article-highlight
+ "h" gnus-article-highlight-headers
+ "c" gnus-article-highlight-citation
+ "s" gnus-article-highlight-signature)
+
+(gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
+ "f" gnus-article-treat-fold-headers
+ "u" gnus-article-treat-unfold-headers
+ "n" gnus-article-treat-fold-newsgroups)
+
+(gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
+ "x" gnus-article-display-x-face
+ "d" gnus-article-display-face
+ "s" gnus-treat-smiley
+ "D" gnus-article-remove-images
+ "f" gnus-treat-from-picon
+ "m" gnus-treat-mail-picon
+ "n" gnus-treat-newsgroups-picon)
+
+(gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
+ "w" gnus-article-decode-mime-words
+ "c" gnus-article-decode-charset
+ "v" gnus-mime-view-all-parts
+ "b" gnus-article-view-part)
+
+(gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
+ "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
+ "s" gnus-article-date-user)
+
+(gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
+ "t" gnus-article-remove-trailing-blank-lines
+ "l" gnus-article-strip-leading-blank-lines
+ "m" gnus-article-strip-multiple-blank-lines
+ "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
+ "w" gnus-article-remove-leading-whitespace)
+
+(gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
+ "v" gnus-version
+ "f" gnus-summary-fetch-faq
+ "d" gnus-summary-describe-group
+ "h" gnus-summary-describe-briefly
+ "i" gnus-info-find-node
+ "c" gnus-group-fetch-charter
+ "C" gnus-group-fetch-control)
+
+(gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
+ "e" gnus-summary-expire-articles
+ "\M-\C-e" gnus-summary-expire-articles-now
+ "\177" gnus-summary-delete-article
+ [delete] gnus-summary-delete-article
+ [backspace] gnus-summary-delete-article
+ "m" gnus-summary-move-article
+ "r" gnus-summary-respool-article
+ "w" gnus-summary-edit-article
+ "c" gnus-summary-copy-article
+ "B" gnus-summary-crosspost-article
+ "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)
+ "o" gnus-summary-save-article
+ "m" gnus-summary-save-article-mail
+ "F" gnus-summary-write-article-file
+ "r" gnus-summary-save-article-rmail
+ "f" gnus-summary-save-article-file
+ "b" gnus-summary-save-article-body-file
+ "h" gnus-summary-save-article-folder
+ "v" gnus-summary-save-article-vm
+ "p" gnus-summary-pipe-output
+ "P" gnus-summary-muttprint
+ "s" gnus-soup-add-article)
+
+(gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
+ "b" gnus-summary-display-buttonized
+ "m" gnus-summary-repair-multipart
+ "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-view-part-externally
+ "E" gnus-article-encrypt-body
+ "i" gnus-article-inline-part
+ "|" gnus-article-pipe-part)
+
+(gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
+ "p" gnus-summary-mark-as-processable
+ "u" gnus-summary-unmark-as-processable
+ "U" gnus-summary-unmark-all-processable
+ "v" gnus-uu-mark-over
+ "s" gnus-uu-mark-series
+ "r" gnus-uu-mark-region
+ "g" gnus-uu-unmark-region
+ "R" gnus-uu-mark-by-regexp
+ "G" gnus-uu-unmark-by-regexp
+ "t" gnus-uu-mark-thread
+ "T" gnus-uu-unmark-thread
+ "a" gnus-uu-mark-all
+ "b" gnus-uu-mark-buffer
+ "S" gnus-uu-mark-sparse
+ "k" gnus-summary-kill-process-mark
+ "y" gnus-summary-yank-process-mark
+ "w" gnus-summary-save-process-mark
+ "i" gnus-uu-invert-processable)
+
+(gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
+ ;;"x" gnus-uu-extract-any
+ "m" gnus-summary-save-parts
+ "u" gnus-uu-decode-uu
+ "U" gnus-uu-decode-uu-and-save
+ "s" gnus-uu-decode-unshar
+ "S" gnus-uu-decode-unshar-and-save
+ "o" gnus-uu-decode-save
+ "O" gnus-uu-decode-save
+ "b" gnus-uu-decode-binhex
+ "B" gnus-uu-decode-binhex
+ "p" gnus-uu-decode-postscript
+ "P" gnus-uu-decode-postscript-and-save)
+
+(gnus-define-keys
+ (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
+ "u" gnus-uu-decode-uu-view
+ "U" gnus-uu-decode-uu-and-save-view
+ "s" gnus-uu-decode-unshar-view
+ "S" gnus-uu-decode-unshar-and-save-view
+ "o" gnus-uu-decode-save-view
+ "O" gnus-uu-decode-save-view
+ "b" gnus-uu-decode-binhex-view
+ "B" gnus-uu-decode-binhex-view
+ "p" gnus-uu-decode-postscript-view
+ "P" gnus-uu-decode-postscript-and-save-view)
(defvar gnus-article-post-menu nil)
["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
["HZ" gnus-article-decode-HZ t]
("(Outlook) Deuglify"
- ["Unwrap lines" gnus-outlook-unwrap-lines t]
- ["Repair attribution" gnus-outlook-repair-attribution t]
- ["Rearrange citation" gnus-outlook-rearrange-citation t]
+ ["Unwrap lines" gnus-article-outlook-unwrap-lines t]
+ ["Repair attribution" gnus-article-outlook-repair-attribution t]
+ ["Rearrange citation" gnus-article-outlook-rearrange-citation t]
["Full (Outlook) deuglify"
gnus-article-outlook-deuglify-article t])
)
["Catchup all" gnus-summary-catchup-all t]
["Catchup to here" gnus-summary-catchup-to-here t]
["Catchup from here" gnus-summary-catchup-from-here t]
- ["Catchup region" gnus-summary-mark-region-as-read t]
+ ["Catchup region" gnus-summary-mark-region-as-read
+ (gnus-mark-active-p)]
["Mark excluded" gnus-summary-limit-mark-excluded-as-read t])
("Mark Various"
["Tick" gnus-summary-tick-article-forward t]
["Remove all marks" gnus-summary-unmark-all-processable t]
["Mark above" gnus-uu-mark-over t]
["Mark series" gnus-uu-mark-series t]
- ["Mark region" gnus-uu-mark-region t]
- ["Unmark region" gnus-uu-unmark-region t]
+ ["Mark region" gnus-uu-mark-region (gnus-mark-active-p)]
+ ["Unmark region" gnus-uu-unmark-region (gnus-mark-active-p)]
["Mark by regexp..." gnus-uu-mark-by-regexp t]
["Unmark by regexp..." gnus-uu-unmark-by-regexp t]
["Mark all" gnus-uu-mark-all t]
(gnus-summary-goto-subject article)
(let* ((datal (gnus-data-find-list article))
(data (car datal))
- (length (when (cdr datal)
- (- (gnus-data-pos data)
- (gnus-data-pos (cadr datal)))))
(buffer-read-only nil)
(level (gnus-summary-thread-level)))
(gnus-delete-line)
- (gnus-summary-insert-line
- header level nil
- (memq article gnus-newsgroup-undownloaded)
- (gnus-article-mark article)
- (memq article gnus-newsgroup-replied)
- (memq article gnus-newsgroup-expirable)
- ;; Only insert the Subject string when it's different
- ;; from the previous Subject string.
- (if (and
- gnus-show-threads
- (gnus-subject-equal
- (condition-case ()
- (mail-header-subject
- (gnus-data-header
- (cadr
- (gnus-data-find-list
- article
- (gnus-data-list t)))))
- ;; Error on the side of excessive subjects.
- (error ""))
- (mail-header-subject header)))
- ""
- (mail-header-subject header))
- nil (cdr (assq article gnus-newsgroup-scored))
- (memq article gnus-newsgroup-processable))
- (when length
- (gnus-data-update-list
- (cdr datal) (- length (- (gnus-data-pos data) (point))))))))
+ (let ((inserted (- (point)
+ (progn
+ (gnus-summary-insert-line
+ header level nil
+ (memq article gnus-newsgroup-undownloaded)
+ (gnus-article-mark article)
+ (memq article gnus-newsgroup-replied)
+ (memq article gnus-newsgroup-expirable)
+ ;; Only insert the Subject string when it's different
+ ;; from the previous Subject string.
+ (if (and
+ gnus-show-threads
+ (gnus-subject-equal
+ (condition-case ()
+ (mail-header-subject
+ (gnus-data-header
+ (cadr
+ (gnus-data-find-list
+ article
+ (gnus-data-list t)))))
+ ;; Error on the side of excessive subjects.
+ (error ""))
+ (mail-header-subject header)))
+ ""
+ (mail-header-subject header))
+ nil (cdr (assq article gnus-newsgroup-scored))
+ (memq article gnus-newsgroup-processable))
+ (point)))))
+ (when (cdr datal)
+ (gnus-data-update-list
+ (cdr datal)
+ (- (gnus-data-pos data) (gnus-data-pos (cadr datal)) inserted)))))))
(defun gnus-summary-update-article (article &optional iheader)
"Update ARTICLE in the summary buffer."
(setq gnus-newsgroup-unselected
(gnus-sorted-difference gnus-newsgroup-unreads articles))
(when gnus-alter-articles-to-read-function
- (setq gnus-newsgroup-unreads
+ (setq articles
(sort
(funcall gnus-alter-articles-to-read-function
- gnus-newsgroup-name gnus-newsgroup-unreads)
+ gnus-newsgroup-name articles)
'<)))
articles)))
(progn
(while arts
(when (or (and undownloaded
- (memq (car arts) gnus-newsgroup-undownloaded))
+ (memq (car arts)
+ gnus-newsgroup-undownloaded))
(gnus-data-unread-p (car arts)))
(setq result (car arts)
arts nil))
(gnus-summary-goto-subject article t)))
(gnus-summary-limit (append articles gnus-newsgroup-limit))
(gnus-summary-position-point))
-
+
(defun gnus-summary-goto-subject (article &optional force silent)
"Go the subject line of ARTICLE.
If FORCE, also allow jumping to articles not currently shown."
(setq gnus-newsgroup-marked nil
gnus-newsgroup-spam-marked nil
gnus-newsgroup-dormant nil))
- (setq gnus-newsgroup-unreads gnus-newsgroup-downloadable))
+ (setq gnus-newsgroup-unreads
+ (gnus-intersection gnus-newsgroup-unreads
+ gnus-newsgroup-downloadable)))
;; We actually mark all articles as canceled, which we
;; have to do when using auto-expiry or adaptive scoring.
(gnus-summary-show-all-threads)
(post 1.0 point)))
(reply
(vertical 1.0
- (article-copy 0.5)
+ (article 0.5)
(message 1.0 point)))
(forward
(vertical 1.0
;;; gnus-xmas.el --- Gnus functions for XEmacs
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
'gnus-xmas-mode-line-buffer-identification)
(defalias 'gnus-key-press-event-p 'key-press-event-p)
(defalias 'gnus-region-active-p 'region-active-p)
+ (defalias 'gnus-mark-active-p 'region-exists-p)
(defalias 'gnus-annotation-in-region-p 'gnus-xmas-annotation-in-region-p)
(defalias 'gnus-mime-button-menu 'gnus-xmas-mime-button-menu)
(defalias 'gnus-image-type-available-p 'gnus-xmas-image-type-available-p)
;;; gnus.el --- a newsreader for GNU Emacs
;; Copyright (C) 1987, 1988, 1989, 1990, 1993, 1994, 1995, 1996, 1997,
-;; 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Lars Magne Ingebrigtsen <larsi@gnus.org>
(defgroup gnus-format nil
"Dealing with formatting issues."
- :group 'news
- :group 'mail)
+ :group 'gnus)
(defgroup gnus-charset nil
"Group character set issues."
(defgroup gnus-cache nil
"Cache interface."
+ :link '(custom-manual "(gnus)Article Caching")
:group 'gnus)
(defgroup gnus-start nil
:link '(custom-manual "(gnus)Exiting Gnus")
:group 'gnus)
-(defconst gnus-version-number "0.12"
+(defconst gnus-version-number "0.13"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Oort Gnus v%s" gnus-version-number)
(defcustom gnus-home-directory "~/"
"Directory variable that specifies the \"home\" directory.
-All other Gnus path variables are initialized from this variable."
+All other Gnus file and directory variables are initialized from this variable."
:group 'gnus-files
:type 'directory)
("netins" . (concat "http://www.netins.net/usenet/charter/"
(gnus-replace-in-string name "\\." "-") "-charter.html")))
"*An alist of (HIERARCHY . FORM) pairs used to construct the URL of a charter.
- When FORM is evaluated `name' is bound to the name of the group."
+When FORM is evaluated `name' is bound to the name of the group."
:group 'gnus-group-various
:type '(repeat (cons (string :tag "Hierarchy") (sexp :tag "Form"))))
total number of articles in the group.")
;; group parameters for spam processing added by Ted Zlatanov <tzz@lifelogs.com>
-(defvar gnus-group-spam-classification-spam t
- "Spam group classification (requires spam.el).
+(defcustom gnus-install-group-spam-parameters t
+ "*Disable the group parameters for spam detection.
+Enable if `G c' in XEmacs is giving you trouble, and make sure to submit a bug report."
+ :type 'boolean
+ :group 'gnus-start)
+
+(when gnus-install-group-spam-parameters
+ (defvar gnus-group-spam-classification-spam t
+ "Spam group classification (requires spam.el).
This group contains spam messages. On summary entry, unread messages
will be marked as spam. On summary exit, the specified spam
processors will be invoked on spam-marked messages, then those
messages will be expired, so the spam processor will only see a
spam-marked message once.")
-(defvar gnus-group-spam-classification-ham 'ask
- "The ham value for the spam group parameter (requires spam.el).
+ (defvar gnus-group-spam-classification-ham 'ask
+ "The ham value for the spam group parameter (requires spam.el).
On summary exit, the specified ham processors will be invoked on
ham-marked messages. Exercise caution, since the ham processor will
see the same message more than once because there is no ham message
registry.")
-(gnus-define-group-parameter
- spam-contents
- :type list
- :function-document
- "The spam type (spam, ham, or neither) of the group."
- :variable gnus-spam-newsgroup-contents
- :variable-default nil
- :variable-document
- "*Groups in which to automatically mark new articles as spam on
+ (gnus-define-group-parameter
+ spam-contents
+ :type list
+ :function-document
+ "The spam type (spam, ham, or neither) of the group."
+ :variable gnus-spam-newsgroup-contents
+ :variable-default nil
+ :variable-document
+ "*Groups in which to automatically mark new articles as spam on
summary entry. If non-nil, this should be a list of group name
regexps that should match all groups in which to do automatic spam
tagging, associated with a classification (spam, ham, or neither).
This only makes sense for mail groups."
- :variable-group spam
- :variable-type '(repeat
- (list :tag "Group contents spam/ham classification"
+ :variable-group spam
+ :variable-type '(repeat
+ (list :tag "Group contents spam/ham classification"
(regexp :tag "Group")
(choice
(variable-item gnus-group-spam-classification-spam)
(variable-item gnus-group-spam-classification-ham)
(other :tag "Unclassified" nil))))
- :parameter-type '(list :tag "Group contents spam/ham classification"
- (choice :tag "Group contents classification for spam sorting"
- (variable-item gnus-group-spam-classification-spam)
- (variable-item gnus-group-spam-classification-ham)
- (other :tag "Unclassified" nil)))
- :parameter-document
- "The spam classification (spam, ham, or neither) of this group.
+ :parameter-type '(list :tag "Group contents spam/ham classification"
+ (choice :tag "Group contents classification for spam sorting"
+ (variable-item gnus-group-spam-classification-spam)
+ (variable-item gnus-group-spam-classification-ham)
+ (other :tag "Unclassified" nil)))
+ :parameter-document
+ "The spam classification (spam, ham, or neither) of this group.
When a spam group is entered, all unread articles are marked as spam.")
-(defvar gnus-group-spam-exit-processor-ifile "ifile"
- "The ifile summary exit spam processor.
+ (defvar gnus-group-spam-exit-processor-ifile "ifile"
+ "The ifile summary exit spam processor.
Only applicable to spam groups.")
-(defvar gnus-group-spam-exit-processor-stat "stat"
- "The spam-stat summary exit spam processor.
+ (defvar gnus-group-spam-exit-processor-stat "stat"
+ "The spam-stat summary exit spam processor.
Only applicable to spam groups.")
-(defvar gnus-group-spam-exit-processor-bogofilter "bogofilter"
- "The Bogofilter summary exit spam processor.
+ (defvar gnus-group-spam-exit-processor-bogofilter "bogofilter"
+ "The Bogofilter summary exit spam processor.
Only applicable to spam groups.")
-(defvar gnus-group-spam-exit-processor-blacklist "blacklist"
- "The Blacklist summary exit spam processor.
+ (defvar gnus-group-spam-exit-processor-blacklist "blacklist"
+ "The Blacklist summary exit spam processor.
Only applicable to spam groups.")
-(defvar gnus-group-ham-exit-processor-ifile "ifile-ham"
- "The ifile summary exit ham processor.
+ (defvar gnus-group-ham-exit-processor-ifile "ifile-ham"
+ "The ifile summary exit ham processor.
Only applicable to non-spam (unclassified and ham) groups.")
-(defvar gnus-group-ham-exit-processor-stat "stat-ham"
- "The spam-stat summary exit ham processor.
+ (defvar gnus-group-ham-exit-processor-bogofilter "bogofilter-ham"
+ "The Bogofilter summary exit ham processor.
Only applicable to non-spam (unclassified and ham) groups.")
-(defvar gnus-group-ham-exit-processor-whitelist "whitelist"
- "The whitelist summary exit ham processor.
+ (defvar gnus-group-ham-exit-processor-stat "stat-ham"
+ "The spam-stat summary exit ham processor.
Only applicable to non-spam (unclassified and ham) groups.")
-(defvar gnus-group-ham-exit-processor-BBDB "bbdb"
- "The BBDB summary exit ham processor.
+ (defvar gnus-group-ham-exit-processor-whitelist "whitelist"
+ "The whitelist summary exit ham processor.
Only applicable to non-spam (unclassified and ham) groups.")
-(gnus-define-group-parameter
- spam-process
- :type list
- :parameter-type '(choice :tag "Spam Summary Exit Processor"
- :value nil
- (list :tag "Spam Summary Exit Processor Choices"
- (set
- (variable-item gnus-group-spam-exit-processor-ifile)
- (variable-item gnus-group-spam-exit-processor-stat)
- (variable-item gnus-group-spam-exit-processor-bogofilter)
- (variable-item gnus-group-spam-exit-processor-blacklist)
- (variable-item gnus-group-ham-exit-processor-ifile)
- (variable-item gnus-group-ham-exit-processor-stat)
- (variable-item gnus-group-ham-exit-processor-whitelist)
- (variable-item gnus-group-ham-exit-processor-BBDB))))
- :function-document
- "Which spam or ham processors will be applied to the GROUP articles at summary exit."
- :variable gnus-spam-process-newsgroups
- :variable-default nil
- :variable-document
- "*Groups in which to automatically process spam or ham articles with
+ (defvar gnus-group-ham-exit-processor-BBDB "bbdb"
+ "The BBDB summary exit ham processor.
+Only applicable to non-spam (unclassified and ham) groups.")
+
+ (gnus-define-group-parameter
+ spam-process
+ :type list
+ :parameter-type '(choice :tag "Spam Summary Exit Processor"
+ :value nil
+ (list :tag "Spam Summary Exit Processor Choices"
+ (set
+ (variable-item gnus-group-spam-exit-processor-ifile)
+ (variable-item gnus-group-spam-exit-processor-stat)
+ (variable-item gnus-group-spam-exit-processor-bogofilter)
+ (variable-item gnus-group-spam-exit-processor-blacklist)
+ (variable-item gnus-group-ham-exit-processor-bogofilter)
+ (variable-item gnus-group-ham-exit-processor-ifile)
+ (variable-item gnus-group-ham-exit-processor-stat)
+ (variable-item gnus-group-ham-exit-processor-whitelist)
+ (variable-item gnus-group-ham-exit-processor-BBDB))))
+ :function-document
+ "Which spam or ham processors will be applied to the GROUP articles at summary exit."
+ :variable gnus-spam-process-newsgroups
+ :variable-default nil
+ :variable-document
+ "*Groups in which to automatically process spam or ham articles with
a backend on summary exit. If non-nil, this should be a list of group
name regexps that should match all groups in which to do automatic
spam processing, associated with the appropriate processor. This only makes sense
for mail groups."
- :variable-group spam
- :variable-type '(repeat :tag "Spam/Ham Processors"
- (list :tag "Spam Summary Exit Processor Choices"
- (regexp :tag "Group Regexp")
- (set :tag "Spam/Ham Summary Exit Processor"
- (variable-item gnus-group-spam-exit-processor-ifile)
- (variable-item gnus-group-spam-exit-processor-stat)
- (variable-item gnus-group-spam-exit-processor-bogofilter)
- (variable-item gnus-group-spam-exit-processor-blacklist)
- (variable-item gnus-group-ham-exit-processor-ifile)
- (variable-item gnus-group-ham-exit-processor-stat)
- (variable-item gnus-group-ham-exit-processor-whitelist)
- (variable-item gnus-group-ham-exit-processor-BBDB))))
- :parameter-document
- "Which spam processors will be applied to the spam or ham GROUP articles at summary exit.")
-
-(gnus-define-group-parameter
- spam-process-destination
- :parameter-type '(choice :tag "Destination for spam-processed articles at summary exit"
- (string :tag "Move to a group")
- (other :tag "Expire" nil))
- :function-document
- "Where spam-processed articles will go at summary exit."
- :variable gnus-spam-process-destinations
- :variable-default nil
- :variable-document
- "*Groups in which to explicitly send spam-processed articles to
+ :variable-group spam
+ :variable-type '(repeat :tag "Spam/Ham Processors"
+ (list :tag "Spam Summary Exit Processor Choices"
+ (regexp :tag "Group Regexp")
+ (set :tag "Spam/Ham Summary Exit Processor"
+ (variable-item gnus-group-spam-exit-processor-ifile)
+ (variable-item gnus-group-spam-exit-processor-stat)
+ (variable-item gnus-group-spam-exit-processor-bogofilter)
+ (variable-item gnus-group-spam-exit-processor-blacklist)
+ (variable-item gnus-group-ham-exit-processor-bogofilter)
+ (variable-item gnus-group-ham-exit-processor-ifile)
+ (variable-item gnus-group-ham-exit-processor-stat)
+ (variable-item gnus-group-ham-exit-processor-whitelist)
+ (variable-item gnus-group-ham-exit-processor-BBDB))))
+ :parameter-document
+ "Which spam processors will be applied to the spam or ham GROUP articles at summary exit.")
+
+ (gnus-define-group-parameter
+ spam-process-destination
+ :parameter-type '(choice :tag "Destination for spam-processed articles at summary exit"
+ (string :tag "Move to a group")
+ (other :tag "Expire" nil))
+ :function-document
+ "Where spam-processed articles will go at summary exit."
+ :variable gnus-spam-process-destinations
+ :variable-default nil
+ :variable-document
+ "*Groups in which to explicitly send spam-processed articles to
another group, or expire them (the default). If non-nil, this should
be a list of group name regexps that should match all groups in which
to do spam-processed article moving, associated with the destination
group or `nil' for explicit expiration. This only makes sense for
mail groups."
- :variable-group spam
- :variable-type '(repeat
- :tag "Spam-processed articles destination"
- (list
- (regexp :tag "Group Regexp")
- (choice
- :tag "Destination for spam-processed articles at summary exit"
- (string :tag "Move to a group")
- (other :tag "Expire" nil))))
- :parameter-document
- "Where spam-processed articles will go at summary exit.")
-
-(gnus-define-group-parameter
- ham-process-destination
- :parameter-type '(choice
- :tag "Destination for ham articles at summary exit from a spam group"
- (string :tag "Move to a group")
- (other :tag "Do nothing" nil))
- :function-document
- "Where ham articles will go at summary exit from a spam group."
- :variable gnus-ham-process-destinations
- :variable-default nil
- :variable-document
- "*Groups in which to explicitly send ham articles to
+ :variable-group spam
+ :variable-type '(repeat
+ :tag "Spam-processed articles destination"
+ (list
+ (regexp :tag "Group Regexp")
+ (choice
+ :tag "Destination for spam-processed articles at summary exit"
+ (string :tag "Move to a group")
+ (other :tag "Expire" nil))))
+ :parameter-document
+ "Where spam-processed articles will go at summary exit.")
+
+ (gnus-define-group-parameter
+ ham-process-destination
+ :parameter-type '(choice
+ :tag "Destination for ham articles at summary exit from a spam group"
+ (string :tag "Move to a group")
+ (other :tag "Do nothing" nil))
+ :function-document
+ "Where ham articles will go at summary exit from a spam group."
+ :variable gnus-ham-process-destinations
+ :variable-default nil
+ :variable-document
+ "*Groups in which to explicitly send ham articles to
another group, or do nothing (the default). If non-nil, this should
be a list of group name regexps that should match all groups in which
to do ham article moving, associated with the destination
group or `nil' for explicit ignoring. This only makes sense for
mail groups, and only works in spam groups."
- :variable-group spam
- :variable-type '(repeat
- :tag "Ham articles destination"
- (list
- (regexp :tag "Group Regexp")
- (choice
- :tag "Destination for ham articles at summary exit from spam group"
- (string :tag "Move to a group")
- (other :tag "Expire" nil))))
- :parameter-document
- "Where ham articles will go at summary exit from a spam group.")
+ :variable-group spam
+ :variable-type '(repeat
+ :tag "Ham articles destination"
+ (list
+ (regexp :tag "Group Regexp")
+ (choice
+ :tag "Destination for ham articles at summary exit from spam group"
+ (string :tag "Move to a group")
+ (other :tag "Expire" nil))))
+ :parameter-document
+ "Where ham articles will go at summary exit from a spam group."))
(defcustom gnus-group-uncollapsed-levels 1
"Number of group name elements to leave alone when making a short group name."
%V Total thread score (number).
%P The line number (number).
%O Download mark (character).
-%C If present, indicates desired cursor position
+%* If present, indicates desired cursor position
(instead of after first colon).
%u User defined specifier. The next character in the format string should
be a letter. Gnus will call the function gnus-user-format-function-X,
;;; mailcap.el --- MIME media types configuration
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+;; Free Software Foundation, Inc.
;; Author: William M. Perry <wmperry@aventail.com>
;; Lars Magne Ingebrigtsen <larsi@gnus.org>
table)
"A syntax table for parsing sgml attributes.")
+(defvar mailcap-print-command
+ (mapconcat 'identity
+ (cons (if (boundp 'lpr-command)
+ lpr-command
+ "lpr")
+ (when (boundp 'lpr-switches)
+ (if (stringp lpr-switches)
+ (list lpr-switches)
+ lpr-switches)))
+ " ")
+ "Shell command (including switches) used to print Postscript files.")
+
;; Postpone using defcustom for this as it's so big and we essentially
;; have to have two copies of the data around then. Perhaps just
;; customize the Lisp viewers and rely on the normal configuration
;; files for the rest? -- fx
(defvar mailcap-mime-data
- '(("application"
+ `(("application"
("vnd.ms-excel"
(viewer . "gnumeric %s")
(test . (getenv "DISPLAY"))
(viewer . mailcap-save-binary-file)
(non-viewer . t)
(type . "application/octet-stream"))
-;;; XEmacs says `ns' device-type not implemented.
-;; ("dvi"
-;; (viewer . "open %s")
-;; (type . "application/dvi")
-;; (test . (eq (mm-device-type) 'ns)))
("dvi"
(viewer . "xdvi -safer %s")
(test . (eq window-system 'x))
("needsx11")
- (type . "application/dvi"))
+ (type . "application/dvi")
+ ("print" . "dvips -qRP %s"))
("dvi"
(viewer . "dvitty %s")
(test . (not (getenv "DISPLAY")))
- (type . "application/dvi"))
+ (type . "application/dvi")
+ ("print" . "dvips -qRP %s"))
("emacs-lisp"
(viewer . mailcap-maybe-eval)
(type . "application/emacs-lisp"))
("pdf"
(viewer . "gv -safer %s")
(type . "application/pdf")
- (test . window-system))
+ (test . window-system)
+ ("print" . ,(concat "pdf2ps %s - | " mailcap-print-command)))
("pdf"
(viewer . "xpdf %s")
(type . "application/pdf")
+ ("print" . ,(concat "pdftops %s - | " mailcap-print-command))
(test . (eq window-system 'x)))
("pdf"
(viewer . "acroread %s")
- (type . "application/pdf"))
-;;; XEmacs says `ns' device-type not implemented.
-;; ("postscript"
-;; (viewer . "open %s")
-;; (type . "application/postscript")
-;; (test . (eq (mm-device-type) 'ns)))
+ (type . "application/pdf")
+ ("print" . ,(concat "cat %s | acroread -toPostScript | "
+ mailcap-print-command))
+ (test . window-system))
+ ("pdf"
+ (viewer . ,(concat "pdftotext %s - | "))
+ (type . "application/pdf")
+ ("print" . ,(concat "pdftops %s - | " mailcap-print-command))
+ ("copiousoutput"))
("postscript"
(viewer . "gv -safer %s")
(type . "application/postscript")
(test . window-system)
+ ("print" . ,(concat mailcap-print-command " %s"))
("needsx11"))
("postscript"
(viewer . "ghostview -dSAFER %s")
(type . "application/postscript")
(test . (eq window-system 'x))
+ ("print" . ,(concat mailcap-print-command " %s"))
("needsx11"))
("postscript"
(viewer . "ps2ascii %s")
(type . "application/postscript")
(test . (not (getenv "DISPLAY")))
+ ("print" . ,(concat mailcap-print-command " %s"))
("copiousoutput"))
("sieve"
(viewer . sieve-mode)
("compose" . "xwd -frame > %s")
(test . (eq window-system 'x))
("needsx11"))
-;;; XEmacs says `ns' device-type not implemented.
-;; (".*"
-;; (viewer . "aopen %s")
-;; (type . "image/*")
-;; (test . (eq (mm-device-type) 'ns)))
(".*"
(viewer . "display %s")
(type . "image/*")
The cdr of each entry is a function for applying the face to a region.")
(defcustom message-send-hook nil
- "Hook run before sending messages."
+ "Hook run before sending messages.
+This hook is run quite early when sending."
:group 'message-various
:options '(ispell-message)
:type 'hook)
(defcustom message-send-mail-hook nil
- "Hook run before sending mail messages."
+ "Hook run before sending mail messages.
+This hook is run very late -- just before the message is sent as
+mail."
:group 'message-various
:type 'hook)
(defcustom message-send-news-hook nil
- "Hook run before sending news messages."
+ "Hook run before sending news messages.
+This hook is run very late -- just before the message is sent as
+news."
:group 'message-various
:type 'hook)
`(delete-region (progn (beginning-of-line) (point))
(progn (forward-line ,(or n 1)) (point))))
+(defun message-mark-active-p ()
+ "Non-nil means the mark and region are currently active in this buffer."
+ mark-active)
+
(defun message-unquote-tokens (elems)
"Remove double quotes (\") from strings in list ELEMS."
(mapcar (lambda (item)
(easy-menu-define
message-mode-menu message-mode-map "Message Menu."
`("Message"
- ["Yank Original" message-yank-original t]
+ ["Yank Original" message-yank-original message-reply-buffer]
["Fill Yanked Message" message-fill-yanked-message t]
["Insert Signature" message-insert-signature t]
["Caesar (rot13) Message" message-caesar-buffer-body t]
- ["Caesar (rot13) Region" message-caesar-region (mark t)]
- ["Elide Region" message-elide-region (mark t)]
- ["Delete Outside Region" message-delete-not-region (mark t)]
+ ["Caesar (rot13) Region" message-caesar-region (message-mark-active-p)]
+ ["Elide Region" message-elide-region
+ :active (message-mark-active-p)
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Replace text in region with an ellipsis"))]
+ ["Delete Outside Region" message-delete-not-region
+ :active (message-mark-active-p)
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Delete all quoted text outside region"))]
["Kill To Signature" message-kill-to-signature t]
["Newline and Reformat" message-newline-and-reformat t]
["Rename buffer" message-rename-buffer t]
'(:help "Spellcheck this message"))]
"----"
["Insert Region Marked" message-mark-inserted-region
- ,@(if (featurep 'xemacs) '(t)
+ :active (message-mark-active-p)
+ ,@(if (featurep 'xemacs) nil
'(:help "Mark region with enclosing tags"))]
["Insert File Marked..." message-mark-insert-file
,@(if (featurep 'xemacs) '(t)
(when (funcall (cadr elem))
(when (and (or (not (memq (car elem)
message-sent-message-via))
+ (not (message-fetch-field "supersedes"))
(if (or (message-gnksa-enable-p 'multiple-copies)
(not (eq (car elem) 'news)))
(y-or-n-p
;;; messagexmas.el --- XEmacs extensions to message
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2003
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
"Redefine message functions for XEmacs."
(defalias 'message-exchange-point-and-mark
'message-xmas-exchange-point-and-mark)
-
+ (defalias 'message-mark-active-p
+ 'region-exists-p)
(when (>= emacs-major-version 20)
(defalias 'message-make-caesar-translation-table
'message-xmas-make-caesar-translation-table)))
(nnheader-message 5 "")))
(defun nnfolder-group-pathname (group)
- "Make pathname for GROUP."
+ "Make file name for GROUP."
(setq group
(mm-encode-coding-string group nnmail-pathname-coding-system))
(let ((dir (file-name-as-directory (expand-file-name nnfolder-directory))))
"Regexp that matches numerical file names.")
(defvar nnheader-numerical-full-files (concat "/" nnheader-numerical-files)
- "Regexp that matches numerical full file paths.")
+ "Regexp that matches numerical full file names.")
(defsubst nnheader-file-to-number (file)
"Take a FILE name and return the article number."
(<= level gnus-verbose-backends)))
(defvar nnheader-pathname-coding-system 'iso-8859-1
- "*Coding system for pathname.")
+ "*Coding system for file name.")
(defun nnheader-group-pathname (group dir &optional file)
- "Make pathname for GROUP."
+ "Make file name for GROUP."
(concat
(let ((dir (file-name-as-directory (expand-file-name dir))))
;; If this directory exists, we use it directly.
:group 'nnimap
:type 'sexp)
+(defcustom nnimap-split-download-body nil
+ "Whether to download entire articles during splitting.
+This is generally not required, and will slow things down considerably.
+You may need it if you want to use an advanced splitting function that
+analyses the body before splitting the article."
+ :group 'nnimap
+ :type 'boolean)
+
;; Performance / bug workaround variables
(defcustom nnimap-close-asynchronous t
articles))))
(defun nnimap-group-overview-filename (group server)
- "Make pathname for GROUP on SERVER."
+ "Make file name for GROUP on SERVER."
(let* ((dir (file-name-as-directory (expand-file-name nnimap-directory)))
(uidvalidity (gnus-group-get-parameter
(gnus-group-prefixed-name
(when (setq rule (nnimap-split-find-rule server inbox))
;; iterate over articles
(dolist (article (imap-search nnimap-split-predicate))
- (when (nnimap-request-head article)
+ (when (if nnimap-split-download-body
+ (and (nnimap-request-article article)
+ (mail-narrow-to-head))
+ (nnimap-request-head article))
;; copy article to right group(s)
(setq removeorig nil)
(dolist (to-group (nnimap-split-to-groups rule))
(t
(message "IMAP split failed to move %s:%s:%d to %s"
server inbox article to-group))))
+ (if nnimap-split-download-body
+ (widen))
;; remove article if it was successfully copied somewhere
(and removeorig
(imap-message-flags-add (format "%d" article)
"Coding system used in reading inbox")
(defvar nnmail-pathname-coding-system nil
- "*Coding system for pathname.")
+ "*Coding system for file name.")
(defun nnmail-find-file (file)
"Insert FILE in server buffer safely."
(file-error nil))))
(defun nnmail-group-pathname (group dir &optional file)
- "Make pathname for GROUP."
+ "Make file name for GROUP."
(concat
(let ((dir (file-name-as-directory (expand-file-name dir))))
(setq group (nnheader-replace-duplicate-chars-in-string
(if (not (and (re-search-forward "^From " nil t)
(goto-char (match-beginning 0))))
;; Possibly wrong format?
- (error "Error, unknown mail format! (Possibly corrupted.)")
+ (error "Error, unknown mail format! (Possibly corrupted %s `%s'.)"
+ (if (buffer-file-name) "file" "buffer")
+ (or (buffer-file-name) (buffer-name)))
;; Carry on until the bitter end.
(while (not (eobp))
(setq start (point)
prefix))
(defun nnsoup-file-name (dir file)
- "Return the full path of FILE (in any case) in DIR."
+ "Return the full name of FILE (in any case) in DIR."
(let* ((case-fold-search t)
(files (directory-files dir t))
(regexp (concat (regexp-quote file) "$")))
(nnheader-report 'nnspool "No such newsgroup: %s" group)))))
(defun nnspool-article-pathname (group &optional article)
- "Find the path for GROUP."
+ "Find the file name for GROUP."
(nnheader-group-pathname group nnspool-spool-directory article))
(provide 'nnspool)
:type 'boolean
:group 'spam)
+(defcustom spam-use-bogofilter-headers nil
+ "Whether bogofilter headers should be used by spam-split.
+Enable this if you pre-process messages with Bogofilter BEFORE Gnus sees them."
+ :type 'boolean
+ :group 'spam)
+
(defcustom spam-use-bogofilter nil
- "Whether bogofilter should be used by spam-split."
+ "Whether bogofilter should be invoked by spam-split.
+Enable this if you want Gnus to invoke Bogofilter on new messages."
:type 'boolean
:group 'spam)
"Spam bogofilter configuration."
:group 'spam)
-(defcustom spam-bogofilter-output-buffer-name "*Bogofilter Output*"
- "Name of buffer when displaying `bogofilter -v' output."
- :type 'string
- :group 'spam-bogofilter)
-
-(defcustom spam-bogofilter-initial-timeout 40
- "Timeout in seconds for the initial reply from the `bogofilter' program."
- :type 'integer
- :group 'spam-bogofilter)
-
-(defcustom spam-bogofilter-subsequent-timeout 15
- "Timeout in seconds for any subsequent reply from the `bogofilter' program."
- :type 'integer
- :group 'spam-bogofilter)
-
(defcustom spam-bogofilter-path (executable-find "bogofilter")
"File path of the Bogofilter executable program."
:type '(choice (file :tag "Location of bogofilter")
(const :tag "Bogofilter is not installed"))
:group 'spam-bogofilter)
-;; FIXME! In the following regexp, we should explain which tool produces
-;; which kind of header. I do not even remember them all by now. X-Junk
-;; (and previously X-NoSpam) are produced by the `NoSpam' tool, which has
-;; never been published, so it might not be reasonable leaving it in the
-;; list.
-(defcustom spam-bogofilter-spaminfo-header-regexp
- "^X-\\(jf\\|Junk\\|NoSpam\\|Spam\\|SB\\)[^:]*:"
- "Regexp for spam markups in headers.
-Markup from spam recognisers, as well as `Xref', are to be removed from
-articles before they get registered by Bogofilter."
- :type 'regexp
+(defcustom spam-bogofilter-header "X-Bogosity"
+ "The header that Bogofilter inserts in messages."
+ :type 'string
:group 'spam-bogofilter)
+(defcustom spam-bogofilter-database-directory nil
+ "Directory path of the Bogofilter databases."
+ :type '(choice (directory :tag "Location of the Bogofilter database directory")
+ (const :tag "Use the default"))
+ :group 'spam-ifile)
+
;;; Key bindings for spam control.
(gnus-define-keys gnus-summary-mode-map
(defun spam-group-ham-processor-ifile-p (group)
(spam-group-processor-p group 'gnus-group-ham-exit-processor-ifile))
+(defun spam-group-ham-processor-bogofilter-p (group)
+ (spam-group-processor-p group 'gnus-group-ham-exit-processor-ifile))
+
(defun spam-group-spam-processor-stat-p (group)
(spam-group-processor-p group 'gnus-group-spam-exit-processor-stat))
;; The spam processors are invoked for any group, spam or ham or neither
(when (and spam-bogofilter-path
(spam-group-spam-processor-bogofilter-p gnus-newsgroup-name))
- (spam-bogofilter-register-routine))
+ (spam-bogofilter-register-spam-routine))
(when (and spam-ifile-path
(spam-group-spam-processor-ifile-p gnus-newsgroup-name))
(when (spam-group-spam-processor-stat-p gnus-newsgroup-name)
(spam-stat-register-spam-routine))
- (when (spam-group-spam-processor-bogofilter-p gnus-newsgroup-name)
+ (when (spam-group-spam-processor-blacklist-p gnus-newsgroup-name)
(spam-blacklist-register-routine))
(if spam-move-spam-nonspam-groups-only
(spam-whitelist-register-routine))
(when (spam-group-ham-processor-ifile-p gnus-newsgroup-name)
(spam-ifile-register-ham-routine))
+ (when (spam-group-ham-processor-bogofilter-p gnus-newsgroup-name)
+ (spam-bogofilter-register-ham-routine))
(when (spam-group-ham-processor-stat-p gnus-newsgroup-name)
(spam-stat-register-ham-routine))
(when (spam-group-ham-processor-BBDB-p gnus-newsgroup-name)
'line-end-position)))
(defun spam-get-article-as-string (article)
- (let ((article-string))
+ (let ((article-buffer (spam-get-article-as-buffer article))
+ article-string)
+ (when article-buffer
+ (save-window-excursion
+ (set-buffer article-buffer)
+ (setq article-string (buffer-string))))
+ article-string))
+
+(defun spam-get-article-as-buffer (article)
+ (let ((article-buffer))
(when (numberp article)
(save-window-excursion
(gnus-summary-goto-subject article)
(gnus-summary-show-article t)
- (set-buffer gnus-article-buffer)
- (setq article-string (buffer-string))))
- article-string))
+ (setq article-buffer (get-buffer gnus-article-buffer))))
+ article-buffer))
+
+(defun spam-get-article-as-filename (article)
+ (let ((article-filename))
+ (when (numberp article)
+ (nnml-possibly-change-directory (gnus-group-real-name gnus-newsgroup-name))
+ (setq article-filename (expand-file-name (int-to-string article) nnml-current-directory)))
+ (if (file-exists-p article-filename)
+ article-filename
+ nil)))
(defun spam-fetch-field-from-fast (article)
"Fetch the `from' field quickly, using the internal gnus-data-list function"
;;;; Spam determination.
(defvar spam-list-of-checks
- '((spam-use-blacklist . spam-check-blacklist)
- (spam-use-whitelist . spam-check-whitelist)
- (spam-use-BBDB . spam-check-BBDB)
- (spam-use-ifile . spam-check-ifile)
- (spam-use-stat . spam-check-stat)
- (spam-use-blackholes . spam-check-blackholes)
- (spam-use-bogofilter . spam-check-bogofilter))
+ '((spam-use-blacklist . spam-check-blacklist)
+ (spam-use-whitelist . spam-check-whitelist)
+ (spam-use-BBDB . spam-check-BBDB)
+ (spam-use-ifile . spam-check-ifile)
+ (spam-use-stat . spam-check-stat)
+ (spam-use-blackholes . spam-check-blackholes)
+ (spam-use-bogofilter-headers . spam-check-bogofilter-headers)
+ (spam-use-bogofilter . spam-check-bogofilter))
"The spam-list-of-checks list contains pairs associating a parameter
variable with a spam checking function. If the parameter variable is
true, then the checking function is called, and its value decides what
\f
;;;; Bogofilter
-;;; See Paul Graham article, at `http://www.paulgraham.com/spam.html'.
-
-;;; This page is for those wanting to control spam with the help of
-;;; Eric Raymond's speedy Bogofilter, see
-;;; http://www.tuxedo.org/~esr/bogofilter. This has been tested with
-;;; a locally patched copy of version 0.4.
-
-;;; Make sure Bogofilter is installed. Bogofilter internally uses
-;;; Judy fast associative arrays, so you need to install Judy first,
-;;; and Bogofilter next. Fetch both distributions by visiting the
-;;; following links and downloading the latest version of each:
-;;;
-;;; http://sourceforge.net/projects/judy/
-;;; http://www.tuxedo.org/~esr/bogofilter/
-;;;
-;;; Unpack the Judy distribution and enter its main directory. Then do:
-;;;
-;;; ./configure
-;;; make
-;;; make install
-;;;
-;;; You will likely need to become super-user for the last step.
-;;; Then, unpack the Bogofilter distribution and enter its main
-;;; directory:
-;;;
-;;; make
-;;; make install
-;;;
-;;; Here as well, you need to become super-user for the last step.
-;;; Now, initialize your word lists by doing, under your own identity:
-;;;
-;;; mkdir ~/.bogofilter
-;;; touch ~/.bogofilter/badlist
-;;; touch ~/.bogofilter/goodlist
-;;;
-;;; These two files are text files you may edit, but you normally don't!
-
-;;; The `M-d' command gets added to Gnus summary mode, marking current
-;;; article as spam, showing it with the `H' mark. Whenever you see a
-;;; spam article, make sure to mark its summary line with `M-d' before
-;;; leaving the group. Some groups, as per variable
-;;; `spam-junk-mailgroups' below, receive articles from Gnus splitting
-;;; on clues added by spam recognisers, so for these groups, we tack
-;;; an `H' mark at group entry for all summary lines which would
-;;; otherwise have no other mark. Make sure to _remove_ `H' marks for
-;;; any article which is _not_ genuine spam, before leaving such
-;;; groups: you may use `M-u' to "unread" the article, or `d' for
-;;; declaring it read the non-spam way. When you leave a group, all
-;;; `H' marked articles, saved or unsaved, are sent to Bogofilter
-;;; which will study them as spam samples.
-
-;;; Messages may also be deleted in various other ways, and unless
-;;; `spam-ham-marks-form' gets overridden below, marks `R' and `r' for
-;;; default read or explicit delete, marks `X' and 'K' for automatic
-;;; or explicit kills, as well as mark `Y' for low scores, are all
-;;; considered to be associated with articles which are not spam.
-;;; This assumption might be false, in particular if you use kill
-;;; files or score files as means for detecting genuine spam, you
-;;; should then adjust `spam-ham-marks-form'. When you leave a group,
-;;; all _unsaved_ articles bearing any the above marks are sent to
-;;; Bogofilter which will study these as not-spam samples. If you
-;;; explicit kill a lot, you might sometimes end up with articles
-;;; marked `K' which you never saw, and which might accidentally
-;;; contain spam. Best is to make sure that real spam is marked with
-;;; `H', and nothing else.
-
-;;; All other marks do not contribute to Bogofilter pre-conditioning.
-;;; In particular, ticked, dormant or souped articles are likely to
-;;; contribute later, when they will get deleted for real, so there is
-;;; no need to use them prematurely. Explicitly expired articles do
-;;; not contribute, command `E' is a way to get rid of an article
-;;; without Bogofilter ever seeing it.
-
-;;; In a word, with a minimum of care for associating the `H' mark for
-;;; spam articles only, Bogofilter training all gets fairly automatic.
-;;; You should do this until you get a few hundreds of articles in
-;;; each category, spam or not. The shell command `head -1
-;;; ~/.bogofilter/*' shows both article counts. The command `S S' in
-;;; summary mode, either for debugging or for curiosity, triggers
-;;; Bogofilter into displaying in another buffer the "spamicity" score
-;;; of the current article (between 0.0 and 1.0), together with the
-;;; article words which most significantly contribute to the score.
-
-;;; The real way for using Bogofilter, however, is to have some use
-;;; tool like `procmail' for invoking it on message reception, then
-;;; adding some recognisable header in case of detected spam. Gnus
-;;; splitting rules might later trip on these added headers and react
-;;; by sorting such articles into specific junk folders as per
-;;; `spam-junk-mailgroups'. Here is a possible `.procmailrc' contents
-;;; (still untested -- please tell me how it goes):
-;;;
-;;; :0HBf:
-;;; * ? bogofilter
-;;; | formail -bfI "X-Spam-Status: Yes"
-
-(defun spam-check-bogofilter ()
- ;; Dynamic spam check. I do not know how to check the exit status,
- ;; so instead, read `bogofilter -v' output.
- (when (and spam-use-bogofilter spam-bogofilter-path)
- (spam-bogofilter-articles nil "-v" (list (gnus-summary-article-number)))
- (when (save-excursion
- (set-buffer spam-bogofilter-output-buffer-name)
- (goto-char (point-min))
- (re-search-forward "Spamicity: \\(0\\.9\\|1\\.0\\)" nil t))
- spam-split-group)))
-
+(defun spam-check-bogofilter-headers (&optional score)
+ (let ((header (message-fetch-field spam-bogofilter-header)))
+ (when (and header
+ (string-match "^Yes" header))
+ (if score
+ (when (string-match "spamicity=\\([0-9.]+\\)" header)
+ (match-string 1 header))
+ spam-split-group))))
+
+
+;; return something sensible if the score can't be determined
(defun spam-bogofilter-score ()
- "Use `bogofilter -v' on the current article.
-This yields the 15 most discriminant words for this article and the
-spamicity coefficient of each, and the overall article spamicity."
+ "Get the Bogofilter spamicity score"
(interactive)
- (when (and spam-use-bogofilter spam-bogofilter-path)
- (spam-bogofilter-articles nil "-v" (list (gnus-summary-article-number)))
- (with-current-buffer spam-bogofilter-output-buffer-name
- (unless (zerop (buffer-size))
- (if (<= (count-lines (point-min) (point-max)) 1)
- (progn
- (goto-char (point-max))
- (when (bolp)
- (backward-char 1))
- (message "%s" (buffer-substring (point-min) (point))))
- (goto-char (point-min))
- (display-buffer (current-buffer)))))))
-
-(defun spam-bogofilter-register-routine ()
- (let ((articles gnus-newsgroup-articles)
- article mark ham-articles spam-articles spam-mark-values
- ham-mark-values)
-
- ;; marks are stored as symbolic values, so we have to dereference
- ;; them for memq to work we wouldn't have to do this if
- ;; gnus-summary-article-mark returned a symbol.
- (dolist (mark spam-ham-marks)
- (push (symbol-value mark) ham-mark-values))
+ (save-window-excursion
+ (gnus-summary-show-article t)
+ (set-buffer gnus-article-buffer)
+ (let ((score (spam-check-bogofilter t)))
+ (message "Spamicity score %s" score)
+ (or score "0"))))
+
+(defun spam-check-bogofilter (&optional score)
+ "Check the Bogofilter backend for the classification of this message"
+ (let ((article-buffer-name (buffer-name))
+ return)
+ (with-temp-buffer
+ (let ((temp-buffer-name (buffer-name)))
+ (save-excursion
+ (set-buffer article-buffer-name)
+ (if spam-bogofilter-database-directory
+ (call-process-region (point-min) (point-max)
+ spam-bogofilter-path
+ nil temp-buffer-name nil "-v"
+ "-d" spam-bogofilter-database-directory)
+ (call-process-region (point-min) (point-max) spam-bogofilter-path
+ nil temp-buffer-name nil "-v")))
+ (setq return (spam-check-bogofilter-headers score))))
+ return))
- (dolist (mark spam-spam-marks)
- (push (symbol-value mark) spam-mark-values))
+(defun spam-bogofilter-register-with-bogofilter (article-string spam)
+ "Register an article, given as a string, as spam or non-spam."
+ (when (stringp article-string)
+ (let ((switch (if spam "-s" "-n")))
+ (with-temp-buffer
+ (insert-string article-string)
+ (if spam-bogofilter-database-directory
+ (call-process-region (point-min) (point-max)
+ spam-bogofilter-path
+ nil nil nil "-v" switch
+ "-d" spam-bogofilter-database-directory)
+ (call-process-region (point-min) (point-max) spam-bogofilter-path
+ nil nil nil "-v" switch))))))
+
+(defun spam-bogofilter-register-spam-routine ()
+ (spam-generic-register-routine
+ (lambda (article)
+ (spam-bogofilter-register-with-bogofilter
+ (spam-get-article-as-string article) t))
+ nil))
- (while articles
- (setq article (pop articles)
- mark (gnus-summary-article-mark article))
- (cond ((memq mark spam-mark-values) (push article spam-articles))
- ((memq article gnus-newsgroup-saved))
- ((memq mark ham-mark-values) (push article ham-articles))))
- (when ham-articles
- (spam-bogofilter-articles "ham" "-n" ham-articles))
- (when spam-articles
- (spam-bogofilter-articles "SPAM" "-s" spam-articles))))
-
-(defun spam-bogofilter-articles (type option articles)
- (let ((output-buffer (get-buffer-create spam-bogofilter-output-buffer-name))
- (article-copy (get-buffer-create " *Bogofilter Article Copy*"))
- (remove-regexp (concat spam-bogofilter-spaminfo-header-regexp
- "\\|Xref:"))
- (counter 0)
- prefix process article)
- (when type
- (setq prefix (format "Studying %d articles as %s..." (length articles)
- type))
- (message "%s" prefix))
- (save-excursion (set-buffer output-buffer) (erase-buffer))
- (setq process (start-process "bogofilter" output-buffer
- spam-bogofilter-path "-F" option))
- (process-kill-without-query process t)
- (unwind-protect
- (save-window-excursion
- (while articles
- (setq counter (1+ counter))
- (when prefix
- (message "%s %d" prefix counter))
- (setq article (pop articles))
- (gnus-summary-goto-subject article)
- (gnus-summary-show-article t)
- (gnus-eval-in-buffer-window article-copy
- (insert-buffer-substring gnus-original-article-buffer)
- ;; Remove spam classification redundant headers: they may induce
- ;; unwanted biases in later analysis.
- (message-remove-header remove-regexp t)
- ;; Bogofilter really wants From envelopes for counting articles.
- ;; Fake one at the beginning, make sure there will be no other.
- (goto-char (point-min))
- (if (looking-at "From ")
- (forward-line 1)
- (insert "From nobody " (current-time-string) "\n"))
- (let (case-fold-search)
- (while (re-search-forward "^From " nil t)
- (beginning-of-line)
- (insert ">")))
- (process-send-region process (point-min) (point-max))
- (erase-buffer))))
- ;; Sending the EOF is unwind-protected. This is to prevent lost copies
- ;; of `bogofilter', hung on reading their standard input, in case the
- ;; whole registering process gets interrupted by the user.
- (process-send-eof process))
- (kill-buffer article-copy)
- ;; Receive process output. It sadly seems that we still have to protect
- ;; ourselves against hung `bogofilter' processes.
- (let ((status (process-status process))
- (timeout (* 1000 spam-bogofilter-initial-timeout))
- (quanta 200)) ; also counted in milliseconds
- (while (and (not (eq status 'exit)) (> timeout 0))
- ;; `accept-process-output' timeout is counted in microseconds.
- (setq timeout (if (accept-process-output process 0 (* 1000 quanta))
- (* 1000 spam-bogofilter-subsequent-timeout)
- (- timeout quanta))
- status (process-status process)))
- (if (eq status 'exit)
- (when prefix
- (message "%s done!" prefix))
- ;; Sigh! The process did time out... Become brutal!
- (interrupt-process process)
- (message "%s %d INTERRUPTED! (Article %d, status %s)"
- (or prefix "Bogofilter process...")
- counter article status)
- ;; Give some time for user to read. Sitting redisplays but gives up
- ;; if input is pending. Sleeping does not give up, but it does not
- ;; redisplay either. Mix both: let's redisplay and not give up.
- (sit-for 1)
- (sleep-for 3)))))
+(defun spam-bogofilter-register-ham-routine ()
+ (spam-generic-register-routine
+ nil
+ (lambda (article)
+ (spam-bogofilter-register-with-bogofilter
+ (spam-get-article-as-string article) nil))))
(provide 'spam)
\r
if "%1" == "" goto usage\r
\r
+rem Directory where the info files are installed\r
+set GNUS_INFO_DIR=%1\..\..\xemacs-packages\info\r
+\r
set emacs=xemacs.exe\r
if "%2" == "" set copy="false"\r
if "%2" == "copy" set copy=true\r
if "%2" == "/copy" set copy=true\r
\r
+set EMACSBATCH=call %1\%emacs% -batch -q -no-site-file\r
+\r
cd lisp\r
-call %1\%emacs% -batch -q -no-site-file -l ./dgnushack.el -f dgnushack-compile\r
+%EMACSBATCH% -l ./dgnushack.el -f dgnushack-compile\r
if not %copy%==true goto info\r
attrib -r %1\..\..\xemacs-packages\lisp\gnus\*.*\r
copy *.el? %1\..\..\xemacs-packages\lisp\gnus\r
\r
:info\r
-set EMACSINFO=call %1\%emacs% -no-site-file -no-init-file -batch -q -l infohack.el -f batch-makeinfo\r
+set EMACSINFO=%EMACSBATCH% -l infohack.el -f batch-makeinfo\r
cd ..\texi\r
%EMACSINFO% message.texi\r
%EMACSINFO% emacs-mime.texi\r
%EMACSINFO% gnus.texi\r
if not %copy%==true goto done\r
-copy gnus %1\..\..\xemacs-packages\info\r
-copy gnus-?? %1\..\..\xemacs-packages\info\r
-copy message %1\..\..\xemacs-packages\info\r
-copy emacs-mime %1\..\..\xemacs-packages\info\r
+copy gnus %GNUS_INFO_DIR%\r
+copy gnus-? %GNUS_INFO_DIR%\r
+copy gnus-?? %GNUS_INFO_DIR%\r
+copy message %GNUS_INFO_DIR%\r
+copy message-? %GNUS_INFO_DIR%\r
+copy emacs-mime %GNUS_INFO_DIR%\r
+copy sieve %GNUS_INFO_DIR%\r
+copy pgg %GNUS_INFO_DIR%\r
+echo Maybe you should add the following line to %GNUS_INFO_DIR%\dir:\r
+echo.\r
+echo * PGG: (pgg). Emacs interface to various PGP implementations.\r
+echo * Sieve: (sieve). Managing Sieve scripts in Emacs.\r
+echo.\r
\r
:etc\r
cd ..\etc\r
rem Restore PWD so whoever called this batch file doesn't get confused\r
set PWD=%GNUS_PWD_SAVE%\r
set GNUS_PWD_SAVE=\r
+set EMACSBATCH=\r
+set GNUS_INFO_DIR=\r
:end\r
\r
if "%1" == "" goto usage\r
\r
+rem Directory where the info files are installed\r
+set GNUS_INFO_DIR=%1\info\r
+\r
rem Emacs 20.7 no longer includes emacs.bat. Use emacs.exe if the batch file is\r
rem not present -- this also fixes the problem about too many parameters on Win9x.\r
set emacs=emacs.exe\r
if exist %1\bin\emacs.bat set emacs=emacs.bat\r
+set EMACSBATCH=call %1\bin\%emacs% -no-site-file -batch -q\r
\r
cd lisp\r
-call %1\bin\%emacs% -batch -q -no-site-file -l ./dgnushack.el -f dgnushack-compile\r
+%EMACSBATCH% -l ./dgnushack.el -f dgnushack-compile\r
if not "%2" == "/copy" goto info\r
attrib -r %1\lisp\gnus\*\r
copy *.el* %1\lisp\gnus\r
\r
:info\r
-set EMACSINFO=call %1\bin\%emacs% -no-site-file -no-init-file -batch -q -l infohack.el -f batch-makeinfo\r
+set EMACSINFO=%EMACSBATCH% -l infohack.el -f batch-makeinfo\r
cd ..\texi\r
%EMACSINFO% message.texi\r
%EMACSINFO% emacs-mime.texi\r
%EMACSINFO% gnus.texi\r
if not "%2" == "/copy" goto done\r
-copy gnus %1\info\r
-copy gnus-?? %1\info\r
-copy message %1\info\r
-copy emacs-mime %1\info\r
+copy gnus %GNUS_INFO_DIR%\r
+copy gnus-? %GNUS_INFO_DIR%\r
+copy gnus-?? %GNUS_INFO_DIR%\r
+copy message %GNUS_INFO_DIR%\r
+copy message-? %GNUS_INFO_DIR%\r
+copy emacs-mime %GNUS_INFO_DIR%\r
+copy sieve %GNUS_INFO_DIR%\r
+copy pgg %GNUS_INFO_DIR%\r
+echo Maybe you should add the following line to %GNUS_INFO_DIR%\dir:\r
+echo.\r
+echo * PGG: (pgg). Emacs interface to various PGP implementations.\r
+echo * Sieve: (sieve). Managing Sieve scripts in Emacs.\r
+echo.\r
\r
:etc\r
cd ..\etc\r
rem Restore PWD so whoever called this batch file doesn't get confused\r
set PWD=%GNUS_PWD_SAVE%\r
set GNUS_PWD_SAVE=\r
+set EMACSBATCH=\r
+set GNUS_INFO_DIR=\r
:end\r
+2003-01-21 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus.texi (Various Summary Stuff): Add
+ gnus-summary-display-while-building.
+ (Group Parameters): Index gnus-parameters.
+ (Startup Files): Index gnus-site-init-file
+
+2003-01-20 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus.texi (Summary Buffer Lines): Additions to %B.
+
+ * gnus.texi: Markup fixes: use @code for nil and t, use @file for
+ files.
+
+ * message.texi: do.
+
+ * emacs-mime.texi: do.
+
+2003-01-19 Jesper Harder <harder@ifa.au.dk>
+
+ * dir (File): Add pgg.
+
+ * gnus.texi (Selecting a Group): Index gnus-auto-select-subject
+
+ * emacs-mime.texi (Display Customization): Add mm-keep-viewer-alive-types
+
+2003-01-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus.texi (Summary Agent Commands): Addition.
+
+2003-01-16 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * gnus.texi (Filtering Spam Using The Spam ELisp Package):
+ clarified syntax of gnus-spam-process-destinations and
+ gnus-ham-process-destinations variables
+ (Extending the spam elisp package): fixed typo in node name
+ (Bogofilter): new functionality and variables noted
+ (Filtering Spam Using The Spam ELisp Package): added mention of
+ nnimap-split-download-body
+
+2003-01-15 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus.texi: Don't use `path' in some cases.
+ From the GNU coding standards:
+
+ Please do not use the term ``pathname'' that is used in Unix
+ documentation; use ``file name'' (two words) instead. We use
+ the term ``path'' only for search paths, which are lists of
+ directory names.
+
+ * message.texi: Ditto.
+
+2003-01-15 Simon Josefsson <jas@extundo.com>
+
+ * gnus.texi (X-Face): Revert substantial part of last fix.
+ (Splitting in IMAP): Add.
+
+2003-01-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi (Window Layout): Fixed braces in example.
+
+2003-01-13 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * gnus.texi (Article Washing): Use new function names in
+ `deuglify.el'. Addition.
+
+2003-01-13 Simon Josefsson <jas@extundo.com>
+
+ * gnus.texi (X-Face): Fix.
+
+ * message.texi (Security): Fix.
+
+ * gnus.texi (Security): Fix.
+ (Signing and encrypting): Fix.
+
+2003-01-12 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * gnus.texi (Filtering Spam Using The Spam ELisp Package): removed
+ spam.el and spam-stat.el from the node and section names wherever
+ possible, since info indexing doesn't like `.' in the name
+
2003-01-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
* gnus.texi (Article Display): Addition.
* Message: (message). The Message sending thingamabob.
* Emacs MIME: (emacs-mime). Libraries for handling MIME.
* Sieve: (sieve). Managing Sieve scripts in Emacs.
+* PGG: (pgg). Emacs interface to various PGP implementations.
This file documents the Emacs MIME interface functionality.
-Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1998, 1999, 2000, 2001, 2002 Free Software
+Copyright @copyright{} 1998, 1999, 2000, 2001, 2002, 2003 Free Software
Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
This is a list of types that will be displayed automatically in an
external viewer.
+@item mm-keep-viewer-alive-types
+@vindex mm-keep-viewer-alive-types
+This is a list of media types for which the external viewer will not
+be killed when selecting a different article.
+
@item mm-attachment-override-types
@vindex mm-attachment-override-types
Some @sc{mime} agents create parts that have a content-disposition of
@item mm-coding-system-priorities
@vindex mm-coding-system-priorities
Prioritize coding systems to use for outgoing messages. The default
-is nil, which means to use the defaults in Emacs. It is a list of
+is @code{nil}, which means to use the defaults in Emacs. It is a list of
coding system symbols (aliases of coding systems does not work, use
@kbd{M-x describe-coding-system} to make sure you are not specifying
an alias in this variable). For example, if you have configured Emacs
@item mm-use-ultra-safe-encoding
@vindex mm-use-ultra-safe-encoding
-When this is non-nil, it means that textual parts are encoded as
+When this is non-@code{nil}, it means that textual parts are encoded as
quoted-printable if they contain lines longer than 76 characters or
starting with "From " in the body. Non-7bit encodings (8bit, binary)
are generally disallowed. This reduce the probability that a non-8bit
@table @code
@item mailcap-parse-mailcaps
@findex mailcap-parse-mailcaps
-Parse the @code{~/.mailcap} file.
+Parse the @file{~/.mailcap} file.
@item mailcap-mime-info
Takes a @sc{mime} type as its argument and returns the matching viewer.
\makeindex
\begin{document}
-\newcommand{\gnusversionname}{Oort Gnus v0.12}
+\newcommand{\gnusversionname}{Oort Gnus v0.13}
\newcommand{\gnuschaptername}{}
\newcommand{\gnussectionname}{}
spool or your mbox file. All at the same time, if you want to push your
luck.
-This manual corresponds to Oort Gnus v0.12.
+This manual corresponds to Oort Gnus v0.13.
@end ifinfo
* Anti-Spam Basics:: Simple steps to reduce the amount of spam.
* SpamAssassin:: How to use external anti-spam tools.
* Hashcash:: Reduce spam by burning CPU time.
-* Filtering Spam Using spam.el::
-* Filtering Spam Using Statistics (spam-stat.el)::
+* Filtering Spam Using The Spam ELisp Package::
+* Filtering Spam Using Statistics with spam-stat::
Appendices
@end lisp
@vindex gnus-init-file
+@vindex gnus-site-init-file
When Gnus starts, it will read the @code{gnus-site-init-file}
(@file{.../site-lisp/gnus} by default) and @code{gnus-init-file}
(@file{~/.gnus} by default) files. These are normal Emacs Lisp files
If non-@code{nil}, the startup message won't be displayed. That way,
your boss might not notice as easily that you are reading news instead
of doing your job. Note that this variable is used before
-@file{.gnus.el} is loaded, so it should be set in @code{.emacs} instead.
+@file{.gnus.el} is loaded, so it should be set in @file{.emacs} instead.
@item gnus-no-groups-message
@vindex gnus-no-groups-message
@vindex gnus-select-group-hook
@vindex gnus-auto-select-first
+@vindex gnus-auto-select-subject
If @code{gnus-auto-select-first} is non-@code{nil}, select an article
automatically when entering a group with the @kbd{SPACE} command.
Which article this is is controlled by the
silly Lisp errors.) You might also be interested in reading about topic
parameters (@pxref{Topic Parameters}).
+@vindex gnus-parameters
Group parameters can be set via the @code{gnus-parameters} variable too.
But some variables, such as @code{visible}, have no effect. For
example:
@vindex gnus-group-name-charset-group-alist
An alist of regexp of group name and the charset for group names. It
is used to show non-ASCII group names. @code{((".*" utf-8))} is the
-default value if UTF-8 is supported, otherwise the default is nil.
+default value if UTF-8 is supported, otherwise the default is
+@code{nil}.
For example:
@lisp
@code{ftp.isc.org} (@code{gnus-group-fetch-control}). Query for a
group if given a prefix argument.
-If @code{gnus-group-fetch-control-use-browse-url} is non-nil, Gnus
-will open the control messages in a browser using @code{browse-url}.
-Otherwise they are fetched using @code{ange-ftp} and displayed in an
-ephemeral group.
+If @code{gnus-group-fetch-control-use-browse-url} is non-@code{nil},
+Gnus will open the control messages in a browser using
+@code{browse-url}. Otherwise they are fetched using @code{ange-ftp}
+and displayed in an ephemeral group.
Note that the control messages are compressed. To use this command
you need to turn on @code{auto-compression-mode}
@vindex gnus-sieve-crosspost
The variable @code{gnus-sieve-crosspost} controls how the Sieve script
-is generated. If it is non-nil (the default) articles is placed in
-all groups that have matching rules, otherwise the article is only
-placed in the group with the first matching rule. For example, the
-group parameter @samp{(sieve address "sender"
+is generated. If it is non-@code{nil} (the default) articles is
+placed in all groups that have matching rules, otherwise the article
+is only placed in the group with the first matching rule. For
+example, the group parameter @samp{(sieve address "sender"
"owner-ding@@hpc.uh.edu")} will generate the following piece of Sieve
-code if @code{gnus-sieve-crosspost} is nil. (When
-@code{gnus-sieve-crosspost} is non-nil, it looks the same except that
-the line containing the call to @code{stop} is removed.)
+code if @code{gnus-sieve-crosspost} is @code{nil}. (When
+@code{gnus-sieve-crosspost} is non-@code{nil}, it looks the same
+except that the line containing the call to @code{stop} is removed.)
@example
if address "sender" "owner-ding@@hpc.uh.edu" @{
Indentation based on thread level (@pxref{Customizing Threading}).
@item B
A complex trn-style thread tree, showing response-connecting trace
-lines.
+lines. A thread could be drawn like this:
+
+@example
+>
++->
+| +->
+| | \->
+| | \->
+| \->
++->
+\->
+@end example
+
+You can customize the appearance with the following options. Note
+that it is possible to make the thread display look really neat by
+replacing the default ASCII characters with graphic line-drawing
+glyphs.
+@table @code
+@item gnus-sum-thread-tree-root
+@vindex gnus-sum-thread-tree-root
+Used for the root of a thread. If @code{nil}, use subject
+instead. The default is @samp{> }.
+
+@item gnus-sum-thread-tree-single-indent
+@vindex gnus-sum-thread-tree-single-indent
+Used for a thread with just one message. If @code{nil}, use subject
+instead. The default is @samp{}.
+
+@item gnus-sum-thread-tree-vertical
+@vindex gnus-sum-thread-tree-vertical
+Used for drawing a vertical line. The default is @samp{| }.
+
+@item gnus-sum-thread-tree-indent
+@vindex gnus-sum-thread-tree-indent
+Used for indenting. The default is @samp{ }.
+
+@item gnus-sum-thread-tree-leaf-with-other
+@vindex gnus-sum-thread-tree-leaf-with-other
+Used for a leaf with brothers. The default is @samp{+-> }.
+
+@item gnus-sum-thread-tree-single-leaf
+@vindex gnus-sum-thread-tree-single-leaf
+Used for a leaf without brothers. The default is @samp{\-> }
+
+@end table
+
@item T
Nothing if the article is a root and lots of spaces if it isn't (it
pushes everything after it off the screen).
@findex gnus-delay-initialize
By default, this function installs @code{gnus-delay-send-queue} in
@code{gnus-get-new-news-hook}. But it accepts the optional second
-argument @code{no-check}. If it is non-nil,
+argument @code{no-check}. If it is non-@code{nil},
@code{gnus-get-new-news-hook} is not changed. The optional first
argument is ignored.
format of the dummy roots. It accepts only one format spec: @samp{S},
which is the subject of the article. @xref{Formatting Variables}.
If you want all threads to have a dummy root, even the non-gathered
-ones, set @code{gnus-summary-make-false-root-always} to t.
+ones, set @code{gnus-summary-make-false-root-always} to @code{t}.
@item empty
Gnus won't actually make any article the parent, but simply leave the
like @code{\222} or @code{\264} where you're expecting some kind of
apostrophe or quotation mark, then try this wash.
-@item W k
-@kindex W k (Summary)
+@item W Y f
@kindex W Y f (Summary)
@findex gnus-article-outlook-deuglify-article
@cindex Outlook Express
-Deuglify broken Outlook (Express) articles.
+Full deuglify of broken Outlook (Express) articles: Treat dumbquotes,
+unwrap lines, repair attribution and rearrange citation.
(@code{gnus-article-outlook-deuglify-article}).
@item W Y u
@kindex W Y u (Summary)
-@findex gnus-outlook-unwrap-lines
+@findex gnus-article-outlook-unwrap-lines
Unwrap lines that appear to be wrapped citation lines. You can control
what lines will be unwrapped by frobbing
@code{gnus-outlook-deuglify-unwrap-min} and
@item W Y a
@kindex W Y a (Summary)
-@findex gnus-outlook-repair-attribution
-Repair a broken attribution line
-(@code{gnus-outlook-repair-attribution}).
+@findex gnus-article-outlook-repair-attribution
+Repair a broken attribution line.
+(@code{gnus-article-outlook-repair-attribution}).
@item W Y c
@kindex W Y c (Summary)
-@findex gnus-outlook-rearrange-citation
+@findex gnus-article-outlook-rearrange-citation
Repair broken citations by rearranging the text.
-(@code{gnus-outlook-rearrange-citation}).
+(@code{gnus-article-outlook-rearrange-citation}).
@item W w
@kindex W w (Summary)
@end menu
@table @code
+@vindex gnus-summary-display-while-building
+@item gnus-summary-display-while-building
+If non-@code{nil}, show and update the summary buffer as it's being
+built. If @code{t}, update the buffer after every line is inserted.
+If the value is an integer, @var{n}, update the display every @var{n}
+lines. The default is @code{nil}.
+
@vindex gnus-summary-mode-hook
@item gnus-summary-mode-hook
This hook is called when creating a summary mode buffer.
@enumerate
@item
-To handle PGP messages, you have to install mailcrypt or gpg.el as
-well as a OpenPGP implementation (such as GnuPG).
+To handle PGP and PGP/MIME messages, you have to install an OpenPGP
+implementation such as GnuPG. The lisp interface to GnuPG included
+with Gnus is called PGG (@pxref{Top, ,PGG, pgg, PGG Manual}), but
+Mailcrypt and gpg.el are also supported.
@item
To handle @sc{s/mime} message, you need to install OpenSSL. OpenSSL 0.9.6
@code{always}, always decrypt; @code{known}, only decrypt known
protocols. Otherwise, ask user.
+@item mml1991-use
+@vindex mml1991-use
+Symbol indicating elisp interface to OpenPGP implementation for PGP
+messages. The default is @code{pgg}, but @code{mailcrypt} and
+@code{gpg} are also supported although deprecated.
+
+@item mml2015-use
+@vindex mml2015-use
+Symbol indicating elisp interface to OpenPGP implementation for
+PGP/MIME messages. The default is @code{pgg}, but @code{mailcrypt}
+and @code{gpg} are also supported although deprecated.
+
@end table
@node Mailing List
@item c (Article)
@kindex c (Article)
Copy the @sc{mime} object to a fresh buffer and display this buffer
-(@code{gnus-mime-copy-part}).
+(@code{gnus-mime-copy-part}). Compressed files like @file{.gz} and
+@file{.bz2} are automatically decompressed if
+@code{auto-compression-mode} is enabled (@pxref{Compressed Files,,
+Accessing Compressed Files, emacs, The Emacs Editor}).
@findex gnus-mime-print-part
@item p (Article)
see the @code{mm-verify-option} and @code{mm-decrypt-option} options
(@pxref{Security}).
-For PGP, Gnus supports two external libraries, @sc{gpg.el} and
-@sc{Mailcrypt}, you need to install at least one of them. The
-@sc{s/mime} support in Gnus requires the external program OpenSSL.
-
Often, you would like to sign replies to people who send you signed
messages. Even more often, you might want to encrypt messages which
are in reply to encrypted messages. Gnus offers
@end table
-Also @xref{Security, ,Security, message, Message Manual}.
+@xref{Security, ,Security, message, Message Manual}, for more information.
@node Select Methods
@chapter Select Methods
@item nnspool-active-file
@vindex nnspool-active-file
-The path to the active file.
+The name of the active file.
@item nnspool-newsgroups-file
@vindex nnspool-newsgroups-file
-The path to the group descriptions file.
+The name of the group descriptions file.
@item nnspool-history-file
@vindex nnspool-history-file
-The path to the news history file.
+The name of the news history file.
@item nnspool-active-times-file
@vindex nnspool-active-times-file
-The path to the active date file.
+The name of the active date file.
@item nnspool-nov-is-evil
@vindex nnspool-nov-is-evil
@table @code
@item :path
-The path of the file. Defaults to the value of the @code{MAIL}
+The file name. Defaults to the value of the @code{MAIL}
environment variable or the value of @code{rmail-spool-directory}
(usually something like @file{/usr/mail/spool/user-name}).
@end table
(file :path "/usr/spool/mail/user-name")
@end lisp
-Or using the default path:
+Or using the default file name:
@lisp
(file)
@table @code
@item :path
-The path of the directory where the files are. There is no default
+The name of the directory where the files are. There is no default
value.
@item :suffix
@table @code
@item :path
-The path of the directory where the mails are stored. The default is
+The name of the directory where the mails are stored. The default is
taken from the @code{MAILDIR} environment variable or
@samp{~/Maildir/}.
@item :subdirs
Go to the group buffer.
@item
-Type `G f' and give the path to the mbox file when prompted to create an
+Type @kbd{G f} and give the file name to the mbox file when prompted to create an
@code{nndoc} group from the mbox file (@pxref{Foreign Groups}).
@item
-Type `SPACE' to enter the newly created group.
+Type @kbd{SPACE} to enter the newly created group.
@item
-Type `M P b' to process-mark all articles in this group's buffer
+Type @kbd{M P b} to process-mark all articles in this group's buffer
(@pxref{Setting Process Marks}).
@item
-Type `B r' to respool all the process-marked articles, and answer
+Type @kbd{B r} to respool all the process-marked articles, and answer
@samp{nnml} when prompted (@pxref{Mail Group Commands}).
@end enumerate
Nnmail equivalent: @code{nnmail-split-fancy}.
+@item nnimap-split-download-body
+@findex nnimap-split-download-body
+@vindex nnimap-split-download-body
+
+Set to non-nil to download entire articles during splitting. This is
+generally not required, and will slow things down considerably. You
+may need it if you want to use an advanced splitting function that
+analyses the body to split the article.
+
@end table
@node Expiring in IMAP
Remove the downloading mark from the article
(@code{gnus-agent-unmark-article}).
+@cindex %
@item @@
@kindex @@ (Agent Summary)
@findex gnus-agent-toggle-mark
-Toggle whether to download the article (@code{gnus-agent-toggle-mark}).
+Toggle whether to download the article
+(@code{gnus-agent-toggle-mark}). The dowload mark is @samp{%} by
+default.
@item J c
@kindex J c (Agent Summary)
on the @code{References} header using the @code{Message-ID} of the
current article, thereby matching the following thread.
-You can also score on @code{thread}, which will try to score all
-articles that appear in a thread. @code{thread} matches uses a
-@code{Message-ID} to match on the @code{References} header of the
-article. If the match is made, the @code{Message-ID} of the article is
-added to the @code{thread} rule. (Think about it. I'd recommend two
-aspirins afterwards.)
-
If you use this scheme, you should set the score file atom @code{mark}
to something small---like -300, perhaps, to avoid having small random
changes result in articles getting marked as read.
(vertical 0.24
(if (buffer-live-p gnus-summary-buffer)
'(summary 0.5))
- (group 1.0)))))
+ (group 1.0))))
@end lisp
One common desire for a multiple frame split is to have a separate frame
you'll get top speed again. Gnus will save these compiled specs in the
@file{.newsrc.eld} file. (User-defined functions aren't compiled by
this function, though---you should compile them yourself by sticking
-them into the @code{.gnus.el} file and byte-compiling that file.)
+them into the @file{.gnus.el} file and byte-compiling that file.)
@node Mode Lines
easier insertion of X-Face headers in outgoing messages.
@findex gnus-random-x-face
-@code{gnus-random-x-face} goes through all the @samp{pbm} files
-in @code{gnus-x-face-directory} and picks one at random, and then
+@code{gnus-random-x-face} goes through all the @samp{pbm} files in
+@code{gnus-x-face-directory} and picks one at random, and then
converts it to the X-Face format by using the
@code{gnus-convert-pbm-to-x-face-command} shell command. The
-@samp{pbm} files should be 48x48 pixels big.
+@samp{pbm} files should be 48x48 pixels big. It returns the X-Face
+header data as a string.
+
+@findex gnus-insert-random-x-face-header
+@code{gnus-insert-random-x-face-header} calls
+@code{gnus-random-x-face} and inserts a @samp{X-Face} header with the
+randomly generated data.
+@findex gnus-x-face-from-file
@code{gnus-x-face-from-file} takes a GIF file as the parameter, and then
converts the file to X-Face format by using the
@code{gnus-convert-image-to-x-face-command} shell command.
-Here's how you would typically use the former function. Put something
+Here's how you would typically use the first function. Put something
like the following in your @file{.gnus.el} file:
@lisp
(list '(X-Face . gnus-random-x-face))))
@end lisp
-Using the latter function would be something like this:
+Using the last function would be something like this:
@lisp
(setq message-required-news-headers
* Anti-Spam Basics:: Simple steps to reduce the amount of spam.
* SpamAssassin:: How to use external anti-spam tools.
* Hashcash:: Reduce spam by burning CPU time.
-* Filtering Spam Using spam.el::
-* Filtering Spam Using Statistics (spam-stat.el)::
+* Filtering Spam Using The Spam ELisp Package::
+* Filtering Spam Using Statistics with spam-stat::
@end menu
@node The problem of spam
customized mail filtering scripts. Improvements in this area would be
a useful contribution, however.
-@node Filtering Spam Using spam.el
-@subsection Filtering Spam Using spam.el
+@node Filtering Spam Using The Spam ELisp Package
+@subsection Filtering Spam Using The Spam ELisp Package
@cindex spam filtering
-@cindex spam.el
+@cindex spam
The idea behind @code{spam.el} is to have a control center for spam detection
and filtering in Gnus. To that end, @code{spam.el} does two things: it
@findex spam-bogofilter-score
@code{spam-bogofilter-score}.
-You must have bogofilter processing enabled for that command to work
-properly.
+You must have Bogofilter installed for that command to work properly.
@xref{Bogofilter}.
not done for @emph{unclassified} or @emph{ham} groups. Also, any
@strong{ham} articles in a spam group will be moved to a location
determined by either the @code{ham-process-destination} group
-parameter or the @code{gnus-ham-process-destinations} variable. The
+parameter or a match in the @code{gnus-ham-process-destinations}
+variable, which is a list of regular expressions matched with group
+names (it's easiest to customize this variable with
+@code{customize-variable gnus-ham-process-destinations}). The ultimate
location is a group name. If the @code{ham-process-destination}
parameter is not set, spam articles are only expired.
When you leave a @emph{ham} or @emph{unclassified} group, all
@strong{spam} articles are moved to a location determined by either
-the @code{spam-process-destination} group parameter or the
-@code{gnus-spam-process-destinations} variable. The location is a
-group name. If the @code{spam-process-destination} parameter is not
-set, the spam articles are only expired.
+the @code{spam-process-destination} group parameter or a match in the
+@code{gnus-spam-process-destinations} variable, which is a list of
+regular expressions matched with group names (it's easiest to
+customize this variable with @code{customize-variable
+gnus-spam-process-destinations}). The ultimate location is a group
+name. If the @code{spam-process-destination} parameter is not set,
+the spam articles are only expired.
To use the @code{spam.el} facilities for incoming mail filtering, you
must add the following to your fancy split list
@code{spam-split-group}. By default that group name is @samp{spam},
but you can customize it.
+@emph{Note for IMAP users}
+
+The boolean variable @code{nnimap-split-download-body} needs to be
+set, if you want to split based on the whole message instead of just
+the headers. By default, the nnimap backend will only retrieve the
+message headers. If you use spam-check-bogofilter, spam-check-ifile,
+or spam-check-stat (the splitters that can benefit from the full
+message body), you should set this variable. It is not set by default
+because it will slow IMAP down.
+
+@xref{Splitting in IMAP}.
+
@emph{TODO: Currently, spam.el only supports insertion of articles
into a backend. There is no way to tell spam.el that an article is no
longer spam or ham.}
* Bogofilter::
* ifile spam filtering::
* spam-stat spam filtering::
-* Extending spam.el::
+* Extending the spam elisp package::
@end menu
@node Blacklists and Whitelists
@cindex spam filtering
@cindex whitelists, spam filtering
@cindex blacklists, spam filtering
-@cindex spam.el
+@cindex spam
@defvar spam-use-blacklist
-Set this variable to t if you want to use blacklists when splitting
-incoming mail. Messages whose senders are in the blacklist will be
-sent to the @code{spam-split-group}. This is an explicit filter,
-meaning that it acts only on mail senders @emph{declared} to be
-spammers.
+Set this variable to @code{t} if you want to use blacklists when
+splitting incoming mail. Messages whose senders are in the blacklist
+will be sent to the @code{spam-split-group}. This is an explicit
+filter, meaning that it acts only on mail senders @emph{declared} to
+be spammers.
@end defvar
@defvar spam-use-whitelist
-Set this variable to t if you want to use whitelists when splitting
-incoming mail. Messages whose senders are not in the whitelist will
-be sent to the @code{spam-split-group}. This is an implicit filter,
-meaning it believes everyone to be a spammer unless told otherwise.
-Use with care.
+Set this variable to @code{t} if you want to use whitelists when
+splitting incoming mail. Messages whose senders are not in the
+whitelist will be sent to the @code{spam-split-group}. This is an
+implicit filter, meaning it believes everyone to be a spammer unless
+told otherwise. Use with care.
@end defvar
@defvar gnus-group-spam-exit-processor-blacklist
@cindex spam filtering
@cindex BBDB whitelists, spam filtering
@cindex BBDB, spam filtering
-@cindex spam.el
+@cindex spam
@defvar spam-use-BBDB
@subsubsection Blackholes
@cindex spam filtering
@cindex blackholes, spam filtering
-@cindex spam.el
+@cindex spam
@defvar spam-use-blackholes
@defvar spam-use-dig
Use the @code{dig.el} package instead of the @code{dns.el} package.
-The default setting of t is recommended.
+The default setting of @code{t} is recommended.
@end defvar
@subsubsection Bogofilter
@cindex spam filtering
@cindex bogofilter, spam filtering
-@cindex spam.el
+@cindex spam
@defvar spam-use-bogofilter
Set this variable if you want @code{spam-split} to use Eric Raymond's
-speedy Bogofilter. This has been tested with a locally patched copy
-of version 0.4. Make sure to read the installation comments in
-@code{spam.el}.
+speedy Bogofilter.
With a minimum of care for associating the @samp{H} mark for spam
articles only, Bogofilter training all gets fairly automatic. You
should do this until you get a few hundreds of articles in each
-category, spam or not. The shell command @command{head -1
-~/.bogofilter/*} shows both article counts. The command @kbd{S t} in
-summary mode, either for debugging or for curiosity, triggers
-Bogofilter into displaying in another buffer the @emph{spamicity}
-score of the current article (between 0.0 and 1.0), together with the
-article words which most significantly contribute to the score.
+category, spam or not. The command @kbd{S t} in summary mode, either
+for debugging or for curiosity, shows the @emph{spamicity} score of
+the current article (between 0.0 and 1.0).
+
+Bogofilter determines if a message is spam based on an internal
+threshold, set at compilation time. That threshold can't be
+customized.
If the @code{bogofilter} executable is not in your path, Bogofilter
processing will be turned off.
+You should not enable this if you use @code{spam-use-bogofilter-headers}.
+
@end defvar
+@defvar spam-use-bogofilter-headers
+
+Set this variable if you want @code{spam-split} to use Eric Raymond's
+speedy Bogofilter, looking only at the message headers. It works
+similarly to @code{spam-use-bogofilter}, but the @code{X-Bogosity} header
+must be in the message already. Normally you would do this with a
+procmail recipe or something similar; consult the Bogofilter
+installation documents for details.
+
+You should not enable this if you use @code{spam-use-bogofilter}.
+
+@end defvar
@defvar gnus-group-spam-exit-processor-bogofilter
Add this symbol to a group's @code{spam-process} parameter by
customizing the group parameters or the
@code{gnus-spam-process-newsgroups} variable. When this symbol is
added to a group's @code{spam-process} parameter, spam-marked articles
-will be added to the bogofilter spam database, and ham-marked articles
-will be added to the bogofilter ham database. @strong{Note that the
-Bogofilter spam processor is the only spam processor to also do ham
-processing.}
+will be added to the Bogofilter spam database.
@end defvar
+@defvar gnus-group-ham-exit-processor-bogofilter
+Add this symbol to a group's @code{spam-process} parameter by
+customizing the group parameters or the
+@code{gnus-spam-process-newsgroups} variable. When this symbol is
+added to a group's @code{spam-process} parameter, the ham-marked
+articles in @emph{ham} groups will be added to the Bogofilter database
+of non-spam messages. Note that this ham processor has no effect in
+@emph{spam} or @emph{unclassified} groups.
+@end defvar
+
+@defvar spam-bogofilter-database-directory
+
+This is the directory where Bogofilter will store its databases. It
+is not specified by default, so Bogofilter will use its own default
+database directory.
+
+@end defvar
+
+The Bogofilter mail classifier is similar to ifile in intent and
+purpose. A ham and a spam processor are provided, plus the
+@code{spam-use-bogofilter} and @code{spam-use-bogofilter-headers}
+variables to indicate to spam-split that Bogofilter should either be
+used, or has already been used on the article. The 0.9.2.1 version of
+Bogofilter was used to test this functionality.
+
@node ifile spam filtering
@subsubsection ifile spam filtering
@cindex spam filtering
@cindex ifile, spam filtering
-@cindex spam.el
+@cindex spam
@defvar spam-use-ifile
@subsubsection spam-stat spam filtering
@cindex spam filtering
@cindex spam-stat, spam filtering
-@cindex spam-stat.el
-@cindex spam.el
+@cindex spam-stat
+@cindex spam
-@xref{Filtering Spam Using Statistics (spam-stat.el)}.
+@xref{Filtering Spam Using Statistics with spam-stat}.
@defvar spam-use-stat
processor, and the @code{spam-use-stat} variable for @code{spam-split}
are provided.
-@node Extending spam.el
-@subsubsection Extending spam.el
+@node Extending the spam elisp package
+@subsubsection Extending the spam elisp package
@cindex spam filtering
-@cindex spam.el, extending
-@cindex extending spam.el
+@cindex spam elisp package, extending
+@cindex extending the spam elisp package
Say you want to add a new back end called blackbox. For filtering
incoming mail, provide the following:
@end enumerate
-@node Filtering Spam Using Statistics (spam-stat.el)
-@subsection Filtering Spam Using Statistics (spam-stat.el)
+@node Filtering Spam Using Statistics with spam-stat
+@subsection Filtering Spam Using Statistics with spam-stat
@cindex Paul Graham
@cindex Graham, Paul
@cindex naive Bayesian spam filtering
@table @code
@item gnus-home-directory
-All Gnus path variables will be initialized from this variable, which
-defaults to @file{~/}.
+All Gnus file and directory variables will be initialized from this
+variable, which defaults to @file{~/}.
@item gnus-directory
@vindex gnus-directory
-Most Gnus storage path variables will be initialized from this variable,
-which defaults to the @samp{SAVEDIR} environment variable, or
-@file{~/News/} if that variable isn't set.
+Most Gnus storage file and directory variables will be initialized from
+this variable, which defaults to the @samp{SAVEDIR} environment
+variable, or @file{~/News/} if that variable isn't set.
Note that Gnus is mostly loaded when the @file{.gnus.el} file is read.
This means that other directory variables that are initialized from this
This function (really ``special form'') @code{setq} is the one that can
set a variable to some value. This is really all you need to know. Now
-you can go and fill your @code{.emacs} file with lots of these to change
+you can go and fill your @file{.emacs} file with lots of these to change
how Gnus works.
-If you have put that thing in your @code{.emacs} file, it will be read
+If you have put that thing in your @file{.emacs} file, it will be read
and @code{eval}ed (which is lisp-ese for ``run'') the next time you
start Emacs. If you want to change the variable right away, simply say
@kbd{C-x C-e} after the closing parenthesis. That will @code{eval} the
@subsection Using PGP/MIME
@sc{pgp/mime} requires an external OpenPGP implementation, such as GNU
-Privacy Guard (@uref{http://www.gnupg.org/}). It also requires an
-Emacs interface to it, such as Mailcrypt (available from
-@uref{http://www.nb.net/~lbudney/linux/software/mailcrypt.html}) or
-Florian Weimer's @code{gpg.el}.
+Privacy Guard (@uref{http://www.gnupg.org/}). One Emacs interface to
+OpenPGP implementations, PGG (@pxref{Top, ,PGG, pgg, PGG Manual}), is
+included, but Mailcrypt and Florian Weimer's @code{gpg.el} are also
+supported.
@vindex gpg-temp-directory
Note, if you are using the @code{gpg.el} you must make sure that the
-path specified by @code{gpg-temp-directory} have permissions 0700.
+directory specified by @code{gpg-temp-directory} have permissions 0700.
Creating your own OpenPGP key is described in detail in the
documentation of your OpenPGP implementation, so we refer to it.
@item message-send-mail-partially-limit
@vindex message-send-mail-partially-limit
-The limitation of messages sent as message/partial.
-The lower bound of message size in characters, beyond which the message
-should be sent in several parts. If it is nil, the size is unlimited.
+The limitation of messages sent as message/partial. The lower bound
+of message size in characters, beyond which the message should be sent
+in several parts. If it is @code{nil}, the size is unlimited.
@end table
@item message-send-mail-hook
@vindex message-send-mail-hook
-Hook run before sending mail messages.
+Hook run before sending mail messages. This hook is run very late --
+just before the message is actually sent as mail.
@item message-send-news-hook
@vindex message-send-news-hook
-Hook run before sending news messages.
+Hook run before sending news messages. This hook is run very late --
+just before the message is actually sent as news.
@item message-sent-hook
@vindex message-sent-hook