Patches between 5.10.3 and 5.10.4
Lars Magne Ingebrigtsen <[email protected]> Sat, 03 Jan 2004 00:10:44 +0100
| Newsgroups | gmane.emacs.gnus.patches |
|---|---|
| Message-ID | <[email protected]> |
Index: gnus/ChangeLog diff -u gnus/ChangeLog:6.64 gnus/ChangeLog:6.65 --- gnus/ChangeLog:6.64 Tue Dec 23 13:53:07 2003 +++ gnus/ChangeLog Fri Jan 2 21:28:23 2004 @@ -1,3 +1,7 @@ +2004-01-02 Reiner Steib <[email protected]> + + * GNUS-NEWS: Add `gnus-group-read-ephemeral-group'. + 2003-12-23 Reiner Steib <[email protected]> * GNUS-NEWS: Mention change of `e' in draft groups. Index: gnus/GNUS-NEWS diff -u gnus/GNUS-NEWS:6.65 gnus/GNUS-NEWS:6.66 --- gnus/GNUS-NEWS:6.65 Tue Dec 23 13:53:07 2003 +++ gnus/GNUS-NEWS Fri Jan 2 21:28:23 2004 @@ -8,6 +8,8 @@ * Changes in Oort Gnus +** `gnus-group-read-ephemeral-group' can be called interactively, using `G M'. + ** In draft groups, `e' is now bound to `gnus-draft-edit-message'. Use `B w' for `gnus-summary-edit-article' instead. Index: gnus/lisp/ChangeLog diff -u gnus/lisp/ChangeLog:6.2727 gnus/lisp/ChangeLog:6.2753 --- gnus/lisp/ChangeLog:6.2727 Tue Dec 30 03:50:44 2003 +++ gnus/lisp/ChangeLog Sat Jan 3 00:09:35 2004 @@ -1,3 +1,124 @@ +2004-01-03 Lars Magne Ingebrigtsen <[email protected]> + + * gnus.el: Gnus v5.10.4 is released. + +2004-01-02 Reiner Steib <[email protected]> + + * gnus.el (gnus-mode-line-buffer-identification): Show version in + help-echo. + (gnus-read-group): Allow most group names. Changed warning. + +2004-01-02 Lars Magne Ingebrigtsen <[email protected]> + + * gnus-dired.el (gnus-dired-mode-map): Change keymaps. + +2004-01-02 Arne J,Ax(Brgensen <[email protected]> + + * smime.el (smime-crl-check): Doc fix. + +2004-01-02 Edwin Steiner <[email protected]> + + * gnus-nocem.el (gnus-nocem-enter-article): Use the real group + hashtb (tiny patch). + +2004-01-02 Kai Grossjohann <[email protected]> + + * nnml.el (nnml-save-mail): Grok compressed articles. From + Michael Albinus <[email protected]>. + +2004-01-02 Teodor Zlatanov <[email protected]> + + * spam.el (spam-ham-copy-or-move-routine): use spam-list-articles + (spam-list-articles): rewritten to only check a mark once per + invocation + +2004-01-01 Simon Josefsson <[email protected]> + + * mml-sec.el (mml-default-encrypt-method) + (mml-default-sign-method): Defcustom. + +2003-12-31 Lars Magne Ingebrigtsen <[email protected]> + + * mml.el (mml-generate-mime-1): Remove extra ). + + * gnus-group.el (gnus-group-set-current-level): Signal errors on + topic lines. + (gnus-group-set-current-level): Fix fix. + +2003-12-31 Jeremy Maitin-Shepard <[email protected]> + + * mml.el (mml-generate-mime-1): Use mml-compute-boundary (tiny + change). + +2003-12-30 Reiner Steib <[email protected]> + + * gnus-group.el: Removed `(when t ...)' around `gnus-define-keys'. + (gnus-group-group-map): Added `gnus-group-read-ephemeral-group' + (already in previous commit inadvertently). + (gnus-group-make-menu-bar): Added `gnus-group-read-ephemeral-group'. + (gnus-group-read-ephemeral-group): Made interactive. + + * gnus-score.el (gnus-score-find-trace): Added comment on sync + with `gnus-score-edit-file-at-point'. + + * gnus-logic.el (gnus-score-advanced): Ditto. + + * gnus-score.el (gnus-score-edit-file-at-point): Fix for + advanced scoring. + +2003-12-30 Simon Josefsson <[email protected]> + + * gnus-score.el (gnus-score-edit-file-at-point): Use + gnus-point-at-*, for portability. + +2003-12-30 Reiner Steib <[email protected]> + + * gnus-art.el (gnus-treat-body-boundary): Fix doc-string and + custom type. + (gnus-button-mid-or-mail-regexp): Don't be too restrictive. + Suggested by Felix Wiemann <[email protected]>. + (gnus-button-alist): Added "M-x ... RET" and "mid:" buttons. + Added comments about relevant RFCs. + + * gnus-sum.el (gnus-summary-mode): Untabify doc-string. + (gnus-summary-goto-article): Allow `%40'. + (gnus-summary-refer-article): Convert `%40' to `@'. + +2003-12-30 Simon Josefsson <[email protected]> + + * smime.el (smime-crl-check): New. + (smime-verify-region): Use it. From Arne J,Ax(Brgensen + <[email protected]> in <[email protected]> (tiny + change). + +2003-12-30 Reiner Steib <[email protected]> + + * gnus-score.el (gnus-score-edit-file-at-point): Consider the + whole match element. From Karl Pfl,Ad(Bsterer <[email protected]>. + (gnus-score-find-trace): Use it. Added `f' and `t' commands, + added quick help. With some suggestions from Karl Pfl,Ad(Bsterer + <[email protected]>. + + * gnus-util.el (gnus-emacs-version): Added doc-string. + + * mml.el (mml-minibuffer-read-disposition): New function. + (mml-attach-file): Use it. + (mml-preview): Added MIME preview to gnus-buffers. + +2003-12-30 Jesper Harder <[email protected]> + + * gnus-sum.el (gnus-summary-make-menu-bar): Add ellipses. + +2003-12-30 Lars Magne Ingebrigtsen <[email protected]> + + * gnus-start.el (gnus-get-unread-articles): Inline gnus-server-get-method. + (gnus-get-unread-articles): Cache methods. + (gnus-get-unread-articles-in-group): Indent. + + * gnus.el (gnus-version-number): Bump. + (gnus-secondary-method-p): Extend servers to methods before comparing. + (gnus-secondary-method-p): Revert. + 2003-12-30 Lars Magne Ingebrigtsen <[email protected]> * gnus.el: Gnus v5.10.3 is released. Index: gnus/lisp/gnus-art.el diff -u gnus/lisp/gnus-art.el:6.379 gnus/lisp/gnus-art.el:6.380 --- gnus/lisp/gnus-art.el:6.379 Tue Nov 25 13:06:18 2003 +++ gnus/lisp/gnus-art.el Tue Dec 30 22:22:43 2003 @@ -1273,12 +1273,12 @@ gnus-treat-from-picon) 'head nil) "Draw a boundary at the end of the headers. -Valid values are nil, t, `head', `last', an integer or a predicate. +Valid values are nil and `head'. See Info node `(gnus)Customizing Articles' for details." :version "21.1" :group 'gnus-article-treat :link '(custom-manual "(gnus)Customizing Articles") - :type gnus-article-treat-custom) + :type gnus-article-treat-head-custom) (defcustom gnus-treat-capitalize-sentences nil "Capitalize sentence-starting words. @@ -5742,7 +5742,8 @@ :type 'regexp) (defcustom gnus-button-mid-or-mail-regexp - (concat "\\b\\(<?[a-z0-9][^<>\")!;:,{}\n\t ]*@" + (concat "\\b\\(<?[a-z0-9$%(*-=?[_][^<>\")!;:,{}\n\t ]*@" + ;; Felix Wiemann in <[email protected]> gnus-button-valid-fqdn-regexp ">?\\)\\b") "Regular expression that matches a message ID or a mail address." @@ -6052,10 +6053,14 @@ 1 (>= gnus-button-message-level 0) gnus-button-fetch-group 5) ("\\b\\(nntp\\|news\\):\\(//\\)?\\([^'\">\n\t ]+\\)" 0 (>= gnus-button-message-level 0) gnus-button-fetch-group 3) + ;; RFC 2392 (Don't allow `/' in domain part --> CID) + ("\\bmid:\\(//\\)?\\([^'\">\n\t ]+@[^'\">\n\t /]+\\)" + 0 (>= gnus-button-message-level 0) gnus-button-message-id 2) ("\\bin\\( +article\\| +message\\)? +\\(<\\([^\n @<>]+@[^\n @<>]+\\)>\\)" 2 (>= gnus-button-message-level 0) gnus-button-message-id 3) ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 0 (>= gnus-button-message-level 0) gnus-url-mailto 2) + ;; RFC 2368 (The mailto URL scheme) ("mailto:\\([-a-z.@_+0-9%=?&]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) ("\\bmailto:\\([^ \n\t]+\\)" @@ -6115,6 +6120,8 @@ 0 (>= gnus-button-emacs-level 9) gnus-button-handle-symbol 1) ("(setq[ \t\n]+\\([a-z][a-z0-9]+-[-a-z0-9]+\\)[ \t\n]+.+)" 1 (>= gnus-button-emacs-level 7) gnus-button-handle-describe-variable 1) + ("\\bM-x[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET" + 1 (>= gnus-button-emacs-level 7) gnus-button-handle-describe-function 1) ("\\b\\(C-h\\|<?[Ff]1>?\\)[ \t\n]+f[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET" 0 (>= gnus-button-emacs-level 1) gnus-button-handle-describe-function 2) ("\\b\\(C-h\\|<?[Ff]1>?\\)[ \t\n]+v[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET" @@ -6123,8 +6130,14 @@ ;; Unlike the other regexps we really have to require quoting ;; here to determine where it ends. 1 (>= gnus-button-emacs-level 1) gnus-button-handle-describe-key 3) - ;; This is how URLs _should_ be embedded in text (RFC 1738)... + ;; This is how URLs _should_ be embedded in text (RFC 1738, RFC 2396)... ("<URL: *\\([^<>]*\\)>" + 1 (>= gnus-button-browse-level 0) gnus-button-embedded-url 1) + ;; RFC 2396 (2.4.3., delims) ... + ("\"URL: *\\([^\"]*\\)\"" + 1 (>= gnus-button-browse-level 0) gnus-button-embedded-url 1) + ;; RFC 2396 (2.4.3., delims) ... + ("\"URL: *\\([^\"]*\\)\"" 1 (>= gnus-button-browse-level 0) gnus-button-embedded-url 1) ;; Raw URLs. (gnus-button-url-regexp Index: gnus/lisp/gnus-dired.el diff -u gnus/lisp/gnus-dired.el:6.6 gnus/lisp/gnus-dired.el:6.7 --- gnus/lisp/gnus-dired.el:6.6 Thu May 1 16:23:14 2003 +++ gnus/lisp/gnus-dired.el Fri Jan 2 22:42:24 2004 @@ -58,9 +58,9 @@ (setq gnus-dired-mode-map (make-sparse-keymap)) (gnus-define-keys gnus-dired-mode-map - "\C-c\C-a" gnus-dired-attach - "\C-c\C-l" gnus-dired-find-file-mailcap - "\C-cP" gnus-dired-print)) + "\C-c\C-m\C-a" gnus-dired-attach + "\C-c\C-m\C-l" gnus-dired-find-file-mailcap + "\C-c\C-m\C-p" gnus-dired-print)) (defun gnus-dired-mode (&optional arg) "Minor mode for intersections of gnus and dired. Index: gnus/lisp/gnus-group.el diff -u gnus/lisp/gnus-group.el:6.121 gnus/lisp/gnus-group.el:6.126 --- gnus/lisp/gnus-group.el:6.121 Sat Nov 29 11:38:58 2003 +++ gnus/lisp/gnus-group.el Wed Dec 31 03:43:18 2003 @@ -528,207 +528,207 @@ (put 'gnus-group-mode 'mode-class 'special) -(when t - (gnus-define-keys gnus-group-mode-map - " " gnus-group-read-group - "=" gnus-group-select-group - "\r" gnus-group-select-group - "\M-\r" gnus-group-quick-select-group - "\M- " gnus-group-visible-select-group - [(meta control return)] gnus-group-select-group-ephemerally - "j" gnus-group-jump-to-group - "n" gnus-group-next-unread-group - "p" gnus-group-prev-unread-group - "\177" gnus-group-prev-unread-group - [delete] gnus-group-prev-unread-group - [backspace] gnus-group-prev-unread-group - "N" gnus-group-next-group - "P" gnus-group-prev-group - "\M-n" gnus-group-next-unread-group-same-level - "\M-p" gnus-group-prev-unread-group-same-level - "," gnus-group-best-unread-group - "." gnus-group-first-unread-group - "u" gnus-group-unsubscribe-current-group - "U" gnus-group-unsubscribe-group - "c" gnus-group-catchup-current - "C" gnus-group-catchup-current-all - "\M-c" gnus-group-clear-data - "l" gnus-group-list-groups - "L" gnus-group-list-all-groups - "m" gnus-group-mail - "i" gnus-group-news - "g" gnus-group-get-new-news - "\M-g" gnus-group-get-new-news-this-group - "R" gnus-group-restart - "r" gnus-group-read-init-file - "B" gnus-group-browse-foreign-server - "b" gnus-group-check-bogus-groups - "F" gnus-group-find-new-groups - "\C-c\C-d" gnus-group-describe-group - "\M-d" gnus-group-describe-all-groups - "\C-c\C-a" gnus-group-apropos - "\C-c\M-\C-a" gnus-group-description-apropos - "a" gnus-group-post-news - "\ek" gnus-group-edit-local-kill - "\eK" gnus-group-edit-global-kill - "\C-k" gnus-group-kill-group - "\C-y" gnus-group-yank-group - "\C-w" gnus-group-kill-region - "\C-x\C-t" gnus-group-transpose-groups - "\C-c\C-l" gnus-group-list-killed - "\C-c\C-x" gnus-group-expire-articles - "\C-c\M-\C-x" gnus-group-expire-all-groups - "V" gnus-version - "s" gnus-group-save-newsrc - "z" gnus-group-suspend - "q" gnus-group-exit - "Q" gnus-group-quit - "?" gnus-group-describe-briefly - "\C-c\C-i" gnus-info-find-node - "\M-e" gnus-group-edit-group-method - "^" gnus-group-enter-server-mode - gnus-mouse-2 gnus-mouse-pick-group - "<" beginning-of-buffer - ">" end-of-buffer - "\C-c\C-b" gnus-bug - "\C-c\C-s" gnus-group-sort-groups - "t" gnus-topic-mode - "\C-c\M-g" gnus-activate-all-groups - "\M-&" gnus-group-universal-argument - "#" gnus-group-mark-group - "\M-#" gnus-group-unmark-group) - - (gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map) - "m" gnus-group-mark-group - "u" gnus-group-unmark-group - "w" gnus-group-mark-region - "b" gnus-group-mark-buffer - "r" gnus-group-mark-regexp - "U" gnus-group-unmark-all-groups) - - (gnus-define-keys (gnus-group-sieve-map "D" gnus-group-mode-map) - "u" gnus-sieve-update - "g" gnus-sieve-generate) - - (gnus-define-keys (gnus-group-group-map "G" gnus-group-mode-map) - "d" gnus-group-make-directory-group - "h" gnus-group-make-help-group - "u" gnus-group-make-useful-group - "a" gnus-group-make-archive-group - "k" gnus-group-make-kiboze-group - "l" gnus-group-nnimap-edit-acl - "m" gnus-group-make-group - "E" gnus-group-edit-group - "e" gnus-group-edit-group-method - "p" gnus-group-edit-group-parameters - "v" gnus-group-add-to-virtual - "V" gnus-group-make-empty-virtual - "D" gnus-group-enter-directory - "f" gnus-group-make-doc-group - "w" gnus-group-make-web-group - "r" gnus-group-rename-group - "R" gnus-group-make-rss-group - "c" gnus-group-customize - "x" gnus-group-nnimap-expunge - "\177" gnus-group-delete-group - [delete] gnus-group-delete-group) - - (gnus-define-keys (gnus-group-soup-map "s" gnus-group-group-map) - "b" gnus-group-brew-soup - "w" gnus-soup-save-areas - "s" gnus-soup-send-replies - "p" gnus-soup-pack-packet - "r" nnsoup-pack-replies) - - (gnus-define-keys (gnus-group-sort-map "S" gnus-group-group-map) - "s" gnus-group-sort-groups - "a" gnus-group-sort-groups-by-alphabet - "u" gnus-group-sort-groups-by-unread - "l" gnus-group-sort-groups-by-level - "v" gnus-group-sort-groups-by-score - "r" gnus-group-sort-groups-by-rank - "m" gnus-group-sort-groups-by-method - "n" gnus-group-sort-groups-by-real-name) - - (gnus-define-keys (gnus-group-sort-selected-map "P" gnus-group-group-map) - "s" gnus-group-sort-selected-groups - "a" gnus-group-sort-selected-groups-by-alphabet - "u" gnus-group-sort-selected-groups-by-unread - "l" gnus-group-sort-selected-groups-by-level - "v" gnus-group-sort-selected-groups-by-score - "r" gnus-group-sort-selected-groups-by-rank - "m" gnus-group-sort-selected-groups-by-method - "n" gnus-group-sort-selected-groups-by-real-name) - - (gnus-define-keys (gnus-group-list-map "A" gnus-group-mode-map) - "k" gnus-group-list-killed - "z" gnus-group-list-zombies - "s" gnus-group-list-groups - "u" gnus-group-list-all-groups - "A" gnus-group-list-active - "a" gnus-group-apropos - "d" gnus-group-description-apropos - "m" gnus-group-list-matching - "M" gnus-group-list-all-matching - "l" gnus-group-list-level - "c" gnus-group-list-cached - "?" gnus-group-list-dormant) - - (gnus-define-keys (gnus-group-list-limit-map "/" gnus-group-list-map) - "k" gnus-group-list-limit - "z" gnus-group-list-limit - "s" gnus-group-list-limit - "u" gnus-group-list-limit - "A" gnus-group-list-limit - "m" gnus-group-list-limit - "M" gnus-group-list-limit - "l" gnus-group-list-limit - "c" gnus-group-list-limit - "?" gnus-group-list-limit) - - (gnus-define-keys (gnus-group-list-flush-map "f" gnus-group-list-map) - "k" gnus-group-list-flush - "z" gnus-group-list-flush - "s" gnus-group-list-flush - "u" gnus-group-list-flush - "A" gnus-group-list-flush - "m" gnus-group-list-flush - "M" gnus-group-list-flush - "l" gnus-group-list-flush - "c" gnus-group-list-flush - "?" gnus-group-list-flush) - - (gnus-define-keys (gnus-group-list-plus-map "p" gnus-group-list-map) - "k" gnus-group-list-plus - "z" gnus-group-list-plus - "s" gnus-group-list-plus - "u" gnus-group-list-plus - "A" gnus-group-list-plus - "m" gnus-group-list-plus - "M" gnus-group-list-plus - "l" gnus-group-list-plus - "c" gnus-group-list-plus - "?" gnus-group-list-plus) - - (gnus-define-keys (gnus-group-score-map "W" gnus-group-mode-map) - "f" gnus-score-flush-cache) - - (gnus-define-keys (gnus-group-help-map "H" gnus-group-mode-map) - "c" gnus-group-fetch-charter - "C" gnus-group-fetch-control - "d" gnus-group-describe-group - "f" gnus-group-fetch-faq - "v" gnus-version) - - (gnus-define-keys (gnus-group-sub-map "S" gnus-group-mode-map) - "l" gnus-group-set-current-level - "t" gnus-group-unsubscribe-current-group - "s" gnus-group-unsubscribe-group - "k" gnus-group-kill-group - "y" gnus-group-yank-group - "w" gnus-group-kill-region - "\C-k" gnus-group-kill-level - "z" gnus-group-kill-all-zombies)) +(gnus-define-keys gnus-group-mode-map + " " gnus-group-read-group + "=" gnus-group-select-group + "\r" gnus-group-select-group + "\M-\r" gnus-group-quick-select-group + "\M- " gnus-group-visible-select-group + [(meta control return)] gnus-group-select-group-ephemerally + "j" gnus-group-jump-to-group + "n" gnus-group-next-unread-group + "p" gnus-group-prev-unread-group + "\177" gnus-group-prev-unread-group + [delete] gnus-group-prev-unread-group + [backspace] gnus-group-prev-unread-group + "N" gnus-group-next-group + "P" gnus-group-prev-group + "\M-n" gnus-group-next-unread-group-same-level + "\M-p" gnus-group-prev-unread-group-same-level + "," gnus-group-best-unread-group + "." gnus-group-first-unread-group + "u" gnus-group-unsubscribe-current-group + "U" gnus-group-unsubscribe-group + "c" gnus-group-catchup-current + "C" gnus-group-catchup-current-all + "\M-c" gnus-group-clear-data + "l" gnus-group-list-groups + "L" gnus-group-list-all-groups + "m" gnus-group-mail + "i" gnus-group-news + "g" gnus-group-get-new-news + "\M-g" gnus-group-get-new-news-this-group + "R" gnus-group-restart + "r" gnus-group-read-init-file + "B" gnus-group-browse-foreign-server + "b" gnus-group-check-bogus-groups + "F" gnus-group-find-new-groups + "\C-c\C-d" gnus-group-describe-group + "\M-d" gnus-group-describe-all-groups + "\C-c\C-a" gnus-group-apropos + "\C-c\M-\C-a" gnus-group-description-apropos + "a" gnus-group-post-news + "\ek" gnus-group-edit-local-kill + "\eK" gnus-group-edit-global-kill + "\C-k" gnus-group-kill-group + "\C-y" gnus-group-yank-group + "\C-w" gnus-group-kill-region + "\C-x\C-t" gnus-group-transpose-groups + "\C-c\C-l" gnus-group-list-killed + "\C-c\C-x" gnus-group-expire-articles + "\C-c\M-\C-x" gnus-group-expire-all-groups + "V" gnus-version + "s" gnus-group-save-newsrc + "z" gnus-group-suspend + "q" gnus-group-exit + "Q" gnus-group-quit + "?" gnus-group-describe-briefly + "\C-c\C-i" gnus-info-find-node + "\M-e" gnus-group-edit-group-method + "^" gnus-group-enter-server-mode + gnus-mouse-2 gnus-mouse-pick-group + "<" beginning-of-buffer + ">" end-of-buffer + "\C-c\C-b" gnus-bug + "\C-c\C-s" gnus-group-sort-groups + "t" gnus-topic-mode + "\C-c\M-g" gnus-activate-all-groups + "\M-&" gnus-group-universal-argument + "#" gnus-group-mark-group + "\M-#" gnus-group-unmark-group) + +(gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map) + "m" gnus-group-mark-group + "u" gnus-group-unmark-group + "w" gnus-group-mark-region + "b" gnus-group-mark-buffer + "r" gnus-group-mark-regexp + "U" gnus-group-unmark-all-groups) + +(gnus-define-keys (gnus-group-sieve-map "D" gnus-group-mode-map) + "u" gnus-sieve-update + "g" gnus-sieve-generate) + +(gnus-define-keys (gnus-group-group-map "G" gnus-group-mode-map) + "d" gnus-group-make-directory-group + "h" gnus-group-make-help-group + "u" gnus-group-make-useful-group + "a" gnus-group-make-archive-group + "k" gnus-group-make-kiboze-group + "l" gnus-group-nnimap-edit-acl + "m" gnus-group-make-group + "E" gnus-group-edit-group + "e" gnus-group-edit-group-method + "p" gnus-group-edit-group-parameters + "v" gnus-group-add-to-virtual + "V" gnus-group-make-empty-virtual + "D" gnus-group-enter-directory + "f" gnus-group-make-doc-group + "w" gnus-group-make-web-group + "M" gnus-group-read-ephemeral-group + "r" gnus-group-rename-group + "R" gnus-group-make-rss-group + "c" gnus-group-customize + "x" gnus-group-nnimap-expunge + "\177" gnus-group-delete-group + [delete] gnus-group-delete-group) + +(gnus-define-keys (gnus-group-soup-map "s" gnus-group-group-map) + "b" gnus-group-brew-soup + "w" gnus-soup-save-areas + "s" gnus-soup-send-replies + "p" gnus-soup-pack-packet + "r" nnsoup-pack-replies) + +(gnus-define-keys (gnus-group-sort-map "S" gnus-group-group-map) + "s" gnus-group-sort-groups + "a" gnus-group-sort-groups-by-alphabet + "u" gnus-group-sort-groups-by-unread + "l" gnus-group-sort-groups-by-level + "v" gnus-group-sort-groups-by-score + "r" gnus-group-sort-groups-by-rank + "m" gnus-group-sort-groups-by-method + "n" gnus-group-sort-groups-by-real-name) + +(gnus-define-keys (gnus-group-sort-selected-map "P" gnus-group-group-map) + "s" gnus-group-sort-selected-groups + "a" gnus-group-sort-selected-groups-by-alphabet + "u" gnus-group-sort-selected-groups-by-unread + "l" gnus-group-sort-selected-groups-by-level + "v" gnus-group-sort-selected-groups-by-score + "r" gnus-group-sort-selected-groups-by-rank + "m" gnus-group-sort-selected-groups-by-method + "n" gnus-group-sort-selected-groups-by-real-name) + +(gnus-define-keys (gnus-group-list-map "A" gnus-group-mode-map) + "k" gnus-group-list-killed + "z" gnus-group-list-zombies + "s" gnus-group-list-groups + "u" gnus-group-list-all-groups + "A" gnus-group-list-active + "a" gnus-group-apropos + "d" gnus-group-description-apropos + "m" gnus-group-list-matching + "M" gnus-group-list-all-matching + "l" gnus-group-list-level + "c" gnus-group-list-cached + "?" gnus-group-list-dormant) + +(gnus-define-keys (gnus-group-list-limit-map "/" gnus-group-list-map) + "k" gnus-group-list-limit + "z" gnus-group-list-limit + "s" gnus-group-list-limit + "u" gnus-group-list-limit + "A" gnus-group-list-limit + "m" gnus-group-list-limit + "M" gnus-group-list-limit + "l" gnus-group-list-limit + "c" gnus-group-list-limit + "?" gnus-group-list-limit) + +(gnus-define-keys (gnus-group-list-flush-map "f" gnus-group-list-map) + "k" gnus-group-list-flush + "z" gnus-group-list-flush + "s" gnus-group-list-flush + "u" gnus-group-list-flush + "A" gnus-group-list-flush + "m" gnus-group-list-flush + "M" gnus-group-list-flush + "l" gnus-group-list-flush + "c" gnus-group-list-flush + "?" gnus-group-list-flush) + +(gnus-define-keys (gnus-group-list-plus-map "p" gnus-group-list-map) + "k" gnus-group-list-plus + "z" gnus-group-list-plus + "s" gnus-group-list-plus + "u" gnus-group-list-plus + "A" gnus-group-list-plus + "m" gnus-group-list-plus + "M" gnus-group-list-plus + "l" gnus-group-list-plus + "c" gnus-group-list-plus + "?" gnus-group-list-plus) + +(gnus-define-keys (gnus-group-score-map "W" gnus-group-mode-map) + "f" gnus-score-flush-cache) + +(gnus-define-keys (gnus-group-help-map "H" gnus-group-mode-map) + "c" gnus-group-fetch-charter + "C" gnus-group-fetch-control + "d" gnus-group-describe-group + "f" gnus-group-fetch-faq + "v" gnus-version) + +(gnus-define-keys (gnus-group-sub-map "S" gnus-group-mode-map) + "l" gnus-group-set-current-level + "t" gnus-group-unsubscribe-current-group + "s" gnus-group-unsubscribe-group + "k" gnus-group-kill-group + "y" gnus-group-yank-group + "w" gnus-group-kill-region + "\C-k" gnus-group-kill-level + "z" gnus-group-kill-all-zombies) (defun gnus-topic-mode-p () "Return non-nil in `gnus-topic-mode'." @@ -891,6 +891,7 @@ ["Make a kiboze group..." gnus-group-make-kiboze-group t] ["Make a virtual group..." gnus-group-make-empty-virtual t] ["Add a group to a virtual..." gnus-group-add-to-virtual t] + ["Make an ephemeral group..." gnus-group-read-ephemeral-group t] ["Make an RSS group..." gnus-group-make-rss-group t] ["Rename group..." gnus-group-rename-group (gnus-check-backend-function @@ -1464,7 +1465,7 @@ (active (gnus-active group)) (total (if active (1+ (- (cdr active) (car active))) 0)) (info (nth 2 entry)) - (method (gnus-server-get-method group (gnus-info-method info))) + (method (inline (gnus-server-get-method group (gnus-info-method info)))) (marked (gnus-info-marks info)) (mailp (apply 'append (mapcar @@ -1985,6 +1986,14 @@ If PARAMETERS, use those as the group parameters. Return the name of the group if selection was successful." + (interactive + (list + ;; (gnus-read-group "Group name: ") + (completing-read + "Group: " gnus-active-hashtb + nil nil nil + 'gnus-group-history) + (gnus-read-method "From method: "))) ;; Transform the select method into a unique server. (when (stringp method) (setq method (gnus-server-to-method method))) @@ -3208,15 +3217,18 @@ (interactive (list current-prefix-arg - (string-to-int - (let ((s (read-string - (format "Level (default %s): " - (or (gnus-group-group-level) - gnus-level-default-subscribed))))) - (if (string-match "^\\s-*$" s) - (int-to-string (or (gnus-group-group-level) - gnus-level-default-subscribed)) - s))))) + (progn + (unless (gnus-group-process-prefix current-prefix-arg) + (error "No group on the current line")) + (string-to-int + (let ((s (read-string + (format "Level (default %s): " + (or (gnus-group-group-level) + gnus-level-default-subscribed))))) + (if (string-match "^\\s-*$" s) + (int-to-string (or (gnus-group-group-level) + gnus-level-default-subscribed)) + s)))))) (unless (and (>= level 1) (<= level gnus-level-killed)) (error "Invalid level: %d" level)) (let ((groups (gnus-group-process-prefix n)) Index: gnus/lisp/gnus-logic.el diff -u gnus/lisp/gnus-logic.el:6.5 gnus/lisp/gnus-logic.el:6.6 --- gnus/lisp/gnus-logic.el:6.5 Fri Aug 2 13:04:37 2002 +++ gnus/lisp/gnus-logic.el Tue Dec 30 22:54:57 2003 @@ -77,6 +77,7 @@ gnus-newsgroup-scored) (when trace (push (cons "A file" rule) + ;; Must be synced with `gnus-score-edit-file-at-point'. gnus-score-trace))))))) (defun gnus-advanced-score-rule (rule) Index: gnus/lisp/gnus-nocem.el diff -u gnus/lisp/gnus-nocem.el:6.3 gnus/lisp/gnus-nocem.el:6.4 --- gnus/lisp/gnus-nocem.el:6.3 Sun Nov 17 23:35:39 2002 +++ gnus/lisp/gnus-nocem.el Fri Jan 2 21:12:56 2004 @@ -297,7 +297,8 @@ (while (search-forward "\t" nil t) (cond ((not (ignore-errors - (setq group (let ((obarray gnus-active-hashtb)) (read buf))))) + (setq group (let ((obarray gnus-nocem-real-group-hashtb)) + (read buf))))) ;; An error. ) ((not (symbolp group)) Index: gnus/lisp/gnus-score.el diff -u gnus/lisp/gnus-score.el:6.38 gnus/lisp/gnus-score.el:6.41 --- gnus/lisp/gnus-score.el:6.38 Mon Dec 22 12:39:05 2003 +++ gnus/lisp/gnus-score.el Tue Dec 30 22:54:57 2003 @@ -1106,21 +1106,38 @@ 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) - (let* ((string (ffap-string-at-point)) - ;; FIXME: Should be the full `match element', not just string at - ;; point. - file) - (save-excursion - (end-of-line) - (setq file (ffap-string-at-point))) - (gnus-score-edit-file file) - (unless (string= string file) - (goto-char (point-min)) - ;; Goto first match - (search-forward string nil t)))) +(defun gnus-score-edit-file-at-point (&optional format) + "Edit score file at point in Score Trace buffers. +If FORMAT, also format the current score file." + (let* ((rule (save-excursion + (beginning-of-line) + (read (current-buffer)))) + (sep "[ \n\r\t]*") + ;; Must be synced with `gnus-score-find-trace': + (reg " -> +") + (file (save-excursion + (end-of-line) + (if (and (re-search-backward reg (gnus-point-at-bol) t) + (re-search-forward reg (gnus-point-at-eol) t)) + (buffer-substring (point) (gnus-point-at-eol)) + nil)))) + (if (or (not file) + (string-match "\\<\\(non-file rule\\|A file\\)\\>" file) + ;; (see `gnus-score-find-trace' and `gnus-score-advanced') + (string= "" file)) + (gnus-error 3 "Can't find a score file in current line.") + (gnus-score-edit-file file) + (when format + (gnus-score-pretty-print)) + (when (consp rule) ;; the rule exists + (setq rule (mapconcat #'(lambda (obj) + (regexp-quote (format "%S" obj))) + rule + sep)) + (goto-char (point-min)) + (re-search-forward rule nil t) + ;; make it easy to use `kill-sexp': + (goto-char (1- (match-beginning 0))))))) (defun gnus-score-load-file (file) ;; Load score file FILE. Returns a list a retrieved score-alists. @@ -2354,7 +2371,10 @@ (let ((gnus-newsgroup-headers (list (gnus-summary-article-header))) (gnus-newsgroup-scored nil) - trace) + ;; Must be synced with `gnus-score-edit-file-at-point': + (frmt "%S [%s] -> %s\n") + trace + file) (save-excursion (nnheader-set-temp-buffer "*Score Trace*")) (setq gnus-score-trace nil) @@ -2364,18 +2384,44 @@ 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? + ;; Use a keymap instead? (local-set-key "q" (lambda () (interactive) (bury-buffer nil) (gnus-summary-expand-window))) - (local-set-key "e" 'gnus-score-edit-file-at-point) + (local-set-key "e" (lambda () + "Run `gnus-score-edit-file-at-point'." + (interactive) + (gnus-score-edit-file-at-point))) + (local-set-key "f" (lambda () + "Run `gnus-score-edit-file-at-point'." + (interactive) + (gnus-score-edit-file-at-point 'format))) + (local-set-key "t" 'toggle-truncate-lines) (setq truncate-lines t) - (while trace - (insert (format "%S -> %s\n" (cdar trace) - (or (caar trace) "(non-file rule)"))) - (setq trace (cdr trace))) + (dolist (entry trace) + (setq file (or (car entry) + ;; Must be synced with + ;; `gnus-score-edit-file-at-point': + "(non-file rule)")) + (insert + (format frmt + (cdr entry) + ;; Don't use `file-name-sans-extension' to see .SCORE and + ;; .ADAPT directly: + (file-name-nondirectory file) + (abbreviate-file-name file)))) + (insert + "\n\nQuick help: + +Type `e' to edit score file corresponding to the score rule on current line, +`f' to format (pretty print) the score file and edit it, +`t' toggle to truncate long lines in this buffer, +`q' to quit. + +The first sexp on each line is the score rule, followed by the file name of +the score file and its full name, including the directory.") (goto-char (point-min)) (gnus-configure-windows 'score-trace))) (set-buffer gnus-summary-buffer) Index: gnus/lisp/gnus-start.el diff -u gnus/lisp/gnus-start.el:6.86 gnus/lisp/gnus-start.el:6.87 --- gnus/lisp/gnus-start.el:6.86 Mon Dec 22 15:06:54 2003 +++ gnus/lisp/gnus-start.el Tue Dec 30 04:58:14 2003 @@ -1532,7 +1532,7 @@ ;; If the agent is enabled, we may have to alter the active info. (when (and gnus-agent info) (gnus-agent-possibly-alter-active - (gnus-info-group info) active)) + (gnus-info-group info) active)) ;; Modify the list of read articles according to what articles ;; are available; then tally the unread articles and add the @@ -1620,7 +1620,10 @@ gnus-activate-foreign-newsgroups) (t 0)) level)) - scanned-methods info group active method retrieve-groups) + (methods-cache nil) + (type-cache nil) + scanned-methods info group active method retrieve-groups cmethod + method-type) (gnus-message 6 "Checking new news...") (while newsrc @@ -1639,12 +1642,25 @@ ;; nil for non-foreign groups that the user has requested not be checked ;; t for unchecked foreign groups or bogus groups, or groups that can't ;; be checked, for one reason or other. - (if (and (setq method (gnus-info-method info)) - (not (inline - (gnus-server-equal - gnus-select-method - (setq method (gnus-server-get-method nil method))))) - (not (gnus-secondary-method-p method))) + (when (setq method (gnus-info-method info)) + (if (setq cmethod (assoc method methods-cache)) + (setq method (cdr cmethod)) + (setq cmethod (inline (gnus-server-get-method nil method))) + (push (cons method cmethod) methods-cache) + (setq method cmethod))) + (when (and method + (not (setq method-type (cdr (assoc method type-cache))))) + (setq method-type + (cond + ((gnus-secondary-method-p method) + 'secondary) + ((inline (gnus-server-equal gnus-select-method method)) + 'primary) + (t + 'foreign))) + (push (cons method method-type) type-cache)) + (if (and method + (eq method-type 'foreign)) ;; These groups are foreign. Check the level. (when (and (<= (gnus-info-level info) foreign-level) (setq active (gnus-activate-group group 'scan))) Index: gnus/lisp/gnus-sum.el diff -u gnus/lisp/gnus-sum.el:6.371 gnus/lisp/gnus-sum.el:6.373 --- gnus/lisp/gnus-sum.el:6.371 Mon Dec 8 15:17:35 2003 +++ gnus/lisp/gnus-sum.el Tue Dec 30 22:13:43 2003 @@ -2109,19 +2109,19 @@ :active (not (gnus-group-read-only-p)) ,@(if (featurep 'xemacs) nil '(:help "Encrypt the message body on disk"))] - ["Extract all parts" gnus-summary-save-parts t] + ["Extract all parts..." gnus-summary-save-parts t] ("Multipart" ["Repair multipart" gnus-summary-repair-multipart t] - ["Pipe part" gnus-article-pipe-part t] + ["Pipe part..." gnus-article-pipe-part t] ["Inline part" gnus-article-inline-part t] ["Encrypt body" gnus-article-encrypt-body :active (not (gnus-group-read-only-p)) ,@(if (featurep 'xemacs) nil '(:help "Encrypt the message body on disk"))] ["View part externally" gnus-article-view-part-externally t] - ["View part with charset" gnus-article-view-part-as-charset t] + ["View part with charset..." gnus-article-view-part-as-charset t] ["Copy part" gnus-article-copy-part t] - ["Save part" gnus-article-save-part t] + ["Save part..." gnus-article-save-part t] ["View part" gnus-article-view-part t])) ("Date" ["Local" gnus-article-date-local t] @@ -2201,20 +2201,20 @@ gnus-article-outlook-deuglify-article t]) ) ("Output" - ["Save in default format" gnus-summary-save-article + ["Save in default format..." gnus-summary-save-article ,@(if (featurep 'xemacs) '(t) '(:help "Save article using default method"))] - ["Save in file" gnus-summary-save-article-file + ["Save in file..." gnus-summary-save-article-file ,@(if (featurep 'xemacs) '(t) '(:help "Save article in file"))] - ["Save in Unix mail format" gnus-summary-save-article-mail t] - ["Save in MH folder" gnus-summary-save-article-folder t] - ["Save in VM folder" gnus-summary-save-article-vm t] - ["Save in RMAIL mbox" gnus-summary-save-article-rmail t] - ["Save body in file" gnus-summary-save-article-body-file t] - ["Pipe through a filter" gnus-summary-pipe-output t] + ["Save in Unix mail format..." gnus-summary-save-article-mail t] + ["Save in MH folder..." gnus-summary-save-article-folder t] + ["Save in VM folder..." gnus-summary-save-article-vm t] + ["Save in RMAIL mbox..." gnus-summary-save-article-rmail t] + ["Save body in file..." gnus-summary-save-article-body-file t] + ["Pipe through a filter..." gnus-summary-pipe-output t] ["Add to SOUP packet" gnus-soup-add-article t] - ["Print with Muttprint" gnus-summary-muttprint t] + ["Print with Muttprint..." gnus-summary-muttprint t] ["Print" gnus-summary-print-article t]) ("Backend" ["Respool article..." gnus-summary-respool-article t] @@ -2649,7 +2649,7 @@ respectively. You can also post articles and send mail from this buffer. To -follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author +follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author of an article, type `\\[gnus-summary-reply]'. There are approx. one gazillion commands you can execute in this @@ -7441,7 +7441,7 @@ t)) (prog1 (if (and (stringp article) - (string-match "@" article)) + (string-match "@\\|%40" article)) (gnus-summary-refer-article article) (when (stringp article) (setq article (string-to-number article))) @@ -8113,6 +8113,9 @@ (setq message-id (concat "<" message-id))) (unless (string-match ">$" message-id) (setq message-id (concat message-id ">"))) + ;; People often post MIDs from URLs, so unhex it: + (unless (string-match "@" message-id) + (setq message-id (gnus-url-unhex-string message-id))) (let* ((header (gnus-id-to-header message-id)) (sparse (and header (gnus-summary-article-sparse-p Index: gnus/lisp/gnus-util.el diff -u gnus/lisp/gnus-util.el:6.103 gnus/lisp/gnus-util.el:6.104 --- gnus/lisp/gnus-util.el:6.103 Mon Dec 8 10:01:47 2003 +++ gnus/lisp/gnus-util.el Tue Dec 30 20:19:36 2003 @@ -1453,6 +1453,7 @@ (defvar xemacs-codename)) (defun gnus-emacs-version () + "Stringified Emacs version." (let ((system-v (cond ((eq gnus-user-agent 'emacs-gnus-config) Index: gnus/lisp/gnus.el diff -u gnus/lisp/gnus.el:6.213 gnus/lisp/gnus.el:6.217 --- gnus/lisp/gnus.el:6.213 Mon Dec 29 16:16:00 2003 +++ gnus/lisp/gnus.el Fri Jan 2 23:02:04 2004 @@ -282,7 +282,7 @@ :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) -(defconst gnus-version-number "5.10.3" +(defconst gnus-version-number "5.10.4" "Version number for this version of Gnus.") (defconst gnus-version (format "Gnus v%s" gnus-version-number) @@ -339,7 +339,9 @@ (:type xbm :file "gnus-pointer.xbm" :ascent center)))) gnus-mode-line-image-cache) - 'help-echo "This is Gnus") + 'help-echo (format + "This is %s, %s." + gnus-version (gnus-emacs-version))) str) (list str)) line))) @@ -3490,10 +3492,10 @@ (defsubst gnus-secondary-method-p (method) "Return whether METHOD is a secondary select method." (let ((methods gnus-secondary-select-methods) - (gmethod (gnus-server-get-method nil method))) + (gmethod (inline (gnus-server-get-method nil method)))) (while (and methods (not (gnus-method-equal - (gnus-server-get-method nil (car methods)) + (inline (gnus-server-get-method nil (car methods))) gmethod))) (setq methods (cdr methods))) methods)) @@ -3904,21 +3906,19 @@ (cons (or default "") 0) 'gnus-group-history))) (let ((match (match-string 0 group))) - ;; `/' may be okay (e.g. for nnimap), so ask the user: - (unless (and (string-match "/" match) + ;; Might be okay (e.g. for nnimap), so ask the user: + (unless (and (not (string-match "^$\\|:" match)) (message-y-or-n-p "Proceed and create group anyway? " t "The group name \"" group "\" contains a forbidden character: \"" match "\". Usually, it's dangerous to create a group with this name, because it's not -supported by all back ends and servers. On some IMAP servers, it's valid to -use the character \"/\". - -If you are really sure, you can proceed anyway and create the group. +supported by all back ends and servers. On IMAP servers it should work, +though. If you are really sure, you can proceed anyway and create the group. You may customize the variable `gnus-invalid-group-regexp', which currently is set to \"" gnus-invalid-group-regexp -"\", if you want to get rid of this query.")) +"\", if you want to get rid of this query permanently.")) (setq prefix (format "Invalid group name: \"%s\". " group) group nil))))) group)) @@ -4058,7 +4058,7 @@ (defun gnus (&optional arg dont-connect slave) "Read network news. If ARG is non-nil and a positive number, Gnus will use that as the -startup level. If ARG is non-nil and not a positive number, Gnus will +startup level. If ARG is non-nil and not a positive number, Gnus will prompt the user for the name of an NNTP server to use." (interactive "P") (unless (byte-code-function-p (symbol-function 'gnus)) Index: gnus/lisp/message.el diff -u gnus/lisp/message.el:6.389 gnus/lisp/message.el:6.390 --- gnus/lisp/message.el:6.389 Sat Dec 20 19:13:22 2003 +++ gnus/lisp/message.el Wed Dec 31 04:03:44 2003 @@ -5149,7 +5149,6 @@ (error (split-line)))) - (defun message-fill-header (header value) (let ((begin (point)) (fill-column 78) Index: gnus/lisp/mml-sec.el diff -u gnus/lisp/mml-sec.el:1.25 gnus/lisp/mml-sec.el:1.26 --- gnus/lisp/mml-sec.el:1.25 Thu Jul 31 03:16:10 2003 +++ gnus/lisp/mml-sec.el Thu Jan 1 15:46:23 2004 @@ -1,5 +1,5 @@ ;;; mml-sec.el --- A package with security functions for MML documents -;; Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Simon Josefsson <[email protected]> @@ -40,8 +40,15 @@ ("pgpmime" mml-pgpmime-sign-buffer list)) "Alist of MIME signer functions.") -(defvar mml-default-sign-method (caar mml-sign-alist) - "Default sign method.") +(defcustom mml-default-sign-method "pgpmime" + "Default sign method. +The string must have an entry in `mml-sign-alist'." + :type '(choice (const "smime") + (const "pgp") + (const "pgpauto") + (const "pgpmime") + string) + :group 'message) (defvar mml-encrypt-alist '(("smime" mml-smime-encrypt-buffer mml-smime-encrypt-query) @@ -50,8 +57,15 @@ ("pgpmime" mml-pgpmime-encrypt-buffer list)) "Alist of MIME encryption functions.") -(defvar mml-default-encrypt-method (caar mml-encrypt-alist) - "Default encryption method.") +(defcustom mml-default-encrypt-method "pgpmime" + "Default encryption method. +The string must have an entry in `mml-encrypt-alist'." + :type '(choice (const "smime") + (const "pgp") + (const "pgpauto") + (const "pgpmime") + string) + :group 'message) (defcustom mml-signencrypt-style-alist '(("smime" separate) @@ -75,7 +89,7 @@ (string :tag "User defined")) (choice (const :tag "Separate" separate) (const :tag "Combined" combined))))) - + ;;; Configuration/helper functions (defun mml-signencrypt-style (method &optional style) Index: gnus/lisp/mml.el diff -u gnus/lisp/mml.el:6.85 gnus/lisp/mml.el:6.88 --- gnus/lisp/mml.el:6.85 Wed Dec 3 23:05:38 2003 +++ gnus/lisp/mml.el Wed Dec 31 04:12:43 2003 @@ -430,8 +430,7 @@ (+ (match-beginning 0) 3)))))) (cond ((eq (car cont) 'mml) - (let ((mml-boundary (funcall mml-boundary-function - (incf mml-multipart-number))) + (let ((mml-boundary (mml-compute-boundary cont)) (mml-generate-default-type "text/plain")) (mml-to-mime)) (let ((mm-7bit-chars (concat mm-7bit-chars "\x1b"))) @@ -936,6 +935,19 @@ (setq description nil)) description)) +(defun mml-minibuffer-read-disposition (type &optional default) + (let* ((default (or default + (if (string-match "^text/.*" type) + "inline" + "attachment"))) + (disposition (completing-read "Disposition: " + '(("attachment") ("inline") ("")) + nil + nil))) + (if (not (equal disposition "")) + disposition + default))) + (defun mml-quote-region (beg end) "Quote the MML tags in the region." (interactive "r") @@ -978,7 +990,7 @@ ;;; Attachment functions. -(defun mml-attach-file (file &optional type description) +(defun mml-attach-file (file &optional type description disposition) "Attach a file to the outgoing MIME message. The file is not inserted or encoded until you send the message with `\\[message-send-and-exit]' or `\\[message-send]'. @@ -989,10 +1001,14 @@ (interactive (let* ((file (mml-minibuffer-read-file "Attach file: ")) (type (mml-minibuffer-read-type file)) - (description (mml-minibuffer-read-description))) - (list file type description))) - (mml-insert-empty-tag 'part 'type type 'filename file - 'disposition "attachment" 'description description)) + (description (mml-minibuffer-read-description)) + (disposition (mml-minibuffer-read-disposition type))) + (list file type description disposition))) + (mml-insert-empty-tag 'part + 'type type + 'filename file + 'disposition (or disposition "attachment") + 'description description)) (defun mml-attach-buffer (buffer &optional type description) "Attach a buffer to the outgoing MIME message. @@ -1061,6 +1077,8 @@ (switch-to-buffer (generate-new-buffer (concat (if raw "*Raw MIME preview of " "*MIME preview of ") (buffer-name)))) + (when (boundp 'gnus-buffers) + (push (current-buffer) gnus-buffers)) (erase-buffer) (insert-buffer-substring buf) (mml-preview-insert-mail-followup-to) Index: gnus/lisp/mml2015.el diff -u gnus/lisp/mml2015.el:6.62 gnus/lisp/mml2015.el:6.63 --- gnus/lisp/mml2015.el:6.62 Fri May 2 19:55:28 2003 +++ gnus/lisp/mml2015.el Wed Dec 31 03:34:25 2003 @@ -277,8 +277,7 @@ (defun mml2015-mailcrypt-sign (cont) (mc-sign-generic (message-options-get 'message-sender) nil nil nil nil) - (let ((boundary - (funcall mml-boundary-function (incf mml-multipart-number))) + (let ((boundary (mml-compute-boundary cont)) hash point) (goto-char (point-min)) (unless (re-search-forward "^-----BEGIN PGP SIGNED MESSAGE-----\r?$" nil t) @@ -341,8 +340,7 @@ (goto-char (point-min)) (unless (looking-at "-----BEGIN PGP MESSAGE-----") (error "Fail to encrypt the message")) - (let ((boundary - (funcall mml-boundary-function (incf mml-multipart-number)))) + (let ((boundary (mml-compute-boundary cont))) (insert (format "Content-Type: multipart/encrypted; boundary=\"%s\";\n" boundary)) (insert "\tprotocol=\"application/pgp-encrypted\"\n\n") @@ -544,8 +542,7 @@ mm-security-handle 'gnus-info "Failed"))) (defun mml2015-gpg-sign (cont) - (let ((boundary - (funcall mml-boundary-function (incf mml-multipart-number))) + (let ((boundary (mml-compute-boundary cont)) (text (current-buffer)) signature) (goto-char (point-max)) (unless (bolp) @@ -578,8 +575,7 @@ (goto-char (point-max))))) (defun mml2015-gpg-encrypt (cont &optional sign) - (let ((boundary - (funcall mml-boundary-function (incf mml-multipart-number))) + (let ((boundary (mml-compute-boundary cont)) (text (current-buffer)) cipher) (mm-with-unibyte-current-buffer @@ -807,7 +803,7 @@ (defun mml2015-pgg-sign (cont) (let ((pgg-errors-buffer mml2015-result-buffer) - (boundary (funcall mml-boundary-function (incf mml-multipart-number))) + (boundary (mml-compute-boundary cont)) (pgg-default-user-id (or (message-options-get 'mml-sender) pgg-default-user-id))) (unless (pgg-sign-region (point-min) (point-max)) @@ -829,7 +825,7 @@ (defun mml2015-pgg-encrypt (cont &optional sign) (let ((pgg-errors-buffer mml2015-result-buffer) - (boundary (funcall mml-boundary-function (incf mml-multipart-number)))) + (boundary (mml-compute-boundary cont))) (unless (pgg-encrypt-region (point-min) (point-max) (split-string (or Index: gnus/lisp/nnml.el diff -u gnus/lisp/nnml.el:6.47 gnus/lisp/nnml.el:6.48 --- gnus/lisp/nnml.el:6.47 Wed Nov 12 21:54:36 2003 +++ gnus/lisp/nnml.el Fri Jan 2 18:50:29 2004 @@ -621,8 +621,12 @@ (defun nnml-save-mail (group-art) "Called narrowed to an article." - (let (chars headers) + (let (chars headers extension) (setq chars (nnmail-insert-lines)) + (setq extension + (and nnml-use-compressed-files + (> chars 1000) + ".gz")) (nnmail-insert-xref group-art) (run-hooks 'nnmail-prepare-save-mail-hook) (run-hooks 'nnml-prepare-save-mail-hook) @@ -637,7 +641,8 @@ (nnml-possibly-create-directory (caar ga)) (let ((file (concat (nnmail-group-pathname (caar ga) nnml-directory) - (int-to-string (cdar ga))))) + (int-to-string (cdar ga)) + extension))) (if first ;; It was already saved, so we just make a hard link. (funcall nnmail-crosspost-link-function first file t) Index: gnus/lisp/smime.el diff -u gnus/lisp/smime.el:6.31 gnus/lisp/smime.el:6.33 --- gnus/lisp/smime.el:6.31 Fri Jul 25 02:53:09 2003 +++ gnus/lisp/smime.el Fri Jan 2 21:24:37 2004 @@ -184,6 +184,27 @@ (const :tag "RC2 128 bits" "-rc2-128")) :group 'smime) +(defcustom smime-crl-check nil + "*Check revocation status of signers certificate using CRLs. +Enabling this will have OpenSSL check the signers certificate +against a certificate revocation list (CRL). + +For this to work the CRL must be up-to-date and since they are +normally updated quite often (ie. several times a day) you +probably need some tool to keep them up-to-date. Unfortunately +Gnus cannot do this for you. + +The CRL should either be appended (in PEM format) to your +`smime-CA-file' or be located in a file (also in PEM format) in +your `smime-certificate-directory' named to the X.509 hash of the +certificate with .r0 as file name extension. + +At least OpenSSL version 0.9.7 is required for this to work." + :type '(choice (const :tag "No check" nil) + (const :tag "Check certificate" "-crl_check") + (const :tag "Check certificate chain" "-crl_check_all")) + :group 'smime) + (defcustom smime-dns-server nil "*DNS server to query certificates from. If nil, use system defaults." @@ -348,6 +369,8 @@ (expand-file-name smime-CA-directory)))))) (unless CAs (error "No CA configured")) + (if smime-crl-check + (add-to-list 'CAs smime-crl-check)) (if (apply 'smime-call-openssl-region b e (list smime-details-buffer t) "smime" "-verify" "-out" "/dev/null" CAs) t Index: gnus/lisp/spam.el diff -u gnus/lisp/spam.el:6.142 gnus/lisp/spam.el:6.143 --- gnus/lisp/spam.el:6.142 Sun Dec 14 04:18:03 2003 +++ gnus/lisp/spam.el Fri Jan 2 17:00:42 2004 @@ -708,16 +708,12 @@ (defun spam-ham-copy-or-move-routine (copy groups) (gnus-summary-kill-process-mark) - (let ((articles gnus-newsgroup-articles) + (let ((todo (spam-list-articles gnus-newsgroup-articles 'ham)) (backend-supports-deletions (gnus-check-backend-function 'request-move-article gnus-newsgroup-name)) (respool-method (gnus-find-method-for-group gnus-newsgroup-name)) article mark todo deletep respool) - (dolist (article articles) - (when (spam-group-ham-mark-p gnus-newsgroup-name - (gnus-summary-article-mark article)) - (push article todo))) (when (member 'respool groups) (setq respool t) ; boolean for later @@ -1038,12 +1034,20 @@ (let ((mark-check (if (eq classification 'spam) 'spam-group-spam-mark-p 'spam-group-ham-mark-p)) - mark list) + list mark-cache-yes mark-cache-no) (dolist (article articles) - (when (funcall mark-check - gnus-newsgroup-name - (gnus-summary-article-mark article)) - (push article list))) + (let ((mark (gnus-summary-article-mark article))) + (unless (memq mark mark-cache-no) + (if (memq mark mark-cache-yes) + (push article list) + ;; else, we have to actually check the mark + (if (funcall mark-check + gnus-newsgroup-name + mark) + (progn + (push article list) + (push mark mark-cache-yes)) + (push mark mark-cache-no)))))) list)) (defun spam-register-routine (classification Index: gnus/texi/ChangeLog diff -u gnus/texi/ChangeLog:6.627 gnus/texi/ChangeLog:6.635 --- gnus/texi/ChangeLog:6.627 Tue Dec 30 02:27:36 2003 +++ gnus/texi/ChangeLog Fri Jan 2 21:47:04 2004 @@ -1,6 +1,55 @@ +2004-01-02 Teodor Zlatanov <[email protected]> + + * gnus.texi (Top): updated menu with new manual nodes + (The problem of spam): more ranting + (Anti-Spam Basics): "spammers are wise to [filtering on From:]" + (SpamAssassin): mention spam.el + (Hashcash): do not a sentence end proposition with + (Filtering Spam Using The Spam ELisp Package): more and better + explanation, took lots of information out into subsections + (Spam ELisp Package Sequence of Events) + (Spam ELisp Package Filtering of Incoming Mail) + (Spam ELisp Package Global Variables): new or updated content all + around + (Spam ELisp Package Configuration Examples): promised new + section, empty for now + (Blacklists and Whitelists, BBDB Whitelists) + (Gmane Spam Reporting, Bogofilter, spam-stat spam filtering) + (SpamOracle): mention that spam/ham processor variables are being + obsoleted + (Extending the Spam ELisp package): add some new documentation + for adding a new backend to spam.el + +2004-01-02 Reiner Steib <[email protected]> + + * gnus.texi (Foreign Groups): Add `gnus-group-read-ephemeral-group'. + (Oort Gnus): Ditto. + +2004-01-02 Lars Magne Ingebrigtsen <[email protected]> + + * message.texi (Key Index): Untabified. + + * gnus.texi (RSS): kindex. + +2003-12-30 Reiner Steib <[email protected]> + + * gnus.texi (Summary Score Commands): Add `f' to + `gnus-score-find-trace'. + (Score File Editing): Added `V t'. + +2003-12-31 Steve Youngs <[email protected]> + + * gnus.texi (XEmacs): Update list of Gnus XEmacs package + requirements. + +2003-12-30 Reiner Steib <[email protected]> + + * gnus.texi (Canceling and Superseding): Mention `Cancel-Lock'. + 2003-12-30 Lars Magne Ingebrigtsen <[email protected]> * gnus.texi (Maildir): Filled. + (Key Index): Untabified. 2003-12-29 Lars Magne Ingebrigtsen <[email protected]> Index: gnus/texi/gnus.texi diff -u gnus/texi/gnus.texi:6.588 gnus/texi/gnus.texi:6.596 --- gnus/texi/gnus.texi:6.588 Tue Dec 30 03:50:45 2003 +++ gnus/texi/gnus.texi Sat Jan 3 00:09:36 2004 @@ -33,7 +33,7 @@ \makeindex \begin{document} -\newcommand{\gnusversionname}{Gnus v5.10.3} +\newcommand{\gnusversionname}{Gnus v5.10.4} \newcommand{\gnuschaptername}{} \newcommand{\gnussectionname}{} @@ -397,7 +397,7 @@ spool or your mbox file. All at the same time, if you want to push your luck. -This manual corresponds to Gnus v5.10.3. +This manual corresponds to Gnus v5.10.4. @end ifinfo @@ -573,9 +573,12 @@ * Unread Articles:: Marks for unread articles. * Read Articles:: Marks for read articles. * Other Marks:: Marks that do not affect readedness. -* Setting Marks:: How to set and remove marks. -* Generic Marking Commands:: How to customize the marking. -* Setting Process Marks:: How to mark articles for later processing. + +Marking Articles + +* Setting Marks:: How to set and remove marks. +* Generic Marking Commands:: How to customize the marking. +* Setting Process Marks:: How to mark articles for later processing. Threading @@ -868,17 +871,21 @@ Filtering Spam Using The Spam ELisp Package -* Blacklists and Whitelists:: -* BBDB Whitelists:: -* Gmane Spam Reporting:: -* Anti-spam Hashcash Payments:: -* Blackholes:: -* Regular Expressions Header Matching:: -* Bogofilter:: -* ifile spam filtering:: -* spam-stat spam filtering:: -* SpamOracle:: -* Extending the spam elisp package:: +* Spam ELisp Package Sequence of Events:: +* Spam ELisp Package Filtering of Incoming Mail:: +* Spam ELisp Package Global Variables:: +* Spam ELisp Package Configuration Examples:: +* Blacklists and Whitelists:: +* BBDB Whitelists:: +* Gmane Spam Reporting:: +* Anti-spam Hashcash Payments:: +* Blackholes:: +* Regular Expressions Header Matching:: +* Bogofilter:: +* ifile spam filtering:: +* spam-stat spam filtering:: +* SpamOracle:: +* Extending the Spam ELisp package:: Filtering Spam Using Statistics with spam-stat @@ -896,7 +903,7 @@ * Troubleshooting:: What you might try if things do not work. * Gnus Reference Guide:: Rilly, rilly technical stuff. * Emacs for Heathens:: A short introduction to Emacsian terms. -* Frequently Asked Questions:: The Gnus FAQ. +* Frequently Asked Questions:: The Gnus FAQ History @@ -2532,6 +2539,12 @@ for a name, a method and possibly an @dfn{address}. For an easier way to subscribe to @acronym{NNTP} groups (@pxref{Browse Foreign Server}). +@item G M +@kindex G M (Group) +@findex gnus-group-read-ephemeral-group +Make an ephemeral group (@code{gnus-group-read-ephemeral-group}). Gnus +will prompt you for a name, a method and an @dfn{address}. + @item G r @kindex G r (Group) @findex gnus-group-rename-group @@ -5547,6 +5560,10 @@ want to use the standard posting method, use the @samp{a} symbolic prefix (@pxref{Symbolic Prefixes}). +Gnus ensures that only you can cancel your own messages using a +@code{Cancel-Lock} header (@pxref{Canceling News, Canceling News, , +message, Message Manual}). + If you discover that you have made some mistakes and want to do some corrections, you can post a @dfn{superseding} article that will replace your original article. @@ -15762,6 +15779,7 @@ @acronym{RSS} has a quite regular and nice interface, and it's possible to get the information Gnus needs to keep groups updated. +@kindex G R (Summary) Use @kbd{G R} from the summary buffer to subscribe to a feed---you will be prompted for the location of the feed. @@ -18659,9 +18677,9 @@ @findex gnus-score-find-trace Display all score rules that have been used on the current article (@code{gnus-score-find-trace}). In the @code{*Score Trace*} buffer, you -can use @kbd{q} to quit. @kbd{e} edits the corresponding score file. -When point is on a string within the match element, @kbd{e} will try to -bring you to this string in the score file. +may type @kbd{e} to edit score file corresponding to the score rule on +current line and @kbd{f} to format (@code{gnus-score-pretty-print}) the +score file and edit it. @item V w @kindex V w (Summary) @@ -19401,8 +19419,8 @@ @vindex gnus-score-mode-hook @code{gnus-score-menu-hook} is run in score mode buffers. -In the summary buffer you can use commands like @kbd{V f} and @kbd{V -e} to begin editing score files. +In the summary buffer you can use commands like @kbd{V f}, @kbd{V e} and +@kbd{V t} to begin editing score files. @node Adaptive Scoring @@ -22144,13 +22162,14 @@ First, some background on spam. If you have access to e-mail, you are familiar with spam (technically -termed @acronym{UCE}, Unsolicited Commercial E-mail). Simply put, it exists -because e-mail delivery is very cheap compared to paper mail, so only -a very small percentage of people need to respond to an UCE to make it -worthwhile to the advertiser. Ironically, one of the most common -spams is the one offering a database of e-mail addresses for further -spamming. Senders of spam are usually called @emph{spammers}, but terms like -@emph{vermin}, @emph{scum}, and @emph{morons} are in common use as well. +termed @acronym{UCE}, Unsolicited Commercial E-mail). Simply put, it +exists because e-mail delivery is very cheap compared to paper mail, +so only a very small percentage of people need to respond to an UCE to +make it worthwhile to the advertiser. Ironically, one of the most +common spams is the one offering a database of e-mail addresses for +further spamming. Senders of spam are usually called @emph{spammers}, +but terms like @emph{vermin}, @emph{scum}, @emph{sociopaths}, and +@emph{morons} are in common use as well. Spam comes from a wide variety of sources. It is simply impossible to dispose of all spam without discarding useful messages. A good @@ -22163,34 +22182,39 @@ requires its users to have a basic understanding of e-mail delivery and processing. -The simplest approach to filtering spam is filtering. If you get 200 -spam messages per day from @samp{random-address@@vmadmin.com}, you -block @samp{vmadmin.com}. If you get 200 messages about -@samp{VIAGRA}, you discard all messages with @samp{VIAGRA} in the -message. This, unfortunately, is a great way to discard legitimate -e-mail. For instance, the very informative and useful RISKS digest -has been blocked by overzealous mail filters because it -@strong{contained} words that were common in spam messages. -Nevertheless, in isolated cases, with great care, direct filtering of -mail can be useful. +The simplest approach to filtering spam is filtering, at the mail +server or when you sort through incoming mail. If you get 200 spam +messages per day from @samp{random-address@@vmadmin.com}, you block +@samp{vmadmin.com}. If you get 200 messages about @samp{VIAGRA}, you +discard all messages with @samp{VIAGRA} in the message. If you get +lots of spam from China, for example, you try to filter all mail from +Chinese IPs. + +This, unfortunately, is a great way to discard legitimate e-mail. For +instance, the very informative and useful RISKS digest has been +blocked by overzealous mail filters because it @strong{contained} +words that were common in spam messages. The risks of blocking a +whole country from contacting you should also be obvious, so don't do +it if you have the choice. Nevertheless, in isolated cases, with +great care, direct filtering of mail can be useful. Another approach to filtering e-mail is the distributed spam processing, for instance DCC implements such a system. In essence, @var{N} systems around the world agree that a machine @var{X} in -China, Ghana, or California is sending out spam e-mail, and these -@var{N} systems enter @var{X} or the spam e-mail from @var{X} into -a database. The criteria for spam detection vary---it may be the -number of messages sent, the content of the messages, and so on. When -a user of the distributed processing system wants to find out if a -message is spam, he consults one of those @var{N} systems. +Ghana, Estonia, or California is sending out spam e-mail, and these +@var{N} systems enter @var{X} or the spam e-mail from @var{X} into a +database. The criteria for spam detection vary---it may be the number +of messages sent, the content of the messages, and so on. When a user +of the distributed processing system wants to find out if a message is +spam, he consults one of those @var{N} systems. Distributed spam processing works very well against spammers that send a large number of messages at once, but it requires the user to set up fairly complicated checks. There are commercial and free distributed spam processing systems. Distributed spam processing has its risks as well. For instance legitimate e-mail senders have been accused of -sending spam, and their web sites have been shut down for some time -because of the incident. +sending spam, and their web sites and mailing lists have been shut +down for some time because of the incident. The statistical approach to spam filtering is also popular. It is based on a statistical analysis of previous spam messages. Usually @@ -22199,7 +22223,19 @@ analysis of spam works very well in most of the cases, but it can classify legitimate e-mail as spam in some cases. It takes time to run the analysis, the full message must be analyzed, and the user has -to store the database of spam analyses. +to store the database of spam analyses. Statistical analysis on the +server is gaining popularity. This has the advantage of letting the +user Just Read Mail, but has the disadvantage that it's harder to tell +the server that it has misclassified mail. + +Fighting spam is not easy, no matter what anyone says. There is no +magic switch that will distinguish Viagra ads from Mom's e-mails. +Even people are having a hard time telling spam apart from non-spam, +because spammers are actively looking to fool us into thinking they +are Mom, essentially. Spamming is irritating, irresponsible, and +idiotic behavior from a bunch of people who think the world owes them +a favor. We hope the following sections will help you in fighting the +spam plague. @node Anti-Spam Basics @subsection Anti-Spam Basics @@ -22265,6 +22301,7 @@ spam. It's a win-win situation. Forging @code{From} headers to point to non-existent domains is yucky, in my opinion. +Be careful with this approach. Spammers are wise to it. @node SpamAssassin @@ -22273,7 +22310,7 @@ @cindex Vipul's Razor @cindex DCC -The days where the hints in the previous section was sufficient in +The days where the hints in the previous section were sufficient in avoiding spam are coming to an end. There are many tools out there that claim to reduce the amount of spam you get. This section could easily become outdated fast, as new products replace old, but @@ -22281,6 +22318,11 @@ though this section will use SpamAssassin as an example, it should be easy to adapt it to most other tools. +Note that this section does not involve the @code{spam.el} package, +which is discussed in the next section. If you don't care for all +the features of @code{spam.el}, you can make do with these simple +recipes. + If the tool you are using is not installed on the mail server, you need to invoke it yourself. Ideas on how to use the @code{:postscript} mail source parameter (@pxref{Mail Source @@ -22362,7 +22404,7 @@ new form of spam appears. This means that a small percentage of spam will always get through. It also means that somewhere, someone needs to read lots of spam to update these tools. Hashcash avoids that, but -instead requires that everyone you communicate with supports the +instead prefers that everyone you contact through e-mail supports the scheme. You can view the two approaches as pragmatic vs dogmatic. The approaches have their own advantages and disadvantages, but as often in the real world, a combination of them is stronger than either @@ -22427,7 +22469,7 @@ The idea behind @file{spam.el} is to have a control center for spam detection and filtering in Gnus. To that end, @file{spam.el} does two things: it -filters incoming mail, and it analyzes mail known to be spam or ham. +filters new mail, and it analyzes mail known to be spam or ham. @dfn{Ham} is the name used throughout @file{spam.el} to indicate non-spam messages. @@ -22444,6 +22486,12 @@ So, what happens when you load @file{spam.el}? +First, some hooks will get installed by @code{spam-initialize}. There +are some hooks for @code{spam-stat} so it can save its databases, and +there are hooks so interesting things will happen when you enter and +leave a group. More on the sequence of events later (@pxref{Spam +ELisp Package Sequence of Events}). + You get the following keyboard commands: @table @kbd @@ -22479,6 +22527,225 @@ variables. Try @code{customize-group} on the @samp{spam} variable group. +@menu +* Spam ELisp Package Sequence of Events:: +* Spam ELisp Package Filtering of Incoming Mail:: +* Spam ELisp Package Global Variables:: +* Spam ELisp Package Configuration Examples:: +* Blacklists and Whitelists:: +* BBDB Whitelists:: +* Gmane Spam Reporting:: +* Anti-spam Hashcash Payments:: +* Blackholes:: +* Regular Expressions Header Matching:: +* Bogofilter:: +* ifile spam filtering:: +* spam-stat spam filtering:: +* SpamOracle:: +* Extending the Spam ELisp package:: +@end menu + +@node Spam ELisp Package Sequence of Events +@subsubsection Spam ELisp Package Sequence of Events +@cindex spam filtering +@cindex spam filtering sequence of events +@cindex spam + +You must read this section to understand how @code{spam.el} works. +Do not skip, speed-read, or glance through this section. + +There are two @emph{contact points}, if you will, between +@code{spam.el} and the rest of Gnus: checking new mail for spam, and +leaving a group. + +Getting new mail is done in one of two ways. You can either split +your incoming mail or you can classify new articles as ham or spam +when you enter the group. + +Splitting incoming mail is better suited to mail backends such as +@code{nnml} or @code{nnimap} where new mail appears in a single file +called a @dfn{Spool File}. See @xref{Spam ELisp Package Filtering of +Incoming Mail}. + +For backends such as @code{nntp} there is no incoming mail spool, so +an alternate mechanism must be used. This may also happen for +backends where the server is in charge of splitting incoming mail, and +Gnus does not do further splitting. The @code{spam-autodetect} and +@code{spam-autodetect-methods} group parameters (accessible with +@kbd{G c} and @kbd{G p} as usual), and the corresponding variables +@code{gnus-spam-autodetect-methods} and +@code{gnus-spam-autodetect-methods} (accessible with @kbd{M-x +customize-variable} as usual). + +When @code{spam-autodetect} is used, it hooks into the process of +entering a group. Thus, entering a group with unseen or unread +articles becomes the substitute for checking incoming mail. Whether +only unseen articles or all unread articles will be processed is +determined by the @code{spam-autodetect-recheck-messages}. When set +to t, unread messages will be rechecked. + +@code{spam-autodetect} grants the user at once more and less control +of spam filtering. The user will have more control over each group's +spam methods, so for instance the @samp{ding} group may have +@code{spam-use-BBDB} as the autodetection method, while the +@samp{suspect} group may have the @code{spam-use-blacklist} and +@code{spam-use-bogofilter} methods enabled. Every article detected to +be spam will be marked with the spam mark @samp{$} and processed on +exit from the group as normal spam. The user has less control over +the @emph{sequence} of checks, as he might with @code{spam-split}. + +When the newly split mail goes into groups, or messages are +autodetected to be ham or spam, those groups must be exited (after +entering, if needed) for further spam processing to happen. It +matters whether the group is considered a ham group, a spam group, or +is unclassified, based on its @code{spam-content} parameter +(@pxref{Spam ELisp Package Global Variables}). Spam groups have the +additional characteristic that, when entered, any unseen or unread +articles (depending on the @code{spam-mark-only-unseen-as-spam} +variable) will be marked as spam. Thus, mail split into a spam group +gets automatically marked as spam when you enter the group. + +So, when you exit a group, the @code{spam-processors} are applied, if +any are set, and the processed mail is moved to the +@code{ham-process-destination} or the @code{spam-process-destination} +depending on the article's classification. If the +@code{ham-process-destination} or the @code{spam-process-destination}, +whichever is appropriate, are nil, the article is left in the current +group. + +If a spam is found in any group (this can be changed to only non-spam +groups with @code{spam-move-spam-nonspam-groups-only}), it is +processed by the active @code{spam-processors} (@pxref{Spam ELisp +Package Global Variables}) when the group is exited. Furthermore, the +spam is moved to the @code{spam-process-destination} (@pxref{Spam +ELisp Package Global Variables}) for further training or deletion. +You have to load the @code{gnus-registry.el} package and enable the +@code{spam-log-to-registry} variable if you want spam to be processed +no more than once. Thus, spam is detected and processed everywhere, +which is what most people want. + +If a ham mail is found in a ham group, as determineed by the +@code{ham-marks} parameter, it is processed as ham by the active ham +@code{spam-processor} when the group is exited. With the variables +@code{spam-process-ham-in-spam-groups} and +@code{spam-process-ham-in-nonham-groups} the behavior can be further +altered so ham found anywhere can be processed. You have to load the +@code{gnus-registry.el} package and enable the +@code{spam-log-to-registry} variable if you want ham to be processed +no more than once. Thus, ham is detected and processed only when +necessary, which is what most people want. More on this in +@xref{Spam ELisp Package Configuration Examples}. + +If all this seems confusing, don't worry. Soon it will be as natural +as typing Lisp one-liners on a neural interface... err, sorry, that's +50 years in the future yet. Just trust us, it's not so bad. + +@node Spam ELisp Package Filtering of Incoming Mail +@subsubsection Spam ELisp Package Filtering of Incoming Mail +@cindex spam filtering +@cindex spam filtering incoming mail +@cindex spam + +To use the @file{spam.el} facilities for incoming mail filtering, you +must add the following to your fancy split list +@code{nnmail-split-fancy} or @code{nnimap-split-fancy}: + +@example +(: spam-split) +@end example + +Note that the fancy split may be called @code{nnmail-split-fancy} or +@code{nnimap-split-fancy}, depending on whether you use the nnmail or +nnimap back ends to retrieve your mail. + +The @code{spam-split} function will process incoming mail and send the +mail considered to be spam into the group name given by the variable +@code{spam-split-group}. By default that group name is @samp{spam}, +but you can customize @code{spam-split-group}. Make sure the contents +of @code{spam-split-group} are an @emph{unqualified} group name, for +instance in an @code{nnimap} server @samp{your-server} the value +@samp{spam} will turn out to be @samp{nnimap+your-server:spam}. The +value @samp{nnimap+server:spam}, therefore, is wrong and will +actually give you the group +@samp{nnimap+your-server:nnimap+server:spam} which may or may not +work depending on your server's tolerance for strange group names. + +You can also give @code{spam-split} a parameter, +e.g. @samp{'spam-use-regex-headers} or @samp{"maybe-spam"}. Why is +this useful? + +Take these split rules (with @code{spam-use-regex-headers} and +@code{spam-use-blackholes} set): + +@example + nnimap-split-fancy '(| + (any "ding" "ding") + (: spam-split) + ;; default mailbox + "mail") +@end example + +Now, the problem is that you want all ding messages to make it to the +ding folder. But that will let obvious spam (for example, spam +detected by SpamAssassin, and @code{spam-use-regex-headers}) through, +when it's sent to the ding list. On the other hand, some messages to +the ding list are from a mail server in the blackhole list, so the +invocation of @code{spam-split} can't be before the ding rule. + +You can let SpamAssassin headers supersede ding rules, but all other +@code{spam-split} rules (including a second invocation of the +regex-headers check) will be after the ding rule: + +@example + nnimap-split-fancy '(| +;;; all spam detected by spam-use-regex-headers goes to "regex-spam" + (: spam-split "regex-spam" 'spam-use-regex-headers) + (any "ding" "ding") +;;; all other spam detected by spam-split goes to spam-split-group + (: spam-split) + ;; default mailbox + "mail") +@end example + +This lets you invoke specific @code{spam-split} checks depending on +your particular needs, and to target the results of those checks to a +particular spam group. You don't have to throw all mail into all the +spam tests. Another reason why this is nice is that messages to +mailing lists you have rules for don't have to have resource-intensive +blackhole checks performed on them. You could also specify different +spam checks for your nnmail split vs. your nnimap split. Go crazy. + +You should still have specific checks such as +@code{spam-use-regex-headers} set to @code{t}, even if you +specifically invoke @code{spam-split} with the check. The reason is +that when loading @file{spam.el}, some conditional loading is done +depending on what @code{spam-use-xyz} variables you have set. This +is usually not critical, though. + +@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 back end will only retrieve the +message headers. If you use @code{spam-check-bogofilter}, +@code{spam-check-ifile}, or @code{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 @acronym{IMAP} down, and +that is not an appropriate decision to make on behalf of the user. + +@xref{Splitting in IMAP}. + +@emph{TODO: spam.el needs to provide a uniform way of training all the +statistical databases. Some have that functionality built-in, others +don't.} + +@node Spam ELisp Package Global Variables +@subsubsection Spam ELisp Package Global Variables +@cindex spam filtering +@cindex spam filtering variables +@cindex spam variables +@cindex spam + @vindex gnus-spam-process-newsgroups The concepts of ham processors and spam processors are very important. Ham processors and spam processors for a group can be set with the @@ -22489,6 +22756,10 @@ processors take mail known to be spam and process it so similar spam will be detected later. +The format of the spam or ham processor entry used to be a symbol, +but now it is a cons cell. See the individual spam processor entries +for more information. + @vindex gnus-spam-newsgroup-contents Gnus learns from the spam you get. You have to collect your spam in one or more spam groups, and set or customize the variable @@ -22533,13 +22804,19 @@ @defvar ham-marks You can customize this group or topic parameter to be the list of marks you want to consider ham. By default, the list contains the -deleted, read, killed, kill-filed, and low-score marks. +deleted, read, killed, kill-filed, and low-score marks (the idea is +that these articles have been read, but are not spam). It can be +useful to also include the tick mark in the ham marks. It is not +recommended to make the unread mark a ham mark, because it normally +indicates a lack of classification. But you can do it, and we'll be +happy for you. @end defvar @defvar spam-marks You can customize this group or topic parameter to be the list of marks you want to consider spam. By default, the list contains only -the spam mark. +the spam mark. It is not recommended to change that, but you can if +you really want to. @end defvar When you leave @emph{any} group, regardless of its @@ -22562,11 +22839,15 @@ @code{customize-variable gnus-ham-process-destinations}). Each newsgroup specification has the format (REGEXP PROCESSOR) in a standard Lisp list, if you prefer to customize the variable manually. -The ultimate location is a group name. If the +The ultimate location is a group name or names. If the @code{ham-process-destination} parameter is not set, ham articles are left in place. If the @code{spam-mark-ham-unread-before-move-from-spam-group} parameter is -set, the ham articles are marked as unread before being moved. +set, the ham articles are marked as unread before being moved. + +Note that you can use multiples destinations per group or regular +expression! This enables you to send your ham to a regular mail +group and to a @emph{ham training} group. When you leave a @emph{ham} group, all ham-marked articles are sent to a ham processor, which will study these as non-spam samples. @@ -22592,125 +22873,51 @@ regular expressions matched with group names (it's easiest to customize this variable with @code{customize-variable gnus-spam-process-destinations}). Each newsgroup specification has -the repeated format (REGEXP PROCESSOR) and they are all in a standard -Lisp list, if you prefer to customize the variable manually. The -ultimate location is a group name. If the +the repeated format (REGEXP GROUP) and they are all in a standard Lisp +list, if you prefer to customize the variable manually. The ultimate +location is a group name or names. If the @code{spam-process-destination} parameter is not set, the spam -articles are only expired. +articles are only expired. The group name is fully qualified, meaning +that if you see @samp{nntp:servername} before the group name in the +group buffer then you need it here as well. + +Note that you can use multiples destinations per group or regular +expression! This enables you to send your spam to multiple @emph{spam +training} groups. + +@vindex spam-log-to-registry +The problem with processing ham and spam is that Gnus doesn't track +this processing by default. Enable the @code{spam-log-to-registry} +variable so @code{spam.el} will use @code{gnus-registry.el} to track +what articles have been processed, and avoid processing articles +multiple times. Keep in mind that if you limit the number of registry +entries, this won't work as well as it does without a limit. + +@vindex spam-mark-only-unseen-as-spam +Set this variable if you want only unseen articles in spam groups to +be marked as spam. By default, it is set. If you set it to nil, +unread articles will also be marked as spam. + +@vindex spam-mark-ham-unread-before-move-from-spam-group +Set this variable if you want ham to be unmarked before it is moved +out of the spam group. This is very useful when you use something +like the tick mark @samp{!} to mark ham - the article will be placed +in your ham-process-destination, unmarked as if it came fresh from +the mail server. + +@vindex spam-autodetect-recheck-messages +When autodetecting spam, this variable tells @code{spam.el} whether +only unseen articles or all unread articles should be checked for +spam. It is recommended that you leave it off. -To use the @file{spam.el} facilities for incoming mail filtering, you -must add the following to your fancy split list -@code{nnmail-split-fancy} or @code{nnimap-split-fancy}: - -@example -(: spam-split) -@end example - -Note that the fancy split may be called @code{nnmail-split-fancy} or -@code{nnimap-split-fancy}, depending on whether you use the nnmail or -nnimap back ends to retrieve your mail. - -The @code{spam-split} function will process incoming mail and send the -mail considered to be spam into the group name given by the variable -@code{spam-split-group}. By default that group name is @samp{spam}, -but you can customize @code{spam-split-group}. Make sure the contents -of @code{spam-split-group} are an @emph{unqualified} group name, for -instance in an @code{nnimap} server @samp{your-server} the value -@samp{spam} will turn out to be @samp{nnimap+your-server:spam}. The -value @samp{nnimap+server:spam}, therefore, is wrong and will -actually give you the group -@samp{nnimap+your-server:nnimap+server:spam} which may or may not -work depending on your server's tolerance for strange group names. - -You can also give @code{spam-split} a parameter, -e.g. @samp{'spam-use-regex-headers} or @samp{"maybe-spam"}. Why is -this useful? - -Take these split rules (with @code{spam-use-regex-headers} and -@code{spam-use-blackholes} set): - -@example - nnimap-split-fancy '(| - (any "ding" "ding") - (: spam-split) - ;; default mailbox - "mail") -@end example - -Now, the problem is that you want all ding messages to make it to the -ding folder. But that will let obvious spam (for example, spam -detected by SpamAssassin, and @code{spam-use-regex-headers}) through, -when it's sent to the ding list. On the other hand, some messages to -the ding list are from a mail server in the blackhole list, so the -invocation of @code{spam-split} can't be before the ding rule. - -You can let SpamAssassin headers supersede ding rules, but all other -@code{spam-split} rules (including a second invocation of the -regex-headers check) will be after the ding rule: - -@example - nnimap-split-fancy '(| -;;; all spam detected by spam-use-regex-headers goes to "regex-spam" - (: spam-split "regex-spam" 'spam-use-regex-headers) - (any "ding" "ding") -;;; all other spam detected by spam-split goes to spam-split-group - (: spam-split) - ;; default mailbox - "mail") -@end example - -Basically, this lets you invoke specific @code{spam-split} checks -depending on your particular needs, and to target the results of those -checks to a particular spam group. You don't have to throw all mail -into all the spam tests. Another reason why this is nice is that -messages to mailing lists you have rules for don't have to have -resource-intensive blackhole checks performed on them. You could also -specify different spam checks for your nnmail split vs. your nnimap -split. Go crazy. - -You still have to have specific checks such as -@code{spam-use-regex-headers} set to @code{t}, even if you specifically -invoke @code{spam-split} with the check. The reason is that when -loading @file{spam.el}, some conditional loading is done depending on -what @code{spam-use-xyz} variables you have set. - -@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 back end will only retrieve the -message headers. If you use @code{spam-check-bogofilter}, -@code{spam-check-ifile}, or @code{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 @acronym{IMAP} down, and -that is not an appropriate decision to make on behalf of the user. - -@xref{Splitting in IMAP}. - -@emph{TODO: Currently, spam.el only supports insertion of articles -into a back end. There is no way to tell spam.el that an article is no -longer spam or ham.} - -@emph{TODO: spam.el needs to provide a uniform way of training all the -statistical databases. Some have that functionality built-in, others -don't.} +@node Spam ELisp Package Configuration Examples +@subsubsection Spam ELisp Package Configuration Examples +@cindex spam filtering +@cindex spam filtering configuration examples +@cindex spam configuration examples +@cindex spam -The following are the methods you can use to control the behavior of -@code{spam-split} and their corresponding spam and ham processors: - -@menu -* Blacklists and Whitelists:: -* BBDB Whitelists:: -* Gmane Spam Reporting:: -* Anti-spam Hashcash Payments:: -* Blackholes:: -* Regular Expressions Header Matching:: -* Bogofilter:: -* ifile spam filtering:: -* spam-stat spam filtering:: -* SpamOracle:: -* Extending the spam elisp package:: -@end menu +@emph{TODO}: add configuration examples with explanations of daily usage @node Blacklists and Whitelists @subsubsection Blacklists and Whitelists @@ -22755,6 +22962,13 @@ added to a group's @code{spam-process} parameter, the senders of spam-marked articles will be added to the blacklist. +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-spam-exit-processor-blacklist}, it is recommended +that you use @code{'(spam spam-use-blacklist)}. Everything will work +the same way, we promise. + @end defvar @defvar gnus-group-ham-exit-processor-whitelist @@ -22767,6 +22981,13 @@ whitelist. Note that this ham processor has no effect in @emph{spam} or @emph{unclassified} groups. +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-ham-exit-processor-whitelist}, it is recommended +that you use @code{'(ham spam-use-whitelist)}. Everything will work +the same way, we promise. + @end defvar Blacklists are lists of regular expressions matching addresses you @@ -22826,6 +23047,13 @@ BBDB. Note that this ham processor has no effect in @emph{spam} or @emph{unclassified} groups. +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-ham-exit-processor-BBDB}, it is recommended +that you use @code{'(ham spam-use-BBDB)}. Everything will work +the same way, we promise. + @end defvar @node Gmane Spam Reporting @@ -22846,6 +23074,13 @@ Gmane can be found at @uref{http://gmane.org}. +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-spam-exit-processor-report-gmane}, it is recommended +that you use @code{'(spam spam-use-gmane)}. Everything will work the +same way, we promise. + @end defvar @defvar spam-report-gmane-use-article-number @@ -23007,6 +23242,13 @@ @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. + +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-spam-exit-processor-bogofilter}, it is recommended +that you use @code{'(spam spam-use-bogofilter)}. Everything will work +the same way, we promise. @end defvar @defvar gnus-group-ham-exit-processor-bogofilter @@ -23017,6 +23259,13 @@ 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. + +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-ham-exit-processor-bogofilter}, it is recommended +that you use @code{'(ham spam-use-bogofilter)}. Everything will work +the same way, we promise. @end defvar @defvar spam-bogofilter-database-directory @@ -23097,6 +23346,13 @@ @code{gnus-spam-process-newsgroups} variable. When this symbol is added to a group's @code{spam-process} parameter, the spam-marked articles will be added to the spam-stat database of spam messages. + +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-spam-exit-processor-stat}, it is recommended +that you use @code{'(spam spam-use-stat)}. Everything will work +the same way, we promise. @end defvar @defvar gnus-group-ham-exit-processor-stat @@ -23107,6 +23363,13 @@ articles in @emph{ham} groups will be added to the spam-stat database of non-spam messages. Note that this ham processor has no effect in @emph{spam} or @emph{unclassified} groups. + +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-ham-exit-processor-stat}, it is recommended +that you use @code{'(ham spam-use-stat)}. Everything will work +the same way, we promise. @end defvar This enables @file{spam.el} to cooperate with @file{spam-stat.el}. @@ -23192,6 +23455,13 @@ @code{gnus-spam-process-newsgroups} variable. When this symbol is added to a group's @code{spam-process} parameter, spam-marked articles will be sent to SpamOracle as spam samples. + +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-spam-exit-processor-spamoracle}, it is recommended +that you use @code{'(spam spam-use-spamoracle)}. Everything will work +the same way, we promise. @end defvar @defvar gnus-group-ham-exit-processor-spamoracle @@ -23202,25 +23472,32 @@ @emph{ham} groups will be sent to the SpamOracle as samples of ham messages. Note that this ham processor has no effect in @emph{spam} or @emph{unclassified} groups. + +@emph{WARNING} + +Instead of the obsolete +@code{gnus-group-ham-exit-processor-spamoracle}, it is recommended +that you use @code{'(ham spam-use-spamoracle)}. Everything will work +the same way, we promise. @end defvar -@emph{Example:} These are the Group Parameters of an group that has been +@emph{Example:} These are the Group Parameters of a group that has been classified as a ham group, meaning that it should only contain ham messages. @example ((spam-contents gnus-group-spam-classification-ham) - (spam-process - (gnus-group-spam-exit-processor-spamoracle))) + (spam-process ((ham spam-use-spamoracle) + (spam spam-use-spamoracle)))) @end example -For this group the @code{gnus-group-spam-exit-processor-spamoracle} is -installed. If the group contains spam message (e.g. because SpamOracle -has not had enough sample messages yet) and the user marks some -messages as spam messages, these messages will be processed by -@code{gnus-group-spam-exit-processor-spamoracle}. This processor sends -the messages to SpamOracle as new samples for spam. +For this group the @code{spam-use-spamoracle} is installed for both +ham and spam processing. If the group contains spam message +(e.g. because SpamOracle has not had enough sample messages yet) and +the user marks some messages as spam messages, these messages will be +processed by SpamOracle. The processor sends the messages to +SpamOracle as new samples for spam. -@node Extending the spam elisp package -@subsubsection Extending the spam elisp package +@node Extending the Spam ELisp package +@subsubsection Extending the Spam ELisp package @cindex spam filtering @cindex spam elisp package, extending @cindex extending the spam elisp package @@ -23240,16 +23517,37 @@ Add @example - (spam-use-blackbox . spam-check-blackbox) + (spam-use-blackbox . spam-check-blackbox) @end example to @code{spam-list-of-checks}. +Add +@example + (gnus-group-ham-exit-processor-blackbox ham spam-use-blackbox) + (gnus-group-spam-exit-processor-blackbox spam spam-use-blackbox) +@end example +to @code{spam-list-of-processors}. + +Add +@example + (spam-use-blackbox spam-blackbox-register-routine + nil + spam-blackbox-unregister-routine + nil) +@end example +to @code{spam-registration-functions}. Write the register/unregister +routines using the bogofilter register/unregister routines as a +start, or other restister/unregister routines more appropriate to +Blackbox. + @item functionality Write the @code{spam-check-blackbox} function. It should return -@samp{nil} or @code{spam-split-group}. See the existing -@code{spam-check-*} functions for examples of what you can do. +@samp{nil} or @code{spam-split-group}, observing the other +conventions. See the existing @code{spam-check-*} functions for +examples of what you can do, and stick to the template unless you +fully understand the reasons why you aren't. Make sure to add @code{spam-use-blackbox} to @code{spam-list-of-statistical-checks} if Blackbox is a statistical @@ -23267,48 +23565,40 @@ Note you don't have to provide a spam or a ham processor. Only provide them if Blackbox supports spam or ham processing. +Also, ham and spam processors are being phased out as single +variables. Instead the form @code{'(spam spam-use-blackbox)} or +@code{'(ham spam-use-blackbox)} is favored. For now, spam/ham +processor variables are still around but they won't be for long. + @lisp -(defvar gnus-group-spam-exit-processor-blackbox "blackbox" +(defvar gnus-group-spam-exit-processor-blackbox "blackbox-spam" "The Blackbox summary exit spam processor. Only applicable to spam groups.") -(defvar gnus-group-ham-exit-processor-blackbox "blackbox" +(defvar gnus-group-ham-exit-processor-blackbox "blackbox-ham" "The whitelist summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") @end lisp @item -functionality +Gnus parameters -@lisp -(defun spam-blackbox-register-spam-routine () - (spam-generic-register-routine - ;; @r{the spam function} - (lambda (article) - (let ((from (spam-fetch-field-from-fast article))) - (when (stringp from) - (blackbox-do-something-with-this-spammer from)))) - ;; @r{the ham function} - nil)) - -(defun spam-blackbox-register-ham-routine () - (spam-generic-register-routine - ;; @r{the spam function} - nil - ;; @r{the ham function} - (lambda (article) - (let ((from (spam-fetch-field-from-fast article))) - (when (stringp from) - (blackbox-do-something-with-this-ham-sender from)))))) -@end lisp - -Write the @code{blackbox-do-something-with-this-ham-sender} and -@code{blackbox-do-something-with-this-spammer} functions. You can add -more complex code than fetching the message sender, but keep in mind -that retrieving the whole message takes significantly longer than the -sender through @code{spam-fetch-field-from-fast}, because the message -senders are kept in memory by Gnus. +Add +@example + (const :tag "Spam: Blackbox" (spam spam-use-blackbox)) + (const :tag "Ham: Blackbox" (ham spam-use-blackbox)) +@end example +to the @code{spam-process} group parameter in @code{gnus.el}. Make +sure you do it twice, once for the parameter and once for the +variable customization. + +Add +@example + (variable-item spam-use-blackbox) +@end example +to the @code{spam-autodetect-methods} group parameter in +@code{gnus.el}. @end enumerate @@ -23451,7 +23741,7 @@ @lisp (setq nnmail-split-fancy `(| (: spam-stat-split-fancy) - "mail.misc")) + "mail.misc")) @end lisp @defvar spam-stat-split-fancy-spam-group @@ -23465,8 +23755,8 @@ @lisp (setq nnmail-split-fancy `(| ("Subject" "\\bspam-stat\\b" "mail.emacs") - (: spam-stat-split-fancy) - "mail.misc")) + (: spam-stat-split-fancy) + "mail.misc")) @end lisp If you want to filter for spam first, then you must be careful when @@ -23479,7 +23769,7 @@ (setq nnmail-split-fancy `(| (: spam-stat-split-fancy) ("Subject" "\\bspam-stat\\b" "mail.emacs") - "mail.misc")) + "mail.misc")) @end lisp You can combine this with traditional filtering. Here, we move all @@ -23492,9 +23782,9 @@ @lisp (setq nnmail-split-fancy `(| ("Content-Type" "text/html" "mail.spam.filtered") - (: spam-stat-split-fancy) + (: spam-stat-split-fancy) ("Subject" "\\bspam-stat\\b" "mail.emacs") - "mail.misc")) + "mail.misc")) @end lisp @@ -23749,10 +24039,10 @@ XEmacs is distributed as a collection of packages. You should install whatever packages the Gnus XEmacs package requires. The current -requirements are @samp{gnus}, @samp{w3}, @samp{mh-e}, -@samp{mailcrypt}, @samp{rmail}, @samp{eterm}, @samp{mail-lib}, -@samp{xemacs-base}, @samp{sh-script} and @samp{fsf-compat}. The -@samp{misc-games} package is required for Morse decoding. +requirements are @samp{gnus}, @samp{mail-lib}, @samp{xemacs-base}, +@samp{eterm}, @samp{sh-script}, @samp{net-utils}, @samp{os-utils}, +@samp{dired}, @samp{mh-e}, @samp{sieve}, @samp{ps-print}, @samp{w3}, +@samp{pgg}, @samp{mailcrypt}, @samp{ecrypto}, and @samp{sasl}. @node History @@ -25155,6 +25445,10 @@ @itemize @bullet @item +@code{gnus-group-read-ephemeral-group} can be called interactively, +using @kbd{G M}. + +@item In draft groups, @kbd{e} is now bound to @code{gnus-draft-edit-message}. Use @kbd{B w} for @code{gnus-summary-edit-article} instead. @@ -25356,10 +25650,10 @@ @lisp (setq gnus-parameters '(("mail\\..*" - (gnus-show-threads nil) - (gnus-use-scoring nil)) - ("^nnimap:\\(foo.bar\\)$" - (to-group . "\\1")))) + (gnus-show-threads nil) + (gnus-use-scoring nil)) + ("^nnimap:\\(foo.bar\\)$" + (to-group . "\\1")))) @end lisp @item @@ -25550,7 +25844,7 @@ The old format like the lines below is obsolete, but still accepted. @lisp (header "to" "larsi.*org" - (Organization "Somewhere, Inc.")) + (Organization "Somewhere, Inc.")) @end lisp @item @@ -26170,7 +26464,7 @@ @item Try doing an @kbd{M-x gnus-version}. If you get something that looks -like @samp{Gnus v5.10.3} you have the right files loaded. Otherwise +like @samp{Gnus v5.10.4} you have the right files loaded. Otherwise you have some old @file{.el} files lying around. Delete these. @item Index: gnus/texi/message.texi diff -u gnus/texi/message.texi:6.93 gnus/texi/message.texi:6.95 --- gnus/texi/message.texi:6.93 Tue Dec 30 03:50:45 2003 +++ gnus/texi/message.texi Sat Jan 3 00:09:37 2004 @@ -88,7 +88,7 @@ * Key Index:: List of Message mode keys. @end menu -This manual corresponds to Message v5.10.3. Message is distributed +This manual corresponds to Message v5.10.4. Message is distributed with the Gnus distribution bearing the same version number as this manual. @@ -1227,7 +1227,7 @@ @lisp (setq ispell-message-dictionary-alist '(("^Newsgroups:.*\\bde\\." . "deutsch8") - (".*" . "default"))) + (".*" . "default"))) @end lisp @code{ispell} depends on having the external @samp{ispell} command