From: yamaoka Date: Sun, 4 Jan 2004 23:52:57 +0000 (+0000) Subject: Feedback T-gnus 6.16. X-Git-Tag: branch-out-to-t-gnus-6_17- X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04ba5250e9e47ebe40860a0902d4ef6405ca143f;p=elisp%2Fgnus.git- Feedback T-gnus 6.16. --- diff --git a/ChangeLog b/ChangeLog index aacb375..ea338cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2821 +1,249 @@ -2003-05-01 Katsumi Yamaoka +2004-01-04 Katsumi Yamaoka - * lisp/gnus-vers.el: T-gnus 6.15.24 revision 00. + * lisp/gnus-vers.el: T-gnus 6.16.6 revision 00. -2003-05-01 Jesper Harder +2004-01-04 Katsumi Yamaoka - * etc/gnus-tut.txt (http): Update. + * lisp/gnus-vers.el: T-gnus 6.16.5 revision 00. -2003-05-01 Katsumi Yamaoka +2004-01-04 Katsumi Yamaoka - * lisp/gnus-vers.el: T-gnus 6.15.23 revision 00. + * lisp/gnus-vers.el: T-gnus 6.16.4 revision 00. -2003-05-01 Simon Josefsson +2004-01-03 Reiner Steib - * GNUS-NEWS: Add prefix limit feature. + * GNUS-NEWS: Update copyright. -2003-05-01 Katsumi Yamaoka + * etc/gnus-tut.txt (Gnus FAQ): Remove text version. Refer to info + documentation and online version instead. - * lisp/gnus-vers.el: T-gnus 6.15.22 revision 00. + * GNUS-NEWS: Changed "Dired integration" -2003-05-01 Katsumi Yamaoka +2004-01-02 Reiner Steib - * lisp/gnus-vers.el: T-gnus 6.15.20 revision 00. + * GNUS-NEWS: Add `gnus-group-read-ephemeral-group'. -2003-04-30 Reiner Steib +2003-12-30 Katsumi Yamaoka - * GNUS-NEWS: Added Article Buttons. Added Upgrading (from Simon - Josefsson). Add gnus-mime-delete-part, markup fixes and some - other corrections. Mention Gnus FAQ. + * lisp/gnus-vers.el: T-gnus 6.16.3 revision 00. -2003-04-30 Jesper Harder +2003-12-25 Katsumi Yamaoka - * GNUS-NEWS: Additions. + * lisp/pop3.el: Autoload `open-ssl-stream' when compiling. -2003-04-30 Katsumi Yamaoka +2003-12-23 Reiner Steib - * lisp/lpath.el: Bind `default-mime-charset-unlimited'. + * GNUS-NEWS: Mention change of `e' in draft groups. -2003-04-29 Katsumi Yamaoka +2003-12-17 Katsumi Yamaoka - * lisp/dgnushack.el: Autoload font-lock and nnheader for XEmacs - -no-autoloads. + * gnus-group.el (gnus-group-edit-group): Let the `C-c C-i' command + choose the language specific info file. - * lisp/pop3.el: Require `advice' for compiling it in Gnus. +2003-12-16 Katsumi Yamaoka -2003-04-28 Reiner Steib + * lisp/gnus-art.el: Require `mime-image' when Emacs is running on + the window system. - * GNUS-NEWS: Fixed X-Draft-Headers entry. + * lisp/gnus-sum.el: Don't require `mime-view'. -2003-04-28 Katsumi Yamaoka +2003-12-15 Katsumi Yamaoka - * lisp/dgnushack.el: Make sure `dolist' is available; require - `advice' before `path-util'; revoke the bogus change of 2003-04-17 - (removing function bindings for XEmacs). - (dgnushack-remove-extra-files-in-package): Clear the value for - `command-line-args-left'. - (dgnushack-install-package-manifest): Ditto. + * lisp/nnmail.el (nnmail-lazy): Replace `widget-default-get' with + the expanded form for Mule 2. - * texi/infohack.el: Load dgnushack.el and ptexinfmt.el first. +2003-12-01 Katsumi Yamaoka -2003-04-27 Simon Josefsson + * lisp/dgnushack.el (dgnushack-make-cus-load): Use + contrib/cus-dep.el to build T-gnus with Mule 2. - * GNUS-NEWS: Fix PGP entry. Doc GCC variable change. + * contrib/cus-dep.el: Imported from Emacs 20.7 for Mule 2. -2003-04-28 Katsumi Yamaoka +2003-11-03 ARISAWA Akihiro - * lisp/gnus-vers.el: T-gnus 6.15.19 revision 00. + * lisp/message.el (message-forward-subject-name-subject): Fixed. -2003-04-24 Katsumi Yamaoka +2003-10-27 Katsumi Yamaoka - * lisp/nnheader.el (nnheader-coding-system-p): New function. - (mm-coding-system-p): Alias to `nnheader-coding-system-p'. + * texi/infohack.el: Don't fiddle with the `features' variable; + fix directories relative to the ../lisp directory in `load-path'. -2003-04-23 Katsumi Yamaoka +2003-10-24 Katsumi Yamaoka - * lisp/gnus-clfns.el (coerce, copy-list, merge, string, subseq): - Comment out those compiler macros. - (mapc): Make it comeback. + * Makefile.in (install-package): Don't call `compose-package'. + (install-package-ja): Ditto. + (package): Ditto. + (package-ja): Ditto. + (compose-package): Abolish. -2003-04-22 Reiner Steib + * lisp/Makefile.in (compose-package): Abolish. - * make.bat: Flag as binary to ensure DOS line terminators. Delete - trailing whitespace. - -2003-04-21 Reiner Steib - From Frank Schmitt - - * etc/gnus-tut.txt: Update Gnus FAQ, delete trailing whitespace. - -2003-04-17 Katsumi Yamaoka - - * Makefile.in (xclever-package, xlick-package): New rules. - (install-package, install-package-ja, package, package-ja): Use - them. - (install-package-manifest, remove-extra-files-in-package, - compose-package): Specify the lisp directory for XEmacs package. - - * aclocal.m4 (AC_PATH_INFO_DIR): Say a note for XEmacs package. - - * lisp/dgnushack.el: Remove useless function bindings for XEmacs. - (dgnushack-install-package-manifest): Create the pkginfo directory. - - * lisp/lpath.el: Fbind `compare-strings' for Mule 2. - -2003-04-17 Kevin Greiner - - * make.bat: Cleaned up end-of-line characters. - -2003-04-17 Steve Youngs - - * Makefile.in (XEMACS): Use @EMACS@. - - * aclocal.m4 (AC_PATH_LISPDIR): Set $datadir to $prefix/lib if - building with XEmacs. - - * aclocal.m4 (AC_SET_BUILD_FLAGS): New. So we can set XEmacs - command line options to '-batch -no-autoloads...' for a cleaner - build environment. - - * configure.in: Use it. - - * configure: Regenerate. - -2003-04-16 Reiner Steib - From Frank Schmitt - - * make.bat: New variable EMACS_ARGS. Changed XEmacs args. - -2003-04-13 Katsumi Yamaoka - - * lisp/lpath.el: Fbind `coding-system-base' for Mule 2. - -2003-04-13 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.18 revision 00. - - * lisp/message.el (message-forward-subject-name-subject): Rewrite. - - * lisp/mail-source.el (mail-source-fetch-pop): Require `pop3' - explicitly. - (mail-source-check-pop): Ditto. - -2003-04-07 Katsumi Yamaoka - - * lisp/nnmail.el (nnmail-split-it): Revoke the change of 1999-08-19. - -2003-04-03 Katsumi Yamaoka - - * lisp/pop3.el (pop3-uidl-support): Default to nil; change the - meaning of a value which it may contain into an alist of servers - and flags of whether they support UIDLs. - (pop3-get-message-numbers): Don't check uidls when - `pop3-leave-mail-on-server' is nil; synch it with the change of - `pop3-uidl-support'. - (pop3-get-uidl): Synch it with the change of `pop3-uidl-support'. - -2003-03-31 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.17 revision 00. - -2003-03-24 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-x-face-command): Don't examine - functions if `noninteractive'. - (gnus-article-should-use-smiley-mule): Don't examine values if - `noninteractive'. - (gnus-treat-display-face): Default to nil if x-face-e21 is - available. - (gnus-treat-display-smileys): Don't examine values if - `noninteractive'. - - * lisp/message.el (message-yank-original): Check not only the - References field but the `message-reply-headers' variable. - - * lisp/imap.el (imap-tls-open): Don't bind coding-systems; use - `set-buffer-multibyte' instead of `imap-disable-multibyte'. - - * lisp/tls.el: Require `pces'. - (open-tls-stream): Use `as-binary-process'. - -2003-03-23 Simon Josefsson - - * GNUS-NEWS: Add IDNA. Add TLS. Fix USEFOR reference. - -2003-03-22 Frank Schmitt - - * make.bat: Redone from scratch; supports both Emacs and XEmacs - now; correctly generate gnus-load.el; check for errors; use - makeinfo if available, infohack.el if it isn't; be less verbose - when copying files; copy files from etc/gnus and etc/smilies, too - -2003-03-22 Frank Schmitt - - * make-x.bat: Removed, make.bat does its job now. - -2003-03-22 Frank Schmitt - - * etc/gnus-tut.txt: Include Gnus FAQ from http://my.gnus.org. - -2003-03-18 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.16 revision 00. - -2003-03-04 Katsumi Yamaoka - - * lisp/gnus-ofsetup.el: Don't require `read-passwd'; don't set - `mail-source-read-passwd' and `gnus-setup-news-hook'. - - * contrib/passwd.el: New file. - -2003-02-20 Katsumi Yamaoka - - * lisp/gnus-offline.el (gnus-offline-add-custom-header): Use - insert instead of insert-string which is obsolete in Emacs 21.4 - (synch to the change of Jesper Harder at 2003-02-20). - -2003-02-19 Reiner Steib - - * GNUS-NEWS: Renamed `gnus-unsightly-citation-regexp' to - `gnus-cite-unsightly-citation-regexp'. - -2003-02-18 Simon Josefsson - - * GNUS-NEWS: Talk about canlock more. - -2003-02-13 Kai Gro,A_(Bjohann - - * GNUS-NEWS: Add user visible changes from Michael Shields from - the past couple of days. Actual text from Michael. - -2003-02-09 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.15 revision 00. - -2003-01-25 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.14 revision 00. - -2003-01-24 Jesper Harder - - * etc/gnus-tut.txt: Update. - -2003-01-24 Katsumi Yamaoka - - * texi/infohack.el (infohack-texi-format): Withdraw the change of - 2003-01-17. - -2003-01-21 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.13 revision 00. - -2003-01-17 Katsumi Yamaoka - - * texi/infohack.el (infohack-texi-format): Insert one excessive - newline after a @foo{bar} thing to prevent clinging of a line and - a line (old texinfmt bug?) if it should be considered only one - thing in a line. - -2003-01-17 TSUCHIYA Masatoshi - - * .cvsignore: Import from Oort Gnus. - * contrib/.cvsignore: Ditto. - * etc/.cvsignore: Ditto. - * lisp/.cvsignore: Ditto. - * texi/.cvsignore: Ditto. - * texi/ps/.cvsignore: Ditto. - -2003-01-16 Katsumi Yamaoka - - * lisp/gnus-msg.el (gnus-summary-digest-mail-forward): Set article - numbers to be marked. - -2003-01-02 Lars Magne Ingebrigtsen - - (A forgotten thing to synchronize to Oort Gnus.) - * lisp/gnus-msg.el (gnus-summary-mail-forward): To many lists of - lists. - -2003-01-15 Simon Josefsson - - * GNUS-NEWS: Add. Fix from Reiner Steib - <4uce.02.r.steib@gmx.net>. - -2003-01-14 Katsumi Yamaoka - - * lisp/binhex.el: Require `path-util'. - * lisp/gnus-audio.el: Ditto. - * lisp/spam.el: Ditto. - * lisp/uudecode.el: Ditto. - - * lisp/binhex.el (binhex-use-external): Replace `executable-find' - with `exec-installed-p'. - * lisp/gnus-audio.el (gnus-audio-au-player): Ditto. - (gnus-audio-wav-player): Ditto. - * lisp/spam.el (spam-ifile-path): Ditto. - (spam-bogofilter-path): Ditto. - * lisp/uudecode.el (uudecode-use-external): Ditto. - - * lisp/gnus-int.el (gnus-agent-expire): Make arguments optional. - -2003-01-13 Katsumi Yamaoka - - * lisp/gnus-util.el (gnus-read-event-char): Take an optional - parameter even if Mule 2.3 is running. - -2003-01-10 Reiner Steib - - * make.bat: Removed "-no-init-file" (it's the same as "-q"). Use - new variables EMACSBATCH and GNUS_INFO_DIR. Install gnus-?, - message-?, sieve and pgg (in texi). Added hint for dir entries. - - * make-x.bat: Ditto. - -2003-01-13 Simon Josefsson - - * GNUS-NEWS: Add smileys, Sender:, message-utils. - Expand anti-spam. Fixes. - -2003-01-12 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.12 revision 00. - -2003-01-12 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.11 revision 00. - -2003-01-11 Katsumi Yamaoka - - * lisp/gnus.art.el (gnus-treat-predicate): Don't follow the Change - of Oort Gnus at 2003-01-02; reverted. - - * lisp/message.el (message-tool-bar-map): Commented out MIME-Edit - buttons. - -2003-01-09 Simon Josefsson - - * etc/gnus/preview.xpm: Add. - -2003-01-06 Simon Josefsson - - * etc/gnus/receipt.xpm: Add. - -2003-01-10 Jesper Harder - - * etc/gnus/preview.xbm: Add. - -2003-01-09 Katsumi Yamaoka - - * lisp/message.el (message-tool-bar-map): Fix keymap for MIME-Edit. - -2003-01-09 NAKAJI Hiroyuki - - * README.semi.ja: "What's T-gnus?" is revised. - - * README.semi: Ditto. - -2003-01-07 Keiichi Suzuki - - * lisp/message.el (message-setup-1): Don't call - `message-use-alternative-email-as-from' if it isn't for replying. - -2003-01-05 Katsumi Yamaoka - - * etc/gnus/gnus.xpm (oort): Make the color replaceable. - -2003-01-05 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.10 revision 00. - -2003-01-03 Katsumi Yamaoka - - * lisp/gnus-xmas.el (gnus-xmas-group-startup-message): Bind the - color for the symbol `oort' as `gnus-group-startup-message' does. - -2002-12-31 Katsumi Yamaoka - - * lisp/gnus-start.el (gnus-re-read-newsrc-el-file): Commented out. - (gnus-load): Allow coding-system as an argument. - -2002-12-16 ARISAWA Akihiro - - * lisp/nnimap.el (nnimap-callback): Use `nnimap-demule'. - (nnimap-request-article-part): Ditto. - -2002-12-10 Katsumi Yamaoka - - * texi/Makefile.in (%.info, .texi): Conceal control procedures. - -2002-12-05 Kai Gro,A_(Bjohann - - * etc/smilies/*.pbm: Made them binary. - -2002-11-28 Daiki Ueno - - * lisp/gnus-agent.el (gnus-agent-fetch-headers): Don't refer to - the value of `gnus-agent-file-name'. - -2002-11-28 Daiki Ueno - - * lisp/gnus-agent.el (gnus-agent-fetch-group-1): Article numbers - should be accessed through `mail-header-number'. - -2002-11-24 ARISAWA Akihiro - - * lisp/mm-url.el (mm-url-program): Use `exec-installed-p' instead of - `executable-find'. - -2002-11-13 Kai Gro,A_(Bjohann - - * etc/smilies/blink.xpm: Changed smileys and some new ones from - Alex Schroeder . - -2002-11-12 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-summary-inherit-default-charset): Inherit - the value for `default-mime-charset-unlimited' as well. - (gnus-summary-setup-default-charset): Bind - `default-mime-charset-unlimited' to nil for nndraft:delayed or - nndraft:drafts groups. - - * lisp/gnus-art.el (gnus-article-prepare-display): Don't use - MIME-View for nndraft:delayed or nndraft:drafts groups. - (gnus-article-decode-article-as-default-mime-charset): Don't - decode an article for nndraft:delayed or nndraft:drafts groups. - -2002-11-06 Katsumi Yamaoka - - * lisp/nndraft.el (nndraft-request-article): Don't give a special - treatment to Mule. - - * lisp/nnheader.el (nnheader-auto-save-coding-system): Undo last - change to restore the default value to emacs-mule or escape-quoted. - -2002-11-05 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-mime-edit-article-setup): Don't - perform `mime-edit-again' for a delayed or a queued article. - (gnus-article-mime-edit-done): Bind `inhibit-read-only' to t while - running `gnus-article-edit-done'. - -2002-10-30 TSUCHIYA Masatoshi - - * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Protect - against unexpected data structure. - -2002-10-30 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el: Clean up codes. - (nnshimbun-buffer, nnshimbun-current-directory) - (nnshimbun-current-group, nnshimbun-server-directory): Removed. - (nnshimbun-current-server, nnshimbun-server-directory) - (nnshimbun-current-group, nnshimbun-current-directory): New macros. - (nnshimbun-backlog, nnshimbun-find-parameter): Use - `nnshimbun-current-server'. - (nnshimbun-possibly-change-group, nnshimbun-open-server): - Reimplemented. - (nnshimbun-close-server): Do not kill `nnshimbun-buffer'. - (nnshimbun-request-article-1, nnshimbun-request-list): Use - `erase-buffer' instead of `delete-region'. - (nnshimbun-request-article): Use `nnshimbun-current-group'. - (nnshimbun-request-group): Remove redundant checks. - (nnshimbun-request-scan): Check arguments strictly. - (nnshimbun-retrieve-headers, nnshimbun-retrieve-headers-with-nov): - Reimplemented. - (nnshimbun-generate-nov-database, nnshimbun-search-id) - (nnshimbun-write-nov, nnshimbun-request-expire-articles): - Simplified. - (nnshimbun-nov-buffer-name, nnshimbun-nov-file-name): Make the - first argument optional. - (nnshimbun-open-nov): Bind variables to set coding systems for - path names. - (nnshimbun-possibly-change-group, nnshimbun-request-article) - (nnshimbun-write-nov): Strict checking. - (nnshimbun-request-expire-articles): Small fix. - -2002-10-29 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 05. - - * lisp/nnheader.el (nnheader-auto-save-coding-system): Default to - `iso-2022-7bit'. - -2002-10-29 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (nnshimbun-request-article-1): Install trick - to keep compatibility between T-gnus and Oort Gnus. - -2002-10-29 Tadashi Watanabe - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Do not - use removed variables. - -2002-10-29 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el: Clean up. - (nnshimbun-nov-last-check): Removed. - (nnshimbun-nov-buffer-alist): Removed. - (nnshimbun-nov-buffer-file-name): Removed. - (nnshimbun-close-server): Use `nnshimbun-write-nov' instead of - `nnshimbun-save-nov'. - (nnshimbun-mail-header-subject): Removed. - (nnshimbun-mail-header-from): Removed. - (nnshimbun-make-shimbun-header): Removed. - (nnshimbun-parse-nov): New function. - (nnshimbun-request-article-1): Use `nnshimbun-parse-nov' instead - of `nnheader-parse-nov'. - (nnshimbun-retrieve-headers): Likewise. - (nnshimbun-nov-buffer-name): New function. - (nnshimbun-nov-file-name): Ditto. - (nnshimbun-open-nov): Clean up. - (nnshimbun-write-nov): Ditto; Aceept the 2nd optional argument. - (nnshimbun-save-nov): Removed. - -2002-10-18 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-dont-compile-files): New constant - containing almost all mm*.el. - (dgnushack-compile): Don't byte-compile the file in - `dgnushack-dont-compile-files'. - -2002-10-09 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 04. - (gnus-version): T-gnus supports SEMI 1.14 and FLIM 1.14. - - * lisp/mmgnus.el: Remove commented obsolete definitions. - - * lisp/message.el (message-header-hook): Replace - `eword-encode-header' with `mime-encode-header-in-buffer'. - (message-send-mail-with-smtp): Don't use `smtp-via-smtp'. - -2002-10-07 Katsumi Yamaoka - - * lisp/mm-url.el (mm-url-form-encode-xwfu): Use - `file-coding-system' instead of `buffer-file-coding-system' when - Mule 2 is running. - - * lisp/gnus-group.el: Require `mm-url' only when compiling. - (gnus-group-fetch-charter): Require `mm-url'. - - * lisp/gnus.el (gnus-default-charset): Default to `iso-8859-1'. - -2002-09-13 TSUCHIYA Masatoshi - - * lisp/nnheader.el (toplevel) [XEmacs]: Remove code to define - `emacs-mule' coding-system, because the generated coding system is - not compatible to the original coding system of FSF Emacs. - -2002-09-12 TSUCHIYA Masatoshi - - * lisp/nnheader.el (toplevel) [XEmacs]: Define `emacs-mule' coding - system in order to cancel difference on coding systems of - auto-saved files between FSF Emacs and XEmacs. - (nnheader-auto-save-coding-system) [Mule]: The default value of - Mule2 is changed from `*junet*' to `*internal*', in order to unify - coding system of files auto-saved by Mule2. - -2002-09-08 Daiki Ueno - - * lisp/gnus-msg.el (gnus-configure-posting-styles): Follow the - change of arglist of gnus-configure-posting-style. - (gnus-configure-posting-style): Check circular import. - -2002-09-08 Daiki Ueno - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. - - * lisp/gnus-msg.el (gnus-named-posting-styles): Defcustom. - (gnus-posting-styles): Allow (import "..."). - (gnus-configure-posting-style): Splitted from - gnus-configure-posting-styles. - (gnus-summary-execute-command-with-posting-style): Fix prompt string. - - * lisp/gnus-cus.el (gnus-group-parameters): Allow (import "...") - in posting-styles. - -2002-09-08 Daiki Ueno - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. - - * lisp/gnus-msg.el (gnus-named-posting-styles): New variable. - (gnus-summary-send-map): Bind "P" to - gnus-summary-execute-command-with-posting-style. - (gnus-configure-posting-styles): Expand named entries in - gnus-posting-styles. - (gnus-summary-execute-command-with-posting-style): New command. - -2002-09-06 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. - - * lisp/gnus-msg.el (gnus-copy-article-buffer): Set a copy buffer - mutibyte; remove invisible and intangible test properties from a - copied article. - -2002-09-05 TAKAHASHI Kaoru - - * texi/ptexinfmt.el: discard @documentdescription. Support - @ifplaintext, @ifnotplaintext, @ifhtml. Remove obsolete commands. - (texinfo-format-ifhtml, texinfo-format-ifplaintext): New function. - -2002-09-04 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu/highlight-words): Stricten - regular expression to highlight keywords. - -2002-08-28 Katsumi Yamaoka - - * lisp/lpath.el: Fbind `smtpmail-send-it' for Mule 2. - -2002-08-26 Katsumi Yamaoka - - * lisp/gnus-util.el (frame-parameter): New function for oldies. - -2002-08-21 Katsumi Yamaoka - - * lisp/gnus.el (gnus-frame): Remove. - -2002-08-11 Katsumi Yamaoka - - * lisp/gnus-vers.el: Fix T-gnus version number. - -2002-08-06 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.8 revision 00. - -2002-08-06 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu-update-index): Handle error - messages printed by Namazu. - (gnus-namazu/update-sentinel): Likewise. - (gnus-namazu-need-path-normalization): Change its default value. - (gnus-namazu/normalize-results): Remove `file://' prefix. - - * texi/gnus-ja.texi (Namazu Groups): Update documents. - - * lisp/gnus-namazu.el (gnus-namazu/update-p): Print error - messages. - (gnus-namazu-update-index): Small clean up. - (gnus-namazu-update-all-indices): Ditto. - -2002-08-05 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el: Bug fix of updating multiple indices. - (gnus-namazu/setup): Call `gnus-namazu-update-all-indices' without - arguments. - (gnus-namazu-create-index): Clean temporary files even if an - indexer is killed. - (gnus-namazu/update-p): New function. - (gnus-namazu-update-all-indices): Reimplemented. - (gnus-namazu-update-index): Call `gnus-namazu/update-p' to decide - whether the specified index will be updated. - (gnus-namazu/update-sentinel): Follow the change of - `gnus-namazu-update-all-indices'. - -2002-08-05 TSUCHIYA Masatoshi - - * lisp/gnus.el (toplevel): Add autoloads for - `gnus-namazu-create-index', and `gnus-namazu-update-all-indices' - and `gnus-namazu-update-index'. - - * lisp/gnus-namazu.el: Support automatically updating multiple - indices. - (gnus-namazu-make-index-interval): Abolished. - (gnus-namazu-index-update-interval): New option. - (gnus-namazu/setup): Call `gnus-namazu-update-all-indices' instead - of `gnus-namazu-make-index'. - (gnus-namazu/mknmz-process): Abolished. - (gnus-namazu/status-file-name): New macro. - (gnus-namazu-make-index, gnus-namazu-make-index-stop, - gnus-namazu/mknmz-sentinel): Removed. - (gnus-namazu/mknmz-cleanup, gnus-namazu/index-old-p): New function. - (gnus-namazu-create-index, gnus-namazu-update-all-indices, - gnus-namazu-update-index, gnus-namazu-stop-update): New command. - (gnus-namazu/update-directories, gnus-namazu/update-process): New - internal variable. - -2002-07-31 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el: Support automatically updating index. - (gnus-namazu-default-index-directory): New constant. - (gnus-namazu-make-index-interval, gnus-namazu-make-index-command, - gnus-namazu-make-index-arguments): New options. - (gnus-namazu/setup): Call `gnus-namazu-make-index'. - (gnus-namazu/real-group-name): Renamed from - `gnus-namazu/check-cache-group'. - (gnus-namazu/cache-group-candidates): Renamed from - `gnus-namazu/cache-group-candidates'. - (gnus-namazu/search): Experimental support of articles covered by - agent. - (gnus-namazu/default-index-directory, gnus-namazu/lapse-seconds, - gnus-namazu/mknmz-sentinel): New internal functions. - (gnus-namazu/mknmz-process): New internal variable. - (gnus-namazu/lock-file-name, gnus-namazu/index-file-name): New - macros. - (gnus-namazu-make-index, gnus-namazu-make-index-stop): New - commands. - -2002-07-30 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu/request-list): Removed. - (gnus-namazu/get-current-to): New function. - (gnus-namazu/complete-query): Call the above. - -2002-07-19 Katsumi Yamaoka - - * lisp/pop3.el: Don't autoload "ssl". - (pop3-open-ssl-stream-1): Require `ssl' before binding ssl-* vars. - -2002-07-18 Katsumi Yamaoka - - * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): Remove - a redundancy. - -2002-07-11 TSUCHIYA Masatoshi - - * texi/gnus-ja.texi (Web Newspaper): Update the url of w3m. - -2002-07-05 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-summary-mode-map): Replace - `gnus-article-toggle-headers' with `gnus-summary-toggle-header'. - (gnus-summary-wash-map): Ditto. - (gnus-summary-wash-hide-map): Replace - `gnus-article-toggle-headers' with `gnus-article-hide-headers'. - (gnus-summary-article-menu): Ditto. - - * lisp/gnus.el: Remove autoload for `gnus-article-toggle-headers'. - - * lisp/gnus-art.el (article-toggle-headers): Abolished. - -2002-07-04 Katsumi Yamaoka - - * lisp/dgnushack.el (byte-optimize-form-code-walker): Don't modify - the function definition if the bug has already gone; revert to the - use of `defadvice'. - -2002-07-03 Keiichi Suzuki - - * lisp/gnus-logic.el (gnus-advanced-index): Use luna based index - numbers. - -2002-06-26 Tetsuo Tsukamoto - - * lisp/imap.el (imap-ssl-open-2): Do away with w32-related - workaround I installed on 1999-12-28, i.e. also call - `as-binary-process' in windows-nt. - -2002-06-26 Katsumi Yamaoka - - * contrib/hashcash.el: Require `cl' when compiling. - (hashcash-strip-quoted-names): Replace `subseq' with `substring'. - (mail-add-payment): Allow no `mail-header-separator' in the buffer; - don't use `mapc'. - -2002-06-25 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): When - `gnus-large-newsgroup' is equal to nil, no confirmation is - required. - -2002-06-23 Tetsuo Tsukamoto - - * lisp/pop3.el (pop3-open-ssl-stream): Do away with w32-related - workaround I installed on 1999-12-27, i.e. also call - `as-binary-process' in windows-nt. - -2002-06-12 Katsumi Yamaoka - - * lisp/message.el (message-send): Kill `message-encoding-buffer' - even if sending failed. - -2002-06-11 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. - - * lisp/gnus-msg.el (gnus-message-setup-hook): Default to nil. - (gnus-setup-message): Run `gnus-maybe-setup-default-charset'. - (gnus-summary-supersede-article): Don't bind the value for - `gnus-message-setup-hook'. - (gnus-summary-resend-bounced-mail): Ditto. - - * lisp/dns.el (dns-make-network-process): Bind - `default-process-coding-system' to `(binary . binary)'; bind - `program-coding-system-alist' to nil. - - * lisp/gnus-fun.el (gnus-convert-gray-x-face-to-xpm): Bind - `input-coding-system' and `output-coding-system' to `binary'. - - * lisp/gnus-namazu.el (gnus-namazu/call-namazu): Bind - `input-coding-system' and `output-coding-system' to the velue of - `gnus-namazu-coding-system'. - - * lisp/imap.el (imap-ssl-open): Don't bind the values for - `input-coding-system' and `output-coding-system'. - - * lisp/nnmaildir.el (nnmaildir-request-scan): Bind - `output-coding-system' to the value of - `nnheader-file-coding-system'; bind `file-coding-system' to nil. - (nnmaildir-request-rename-group): Ditto. - (nnmaildir-request-replace-article): Ditto. - (nnmaildir-request-accept-article): Ditto. - (nnmaildir-request-set-mark): Ditto. - - * lisp/nnmbox.el (nnmbox-save-buffer): Simplify the source code. - - * lisp/nnrss.el (nnrss-read-server-data): Bind - `input-coding-system' to `binary'. - (nnrss-save-server-data): Bind `output-coding-system' to `binary'. - (nnrss-read-group-data): Bind `input-coding-system' to `binary'. - (nnrss-save-group-data): Bind `output-coding-system' to `binary'. - -2002-06-07 Katsumi Yamaoka - - * lisp/pop3.el: Add a comment for the use of `ssl' or `tls' - connection with Gnus; always require `pces' and `path-util' for - Gnus. - (pop3-open-ssl-stream-1): Don't require `path-util' here. - -2002-06-06 Katsumi Yamaoka - - * lisp/pop3.el: Make it can be byte-compiled in the Gnus source - tree with neither errors nor warnings. - (pop3-md5): Fix the logic to check whether the built-in `md5' - allows the 4th argument CODING-SYSTEM. - -2002-06-04 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. - - * contrib/gpg-ring.el: Remove RCS magic cookie. - * lisp/nnir.el: Ditto. - - * texi/ptexinfmt.el (texinfo-discard-command-and-arg): New - function. - -2002-06-03 TAKAHASHI Kaoru - - * texi/ptexinfmt.el: discard @cartouche. @anchor discard for Mule - 2.3. Support @., @:, @-. - (texinfo-format-inforef): New function. - -2002-05-30 Katsumi Yamaoka - - * lisp/nnheader.el (nnheader-unfold-fws): New function copied from - `ietf-drums-unfold-fws'. - (ietf-drums-unfold-fws): Alias to `nnheader-unfold-fws'. - -2002-05-07 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.7 revision 00. - -2002-04-30 Daiki Ueno - - * lisp/message.el (message-expand-name-function): New user option. - (message-expand-name): Use it. - * lisp/lpath.el: Don't bind lsdb-complete-name and bbdb-complete-name. - -2002-04-30 Daiki Ueno - - * lisp/message.el (message-expand-name): Use lsdb-complete-name if - available. - * lisp/lpath.el: Bind lsdb-complete-name. - -2002-04-30 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Also examine - backquote'd forms. - - * lisp/nnheader.el (nnheader-with-unibyte): New macro. - (mm-with-unibyte): Alias to `nnheader-with-unibyte'. - -2002-04-26 Steve Youngs - - * aclocal.m4 (AC_PATH_INFODIR): New. Defaults to '$prefix/info' - for Emacs and 'site-packages/info' for XEmacs. - (AC_PATH_ETCDIR): Drop 'gnus' off the end of the default directory - for XEmacs. - - * configure.in: Use 'AC_PATH_INFO_DIR'. - -2002-04-23 Daiki Ueno - - * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Disregard the - message cache when bbdb/news-auto-create-p is nil. - -2002-04-23 Daiki Ueno - - * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Work around the - incompatibility with BBDB 2.3x. - -2002-04-22 Daiki Ueno - - * lisp/message.el (message-make-user-agent): Remove product tokens - for gnus-vers. [cf. ] - -2002-04-22 Daiki Ueno - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. - - * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Tweak BBDB message - caching. - (gnus-bbdb/extract-message-sender-function): New user option. - (gnus-bbdb/extract-message-sender): New function. - -2002-04-20 Daiki Ueno - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. - - * lisp/gnus-sum.el: Don't autoload gnus-set-summary-default-charset. - (gnus-summary-inherit-default-charset): New function. - (gnus-parse-headers-hook): Use it. - (gnus-summary-setup-default-charset): Set default-mime-charset here. - - * lisp/gnus-delay.el (gnus-delay-article): Undo the last change. - - * lisp/gnus-draft.el: Revert to the original implementation. - (gnus-draft-edit-message): Pass restore as the 3rd argument of - gnus-draft-setup; call save-buffer instead of message-save-drafts. - (gnus-draft-setup): Rename from gnus-draft-setup-for-editing. - (gnus-draft-setup-for-sending): Abolish. - - * lisp/nnheader.el (nnheader-auto-save-coding-system): New variable. - - * lisp/message.el (message-draft-coding-system): Delegate the - value to nnheader-auto-save-coding-system. - (message-mode-map): Don't bind message-save-drafts. - (message-dont-send): Use save-buffer instead of message-save-buffer. - (message-save-drafts): Abolish. - - * lisp/nndraft.el (nndraft-request-article): Revert to the - original implementation. - -2002-04-18 Daiki Ueno - - * lisp/gnus-draft.el (gnus-group-send-queue): Pass group and - interactive as the arguments of gnus-draft-send. - (gnus-draft-send): Don't give "nndraft:queue" special treatment. - -2002-04-17 Daiki Ueno - - * lisp/gnus-delay.el (gnus-delay-article): Use `message-save-drafts' - instead of `save-buffer'. - -2002-04-08 Daiki Ueno - - * lisp/gnus-draft.el (gnus-draft-send): Always enter the Message - mode. - -2002-03-28 Katsumi Yamaoka - - * lisp/gnus-group.el (gnus-group-completing-read-group-name): Use - `mapatoms' to extract all groups from `gnus-active-hashtb'. - -2002-03-26 Katsumi Yamaoka - - * lisp/gnus-group.el (gnus-group-completing-read-group-name): - Improve to speed up. - (gnus-group-name-charset-group-alist): Change the default value. - -2002-03-25 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. - - * lisp/message.el (message-save-drafts, message-check-8bit, - message-send-news, message-send-mail, message-send): Replace - `insert-buffer' with `insert-buffer-substring'. - * lisp/gnus-art.el (gnus-article-mime-edit-article-setup, - gnus-article-edit-exit, article-verify-x-pgp-sig): Ditto. - -2002-03-20 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-summary-make-menu-bar): Don't provide - "View as different encoding" submenu if the function - `coding-system-list' is not available. - -2002-03-19 Katsumi Yamaoka - - * lisp/pop3.el (pop3-md5): Treat a given string as binary. - -2002-03-06 Katsumi Yamaoka - - * lisp/gnus-msg.el (gnus-summary-resend-message-edit): Use - `mime-edit-again' instead of `mime-to-mml' to recompose a message. - -2002-03-05 Katsumi Yamaoka - - * lisp/message.el (mm-make-temp-file): Copied from mm-util.el. - -2002-03-04 Katsumi Yamaoka - - * lisp/message.el (message-fix-before-sending): Bind - `mm-7bit-chars' to the value that concat the original value and - escape. - - * lisp/nnheader.el (mm-7bit-chars): Remove. - -2002-03-04 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-edit-mode): Don't call `mml-mode'. - - * lisp/nnheader.el (mm-7bit-chars): Copied from mm-bodies.el. - (mm-multibyte-p): New alias. - (mm-char-int): Alias to `char-int'. - -2002-02-26 TSUCHIYA Masatoshi - - * lisp/gnus-art.el (gnus-request-article-this-buffer): Sync up - with Oort-gnus. - - * lisp/nntp.el (nntp-open-via-rlogin-and-telnet): Wrap - `call-process' with `as-binary-process'. - -2002-02-25 Katsumi Yamaoka - - * lisp/smiley.el (smiley-regexp-alist): Fix the order of faces. - -2002-02-25 Katsumi Yamaoka - - * lisp/smiley.el (smiley-regexp-alist): Use faces which originate - in etc-0.27.tar.gz if exist. - (gnus-smiley-file-types): Add xbm if available. - (smiley-region): Don't put two or more faces in one place. - -2002-02-22 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-request-article-this-buffer): Temporally - fix: erase the buffer before inserting (and saving) an article. - -2002-02-22 Steve Youngs - - * aclocal.m4 (AC_PATH_LISPDIR): Default to - .../site-packages/lisp/gnus for XEmacs. - (AC_PATH_ETCDIR): Default to .../site-packages/etc/gnus for - XEmacs. - -2002-02-21 Daiki Ueno - - * lisp/gnus-group.el (gnus-group-name-encode): New function. - (gnus-group-encoded-name): New function. - (gnus-group-completing-read-group-name): New function. - (gnus-fetch-group): Use it. - (gnus-group-jump-to-group): Use it. - (gnus-group-unsubscribe-current-group): Use it. - -2002-02-21 Daiki Ueno - - * lisp/nnheader.el (mm-string-as-unibyte): Undo the last change. - * lisp/gnus-srvr.el (gnus-browse-foreign-server): Ditto. - -2002-02-21 Daiki Ueno - - * lisp/nnheader.el (mm-string-as-unibyte): Alias to - `string-as-unibyte'. - - * lisp/gnus-srvr.el (gnus-browse-foreign-server): Return unibyte - group names. - -2002-02-19 Katsumi Yamaoka - - * lisp/lpath.el: Bind `navi2ch-mona-font'. - -2002-02-18 Daiki Ueno - - * lisp/gnus-art.el (gnus-treat-monafy): New user option. - (article-monafy): New function. - -2002-02-18 Katsumi Yamaoka - - * lisp/nnheader.el (std11-field-value): Fix regexp. - -2002-02-15 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-treat-display-grey-xface): Default to nil - under NTEmacs 21. - -2002-02-14 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu-kill-summary-buffers): New - advice. - -2002-02-12 Katsumi Yamaoka - - * lisp/mm-view.el: Require `gnus-mailcap' rather than `mailcap'. - - * lisp/nnheader.el (mm-with-unibyte-buffer): Bind `default-mc-flag' - instead of `mc-flag'. - (nnheader-with-unibyte-current-buffer): New macro. - (mm-with-unibyte-current-buffer): Alias to - `nnheader-with-unibyte-current-buffer'. - (nnheader-guess-mime-charset): New macro. - (mm-guess-mime-charset): Alias to `nnheader-guess-mime-charset'. - (shell-command-to-string): New function for old Emacsen. - - * lisp/lpath.el: Don't fbind `shell-command-to-string'. - -2002-02-09 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu/group-alist): Abolished. - (gnus-namazu/setup): Not set it. - (gnus-namazu/shutdown): Removed. - (gnus-namazu/group-prefixed-name): Handle case-insensitive file - names by itself. - -2002-02-09 NISHIDA Masakazu - - * lisp/gnus-namazu.el (gnus-namazu/complete-query): Relaxed the - regexp which matches field search keywords. - -2002-02-01 ShengHuo ZHU - - * etc/gnus/gnus.xpm: Remove some garbages at the end of the file. - -2002-02-03 Daiki Ueno - - * lisp/nnir.el (nnir-run-namazu): According to SUSv3, LC_ALL is - prior to the other environment variables whose names are starting - with "LC_". So there is no need to setting them. - -2002-02-03 Daiki Ueno - - * lisp/nnir.el (nnir-imap-default-charset): New user option. - (nnir-run-imap): Supply the charset of a search criteria. - -2002-02-01 Katsumi Yamaoka - Suggested by Kenichi OKADA - - * lisp/message.el (message-save-drafts): Override - `mime-header-encode-method-alist'. - -2002-02-01 Taiji Can - - * texi/gnus-ja.texi (Posting Styles): Fix typo. - -2002-01-31 ARISAWA Akihiro - - * lisp/gnus-art.el (gnus-article-display-traditional-message): - Reverted. - -2002-01-31 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-setup-buffer): Enable multibyte - in `gnus-original-article-buffer'. - -2002-01-29 Katsumi Yamaoka - - * lisp/message.el (message-cite-prefix-regexp): Fix the regexp. - - * lisp/gnus-sum.el (gnus-mime-extract-message/rfc822): New - implementation. - -2002-01-24 Katsumi Yamaoka - - * lisp/gnus-clfns.el (find-cl-run-time-functions): Insert a - newline before filling a result; ignore non-list forms. - -2002-01-24 ARISAWA Akihiro - - * lisp/gnus-sum.el (gnus-summary-show-article): If coding-system is - specified, bind `default-mime-charset' to it. - -2002-01-23 Katsumi Yamaoka - - * lisp/message.el: Require `base64' before `canlock-om' to avoid - damage to define `base64-encode-string' by MEL. - - * lisp/dgnushack.el: Load base64.el before canlock-om.el to avoid - damage to define `base64-encode-string' by MEL. - -2002-01-23 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-article-commands-menu): Bind "Html" to - the command `gnus-article-wash-html'. - (gnus-summary-article-menu): Ditto. - (gnus-summary-wash-map): Bind "h" to the command - `gnus-article-wash-html'. - - * lisp/gnus-art.el (gnus-article-treatment-menu): Bind - "Treat html" to the command `gnus-article-wash-html'. - - * lisp/nnheader.el: Place mm- stuff and mail-parse stuff in front - of the codes which use (or may use) them. - -2002-01-21 ARISAWA Akihiro - - * lisp/gnus-art.el (gnus-article-display-traditional-message): Use - `set-buffer-multibyte'. - -2002-01-21 TSUCHIYA Masatoshi - - * lisp/gnus-sum.el (gnus-summary-preview-mime-message): Protect - against dead windows. - - * lisp/nnheader.el (mm-encode-coding-string): Alias to - `encode-coding-string'. - (mm-decode-coding-string): Alias to 'decode-coding-string'. - -2002-01-21 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.6 revision 00. - - * lisp/nnheader.el (std11-unfold-region): New function copied from - `rfc2047-unfold-region'. - (std11-unfold-field): New function. - (mail-header-unfold-field): Alias to `std11-unfold-field'. - -2002-01-21 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 02 (synch - with the released version of Oort Gnus v0.05). - -2002-01-16 Katsumi Yamaoka - - * lisp/dgnushack.el: Advise `byte-compile-inline-expand' for Mule - to ignore built-in functions as Emacs 20+ does. - -2002-01-15 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-adjust-marked-articles): Fix the record - for `seen' if it looks like (seen NUM1 . NUM2). It should be - (seen (NUM1 . NUM2)). - -2002-01-15 Katsumi Yamaoka - - * lisp/nntp.el (nntp-send-buffer): Bind `mc-flag' to nil. - - * lisp/nnheader.el (mm-with-unibyte-buffer): Alias to - `nnheader-with-unibyte-buffer'. - (nnheader-with-unibyte-buffer): New macro. - -2002-01-12 Katsuhiro Hermit Endo - - * texi/gnus-ja.texi (Article Date): Update Japanese translation. - -2002-01-11 Katsumi Yamaoka - - * lisp/gnus-clfns.el (butlast): Fix a serious bug that it behaved - like `nbutlast'. Special thanks to Keiichi-san for the great - discovery. - - * lisp/gnus.el (gnus-product-variable-file-list): Add a check for - the value of `gnus-use-correct-string-widths' in the forms. - - * lisp/gnus-start.el (gnus-product-quick-file-format): Include the - value of `gnus-use-correct-string-widths' in the file form. - (gnus-product-read-variable-file-1): Check for the equality in the - value of `gnus-use-correct-string-widths' as well. - -2002-01-10 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 01 in - order to force update cached format specs. - - * lisp/gnus-spec.el (gnus-use-correct-string-widths): Default to t. - -2002-01-10 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el: Adopt for old Gnusae. - -2002-01-10 Katsumi Yamaoka - - * lisp/message.el (message-strip-forbidden-properties): Don't - strip properties when the invisible MIME part is inserted. - - * lisp/gnus-xmas.el (gnus-xmas-group-startup-message): Position - point to the top. - -2002-01-05 Lars Magne Ingebrigtsen - - * etc/gnus/oort.xface (X-Face): Oort X-Face from - Raymond Scholz . - -2002-01-09 Katsumi Yamaoka - - * lisp/lpath.el: Fbind `coding-system-to-mime-charset' for Mule 2. - - * lisp/nnheader.el (std11-fold-region): New function copied from - `rfc2047-fold-region'. - (std11-fold-field): Use it. - -2002-01-09 Katsumi Yamaoka - - * lisp/gnus.el: Don't autoload "gnus-bitmap". - - * lisp/gnus-ems.el: Autoload "smiley-mule" if running Emacs - version is less than 21. - - * lisp/gnus-art.el (gnus-article-smiley-display): Remove. - (gnus-treat-smiley): Reload "smiley-ems" or "smiley-mule" if - needed. - (gnus-treat-display-smileys): Use `gnus-image-type-available-p'. - (gnus-article-smiley-mule-loaded-p): New internal variable. - (gnus-article-should-use-smiley-mule): New user option. - -2002-01-09 TSUCHIYA Masatoshi - - * lisp/nneething.el (nneething-mime-extensions): New variable. - (nneething-request-article): Refer it. - - * lisp/nnheader.el (mm-detect-coding-region): Alias to - `nnheader-detect-coding-region'. - (nnheader-detect-coding-region): New function. - (mm-detect-mime-charset-region): Alias to - `nnheader-detect-mime-charset-region'. - (nnheader-detect-mime-charset-region) New function. - -2002-01-08 TSUCHIYA Masatoshi - - * texi/gnus-ja.texi (Web Newspaper): Update the document of - mime-w3m.el. - -2002-01-08 Katsumi Yamaoka - - * lisp/gnus-art.el (article-toggle-headers): Expose headers even - if there is a boundary line. - - * lisp/nntp.el (nntp-send-buffer): Don't use - `mm-with-unibyte-current-buffer'. Use expanded form instead. - - * lisp/gnus-art.el (gnus-treatment-function-alist): Move X-Face - stuff down after unfolding stuff. - -2002-01-08 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu/highlight-words): Reimplemented. - -2002-01-08 Katsumi Yamaoka - - * lisp/nnheader.el (mail-narrow-to-head): Copy from ietf-drums.el; - it should go to the beginning of the header after narrowing. - (std11-extract-addresses-components): Protect against nil argument. - -2002-01-08 Katsumi Yamaoka - - * lisp/nnheader.el (mail-header-field-value): Alias to - `std11-field-value'. - (std11-field-value): New function. - -2002-01-08 Akihiro Arisawa - - * lisp/nnheader.el (mail-header-parse-addresses): New function. - (std11-extract-addresses-components): New function. - -2002-01-07 Katsumi Yamaoka - - * lisp/gnus-picon.el: Don't require `mail-parse'. - -2002-01-07 TSUCHIYA Masatoshi - - * lisp/nnheader.el (mail-header-fold-field): Alias to - `std11-fold-field'. - (std11-fold-field): New function. - (mail-narrow-to-head): Alias to `std11-narrow-to-header'. - (mail-header-narrow-to-field): Alias to `std11-narrow-to-field'. - (std11-narrow-to-field): New function. - -2002-01-07 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.5 revision 00. - -2002-01-02 ShengHuo ZHU - - * etc/gnus/describe-group.xpm: Set pixels of first line to - background color. A bug in Emacs? - -2002-01-07 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 10. - - * lisp/gnus-picon.el: Require `mail-parse'. - - * lisp/sha1-el.el (sha1-use-external): Replace `executable-find' - with `exec-installed-p'. - -2002-01-06 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el: Update comments. - (gnus-namazu/search): Convert `gnus-cache-directory' to absolute - before the regular expression which matches paths of persistent - articles is generated. Clean up codes. - -2002-01-05 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (nnshimbun-request-article): Handle the - article properly when no group is specified. - (nnshimbun-write-nov, nnshimbun-save-nov): Save nov databases only - when their sizes are greater than zero. - - * lisp/gnus-namazu.el (gnus-namazu-query-highlight): New option. - (gnus-namazu-query-highlight-face): New face. - (gnus-namazu/check-cache-group): New function. - (gnus-namazu/cache-group-candidates): Ditto. - (gnus-namazu/search): Call `gnus-namazu/check-cache-group' to get - groups for cached articles. - (gnus-namazu/highlight-words): New function. - (gnus-namazu-search): Set the group parameter `highlight-words' - when `gnus-namazu-query-highlight' is equal to the other value - than nil. - - * lisp/gnus-ja.texi (Namazu Groups): Updated. - -2001-12-21 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Ignore - non-list forms in the top level. - -2001-12-18 Josh Huber - - * ChangeLog, todo: (oops) changed buffer-file-coding-system back - to coding. - -2001-12-18 Kai Gro,A_(Bjohann - - * make-x.bat: Ensure nonempty variable value. Reported by Frank - Haun . - -2001-12-18 01:00:00 ShengHuo ZHU - - * ChangeLog, todo: Add `coding'. - -2001-12-17 Josh Huber - - * ChangeLog: changed coding to buffer-file-coding-system - * todo: same - -2001-12-10 Kai Gro,A_(Bjohann - - * make-x.bat: Code cleanup. Fix a bug with "/copy". From Frank - Schmitt . - -2001-12-10 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu-summary-buffer-name): Changed - the expression to decide whether `gnus-summary-buffer-name' should - be advised. - (gnus-namazu/setup): Strict checking the other Gnus variants than - Oort-Gnus before handling `gnus-group-name-charset-group-alist'. - -2001-12-09 Katsumi Yamaoka - - * lisp/nnheader.el (mm-multibyte-string-p): Alias to - `multibyte-string-p' or `ignore'. - -2001-12-09 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu-summary-buffer-name): New - advice. - - * lisp/gnus-namazu.el (top): Update comments. - (gnus-namazu-indexed-servers): Abolished. - (gnus-namazu-index-directories, gnus-namazu-command): Changed the - default value. - (gnus-namazu/group-name-regexp): New internal constant. - (gnus-namazu/indexed-servers): New function. - (gnus-namazu/setup): Not initialize `gnus-namazu-indexed-servers'. - Add the entry for ephemeral groups generated by - `gnus-namazu-search' to `gnus-group-name-charset-group-alist'. - (gnus-namazu/group-prefixed-name): Fix. - (gnus-namazu/search): Stricten checking the return value of - `gnus-namazu/call-namazu'. Install changes in order to avoid the - difference between regexp-opt module of FSF Emacs and one of XEmacs. - (gnus-namazu/get-target-groups, gnus-namazu/get-current-query): - Refer `gnus-namazu/group-name-regexp'. - (gnus-namazu-search): Slightly modified. - -2001-12-07 Katsumi Yamaoka - - * lisp/message.el (message-mimic-kill-buffer): Bind - `message-kill-buffer-and-remove-file' to nil while calling the - function `message-kill-buffer'. - - * texi/message-ja.texi, texi/message-ja.texi: Update. - - * lisp/lpath.el: Fbind `replace-regexp-in-string' for XEmacs and - Mule; don't fbind coding-system-list for Mule. - -2001-12-03 TSUCHIYA Masatoshi - (cf. news://news.gnus.org/gnus.gnus-bug #48523) - - * lisp/message.el (message-kill-buffer-and-remove-file): New user - option. - (message-kill-buffer): Don't remove the backup file if - `message-kill-buffer-and-remove-file' is nil. - -2001-12-07 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu-case-sensitive-filesystem): New - option. - (gnus-namazu/group-alist): New internal variable. - (gnus-namazu/setup): Initialize it. - (gnus-namazu/shutdown) New function. - (gnus-namazu/request-list): Ditto. - (gnus-namazu/group-prefixed-name): Ditto. - (gnus-namazu/search): Call it instead of - `gnus-group-prefixed-name' in order to normalize a group name on a - case-insensitive file system. - -2001-12-05 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (gnus-namazu-need-path-normalization): New - option. - (gnus-namazu/normalize-results): Refined. - - * lisp/gnus-namazu.el (gnus-namazu-index-directory): Abolished. - (gnus-namazu-index-directories): New option. - (gnus-namazu-coding-system): Changed the default value for Windows - and OS/2. - (gnus-namazu/setup): Follow the abolition of - `gnus-namazu-index-directory'. - (gnus-namazu/normalize-results): New inline function. - (gnus-namazu/call-namazu): Set `file-name-coding-system' and - `pathname-coding-system' to handle querys which include multibyte - characters. Not reset locale environments. Refer - `gnus-namazu-locale' and `gnus-namazu-index-directories'. - (gnus-namazu/search): Call `gnus-namazu/normalize-results'. - Modify a regular expression. - (gnus-namazu/get-target-groups): Modify a regular expression. - (gnus-namazu/get-current-query): Ditto. - (gnus-namazu/truncate-article-list): Ditto. - -2001-12-03 Katsumi Yamaoka - - * lisp/mm-url.el: Require `path-util'. - (mm-url-program): Replace `executable-find' to `exec-installed-p'. - -2001-11-29 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 09. - - * lisp/canlock-om.el: New file. - * lips/dgnushack.el: Load canlock-om.el for compiling canlock.el - when `MULE' is bound. - (dgnushack-unexporting-files): Add canlock-om.el when `MULE' is - not bound. - * lisp/message.el: Require `canlock-om' when Mule is running; - autoload cus-edit for the function `customize-save-variable'. - * lisp/nnheader.el (customize-save-variable): Remove. - -2001-11-26 Katsumi Yamaoka - - * lisp/message.el (message-strip-special-text-properties): Default - to t because of the new function `message-tamago-not-in-use-p'. - -2001-11-26 Kai GroN_johann - - * make-x.bat: Use parameter "/copy" rather than "copy" for increased - dwimishness for old-time DOS users. From Frank Schmitt - . - -2001-11-18 Katsumi Yamaoka - - * lisp/message.el (message-strip-special-text-properties): Default - to nil temporarily (it should be automated). - (message-forbidden-properties): Undo last change. - (message-strip-forbidden-properties): Undo last change; synch with - Oort Gnus. - -2001-11-16 Katsumi Yamaoka - - * lisp/message.el (message-forbidden-properties): Defcustom; make - it a list; don't include `intangible', `invisible', - `modification-hooks' or `read-only'. - (message-strip-forbidden-properties): Convert the value of - `message-forbidden-properties' to plist. - -2001-11-16 Katsumi Yamaoka - - * lisp/gnus-group.el (gnus-group-group-map): Bind `G n' key to the - command `gnus-group-make-shimbun-group'. - (gnus-group-group-menu): Add `gnus-group-make-shimbun-group'. - - * texi/gnus-ja.texi (Foreign Groups): Add a documentation for the - shimbun groups. - (Web Newspaper): Use `G n' key for `gnus-group-make-shimbun-group'. - -2001-11-15 Simon Josefsson - - * etc/gnus/unimportant.xpm, etc/gnus/important.xpm: New files. - -2001-11-13 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-summary-wash-map): Remove - `gnus-smiley-display'. - -2001-11-11 Simon Josefsson - - * make-x.bat: Don't use -nw. Suggested by Frank Haun - . - -2001-11-09 TSUCHIYA Masatoshi - - * texi/infohack.el (infohack-texi-format): To process - write-protected files safely, make this buffer be writable after - `find-file' - -2001-11-06 Katsumi Yamaoka - - * lisp/nnheader.el (customize-save-variable): Defun-maybe. - -2001-11-01 07:00:00 ShengHuo ZHU - - * etc/smilies/blink.xpm: New set of xpm. From Oliver Scholz - . - -2001-10-29 Per Abrahamsen - - * etc/smilies/sad.pbm: New bitmap. - * etc/smilies/blink.pbm: Ditto. - Contributed by Kim F. Storm . - -2001-10-22 Katsumi Yamaoka - - * lisp/message.el (rfc822-goto-eoh): Remove. - -2001-10-19 Kai GroN_johann - From Frank Schmitt . - - * make-x.bat: Use correct directory structure for XEmacs on Windows. - -2001-10-19 Katsumi Yamaoka - - * lisp/message.el (rfc822-goto-eoh): Define it when void. - -2001-10-19 Katsumi Yamaoka - - * lisp/message.el (message-resend, message-send): Undo. - -2001-10-19 Katsumi Yamaoka - - * lisp/message.el (message-resend): Bind - `inhibit-field-text-motion' to t while resending a mail. - -2001-10-16 Katsumi Yamaoka - - * lisp/message.el (message-send): Remove the text property `field' - from the encoding buffer. - -2001-10-11 Katsumi Yamaoka - - * lisp/gnus-start.el (gnus-re-read-newsrc-el-file): Use - `gnus-ding-file-coding-system' instead of - `gnus-startup-file-coding-system'; go to the beginning of the - buffer before searching. - (gnus-read-newsrc-el-file): Use `gnus-ding-file-coding-system' - instead of `gnus-startup-file-coding-system'. - -2001-10-10 Katsumi Yamaoka - - * lisp/message.el (message-send-news): Modify the value of - `mime-field-encoding-method-alist' to encode newsgroup names. - - * lisp/gnus-art.el (gnus-article-header-presentation-method): Call - `article-decode-group-name' to decode newsgroup names. - (gnus-article-decode-hook): Default to nil. - -2001-10-06 08:00:00 ShengHuo ZHU - - * Makefile.in (uninstall): Add. - - * etc/Makefile.in (uninstall): Add. - -2001-10-04 Katsumi Yamaoka - - * lisp/message.el (message-fix-before-sending): Don't expose - invisible MIME parts; don't use `message-find-invisible-regions'. - (message-find-invisible-regions): Remove. - (invisible-region): Advise the function to add the text property - `mime-edit-invisible'. - (message-invisible-region): Remove. - (message-save-drafts): Copy all the text properties from the - editing buffer to the encoding buffer. - (message-send): Ditto. - -2001-10-01 Katsumi Yamaoka - - * lisp/nndoc.el (nndoc-oe-dbx-type-p): Use `string-as-multibyte' - instead of `mm-string-as-multibyte'. - (nndoc-possibly-change-buffer): Use `nnheader-insert-file-contents' - instead of `mm-insert-file-contents'. - -2001-09-28 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 08. - -2001-09-27 14:00:00 ShengHuo ZHU - - * aclocal.m4 (GNUS_CHECK_FONTS): Typo. Use /dev/null as latex input. - -2001-09-27 09:00:00 ShengHuo ZHU - - * aclocal.m4, configure.in: Check commercial fonts. - -2001-09-27 Katsumi Yamaoka - - * lisp/message.el (message-find-invisible-regions): Look for the - text-property `mime-edit-invisible' as well as `message-invisible'. - (message-save-drafts): Copy the text-property `mime-edit-invisible' - from the message editing buffer to the encoding buffer. - (message-send): Ditto. - -2001-09-27 Katsuhiro Hermit Endo - - * texi/gnus-ja.texi (Article Hiding): Fix typo. - -2001-09-25 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 07. - -2001-09-24 19:00:00 ShengHuo ZHU - - * configure.in: Generate texi/ps/Makefile. - -2001-09-21 Kai GroN_johann - - * make.bat: Use parameter "/copy" rather than "copy" for increased - dwimishness for old-time DOS users. - -2001-09-18 22:00:00 ShengHuo ZHU - - * make-x.bat: New. - -2001-09-18 Katsumi Yamaoka - - * lisp/dgnushack.el: If W3DIR is identical to URLDIR, don't add it - to `load-path'. - -2001-09-17 Katsumi Yamaoka - - * lisp/gnus-diary.el: Don't use `easy-menu-add-item' if it is not - available. - -2001-09-17 Keiichi Suzuki - - * lisp/gnus-bbdb.el (gnus-bbdb/insert-address-regexp): - `regexp-quote' for each addresses. - -2001-09-16 Katsuhiro Hermit Endo - - * texi/gnus-ja.texi (Drafts): Fix typo. - -2001-09-12 TSUCHIYA Masatoshi - - * lisp/lpath.el: Removed `current-language-environment' and - `language-info-alist'. - -2001-09-11 TSUCHIYA Masatoshi - - * lisp/gnus-art.el (gnus-request-article-this-buffer): Make a copy - of the requested article only when the current directory does noe - equal to `gnus-original-article-buffer'. - - * lisp/gnus-art.el (gnus-request-article-this-buffer): Copy an - article from `gnus-original-article-buffer' to - `gnus-article-buffer'. Generate `gnus-original-article-buffer' - safely. - -2001-09-10 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el: Updated documents. - - * texi/gnus-ja.texi (Namazu Groups): New subsection. - -2001-09-10 Katsumi Yamaoka - - * lisp/gnus-namazu.el: Autoload "regexp-opt" for Mule 2.3. - - * Mule23@1934.en, Mule23@1934.ja: To install contrib/regexp-opt.el - is required. - - * contrib/regexp-opt.el: Imported from Emacs 20.2. - - * lisp/gnus-bbdb.el (gnus-bbdb/pop-up-bbdb-buffer): Use - `bbdb-display-layout' or `bbdb-pop-up-display-layout' instead of - `bbdb-elided-display' or `bbdb-pop-up-elided-display' when BBDB - v2.33 or later is running. - -2001-09-10 TSUCHIYA Masatoshi - - * lisp/gnus-namazu.el (top): Not require `std11'. - (gnus-namazu/get-current-from): Use - `mail-extract-address-components' instead of - `std11-extract-address-components'. - - * lisp/gnus-namazu.el: New file. - - * lisp/gnus.el (top): Add autoload of `gnus-namazu-search'. - - * lisp/gnus-sum.el (gnus-summary-mode-map): Define "\C-c\C-n" as - `gnus-namazu-search'. - - * lisp/gnus-group.el (gnus-group-mode-map): Define "\C-c\C-n" as - `gnus-namazu-search', and removed `gnus-group-make-shimbun-group'. - -2001-09-10 Katsumi Yamaoka - - * lisp/gnus-xmas.el (gnus-tilde-pad-form): Abolished. Use the - new function `gnus-correct-pad-form' instead. - * lisp/gnus-spec.el (gnus-tilde-pad-form): Ditto. - -2001-09-05 TSUCHIYA Masatoshi - - * lisp/nnir.el (nnir-run-namazu): Fix a side effect when handling - of process environments. - -2001-09-04 TSUCHIYA Masatoshi - - * lisp/nnir.el (top): Added code to avoid byte-compile warning - about `nnimap-server-buffer'. - (nnir-run-namazu): Disable locale of Namazu. - -2001-09-04 KOSEKI Yoshinori - - * lisp/nnir.el (gnus-group-mode-hook): Fix typo. - -2001-09-04 TSUCHIYA Masatoshi - - * lisp/nnir.el (top): Don't call `nnir-group-mode-hook' in T-gnus. - - * lisp/gnus-group.el (gnus-group-group-map): Define "G" as - `gnus-group-make-nnir-group', and define "S" as - `gnus-group-make-shimbun-group'. - - * lisp/gnus.el (top): Add autoload of - `gnus-group-make-nnir-group'. - - * lisp/nnir.el: Import from - ftp://ls6-ftp.cs.uni-dortmund.de/pub/src/emacs/nnir.el. - -2001-08-29 Katsumi Yamaoka - - * lisp/gnus-util.el (gnus-truncate-string): Abolished. - -2001-08-18 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (gnus-group-make-shimbun-group): Call - `shimbun-groups' to detect avaiable groups of specified server. - -2001-08-17 KANEMATSU Daiji - - * lisp/message.el (message-signature-separator-for-insertion): New - customizable variable which is used for signature separator. - * lisp/message.el (message-insert-signature): Use variable - `message-signature-separator-for-insertion' instead of hard code. - -2001-08-15 Yoichi NAKAYAMA - - * texi/gnus-ja.texi (Browsing the Web): Fix typo. - -2001-08-13 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 06. - -2001-08-10 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-request-article-this-buffer): Insert an - article into `gnus-original-article-buffer' instead of - `gnus-article-buffer'. - -2001-07-31 Katsumi Yamaoka - - * lisp/mml2015.el: Require `gnus-clfns' when compiling. - * lisp/gnus-clfns.el (string-to-list): New compiler macro. - -2001-07-30 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-select-newsgroup): Don't examine cached - articles with `gnus-cache-articles-in-group' even if the current - group is not a virtual group (see ChangeLog.1 1999-03-02). - -2001-07-30 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 05. - - * lisp/nnmh.el (nnmh-retrieve-parsed-headers): Abolished. - - * lisp/gnus-sum.el (gnus-get-newsgroup-headers-xover): Don't use - `gnus-retrieve-parsed-headers'. - (gnus-fetch-headers): Ditto. - - * lisp/gnus-int.el (gnus-retrieve-parsed-headers): Abolished. - - * lisp/gnus-cache.el (gnus-cache-braid-headers): Abolished. - (gnus-cache-retrieve-parsed-headers): Abolished. - -2001-07-30 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Bind - `nnmail-expiry-wait-function' to nil if the group's parameter - `expiry-wait' is specified by the user or the shimbun's default - value is provided. - -2001-07-27 Katsumi Yamaoka - - * lisp/gnus-msg.el (gnus-message-make-user-agent): New - implementation. - -2001-07-24 Katsumi Yamaoka - - * lisp/gnus-clfns.el (copy-list): New compiler macro. - -2001-07-23 Katsumi Yamaoka - - * lisp/gnus-delay.el (gnus-delay-initialize): Don't use the macro - `kbd'. - - * lisp/nnheader.el (mm-read-coding-system): New function which is - a substitute for mm-util.el. - -2001-07-19 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 04. - - * lisp/nntp.el (nntp-request-newgroups): Use UTC date for - NEWGROUPS command. - - * lisp/gnus-start.el (gnus-find-new-newsgroups): Use - `message-make-date' instead of `current-time-string'. - (gnus-ask-server-for-new-groups): Ditto. - (gnus-check-first-time-used): Ditto. - -2001-07-17 Katsumi Yamaoka - - * texi/message-ja.texi (message-citation-line-function): Add a - comma just after the `@xref' form. - - * lisp/nnheader.el (nnheader-header-value): Ignore leading - whitespaces. - - * lisp/dgnushack.el (dgnushack-make-auto-load): Advise - `make-autoload' to handle `define-derived-mode'. - -2001-07-12 Katsumi Yamaoka - - * lisp/message.el (message-yank-original): Unwind-protect while - suspending font-lock. - (message-mode): Modify for the following changes. - (message-font-lock-keywords-2): Abolished. - (message-font-lock-keywords-1): Abolished. - (message-font-lock-keywords): Unified. - (message-font-lock-cited-text-matcher): Abolished. - (font-lock-after-change-function): Don't advise it. - (message-font-lock-last-position): Abolished. - (message-font-lock-citation-name-max-column): Abolished. - (message-font-lock-cited-text-regexp) Abolished. - (message-font-lock-fence-close-position): Abolished. - (message-font-lock-fence-open-position): Abolished. - (message-font-lock-fence-close-regexp): Abolished. - (message-font-lock-fence-open-regexp): Abolished. - -2001-07-10 Katsumi Yamaoka - - * lisp/message.el (message-font-lock-keywords-1): Replace regexp - for mml tags with `mime-edit-tag-regexp'. - -2001-07-10 Katsumi Yamaoka - - * lisp/message.el (message-font-lock-keywords-2): Move definitions - for cited texts and mml tags to `message-font-lock-keywords-1'. - -2001-07-10 Katsuhiro Hermit Endo - - * texi/gnus-ja.texi (Mail Group Commands): Fix a slight mistake. - -2001-07-09 Katsumi Yamaoka - - * lisp/dgnushack.el: Add the parent directory of the directory - where the APEL modules are installed to `load-path' according to - the description of the file Mule23@1934. - -2001-07-04 Yair Friedman - - * make.bat: Use infohack.el to create info files. - -2001-07-09 Akihiro Arisawa - - * README.semi: Modify URI of emacs-w3m. - * README.semi.ja: Ditto. - * Mule23@1934.en: Ditto. - * Mule23@1934.ja: Ditto. - * lisp/nnshimbun.el: Ditto. - - * texi/gnus-ja.texi (Top, Article Treatment): Fix typo. - (Web Newspaper): Modify URI of emacs-w3m. - -2001-07-06 KITAGAWA Takurou - - * lisp/Makefile.in (clever): Use `if test... then' instead of - `test... &&'. - -2001-07-06 Katsumi Yamaoka - - * lisp/Makefile.in (clever): Change the quoting style for the - elisp form to check for XEmacs-p. - - * lisp/dgnushack.el: Require `path-util' first, and then search - for the path if it is not found. - -2001-07-05 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. - -2001-06-28 Akitada Koyama - - * texi/gnus-ja.texi (Web Newspaper): Add a description how to show - html documents inline. - -2001-06-28 Katsumi Yamaoka - - * texi/message-ja.texi (message-suspend-font-lock-when-citing): Add - a description. - * texi/message.texi (message-suspend-font-lock-when-citing): Ditto. - - * lisp/message.el (message-yank-original): Suspend font-lock'ing - while citing an original message. - (message-suspend-font-lock-when-citing): New user option. - -2001-06-25 Katsumi Yamaoka - - * lisp/gnus-clfns.el (find-cl-run-time-functions): New - implementation. - -2001-06-22 Katsumi Yamaoka + * lisp/dgnushack.el (dgnushack-unexporting-files): Add + gnus-load.el when using XEmacs. + (dgnushack-dont-compile-files): Add gnus-load.el. + (dgnushack-auto-load-file): Abolish. + (dgnushack-make-auto-load): Don't delete the file specified by + `dgnushack-auto-load-file'. + (dgnushack-compose-package): Abolish. + +2003-08-26 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-treat-display-x-face): Use `set-default' + instead of `custom-set-default' for old Emacsen. + + * lisp/gnus-sum.el + (gnus-summary-search-article-highlight-matched-text): Replace + `gnus-treat-display-xface' with `gnus-treat-display-x-face'. + +2003-08-01 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/search): Small modified to + reduce its spending time. + +2003-07-30 TSUCHIYA Masatoshi + + * gnus-namazu.el (gnus-namazu/group-prefixed-name): Removed. + (gnus-namazu/real-group-name): Removed. + (gnus-namazu/decode-group-name): Removed. + (gnus-namazu/directory-table): New internal variable. + (gnus-namazu/make-directory-table): New function. + (gnus-namazu/search): Call the above function, and use + `gnus-namazu/directory-table' to get a real group name from a file + name. + (gnus-namazu-create-index): Call `gnus-namazu/make-directory-table'. + (gnus-namazu/update-sentinel): Ditto. + (gnus-namazu-update-all-indices): Simplified. + (gnus-namazu-update-indices): New function. + +2003-07-28 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/group-prefixed-name): Return + the whole name from a given group and a method, only when it + exists. Otherwise, return nil. + (gnus-namazu/possible-real-groups): Removed. + (gnus-namazu/decode-group-name): The successor of the above + function. + (gnus-namazu/real-group-name): Use the above functions, and accept + the third optional argument, `method'. + (gnus-namazu/search): Change the order getting groups and article + numbers from file names. - * lisp/gnus-art.el (article-display-x-face): Don't gather X-Face - fields in `gnus-original-article-buffer'. +2003-07-10 Katsumi Yamaoka -2001-06-18 Katsumi Yamaoka + * lisp/pop3.el: Silence the byte-compiler when modifying + `byte-compile-function-environment' for `md5' under latest Emacs. - * lisp/nnshimbun.el (nnshimbun-find-parameter): Undo the last - bogus changes; use the value of `nnshimbun-pre-fetch-article' if - the value of the group parameter `prefetch-articles' is nil; do - likewise for `encapsulate-images'. + * texi/ptexinfmt.el (texinfo-discard-command-and-arg): Revive it + for Mule 2. -2001-06-18 Katsumi Yamaoka +2003-07-01 TAKAHASHI Kaoru - * lisp/nnshimbun.el (nnshimbun-find-parameter): Use the value of - `nnshimbun-pre-fetch-article' if the value of the group parameter - `prefetch-articles' is `off'; do likewise for `encapsulate-images'. + * texi/ptexinfmt.el: @verb, @tie, @/ support. + (ptexinfmt-broken-facility): Abolish NO-NOTICE argument. + Use `ptexinfmt-disable-broken-notice-flag' instead. -2001-06-18 Katsumi Yamaoka +2003-06-26 Katsumi Yamaoka - * lisp/nnshimbun.el (nnshimbun-encapsulate-images): Fix a - doc-string that both the values `off' and nil specifies not to - encapsulate images. - (nnshimbun-pre-fetch-article): Default to `off'. + * texi/infohack.el (infohack-texi-format): Include other files + first. -2001-06-18 Katsumi Yamaoka +2003-06-19 Katsumi Yamaoka - * lisp/nnshimbun.el (nnshimbun-encapsulate-images): Renamed from - `nnshimbun-encapsulate-article'. - (nnshimbun-request-article-1): Replace `encapsulate-article' with - `encapsulate-images'. - (nnshimbun-find-parameter): Ditto. - (nnshimbun-group-parameters): Ditto. - (nnshimbun-group-parameters-custom): Ditto. + * lisp/lpath.el: Fbind `read-passwd' for Mule 2. -2001-06-15 TSUCHIYA Masatoshi +2003-06-18 Katsumi Yamaoka - * lisp/nnshimbun.el (nnshimbun-group-parameters-custom): Add - `encapsulate-article' as a customizable option, and modified - `prefetch-articles'. - (nnshimbun-group-parameters): Add document for - `encapsulate-article'. - (nnshimbun-encapsulate-article): New server variable. - (nnshimbun-find-parameter): Add code for `encapsulate-article'. - (nnshimbun-request-article-1): Refer `encapsulate-article' group - parameter to control `shimbun-encapsulate-article' value when - `shimbun-article' is called. + * texi/infohack.el: Require `bytecomp'. -2001-06-14 Katsumi Yamaoka +2003-06-18 Katsumi Yamaoka * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. -2001-06-14 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Use - `nnshimbun-find-parameter'. - (nnshimbun-generate-nov-database): Bind a full group name while - processing. - (nnshimbun-find-parameter): New implementation to refer to the - nnshimbun group parameters. - (nnshimbun-index-range): Add a document that it's just a default. - (nnshimbun-pre-fetch-article): Ditto. - (nnshimbun-group-parameters): Specify a parameter type as `list'. - (TopLevel): Remove the local variable "-*- coding: junet; -*-". - -2001-06-13 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-group-parameters): New group - parameter. It also provides the user option - `nnshimbun-group-parameters-alist' and the function - `nnshimbun-find-group-parameters'. - (nnshimbun-group-parameters-custom): New variable. - (TopLevel): Require `gnus' expressly. - -2001-06-12 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (nnshimbun-find-parameter): New macro. - (nnshimbun-generate-nov-database): Use `nnshimbun-find-parameter'. - (nnshimbun-request-expire-articles): Fixed. - -2001-06-12 Katsumi Yamaoka - - * lisp/nnshimbun.el (Gnus-p): Use `file-exists-p' instead of - `locate-library' to check for the existence of mailcap.el in the - same directory of gnus.el. - (nnshimbun-retrieve-headers-with-nov): Remove a redundant check - that I made. - -2001-06-11 Katsumi Yamaoka - - * lisp/lpath.el: Don't Fbind `xml-node-children'. - -2001-06-11 Akihiro Arisawa - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Fix - inhibiting the expiring when `nnshimbun-keep-unparsable-dated-articles' - is nil. - -2001-06-11 TSUCHIYA Masatoshi - - * lisp/gnus-group.el (toplevel): Removed autoload code for - "nnshimbun". - - * texi/gnus-ja.texi (Web Newspaper): Add documents about - `nnshimbun-index-range'. - -2001-06-11 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Don't - refer to the variable `nnshimbun-keep-last-article', we should - keep the last article anyway. - (nnshimbun-keep-last-article): Abolished. - - * lisp/gnus.el: Autoload "nnshimbun" for the command `gnus-group- - make-shimbun-group'. - -2001-06-11 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el: Remove some garbage. + * lisp/nnshimbun.el: Moved to the emacs-w3m package. -2001-06-10 Katsumi Yamaoka +2003-06-18 Katsumi Yamaoka - * texi/message-ja.texi: Use `iso-2022-7bit' instead of - `iso-2022-7bit-ss2' to keep a compatibility between XEmacsen and - FSF Emacsen. - * texi/gnus-ja.texi: Ditto. + * texi/infohack.el (infohack-texi-format): Encode messages to + terminal while formatting info pages. -2001-06-09 TSUCHIYA Masatoshi +2003-06-16 Katsumi Yamaoka - * lisp/nnshimbun.el (top-level): Updated comments. - (nnshimbun): New customize group. - (nnshimbun-keep-last-article): Defined as customize variable. - (nnshimbun-keep-unparsable-dated-articles): Ditto. - (nnshimbun-insert-nov): Use `when' instead of `if'. - (gnus-group-shimbun-server-history): Imported from - `gnus-group.el'. - (gnus-group-make-shimbun-group): Ditto. - - * lisp/gnus-group.el (gnus-group-make-shimbun-group): Its real - definition is moved to `nnshimbun.el' and autload code is added. - (gnus-group-shimbun-server-history): Its definition is moved to - `nnshimbun.el'. - -2001-06-08 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (nnshimbun-use-entire-index): Removed. - (nnshimbun-index-range): New variable. - (nnshimbun-close-server): Check status strictly to close server - safely. - (nnshimbun-generate-nov-database): Refer the group paramter - `nnshimbun-index-range' as the second parameter of - `shimbun-headers'. - (shimbun-mua-use-entire-index): Removed. - (nnshimbun-request-article-1): Replace a date string in - `gnus-newsgroup-data' only when article header has non-nil value. - (nnshimbun-insert-nov): Fixed condition to decide whether - `X-Nnshimbun-Id' should be inseted or not. - -2001-06-08 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-expire-nov-databases): Removed. - (nnshimbun-request-expire-articles): Simplified; refer to the - shimbun's default expiration days. - -2001-06-08 Katsumi Yamaoka - - * lisp/lpath.el: Fbind `xml-node-children' for XEmacsen and old FSF - Emacsen. - -2001-06-07 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Prefer the - group parameter `expiry-wait' when expiring a closed group. - -2001-06-07 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-request-article-1): Replace a date - string in `gnus-newsgroup-data' based on the newly retrieved - article. - -2001-06-07 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Fix - inhibiting the expiring. - -2001-06-06 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-expire-nov-databases): New command. - (nnshimbun-request-expire-articles): New function. - (nnshimbun-keep-unparsable-dated-articles): New variable. - (nnshimbun-keep-last-article): New variable. - (nnshimbun-insert-nov): Rewrite using `nnshimbun-string-or'. - (nnshimbun-string-or): New macro. - (nnshimbun-tmp-string): New internal variable. - (TopLevel): Require `message' for `message-make-date'. - -2001-05-30 Katsumi Yamaoka - - * lisp/gnus-clfns.el (find-cl-run-time-functions): Remove a - useless non-global var; scroll the output window automatically. - -2001-05-31 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (nnshimbun-header-xref): Removed. - (nnshimbun-check-header): Removed. - (nnshimbun-make-shimbun-header): Don't call - `nnshimbun-header-xref'. - (nnshimbun-request-group): Simplified. - (nnshimbun-request-article-1): Call `nnshimbun-replace-nov-entry' - instead of `nnshimbun-check-header'. - (nnshimbun-insert-nov): New function. - (nnshimbun-generate-nov-database): Call `nnshimbun-insert-nov' - instead of `nnheader-insert-nov'. - (nnshimbun-replace-nov-entry): New function. - -2001-05-29 Katsumi Yamaoka - - * lisp/gnus-clfns.el (find-cl-run-time-functions): Add a parser for - `dolist'; protect against errors. - -2001-05-29 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-retrieve-headers-with-nov): Don't - use `last'. - (nnshimbun-make-shimbun-header): Use the following macros. - (nnshimbun-mail-header-from): New macro whose definition will be - changed statically for Gnus or gnus. - (nnshimbun-mail-header-subject): Ditto. - (TopLevel): Don't require `gnus-clfns'. - - * lisp/gnus.el: Add autoload for `find-cl-run-time-functions'. - - * lisp/gnus-clfns.el (find-cl-run-time-functions): New command for - the developers. - (cl-run-time-functions): New variable. - (TopLevel): Don't require `cl' at run-time. - -2001-05-28 TSUCHIYA Masatoshi - - * texi/gnus-ja.texi (Web Newspaper): Updated. - -2001-05-28 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-unexporting-files): Add - "nnshimbun.el" if the library "shimbun" is not found. - (TopLevel): Add "/somewhere/apel/" to `load-path' if it is needed. - (locate-library): Redefine it for Mule before it is called. - - * README.semi.ja: Update for the use of Emacs-W3M. - * README.semi: Ditto. - * Mule23@1934.ja: Ditto. - * Mule23@1934.en: Ditto. - -2001-05-28 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el: Reconstructed to use `shimbun'. - - * lisp/gnus-group.el (gnus-group-make-shimbun-group): - Reconstructed to use `shimbun'. - - * lisp/dgnushack.el (toplevel): Add paths if and only if APEL and - FLIM can't be found. - -2001-05-17 Kai =?iso-8859-1?q?Gro=DFjohann?= - - * etc/Makefile.in (datadir): Set this variable, like in the other - Makefile.in's. Patch from Gaute B Strokkenes . - -2001-05-16 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Don't ignore - `widget-convert-button', `widget-create' and `widget-put'; ignore - `defface'. - -2001-05-14 Katsumi Yamaoka - - * lisp/gnus.el: Require `base64' if `base64-encode-string' is not a - built-in function. - - * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Ignore - `defgroup'. - -2001-05-14 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + * lisp/message.el (message-check-news-header-syntax): Replace + `mail-extract-address-components' with + `std11-extract-address-components'. + (message-sendmail-envelope-from): Ditto. + (message-buffer-name): Ditto. + (message-do-send-housekeeping): Ditto. - * lisp/nnmail.el: Don't bind the colon keywords here. - * lisp/gnus.el (gnus-colon-keywords): New variable which will - default to the value of `dgnushack-colon-keywords'; bind them. - * lisp/dgnushack.el (dgnushack-unexporting-files): Add - dgnuskwds.el. - (dgnushack-colon-keywords): New constant which will have the colon - keywords shuld be bound at run-time for old Emacsen; cache them in - the file dgnuskwds.el and bind them. - (dgnushack-bind-colon-keywords): New function. - (locate-library): Make the function to be silent for Mule. - * lisp/Makefile.in (clean): Remove dgnuskwds.el. +2003-06-10 TSUCHIYA Masatoshi -2001-05-07 Katsumi Yamaoka + * lisp/message.el (message-yank-original): When + `message-reply-headers' is equal to nil, do not reset its + message-id and references. - * lisp/message.el (message-maybe-encode): Don't use - `end-of-invisible'. + * .cvsignore, etc/.cvsignore, lisp/.cvsignore, texi/.cvsignore, + texi/ps/.cvsignore: Created. -2001-05-07 Katsumi Yamaoka +2003-06-09 Katsumi Yamaoka - * lisp/gnus-vers.el: T-gnus 6.15.4 revision 00. + * lisp/message.el (message-fix-before-sending): Don't check for + `illegible text' messages (see the comment). -2001-04-27 Katsumi Yamaoka +2003-05-22 Katsumi Yamaoka * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. - * lisp/gnus-art.el (gnus-article-mime-edit-exit): Set buffer to - `gnus-article-buffer' just before `gnus-article-prepare-display' is - called. - (gnus-article-mime-edit-article-setup): Ditto. - (gnus-article-prepare-display): Don't bind `buffer-read-only' - because of `inhibit-read-only'; don't set the value of - `gnus-article-current-summary' here; delete all extents or overlays - and clear the value of `gnus-button-marker-list' in advance; make - it to run in `gnus-article-buffer'. - (gnus-article-prepare): Make it to run in `gnus-article-buffer'. - (article-toggle-headers): Don't bind `buffer-read-only' because of - `inhibit-read-only'. - (article-hide-headers): Ditto. - -2001-04-16 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.3 revision 00. - -2001-04-16 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.2 revision 00. - -2001-04-16 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.1 revision 00. - -2001-04-13 Katsumi Yamaoka - - * lisp/lpath.el: Fbind `xml-parse-region' for XEmacsen and old FSF - Emacsen; don't bind `mh-lib-progs'. - -2001-04-10 Katsumi Yamaoka - - * lisp/nnshimbun.el: Enclose w3m stuff with `eval-and-compile'; - bind `w3m-work-buffer-name' and `w3m-retrieve' when compiling. - -2001-04-09 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 10. - -2001-04-03 TSUCHIYA Masatoshi - - * lisp/nnshimbun.el (nnshimbun-type-definition: Follow changes in - asahi.com. - (nnshimbun-asahi-get-headers): Ditto. - (nnshimbun-retrieve-url): Use `w3m-retrieve' if it is available. - -2001-04-02 Katsumi Yamaoka - - * lisp/gnus-msg.el (gnus-inews-yank-articles): Make it to work with - multiple articles even if there is a detached minibuffer frame on - some window managers. - -2001-03-21 Thierry Emery +2001-07-11 18:00:00 ShengHuo ZHU - * lisp/mm-decode.el (mm-copy-to-buffer): Copy buffer in unibyte - mode. + We thank to Thierry Emery who + made it notice that there was a change to have to be merged from + Gnus. -- 2003-05-21 ky -2001-03-19 Katsumi Yamaoka + * lisp/nnfolder.el (nnfolder-read-folder): Force to use a + multibyte buffer. - * lisp/gnus-kill.el (gnus-execute): Work with the extra headers. - * lisp/gnus-sum.el (gnus-summary-execute-command): Ditto. +2003-05-21 ARISAWA Akihiro -2001-03-13 Katsumi Yamaoka + * lisp/gnus-msg.el (gnus-message-make-user-agent): Don't use `@' + for rfc2616 compliance. - * lisp/message.el (message-fix-before-sending): Hide again the - invisible property of encoded binary data parts after checking is - done. - (message-find-invisible-regions): New function. - (message-save-drafts, message-send): Inherit the invisible property - of encoded binary data parts to make MIME-Edit find the MIME part - boundaries. +2003-05-20 Katsumi Yamaoka - * lisp/dgnushack.el (dgnushack-compose-package): Tidy up. - (dgnushack-make-load): Ditto. - -2001-03-12 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-compose-package): New function. - (dgnushack-make-load): Add autoload for cus-load if it is missing. - - * lisp/Makefile.in (compose-package): Use - `dgnushack-compose-package'. - (clean, clever): Remove custom-load.el. - - * Makefile.in (elclean): Remove custom-load.el. - -2001-03-08 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-prepare-display): Setup MIME - entity even if `gnus-show-mime' is nil. - -2001-03-08 Katsumi Yamaoka - - * lisp/dgnushack.el: Load gnus-clfns.el after `load-path' is - adjusted. - - * lisp/gnus-clfns.el (string): New compiler macro. - (string): Defun-maybe as an ordinary function since it won't be - provided in cl. - * lisp/gnus-score.el (gnus-score-find-bnews): Use it as Gnus does. - -2001-03-06 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-retrieve-url): Check if - `url-current-mime-charset' is bound. - -2001-03-04 Katsumi Yamaoka - - * lisp/gnus.el (gnus-info-find-node): Pretend to be - `gnus-article-mode' in the article buffer. - -2001-03-02 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-kinsoku-eol-list): Simplified. - (nnshimbun-kinsoku-bol-list): Ditto. - -2001-03-01 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 09. - - * lisp/gnus-offline.el (gnus-offline-get-menu-items): Rewrite using - `dolist'. - - * lisp/gnus-group.el (gnus-group-make-shimbun-group): Simplified. - - * lisp/dgnushack.el: Load cl-macs to ensure that the macro `dolist' - is defined properly. - -2001-02-28 Katsumi Yamaoka - - * lisp/nnwfm.el: Require `gnus-clfns' when compiling. - * lisp/nnshimbun.el: Ditto. - * lisp/nnfolder.el: Ditto. - * lisp/mm-util.el: Ditto. - * lisp/gnus-vers.el: Ditto. - * lisp/gnus-sum.el: Ditto. - * lisp/gnus-score.el: Ditto. - * lisp/gnus-nocem.el: Ditto. - - * lisp/gnus-ofsetup.el: Don't require `gnus-clfns'. - (gnus-ofsetup-customize-done): Use `dolist' instead of `mapc'. - (gnus-setup-for-offline): Ditto. - - * lisp/gnus-offline.el: Don't use `mapc' for binding some vars; - don't require `gnus-clfns'. - - * lisp/gnus-clfns.el (subseq, merge, coerce, butlast): New compiler - macros. - (mapc): Remove. - - * lisp/gnus-art.el: Use `dolist' instead of `mapcar' for defining - `gnus-article-read-summary-keys'. - -2001-02-28 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-mime-edit-article-setup): Leave - the forwarded parts undecoded. - (gnus-article-decode-article-as-default-mime-charset): Set the - value of `default-mime-charset' buffer-locally. - -2001-02-27 Katsumi Yamaoka - - * lisp/gnus.el: Add autoloads for - `gnus-summary-digest-post-forward' and - `gnus-summary-digest-mail-forward'. - - * lisp/gnus-sum.el (gnus-summary-post-menu): Replace - `gnus-uu-digest-mail-forward' and `gnus-uu-digest-post-forward' - with `gnus-summary-digest-post-forward' and - `gnus-summary-digest-mail-forward'. - - * lisp/gnus-msg.el (gnus-summary-digest-post-forward): Restore and - repair the command `gnus-summary-post-digest' and rename it. - (gnus-summary-digest-mail-forward): Ditto. - (gnus-summary-send-map): Replace `gnus-uu-digest-mail-forward' and - `gnus-uu-digest-post-forward' with - `gnus-summary-digest-post-forward' and - `gnus-summary-digest-mail-forward'. - -2001-02-27 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-summary-show-article): Bind - `gnus-inhibit-treatment' to t while fetching the raw article. - - * lisp/gnus-art.el (gnus-article-mime-edit-exit): Bind - `mime-edit-insert-user-agent-field' to nil while `mime-edit-exit' - is being done; turn off font-lock first; query if the buffer is - modified. - (gnus-article-mime-edit-done): New function. - (gnus-article-mime-edit-article-setup): Make the window fill its - frame; clear the buffere modified flag; substitute key definition - `gnus-article-edit-done' with `gnus-article-mime-edit-done'; don't - turn off font-lock here; bind `mime-edit-insert-user-agent-field' - to nil while `mime-edit-exit' is being done. - (gnus-article-mime-edit-article-unwind): Turn off font-lock first. - -2001-02-23 Katsumi Yamaoka - - * lisp/dgnushack.el: Don't require `emu'. - -2001-02-16 Katsumi Yamaoka - - * lisp/message.el (message-forward-subject-author-subject): Decode - `From' field. - -2001-02-16 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 08. - - * lisp/gnus-sum.el (gnus-get-newsgroup-headers-xover): Don't use - `gnus-retrieve-parsed-headers' when the backend is nnimap. It is - only a temporary fix for an infloop on nnimap. FIXME!!! - (gnus-select-newsgroup): Ditto. - -2001-02-16 Katsumi Yamaoka - - * texi/gnus-ja.texi (New features in Gnus 5.8): Remove annotation - about `gnus-article-display-hook.' - * texi/gnus-faq-ja.texi (Q2.1): Remove mention of - `gnus-article-display-hook.' - - * lisp/gnus.el (gnus-article-display-hook): Abolished. - - * lisp/gnus-uu.el (gnus-uu-grab-articles): Don't care about - `gnus-article-display-hook'. - * lisp/gnus-sum.el (gnus-summary-show-article): Ditto. - (gnus-summary-search-article): Ditto. - - * lisp/gnus-bbdb.el (gnus-bbdb-insinuate): Use - `gnus-article-prepare-hook' instead of `gnus-article-display-hook'. - - * lisp/gnus-art.el (gnus-article-prepare-display): Evaluate - `gnus-article-prepare-hook' after an article has been prepared; - don't evaluate `gnus-article-display-hook'. - -2001-02-15 Katsumi Yamaoka - - * lisp/message.el (message-cite-original-without-signature): - Extract from field for the simple citation line. - -2001-02-14 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 07. - - * lisp/dgnushack.el (dgnushack-make-autoloads): Remove function. - (dgnushack-make-load): Ignore cus-load.el if it does not exist. - (dgnushack-make-auto-load): Remove auto-autoloads.el. - (dgnushack-make-cus-load): Do nothing if loading cus-dep is failed. - - * lisp/Makefile.in (clean): Remove gnus-load.el instead of - custom-load.el. - (compose-package): Call `gnus-load.elc' and then rename - gnus-load.el(c) to auto-autoloads.el(c) instead of the use of - `dgnushack-make-autoloads'. - (clever): No need to remove custom-load.el. - - * Makefile.in (elclean): Remove gnus-load.el instead of - custom-load.el. - - * aclocal.m4 (AC_CHECK_URL): Ignore cache. - -2001-02-13 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 06. - -2001-02-11 18:00:00 ShengHuo ZHU - - * GNUS-NEWS: Copyright and others. - -2001-02-09 20:00:00 ShengHuo ZHU - - * aclocal.m4 (AC_CHECK_URL): Add. - - * configure.in: Use it. - -2001-02-08 Katsumi Yamaoka - - * lisp/nnshimbun.el (nnshimbun-fml-get-headers): Fix unbalanced - parentheses. - -2001-02-08 Akihiro Arisawa - - * lisp/nnshimbun.el: Add `bbdb-ml' support. - -2001-02-02 Akihiro Arisawa - - * lisp/nnshimbun.el (nnshimbun-type-definition): Follow URL change - of `xemacs'. - (nnshimbun-xemacs-get-headers): Ditto. - -2001-02-06 Katsumi Yamaoka - - * README-gnus-bbdb.{en,ja}: Update the patch for BBDB v2.2. - -2001-02-01 Katsumi Yamaoka - - * texi/Makefile.in (.texi, %.info): Don't use makeinfo command when - gnus-ja.texi or message-ja.texi is given. It is needed for some - make command if which can not understand "%-ja:" or "%-ja.info:". - -2001-01-31 Katsumi Yamaoka - - * lisp/gnus-sum.el (gnus-summary-display-article): Replace - `mm-enable-multibyte-mule4' with `set-buffer-multibyte'. - -2001-01-29 Katsumi Yamaoka - - * lisp/gnus-art.el (gnus-article-mime-edit-exit): Use - `buffer-substring-no-properties' instead of `format'. - -2001-01-23 TAKAHASHI Kaoru - - * texi/ptexinfmt.el: Support @letterpaper and @afivepaper. - -2001-01-22 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 05. - - * Makefile.in (install-package-lisp): Use - `install-without-compiling' instead of `install'. - - * lisp/Makefile.in (install): Use `install-without-compiling'. - (install-without-compiling): New target. - -2001-01-22 Katsumi Yamaoka - - * texi/Makefile.in (.texi, %.info, %-ja.info, %-ja): Use - `infohack-texi-format'. - - * texi/infohack: (infohack-texi-format): New function. - * lisp/dgnushack.el (dgnushack-texi-format): Move to - texi/infohack.el and rename. - (dgnushack-texi-add-suffix-and-format): Remove. - - * texi/ptexinfmt.el: New file. - * lisp/ptexinfmt.el: Move to texi/. - -2001-01-18 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 04. - -2001-01-17 Katsumi Yamaoka - - * lisp/dgnushack.el (dgnushack-make-autoloads): Do nothing if the - files for autoloads already exist. - (dgnushack-unexporting-files): More useful message. - - * lisp/Makefile.in (install): Call `clever' before installing. - (install-lisp): Remove. - (clever): Check for whether the all elc files should be recompiled. - - * Makefile.in (xclever): New target. - (install-package-lisp): Replace `install-lisp' with `install'. - (install-package-ja): Replace `xlick' with `xclever'. - (install-package): Ditto. - -2001-01-17 KOSEKI Yoshinori - - * Makefile.in: Unset `PWD' for Meadow/NTEmacs. - -2001-01-15 Jesper Harder - - * make.bat: Fix doc. - -2001-01-15 Katsumi Yamaoka - - * lisp/nnheader.el: Require `pces', `poem' and `std11' to reduce - the required value of `recursive-load-depth-limit' for Emacs 21. - - * lisp/message.el (message-followup): Handle "Mail-Copies-To:" - correctly. - (message-get-reply-headers): Ditto. - -2001-01-15 Keiichi Suzuki - - * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Save excursion - while `bbdb-annotate-message-sender' is being done. - -2001-01-13 Kinji Itoh - - * Makefile.in (install-package-lisp): Specify EMACS=$(XEMACS). - -2001-01-11 Katsumi Yamaoka - - * lisp/gnus-msg.el (gnus-copy-article-buffer): Remove smiley - extents for XEmacs 21.1 using `format'. - - * lisp/dgnushack.el (dgnushack-texi-format): Cancel last change. - -2001-01-10 Katsumi Yamaoka - - * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. + * lisp/gnus-msg.el (gnus-message-make-user-agent): Check whether + Mule 2 is running. - * lisp/gnus.el: Don't autoload "smiley" for `smiley-toggle-buffer'; - don't autoload "gnus-bitmap" or "x-face-mule" when Emacs 21 is - running. +2003-05-14 ARISAWA Akihiro - * lisp/gnus-art.el (TopLevel): Autoload "gnus-bitmap" for - `smiley-toggle-buffer' when compiling. - (gnus-treatment-function-alist): Use `gnus-smiley-display' for - `gnus-treat-display-smileys' by default when XEmacs or Emacs 21 is - running. - (gnus-treat-display-smileys): Check for `smiley-mule' instead of - `gnus-bitmap'. - (gnus-article-x-face-command): Don't check for xbm for x-face-e21. + * lisp/gnus-msg.el (gnus-user-agent): Added `gnus-mime-edit'. + (gnus-inews-add-send-actions): Use `gnus-message-make-user-agent' + instead of `gnus-extended-version'. + (xemacs-codename): Defvar while compiling. + (gnus-message-make-user-agent): Use `gnus-user-agent'. -2001-01-05 Katsumi Yamaoka + * lisp/message.el (message-make-user-agent): If the "User-Agent" field + has alread exist, remove it. - * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. +2003-05-14 Katsumi Yamaoka - * lisp/dgnushack.el (dgnushack-texi-format): Remove "@anchor" if it - is not supported. + * lisp/gnus-vers.el: T-gnus 6.16.2 revision 00. -2000-12-26 Katsumi Yamaoka +2003-05-05 Daiki Ueno - * lisp/gnus.el: Bind `:parameter-type', `:parameter-document', - `:function', `:function-document', `:variable', - `:variable-document', `:variable-group', `:variable-type' and - `:variable-default' for old Emacsen. + * lisp/gnus-sum.el (gnus-summary-toggle-header): Call + article-decode-encoded-words explicitly. -2000-12-22 Katsumi Yamaoka +2003-05-02 Katsumi Yamaoka * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. - * configure: Regenerate. - * configure.in: Add `AC_PATH_ETCDIR'. - * Makefile.in (install-etc): New target. - - * lisp/nnheader.el (mm-image-load-path): Alias to - `nnheader-image-load-path'. - (nnheader-image-load-path): New function copied from - the function `mm-image-load-path' in mm-util.el. - - * lisp/drums.el: Remove. - -2000-12-22 03:00:00 ShengHuo ZHU - - * configure.in: Add etc/Makefile. - -2000-12-22 Katsumi Yamaoka - - * lisp/gnus-msg.el (gnus-debug): Use `sit-for' in the inside of - `save-excursion'. - (gnus-bug): Pop up the sending buffer first. - - * lisp/gnus-art.el (article-treat-dumbquotes): Quote backslashes in - doc-string. - - * lisp/dgnushack.el - (byte-compile-file-form-custom-declare-variable): Use `defvar' - instead of `custom-declare-variable' to make the variable - uncustomizable if the arguments has the keyword `:version'. - -2000-12-22 Katsuhiro Hermit Endo - - * README.semi.ja: Fix typo. - -2000-12-21 Katsumi Yamaoka - - * lisp/lpath.el: Fbind `compose-mail' for Mule. - - * lisp/dgnushack.el (TopLevel): Byte-optimize - `custom-declare-variable', `custom-declare-group, and - `custom-declare-face' to omit unsupported keywords when Mule is - running. - -2000-12-20 Katsumi Yamaoka - - * lisp/gnus-vers.el: T-gnus 6.15.0 revision 00. - - * lisp/dgnushack.el (TopLevel): Advise `custom-handle-keyword' not - to signal an error when Mule is running. - (TopLevel): Bind `:ascent', `:foreground', `:help', `:version' and - `:set-after' if colon keyword is not available. - (TopLevel): Require `custom'. - - * lisp/lpath.el (TopLevel): Fbind `shell-command-to-string' for - Mule. - (TopLevel): Don't require `custom' here. + * lisp/nnheader.el: Don't use `defun-maybe' for the extra std11- + stuff. -2000-12-20 Jesper Harder +2003-05-02 Katsumi Yamaoka - * make.bat: set max-lisp-eval-depth. + * lisp/gnus-vers.el: T-gnus 6.16.1 revision 00. -See ChangeLog.3 for earlier changes. +See ChangeLog.4 for earlier changes. ;; Local Variables: ;; coding: iso-2022-7bit diff --git a/ChangeLog.4 b/ChangeLog.4 new file mode 100644 index 0000000..aacb375 --- /dev/null +++ b/ChangeLog.4 @@ -0,0 +1,2822 @@ +2003-05-01 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.24 revision 00. + +2003-05-01 Jesper Harder + + * etc/gnus-tut.txt (http): Update. + +2003-05-01 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.23 revision 00. + +2003-05-01 Simon Josefsson + + * GNUS-NEWS: Add prefix limit feature. + +2003-05-01 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.22 revision 00. + +2003-05-01 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.20 revision 00. + +2003-04-30 Reiner Steib + + * GNUS-NEWS: Added Article Buttons. Added Upgrading (from Simon + Josefsson). Add gnus-mime-delete-part, markup fixes and some + other corrections. Mention Gnus FAQ. + +2003-04-30 Jesper Harder + + * GNUS-NEWS: Additions. + +2003-04-30 Katsumi Yamaoka + + * lisp/lpath.el: Bind `default-mime-charset-unlimited'. + +2003-04-29 Katsumi Yamaoka + + * lisp/dgnushack.el: Autoload font-lock and nnheader for XEmacs + -no-autoloads. + + * lisp/pop3.el: Require `advice' for compiling it in Gnus. + +2003-04-28 Reiner Steib + + * GNUS-NEWS: Fixed X-Draft-Headers entry. + +2003-04-28 Katsumi Yamaoka + + * lisp/dgnushack.el: Make sure `dolist' is available; require + `advice' before `path-util'; revoke the bogus change of 2003-04-17 + (removing function bindings for XEmacs). + (dgnushack-remove-extra-files-in-package): Clear the value for + `command-line-args-left'. + (dgnushack-install-package-manifest): Ditto. + + * texi/infohack.el: Load dgnushack.el and ptexinfmt.el first. + +2003-04-27 Simon Josefsson + + * GNUS-NEWS: Fix PGP entry. Doc GCC variable change. + +2003-04-28 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.19 revision 00. + +2003-04-24 Katsumi Yamaoka + + * lisp/nnheader.el (nnheader-coding-system-p): New function. + (mm-coding-system-p): Alias to `nnheader-coding-system-p'. + +2003-04-23 Katsumi Yamaoka + + * lisp/gnus-clfns.el (coerce, copy-list, merge, string, subseq): + Comment out those compiler macros. + (mapc): Make it comeback. + +2003-04-22 Reiner Steib + + * make.bat: Flag as binary to ensure DOS line terminators. Delete + trailing whitespace. + +2003-04-21 Reiner Steib + From Frank Schmitt + + * etc/gnus-tut.txt: Update Gnus FAQ, delete trailing whitespace. + +2003-04-17 Katsumi Yamaoka + + * Makefile.in (xclever-package, xlick-package): New rules. + (install-package, install-package-ja, package, package-ja): Use + them. + (install-package-manifest, remove-extra-files-in-package, + compose-package): Specify the lisp directory for XEmacs package. + + * aclocal.m4 (AC_PATH_INFO_DIR): Say a note for XEmacs package. + + * lisp/dgnushack.el: Remove useless function bindings for XEmacs. + (dgnushack-install-package-manifest): Create the pkginfo directory. + + * lisp/lpath.el: Fbind `compare-strings' for Mule 2. + +2003-04-17 Kevin Greiner + + * make.bat: Cleaned up end-of-line characters. + +2003-04-17 Steve Youngs + + * Makefile.in (XEMACS): Use @EMACS@. + + * aclocal.m4 (AC_PATH_LISPDIR): Set $datadir to $prefix/lib if + building with XEmacs. + + * aclocal.m4 (AC_SET_BUILD_FLAGS): New. So we can set XEmacs + command line options to '-batch -no-autoloads...' for a cleaner + build environment. + + * configure.in: Use it. + + * configure: Regenerate. + +2003-04-16 Reiner Steib + From Frank Schmitt + + * make.bat: New variable EMACS_ARGS. Changed XEmacs args. + +2003-04-13 Katsumi Yamaoka + + * lisp/lpath.el: Fbind `coding-system-base' for Mule 2. + +2003-04-13 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.18 revision 00. + + * lisp/message.el (message-forward-subject-name-subject): Rewrite. + + * lisp/mail-source.el (mail-source-fetch-pop): Require `pop3' + explicitly. + (mail-source-check-pop): Ditto. + +2003-04-07 Katsumi Yamaoka + + * lisp/nnmail.el (nnmail-split-it): Revoke the change of 1999-08-19. + +2003-04-03 Katsumi Yamaoka + + * lisp/pop3.el (pop3-uidl-support): Default to nil; change the + meaning of a value which it may contain into an alist of servers + and flags of whether they support UIDLs. + (pop3-get-message-numbers): Don't check uidls when + `pop3-leave-mail-on-server' is nil; synch it with the change of + `pop3-uidl-support'. + (pop3-get-uidl): Synch it with the change of `pop3-uidl-support'. + +2003-03-31 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.17 revision 00. + +2003-03-24 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-x-face-command): Don't examine + functions if `noninteractive'. + (gnus-article-should-use-smiley-mule): Don't examine values if + `noninteractive'. + (gnus-treat-display-face): Default to nil if x-face-e21 is + available. + (gnus-treat-display-smileys): Don't examine values if + `noninteractive'. + + * lisp/message.el (message-yank-original): Check not only the + References field but the `message-reply-headers' variable. + + * lisp/imap.el (imap-tls-open): Don't bind coding-systems; use + `set-buffer-multibyte' instead of `imap-disable-multibyte'. + + * lisp/tls.el: Require `pces'. + (open-tls-stream): Use `as-binary-process'. + +2003-03-23 Simon Josefsson + + * GNUS-NEWS: Add IDNA. Add TLS. Fix USEFOR reference. + +2003-03-22 Frank Schmitt + + * make.bat: Redone from scratch; supports both Emacs and XEmacs + now; correctly generate gnus-load.el; check for errors; use + makeinfo if available, infohack.el if it isn't; be less verbose + when copying files; copy files from etc/gnus and etc/smilies, too + +2003-03-22 Frank Schmitt + + * make-x.bat: Removed, make.bat does its job now. + +2003-03-22 Frank Schmitt + + * etc/gnus-tut.txt: Include Gnus FAQ from http://my.gnus.org. + +2003-03-18 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.16 revision 00. + +2003-03-04 Katsumi Yamaoka + + * lisp/gnus-ofsetup.el: Don't require `read-passwd'; don't set + `mail-source-read-passwd' and `gnus-setup-news-hook'. + + * contrib/passwd.el: New file. + +2003-02-20 Katsumi Yamaoka + + * lisp/gnus-offline.el (gnus-offline-add-custom-header): Use + insert instead of insert-string which is obsolete in Emacs 21.4 + (synch to the change of Jesper Harder at 2003-02-20). + +2003-02-19 Reiner Steib + + * GNUS-NEWS: Renamed `gnus-unsightly-citation-regexp' to + `gnus-cite-unsightly-citation-regexp'. + +2003-02-18 Simon Josefsson + + * GNUS-NEWS: Talk about canlock more. + +2003-02-13 Kai Gro,A_(Bjohann + + * GNUS-NEWS: Add user visible changes from Michael Shields from + the past couple of days. Actual text from Michael. + +2003-02-09 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.15 revision 00. + +2003-01-25 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.14 revision 00. + +2003-01-24 Jesper Harder + + * etc/gnus-tut.txt: Update. + +2003-01-24 Katsumi Yamaoka + + * texi/infohack.el (infohack-texi-format): Withdraw the change of + 2003-01-17. + +2003-01-21 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.13 revision 00. + +2003-01-17 Katsumi Yamaoka + + * texi/infohack.el (infohack-texi-format): Insert one excessive + newline after a @foo{bar} thing to prevent clinging of a line and + a line (old texinfmt bug?) if it should be considered only one + thing in a line. + +2003-01-17 TSUCHIYA Masatoshi + + * .cvsignore: Import from Oort Gnus. + * contrib/.cvsignore: Ditto. + * etc/.cvsignore: Ditto. + * lisp/.cvsignore: Ditto. + * texi/.cvsignore: Ditto. + * texi/ps/.cvsignore: Ditto. + +2003-01-16 Katsumi Yamaoka + + * lisp/gnus-msg.el (gnus-summary-digest-mail-forward): Set article + numbers to be marked. + +2003-01-02 Lars Magne Ingebrigtsen + + (A forgotten thing to synchronize to Oort Gnus.) + * lisp/gnus-msg.el (gnus-summary-mail-forward): To many lists of + lists. + +2003-01-15 Simon Josefsson + + * GNUS-NEWS: Add. Fix from Reiner Steib + <4uce.02.r.steib@gmx.net>. + +2003-01-14 Katsumi Yamaoka + + * lisp/binhex.el: Require `path-util'. + * lisp/gnus-audio.el: Ditto. + * lisp/spam.el: Ditto. + * lisp/uudecode.el: Ditto. + + * lisp/binhex.el (binhex-use-external): Replace `executable-find' + with `exec-installed-p'. + * lisp/gnus-audio.el (gnus-audio-au-player): Ditto. + (gnus-audio-wav-player): Ditto. + * lisp/spam.el (spam-ifile-path): Ditto. + (spam-bogofilter-path): Ditto. + * lisp/uudecode.el (uudecode-use-external): Ditto. + + * lisp/gnus-int.el (gnus-agent-expire): Make arguments optional. + +2003-01-13 Katsumi Yamaoka + + * lisp/gnus-util.el (gnus-read-event-char): Take an optional + parameter even if Mule 2.3 is running. + +2003-01-10 Reiner Steib + + * make.bat: Removed "-no-init-file" (it's the same as "-q"). Use + new variables EMACSBATCH and GNUS_INFO_DIR. Install gnus-?, + message-?, sieve and pgg (in texi). Added hint for dir entries. + + * make-x.bat: Ditto. + +2003-01-13 Simon Josefsson + + * GNUS-NEWS: Add smileys, Sender:, message-utils. + Expand anti-spam. Fixes. + +2003-01-12 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.12 revision 00. + +2003-01-12 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.11 revision 00. + +2003-01-11 Katsumi Yamaoka + + * lisp/gnus.art.el (gnus-treat-predicate): Don't follow the Change + of Oort Gnus at 2003-01-02; reverted. + + * lisp/message.el (message-tool-bar-map): Commented out MIME-Edit + buttons. + +2003-01-09 Simon Josefsson + + * etc/gnus/preview.xpm: Add. + +2003-01-06 Simon Josefsson + + * etc/gnus/receipt.xpm: Add. + +2003-01-10 Jesper Harder + + * etc/gnus/preview.xbm: Add. + +2003-01-09 Katsumi Yamaoka + + * lisp/message.el (message-tool-bar-map): Fix keymap for MIME-Edit. + +2003-01-09 NAKAJI Hiroyuki + + * README.semi.ja: "What's T-gnus?" is revised. + + * README.semi: Ditto. + +2003-01-07 Keiichi Suzuki + + * lisp/message.el (message-setup-1): Don't call + `message-use-alternative-email-as-from' if it isn't for replying. + +2003-01-05 Katsumi Yamaoka + + * etc/gnus/gnus.xpm (oort): Make the color replaceable. + +2003-01-05 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.10 revision 00. + +2003-01-03 Katsumi Yamaoka + + * lisp/gnus-xmas.el (gnus-xmas-group-startup-message): Bind the + color for the symbol `oort' as `gnus-group-startup-message' does. + +2002-12-31 Katsumi Yamaoka + + * lisp/gnus-start.el (gnus-re-read-newsrc-el-file): Commented out. + (gnus-load): Allow coding-system as an argument. + +2002-12-16 ARISAWA Akihiro + + * lisp/nnimap.el (nnimap-callback): Use `nnimap-demule'. + (nnimap-request-article-part): Ditto. + +2002-12-10 Katsumi Yamaoka + + * texi/Makefile.in (%.info, .texi): Conceal control procedures. + +2002-12-05 Kai Gro,A_(Bjohann + + * etc/smilies/*.pbm: Made them binary. + +2002-11-28 Daiki Ueno + + * lisp/gnus-agent.el (gnus-agent-fetch-headers): Don't refer to + the value of `gnus-agent-file-name'. + +2002-11-28 Daiki Ueno + + * lisp/gnus-agent.el (gnus-agent-fetch-group-1): Article numbers + should be accessed through `mail-header-number'. + +2002-11-24 ARISAWA Akihiro + + * lisp/mm-url.el (mm-url-program): Use `exec-installed-p' instead of + `executable-find'. + +2002-11-13 Kai Gro,A_(Bjohann + + * etc/smilies/blink.xpm: Changed smileys and some new ones from + Alex Schroeder . + +2002-11-12 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-summary-inherit-default-charset): Inherit + the value for `default-mime-charset-unlimited' as well. + (gnus-summary-setup-default-charset): Bind + `default-mime-charset-unlimited' to nil for nndraft:delayed or + nndraft:drafts groups. + + * lisp/gnus-art.el (gnus-article-prepare-display): Don't use + MIME-View for nndraft:delayed or nndraft:drafts groups. + (gnus-article-decode-article-as-default-mime-charset): Don't + decode an article for nndraft:delayed or nndraft:drafts groups. + +2002-11-06 Katsumi Yamaoka + + * lisp/nndraft.el (nndraft-request-article): Don't give a special + treatment to Mule. + + * lisp/nnheader.el (nnheader-auto-save-coding-system): Undo last + change to restore the default value to emacs-mule or escape-quoted. + +2002-11-05 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-mime-edit-article-setup): Don't + perform `mime-edit-again' for a delayed or a queued article. + (gnus-article-mime-edit-done): Bind `inhibit-read-only' to t while + running `gnus-article-edit-done'. + +2002-10-30 TSUCHIYA Masatoshi + + * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Protect + against unexpected data structure. + +2002-10-30 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el: Clean up codes. + (nnshimbun-buffer, nnshimbun-current-directory) + (nnshimbun-current-group, nnshimbun-server-directory): Removed. + (nnshimbun-current-server, nnshimbun-server-directory) + (nnshimbun-current-group, nnshimbun-current-directory): New macros. + (nnshimbun-backlog, nnshimbun-find-parameter): Use + `nnshimbun-current-server'. + (nnshimbun-possibly-change-group, nnshimbun-open-server): + Reimplemented. + (nnshimbun-close-server): Do not kill `nnshimbun-buffer'. + (nnshimbun-request-article-1, nnshimbun-request-list): Use + `erase-buffer' instead of `delete-region'. + (nnshimbun-request-article): Use `nnshimbun-current-group'. + (nnshimbun-request-group): Remove redundant checks. + (nnshimbun-request-scan): Check arguments strictly. + (nnshimbun-retrieve-headers, nnshimbun-retrieve-headers-with-nov): + Reimplemented. + (nnshimbun-generate-nov-database, nnshimbun-search-id) + (nnshimbun-write-nov, nnshimbun-request-expire-articles): + Simplified. + (nnshimbun-nov-buffer-name, nnshimbun-nov-file-name): Make the + first argument optional. + (nnshimbun-open-nov): Bind variables to set coding systems for + path names. + (nnshimbun-possibly-change-group, nnshimbun-request-article) + (nnshimbun-write-nov): Strict checking. + (nnshimbun-request-expire-articles): Small fix. + +2002-10-29 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 05. + + * lisp/nnheader.el (nnheader-auto-save-coding-system): Default to + `iso-2022-7bit'. + +2002-10-29 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-request-article-1): Install trick + to keep compatibility between T-gnus and Oort Gnus. + +2002-10-29 Tadashi Watanabe + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Do not + use removed variables. + +2002-10-29 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el: Clean up. + (nnshimbun-nov-last-check): Removed. + (nnshimbun-nov-buffer-alist): Removed. + (nnshimbun-nov-buffer-file-name): Removed. + (nnshimbun-close-server): Use `nnshimbun-write-nov' instead of + `nnshimbun-save-nov'. + (nnshimbun-mail-header-subject): Removed. + (nnshimbun-mail-header-from): Removed. + (nnshimbun-make-shimbun-header): Removed. + (nnshimbun-parse-nov): New function. + (nnshimbun-request-article-1): Use `nnshimbun-parse-nov' instead + of `nnheader-parse-nov'. + (nnshimbun-retrieve-headers): Likewise. + (nnshimbun-nov-buffer-name): New function. + (nnshimbun-nov-file-name): Ditto. + (nnshimbun-open-nov): Clean up. + (nnshimbun-write-nov): Ditto; Aceept the 2nd optional argument. + (nnshimbun-save-nov): Removed. + +2002-10-18 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-dont-compile-files): New constant + containing almost all mm*.el. + (dgnushack-compile): Don't byte-compile the file in + `dgnushack-dont-compile-files'. + +2002-10-09 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 04. + (gnus-version): T-gnus supports SEMI 1.14 and FLIM 1.14. + + * lisp/mmgnus.el: Remove commented obsolete definitions. + + * lisp/message.el (message-header-hook): Replace + `eword-encode-header' with `mime-encode-header-in-buffer'. + (message-send-mail-with-smtp): Don't use `smtp-via-smtp'. + +2002-10-07 Katsumi Yamaoka + + * lisp/mm-url.el (mm-url-form-encode-xwfu): Use + `file-coding-system' instead of `buffer-file-coding-system' when + Mule 2 is running. + + * lisp/gnus-group.el: Require `mm-url' only when compiling. + (gnus-group-fetch-charter): Require `mm-url'. + + * lisp/gnus.el (gnus-default-charset): Default to `iso-8859-1'. + +2002-09-13 TSUCHIYA Masatoshi + + * lisp/nnheader.el (toplevel) [XEmacs]: Remove code to define + `emacs-mule' coding-system, because the generated coding system is + not compatible to the original coding system of FSF Emacs. + +2002-09-12 TSUCHIYA Masatoshi + + * lisp/nnheader.el (toplevel) [XEmacs]: Define `emacs-mule' coding + system in order to cancel difference on coding systems of + auto-saved files between FSF Emacs and XEmacs. + (nnheader-auto-save-coding-system) [Mule]: The default value of + Mule2 is changed from `*junet*' to `*internal*', in order to unify + coding system of files auto-saved by Mule2. + +2002-09-08 Daiki Ueno + + * lisp/gnus-msg.el (gnus-configure-posting-styles): Follow the + change of arglist of gnus-configure-posting-style. + (gnus-configure-posting-style): Check circular import. + +2002-09-08 Daiki Ueno + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. + + * lisp/gnus-msg.el (gnus-named-posting-styles): Defcustom. + (gnus-posting-styles): Allow (import "..."). + (gnus-configure-posting-style): Splitted from + gnus-configure-posting-styles. + (gnus-summary-execute-command-with-posting-style): Fix prompt string. + + * lisp/gnus-cus.el (gnus-group-parameters): Allow (import "...") + in posting-styles. + +2002-09-08 Daiki Ueno + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. + + * lisp/gnus-msg.el (gnus-named-posting-styles): New variable. + (gnus-summary-send-map): Bind "P" to + gnus-summary-execute-command-with-posting-style. + (gnus-configure-posting-styles): Expand named entries in + gnus-posting-styles. + (gnus-summary-execute-command-with-posting-style): New command. + +2002-09-06 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + + * lisp/gnus-msg.el (gnus-copy-article-buffer): Set a copy buffer + mutibyte; remove invisible and intangible test properties from a + copied article. + +2002-09-05 TAKAHASHI Kaoru + + * texi/ptexinfmt.el: discard @documentdescription. Support + @ifplaintext, @ifnotplaintext, @ifhtml. Remove obsolete commands. + (texinfo-format-ifhtml, texinfo-format-ifplaintext): New function. + +2002-09-04 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/highlight-words): Stricten + regular expression to highlight keywords. + +2002-08-28 Katsumi Yamaoka + + * lisp/lpath.el: Fbind `smtpmail-send-it' for Mule 2. + +2002-08-26 Katsumi Yamaoka + + * lisp/gnus-util.el (frame-parameter): New function for oldies. + +2002-08-21 Katsumi Yamaoka + + * lisp/gnus.el (gnus-frame): Remove. + +2002-08-11 Katsumi Yamaoka + + * lisp/gnus-vers.el: Fix T-gnus version number. + +2002-08-06 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.8 revision 00. + +2002-08-06 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu-update-index): Handle error + messages printed by Namazu. + (gnus-namazu/update-sentinel): Likewise. + (gnus-namazu-need-path-normalization): Change its default value. + (gnus-namazu/normalize-results): Remove `file://' prefix. + + * texi/gnus-ja.texi (Namazu Groups): Update documents. + + * lisp/gnus-namazu.el (gnus-namazu/update-p): Print error + messages. + (gnus-namazu-update-index): Small clean up. + (gnus-namazu-update-all-indices): Ditto. + +2002-08-05 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el: Bug fix of updating multiple indices. + (gnus-namazu/setup): Call `gnus-namazu-update-all-indices' without + arguments. + (gnus-namazu-create-index): Clean temporary files even if an + indexer is killed. + (gnus-namazu/update-p): New function. + (gnus-namazu-update-all-indices): Reimplemented. + (gnus-namazu-update-index): Call `gnus-namazu/update-p' to decide + whether the specified index will be updated. + (gnus-namazu/update-sentinel): Follow the change of + `gnus-namazu-update-all-indices'. + +2002-08-05 TSUCHIYA Masatoshi + + * lisp/gnus.el (toplevel): Add autoloads for + `gnus-namazu-create-index', and `gnus-namazu-update-all-indices' + and `gnus-namazu-update-index'. + + * lisp/gnus-namazu.el: Support automatically updating multiple + indices. + (gnus-namazu-make-index-interval): Abolished. + (gnus-namazu-index-update-interval): New option. + (gnus-namazu/setup): Call `gnus-namazu-update-all-indices' instead + of `gnus-namazu-make-index'. + (gnus-namazu/mknmz-process): Abolished. + (gnus-namazu/status-file-name): New macro. + (gnus-namazu-make-index, gnus-namazu-make-index-stop, + gnus-namazu/mknmz-sentinel): Removed. + (gnus-namazu/mknmz-cleanup, gnus-namazu/index-old-p): New function. + (gnus-namazu-create-index, gnus-namazu-update-all-indices, + gnus-namazu-update-index, gnus-namazu-stop-update): New command. + (gnus-namazu/update-directories, gnus-namazu/update-process): New + internal variable. + +2002-07-31 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el: Support automatically updating index. + (gnus-namazu-default-index-directory): New constant. + (gnus-namazu-make-index-interval, gnus-namazu-make-index-command, + gnus-namazu-make-index-arguments): New options. + (gnus-namazu/setup): Call `gnus-namazu-make-index'. + (gnus-namazu/real-group-name): Renamed from + `gnus-namazu/check-cache-group'. + (gnus-namazu/cache-group-candidates): Renamed from + `gnus-namazu/cache-group-candidates'. + (gnus-namazu/search): Experimental support of articles covered by + agent. + (gnus-namazu/default-index-directory, gnus-namazu/lapse-seconds, + gnus-namazu/mknmz-sentinel): New internal functions. + (gnus-namazu/mknmz-process): New internal variable. + (gnus-namazu/lock-file-name, gnus-namazu/index-file-name): New + macros. + (gnus-namazu-make-index, gnus-namazu-make-index-stop): New + commands. + +2002-07-30 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/request-list): Removed. + (gnus-namazu/get-current-to): New function. + (gnus-namazu/complete-query): Call the above. + +2002-07-19 Katsumi Yamaoka + + * lisp/pop3.el: Don't autoload "ssl". + (pop3-open-ssl-stream-1): Require `ssl' before binding ssl-* vars. + +2002-07-18 Katsumi Yamaoka + + * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): Remove + a redundancy. + +2002-07-11 TSUCHIYA Masatoshi + + * texi/gnus-ja.texi (Web Newspaper): Update the url of w3m. + +2002-07-05 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-summary-mode-map): Replace + `gnus-article-toggle-headers' with `gnus-summary-toggle-header'. + (gnus-summary-wash-map): Ditto. + (gnus-summary-wash-hide-map): Replace + `gnus-article-toggle-headers' with `gnus-article-hide-headers'. + (gnus-summary-article-menu): Ditto. + + * lisp/gnus.el: Remove autoload for `gnus-article-toggle-headers'. + + * lisp/gnus-art.el (article-toggle-headers): Abolished. + +2002-07-04 Katsumi Yamaoka + + * lisp/dgnushack.el (byte-optimize-form-code-walker): Don't modify + the function definition if the bug has already gone; revert to the + use of `defadvice'. + +2002-07-03 Keiichi Suzuki + + * lisp/gnus-logic.el (gnus-advanced-index): Use luna based index + numbers. + +2002-06-26 Tetsuo Tsukamoto + + * lisp/imap.el (imap-ssl-open-2): Do away with w32-related + workaround I installed on 1999-12-28, i.e. also call + `as-binary-process' in windows-nt. + +2002-06-26 Katsumi Yamaoka + + * contrib/hashcash.el: Require `cl' when compiling. + (hashcash-strip-quoted-names): Replace `subseq' with `substring'. + (mail-add-payment): Allow no `mail-header-separator' in the buffer; + don't use `mapc'. + +2002-06-25 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/truncate-article-list): When + `gnus-large-newsgroup' is equal to nil, no confirmation is + required. + +2002-06-23 Tetsuo Tsukamoto + + * lisp/pop3.el (pop3-open-ssl-stream): Do away with w32-related + workaround I installed on 1999-12-27, i.e. also call + `as-binary-process' in windows-nt. + +2002-06-12 Katsumi Yamaoka + + * lisp/message.el (message-send): Kill `message-encoding-buffer' + even if sending failed. + +2002-06-11 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. + + * lisp/gnus-msg.el (gnus-message-setup-hook): Default to nil. + (gnus-setup-message): Run `gnus-maybe-setup-default-charset'. + (gnus-summary-supersede-article): Don't bind the value for + `gnus-message-setup-hook'. + (gnus-summary-resend-bounced-mail): Ditto. + + * lisp/dns.el (dns-make-network-process): Bind + `default-process-coding-system' to `(binary . binary)'; bind + `program-coding-system-alist' to nil. + + * lisp/gnus-fun.el (gnus-convert-gray-x-face-to-xpm): Bind + `input-coding-system' and `output-coding-system' to `binary'. + + * lisp/gnus-namazu.el (gnus-namazu/call-namazu): Bind + `input-coding-system' and `output-coding-system' to the velue of + `gnus-namazu-coding-system'. + + * lisp/imap.el (imap-ssl-open): Don't bind the values for + `input-coding-system' and `output-coding-system'. + + * lisp/nnmaildir.el (nnmaildir-request-scan): Bind + `output-coding-system' to the value of + `nnheader-file-coding-system'; bind `file-coding-system' to nil. + (nnmaildir-request-rename-group): Ditto. + (nnmaildir-request-replace-article): Ditto. + (nnmaildir-request-accept-article): Ditto. + (nnmaildir-request-set-mark): Ditto. + + * lisp/nnmbox.el (nnmbox-save-buffer): Simplify the source code. + + * lisp/nnrss.el (nnrss-read-server-data): Bind + `input-coding-system' to `binary'. + (nnrss-save-server-data): Bind `output-coding-system' to `binary'. + (nnrss-read-group-data): Bind `input-coding-system' to `binary'. + (nnrss-save-group-data): Bind `output-coding-system' to `binary'. + +2002-06-07 Katsumi Yamaoka + + * lisp/pop3.el: Add a comment for the use of `ssl' or `tls' + connection with Gnus; always require `pces' and `path-util' for + Gnus. + (pop3-open-ssl-stream-1): Don't require `path-util' here. + +2002-06-06 Katsumi Yamaoka + + * lisp/pop3.el: Make it can be byte-compiled in the Gnus source + tree with neither errors nor warnings. + (pop3-md5): Fix the logic to check whether the built-in `md5' + allows the 4th argument CODING-SYSTEM. + +2002-06-04 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + + * contrib/gpg-ring.el: Remove RCS magic cookie. + * lisp/nnir.el: Ditto. + + * texi/ptexinfmt.el (texinfo-discard-command-and-arg): New + function. + +2002-06-03 TAKAHASHI Kaoru + + * texi/ptexinfmt.el: discard @cartouche. @anchor discard for Mule + 2.3. Support @., @:, @-. + (texinfo-format-inforef): New function. + +2002-05-30 Katsumi Yamaoka + + * lisp/nnheader.el (nnheader-unfold-fws): New function copied from + `ietf-drums-unfold-fws'. + (ietf-drums-unfold-fws): Alias to `nnheader-unfold-fws'. + +2002-05-07 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.7 revision 00. + +2002-04-30 Daiki Ueno + + * lisp/message.el (message-expand-name-function): New user option. + (message-expand-name): Use it. + * lisp/lpath.el: Don't bind lsdb-complete-name and bbdb-complete-name. + +2002-04-30 Daiki Ueno + + * lisp/message.el (message-expand-name): Use lsdb-complete-name if + available. + * lisp/lpath.el: Bind lsdb-complete-name. + +2002-04-30 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Also examine + backquote'd forms. + + * lisp/nnheader.el (nnheader-with-unibyte): New macro. + (mm-with-unibyte): Alias to `nnheader-with-unibyte'. + +2002-04-26 Steve Youngs + + * aclocal.m4 (AC_PATH_INFODIR): New. Defaults to '$prefix/info' + for Emacs and 'site-packages/info' for XEmacs. + (AC_PATH_ETCDIR): Drop 'gnus' off the end of the default directory + for XEmacs. + + * configure.in: Use 'AC_PATH_INFO_DIR'. + +2002-04-23 Daiki Ueno + + * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Disregard the + message cache when bbdb/news-auto-create-p is nil. + +2002-04-23 Daiki Ueno + + * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Work around the + incompatibility with BBDB 2.3x. + +2002-04-22 Daiki Ueno + + * lisp/message.el (message-make-user-agent): Remove product tokens + for gnus-vers. [cf. ] + +2002-04-22 Daiki Ueno + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. + + * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Tweak BBDB message + caching. + (gnus-bbdb/extract-message-sender-function): New user option. + (gnus-bbdb/extract-message-sender): New function. + +2002-04-20 Daiki Ueno + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. + + * lisp/gnus-sum.el: Don't autoload gnus-set-summary-default-charset. + (gnus-summary-inherit-default-charset): New function. + (gnus-parse-headers-hook): Use it. + (gnus-summary-setup-default-charset): Set default-mime-charset here. + + * lisp/gnus-delay.el (gnus-delay-article): Undo the last change. + + * lisp/gnus-draft.el: Revert to the original implementation. + (gnus-draft-edit-message): Pass restore as the 3rd argument of + gnus-draft-setup; call save-buffer instead of message-save-drafts. + (gnus-draft-setup): Rename from gnus-draft-setup-for-editing. + (gnus-draft-setup-for-sending): Abolish. + + * lisp/nnheader.el (nnheader-auto-save-coding-system): New variable. + + * lisp/message.el (message-draft-coding-system): Delegate the + value to nnheader-auto-save-coding-system. + (message-mode-map): Don't bind message-save-drafts. + (message-dont-send): Use save-buffer instead of message-save-buffer. + (message-save-drafts): Abolish. + + * lisp/nndraft.el (nndraft-request-article): Revert to the + original implementation. + +2002-04-18 Daiki Ueno + + * lisp/gnus-draft.el (gnus-group-send-queue): Pass group and + interactive as the arguments of gnus-draft-send. + (gnus-draft-send): Don't give "nndraft:queue" special treatment. + +2002-04-17 Daiki Ueno + + * lisp/gnus-delay.el (gnus-delay-article): Use `message-save-drafts' + instead of `save-buffer'. + +2002-04-08 Daiki Ueno + + * lisp/gnus-draft.el (gnus-draft-send): Always enter the Message + mode. + +2002-03-28 Katsumi Yamaoka + + * lisp/gnus-group.el (gnus-group-completing-read-group-name): Use + `mapatoms' to extract all groups from `gnus-active-hashtb'. + +2002-03-26 Katsumi Yamaoka + + * lisp/gnus-group.el (gnus-group-completing-read-group-name): + Improve to speed up. + (gnus-group-name-charset-group-alist): Change the default value. + +2002-03-25 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + + * lisp/message.el (message-save-drafts, message-check-8bit, + message-send-news, message-send-mail, message-send): Replace + `insert-buffer' with `insert-buffer-substring'. + * lisp/gnus-art.el (gnus-article-mime-edit-article-setup, + gnus-article-edit-exit, article-verify-x-pgp-sig): Ditto. + +2002-03-20 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-summary-make-menu-bar): Don't provide + "View as different encoding" submenu if the function + `coding-system-list' is not available. + +2002-03-19 Katsumi Yamaoka + + * lisp/pop3.el (pop3-md5): Treat a given string as binary. + +2002-03-06 Katsumi Yamaoka + + * lisp/gnus-msg.el (gnus-summary-resend-message-edit): Use + `mime-edit-again' instead of `mime-to-mml' to recompose a message. + +2002-03-05 Katsumi Yamaoka + + * lisp/message.el (mm-make-temp-file): Copied from mm-util.el. + +2002-03-04 Katsumi Yamaoka + + * lisp/message.el (message-fix-before-sending): Bind + `mm-7bit-chars' to the value that concat the original value and + escape. + + * lisp/nnheader.el (mm-7bit-chars): Remove. + +2002-03-04 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-edit-mode): Don't call `mml-mode'. + + * lisp/nnheader.el (mm-7bit-chars): Copied from mm-bodies.el. + (mm-multibyte-p): New alias. + (mm-char-int): Alias to `char-int'. + +2002-02-26 TSUCHIYA Masatoshi + + * lisp/gnus-art.el (gnus-request-article-this-buffer): Sync up + with Oort-gnus. + + * lisp/nntp.el (nntp-open-via-rlogin-and-telnet): Wrap + `call-process' with `as-binary-process'. + +2002-02-25 Katsumi Yamaoka + + * lisp/smiley.el (smiley-regexp-alist): Fix the order of faces. + +2002-02-25 Katsumi Yamaoka + + * lisp/smiley.el (smiley-regexp-alist): Use faces which originate + in etc-0.27.tar.gz if exist. + (gnus-smiley-file-types): Add xbm if available. + (smiley-region): Don't put two or more faces in one place. + +2002-02-22 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-request-article-this-buffer): Temporally + fix: erase the buffer before inserting (and saving) an article. + +2002-02-22 Steve Youngs + + * aclocal.m4 (AC_PATH_LISPDIR): Default to + .../site-packages/lisp/gnus for XEmacs. + (AC_PATH_ETCDIR): Default to .../site-packages/etc/gnus for + XEmacs. + +2002-02-21 Daiki Ueno + + * lisp/gnus-group.el (gnus-group-name-encode): New function. + (gnus-group-encoded-name): New function. + (gnus-group-completing-read-group-name): New function. + (gnus-fetch-group): Use it. + (gnus-group-jump-to-group): Use it. + (gnus-group-unsubscribe-current-group): Use it. + +2002-02-21 Daiki Ueno + + * lisp/nnheader.el (mm-string-as-unibyte): Undo the last change. + * lisp/gnus-srvr.el (gnus-browse-foreign-server): Ditto. + +2002-02-21 Daiki Ueno + + * lisp/nnheader.el (mm-string-as-unibyte): Alias to + `string-as-unibyte'. + + * lisp/gnus-srvr.el (gnus-browse-foreign-server): Return unibyte + group names. + +2002-02-19 Katsumi Yamaoka + + * lisp/lpath.el: Bind `navi2ch-mona-font'. + +2002-02-18 Daiki Ueno + + * lisp/gnus-art.el (gnus-treat-monafy): New user option. + (article-monafy): New function. + +2002-02-18 Katsumi Yamaoka + + * lisp/nnheader.el (std11-field-value): Fix regexp. + +2002-02-15 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-treat-display-grey-xface): Default to nil + under NTEmacs 21. + +2002-02-14 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu-kill-summary-buffers): New + advice. + +2002-02-12 Katsumi Yamaoka + + * lisp/mm-view.el: Require `gnus-mailcap' rather than `mailcap'. + + * lisp/nnheader.el (mm-with-unibyte-buffer): Bind `default-mc-flag' + instead of `mc-flag'. + (nnheader-with-unibyte-current-buffer): New macro. + (mm-with-unibyte-current-buffer): Alias to + `nnheader-with-unibyte-current-buffer'. + (nnheader-guess-mime-charset): New macro. + (mm-guess-mime-charset): Alias to `nnheader-guess-mime-charset'. + (shell-command-to-string): New function for old Emacsen. + + * lisp/lpath.el: Don't fbind `shell-command-to-string'. + +2002-02-09 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/group-alist): Abolished. + (gnus-namazu/setup): Not set it. + (gnus-namazu/shutdown): Removed. + (gnus-namazu/group-prefixed-name): Handle case-insensitive file + names by itself. + +2002-02-09 NISHIDA Masakazu + + * lisp/gnus-namazu.el (gnus-namazu/complete-query): Relaxed the + regexp which matches field search keywords. + +2002-02-01 ShengHuo ZHU + + * etc/gnus/gnus.xpm: Remove some garbages at the end of the file. + +2002-02-03 Daiki Ueno + + * lisp/nnir.el (nnir-run-namazu): According to SUSv3, LC_ALL is + prior to the other environment variables whose names are starting + with "LC_". So there is no need to setting them. + +2002-02-03 Daiki Ueno + + * lisp/nnir.el (nnir-imap-default-charset): New user option. + (nnir-run-imap): Supply the charset of a search criteria. + +2002-02-01 Katsumi Yamaoka + Suggested by Kenichi OKADA + + * lisp/message.el (message-save-drafts): Override + `mime-header-encode-method-alist'. + +2002-02-01 Taiji Can + + * texi/gnus-ja.texi (Posting Styles): Fix typo. + +2002-01-31 ARISAWA Akihiro + + * lisp/gnus-art.el (gnus-article-display-traditional-message): + Reverted. + +2002-01-31 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-setup-buffer): Enable multibyte + in `gnus-original-article-buffer'. + +2002-01-29 Katsumi Yamaoka + + * lisp/message.el (message-cite-prefix-regexp): Fix the regexp. + + * lisp/gnus-sum.el (gnus-mime-extract-message/rfc822): New + implementation. + +2002-01-24 Katsumi Yamaoka + + * lisp/gnus-clfns.el (find-cl-run-time-functions): Insert a + newline before filling a result; ignore non-list forms. + +2002-01-24 ARISAWA Akihiro + + * lisp/gnus-sum.el (gnus-summary-show-article): If coding-system is + specified, bind `default-mime-charset' to it. + +2002-01-23 Katsumi Yamaoka + + * lisp/message.el: Require `base64' before `canlock-om' to avoid + damage to define `base64-encode-string' by MEL. + + * lisp/dgnushack.el: Load base64.el before canlock-om.el to avoid + damage to define `base64-encode-string' by MEL. + +2002-01-23 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-article-commands-menu): Bind "Html" to + the command `gnus-article-wash-html'. + (gnus-summary-article-menu): Ditto. + (gnus-summary-wash-map): Bind "h" to the command + `gnus-article-wash-html'. + + * lisp/gnus-art.el (gnus-article-treatment-menu): Bind + "Treat html" to the command `gnus-article-wash-html'. + + * lisp/nnheader.el: Place mm- stuff and mail-parse stuff in front + of the codes which use (or may use) them. + +2002-01-21 ARISAWA Akihiro + + * lisp/gnus-art.el (gnus-article-display-traditional-message): Use + `set-buffer-multibyte'. + +2002-01-21 TSUCHIYA Masatoshi + + * lisp/gnus-sum.el (gnus-summary-preview-mime-message): Protect + against dead windows. + + * lisp/nnheader.el (mm-encode-coding-string): Alias to + `encode-coding-string'. + (mm-decode-coding-string): Alias to 'decode-coding-string'. + +2002-01-21 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.6 revision 00. + + * lisp/nnheader.el (std11-unfold-region): New function copied from + `rfc2047-unfold-region'. + (std11-unfold-field): New function. + (mail-header-unfold-field): Alias to `std11-unfold-field'. + +2002-01-21 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 02 (synch + with the released version of Oort Gnus v0.05). + +2002-01-16 Katsumi Yamaoka + + * lisp/dgnushack.el: Advise `byte-compile-inline-expand' for Mule + to ignore built-in functions as Emacs 20+ does. + +2002-01-15 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-adjust-marked-articles): Fix the record + for `seen' if it looks like (seen NUM1 . NUM2). It should be + (seen (NUM1 . NUM2)). + +2002-01-15 Katsumi Yamaoka + + * lisp/nntp.el (nntp-send-buffer): Bind `mc-flag' to nil. + + * lisp/nnheader.el (mm-with-unibyte-buffer): Alias to + `nnheader-with-unibyte-buffer'. + (nnheader-with-unibyte-buffer): New macro. + +2002-01-12 Katsuhiro Hermit Endo + + * texi/gnus-ja.texi (Article Date): Update Japanese translation. + +2002-01-11 Katsumi Yamaoka + + * lisp/gnus-clfns.el (butlast): Fix a serious bug that it behaved + like `nbutlast'. Special thanks to Keiichi-san for the great + discovery. + + * lisp/gnus.el (gnus-product-variable-file-list): Add a check for + the value of `gnus-use-correct-string-widths' in the forms. + + * lisp/gnus-start.el (gnus-product-quick-file-format): Include the + value of `gnus-use-correct-string-widths' in the file form. + (gnus-product-read-variable-file-1): Check for the equality in the + value of `gnus-use-correct-string-widths' as well. + +2002-01-10 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01 in + order to force update cached format specs. + + * lisp/gnus-spec.el (gnus-use-correct-string-widths): Default to t. + +2002-01-10 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el: Adopt for old Gnusae. + +2002-01-10 Katsumi Yamaoka + + * lisp/message.el (message-strip-forbidden-properties): Don't + strip properties when the invisible MIME part is inserted. + + * lisp/gnus-xmas.el (gnus-xmas-group-startup-message): Position + point to the top. + +2002-01-05 Lars Magne Ingebrigtsen + + * etc/gnus/oort.xface (X-Face): Oort X-Face from + Raymond Scholz . + +2002-01-09 Katsumi Yamaoka + + * lisp/lpath.el: Fbind `coding-system-to-mime-charset' for Mule 2. + + * lisp/nnheader.el (std11-fold-region): New function copied from + `rfc2047-fold-region'. + (std11-fold-field): Use it. + +2002-01-09 Katsumi Yamaoka + + * lisp/gnus.el: Don't autoload "gnus-bitmap". + + * lisp/gnus-ems.el: Autoload "smiley-mule" if running Emacs + version is less than 21. + + * lisp/gnus-art.el (gnus-article-smiley-display): Remove. + (gnus-treat-smiley): Reload "smiley-ems" or "smiley-mule" if + needed. + (gnus-treat-display-smileys): Use `gnus-image-type-available-p'. + (gnus-article-smiley-mule-loaded-p): New internal variable. + (gnus-article-should-use-smiley-mule): New user option. + +2002-01-09 TSUCHIYA Masatoshi + + * lisp/nneething.el (nneething-mime-extensions): New variable. + (nneething-request-article): Refer it. + + * lisp/nnheader.el (mm-detect-coding-region): Alias to + `nnheader-detect-coding-region'. + (nnheader-detect-coding-region): New function. + (mm-detect-mime-charset-region): Alias to + `nnheader-detect-mime-charset-region'. + (nnheader-detect-mime-charset-region) New function. + +2002-01-08 TSUCHIYA Masatoshi + + * texi/gnus-ja.texi (Web Newspaper): Update the document of + mime-w3m.el. + +2002-01-08 Katsumi Yamaoka + + * lisp/gnus-art.el (article-toggle-headers): Expose headers even + if there is a boundary line. + + * lisp/nntp.el (nntp-send-buffer): Don't use + `mm-with-unibyte-current-buffer'. Use expanded form instead. + + * lisp/gnus-art.el (gnus-treatment-function-alist): Move X-Face + stuff down after unfolding stuff. + +2002-01-08 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu/highlight-words): Reimplemented. + +2002-01-08 Katsumi Yamaoka + + * lisp/nnheader.el (mail-narrow-to-head): Copy from ietf-drums.el; + it should go to the beginning of the header after narrowing. + (std11-extract-addresses-components): Protect against nil argument. + +2002-01-08 Katsumi Yamaoka + + * lisp/nnheader.el (mail-header-field-value): Alias to + `std11-field-value'. + (std11-field-value): New function. + +2002-01-08 Akihiro Arisawa + + * lisp/nnheader.el (mail-header-parse-addresses): New function. + (std11-extract-addresses-components): New function. + +2002-01-07 Katsumi Yamaoka + + * lisp/gnus-picon.el: Don't require `mail-parse'. + +2002-01-07 TSUCHIYA Masatoshi + + * lisp/nnheader.el (mail-header-fold-field): Alias to + `std11-fold-field'. + (std11-fold-field): New function. + (mail-narrow-to-head): Alias to `std11-narrow-to-header'. + (mail-header-narrow-to-field): Alias to `std11-narrow-to-field'. + (std11-narrow-to-field): New function. + +2002-01-07 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.5 revision 00. + +2002-01-02 ShengHuo ZHU + + * etc/gnus/describe-group.xpm: Set pixels of first line to + background color. A bug in Emacs? + +2002-01-07 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 10. + + * lisp/gnus-picon.el: Require `mail-parse'. + + * lisp/sha1-el.el (sha1-use-external): Replace `executable-find' + with `exec-installed-p'. + +2002-01-06 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el: Update comments. + (gnus-namazu/search): Convert `gnus-cache-directory' to absolute + before the regular expression which matches paths of persistent + articles is generated. Clean up codes. + +2002-01-05 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-request-article): Handle the + article properly when no group is specified. + (nnshimbun-write-nov, nnshimbun-save-nov): Save nov databases only + when their sizes are greater than zero. + + * lisp/gnus-namazu.el (gnus-namazu-query-highlight): New option. + (gnus-namazu-query-highlight-face): New face. + (gnus-namazu/check-cache-group): New function. + (gnus-namazu/cache-group-candidates): Ditto. + (gnus-namazu/search): Call `gnus-namazu/check-cache-group' to get + groups for cached articles. + (gnus-namazu/highlight-words): New function. + (gnus-namazu-search): Set the group parameter `highlight-words' + when `gnus-namazu-query-highlight' is equal to the other value + than nil. + + * lisp/gnus-ja.texi (Namazu Groups): Updated. + +2001-12-21 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Ignore + non-list forms in the top level. + +2001-12-18 Josh Huber + + * ChangeLog, todo: (oops) changed buffer-file-coding-system back + to coding. + +2001-12-18 Kai Gro,A_(Bjohann + + * make-x.bat: Ensure nonempty variable value. Reported by Frank + Haun . + +2001-12-18 01:00:00 ShengHuo ZHU + + * ChangeLog, todo: Add `coding'. + +2001-12-17 Josh Huber + + * ChangeLog: changed coding to buffer-file-coding-system + * todo: same + +2001-12-10 Kai Gro,A_(Bjohann + + * make-x.bat: Code cleanup. Fix a bug with "/copy". From Frank + Schmitt . + +2001-12-10 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu-summary-buffer-name): Changed + the expression to decide whether `gnus-summary-buffer-name' should + be advised. + (gnus-namazu/setup): Strict checking the other Gnus variants than + Oort-Gnus before handling `gnus-group-name-charset-group-alist'. + +2001-12-09 Katsumi Yamaoka + + * lisp/nnheader.el (mm-multibyte-string-p): Alias to + `multibyte-string-p' or `ignore'. + +2001-12-09 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu-summary-buffer-name): New + advice. + + * lisp/gnus-namazu.el (top): Update comments. + (gnus-namazu-indexed-servers): Abolished. + (gnus-namazu-index-directories, gnus-namazu-command): Changed the + default value. + (gnus-namazu/group-name-regexp): New internal constant. + (gnus-namazu/indexed-servers): New function. + (gnus-namazu/setup): Not initialize `gnus-namazu-indexed-servers'. + Add the entry for ephemeral groups generated by + `gnus-namazu-search' to `gnus-group-name-charset-group-alist'. + (gnus-namazu/group-prefixed-name): Fix. + (gnus-namazu/search): Stricten checking the return value of + `gnus-namazu/call-namazu'. Install changes in order to avoid the + difference between regexp-opt module of FSF Emacs and one of XEmacs. + (gnus-namazu/get-target-groups, gnus-namazu/get-current-query): + Refer `gnus-namazu/group-name-regexp'. + (gnus-namazu-search): Slightly modified. + +2001-12-07 Katsumi Yamaoka + + * lisp/message.el (message-mimic-kill-buffer): Bind + `message-kill-buffer-and-remove-file' to nil while calling the + function `message-kill-buffer'. + + * texi/message-ja.texi, texi/message-ja.texi: Update. + + * lisp/lpath.el: Fbind `replace-regexp-in-string' for XEmacs and + Mule; don't fbind coding-system-list for Mule. + +2001-12-03 TSUCHIYA Masatoshi + (cf. news://news.gnus.org/gnus.gnus-bug #48523) + + * lisp/message.el (message-kill-buffer-and-remove-file): New user + option. + (message-kill-buffer): Don't remove the backup file if + `message-kill-buffer-and-remove-file' is nil. + +2001-12-07 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu-case-sensitive-filesystem): New + option. + (gnus-namazu/group-alist): New internal variable. + (gnus-namazu/setup): Initialize it. + (gnus-namazu/shutdown) New function. + (gnus-namazu/request-list): Ditto. + (gnus-namazu/group-prefixed-name): Ditto. + (gnus-namazu/search): Call it instead of + `gnus-group-prefixed-name' in order to normalize a group name on a + case-insensitive file system. + +2001-12-05 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (gnus-namazu-need-path-normalization): New + option. + (gnus-namazu/normalize-results): Refined. + + * lisp/gnus-namazu.el (gnus-namazu-index-directory): Abolished. + (gnus-namazu-index-directories): New option. + (gnus-namazu-coding-system): Changed the default value for Windows + and OS/2. + (gnus-namazu/setup): Follow the abolition of + `gnus-namazu-index-directory'. + (gnus-namazu/normalize-results): New inline function. + (gnus-namazu/call-namazu): Set `file-name-coding-system' and + `pathname-coding-system' to handle querys which include multibyte + characters. Not reset locale environments. Refer + `gnus-namazu-locale' and `gnus-namazu-index-directories'. + (gnus-namazu/search): Call `gnus-namazu/normalize-results'. + Modify a regular expression. + (gnus-namazu/get-target-groups): Modify a regular expression. + (gnus-namazu/get-current-query): Ditto. + (gnus-namazu/truncate-article-list): Ditto. + +2001-12-03 Katsumi Yamaoka + + * lisp/mm-url.el: Require `path-util'. + (mm-url-program): Replace `executable-find' to `exec-installed-p'. + +2001-11-29 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 09. + + * lisp/canlock-om.el: New file. + * lips/dgnushack.el: Load canlock-om.el for compiling canlock.el + when `MULE' is bound. + (dgnushack-unexporting-files): Add canlock-om.el when `MULE' is + not bound. + * lisp/message.el: Require `canlock-om' when Mule is running; + autoload cus-edit for the function `customize-save-variable'. + * lisp/nnheader.el (customize-save-variable): Remove. + +2001-11-26 Katsumi Yamaoka + + * lisp/message.el (message-strip-special-text-properties): Default + to t because of the new function `message-tamago-not-in-use-p'. + +2001-11-26 Kai GroN_johann + + * make-x.bat: Use parameter "/copy" rather than "copy" for increased + dwimishness for old-time DOS users. From Frank Schmitt + . + +2001-11-18 Katsumi Yamaoka + + * lisp/message.el (message-strip-special-text-properties): Default + to nil temporarily (it should be automated). + (message-forbidden-properties): Undo last change. + (message-strip-forbidden-properties): Undo last change; synch with + Oort Gnus. + +2001-11-16 Katsumi Yamaoka + + * lisp/message.el (message-forbidden-properties): Defcustom; make + it a list; don't include `intangible', `invisible', + `modification-hooks' or `read-only'. + (message-strip-forbidden-properties): Convert the value of + `message-forbidden-properties' to plist. + +2001-11-16 Katsumi Yamaoka + + * lisp/gnus-group.el (gnus-group-group-map): Bind `G n' key to the + command `gnus-group-make-shimbun-group'. + (gnus-group-group-menu): Add `gnus-group-make-shimbun-group'. + + * texi/gnus-ja.texi (Foreign Groups): Add a documentation for the + shimbun groups. + (Web Newspaper): Use `G n' key for `gnus-group-make-shimbun-group'. + +2001-11-15 Simon Josefsson + + * etc/gnus/unimportant.xpm, etc/gnus/important.xpm: New files. + +2001-11-13 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-summary-wash-map): Remove + `gnus-smiley-display'. + +2001-11-11 Simon Josefsson + + * make-x.bat: Don't use -nw. Suggested by Frank Haun + . + +2001-11-09 TSUCHIYA Masatoshi + + * texi/infohack.el (infohack-texi-format): To process + write-protected files safely, make this buffer be writable after + `find-file' + +2001-11-06 Katsumi Yamaoka + + * lisp/nnheader.el (customize-save-variable): Defun-maybe. + +2001-11-01 07:00:00 ShengHuo ZHU + + * etc/smilies/blink.xpm: New set of xpm. From Oliver Scholz + . + +2001-10-29 Per Abrahamsen + + * etc/smilies/sad.pbm: New bitmap. + * etc/smilies/blink.pbm: Ditto. + Contributed by Kim F. Storm . + +2001-10-22 Katsumi Yamaoka + + * lisp/message.el (rfc822-goto-eoh): Remove. + +2001-10-19 Kai GroN_johann + From Frank Schmitt . + + * make-x.bat: Use correct directory structure for XEmacs on Windows. + +2001-10-19 Katsumi Yamaoka + + * lisp/message.el (rfc822-goto-eoh): Define it when void. + +2001-10-19 Katsumi Yamaoka + + * lisp/message.el (message-resend, message-send): Undo. + +2001-10-19 Katsumi Yamaoka + + * lisp/message.el (message-resend): Bind + `inhibit-field-text-motion' to t while resending a mail. + +2001-10-16 Katsumi Yamaoka + + * lisp/message.el (message-send): Remove the text property `field' + from the encoding buffer. + +2001-10-11 Katsumi Yamaoka + + * lisp/gnus-start.el (gnus-re-read-newsrc-el-file): Use + `gnus-ding-file-coding-system' instead of + `gnus-startup-file-coding-system'; go to the beginning of the + buffer before searching. + (gnus-read-newsrc-el-file): Use `gnus-ding-file-coding-system' + instead of `gnus-startup-file-coding-system'. + +2001-10-10 Katsumi Yamaoka + + * lisp/message.el (message-send-news): Modify the value of + `mime-field-encoding-method-alist' to encode newsgroup names. + + * lisp/gnus-art.el (gnus-article-header-presentation-method): Call + `article-decode-group-name' to decode newsgroup names. + (gnus-article-decode-hook): Default to nil. + +2001-10-06 08:00:00 ShengHuo ZHU + + * Makefile.in (uninstall): Add. + + * etc/Makefile.in (uninstall): Add. + +2001-10-04 Katsumi Yamaoka + + * lisp/message.el (message-fix-before-sending): Don't expose + invisible MIME parts; don't use `message-find-invisible-regions'. + (message-find-invisible-regions): Remove. + (invisible-region): Advise the function to add the text property + `mime-edit-invisible'. + (message-invisible-region): Remove. + (message-save-drafts): Copy all the text properties from the + editing buffer to the encoding buffer. + (message-send): Ditto. + +2001-10-01 Katsumi Yamaoka + + * lisp/nndoc.el (nndoc-oe-dbx-type-p): Use `string-as-multibyte' + instead of `mm-string-as-multibyte'. + (nndoc-possibly-change-buffer): Use `nnheader-insert-file-contents' + instead of `mm-insert-file-contents'. + +2001-09-28 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 08. + +2001-09-27 14:00:00 ShengHuo ZHU + + * aclocal.m4 (GNUS_CHECK_FONTS): Typo. Use /dev/null as latex input. + +2001-09-27 09:00:00 ShengHuo ZHU + + * aclocal.m4, configure.in: Check commercial fonts. + +2001-09-27 Katsumi Yamaoka + + * lisp/message.el (message-find-invisible-regions): Look for the + text-property `mime-edit-invisible' as well as `message-invisible'. + (message-save-drafts): Copy the text-property `mime-edit-invisible' + from the message editing buffer to the encoding buffer. + (message-send): Ditto. + +2001-09-27 Katsuhiro Hermit Endo + + * texi/gnus-ja.texi (Article Hiding): Fix typo. + +2001-09-25 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 07. + +2001-09-24 19:00:00 ShengHuo ZHU + + * configure.in: Generate texi/ps/Makefile. + +2001-09-21 Kai GroN_johann + + * make.bat: Use parameter "/copy" rather than "copy" for increased + dwimishness for old-time DOS users. + +2001-09-18 22:00:00 ShengHuo ZHU + + * make-x.bat: New. + +2001-09-18 Katsumi Yamaoka + + * lisp/dgnushack.el: If W3DIR is identical to URLDIR, don't add it + to `load-path'. + +2001-09-17 Katsumi Yamaoka + + * lisp/gnus-diary.el: Don't use `easy-menu-add-item' if it is not + available. + +2001-09-17 Keiichi Suzuki + + * lisp/gnus-bbdb.el (gnus-bbdb/insert-address-regexp): + `regexp-quote' for each addresses. + +2001-09-16 Katsuhiro Hermit Endo + + * texi/gnus-ja.texi (Drafts): Fix typo. + +2001-09-12 TSUCHIYA Masatoshi + + * lisp/lpath.el: Removed `current-language-environment' and + `language-info-alist'. + +2001-09-11 TSUCHIYA Masatoshi + + * lisp/gnus-art.el (gnus-request-article-this-buffer): Make a copy + of the requested article only when the current directory does noe + equal to `gnus-original-article-buffer'. + + * lisp/gnus-art.el (gnus-request-article-this-buffer): Copy an + article from `gnus-original-article-buffer' to + `gnus-article-buffer'. Generate `gnus-original-article-buffer' + safely. + +2001-09-10 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el: Updated documents. + + * texi/gnus-ja.texi (Namazu Groups): New subsection. + +2001-09-10 Katsumi Yamaoka + + * lisp/gnus-namazu.el: Autoload "regexp-opt" for Mule 2.3. + + * Mule23@1934.en, Mule23@1934.ja: To install contrib/regexp-opt.el + is required. + + * contrib/regexp-opt.el: Imported from Emacs 20.2. + + * lisp/gnus-bbdb.el (gnus-bbdb/pop-up-bbdb-buffer): Use + `bbdb-display-layout' or `bbdb-pop-up-display-layout' instead of + `bbdb-elided-display' or `bbdb-pop-up-elided-display' when BBDB + v2.33 or later is running. + +2001-09-10 TSUCHIYA Masatoshi + + * lisp/gnus-namazu.el (top): Not require `std11'. + (gnus-namazu/get-current-from): Use + `mail-extract-address-components' instead of + `std11-extract-address-components'. + + * lisp/gnus-namazu.el: New file. + + * lisp/gnus.el (top): Add autoload of `gnus-namazu-search'. + + * lisp/gnus-sum.el (gnus-summary-mode-map): Define "\C-c\C-n" as + `gnus-namazu-search'. + + * lisp/gnus-group.el (gnus-group-mode-map): Define "\C-c\C-n" as + `gnus-namazu-search', and removed `gnus-group-make-shimbun-group'. + +2001-09-10 Katsumi Yamaoka + + * lisp/gnus-xmas.el (gnus-tilde-pad-form): Abolished. Use the + new function `gnus-correct-pad-form' instead. + * lisp/gnus-spec.el (gnus-tilde-pad-form): Ditto. + +2001-09-05 TSUCHIYA Masatoshi + + * lisp/nnir.el (nnir-run-namazu): Fix a side effect when handling + of process environments. + +2001-09-04 TSUCHIYA Masatoshi + + * lisp/nnir.el (top): Added code to avoid byte-compile warning + about `nnimap-server-buffer'. + (nnir-run-namazu): Disable locale of Namazu. + +2001-09-04 KOSEKI Yoshinori + + * lisp/nnir.el (gnus-group-mode-hook): Fix typo. + +2001-09-04 TSUCHIYA Masatoshi + + * lisp/nnir.el (top): Don't call `nnir-group-mode-hook' in T-gnus. + + * lisp/gnus-group.el (gnus-group-group-map): Define "G" as + `gnus-group-make-nnir-group', and define "S" as + `gnus-group-make-shimbun-group'. + + * lisp/gnus.el (top): Add autoload of + `gnus-group-make-nnir-group'. + + * lisp/nnir.el: Import from + ftp://ls6-ftp.cs.uni-dortmund.de/pub/src/emacs/nnir.el. + +2001-08-29 Katsumi Yamaoka + + * lisp/gnus-util.el (gnus-truncate-string): Abolished. + +2001-08-18 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (gnus-group-make-shimbun-group): Call + `shimbun-groups' to detect avaiable groups of specified server. + +2001-08-17 KANEMATSU Daiji + + * lisp/message.el (message-signature-separator-for-insertion): New + customizable variable which is used for signature separator. + * lisp/message.el (message-insert-signature): Use variable + `message-signature-separator-for-insertion' instead of hard code. + +2001-08-15 Yoichi NAKAYAMA + + * texi/gnus-ja.texi (Browsing the Web): Fix typo. + +2001-08-13 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 06. + +2001-08-10 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-request-article-this-buffer): Insert an + article into `gnus-original-article-buffer' instead of + `gnus-article-buffer'. + +2001-07-31 Katsumi Yamaoka + + * lisp/mml2015.el: Require `gnus-clfns' when compiling. + * lisp/gnus-clfns.el (string-to-list): New compiler macro. + +2001-07-30 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-select-newsgroup): Don't examine cached + articles with `gnus-cache-articles-in-group' even if the current + group is not a virtual group (see ChangeLog.1 1999-03-02). + +2001-07-30 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 05. + + * lisp/nnmh.el (nnmh-retrieve-parsed-headers): Abolished. + + * lisp/gnus-sum.el (gnus-get-newsgroup-headers-xover): Don't use + `gnus-retrieve-parsed-headers'. + (gnus-fetch-headers): Ditto. + + * lisp/gnus-int.el (gnus-retrieve-parsed-headers): Abolished. + + * lisp/gnus-cache.el (gnus-cache-braid-headers): Abolished. + (gnus-cache-retrieve-parsed-headers): Abolished. + +2001-07-30 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Bind + `nnmail-expiry-wait-function' to nil if the group's parameter + `expiry-wait' is specified by the user or the shimbun's default + value is provided. + +2001-07-27 Katsumi Yamaoka + + * lisp/gnus-msg.el (gnus-message-make-user-agent): New + implementation. + +2001-07-24 Katsumi Yamaoka + + * lisp/gnus-clfns.el (copy-list): New compiler macro. + +2001-07-23 Katsumi Yamaoka + + * lisp/gnus-delay.el (gnus-delay-initialize): Don't use the macro + `kbd'. + + * lisp/nnheader.el (mm-read-coding-system): New function which is + a substitute for mm-util.el. + +2001-07-19 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 04. + + * lisp/nntp.el (nntp-request-newgroups): Use UTC date for + NEWGROUPS command. + + * lisp/gnus-start.el (gnus-find-new-newsgroups): Use + `message-make-date' instead of `current-time-string'. + (gnus-ask-server-for-new-groups): Ditto. + (gnus-check-first-time-used): Ditto. + +2001-07-17 Katsumi Yamaoka + + * texi/message-ja.texi (message-citation-line-function): Add a + comma just after the `@xref' form. + + * lisp/nnheader.el (nnheader-header-value): Ignore leading + whitespaces. + + * lisp/dgnushack.el (dgnushack-make-auto-load): Advise + `make-autoload' to handle `define-derived-mode'. + +2001-07-12 Katsumi Yamaoka + + * lisp/message.el (message-yank-original): Unwind-protect while + suspending font-lock. + (message-mode): Modify for the following changes. + (message-font-lock-keywords-2): Abolished. + (message-font-lock-keywords-1): Abolished. + (message-font-lock-keywords): Unified. + (message-font-lock-cited-text-matcher): Abolished. + (font-lock-after-change-function): Don't advise it. + (message-font-lock-last-position): Abolished. + (message-font-lock-citation-name-max-column): Abolished. + (message-font-lock-cited-text-regexp) Abolished. + (message-font-lock-fence-close-position): Abolished. + (message-font-lock-fence-open-position): Abolished. + (message-font-lock-fence-close-regexp): Abolished. + (message-font-lock-fence-open-regexp): Abolished. + +2001-07-10 Katsumi Yamaoka + + * lisp/message.el (message-font-lock-keywords-1): Replace regexp + for mml tags with `mime-edit-tag-regexp'. + +2001-07-10 Katsumi Yamaoka + + * lisp/message.el (message-font-lock-keywords-2): Move definitions + for cited texts and mml tags to `message-font-lock-keywords-1'. + +2001-07-10 Katsuhiro Hermit Endo + + * texi/gnus-ja.texi (Mail Group Commands): Fix a slight mistake. + +2001-07-09 Katsumi Yamaoka + + * lisp/dgnushack.el: Add the parent directory of the directory + where the APEL modules are installed to `load-path' according to + the description of the file Mule23@1934. + +2001-07-04 Yair Friedman + + * make.bat: Use infohack.el to create info files. + +2001-07-09 Akihiro Arisawa + + * README.semi: Modify URI of emacs-w3m. + * README.semi.ja: Ditto. + * Mule23@1934.en: Ditto. + * Mule23@1934.ja: Ditto. + * lisp/nnshimbun.el: Ditto. + + * texi/gnus-ja.texi (Top, Article Treatment): Fix typo. + (Web Newspaper): Modify URI of emacs-w3m. + +2001-07-06 KITAGAWA Takurou + + * lisp/Makefile.in (clever): Use `if test... then' instead of + `test... &&'. + +2001-07-06 Katsumi Yamaoka + + * lisp/Makefile.in (clever): Change the quoting style for the + elisp form to check for XEmacs-p. + + * lisp/dgnushack.el: Require `path-util' first, and then search + for the path if it is not found. + +2001-07-05 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. + +2001-06-28 Akitada Koyama + + * texi/gnus-ja.texi (Web Newspaper): Add a description how to show + html documents inline. + +2001-06-28 Katsumi Yamaoka + + * texi/message-ja.texi (message-suspend-font-lock-when-citing): Add + a description. + * texi/message.texi (message-suspend-font-lock-when-citing): Ditto. + + * lisp/message.el (message-yank-original): Suspend font-lock'ing + while citing an original message. + (message-suspend-font-lock-when-citing): New user option. + +2001-06-25 Katsumi Yamaoka + + * lisp/gnus-clfns.el (find-cl-run-time-functions): New + implementation. + +2001-06-22 Katsumi Yamaoka + + * lisp/gnus-art.el (article-display-x-face): Don't gather X-Face + fields in `gnus-original-article-buffer'. + +2001-06-18 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-find-parameter): Undo the last + bogus changes; use the value of `nnshimbun-pre-fetch-article' if + the value of the group parameter `prefetch-articles' is nil; do + likewise for `encapsulate-images'. + +2001-06-18 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-find-parameter): Use the value of + `nnshimbun-pre-fetch-article' if the value of the group parameter + `prefetch-articles' is `off'; do likewise for `encapsulate-images'. + +2001-06-18 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-encapsulate-images): Fix a + doc-string that both the values `off' and nil specifies not to + encapsulate images. + (nnshimbun-pre-fetch-article): Default to `off'. + +2001-06-18 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-encapsulate-images): Renamed from + `nnshimbun-encapsulate-article'. + (nnshimbun-request-article-1): Replace `encapsulate-article' with + `encapsulate-images'. + (nnshimbun-find-parameter): Ditto. + (nnshimbun-group-parameters): Ditto. + (nnshimbun-group-parameters-custom): Ditto. + +2001-06-15 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-group-parameters-custom): Add + `encapsulate-article' as a customizable option, and modified + `prefetch-articles'. + (nnshimbun-group-parameters): Add document for + `encapsulate-article'. + (nnshimbun-encapsulate-article): New server variable. + (nnshimbun-find-parameter): Add code for `encapsulate-article'. + (nnshimbun-request-article-1): Refer `encapsulate-article' group + parameter to control `shimbun-encapsulate-article' value when + `shimbun-article' is called. + +2001-06-14 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. + +2001-06-14 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Use + `nnshimbun-find-parameter'. + (nnshimbun-generate-nov-database): Bind a full group name while + processing. + (nnshimbun-find-parameter): New implementation to refer to the + nnshimbun group parameters. + (nnshimbun-index-range): Add a document that it's just a default. + (nnshimbun-pre-fetch-article): Ditto. + (nnshimbun-group-parameters): Specify a parameter type as `list'. + (TopLevel): Remove the local variable "-*- coding: junet; -*-". + +2001-06-13 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-group-parameters): New group + parameter. It also provides the user option + `nnshimbun-group-parameters-alist' and the function + `nnshimbun-find-group-parameters'. + (nnshimbun-group-parameters-custom): New variable. + (TopLevel): Require `gnus' expressly. + +2001-06-12 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-find-parameter): New macro. + (nnshimbun-generate-nov-database): Use `nnshimbun-find-parameter'. + (nnshimbun-request-expire-articles): Fixed. + +2001-06-12 Katsumi Yamaoka + + * lisp/nnshimbun.el (Gnus-p): Use `file-exists-p' instead of + `locate-library' to check for the existence of mailcap.el in the + same directory of gnus.el. + (nnshimbun-retrieve-headers-with-nov): Remove a redundant check + that I made. + +2001-06-11 Katsumi Yamaoka + + * lisp/lpath.el: Don't Fbind `xml-node-children'. + +2001-06-11 Akihiro Arisawa + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Fix + inhibiting the expiring when `nnshimbun-keep-unparsable-dated-articles' + is nil. + +2001-06-11 TSUCHIYA Masatoshi + + * lisp/gnus-group.el (toplevel): Removed autoload code for + "nnshimbun". + + * texi/gnus-ja.texi (Web Newspaper): Add documents about + `nnshimbun-index-range'. + +2001-06-11 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Don't + refer to the variable `nnshimbun-keep-last-article', we should + keep the last article anyway. + (nnshimbun-keep-last-article): Abolished. + + * lisp/gnus.el: Autoload "nnshimbun" for the command `gnus-group- + make-shimbun-group'. + +2001-06-11 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el: Remove some garbage. + +2001-06-10 Katsumi Yamaoka + + * texi/message-ja.texi: Use `iso-2022-7bit' instead of + `iso-2022-7bit-ss2' to keep a compatibility between XEmacsen and + FSF Emacsen. + * texi/gnus-ja.texi: Ditto. + +2001-06-09 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (top-level): Updated comments. + (nnshimbun): New customize group. + (nnshimbun-keep-last-article): Defined as customize variable. + (nnshimbun-keep-unparsable-dated-articles): Ditto. + (nnshimbun-insert-nov): Use `when' instead of `if'. + (gnus-group-shimbun-server-history): Imported from + `gnus-group.el'. + (gnus-group-make-shimbun-group): Ditto. + + * lisp/gnus-group.el (gnus-group-make-shimbun-group): Its real + definition is moved to `nnshimbun.el' and autload code is added. + (gnus-group-shimbun-server-history): Its definition is moved to + `nnshimbun.el'. + +2001-06-08 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-use-entire-index): Removed. + (nnshimbun-index-range): New variable. + (nnshimbun-close-server): Check status strictly to close server + safely. + (nnshimbun-generate-nov-database): Refer the group paramter + `nnshimbun-index-range' as the second parameter of + `shimbun-headers'. + (shimbun-mua-use-entire-index): Removed. + (nnshimbun-request-article-1): Replace a date string in + `gnus-newsgroup-data' only when article header has non-nil value. + (nnshimbun-insert-nov): Fixed condition to decide whether + `X-Nnshimbun-Id' should be inseted or not. + +2001-06-08 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-expire-nov-databases): Removed. + (nnshimbun-request-expire-articles): Simplified; refer to the + shimbun's default expiration days. + +2001-06-08 Katsumi Yamaoka + + * lisp/lpath.el: Fbind `xml-node-children' for XEmacsen and old FSF + Emacsen. + +2001-06-07 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Prefer the + group parameter `expiry-wait' when expiring a closed group. + +2001-06-07 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-request-article-1): Replace a date + string in `gnus-newsgroup-data' based on the newly retrieved + article. + +2001-06-07 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-request-expire-articles): Fix + inhibiting the expiring. + +2001-06-06 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-expire-nov-databases): New command. + (nnshimbun-request-expire-articles): New function. + (nnshimbun-keep-unparsable-dated-articles): New variable. + (nnshimbun-keep-last-article): New variable. + (nnshimbun-insert-nov): Rewrite using `nnshimbun-string-or'. + (nnshimbun-string-or): New macro. + (nnshimbun-tmp-string): New internal variable. + (TopLevel): Require `message' for `message-make-date'. + +2001-05-30 Katsumi Yamaoka + + * lisp/gnus-clfns.el (find-cl-run-time-functions): Remove a + useless non-global var; scroll the output window automatically. + +2001-05-31 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-header-xref): Removed. + (nnshimbun-check-header): Removed. + (nnshimbun-make-shimbun-header): Don't call + `nnshimbun-header-xref'. + (nnshimbun-request-group): Simplified. + (nnshimbun-request-article-1): Call `nnshimbun-replace-nov-entry' + instead of `nnshimbun-check-header'. + (nnshimbun-insert-nov): New function. + (nnshimbun-generate-nov-database): Call `nnshimbun-insert-nov' + instead of `nnheader-insert-nov'. + (nnshimbun-replace-nov-entry): New function. + +2001-05-29 Katsumi Yamaoka + + * lisp/gnus-clfns.el (find-cl-run-time-functions): Add a parser for + `dolist'; protect against errors. + +2001-05-29 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-retrieve-headers-with-nov): Don't + use `last'. + (nnshimbun-make-shimbun-header): Use the following macros. + (nnshimbun-mail-header-from): New macro whose definition will be + changed statically for Gnus or gnus. + (nnshimbun-mail-header-subject): Ditto. + (TopLevel): Don't require `gnus-clfns'. + + * lisp/gnus.el: Add autoload for `find-cl-run-time-functions'. + + * lisp/gnus-clfns.el (find-cl-run-time-functions): New command for + the developers. + (cl-run-time-functions): New variable. + (TopLevel): Don't require `cl' at run-time. + +2001-05-28 TSUCHIYA Masatoshi + + * texi/gnus-ja.texi (Web Newspaper): Updated. + +2001-05-28 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-unexporting-files): Add + "nnshimbun.el" if the library "shimbun" is not found. + (TopLevel): Add "/somewhere/apel/" to `load-path' if it is needed. + (locate-library): Redefine it for Mule before it is called. + + * README.semi.ja: Update for the use of Emacs-W3M. + * README.semi: Ditto. + * Mule23@1934.ja: Ditto. + * Mule23@1934.en: Ditto. + +2001-05-28 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el: Reconstructed to use `shimbun'. + + * lisp/gnus-group.el (gnus-group-make-shimbun-group): + Reconstructed to use `shimbun'. + + * lisp/dgnushack.el (toplevel): Add paths if and only if APEL and + FLIM can't be found. + +2001-05-17 Kai =?iso-8859-1?q?Gro=DFjohann?= + + * etc/Makefile.in (datadir): Set this variable, like in the other + Makefile.in's. Patch from Gaute B Strokkenes . + +2001-05-16 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Don't ignore + `widget-convert-button', `widget-create' and `widget-put'; ignore + `defface'. + +2001-05-14 Katsumi Yamaoka + + * lisp/gnus.el: Require `base64' if `base64-encode-string' is not a + built-in function. + + * lisp/dgnushack.el (dgnushack-bind-colon-keywords): Ignore + `defgroup'. + +2001-05-14 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + + * lisp/nnmail.el: Don't bind the colon keywords here. + * lisp/gnus.el (gnus-colon-keywords): New variable which will + default to the value of `dgnushack-colon-keywords'; bind them. + * lisp/dgnushack.el (dgnushack-unexporting-files): Add + dgnuskwds.el. + (dgnushack-colon-keywords): New constant which will have the colon + keywords shuld be bound at run-time for old Emacsen; cache them in + the file dgnuskwds.el and bind them. + (dgnushack-bind-colon-keywords): New function. + (locate-library): Make the function to be silent for Mule. + * lisp/Makefile.in (clean): Remove dgnuskwds.el. + +2001-05-07 Katsumi Yamaoka + + * lisp/message.el (message-maybe-encode): Don't use + `end-of-invisible'. + +2001-05-07 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.4 revision 00. + +2001-04-27 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + + * lisp/gnus-art.el (gnus-article-mime-edit-exit): Set buffer to + `gnus-article-buffer' just before `gnus-article-prepare-display' is + called. + (gnus-article-mime-edit-article-setup): Ditto. + (gnus-article-prepare-display): Don't bind `buffer-read-only' + because of `inhibit-read-only'; don't set the value of + `gnus-article-current-summary' here; delete all extents or overlays + and clear the value of `gnus-button-marker-list' in advance; make + it to run in `gnus-article-buffer'. + (gnus-article-prepare): Make it to run in `gnus-article-buffer'. + (article-toggle-headers): Don't bind `buffer-read-only' because of + `inhibit-read-only'. + (article-hide-headers): Ditto. + +2001-04-16 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.3 revision 00. + +2001-04-16 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.2 revision 00. + +2001-04-16 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.1 revision 00. + +2001-04-13 Katsumi Yamaoka + + * lisp/lpath.el: Fbind `xml-parse-region' for XEmacsen and old FSF + Emacsen; don't bind `mh-lib-progs'. + +2001-04-10 Katsumi Yamaoka + + * lisp/nnshimbun.el: Enclose w3m stuff with `eval-and-compile'; + bind `w3m-work-buffer-name' and `w3m-retrieve' when compiling. + +2001-04-09 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 10. + +2001-04-03 TSUCHIYA Masatoshi + + * lisp/nnshimbun.el (nnshimbun-type-definition: Follow changes in + asahi.com. + (nnshimbun-asahi-get-headers): Ditto. + (nnshimbun-retrieve-url): Use `w3m-retrieve' if it is available. + +2001-04-02 Katsumi Yamaoka + + * lisp/gnus-msg.el (gnus-inews-yank-articles): Make it to work with + multiple articles even if there is a detached minibuffer frame on + some window managers. + +2001-03-21 Thierry Emery + + * lisp/mm-decode.el (mm-copy-to-buffer): Copy buffer in unibyte + mode. + +2001-03-19 Katsumi Yamaoka + + * lisp/gnus-kill.el (gnus-execute): Work with the extra headers. + * lisp/gnus-sum.el (gnus-summary-execute-command): Ditto. + +2001-03-13 Katsumi Yamaoka + + * lisp/message.el (message-fix-before-sending): Hide again the + invisible property of encoded binary data parts after checking is + done. + (message-find-invisible-regions): New function. + (message-save-drafts, message-send): Inherit the invisible property + of encoded binary data parts to make MIME-Edit find the MIME part + boundaries. + + * lisp/dgnushack.el (dgnushack-compose-package): Tidy up. + (dgnushack-make-load): Ditto. + +2001-03-12 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-compose-package): New function. + (dgnushack-make-load): Add autoload for cus-load if it is missing. + + * lisp/Makefile.in (compose-package): Use + `dgnushack-compose-package'. + (clean, clever): Remove custom-load.el. + + * Makefile.in (elclean): Remove custom-load.el. + +2001-03-08 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-prepare-display): Setup MIME + entity even if `gnus-show-mime' is nil. + +2001-03-08 Katsumi Yamaoka + + * lisp/dgnushack.el: Load gnus-clfns.el after `load-path' is + adjusted. + + * lisp/gnus-clfns.el (string): New compiler macro. + (string): Defun-maybe as an ordinary function since it won't be + provided in cl. + * lisp/gnus-score.el (gnus-score-find-bnews): Use it as Gnus does. + +2001-03-06 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-retrieve-url): Check if + `url-current-mime-charset' is bound. + +2001-03-04 Katsumi Yamaoka + + * lisp/gnus.el (gnus-info-find-node): Pretend to be + `gnus-article-mode' in the article buffer. + +2001-03-02 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-kinsoku-eol-list): Simplified. + (nnshimbun-kinsoku-bol-list): Ditto. + +2001-03-01 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 09. + + * lisp/gnus-offline.el (gnus-offline-get-menu-items): Rewrite using + `dolist'. + + * lisp/gnus-group.el (gnus-group-make-shimbun-group): Simplified. + + * lisp/dgnushack.el: Load cl-macs to ensure that the macro `dolist' + is defined properly. + +2001-02-28 Katsumi Yamaoka + + * lisp/nnwfm.el: Require `gnus-clfns' when compiling. + * lisp/nnshimbun.el: Ditto. + * lisp/nnfolder.el: Ditto. + * lisp/mm-util.el: Ditto. + * lisp/gnus-vers.el: Ditto. + * lisp/gnus-sum.el: Ditto. + * lisp/gnus-score.el: Ditto. + * lisp/gnus-nocem.el: Ditto. + + * lisp/gnus-ofsetup.el: Don't require `gnus-clfns'. + (gnus-ofsetup-customize-done): Use `dolist' instead of `mapc'. + (gnus-setup-for-offline): Ditto. + + * lisp/gnus-offline.el: Don't use `mapc' for binding some vars; + don't require `gnus-clfns'. + + * lisp/gnus-clfns.el (subseq, merge, coerce, butlast): New compiler + macros. + (mapc): Remove. + + * lisp/gnus-art.el: Use `dolist' instead of `mapcar' for defining + `gnus-article-read-summary-keys'. + +2001-02-28 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-mime-edit-article-setup): Leave + the forwarded parts undecoded. + (gnus-article-decode-article-as-default-mime-charset): Set the + value of `default-mime-charset' buffer-locally. + +2001-02-27 Katsumi Yamaoka + + * lisp/gnus.el: Add autoloads for + `gnus-summary-digest-post-forward' and + `gnus-summary-digest-mail-forward'. + + * lisp/gnus-sum.el (gnus-summary-post-menu): Replace + `gnus-uu-digest-mail-forward' and `gnus-uu-digest-post-forward' + with `gnus-summary-digest-post-forward' and + `gnus-summary-digest-mail-forward'. + + * lisp/gnus-msg.el (gnus-summary-digest-post-forward): Restore and + repair the command `gnus-summary-post-digest' and rename it. + (gnus-summary-digest-mail-forward): Ditto. + (gnus-summary-send-map): Replace `gnus-uu-digest-mail-forward' and + `gnus-uu-digest-post-forward' with + `gnus-summary-digest-post-forward' and + `gnus-summary-digest-mail-forward'. + +2001-02-27 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-summary-show-article): Bind + `gnus-inhibit-treatment' to t while fetching the raw article. + + * lisp/gnus-art.el (gnus-article-mime-edit-exit): Bind + `mime-edit-insert-user-agent-field' to nil while `mime-edit-exit' + is being done; turn off font-lock first; query if the buffer is + modified. + (gnus-article-mime-edit-done): New function. + (gnus-article-mime-edit-article-setup): Make the window fill its + frame; clear the buffere modified flag; substitute key definition + `gnus-article-edit-done' with `gnus-article-mime-edit-done'; don't + turn off font-lock here; bind `mime-edit-insert-user-agent-field' + to nil while `mime-edit-exit' is being done. + (gnus-article-mime-edit-article-unwind): Turn off font-lock first. + +2001-02-23 Katsumi Yamaoka + + * lisp/dgnushack.el: Don't require `emu'. + +2001-02-16 Katsumi Yamaoka + + * lisp/message.el (message-forward-subject-author-subject): Decode + `From' field. + +2001-02-16 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 08. + + * lisp/gnus-sum.el (gnus-get-newsgroup-headers-xover): Don't use + `gnus-retrieve-parsed-headers' when the backend is nnimap. It is + only a temporary fix for an infloop on nnimap. FIXME!!! + (gnus-select-newsgroup): Ditto. + +2001-02-16 Katsumi Yamaoka + + * texi/gnus-ja.texi (New features in Gnus 5.8): Remove annotation + about `gnus-article-display-hook.' + * texi/gnus-faq-ja.texi (Q2.1): Remove mention of + `gnus-article-display-hook.' + + * lisp/gnus.el (gnus-article-display-hook): Abolished. + + * lisp/gnus-uu.el (gnus-uu-grab-articles): Don't care about + `gnus-article-display-hook'. + * lisp/gnus-sum.el (gnus-summary-show-article): Ditto. + (gnus-summary-search-article): Ditto. + + * lisp/gnus-bbdb.el (gnus-bbdb-insinuate): Use + `gnus-article-prepare-hook' instead of `gnus-article-display-hook'. + + * lisp/gnus-art.el (gnus-article-prepare-display): Evaluate + `gnus-article-prepare-hook' after an article has been prepared; + don't evaluate `gnus-article-display-hook'. + +2001-02-15 Katsumi Yamaoka + + * lisp/message.el (message-cite-original-without-signature): + Extract from field for the simple citation line. + +2001-02-14 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 07. + + * lisp/dgnushack.el (dgnushack-make-autoloads): Remove function. + (dgnushack-make-load): Ignore cus-load.el if it does not exist. + (dgnushack-make-auto-load): Remove auto-autoloads.el. + (dgnushack-make-cus-load): Do nothing if loading cus-dep is failed. + + * lisp/Makefile.in (clean): Remove gnus-load.el instead of + custom-load.el. + (compose-package): Call `gnus-load.elc' and then rename + gnus-load.el(c) to auto-autoloads.el(c) instead of the use of + `dgnushack-make-autoloads'. + (clever): No need to remove custom-load.el. + + * Makefile.in (elclean): Remove gnus-load.el instead of + custom-load.el. + + * aclocal.m4 (AC_CHECK_URL): Ignore cache. + +2001-02-13 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 06. + +2001-02-11 18:00:00 ShengHuo ZHU + + * GNUS-NEWS: Copyright and others. + +2001-02-09 20:00:00 ShengHuo ZHU + + * aclocal.m4 (AC_CHECK_URL): Add. + + * configure.in: Use it. + +2001-02-08 Katsumi Yamaoka + + * lisp/nnshimbun.el (nnshimbun-fml-get-headers): Fix unbalanced + parentheses. + +2001-02-08 Akihiro Arisawa + + * lisp/nnshimbun.el: Add `bbdb-ml' support. + +2001-02-02 Akihiro Arisawa + + * lisp/nnshimbun.el (nnshimbun-type-definition): Follow URL change + of `xemacs'. + (nnshimbun-xemacs-get-headers): Ditto. + +2001-02-06 Katsumi Yamaoka + + * README-gnus-bbdb.{en,ja}: Update the patch for BBDB v2.2. + +2001-02-01 Katsumi Yamaoka + + * texi/Makefile.in (.texi, %.info): Don't use makeinfo command when + gnus-ja.texi or message-ja.texi is given. It is needed for some + make command if which can not understand "%-ja:" or "%-ja.info:". + +2001-01-31 Katsumi Yamaoka + + * lisp/gnus-sum.el (gnus-summary-display-article): Replace + `mm-enable-multibyte-mule4' with `set-buffer-multibyte'. + +2001-01-29 Katsumi Yamaoka + + * lisp/gnus-art.el (gnus-article-mime-edit-exit): Use + `buffer-substring-no-properties' instead of `format'. + +2001-01-23 TAKAHASHI Kaoru + + * texi/ptexinfmt.el: Support @letterpaper and @afivepaper. + +2001-01-22 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 05. + + * Makefile.in (install-package-lisp): Use + `install-without-compiling' instead of `install'. + + * lisp/Makefile.in (install): Use `install-without-compiling'. + (install-without-compiling): New target. + +2001-01-22 Katsumi Yamaoka + + * texi/Makefile.in (.texi, %.info, %-ja.info, %-ja): Use + `infohack-texi-format'. + + * texi/infohack: (infohack-texi-format): New function. + * lisp/dgnushack.el (dgnushack-texi-format): Move to + texi/infohack.el and rename. + (dgnushack-texi-add-suffix-and-format): Remove. + + * texi/ptexinfmt.el: New file. + * lisp/ptexinfmt.el: Move to texi/. + +2001-01-18 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 04. + +2001-01-17 Katsumi Yamaoka + + * lisp/dgnushack.el (dgnushack-make-autoloads): Do nothing if the + files for autoloads already exist. + (dgnushack-unexporting-files): More useful message. + + * lisp/Makefile.in (install): Call `clever' before installing. + (install-lisp): Remove. + (clever): Check for whether the all elc files should be recompiled. + + * Makefile.in (xclever): New target. + (install-package-lisp): Replace `install-lisp' with `install'. + (install-package-ja): Replace `xlick' with `xclever'. + (install-package): Ditto. + +2001-01-17 KOSEKI Yoshinori + + * Makefile.in: Unset `PWD' for Meadow/NTEmacs. + +2001-01-15 Jesper Harder + + * make.bat: Fix doc. + +2001-01-15 Katsumi Yamaoka + + * lisp/nnheader.el: Require `pces', `poem' and `std11' to reduce + the required value of `recursive-load-depth-limit' for Emacs 21. + + * lisp/message.el (message-followup): Handle "Mail-Copies-To:" + correctly. + (message-get-reply-headers): Ditto. + +2001-01-15 Keiichi Suzuki + + * lisp/gnus-bbdb.el (gnus-bbdb/update-record): Save excursion + while `bbdb-annotate-message-sender' is being done. + +2001-01-13 Kinji Itoh + + * Makefile.in (install-package-lisp): Specify EMACS=$(XEMACS). + +2001-01-11 Katsumi Yamaoka + + * lisp/gnus-msg.el (gnus-copy-article-buffer): Remove smiley + extents for XEmacs 21.1 using `format'. + + * lisp/dgnushack.el (dgnushack-texi-format): Cancel last change. + +2001-01-10 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 03. + + * lisp/gnus.el: Don't autoload "smiley" for `smiley-toggle-buffer'; + don't autoload "gnus-bitmap" or "x-face-mule" when Emacs 21 is + running. + + * lisp/gnus-art.el (TopLevel): Autoload "gnus-bitmap" for + `smiley-toggle-buffer' when compiling. + (gnus-treatment-function-alist): Use `gnus-smiley-display' for + `gnus-treat-display-smileys' by default when XEmacs or Emacs 21 is + running. + (gnus-treat-display-smileys): Check for `smiley-mule' instead of + `gnus-bitmap'. + (gnus-article-x-face-command): Don't check for xbm for x-face-e21. + +2001-01-05 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 02. + + * lisp/dgnushack.el (dgnushack-texi-format): Remove "@anchor" if it + is not supported. + +2000-12-26 Katsumi Yamaoka + + * lisp/gnus.el: Bind `:parameter-type', `:parameter-document', + `:function', `:function-document', `:variable', + `:variable-document', `:variable-group', `:variable-type' and + `:variable-default' for old Emacsen. + +2000-12-22 Katsumi Yamaoka + + * lisp/gnus-vers.el (gnus-revision-number): Increment to 01. + + * configure: Regenerate. + * configure.in: Add `AC_PATH_ETCDIR'. + * Makefile.in (install-etc): New target. + + * lisp/nnheader.el (mm-image-load-path): Alias to + `nnheader-image-load-path'. + (nnheader-image-load-path): New function copied from + the function `mm-image-load-path' in mm-util.el. + + * lisp/drums.el: Remove. + +2000-12-22 03:00:00 ShengHuo ZHU + + * configure.in: Add etc/Makefile. + +2000-12-22 Katsumi Yamaoka + + * lisp/gnus-msg.el (gnus-debug): Use `sit-for' in the inside of + `save-excursion'. + (gnus-bug): Pop up the sending buffer first. + + * lisp/gnus-art.el (article-treat-dumbquotes): Quote backslashes in + doc-string. + + * lisp/dgnushack.el + (byte-compile-file-form-custom-declare-variable): Use `defvar' + instead of `custom-declare-variable' to make the variable + uncustomizable if the arguments has the keyword `:version'. + +2000-12-22 Katsuhiro Hermit Endo + + * README.semi.ja: Fix typo. + +2000-12-21 Katsumi Yamaoka + + * lisp/lpath.el: Fbind `compose-mail' for Mule. + + * lisp/dgnushack.el (TopLevel): Byte-optimize + `custom-declare-variable', `custom-declare-group, and + `custom-declare-face' to omit unsupported keywords when Mule is + running. + +2000-12-20 Katsumi Yamaoka + + * lisp/gnus-vers.el: T-gnus 6.15.0 revision 00. + + * lisp/dgnushack.el (TopLevel): Advise `custom-handle-keyword' not + to signal an error when Mule is running. + (TopLevel): Bind `:ascent', `:foreground', `:help', `:version' and + `:set-after' if colon keyword is not available. + (TopLevel): Require `custom'. + + * lisp/lpath.el (TopLevel): Fbind `shell-command-to-string' for + Mule. + (TopLevel): Don't require `custom' here. + +2000-12-20 Jesper Harder + + * make.bat: set max-lisp-eval-depth. + +See ChangeLog.3 for earlier changes. + +;; Local Variables: +;; coding: iso-2022-7bit +;; End: diff --git a/GNUS-NEWS b/GNUS-NEWS index 79b7cf7..b891063 100644 --- a/GNUS-NEWS +++ b/GNUS-NEWS @@ -1,5 +1,5 @@ GNUS NEWS -- history of user-visible changes. -Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. See the end for copying conditions. Please send Gnus bug reports to bugs@gnus.org. @@ -8,6 +8,11 @@ For older news, see Gnus info node "New Features". * 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. + ** The revised Gnus FAQ is included in the manual. See the info node "Frequently Asked Questions". @@ -19,7 +24,7 @@ to this version. In particular, you will probably want to remove all .marks (nnml) and .mrk (nnfolder) files, so that flags are read from your ~/.newsrc.eld instead of from the .marks/.mrk file where this release store flags. See a later entry for more information about -marks. Note that downgrading isn't save in general. +marks. Note that downgrading isn't safe in general. ** Article Buttons @@ -29,12 +34,12 @@ variables `gnus-button-*-level' can be used to control the appearance of all article buttons, see the info node "Article Button Levels". ** Dired integration -`gnus-dired-minor-mode' installs key bindings in dired buffers to send -a file as an attachment (`C-c C-a'), open a file using the approriate -mailcap entry (`C-c C-l'), and print a file using the mailcap entry -(`C-c P'). It is enabled with - (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) +`gnus-dired-minor-mode' installs key bindings in dired buffers to send a file +as an attachment (`C-c C-m C-a'), open a file using the approriate mailcap +entry (`C-c C-m C-l'), and print a file using the mailcap entry (`C-c C-m +C-p'). See the info node "Other modes". + ** Gnus can display RSS newsfeeds as a newsgroup. To get started do `B nnrss RET RET' in the Group buffer. @@ -42,7 +47,7 @@ nnrss RET RET' in the Group buffer. ** Single-part yenc encoded attachments can be decoded. ** Picons -The picons code has been reimplemented to work in GNU Emacs -- some of +The picons code has been reimplemented to work in Emacs 21 -- some of the previous options have been removed or renamed. Picons are small "personal icons" representing users, domain and @@ -73,8 +78,9 @@ the nnml back end allows compressed message files. ** Signed article headers (X-PGP-Sig) can be verified with `W p'. -** The Summary Buffer uses an arrow in the fringe to indicate the current -article. Use (setq gnus-summary-display-arrow nil) to disable it. +** The Summary Buffer uses an arrow in the fringe to indicate the +current article in Emacs 21 running on a graphical display. Customize +`gnus-summary-display-arrow' to disable it. ** Warn about email replies to news Do you often find yourself replying to news by email by mistake? Then @@ -117,11 +123,11 @@ argument to the batch-program should be the directory where xemacs.exe respectively emacs.exe is located, iff you want to install Gnus after compiling it, give make.bat /copy as the second parameter. -Make.bat has been rewritten from scratch, it now features automatic +`make.bat' has been rewritten from scratch, it now features automatic recognition of XEmacs and GNU Emacs, generates gnus-load.el, checks if errors occur while compilation and generation of info files and reports -them at the end of the build process. It now uses makeinfo if it is -available and falls back to infohack.el otherwise. Make.bat should now +them at the end of the build process. It now uses makeinfo if it is +available and falls back to infohack.el otherwise. `make.bat' should now install all files which are necessary to run Gnus and be generally a complete replacement for the "configure; make; make install" cycle used under Unix systems. @@ -174,13 +180,13 @@ expressions matching group names to group parameters, a'la: ** Smileys (":-)", ";-)" etc) are now iconized for Emacs too. -Put (setq gnus-treat-display-smileys nil) in ~/.emacs to disable it. +Customize `gnus-treat-display-smileys' to disable it. -** Gnus no longer generate the Sender: header automatically. +** Gnus no longer generates the Sender: header automatically. Earlier it was generated iff the user configurable email address was different from the Gnus guessed default user address. As the guessing -algorithm is rarely correct these days, and (more controversally) the +algorithm is rarely correct these days, and (more controversially) the only use of the Sender: header was to check if you are entitled to cancel/supersede news (which is now solved by Cancel Locks instead, see another entry), generation of the header has been disabled by @@ -197,12 +203,12 @@ note in the body for cross-postings and followups (see the variables `message-cross-post-*'). ** References and X-Draft-Headers are no longer generated when you - start composing messages and `message-generate-headers-first' is nil. +start composing messages and `message-generate-headers-first' is nil. ** Improved anti-spam features. Gnus is now able to take out spam from your mail and news streams -using a wide variety of programs and filter rules. Among the supported +using a wide variety of programs and filter rules. Among the supported methods are RBL blocklists, bogofilter and white/blacklists. Hooks for easy use of external packages such as SpamAssassin and Hashcash are also new. @@ -220,8 +226,8 @@ The estimated number of unread articles in the group buffer should now be correct for nnimap groups. This is achieved by calling `nnimap-fixup-unread-after-getting-new-news' from the `gnus-setup-news-hook' (called on startup) and -gnus-after-getting-new-news-hook. (called after getting new mail). If -you have modified those variables from the default, you may want to +`gnus-after-getting-new-news-hook' (called after getting new mail). +If you have modified those variables from the default, you may want to add n-f-u-a-g-n-n again. If you were happy with the estimate and want to save some (minimal) time when getting new mail, remove the function. @@ -245,25 +251,25 @@ not used any more. You can safely delete the entire hierarchy. ** gnus-agent -The Gnus Agent has seen a major updated and is now enabled by default, -and all nntp and nnimap servers from gnus-select-method and -gnus-secondary-select-method are agentized by default. Earlier only -the server in gnus-select-method was agentized by the default, and the +The Gnus Agent has seen a major update. It is now enabled by default, +and all nntp and nnimap servers from `gnus-select-method' and +`gnus-secondary-select-method' are agentized by default. Earlier only +the server in `gnus-select-method' was agentized by the default, and the agent was disabled by default. When the agent is enabled, headers are now also retrieved from the Agent cache instead of the backends when -possible. Earlier this only happened in the unplugged state. You can +possible. Earlier this only happened in the unplugged state. You can enroll or remove servers with `J a' and `J r' in the server buffer. Gnus will not download articles into the Agent cache, unless you instruct it to do so, though, by using `J u' or `J s' from the Group buffer. You revert to the old behaviour of having the Agent disabled -with `(setq gnus-agent nil)'. Note that putting (gnus-agentize) in +by customizing `gnus-agent'. Note that putting `(gnus-agentize)' in ~/.gnus is not needed any more. ** gnus-summary-line-format The default value changed to "%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n". -Moreover gnus-extra-headers, nnmail-extra-headers and -gnus-ignored-from-addresses changed their default so that the users +Moreover `gnus-extra-headers', `nnmail-extra-headers' and +`gnus-ignored-from-addresses' changed their default so that the users name will be replaced by the recipient's name or the group name posting to for NNTP groups. @@ -274,9 +280,9 @@ broken Outlook (Express) articles. ** (require 'gnus-load) -If you use a stand-alone Gnus distribution, you'd better add (require -'gnus-load) into your ~/.emacs after adding the Gnus lisp directory -into load-path. +If you use a stand-alone Gnus distribution, you'd better add +"(require 'gnus-load)" to your ~/.emacs after adding the Gnus +lisp directory into load-path. File gnus-load.el contains autoload commands, functions and variables, some of which may not be included in distributions of Emacsen. @@ -287,33 +293,33 @@ A new command which starts gnus offline in slave mode. ** message-insinuate-rmail -Adding (message-insinuate-rmail) and (setq mail-user-agent -'gnus-user-agent) in .emacs convinces Rmail to compose, reply and -forward messages in message-mode, where you can enjoy the power of -MML. +Adding (message-insinuate-rmail) in .emacs and customizing +`mail-user-agent' to `gnus-user-agent' convinces Rmail to compose, +reply and forward messages in Message mode, where you can enjoy the +power of MML. ** message-minibuffer-local-map The line below enables BBDB in resending a message: -(define-key message-minibuffer-local-map [(tab)] 'bbdb-complete-name) +(define-key message-minibuffer-local-map [?\t] 'bbdb-complete-name) ** Externalizing and deleting of attachments. -If gnus-gcc-externalize-attachments (or -message-fcc-externalize-attachments) is non-nil, attach local files as -external parts. +If `gnus-gcc-externalize-attachments' (or +`message-fcc-externalize-attachments') is non-nil, attach local files +as external parts. -The command gnus-mime-save-part-and-strip (bound to `C-o' on MIME +The command `gnus-mime-save-part-and-strip' (bound to `C-o' on MIME buttons) saves a part and replaces the part with an external one. -gnus-mime-delete-part (bound to `d' on MIME buttons) removes a part. +`gnus-mime-delete-part' (bound to `d' on MIME buttons) removes a part. It works only on back ends that support editing. ** gnus-default-charset -The default value is determined from the current-language-environment -variable, instead of 'iso-8859-1. Also the ".*" item in -gnus-group-charset-alist is removed. +The default value now guesses on the basis of your environment instead +of using Latin-1. Also the ".*" item in gnus-group-charset-alist is +removed. ** gnus-posting-styles @@ -330,14 +336,14 @@ The old format like the lines below is obsolete, but still accepted. ** message-ignored-news-headers and message-ignored-mail-headers X-Draft-From and X-Gnus-Agent-Meta-Information have been added into -these two variables. If you customized those, perhaps you need add +these two variables. If you customized those, perhaps you need add those two headers too. ** Gnus reads the NOV and articles in the Agent if plugged. If one reads an article while plugged, and the article already exists -in the Agent, it won't get downloaded once more. (setq -gnus-agent-cache nil) reverts to the old behavior. +in the Agent, it won't get downloaded once more. Customize +`gnus-agent-cache' to revert to the old behavior. ** Gnus supports the "format=flowed" (RFC 2646) parameter. @@ -368,11 +374,11 @@ valid values. This means a header "Cancel-Lock" is inserted in news posting. It is used to determine if you wrote a article or not (for cancelling and superseding). Gnus generates a random password string the first time -you post a message, and saves it in your ~/.emacs using the Custom -system. While the variable is called `canlock-password', it is not -security sensitive data. Publishing your canlock string on the web -will not allow anyone to be able to anything she could not already do. -The behaviour can be changed by customizing `message-insert-canlock'. +you post a message, and saves it using the Custom system. While the +variable is called `canlock-password', it is not security sensitive +data. Publishing your canlock string on the web will not allow anyone +to be able to anything she could not already do. The behaviour can be +changed by customizing `message-insert-canlock'. ** Gnus supports server-side mail filtering using Sieve. @@ -385,9 +391,9 @@ Sieve manual, for more information. ** Extended format specs. Format spec "%&user-date;" is added into -gnus-summary-line-format-alist. Also, user defined extended format +`gnus-summary-line-format-alist'. Also, user defined extended format specs are supported. The extended format specs look like "%u&foo;", -which invokes function gnus-user-format-function-foo. Because "&" is +which invokes function `gnus-user-format-function-foo'. Because "&" is used as the escape character, old user defined format "%u&" is no longer supported. @@ -409,7 +415,7 @@ This is supposedly what USEFOR wanted to migrate to. See `gnus-group-name-charset-group-alist' and `gnus-group-name-charset-method-alist' for customization. -** The nnml and nnfolder backends store marks for each groups. +** The nnml and nnfolder backends store marks for each group. This makes it possible to take backup of nnml/nnfolder servers/groups separately of ~/.newsrc.eld, while preserving marks. It also makes it @@ -438,7 +444,8 @@ variables should change those regexps accordingly. For example: ("^han\\>" euc-kr) -> ("\\(^\\|:\\)han\\>" euc-kr) ** Gnus supports PGP (RFC 1991/2440), PGP/MIME (RFC 2015/3156) and -** S/MIME (RFC 2630-2633). +S/MIME (RFC 2630-2633). + It needs an external S/MIME and OpenPGP implementation, but no additional lisp libraries. This add several menu items to the Attachments menu, and C-c RET key bindings, when composing messages. @@ -451,6 +458,13 @@ This also obsoletes `gnus-article-hide-pgp-hook'. This change was made to avoid conflict with the standard binding of `back-to-indentation', which is also useful in message mode. +** The default for message-forward-show-mml changed to symbol best. + +The behaviour for the `best' value is to show MML (i.e., convert MIME +to MML) when appropriate. MML will not be used when forwarding signed +or encrypted messages, as the conversion invalidate the digital +signature. + ** Bug fixes. @@ -509,7 +523,7 @@ ever-changing layouts. ---------------------------------------------------------------------- Copyright information: -Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Permission is granted to anyone to make or distribute verbatim copies of this document as received, in any medium, provided that the diff --git a/Makefile.in b/Makefile.in index 69c491b..c566844 100644 --- a/Makefile.in +++ b/Makefile.in @@ -60,22 +60,20 @@ install-info-ja: ## Rule for XEmacs package. install-package: \ xclever-package \ - compose-package \ remove-extra-files-in-package \ install-package-lisp \ install-package-info install-package-manifest install-package-ja: \ xclever-package \ - compose-package \ remove-extra-files-in-package \ install-package-lisp \ install-package-info install-package-info-ja \ install-package-manifest -package: xlick-package xinfo compose-package +package: xlick-package xinfo -package-ja: xlick-package xinfo xinfo-ja compose-package +package-ja: xlick-package xinfo xinfo-ja # Sub-rule for XEmacs package. install-package-lisp: @@ -138,10 +136,6 @@ remove-extra-files-in-package: cd lisp && $(MAKE) EMACS="$(XEMACS)" PACKAGEDIR=$$package_dir \ lispdir="$(PACKAGEDIR)/lisp/$(GNUS_PRODUCT_NAME)" \ remove-extra-files-in-package - -compose-package: - cd lisp && $(MAKE) EMACS="$(XEMACS)" \ - lispdir="$(PACKAGEDIR)/lisp/$(GNUS_PRODUCT_NAME)" compose-package ## xclever: diff --git a/Mule23@1934.en b/Mule23@1934.en index 9ed0acf..ba70609 100644 --- a/Mule23@1934.en +++ b/Mule23@1934.en @@ -65,6 +65,10 @@ By the way, the latest CUSTOM package for Emacs v19 is available from: ftp://ftp.dina.kvl.dk/pub/Staff/Per.Abrahamsen/custom/custom-1.9962.tar.gz +However, since the `custom-make-dependencies' function does not exist +in this version of CUSTOM, we will use the contrib/cus-dep.el which is +imported from Emacs 20.7 when building T-gnus. + INSTALL regexp-opt.el ===================== @@ -161,28 +165,15 @@ There are three ways of making T-gnus with Mule 2.3 based on Emacs 19.34. USING emacs-w3m (and Emacs/W3) ============================== -The web based backend `nnshimbun' uses the shimbun modules which are -included in emacs-w3m package (and the other web based backends of T- -gnus requires Emacs/W3). emacs-w3m is an interface program to the -external command w3m, visit the following pages for more information. +The `nnshimbun' web based back end has been moved to the emacs-w3m +package at 18 June 2003. You need to install the latest version of +emacs-w3m if you want to browse web newspapers using T-gnus as before. +In that case, you *must* delete nnshimbun.el and nnshimbun.elc files +originated by T-gnus. Emacs-w3m is an Emacs interface to the external +command w3m, visit the following pages for more information: http://emacs-w3m.namazu.org/ - http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/ - -If you wish to build T-gnus to be able to use emacs-w3m and nnshimbun, -you have to specify the path where emacs-w3m is installed using the -configure option `--with-addpath=' (for Emacs/W3, use the configure -option `--with-w3=' or editing the file `~/.lpath.el'). Here is an -example for that: - - % ./configure --with-emacs=mule\ - --with-addpath=~/elisp/emu/:~/elisp/apel/: ... :~/elisp/w3m/\ - --with-w3=/usr/local/share/mule/site-lisp/w3/ - % make install - -;; Don't mind if configure says "W3... not found". It is currently -;; malfunction when the configure option `--with-w3=' is not used even -;; if the path of Emacs/W3 is specified in the file `~/.lpath.el'. + http://w3m.sourceforge.net/ -;; By the way, does anyone know where do we find Emacs/W3 package -;; which is suitable to Mule 2.3 based on Emacs 19.34? +Please give up the idea to use Emacs/W3 under Mule 2.3. There is no +information, sorry. diff --git a/Mule23@1934.ja b/Mule23@1934.ja index 3bcdc8a..65b6607 100644 --- a/Mule23@1934.ja +++ b/Mule23@1934.ja @@ -63,10 +63,14 @@ ftp://ftp.jpl.org/pub/m17n/clime-1_14-************.tar.gz (let* ((frames (frame-list)) ------ cut here ------ cut here ------ cut here ------ cut here ------ -$B$J$*(B Emacs v19 $BMQ$N:G?7$N(B CUSTOM $B$O0J2<$N$b$N$rF~$N(B T-gnus $B$N%&%'%V$K(B -$B4p$E$$$?%P%C%/%(%s%I$O(B Emacs/W3 $B$rI,MW$H$7$^$9(B)$B!#(Bemacs-w3m $B$O30It%3%^(B -$B%s%I(B w3m $B$X$N%$%s%?!<%U%'!<%9$r9T$J$&%W%m%0%i%`$G!">\:Y>pJs$K$D$$$F$O(B -$B0J2<$N%Z!<%8$rK,$M$F$_$F2<$5$$!#(B +$B%&%'%V$K4p$E$$$?%P%C%/%(%s%I$G$"$k(B `nnshimbun' $B$O!"(B2003$BG/(B6$B7n(B18$BF|$r0J$F(B +emacs-w3m $B%Q%C%1!<%8$K0\@R$5$l$^$7$?!#:#$^$G$N$h$&$K(B T-gnus $B$G%&%'%V$N(B +$B?7J9$r1\Mw$7$?$$$N$G$"$l$P!":G?7HG$N(B emacs-w3m $B$r%$%s%9%H!<%k$9$kI,MW(B +$B$,$"$j$^$9!#$=$N:]!"(B*$BI,$:(B* T-gnus $BM3Mh$N(B nnshimbun.el $B$H(B nnshimbun.elc +$B%U%!%$%k$r>C$7$F2<$5$$!#(BEmacs-w3m $B$O30It%3%^%s%I(B w3m $B$X$N(B Emacs $B$N%$%s(B +$B%?!<%U%'!<%9$G$9!#>\:Y>pJs$K$D$$$F$O0J2<$N%Z!<%8$rK,$M$F$_$F2<$5$$!#(B http://emacs-w3m.namazu.org/ - http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/ - -emacs-w3m $B$H(B nnshimbun $B$,;H$($k$h$&$K(B T-gnus $B$r:n$k$K$O!"(Bemacs-w3m $B$,(B -$B%$%s%9%H!<%k$5$l$F$$$k%Q%9$r(B configure $B%*%W%7%g%s$N(B `--with-addpath=' -$B$G;XDj$7$J$1$l$P$J$j$^$;$s(B (Emacs/W3 $BMQ$K$O(B `--with-w3=' $B$r;H$&$+!"$^(B -$B$?$O(B `~/.lpath.el' $B%U%!%$%k$rJT=8$7$F2<$5$$(B)$B!#0J2<$ONc$G$9!#(B - - % ./configure --with-emacs=mule\ - --with-addpath=~/elisp/emu/:~/elisp/apel/: ... :~/elisp/w3m/\ - --with-w3=/usr/local/share/mule/site-lisp/w3/ - % make install - -;; $B$b$7(B configure $B$,!V(BW3... not found$B!W$H8@$C$F$b5$$K$7$J$$$G2<$5$$!#(B -;; $B$?$H$((B `~/.lpath.el' $B%U%!%$%k$G(B Emacs/W3 $B$N(B path $B$,;XDj$5$l$F$$$F$b!"(B -;; configure $B%*%W%7%g%s$N(B `--with-w3=' $B$r;H$o$J$$$H!"8=:_$=$l$O@5>o$K(B -;; $BF/$-$^$;$s$N$G!#(B + http://w3m.sourceforge.net/ -;; $B$H$3$m$G!"C/$+(B Emacs 19.34 $B$r%Y!<%9$K$7$?(B Mule 2.3 $B$KE,9g$9$k(B -;; Emacs/W3 $B$,$I$3$K$"$k$+CN$j$^$;$s$+(B? +Mule 2.3 $B$G(B Emacs/W3 $B$r;H$&$3$H$OD|$a$F2<$5$$!#$9$_$^$;$s$,>pJs$O$"$j(B +$B$^$;$s!#(B diff --git a/README.T-gnus b/README.T-gnus index 8051cb0..e7782dc 100644 --- a/README.T-gnus +++ b/README.T-gnus @@ -1,7 +1,7 @@ ======================================================================== Codename: T-gnus -Branch Tag: t-gnus-6_15 -Branch Status: Develop, Synchronize with Oort Gnus +Branch Tag: t-gnus-6_16 +Branch Status: Develop, Synchronize with Gnus Branch Goal: Implement latest features of gnus and offline features Use Gnus in Offline status. Branch Policy: (not defined yet) @@ -31,7 +31,7 @@ NEWS: See TODO.ja -* T-gnus 6.15 - this is based on Oort Gnus. +* T-gnus 6.16 - this is based on Gnus. - The latest T-gnus is T-gnus 6.15.24 (based on Oort Gnus 0.24). It + The latest T-gnus is T-gnus 6.16.6 (based on Gnus 5.10.6). It requires SEMI 1.14, FLIM 1.14, and APEL 10.0 or later. diff --git a/README.branch b/README.branch index 4bd8cc8..d8f40eb 100644 --- a/README.branch +++ b/README.branch @@ -1,7 +1,7 @@ README.branch --- description of branches and tags. (DRAFT) ======================================================================== -Semi-gnus revision tree (2002-10-09) +Semi-gnus revision tree (2003-05-02) vendor personal main trunk public branch branches branches @@ -39,14 +39,26 @@ qGnus 0.?? ------> Semi-gnus 6.0.0 : V V : : | : t-gnus-6_15-quimby<---<-----(t-gnus-6_14-quimby)<-----+ : | : : | - : : : | feedback | - : : +<--------------+ - : : | | - : akr <-- 6.2.3 : t-gnus-6_15 - : shuhei-k <-- 6.3.1 (for FLIM 1.14, -Gnus 5.6.11 ------> 6.3.3 develop) - : 6.4.0 (for SEMI 1.5) | - : (6.4.?)------> for SEMI 1.5 : + : | : | feedback | + : | : (Gnus 5.8.8)->+<--------------+ + : | : | | + : | : | t-gnus-6_15 + : +------------->--------------->----------> (for FLIM 1.14, + : : | develop) + : : | feedback | + : : (Gnus 5.10)->+<--------------+ + : : /|\ + : +------------->-------------- | ------------- + + : | : : | + : t-gnus-6_16-quimby : : V + : | : : t-gnus-6_16 + : +------------->--------------->----------> (for FLIM 1.14, + : : : develop) + : akr <-- 6.2.3 : | + : shuhei-k <-- 6.3.1 : +Gnus 5.6.11 ------> 6.3.3 + : 6.4.0 (for SEMI 1.5) + : (6.4.?)------> for SEMI 1.5 : | \ : | \ (Synch with original Gnus | ---> for SEMI 1.6 @@ -135,7 +147,8 @@ Public Branches t-gnus-6_13 T-gnus for SEMI 1.13, FLIM 1.13 API (develop) t-gnus-6_14 T-gnus for SEMI 1.13, FLIM 1.13 API (develop) t-gnus-6_15 T-gnus for SEMI 1.14, FLIM 1.14 API (develop) - t-gnus-6_15-quimby T-gnus for SEMI 1.14, FLIM 1.14 API (develop) + t-gnus-6_16 T-gnus for SEMI 1.14, FLIM 1.14 API (develop) + t-gnus-6_16-quimby T-gnus for SEMI 1.14, FLIM 1.14 API (develop) Note: T-gnus versions 6.15 based on Oort Gnus v0.03 and earlier had supported SEMI 1.13 and FLIM 1.13 as well. diff --git a/README.branch.ja b/README.branch.ja index 3eb56f1..5f91504 100644 --- a/README.branch.ja +++ b/README.branch.ja @@ -1,7 +1,7 @@ README.branch.ja --- branch $B$H(B tag $B$N@bL@(B ($BAp9F(B) ======================================================================== -Semi-gnus revision tree (2001-04-16) +Semi-gnus revision tree (2003-05-02) vendor personal main trunk public branch branches branches @@ -40,13 +40,25 @@ qGnus 0.?? ------> Semi-gnus 6.0.0 : t-gnus-6_15-quimby<---<-----(t-gnus-6_14-quimby)<-----+ : | : : | : : : | feedback | - : : +<--------------+ - : : | | - : akr <-- 6.2.3 : t-gnus-6_15 - : shuhei-k <-- 6.3.1 (for FLIM 1.14, -Gnus 5.6.11 ------> 6.3.3 develop) - : 6.4.0 (for SEMI 1.5) | - : (6.4.?)------> for SEMI 1.5 : + : | : (Gnus 5.8.8)->+<--------------+ + : | : | | + : | : | t-gnus-6_15 + : +------------->--------------->----------> (for FLIM 1.14, + : : | develop) + : : | feedback | + : : (Gnus 5.10)->+<--------------+ + : : /|\ + : +------------->-------------- | ------------- + + : | : : | + : t-gnus-6_16-quimby : : V + : | : : t-gnus-6_16 + : +------------->--------------->----------> (for FLIM 1.14, + : : : develop) + : akr <-- 6.2.3 : | + : shuhei-k <-- 6.3.1 : +Gnus 5.6.11 ------> 6.3.3 + : 6.4.0 (for SEMI 1.5) + : (6.4.?)------> for SEMI 1.5 : | \ : | \ ($B85$N(B Gnus $B$H$N(B Sync $B$O2?EY(B | ---> for SEMI 1.6 @@ -135,7 +147,8 @@ Public Branches t-gnus-6_13 T-gnus for SEMI 1.13, FLIM 1.13 API (develop) t-gnus-6_14 T-gnus for SEMI 1.13, FLIM 1.13 API (develop) t-gnus-6_15 T-gnus for SEMI 1.14, FLIM 1.14 API (develop) - t-gnus-6_15-quimby T-gnus for SEMI 1.14, FLIM 1.14 API (develop) + t-gnus-6_16 T-gnus for SEMI 1.14, FLIM 1.14 API (develop) + t-gnus-6_16-quimby T-gnus for SEMI 1.14, FLIM 1.14 API (develop) $BCm(B: v0.03 $B0JA0$N(B Oort Gnus $B$r85$K$7$?(B T-gnus 6.15 $B$O!"(BSEMI 1.13 $B$H(B FLIM 1.13 $B$b%5%]!<%H$7$F$$$^$7$?!#(B diff --git a/README.semi b/README.semi index 3b4e80b..5b41eb8 100644 --- a/README.semi +++ b/README.semi @@ -1,16 +1,16 @@ -This package contains T-gnus 6.15. +This package contains T-gnus 6.16. What is T-gnus? =============== T-gnus is an improvement of Gnus with SEMI's MIME feature. T-gnus -6.15 is based on Oort Gnus v0.24. SEMI may stand for "SEMI is Emacs -MIME Interface" and is developped to provide an easy interfaces for -users to handle MIME message structures. For further information, -refer to REASME.en of SEMI. +6.16 is based on Gnus v5.10. SEMI may stand for "SEMI is Emacs MIME +Interface" and is developped to provide an easy interfaces for users +to handle MIME message structures. For further information, refer to +README.en of SEMI. It requires APEL, FLIM and SEMI packages, so please get and install -them before to install it. T-gnus 6.15 requires APEL 10.0 or later, +them before to install it. T-gnus 6.16 requires APEL 10.0 or later, FLIM 1.14 and SEMI 1.14. You can get these packages from: ftp://ftp.m17n.org/pub/mule/apel/ @@ -39,7 +39,7 @@ How to get? (via CVS) (1) checkout % cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root \ - checkout -r t-gnus-6_15 gnus + checkout -r t-gnus-6_16 gnus (2) compile @@ -49,16 +49,16 @@ How to get? (via CVS) (3) update - % cvs update -r t-gnus-6_15 gnus + % cvs update -r t-gnus-6_16 gnus Major tags are following: - t-gnus-6_15-quimby Assigned to the latest version of T-gnus for - developing and synchronizing with Oort Gnus. + t-gnus-6_16-quimby Assigned to the latest version of T-gnus for + developing and synchronizing with Gnus. - t-gnus-6_15 Assigned to the latest version of T-gnus for + t-gnus-6_16 Assigned to the latest version of T-gnus for developing and synchronizing with the released - version of Oort Gnus. + version of Gnus. pgnus-ichikawa The main trunk of T-gnus. @@ -90,9 +90,9 @@ For more detailed information, please read README.branch. How to get? (via ftp) ===================== - T-gnus 6.15 is available from + T-gnus 6.16 is available from - ftp://ftp.jpl.org/pub/elisp/t-gnus-6.15/snapshots/ + ftp://ftp.jpl.org/pub/elisp/t-gnus-6.16/snapshots/ NOTE: These snapshots are manually created when the urge takes the administrator of the a-ftp site, and will usually not be tested. diff --git a/README.semi.ja b/README.semi.ja index 11d5455..57dda96 100644 --- a/README.semi.ja +++ b/README.semi.ja @@ -1,16 +1,16 @@ -$B$3$N%Q%C%1!<%8$K$O(B T-gnus 6.15 $B$,F~$C$F$$$^$9!#(B +$B$3$N%Q%C%1!<%8$K$O(B T-gnus 6.16 $B$,F~$C$F$$$^$9!#(B T-gnus $B$H$O!)(B ============= T-gnus $B$O!"(BSEMI $B$rMxMQ$7$F(B Gnus $B$K(B MIME $B5!G=$rDI2C$9$k$b$N$G$9!#(B -T-gnus 6.15 $B$O(B Oort Gnus v0.24 $B$r%Y!<%9$K$7$F$$$^$9!#(BSEMI $B$O(B Emacs $B$G(B -MIME $B$r;H$($k$h$&$K$9$k$b$N$G!"(BMIME message $B$N9=J8$N9=B$$HMxMQ\$7$/$O!"(BSEMI $B$N(B README.en $B$r;2>H(B -$B$7$F$/$@$5$$!#(B +T-gnus 6.16 $B$O(B Gnus v5.10 $B$r%Y!<%9$K$7$F$$$^$9!#(BSEMI $B$O(B Emacs $B$G(B MIME +$B$r;H$($k$h$&$K$9$k$b$N$G!"(BMIME message $B$N9=J8$N9=B$$HMxMQ\$7$/$O!"(BSEMI $B$N(B README.en $B$r;2>H$7$F(B +$B$/$@$5$$!#(B T-gnus $B$rMxMQ$9$k$K$O(B APEL, FLIM $B$*$h$S(B SEMI $B%Q%C%1!<%8$,I,MW$G$9$N(B -$B$G!"%$%s%9%H!<%k$9$kA0$K$=$l$i$r%$%s%9%H!<%k$7$F$/$@$5$$!#(BT-gnus 6.15 +$B$G!"%$%s%9%H!<%k$9$kA0$K$=$l$i$r%$%s%9%H!<%k$7$F$/$@$5$$!#(BT-gnus 6.16 $B$O(B APEL 10.0 $B0J>e!"(BFLIM 1.14 $B$*$h$S(B SEMI 1.14 $B$rI,MW$H$7$^$9!#$=$l$i$N(B $B%Q%C%1!<%8$O(B @@ -40,7 +40,7 @@ http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/ (1) checkout % cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/root \ - checkout -r t-gnus-6_15 gnus + checkout -r t-gnus-6_16 gnus (2) compile @@ -50,15 +50,15 @@ http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/ (3) update - % cvs update -r t-gnus-6_15 gnus + % cvs update -r t-gnus-6_16 gnus $Bl=j$+$il=j$+$i + + * starttls.el: Sync with recent gnu.emacs.sources post. + +2003-10-24 Steve Youngs + + * nnir.el: Autoload `read-kbd-macro' at compile time. + +2003-09-30 Kai Grossjohann + From Torsten Hilbrich . + + * nnir.el (nnir-imap-search-field, nnir-imap-search-arguments) + (nnir-imap-search-argument-history): New variables. + (nnir-engines, nnir-run-imap): Use them. + (nnir-read-parm): Support reading the new IMAP query parameters. + +2003-06-03 Kai Gro,A_(Bjohann + + * README: Explain purpose of each file (well, most files). + 2003-05-01 Vasily Korytov * gpg.el (gpg-passphrase-forget): Check that gpg-passphrase is diff --git a/contrib/README b/contrib/README index 76d0e5c..7c3c3fc 100644 --- a/contrib/README +++ b/contrib/README @@ -1,3 +1,59 @@ -The files in this directory are not (yet) part of the -Gnus distribution proper. They may later become part -of the distribution, or they may disappear altogether. +The files in this directory are not (yet) part of the Gnus +distribution proper. They may later become part of the distribution, +or they may disappear altogether. + +Please note that it is not good to just add this directory to +load-path: a number of files in this directory will become part of +more recent Emacs versions, so that you might be running obsolete +libraries with all kinds of ill effects. + +The suggested method for installation is to copy those files that you +need to a directory which is in load-path. + +Here is an overview of the files: + +base64.el + + As of Emacs 21, base64 encoding and decoding is available + natively. So this file appears to be needed for Emacs 20 + only. + +gpg-ring.el +gpg.el + +hashcash.el + +md5.el + + MD5 encoding is part of Emacs as of Emacs 21.2. Hence, this + file is not needed for those Emacs versions. + +one-line-cookie.diff + +ssl.el + +ucs-tables.el + + This file provides improved Unicode functionality. It defines + functions unify-8859-on-encoding-mode and + unify-8859-on-decoding-mode which unify the Latin-N charsets. + Without unify-8859-on-encoding-mode, composing a Latin-9 reply + to a Latin-1 posting, say, will produce a multipart posting (a + Latin-1 part and a Latin-9 part), or perhaps UTF-8. With + unify-8859-on-encoding-mode, the outgoing posting can be all + Latin-1 or all Latin-9 in most cases. + + It is harmless to turn on unify-8859-on-encoding-mode, but + unify-8859-on-decoding-mode may unexpectedly change files in + certain situations. (If the file contains different Latin-N + charsets which should not be unified.) + + This is part of Emacs 21.3 and later, which also turns on + unify-8859-on-encoding-mode by default. + +vcard.el + +xml.el + + This is used for parsing RSS feeds. Part of Emacs 21.3 and + later. diff --git a/contrib/cus-dep.el b/contrib/cus-dep.el new file mode 100644 index 0000000..8b689bf --- /dev/null +++ b/contrib/cus-dep.el @@ -0,0 +1,171 @@ +;;; cus-dep.el --- Find customization dependencies. +;; +;; Copyright (C) 1997 Free Software Foundation, Inc. +;; +;; Author: Per Abrahamsen +;; Keywords: internal + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Code: + +(require 'cl) +(require 'widget) +(require 'cus-face) +(require 'autoload) + +(defun custom-make-dependencies () + "Batch function to extract custom dependencies from .el files. +Usage: emacs -batch -l ./cus-dep.el -f custom-make-dependencies DIRS" + (let ((enable-local-eval nil) + (all-subdirs command-line-args-left) + (start-directory default-directory)) + (get-buffer-create " cus-dep temp") + (set-buffer " cus-dep temp") + (while all-subdirs + (message "Directory %s" (car all-subdirs)) + (let ((files (directory-files (car all-subdirs) nil "\\`[^=].*\\.el\\'")) + (default-directory default-directory) + file + is-autoloaded) + (cd (car all-subdirs)) + (while files + (setq file (car files) + files (cdr files)) + (when (file-exists-p file) + (erase-buffer) + (insert-file-contents file) + (goto-char (point-min)) + (string-match "\\`\\(.*\\)\\.el\\'" file) + (let ((name (file-name-nondirectory (match-string 1 file)))) + (condition-case nil + (while (re-search-forward "^(defcustom\\|^(defface\\|^(defgroup" + nil t) + (setq is-autoloaded nil) + (beginning-of-line) + (save-excursion + (forward-line -1) + (if (looking-at generate-autoload-cookie) + (setq is-autoloaded t))) + (let ((expr (read (current-buffer)))) + (condition-case nil + (progn + (eval expr) + (put (nth 1 expr) 'custom-autoloaded is-autoloaded) + (put (nth 1 expr) 'custom-where name)) + (error nil)))) + (error nil))))) + (setq all-subdirs (cdr all-subdirs))))) + (message "Generating cus-load.el...") + (find-file "cus-load.el") + (erase-buffer) + (insert "\ +;;; cus-load.el --- automatically extracted custom dependencies +;; +;;; Code: + +") + (mapatoms (lambda (symbol) + (let ((members (get symbol 'custom-group)) + item where found) + (when members + (while members + (setq item (car (car members)) + members (cdr members) + where (get item 'custom-where)) + (unless (or (null where) + (member where found)) + (if found + (insert " ") + (insert "(put '" (symbol-name symbol) + " 'custom-loads '(")) + (prin1 where (current-buffer)) + (push where found))) + (when found + (insert "))\n")))))) + (insert "\ +;;; These are for handling :version. We need to have a minimum of +;;; information so `custom-changed-variables' could do its job. +;;; For both groups and variables we have to set `custom-version'. +;;; For variables we also set the `standard-value' and for groups +;;; `group-documentation' (which is shown in the customize buffer), so +;;; we don't have to load the file containing the group. + +;;; `custom-versions-load-alist' is an alist that has as car a version +;;; number and as elts the files that have variables that contain that +;;; version. These files should be loaded before showing the +;;; customization buffer that `customize-changed-options' generates. + + +;;; This macro is used so we don't modify the information about +;;; variables and groups if it's already set. (We don't know when +;;; cus-load.el is going to be loaded and at that time some of the +;;; files might be loaded and some others might not). +(defmacro custom-put-if-not (symbol propname value) + `(unless (get ,symbol ,propname) + (put ,symbol ,propname ,value))) + +") + (let ((version-alist nil)) + (mapatoms (lambda (symbol) + (let ((version (get symbol 'custom-version)) + where) + (when version + (setq where (get symbol 'custom-where)) + (when (and where + ;; Don't bother to do anything if it's + ;; autoloaded because we will have all + ;; this info when emacs is running + ;; anyway. + (not (get symbol 'custom-autoloaded))) + (insert "(custom-put-if-not '" (symbol-name symbol) + " 'custom-version ") + (prin1 version (current-buffer)) + (insert ")\n") + (insert "(custom-put-if-not '" (symbol-name symbol)) + (if (get symbol 'standard-value) + ;; This means it's a variable + (progn + (insert " 'standard-value t)\n") + (if (assoc version version-alist) + (unless + (member where + (cdr (assoc version version-alist))) + (push where (cdr (assoc version version-alist)))) + (push (cons version (list where)) version-alist))) + ;; This is a group + (insert " 'group-documentation ") + (prin1 (get symbol 'group-documentation) (current-buffer)) + (insert ")\n"))))))) + + (insert "\n(defvar custom-versions-load-alist " + (if version-alist "'" "")) + (prin1 version-alist (current-buffer)) + (insert "\n \"For internal use by custom.\")\n")) + + (insert "\ + +\(provide 'cus-load) + +;;; cus-load.el ends here\n") + (let ((kept-new-versions 10000000)) + (save-buffer)) + (message "Generating cus-load.el...done") + (kill-emacs)) + +;;; cus-dep.el ends here diff --git a/contrib/hashcash.el b/contrib/hashcash.el index 6702faf..84dfcae 100644 --- a/contrib/hashcash.el +++ b/contrib/hashcash.el @@ -1,7 +1,7 @@ ;;; hashcash.el --- Add hashcash payments to email -;; Copyright (C) 1997--2002 Paul E. Foley ;; Copyright (C) 2003 Free Software Foundation +;; Copyright (C) 1997--2002 Paul E. Foley ;; Maintainer: Paul Foley ;; Keywords: mail, hashcash @@ -21,8 +21,6 @@ ;;; Code: -(eval-when-compile (require 'cl)) - (eval-and-compile (autoload 'executable-find "executable")) @@ -61,38 +59,30 @@ is used instead.") (require 'mail-utils) -(if (fboundp 'point-at-bol) - (defalias 'hashcash-point-at-bol 'point-at-bol) - (defalias 'hashcash-point-at-bol 'line-beginning-position)) +(eval-and-compile + (if (fboundp 'point-at-bol) + (defalias 'hashcash-point-at-bol 'point-at-bol) + (defalias 'hashcash-point-at-bol 'line-beginning-position)) -(if (fboundp 'point-at-eol) - (defalias 'hashcash-point-at-eol 'point-at-eol) - (defalias 'hashcash-point-at-eol 'line-end-position)) + (if (fboundp 'point-at-eol) + (defalias 'hashcash-point-at-eol 'point-at-eol) + (defalias 'hashcash-point-at-eol 'line-end-position))) (defun hashcash-strip-quoted-names (addr) (setq addr (mail-strip-quoted-names addr)) - (if (and addr (string-match "^[^+@]+\\(\\+[^@]*\\)@" addr)) - (concat (substring addr 0 (match-beginning 1)) - (substring addr (match-end 1))) + (if (and addr (string-match "\\`\\([^+@]+\\)\\+[^@]*\\(@.+\\)" addr)) + (concat (match-string 1 addr) (match-string 2 addr)) addr)) (defun hashcash-payment-required (addr) "Return the hashcash payment value required for the given address." (let ((val (assoc addr hashcash-payment-alist))) - (if val - (if (cddr val) - (caddr val) - (cadr val)) - hashcash-default-payment))) + (or (nth 2 val) (nth 1 val) hashcash-default-payment))) (defun hashcash-payment-to (addr) "Return the string with which hashcash payments should collide." (let ((val (assoc addr hashcash-payment-alist))) - (if val - (if (cddr val) - (cadr val) - (car val)) - addr))) + (or (nth 1 val) (nth 0 val) addr))) (defun hashcash-generate-payment (str val) "Generate a hashcash payment by finding a VAL-bit collison on STR." @@ -101,7 +91,7 @@ is used instead.") (set-buffer (get-buffer-create " *hashcash*")) (erase-buffer) (call-process hashcash-path nil t nil - (concat "-b " (number-to-string val)) str) + "-m" "-q" "-b" (number-to-string val) str) (goto-char (point-min)) (buffer-substring (hashcash-point-at-bol) (hashcash-point-at-eol))) nil)) @@ -137,17 +127,17 @@ is used instead.") (let ((pay (hashcash-generate-payment (hashcash-payment-to arg) (hashcash-payment-required arg)))) (when pay - (insert-before-markers "X-Payment: hashcash " - (number-to-string (hashcash-version pay)) " " - pay "\n") +; (insert-before-markers "X-Payment: hashcash " +; (number-to-string (hashcash-version pay)) " " +; pay "\n") (insert-before-markers "X-Hashcash: " pay "\n")))) ;;;###autoload (defun hashcash-verify-payment (token &optional resource amount) "Verify a hashcash payment" (let ((key (if (< (hashcash-version token) 1.2) - (cadr (split-string token ":")) - (caddr (split-string token ":"))))) + (nth 1 (split-string token ":")) + (nth 2 (split-string token ":"))))) (cond ((null resource) (let ((elt (assoc key hashcash-accept-resources))) (and elt (hashcash-check-payment token (car elt) @@ -168,9 +158,7 @@ for each recipient address. Prefix arg sets default payment temporarily." (save-excursion (save-restriction (goto-char (point-min)) - (re-search-forward (concat "^\\(" - (regexp-quote mail-header-separator) - "\\)?$")) + (search-forward mail-header-separator) (beginning-of-line) (narrow-to-region (point-min) (point)) (let ((to (hashcash-strip-quoted-names (mail-fetch-field "To" nil t))) @@ -183,8 +171,8 @@ for each recipient address. Prefix arg sets default payment temporarily." (setq addrlist (nconc addrlist (split-string cc ",[ \t\n]*")))) (when (and hashcash-in-news ng) (setq addrlist (nconc addrlist (split-string ng ",[ \t\n]*"))))) - (while addrlist - (hashcash-insert-payment (pop addrlist)))))) + (when addrlist + (mapcar #'hashcash-insert-payment addrlist))))) ; mapc t) ;;;###autoload diff --git a/contrib/nnir.el b/contrib/nnir.el new file mode 100644 index 0000000..0a2347b --- /dev/null +++ b/contrib/nnir.el @@ -0,0 +1,1559 @@ +;;; nnir.el --- search mail with various search engines -*- coding: iso-8859-1 -*- +;; Copyright (C) 1998 Kai Großjohann + +;; Author: Kai Großjohann +;; Keywords: news, mail, searching, ir, glimpse, wais, hyrex + +;; This file is not part of GNU Emacs. + +;; This is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; The most recent version of this can always be fetched from the Gnus +;; CVS repository. See http://www.gnus.org/ for more information. + +;; This code is still in the development stage but I'd like other +;; people to have a look at it. Please do not hesitate to contact me +;; with your ideas. + +;; What does it do? Well, it allows you to index your mail using some +;; search engine (freeWAIS-sf, Glimpse and others -- see later), +;; then type `G G' in the Group buffer and issue a query to the search +;; engine. You will then get a buffer which shows all articles +;; matching the query, sorted by Retrieval Status Value (score). + +;; When looking at the retrieval result (in the Summary buffer) you +;; can type `G T' (aka M-x gnus-summary-nnir-goto-thread RET) on an +;; article. You will be teleported into the group this article came +;; from, showing the thread this article is part of. (See below for +;; restrictions.) + +;; The Lisp installation is simple: just put this file on your +;; load-path, byte-compile it, and load it from ~/.gnus or something. +;; This will install a new command `G G' in your Group buffer for +;; searching your mail. Note that you also need to configure a number +;; of variables, as described below. + +;; Restrictions: +;; +;; * If you don't use HyREX as your search engine, this expects that +;; you use nnml or another one-file-per-message backend, because the +;; others doesn't support nnfolder. +;; * It can only search the mail backend's which are supported by one +;; search engine, because of different query languages. +;; * There are restrictions to the Glimpse setup. +;; * There are restrictions to the Wais setup. +;; * There are restrictions to the imap setup. +;; * gnus-summary-nnir-goto-thread: Fetches whole group first, before +;; limiting to the right articles. This is much too slow, of +;; course. May issue a query for number of articles to fetch; you +;; must accept the default of all articles at this point or things +;; may break. + +;; The Lisp setup involves setting a few variables and setting up the +;; search engine. You can define the variables in the server definition +;; like this : +;; (setq gnus-secondary-select-methods '( +;; (nnimap "" (nnimap-address "localhost") +;; (nnir-search-engine hyrex) +;; (nnir-hyrex-additional-switches ("-d" "ddl-nnimap.xml")) +;; ))) +;; Or you can define the global ones. The variables set in the mailer- +;; definition will be used first. +;; The variable to set is `nnir-search-engine'. Choose one of the engines +;; listed in `nnir-engines'. (Actually `nnir-engines' is an alist, +;; type `C-h v nnir-engines RET' for more information; this includes +;; examples for setting `nnir-search-engine', too.) +;; +;; The variable nnir-mail-backend isn't used anymore. +;; + +;; You must also set up a search engine. I'll tell you about the two +;; search engines currently supported: + +;; 1. freeWAIS-sf +;; +;; As always with freeWAIS-sf, you need a so-called `format file'. I +;; use the following file: +;; +;; ,----- +;; | # Kai's format file for freeWAIS-sf for indexing mails. +;; | # Each mail is in a file, much like the MH format. +;; | +;; | # Document separator should never match -- each file is a document. +;; | record-sep: /^@this regex should never match@$/ +;; | +;; | # Searchable fields specification. +;; | +;; | region: /^[sS]ubject:/ /^[sS]ubject: */ +;; | subject "Subject header" stemming TEXT BOTH +;; | end: /^[^ \t]/ +;; | +;; | region: /^([tT][oO]|[cC][cC]):/ /^([tT][oO]|[cC][cC]): */ +;; | to "To and Cc headers" SOUNDEX BOTH +;; | end: /^[^ \t]/ +;; | +;; | region: /^[fF][rR][oO][mM]:/ /^[fF][rR][oO][mM]: */ +;; | from "From header" SOUNDEX BOTH +;; | end: /^[^ \t]/ +;; | +;; | region: /^$/ +;; | stemming TEXT GLOBAL +;; | end: /^@this regex should never match@$/ +;; `----- +;; +;; 1998-07-22: waisindex would dump core on me for large articles with +;; the above settings. I used /^$/ as the end regex for the global +;; field. That seemed to work okay. + +;; There is a Perl module called `WAIS.pm' which is available from +;; CPAN as well as ls6-ftp.cs.uni-dortmund.de:/pub/wais/Perl. This +;; module comes with a nifty tool called `makedb', which I use for +;; indexing. Here's my `makedb.conf': +;; +;; ,----- +;; | # Config file for makedb +;; | +;; | # Global options +;; | waisindex = /usr/local/bin/waisindex +;; | wais_opt = -stem -t fields +;; | # `-stem' option necessary when `stemming' is specified for the +;; | # global field in the *.fmt file +;; | +;; | # Own variables +;; | homedir = /home/kai +;; | +;; | # The mail database. +;; | database = mail +;; | files = `find $homedir/Mail -name \*[0-9] -print` +;; | dbdir = $homedir/.wais +;; | limit = 100 +;; `----- +;; +;; The Lisp setup involves the `nnir-wais-*' variables. The most +;; difficult to understand variable is probably +;; `nnir-wais-remove-prefix'. Here's what it does: the output of +;; `waissearch' basically contains the file name and the (full) +;; directory name. As Gnus works with group names rather than +;; directory names, the directory name is transformed into a group +;; name as follows: first, a prefix is removed from the (full) +;; directory name, then all `/' are replaced with `.'. The variable +;; `nnir-wais-remove-prefix' should contain a regex matching exactly +;; this prefix. It defaults to `$HOME/Mail/' (note the trailing +;; slash). + +;; 2. Glimpse +;; +;; The code expects you to have one Glimpse index which contains all +;; your mail files. The Lisp setup involves setting the +;; `nnir-glimpse-*' variables. The most difficult to understand +;; variable is probably `nnir-glimpse-remove-prefix', it corresponds +;; to `nnir-wais-remove-prefix', see above. The `nnir-glimpse-home' +;; variable should be set to the value of the `-H' option which allows +;; one to search this Glimpse index. I have indexed my whole home +;; directory with Glimpse, so I assume a default of `$HOME'. + +;; 3. Namazu +;; +;; The Namazu backend requires you to have one directory containing all +;; index files, this is controlled by the `nnir-namazu-index-directory' +;; variable. To function the `nnir-namazu-remove-prefix' variable must +;; also be correct, see the documentation for `nnir-wais-remove-prefix' +;; above. +;; +;; It is particularly important not to pass any any switches to namazu +;; that will change the output format. Good switches to use include +;; `--sort', `--ascending', `--early' and `--late'. Refer to the Namazu +;; documentation for further information on valid switches. +;; +;; To index my mail with the `mknmz' program I use the following +;; configuration file: +;; +;; ,---- +;; | package conf; # Don't remove this line! +;; | +;; | # Paths which will not be indexed. Don't use `^' or `$' anchors. +;; | $EXCLUDE_PATH = "spam|sent"; +;; | +;; | # Header fields which should be searchable. case-insensitive +;; | $REMAIN_HEADER = "from|date|message-id|subject"; +;; | +;; | # Searchable fields. case-insensitive +;; | $SEARCH_FIELD = "from|date|message-id|subject"; +;; | +;; | # The max length of a word. +;; | $WORD_LENG_MAX = 128; +;; | +;; | # The max length of a field. +;; | $MAX_FIELD_LENGTH = 256; +;; `---- +;; +;; My mail is stored in the directories ~/Mail/mail/, ~/Mail/lists/ and +;; ~/Mail/archive/, so to index them I go to the directory set in +;; `nnir-namazu-index-directory' and issue the following command. +;; +;; mknmz --mailnews ~/Mail/archive/ ~/Mail/mail/ ~/Mail/lists/ +;; +;; For maximum searching efficiency I have a cron job set to run this +;; command every four hours. + +;; 4. HyREX +;; +;; The HyREX backend requires you to have one directory from where all +;; your relative paths are to, if you use them. This directory must be +;; set in the `nnir-hyrex-index-directory' variable, which defaults to +;; your home directory. You must also pass the base, class and +;; directory options or simply your dll to the `nnir-hyrex-programm' by +;; setting the `nnir-hyrex-additional-switches' variable accordently. +;; To function the `nnir-hyrex-remove-prefix' variable must also be +;; correct, see the documentation for `nnir-wais-remove-prefix' above. + +;; Developer information: + +;; I have tried to make the code expandable. Basically, it is divided +;; into two layers. The upper layer is somewhat like the `nnvirtual' +;; or `nnkiboze' backends: given a specification of what articles to +;; show from another backend, it creates a group containing exactly +;; those articles. The lower layer issues a query to a search engine +;; and produces such a specification of what articles to show from the +;; other backend. + +;; The interface between the two layers consists of the single +;; function `nnir-run-query', which just selects the appropriate +;; function for the search engine one is using. The input to +;; `nnir-run-query' is a string, representing the query as input by +;; the user. The output of `nnir-run-query' is supposed to be a +;; vector, each element of which should in turn be a three-element +;; vector. The first element should be full group name of the article, +;; the second element should be the article number, and the third +;; element should be the Retrieval Status Value (RSV) as returned from +;; the search engine. An RSV is the score assigned to the document by +;; the search engine. For Boolean search engines like Glimpse, the +;; RSV is always 1000 (or 1 or 100, or whatever you like). + +;; The sorting order of the articles in the summary buffer created by +;; nnir is based on the order of the articles in the above mentioned +;; vector, so that's where you can do the sorting you'd like. Maybe +;; it would be nice to have a way of displaying the search result +;; sorted differently? + +;; So what do you need to do when you want to add another search +;; engine? You write a function that executes the query. Temporary +;; data from the search engine can be put in `nnir-tmp-buffer'. This +;; function should return the list of articles as a vector, as +;; described above. Then, you need to register this backend in +;; `nnir-engines'. Then, users can choose the backend by setting +;; `nnir-search-engine'. + +;; Todo, or future ideas: + +;; * Make it so that Glimpse can also be called without `-F'. +;; +;; * It should be possible to restrict search to certain groups. +;; +;; * There is currently no error checking. +;; +;; * The summary buffer display is currently really ugly, with all the +;; added information in the subjects. How could I make this +;; prettier? +;; +;; * A function which can be called from an nnir summary buffer which +;; teleports you into the group the current article came from and +;; shows you the whole thread this article is part of. +;; Implementation suggestions? +;; (1998-07-24: There is now a preliminary implementation, but +;; it is much too slow and quite fragile.) +;; +;; * Support other mail backends. In particular, probably quite a few +;; people use nnfolder. How would one go about searching nnfolders +;; and producing the right data needed? The group name and the RSV +;; are simple, but what about the article number? +;; - The article number is encoded in the `X-Gnus-Article-Number' +;; header of each mail. +;; - The HyREX engine supports nnfolder. +;; +;; * Support compressed mail files. Probably, just stripping off the +;; `.gz' or `.Z' file name extension is sufficient. +;; +;; * Support a find/grep combination. +;; +;; * At least for imap, the query is performed twice. +;; + +;; Have you got other ideas? + +;;; Setup Code: + +(defconst nnir-version "$Id: nnir.el,v 1.1.6.1 2004-01-04 23:51:01 yamaoka Exp $" + "Version of NNIR.") + +(require 'cl) +(require 'nnoo) +(require 'gnus-group) +(require 'gnus-sum) +(eval-and-compile + (require 'gnus-util)) +(eval-when-compile + (require 'nnimap) + (autoload 'read-kbd-macro "edmacro" nil t)) + +(nnoo-declare nnir) +(nnoo-define-basics nnir) + +(gnus-declare-backend "nnir" 'mail) + +(defvar nnir-imap-search-field "TEXT" + "The IMAP search item when doing an nnir search") + +(defvar nnir-imap-search-arguments + '(("Whole message" . "TEXT") + ("Subject" . "SUBJECT") + ("To" . "TO") + ("From" . "FROM") + (nil . "HEADER \"%s\"")) + "Mapping from user readable strings to IMAP search items for use in nnir") + +(defvar nnir-imap-search-argument-history () + "The history for querying search options in nnir") + +;;; Developer Extension Variable: + +(defvar nnir-engines + `((glimpse nnir-run-glimpse + ((group . "Group spec: "))) + (wais nnir-run-waissearch + ()) + (excite nnir-run-excite-search + ()) + (imap nnir-run-imap + ((criteria + "Search in: " ; Prompt + ,nnir-imap-search-arguments ; alist for completing + nil ; no filtering + nil ; allow any user input + nil ; initial value + nnir-imap-search-argument-history ; the history to use + ,nnir-imap-search-field ; default + ))) + (swish++ nnir-run-swish++ + ((group . "Group spec: "))) + (swish-e nnir-run-swish-e + ((group . "Group spec: "))) + (namazu nnir-run-namazu + ()) + (hyrex nnir-run-hyrex + ((group . "Group spec: ")))) + "Alist of supported search engines. +Each element in the alist is a three-element list (ENGINE FUNCTION ARGS). +ENGINE is a symbol designating the searching engine. FUNCTION is also +a symbol, giving the function that does the search. The third element +ARGS is a list of cons pairs (PARAM . PROMPT). When issuing a query, +the FUNCTION will issue a query for each of the PARAMs, using PROMPT. + +The value of `nnir-search-engine' must be one of the ENGINE symbols. +For example, use the following line for searching using freeWAIS-sf: + (setq nnir-search-engine 'wais) +Use the following line if you read your mail via IMAP and your IMAP +server supports searching: + (setq nnir-search-engine 'imap) +Note that you have to set additional variables for most backends. For +example, the `wais' backend needs the variables `nnir-wais-program', +`nnir-wais-database' and `nnir-wais-remove-prefix'. + +Add an entry here when adding a new search engine.") + +;;; User Customizable Variables: + +(defgroup nnir nil + "Search nnmh and nnml groups in Gnus with Glimpse, freeWAIS-sf, or EWS.") + +;; Mail backend. + +;; TODO: +;; If `nil', use server parameters to find out which server to search. CCC +;; +(defcustom nnir-mail-backend '(nnml "") + "*Specifies which backend should be searched. +More precisely, this is used to determine from which backend to fetch the +messages found. + +This must be equal to an existing server, so maybe it is best to use +something like the following: + (setq nnir-mail-backend (nth 0 gnus-secondary-select-methods)) +The above line works fine if the mail backend you want to search is +the first element of gnus-secondary-select-methods (`nth' starts counting +at zero)." + :type '(sexp) + :group 'nnir) + +;; Search engine to use. + +(defcustom nnir-search-engine 'wais + "*The search engine to use. Must be a symbol. +See `nnir-engines' for a list of supported engines, and for example +settings of `nnir-search-engine'." + :type '(sexp) + :group 'nnir) + +;; Glimpse engine. + +(defcustom nnir-glimpse-program "glimpse" + "*Name of Glimpse executable." + :type '(string) + :group 'nnir) + +(defcustom nnir-glimpse-home (getenv "HOME") + "*Value of `-H' glimpse option. +`~' and environment variables must be expanded, see the functions +`expand-file-name' and `substitute-in-file-name'." + :type '(directory) + :group 'nnir) + +(defcustom nnir-glimpse-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each file name returned by Glimpse +in order to get a group name (albeit with / instead of .). This is a +regular expression. + +For example, suppose that Glimpse returns file names such as +\"/home/john/Mail/mail/misc/42\". For this example, use the following +setting: (setq nnir-glimpse-remove-prefix \"/home/john/Mail/\") +Note the trailing slash. Removing this prefix gives \"mail/misc/42\". +`nnir' knows to remove the \"/42\" and to replace \"/\" with \".\" to +arrive at the correct group name, \"mail.misc\"." + :type '(regexp) + :group 'nnir) + +(defcustom nnir-glimpse-additional-switches '("-i") + "*A list of strings, to be given as additional arguments to glimpse. +The switches `-H', `-W', `-l' and `-y' are always used -- calling +glimpse without them does not make sense in our situation. +Suggested elements to put here are `-i' and `-w'. + +Note that this should be a list. Ie, do NOT use the following: + (setq nnir-glimpse-additional-switches \"-i -w\") ; wrong! +Instead, use this: + (setq nnir-glimpse-additional-switches '(\"-i\" \"-w\"))" + :type '(repeat (string)) + :group 'nnir) + +;; freeWAIS-sf. + +(defcustom nnir-wais-program "waissearch" + "*Name of waissearch executable." + :type '(string) + :group 'nnir) + +(defcustom nnir-wais-database (expand-file-name "~/.wais/mail") + "*Name of Wais database containing the mail. + +Note that this should be a file name without extension. For example, +if you have a file /home/john/.wais/mail.fmt, use this: + (setq nnir-wais-database \"/home/john/.wais/mail\") +The string given here is passed to `waissearch -d' as-is." + :type '(file) + :group 'nnir) + +(defcustom nnir-wais-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each directory name returned by waissearch +in order to get a group name (albeit with / instead of .). This is a +regular expression. + +This variable is similar to `nnir-glimpse-remove-prefix', only for Wais, +not Glimpse." + :type '(regexp) + :group 'nnir) + +;; EWS (Excite for Web Servers) engine. + +(defcustom nnir-excite-aquery-program "aquery.pl" + "*Name of the EWS query program. Should be `aquery.pl' or a path to same." + :type '(string) + :group 'nnir) + +(defcustom nnir-excite-collection "Mail" + "*Name of the EWS collection to search." + :type '(string) + :group 'nnir) + +(defcustom nnir-excite-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each file name returned by EWS +in order to get a group name (albeit with / instead of .). This is a +regular expression. + +This variable is very similar to `nnir-glimpse-remove-prefix', except +that it is for EWS, not Glimpse." + :type '(regexp) + :group 'nnir) + +;; Swish++. Next three variables Copyright (C) 2000, 2001 Christoph +;; Conrad . +;; Swish++ home page: http://homepage.mac.com/pauljlucas/software/swish/ + +(defcustom nnir-swish++-configuration-file + (expand-file-name "~/Mail/swish++.conf") + "*Configuration file for swish++." + :type '(file) + :group 'nnir) + +(defcustom nnir-swish++-program "search" + "*Name of swish++ search executable." + :type '(string) + :group 'nnir) + +(defcustom nnir-swish++-additional-switches '() + "*A list of strings, to be given as additional arguments to swish++. + +Note that this should be a list. Ie, do NOT use the following: + (setq nnir-swish++-additional-switches \"-i -w\") ; wrong +Instead, use this: + (setq nnir-swish++-additional-switches '(\"-i\" \"-w\"))" + :type '(repeat (string)) + :group 'nnir) + +(defcustom nnir-swish++-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each file name returned by swish++ +in order to get a group name (albeit with / instead of .). This is a +regular expression. + +This variable is very similar to `nnir-glimpse-remove-prefix', except +that it is for swish++, not Glimpse." + :type '(regexp) + :group 'nnir) + +;; Swish-E. Next three variables Copyright (C) 2000 Christoph Conrad +;; . +;; URL: http://sunsite.berkeley.edu/SWISH-E/ +;; New version: http://www.boe.es/swish-e + +(defcustom nnir-swish-e-index-file + (expand-file-name "~/Mail/index.swish-e") + "*Index file for swish-e. +This could be a server parameter." + :type '(file) + :group 'nnir) + +(defcustom nnir-swish-e-program "swish-e" + "*Name of swish-e search executable. +This cannot be a server parameter." + :type '(string) + :group 'nnir) + +(defcustom nnir-swish-e-additional-switches '() + "*A list of strings, to be given as additional arguments to swish-e. + +Note that this should be a list. Ie, do NOT use the following: + (setq nnir-swish-e-additional-switches \"-i -w\") ; wrong +Instead, use this: + (setq nnir-swish-e-additional-switches '(\"-i\" \"-w\")) + +This could be a server parameter." + :type '(repeat (string)) + :group 'nnir) + +(defcustom nnir-swish-e-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each file name returned by swish-e +in order to get a group name (albeit with / instead of .). This is a +regular expression. + +This variable is very similar to `nnir-glimpse-remove-prefix', except +that it is for swish-e, not Glimpse. + +This could be a server parameter." + :type '(regexp) + :group 'nnir) + +;; HyREX engine, see + +(defcustom nnir-hyrex-program "nnir-search" + "*Name of the nnir-search executable." + :type '(string) + :group 'nnir) + +(defcustom nnir-hyrex-additional-switches '() + "*A list of strings, to be given as additional arguments for nnir-search. +Note that this should be a list. Ie, do NOT use the following: + (setq nnir-hyrex-additional-switches \"-ddl ddl.xml -c nnir\") ; wrong ! +Instead, use this: + (setq nnir-hyrex-additional-switches '(\"-ddl\" \"ddl.xml\" \"-c\" \"nnir\"))" + :type '(repeat (string)) + :group 'nnir) + +(defcustom nnir-hyrex-index-directory (getenv "HOME") + "*Index directory for HyREX." + :type '(directory) + :group 'nnir) + +(defcustom nnir-hyrex-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each file name returned by HyREX +in order to get a group name (albeit with / instead of .). + +For example, suppose that HyREX returns file names such as +\"/home/john/Mail/mail/misc/42\". For this example, use the following +setting: (setq nnir-hyrex-remove-prefix \"/home/john/Mail/\") +Note the trailing slash. Removing this prefix gives \"mail/misc/42\". +`nnir' knows to remove the \"/42\" and to replace \"/\" with \".\" to +arrive at the correct group name, \"mail.misc\"." + :type '(directory) + :group 'nnir) + +;; Namazu engine, see + +(defcustom nnir-namazu-program "namazu" + "*Name of Namazu search executable." + :type '(string) + :group 'nnir) + +(defcustom nnir-namazu-index-directory (expand-file-name "~/Mail/namazu/") + "*Index directory for Namazu." + :type '(directory) + :group 'nnir) + +(defcustom nnir-namazu-additional-switches '() + "*A list of strings, to be given as additional arguments to namazu. +The switches `-q', `-a', and `-s' are always used, very few other switches +make any sense in this context. + +Note that this should be a list. Ie, do NOT use the following: + (setq nnir-namazu-additional-switches \"-i -w\") ; wrong +Instead, use this: + (setq nnir-namazu-additional-switches '(\"-i\" \"-w\"))" + :type '(repeat (string)) + :group 'nnir) + +(defcustom nnir-namazu-remove-prefix (concat (getenv "HOME") "/Mail/") + "*The prefix to remove from each file name returned by Namazu +in order to get a group name (albeit with / instead of .). + +This variable is very similar to `nnir-glimpse-remove-prefix', except +that it is for Namazu, not Glimpse." + :type '(directory) + :group 'nnir) + +;;; Internal Variables: + +(defvar nnir-current-query nil + "Internal: stores current query (= group name).") + +(defvar nnir-current-server nil + "Internal: stores current server (does it ever change?).") + +(defvar nnir-current-group-marked nil + "Internal: stores current list of process-marked groups.") + +(defvar nnir-artlist nil + "Internal: stores search result.") + +(defvar nnir-tmp-buffer " *nnir*" + "Internal: temporary buffer.") + +;;; Code: + +;; Gnus glue. + +(defun gnus-group-make-nnir-group (extra-parms query) + "Create an nnir group. Asks for query." + (interactive "P\nsQuery: ") + (setq nnir-current-query nil + nnir-current-server nil + nnir-current-group-marked nil + nnir-artlist nil) + (let ((parms nil)) + (if extra-parms + (setq parms (nnir-read-parms query)) + (setq parms (list (cons 'query query)))) + (gnus-group-read-ephemeral-group + (concat "nnir:" (prin1-to-string parms)) '(nnir "") t + (cons (current-buffer) + gnus-current-window-configuration) + nil))) + +;; Emacs 19 compatibility? +(or (fboundp 'kbd) (defalias 'kbd 'read-kbd-macro)) + +(defun nnir-group-mode-hook () + (define-key gnus-group-mode-map + (if (fboundp 'read-kbd-macro) + (kbd "G G") + "GG") ; XEmacs 19 compat + 'gnus-group-make-nnir-group)) +(add-hook 'gnus-group-mode-hook 'nnir-group-mode-hook) + + + +;; Summary mode commands. + +(defun gnus-summary-nnir-goto-thread () + "Only applies to nnir groups. Go to group this article came from +and show thread that contains this article." + (interactive) + (unless (eq 'nnir (car (gnus-find-method-for-group gnus-newsgroup-name))) + (error "Can't execute this command unless in nnir group.")) + (let* ((cur (gnus-summary-article-number)) + (group (nnir-artlist-artitem-group nnir-artlist cur)) + (backend-number (nnir-artlist-artitem-number nnir-artlist cur)) + server backend-group) + (setq server (nnir-group-server group)) + (setq backend-group (gnus-group-real-name group)) + (gnus-group-read-ephemeral-group + backend-group + (gnus-server-to-method server) + t ; activate + (cons (current-buffer) + 'summary) ; window config + nil + (list backend-number)) + (gnus-summary-limit (list backend-number)) + (gnus-summary-refer-thread))) + +(if (fboundp 'eval-after-load) + (eval-after-load "gnus-sum" + '(define-key gnus-summary-goto-map + "T" 'gnus-summary-nnir-goto-thread)) + (add-hook 'gnus-summary-mode-hook + (function (lambda () + (define-key gnus-summary-goto-map + "T" 'gnus-summary-nnir-goto-thread))))) + + + +;; Gnus backend interface functions. + +(deffoo nnir-open-server (server &optional definitions) + ;; Just set the server variables appropriately. + (nnoo-change-server 'nnir server definitions)) + +(deffoo nnir-request-group (group &optional server fast) + "GROUP is the query string." + (nnir-possibly-change-server server) + ;; Check for cache and return that if appropriate. + (if (and (equal group nnir-current-query) + (equal gnus-group-marked nnir-current-group-marked) + (or (null server) + (equal server nnir-current-server))) + nnir-artlist + ;; Cache miss. + (setq nnir-artlist (nnir-run-query group))) + (save-excursion + (set-buffer nntp-server-buffer) + (if (zerop (length nnir-artlist)) + (progn + (setq nnir-current-query nil + nnir-current-server nil + nnir-current-group-marked nil + nnir-artlist nil) + (nnheader-report 'nnir "Search produced empty results.")) + ;; Remember data for cache. + (setq nnir-current-query group) + (when server (setq nnir-current-server server)) + (setq nnir-current-group-marked gnus-group-marked) + (nnheader-insert "211 %d %d %d %s\n" + (nnir-artlist-length nnir-artlist) ; total # + 1 ; first # + (nnir-artlist-length nnir-artlist) ; last # + group)))) ; group name + +(deffoo nnir-retrieve-headers (articles &optional group server fetch-old) + (save-excursion + (let ((artlist (copy-sequence articles)) + (idx 1) + (art nil) + (artitem nil) + (artgroup nil) (artno nil) + (artrsv nil) + (artfullgroup nil) + (novitem nil) + (novdata nil) + (foo nil) + server) + (while (not (null artlist)) + (setq art (car artlist)) + (or (numberp art) + (nnheader-report + 'nnir + "nnir-retrieve-headers doesn't grok message ids: %s" + art)) + (setq artitem (nnir-artlist-article nnir-artlist art)) + (setq artrsv (nnir-artitem-rsv artitem)) + (setq artfullgroup (nnir-artitem-group artitem)) + (setq artno (nnir-artitem-number artitem)) + (setq artgroup (gnus-group-real-name artfullgroup)) + (setq server (nnir-group-server artfullgroup)) + ;; retrieve NOV or HEAD data for this article, transform into + ;; NOV data and prepend to `novdata' + (set-buffer nntp-server-buffer) + (nnir-possibly-change-server server) + (case (setq foo (gnus-retrieve-headers (list artno) artfullgroup nil)) + (nov + (goto-char (point-min)) + (setq novitem (nnheader-parse-nov)) + (unless novitem + (pop-to-buffer nntp-server-buffer) + (error + "nnheader-parse-nov returned nil for article %s in group %s" + artno artfullgroup))) + (headers + (goto-char (point-min)) + (setq novitem (nnheader-parse-head)) + (unless novitem + (pop-to-buffer nntp-server-buffer) + (error + "nnheader-parse-head returned nil for article %s in group %s" + artno artfullgroup))) + (t (nnheader-report 'nnir "Don't support header type %s." foo))) + ;; replace article number in original group with article number + ;; in nnir group + (mail-header-set-number novitem idx) + (mail-header-set-from novitem + (mail-header-from novitem)) + (mail-header-set-subject + novitem + (format "[%d: %s/%d] %s" + artrsv artgroup artno + (mail-header-subject novitem))) + ;;-(mail-header-set-extra novitem nil) + (push novitem novdata) + (setq artlist (cdr artlist)) + (setq idx (1+ idx))) + (setq novdata (nreverse novdata)) + (set-buffer nntp-server-buffer) (erase-buffer) + (mapcar 'nnheader-insert-nov novdata) + 'nov))) + +(deffoo nnir-request-article (article + &optional group server to-buffer) + (save-excursion + (let* ((artitem (nnir-artlist-article nnir-artlist + article)) + (artfullgroup (nnir-artitem-group artitem)) + (artno (nnir-artitem-number artitem)) + ;; Bug? + ;; Why must we bind nntp-server-buffer here? It won't + ;; work if `buf' is used, say. (Of course, the set-buffer + ;; line below must then be updated, too.) + (nntp-server-buffer (or to-buffer nntp-server-buffer))) + (set-buffer nntp-server-buffer) + (erase-buffer) + (message "Requesting article %d from group %s" + artno artfullgroup) + (gnus-request-article artno artfullgroup nntp-server-buffer) + (cons artfullgroup artno)))) + + +(nnoo-define-skeleton nnir) + +;;; Search Engine Interfaces: + +;; Glimpse interface. +(defun nnir-run-glimpse (query server &optional group) + "Run given query against glimpse. Returns a vector of (group name, file name) +pairs (also vectors, actually)." + (save-excursion + (let ((artlist nil) + (groupspec (cdr (assq 'group query))) + (qstring (cdr (assq 'query query))) + (prefix (nnir-read-server-parm 'nnir-glimps-remove-prefix server)) + artno dirnam) + (when (and group groupspec) + (error (concat "It does not make sense to use a group spec" + " with process-marked groups."))) + (when group + (setq groupspec (gnus-group-real-name group))) + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + (if groupspec + (message "Doing glimpse query %s on %s..." query groupspec) + (message "Doing glimpse query %s..." query)) + (let* ((cp-list + `( ,nnir-glimpse-program + nil ; input from /dev/null + t ; output + nil ; don't redisplay + "-H" ,(nnir-read-server-parm 'nnir-glimpse-home server) ; search home dir + "-W" ; match pattern in file + "-l" "-y" ; misc options + ,@(nnir-read-server-parm 'nnir-glimpse-additional-switches server) + "-F" ,prefix ; restrict output to mail + ,qstring ; the query, in glimpse format + )) + (exitstatus + (progn + (message "%s args: %s" nnir-glimpse-program + (mapconcat 'identity (cddddr cp-list) " ")) + (apply 'call-process cp-list)))) + (unless (or (null exitstatus) + (zerop exitstatus)) + (nnheader-report 'nnir "Couldn't run glimpse: %s" exitstatus) + ;; Glimpse failure reason is in this buffer, show it if + ;; the user wants it. + (when (> gnus-verbose 6) + (display-buffer nnir-tmp-buffer)))) + (when groupspec + (keep-lines groupspec)) + (if groupspec + (message "Doing glimpse query %s on %s...done" query groupspec) + (message "Doing glimpse query %s...done" query)) + (sit-for 0) + ;; remove superfluous stuff from glimpse output + (goto-char (point-min)) + (delete-non-matching-lines "/[0-9]+$") + ;;(delete-matching-lines "\\.overview~?$") + (goto-char (point-min)) + (while (re-search-forward (concat "^" prefix "\\(.+\\)" "/\\([0-9]\\)+$") nil t) + ;; replace / with . in group names + (setq dirnam (substitute ?. ?/ (match-string 1)) + artno (match-string 2)) + (push (vector (nnir-group-full-name dirnam server) + (string-to-int artno)) artlist)) + + (sort* artlist + (function (lambda (x y) + (if (string-lessp (nnir-artitem-group x) + (nnir-artitem-group y)) + t + (< (nnir-artitem-number x) + (nnir-artitem-number y)))))) + ))) + +;; freeWAIS-sf interface. +(defun nnir-run-waissearch (query server &optional group) + "Run given query agains waissearch. Returns vector of (group name, file name) +pairs (also vectors, actually)." + (when group + (error "The freeWAIS-sf backend cannot search specific groups.")) + (save-excursion + (let ((qstring (cdr (assq 'query query))) + (prefix (nnir-read-server-parm 'nnir-wais-remove-prefix server)) + (artlist nil) + (score nil) (artno nil) (dirnam nil) (group nil)) + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + (message "Doing WAIS query %s..." query) + (call-process nnir-wais-program + nil ; input from /dev/null + t ; output to current buffer + nil ; don't redisplay + "-d" (nnir-read-server-parm 'nnir-wais-database server) ; database to search + qstring) + (message "Massaging waissearch output...") + ;; remove superfluous lines + (keep-lines "Score:") + ;; extract data from result lines + (goto-char (point-min)) + (while (re-search-forward + "Score: +\\([0-9]+\\).*'\\([0-9]+\\) +\\([^']+\\)/'" nil t) + (setq score (match-string 1) + artno (match-string 2) + dirnam (match-string 3)) + (unless (string-match prefix dirnam) + (nnheader-report 'nnir "Dir name %s doesn't contain prefix %s" + dirnam prefix)) + (setq group (substitute ?. ?/ (replace-match "" t t dirnam))) + (push (vector (nnir-group-full-name group server) + (string-to-int artno) + (string-to-int score)) + artlist)) + (message "Massaging waissearch output...done") + (apply 'vector + (sort* artlist + (function (lambda (x y) + (> (nnir-artitem-rsv x) + (nnir-artitem-rsv y))))))))) + +;; EWS (Excite for Web Servers) interface +(defun nnir-run-excite-search (query server &optional group) + "Run a given query against EWS. Returns vector of (group name, file name) +pairs (also vectors, actually)." + (when group + (error "Searching specific groups not implemented for EWS.")) + (save-excursion + (let ((qstring (cdr (assq 'query query))) + (prefix (nnir-read-server-parm 'nnir-excite-remove-prefix server)) + artlist group article-num article) + (setq nnir-current-query query) + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + (message "Doing EWS query %s..." qstring) + (call-process nnir-excite-aquery-program + nil ; input from /dev/null + t ; output to current buffer + nil ; don't redisplay + (nnir-read-server-parm 'nnir-excite-collection server) + (if (string= (substring qstring 0 1) "(") + qstring + (format "(concept %s)" qstring))) + (message "Gathering query output...") + + (goto-char (point-min)) + (while (re-search-forward + "^[0-9]+\\s-[0-9]+\\s-[0-9]+\\s-\\(\\S-*\\)" nil t) + (setq article (match-string 1)) + (unless (string-match + (concat "^" (regexp-quote prefix) + "\\(.*\\)/\\([0-9]+\\)") article) + (nnheader-report 'nnir "Dir name %s doesn't contain prefix %s" + article prefix)) + (setq group (substitute ?. ?/ (match-string 1 article))) + (setq group (nnir-group-full-name group server)) + (setq article-num (match-string 2 article)) + (setq artlist (vconcat artlist (vector (vector group + (string-to-int article-num) + 1000))))) + (message "Gathering query output...done") + artlist))) + +;; IMAP interface. The following function is Copyright (C) 1998 Simon +;; Josefsson . +;; todo: +;; nnir invokes this two (2) times???! +;; we should not use nnimap at all but open our own server connection +;; we should not LIST * but use nnimap-list-pattern from defs +;; send queries as literals +;; handle errors + +(defun nnir-run-imap (query srv &optional group-option) + (require 'imap) + (require 'nnimap) + (save-excursion + (let ((qstring (cdr (assq 'query query))) + (server (cadr (gnus-server-to-method srv))) + (group (or group-option (gnus-group-group-name))) + (defs (caddr (gnus-server-to-method srv))) + (criteria (or (cdr (assq 'criteria query)) + nnir-imap-search-field)) + artlist buf) + (message "Opening server %s" server) + (condition-case () + (when (nnimap-open-server server defs) ;; xxx + (setq buf nnimap-server-buffer) ;; xxx + (message "Searching %s..." group) + (let ((arts 0) + (mbx (gnus-group-real-name group))) + (when (imap-mailbox-select mbx nil buf) + (mapcar + (lambda (artnum) + (push (vector group artnum 1) artlist) + (setq arts (1+ arts))) + (imap-search (concat criteria " \"" qstring "\"") buf)) + (message "Searching %s... %d matches" mbx arts))) + (message "Searching %s...done" group)) + (quit nil)) + (reverse artlist)))) + +;; Swish++ interface. The following function is Copyright (C) 2000, +;; 2001 Christoph Conrad . +;; -cc- Todo +;; Search by +;; - group +;; Sort by +;; - rank (default) +;; - article number +;; - file size +;; - group +(defun nnir-run-swish++ (query server &optional group) + "Run given query against swish++. +Returns a vector of (group name, file name) pairs (also vectors, +actually). + +Tested with swish++ 4.7 on GNU/Linux and with with swish++ 5.0b2 on +Windows NT 4.0." + + (when group + (error "The swish++ backend cannot search specific groups.")) + + (save-excursion + (let ( (qstring (cdr (assq 'query query))) + (groupspec (cdr (assq 'group query))) + (prefix (nnir-read-server-parm 'nnir-swish++-remove-prefix server)) + (artlist nil) + (score nil) (artno nil) (dirnam nil) (group nil) ) + + (when (equal "" qstring) + (error "swish++: You didn't enter anything.")) + + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + + (if groupspec + (message "Doing swish++ query %s on %s..." qstring groupspec) + (message "Doing swish++ query %s..." qstring)) + + (let* ((cp-list `( ,nnir-swish++-program + nil ; input from /dev/null + t ; output + nil ; don't redisplay + "--config-file" ,(nnir-read-server-parm 'nnir-swish++-configuration-file server) + ,@(nnir-read-server-parm 'nnir-swish++-additional-switches server) + ,qstring ; the query, in swish++ format + )) + (exitstatus + (progn + (message "%s args: %s" nnir-swish++-program + (mapconcat 'identity (cddddr cp-list) " ")) ;; ??? + (apply 'call-process cp-list)))) + (unless (or (null exitstatus) + (zerop exitstatus)) + (nnheader-report 'nnir "Couldn't run swish++: %s" exitstatus) + ;; swish++ failure reason is in this buffer, show it if + ;; the user wants it. + (when (> gnus-verbose 6) + (display-buffer nnir-tmp-buffer)))) + + ;; The results are output in the format of: + ;; V 4.7 Linux + ;; rank relative-path-name file-size file-title + ;; V 5.0b2: + ;; rank relative-path-name file-size topic?? + ;; where rank is an integer from 1 to 100. + (goto-char (point-min)) + (while (re-search-forward + "\\(^[0-9]+\\) \\([^ ]+\\) [0-9]+ \\(.*\\)$" nil t) + (setq score (match-string 1) + artno (file-name-nondirectory (match-string 2)) + dirnam (file-name-directory (match-string 2))) + + ;; don't match directories + (when (string-match "^[0-9]+$" artno) + (when (not (null dirnam)) + + ;; maybe limit results to matching groups. + (when (or (not groupspec) + (string-match groupspec dirnam)) + + ;; remove nnir-swish++-remove-prefix from beginning of dirname + (when (string-match (concat "^" prefix) + dirnam) + (setq dirnam (replace-match "" t t dirnam))) + + (setq dirnam (substring dirnam 0 -1)) + ;; eliminate all ".", "/", "\" from beginning. Always matches. + (string-match "^[./\\]*\\(.*\\)$" dirnam) + ;; "/" -> "." + (setq group (substitute ?. ?/ (match-string 1 dirnam))) + ;; "\\" -> "." + (setq group (substitute ?. ?\\ group)) + + (push (vector (nnir-group-full-name group server) + (string-to-int artno) + (string-to-int score)) + artlist))))) + + (message "Massaging swish++ output...done") + + ;; Sort by score + (apply 'vector + (sort* artlist + (function (lambda (x y) + (> (nnir-artitem-rsv x) + (nnir-artitem-rsv y))))))))) + +;; Swish-E interface. The following function is Copyright (C) 2000, +;; 2001 by Christoph Conrad . +(defun nnir-run-swish-e (query server &optional group) + "Run given query against swish-e. +Returns a vector of (group name, file name) pairs (also vectors, +actually). + +Tested with swish-e-2.0.1 on Windows NT 4.0." + + ;; swish-e crashes with empty parameter to "-w" on commandline... + (when group + (error "The swish-e backend cannot search specific groups.")) + + (save-excursion + (let ((qstring (cdr (assq 'query query))) + (prefix + (or (nnir-read-server-parm 'nnir-swish-e-remove-prefix server) + (error "Missing parameter `nnir-swish-e-remove-prefix'"))) + (artlist nil) + (score nil) (artno nil) (dirnam nil) (group nil) ) + + (when (equal "" qstring) + (error "swish-e: You didn't enter anything.")) + + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + + (message "Doing swish-e query %s..." query) + (let* ((index-file + (or (nnir-read-server-parm + 'nnir-swish-e-index-file server) + (error "Missing parameter `nnir-swish-e-index-file'"))) + (additional-switches + (nnir-read-server-parm + 'nnir-swish++-additional-switches server)) + (cp-list `(,nnir-swish-e-program + nil ; input from /dev/null + t ; output + nil ; don't redisplay + "-f" ,index-file + ,@additional-switches + "-w" + ,qstring ; the query, in swish-e format + )) + (exitstatus + (progn + (message "%s args: %s" nnir-swish-e-program + (mapconcat 'identity (cddddr cp-list) " ")) + (apply 'call-process cp-list)))) + (unless (or (null exitstatus) + (zerop exitstatus)) + (nnheader-report 'nnir "Couldn't run swish-e: %s" exitstatus) + ;; swish-e failure reason is in this buffer, show it if + ;; the user wants it. + (when (> gnus-verbose 6) + (display-buffer nnir-tmp-buffer)))) + + ;; The results are output in the format of: + ;; rank path-name file-title file-size + (goto-char (point-min)) + (while (re-search-forward + "\\(^[0-9]+\\) \\([^ ]+\\) \"\\([^\"]+\\)\" [0-9]+$" nil t) + (setq score (match-string 1) + artno (match-string 3) + dirnam (file-name-directory (match-string 2))) + + ;; don't match directories + (when (string-match "^[0-9]+$" artno) + (when (not (null dirnam)) + + ;; remove nnir-swish-e-remove-prefix from beginning of dirname + (when (string-match (concat "^" prefix) dirnam) + (setq dirnam (replace-match "" t t dirnam))) + + (setq dirnam (substring dirnam 0 -1)) + ;; eliminate all ".", "/", "\" from beginning. Always matches. + (string-match "^[./\\]*\\(.*\\)$" dirnam) + ;; "/" -> "." + (setq group (substitute ?. ?/ (match-string 1 dirnam))) + ;; Windows "\\" -> "." + (setq group (substitute ?. ?\\ group)) + + (push (vector (nnir-group-full-name group server) + (string-to-int artno) + (string-to-int score)) + artlist)))) + + (message "Massaging swish-e output...done") + + ;; Sort by score + (apply 'vector + (sort* artlist + (function (lambda (x y) + (> (nnir-artitem-rsv x) + (nnir-artitem-rsv y))))))))) + +;; HyREX interface +(defun nnir-run-hyrex (query server &optional group) + (save-excursion + (let ((artlist nil) + (groupspec (cdr (assq 'group query))) + (qstring (cdr (assq 'query query))) + (prefix (nnir-read-server-parm 'nnir-hyrex-remove-prefix server)) + score artno dirnam) + (when (and group groupspec) + (error (concat "It does not make sense to use a group spec" + " with process-marked groups."))) + (when group + (setq groupspec (gnus-group-real-name group))) + (when (and group (not (equal group (nnir-group-full-name groupspec server)))) + (message "%s vs. %s" group (nnir-group-full-name groupspec server)) + (error "Server with groupspec doesn't match group !")) + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + (if groupspec + (message "Doing hyrex-search query %s on %s..." query groupspec) + (message "Doing hyrex-search query %s..." query)) + (let* ((cp-list + `( ,nnir-hyrex-program + nil ; input from /dev/null + t ; output + nil ; don't redisplay + "-i",(nnir-read-server-parm 'nnir-hyrex-index-directory server) ; index directory + ,@(nnir-read-server-parm 'nnir-hyrex-additional-switches server) + ,qstring ; the query, in hyrex-search format + )) + (exitstatus + (progn + (message "%s args: %s" nnir-hyrex-program + (mapconcat 'identity (cddddr cp-list) " ")) + (apply 'call-process cp-list)))) + (unless (or (null exitstatus) + (zerop exitstatus)) + (nnheader-report 'nnir "Couldn't run hyrex-search: %s" exitstatus) + ;; nnir-search failure reason is in this buffer, show it if + ;; the user wants it. + (when (> gnus-verbose 6) + (display-buffer nnir-tmp-buffer)))) ;; FIXME: Dont clear buffer ! + (if groupspec + (message "Doing hyrex-search query \"%s\" on %s...done" qstring groupspec) + (message "Doing hyrex-search query \"%s\"...done" qstring)) + (sit-for 0) + ;; nnir-search returns: + ;; for nnml/nnfolder: "filename mailid weigth" + ;; for nnimap: "group mailid weigth" + (goto-char (point-min)) + (delete-non-matching-lines "^\\S + [0-9]+ [0-9]+$") + ;; HyREX couldn't search directly in groups -- so filter out here. + (when groupspec + (keep-lines groupspec)) + ;; extract data from result lines + (goto-char (point-min)) + (while (re-search-forward + "\\(\\S +\\) \\([0-9]+\\) \\([0-9]+\\)" nil t) + (setq dirnam (match-string 1) + artno (match-string 2) + score (match-string 3)) + (when (string-match prefix dirnam) + (setq dirnam (replace-match "" t t dirnam))) + (push (vector (nnir-group-full-name (substitute ?. ?/ dirnam) server) + (string-to-int artno) + (string-to-int score)) + artlist)) + (message "Massaging hyrex-search output...done.") + (apply 'vector + (sort* artlist + (function (lambda (x y) + (if (string-lessp (nnir-artitem-group x) + (nnir-artitem-group y)) + t + (< (nnir-artitem-number x) + (nnir-artitem-number y))))))) + ))) + +;; Namazu interface +(defun nnir-run-namazu (query server &optional group) + "Run given query against Namazu. Returns a vector of (group name, file name) +pairs (also vectors, actually). + +Tested with Namazu 2.0.6 on a GNU/Linux system." + (when group + (error "The Namazu backend cannot search specific groups")) + (save-excursion + (let ( + (artlist nil) + (qstring (cdr (assq 'query query))) + (prefix (nnir-read-server-parm 'nnir-namazu-remove-prefix server)) + (score nil) + (group nil) + (article nil) + (process-environment (copy-sequence process-environment)) + ) + (setenv "LC_MESSAGES" "C") + (set-buffer (get-buffer-create nnir-tmp-buffer)) + (erase-buffer) + (let* ((cp-list + `( ,nnir-namazu-program + nil ; input from /dev/null + t ; output + nil ; don't redisplay + "-q" ; don't be verbose + "-a" ; show all matches + "-s" ; use short format + ,@(nnir-read-server-parm 'nnir-namazu-additional-switches server) + ,qstring ; the query, in namazu format + ,(nnir-read-server-parm 'nnir-namazu-index-directory server) ; index directory + )) + (exitstatus + (progn + (message "%s args: %s" nnir-namazu-program + (mapconcat 'identity (cddddr cp-list) " ")) + (apply 'call-process cp-list)))) + (unless (or (null exitstatus) + (zerop exitstatus)) + (nnheader-report 'nnir "Couldn't run namazu: %s" exitstatus) + ;; Namazu failure reason is in this buffer, show it if + ;; the user wants it. + (when (> gnus-verbose 6) + (display-buffer nnir-tmp-buffer)))) + + ;; Namazu output looks something like this: + ;; 2. Re: Gnus agent expire broken (score: 55) + ;; /home/henrik/Mail/mail/sent/1310 (4,138 bytes) + + (goto-char (point-min)) + (while (re-search-forward + "^\\([0-9]+\\.\\).*\\((score: \\([0-9]+\\)\\))\n\\([^ ]+\\)" + nil t) + (setq score (match-string 3) + group (file-name-directory (match-string 4)) + article (file-name-nondirectory (match-string 4))) + + ;; make sure article and group is sane + (when (and (string-match "^[0-9]+$" article) + (not (null group))) + (when (string-match (concat "^" prefix) group) + (setq group (replace-match "" t t group))) + + ;; remove trailing slash from groupname + (setq group (substring group 0 -1)) + + ;; stuff results into artlist vector + (push (vector (nnir-group-full-name (substitute ?. ?/ group) server) + (string-to-int article) + (string-to-int score)) artlist))) + + ;; sort artlist by score + (apply 'vector + (sort* artlist + (function (lambda (x y) + (> (nnir-artitem-rsv x) + (nnir-artitem-rsv y))))))))) + +;;; Util Code: + +(defun nnir-read-parms (query) + "Reads additional search parameters according to `nnir-engines'." + (let ((parmspec (caddr (assoc nnir-search-engine nnir-engines)))) + (cons (cons 'query query) + (mapcar 'nnir-read-parm parmspec)))) + +(defun nnir-read-parm (parmspec) + "Reads a single search parameter. +`parmspec' is a cons cell, the car is a symbol, the cdr is a prompt." + (let ((sym (car parmspec)) + (prompt (cdr parmspec))) + (if (listp prompt) + (let* ((result (apply 'completing-read prompt)) + (mapping (or (assoc result nnir-imap-search-arguments) + (assoc nil nnir-imap-search-arguments)))) + (cons sym (format (cdr mapping) result))) + (cons sym (read-string prompt))))) + +(defun nnir-run-query (query) + "Invoke appropriate search engine function (see `nnir-engines'). +If some groups were process-marked, run the query for each of the groups +and concat the results." + (let ((q (car (read-from-string query)))) + (if gnus-group-marked + (apply 'vconcat + (mapcar (lambda (x) + (let ((server (nnir-group-server x)) + search-func) + (setq search-func (cadr + (assoc + (nnir-read-server-parm 'nnir-search-engine server) nnir-engines))) + (if search-func + (funcall search-func q server x) + nil))) + gnus-group-marked) + ) + (apply 'vconcat + (mapcar (lambda (x) + (if (and (equal (cadr x) 'ok) (not (equal (cadar x) "-ephemeral"))) + (let ((server (format "%s:%s" (caar x) (cadar x))) + search-func) + (setq search-func (cadr + (assoc + (nnir-read-server-parm 'nnir-search-engine server) nnir-engines))) + (if search-func + (funcall search-func q server nil) + nil)) + nil)) + gnus-opened-servers) + )) + )) + +(defun nnir-read-server-parm (key server) + "Returns the parameter value of for the given server, where server is of +form 'backend:name'." + (let ((method (gnus-server-to-method server))) + (cond ((and method (assq key (cddr method))) + (nth 1 (assq key (cddr method)))) + ((and nnir-mail-backend + (gnus-method-equal method nnir-mail-backend)) + (symbol-value key)) + ((null nnir-mail-backend) + (symbol-value key)) + (t nil)))) +;; (if method +;; (if (assq key (cddr method)) +;; (nth 1 (assq key (cddr method))) +;; (symbol-value key)) +;; (symbol-value key)) +;; )) + +(defmacro nnir-group-server (group) + "Returns the server for a foreign newsgroup in the format as gnus-server-to-method needs it. Compare to gnus-group-real-prefix and gnus-group-real-name." + `(let ((gname ,group)) + (if (string-match "^\\([^:]+\\):" gname) + (setq gname (match-string 1 gname)) + nil) + (if (string-match "^\\([^+]+\\)\\+\\(.+\\)$" gname) + (format "%s:%s" (match-string 1 gname) (match-string 2 gname)) + (concat gname ":")) + )) + +(defun nnir-group-full-name (shortname server) + "For the given group name, return a full Gnus group name. +The Gnus backend/server information is added." + (gnus-group-prefixed-name shortname (gnus-server-to-method server))) + +(defun nnir-possibly-change-server (server) + (unless (and server (nnir-server-opened server)) + (nnir-open-server server))) + + +;; Data type article list. + +(defun nnir-artlist-length (artlist) + "Returns number of articles in artlist." + (length artlist)) + +(defun nnir-artlist-article (artlist n) + "Returns from ARTLIST the Nth artitem (counting starting at 1)." + (elt artlist (1- n))) + +(defun nnir-artitem-group (artitem) + "Returns the group from the ARTITEM." + (elt artitem 0)) + +(defun nnir-artlist-artitem-group (artlist n) + "Returns from ARTLIST the group of the Nth artitem (counting from 1)." + (nnir-artitem-group (nnir-artlist-article artlist n))) + +(defun nnir-artitem-number (artitem) + "Returns the number from the ARTITEM." + (elt artitem 1)) + +(defun nnir-artlist-artitem-number (artlist n) + "Returns from ARTLIST the number of the Nth artitem (counting from 1)." + (nnir-artitem-number (nnir-artlist-article artlist n))) + +(defun nnir-artitem-rsv (artitem) + "Returns the Retrieval Status Value (RSV, score) from the ARTITEM." + (elt artitem 2)) + +(defun nnir-artlist-artitem-rsv (artlist n) + "Returns from ARTLIST the Retrieval Status Value of the Nth artitem +(counting from 1)." + (nnir-artitem-rsv (nnir-artlist-article artlist n))) + +;; unused? +(defun nnir-artlist-groups (artlist) + "Returns a list of all groups in the given ARTLIST." + (let ((res nil) + (with-dups nil)) + ;; from each artitem, extract group component + (setq with-dups (mapcar 'nnir-artitem-group artlist)) + ;; remove duplicates from above + (mapcar (function (lambda (x) (add-to-list 'res x))) + with-dups) + res)) + + +;; The end. +(provide 'nnir) diff --git a/contrib/starttls.el b/contrib/starttls.el new file mode 100644 index 0000000..95db27f --- /dev/null +++ b/contrib/starttls.el @@ -0,0 +1,227 @@ +;;; starttls.el --- STARTTLS support via wrapper around GNU TLS + +;; Copyright (C) 2003 Free Software Foundation, Inc. + +;; Author: Simon Josefsson +;; Keywords: comm, tls, gnutls, ssl + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This package implements a simple wrapper around the GNU TLS command +;; line application "gnutls-cli" to make Emacs support STARTTLS. It +;; is backwards compatible (same API functions) with the "starttls.el" +;; that is part of Emacs 21 written by Daiki Ueno . +;; (That version used an external program "starttls" that isn't widely +;; installed, and was based on OpenSSL.) + +;; This package require GNUTLS 0.9.90 (released 2003-10-08) or later. + +;; Usage is similar to `open-network-stream'. Evaluating the following: +;; +;; (progn +;; (setq tmp (open-starttls-stream "test" (current-buffer) "mail.example.com" 143)) +;; (process-send-string tmp ". starttls\n") +;; (sit-for 4) +;; (message "STARTTLS output:\n%s" (negotiate-starttls tmp)) +;; (process-send-string tmp ". capability\n")) +;; +;; in, e.g., the *scratch* buffer, yields the following output: +;; +;; * OK imap.example.com Cyrus IMAP4 v2.1.15 server ready +;; . OK Begin TLS negotiation now +;; * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA ... +;; . OK Completed +;; nil +;; +;; And the message buffer contains: +;; +;; STARTTLS output: +;; *** Starting TLS handshake +;; - Server's trusted authorities: +;; [0]: O=Sendmail,OU=Sendmail Server,CN=imap.example.com,EMAIL=admin@imap.example.com +;; - Certificate type: X.509 +;; - Got a certificate list of 1 certificates. +;; +;; - Certificate[0] info: +;; # The hostname in the certificate matches 'imap.example.com'. +;; # valid since: Wed Aug 28 12:47:00 CEST 2002 +;; # expires at: Thu Aug 28 12:47:00 CEST 2003 +;; # serial number: 00 +;; # fingerprint: 06 3f 25 cb 44 aa 5c 1e 79 d7 63 86 f8 b1 9a cf +;; # version: #3 +;; # public key algorithm: RSA +;; # Modulus: 1024 bits +;; # Subject's DN: O=Sendmail,OU=Sendmail Server,CN=imap.example.com,EMAIL=admin@imap.example.com +;; # Issuer's DN: O=Sendmail,OU=Sendmail Server,CN=imap.example.com,EMAIL=admin@imap.example.com +;; +;; +;; - Peer's certificate issuer is unknown +;; - Peer's certificate is NOT trusted +;; - Version: TLS 1.0 +;; - Key Exchange: RSA +;; - Cipher: ARCFOUR 128 +;; - MAC: SHA +;; - Compression: NULL + +;; Revision history: +;; +;; 2003-09-20: Added to Gnus CVS. +;; 2003-10-02: Minor fixes. +;; 2003-11-15: Cleanup, and posted to gnu.emacs.sources. +;; 2003-11-28: Fixes variable name conflicts, various other fixes, posted g.e.s. + +;;; Code: + +(defgroup starttls nil + "Negotiated Transport Layer Security (STARTTLS) parameters." + :group 'comm) + +(defcustom starttls-file-name "gnutls-cli" + "Name of the program to run in a subprocess to open an STARTTLS connection. +The program should read input on stdin, write output to stdout, +and initiate TLS negotiation when receiving the SIGALRM signal. +Also see `starttls-connect', `starttls-failure', and +`starttls-success' for what the program should output after +initial connection and successful negotiation respectively." + :type 'string + :group 'starttls) + +(defcustom starttls-extra-arguments nil + "List of extra arguments to `starttls-file-name'. +E.g., (\"--protocols\" \"ssl3\")." + :type '(repeat string) + :group 'starttls) + +(defcustom starttls-process-connection-type nil + "*Value for `process-connection-type' to use when starting STARTTLS process." + :type 'boolean + :group 'starttls) + +(defcustom starttls-connect "- Simple Client Mode:\n\n" + "*Regular expression indicating successful connection. +The default is what GNUTLS's \"gnutls-cli\" outputs." + ;; GNUTLS cli.c:main() print this string when it is starting to run + ;; in the application read/write phase. If the logic, or the string + ;; itself, is modified, this must be updated. + :type 'regexp + :group 'starttls) + +(defcustom starttls-failure "*** Handshake has failed" + "*Regular expression indicating failed TLS handshake. +The default is what GNUTLS's \"gnutls-cli\" outputs." + ;; GNUTLS cli.c:do_handshake() print this string on failure. If the + ;; logic, or the string itself, is modified, this must be updated. + :type 'regexp + :group 'starttls) + +(defcustom starttls-success "- Compression: " + "*Regular expression indicating completed TLS handshakes. +The default is what GNUTLS's \"gnutls-cli\" outputs." + ;; GNUTLS cli.c:do_handshake() calls, on success, + ;; common.c:print_info(), that unconditionally print this string + ;; last. If that logic, or the string itself, is modified, this + ;; must be updated. + :type 'regexp + :group 'starttls) + +(defun negotiate-starttls (process) + "Negotiate TLS on process opened by `open-starttls-stream'. +This should typically only be done once. It typically return a +multi-line informational message with information about the +handshake, or NIL on failure." + (let (buffer info old-max done-ok done-bad) + (if (null (setq buffer (process-buffer process))) + ;; XXX How to remove/extract the TLS negotiation junk? + (signal-process (process-id process) 'SIGALRM) + (with-current-buffer buffer + (save-excursion + (setq old-max (goto-char (point-max))) + (signal-process (process-id process) 'SIGALRM) + (while (and (processp process) + (eq (process-status process) 'run) + (save-excursion + (goto-char old-max) + (not (or (setq done-ok (re-search-forward + starttls-success nil t)) + (setq done-bad (re-search-forward + starttls-failure nil t)))))) + (accept-process-output process 1 100) + (sit-for 0.1)) + (setq info (buffer-substring-no-properties old-max (point-max))) + (delete-region old-max (point-max)) + (if (or (and done-ok (not done-bad)) + ;; Prevent mitm that fake success msg after failure msg. + (and done-ok done-bad (< done-ok done-bad))) + info + (message "STARTTLS negotiation failed: %s" info) + nil)))))) + +(defun open-starttls-stream (name buffer host service) + "Open a TLS connection for a service to a host. +Returns a subprocess-object to represent the connection. +Input and output work as for subprocesses; `delete-process' closes it. +Args are NAME BUFFER HOST SERVICE. +NAME is name for process. It is modified if necessary to make it unique. +BUFFER is the buffer (or buffer-name) to associate with the process. + Process output goes at end of that buffer, unless you specify + an output stream or filter function to handle the output. +Third arg is name of the host to connect to, or its IP address. +Fourth arg SERVICE is name of the service desired, or an integer +specifying a port number to connect to." + (message "Opening STARTTLS connection to `%s'..." host) + (let* (done + (old-max (with-current-buffer buffer (point-max))) + (process-connection-type starttls-process-connection-type) + (process (apply #'start-process name buffer + starttls-file-name "-s" host + "-p" (if (integerp service) + (int-to-string service) + service) + starttls-extra-arguments))) + (process-kill-without-query process) + (while (and (processp process) + (eq (process-status process) 'run) + (save-excursion + (set-buffer buffer) + (goto-char old-max) + (not (setq done (re-search-forward + starttls-connect nil t))))) + (accept-process-output process 0 100) + (sit-for 0.1)) + (if done + (with-current-buffer buffer + (delete-region old-max done)) + (delete-process process) + (setq process nil)) + (message "Opening STARTTLS connection to `%s'...%s" + host (if done "done" "failed")) + process)) + +;; Compatibility with starttls.el by Daiki Ueno : +(defvaralias 'starttls-program 'starttls-file-name) +(make-obsolete-variable 'starttls-program 'starttls-file-name) +(defvaralias 'starttls-extra-args 'starttls-extra-arguments) +(make-obsolete-variable 'starttls-extra-args 'starttls-extra-arguments) +(defalias 'starttls-open-stream 'open-starttls-stream) +(defalias 'starttls-negotiate 'negotiate-starttls) + +(provide 'starttls) + +;;; starttls.el ends here diff --git a/etc/gnus-tut.txt b/etc/gnus-tut.txt index 9149610..62d0d01 100644 --- a/etc/gnus-tut.txt +++ b/etc/gnus-tut.txt @@ -296,1594 +296,23 @@ is where to post the questions. From fschmitt Sat Mar 22 18:13:00 2003 From: faq@my.gnus.org (Gnus FAQ team) Date: Sat Mar 22 18:13:00 2003 -Subject: Gnus FAQ -Message-ID: - -This is the text version of the Gnus FAQ, see http://my.gnus.org for -the up to date version of this document, there you can also find a -html version and various other formats. There's also a texinfo version -of the FAQ distributed with Gnus. - -Table of Contents - -Introduction -Frequently Asked Questions with Answers -Glossary - -Abstract - -This is the new Gnus Frequently Asked Questions list. If you have a -Web browser, the official hypertext version is at http:// -my.gnus.org/FAQ/ [http://my.gnus.org/FAQ/], the Docbook source is -available from http://sourceforge.net [http://sourceforge.net/ -projects/gnus/]. - -Please submit features and suggestions to the FAQ discussion list -[mailto:faq-discuss@my.gnus.org]. The list is protected against -junk mail with qconfirm [http://smarden.org/qconfirm/index.html]. -As a subscriber, your submissions will automatically pass. You can -also subscribe to the list by sending a blank email to -faq-discuss-subscribe@my.gnus.org -[mailto:faq-discuss-subscribe@my.gnus.org] and browse the archive. - -Introduction - -This is the Gnus Frequently Asked Questions list. - -Gnus is a Usenet Newsreader and Electronic Mail User Agent -implemented as a part of Emacs. It's been around in some form for -almost a decade now, and has been distributed as a standard part of -Emacs for much of that time. Gnus 5 is the latest (and greatest) -incarnation. The original version was called GNUS, and was written -by Masanobu UMEDA. When autumn crept up in '94, Lars Magne -Ingebrigtsen grew bored and decided to rewrite Gnus. - -Its biggest strength is the fact that it is extremely customizable. -It is somewhat intimidating at first glance, but most of the -complexity can be ignored until you're ready to take advantage of -it. If you receive a reasonable volume of e-mail (you're on various -mailing lists), or you would like to read high-volume mailing lists -but cannot keep up with them, or read high volume newsgroups or are -just bored, then Gnus is what you want. - -This FAQ was maintained by Justin Sheehy until March 2002. He would -like to thank Steve Baur and Per Abrahamsen for doing a wonderful -job with this FAQ before him. We would like to do the same - -thanks, Justin! - -If you have a Web browser, the official hypertext version is at: -http://my.gnus.org/FAQ/ [http://my.gnus.org/FAQ/]. This version is -much nicer than the unofficial hypertext versions that are archived -at Utrecht, Oxford, Smart Pages, Ohio State, and other FAQ -archives. See the resources question below if you want information -on obtaining it in another format. - -The information contained here was compiled with the assistance of -the Gnus development mailing list, and any errors or misprints are -the my.gnus.org team's fault, sorry. - -Frequently Asked Questions with Answers - -1. Installation FAQ - - 1.1. What is the latest version of Gnus? - 1.2. What's new in 5.10.0? - 1.3. Where and how to get Gnus? - 1.4. What to do with the tarball now? - 1.5. Which version of Emacs do I need? - 1.6. How do I run Gnus on both Emacs and XEmacs? - -2. Startup / Group buffer - - 2.1. Every time I start Gnus I get a message "Gnus auto-save - file exists. Do you want to read it?", what does this mean - and how to prevent it? - 2.2. Gnus doesn't remember which groups I'm subscribed to, - what's this? - 2.3. How to change the format of the lines in Group buffer? - 2.4. My group buffer becomes a bit crowded, is there a way to - sort my groups into categories so I can easier browse - through them? - 2.5. How to manually sort the groups in Group buffer? How to - sort the groups in a topic? - -3. Getting Messages - - 3.1. I just installed Gnus, started it via M-x gnus but it only - says "nntp (news) open error", what to do? - 3.2. I'm working under Windows and have no idea what ~/.gnus - means. - 3.3. My news server requires authentication, how to store user - name and password on disk? - 3.4. Gnus seems to start up OK, but I can't find out how to - subscribe to a group. - 3.5. Gnus doesn't show all groups / Gnus says I'm not allowed - to post on this server as well as I am, what's that? - 3.6. I want Gnus to fetch news from several servers, is this - possible? - 3.7. And how about local spool files? - 3.8. OK, reading news works now, but I want to be able to read - my mail with Gnus, too. How to do it? - 3.9. And what about IMAP? - 3.10. At the office we use one of those MS Exchange servers, - can I use Gnus to read my mail from it? - 3.11. Can I tell Gnus not to delete the mails on the server it - retrieves via POP3? - -4. Reading messages - - 4.1. When I enter a group, all read messages are gone. How to - view them again? - 4.2. How to tell Gnus to show an important message every time I - enter a group, even when it's read? - 4.3. How to view the headers of a message? - 4.4. How to view the raw unformatted message? - 4.5. How can I change the headers Gnus displays by default at - the top of the article buffer? - 4.6. I'd like Gnus NOT to render HTML-mails but show me the - text part if it's available. How to do it? - 4.7. Can I use some other browser than w3 to render my - HTML-mails? - 4.8. Is there anything I can do to make poorly formatted mails - more readable? - 4.9. Is there a way to automatically ignore posts by specific - authors or with specific words in the subject? And can I - highlight more interesting ones in some way? - 4.10. How can I disable threading in some (e.g. mail-) groups, - or set other variables specific for some groups? - 4.11. Can I highlight messages written by me and follow-ups to - those? - 4.12. The number of total messages in a group which Gnus - displays in group buffer is by far to high, especially in - mail groups. Is this a bug? - 4.13. I don't like the layout of summary and article buffer, - how to change it? Perhaps even a three pane display? - 4.14. I don't like the way the Summary buffer looks, how to - tweak it? - 4.15. How to split incoming mails in several groups? - -5. Composing messages - - 5.1. What are the basic commands I need to know for sending - mail and postings? - 5.2. How to enable automatic word-wrap when composing messages? - 5.3. How to set stuff like From, Organization, Reply-To, - signature...? - 5.4. Can I set things like From, Signature etc group based on - the group I post too? - 5.5. Is there a spell-checker? Perhaps even on-the-fly - spell-checking? - 5.6. Can I set the dictionary based on the group I'm posting - to? - 5.7. Is there some kind of address-book, so I needn't remember - all those email addresses? - 5.8. Sometimes I see little images at the top of article - buffer. What's that and how can I send one with my - postings, too? - 5.9. Sometimes I accidentally hit r instead of f in newsgroups. - Can Gnus warn me, when I'm replying by mail in newsgroups? - 5.10. How to tell Gnus not to generate a sender header? - 5.11. I want gnus to locally store copies of my send mail and - news, how to do it? - 5.12. People tell me my Message-IDs are not correct, why aren't - they and how to fix it? - -6. Old messages - - 6.1. How to import my old mail into Gnus? - 6.2. How to archive interesting messages? - 6.3. How to search for a specific message? - 6.4. How to get rid of old unwanted mail? - 6.5. I want that all read messages are expired (at least in - some groups). How to do it? - 6.6. I don't want expiration to delete my mails but to move - them to another group. - -7. Gnus in a dial-up environment - - 7.1. I don't have a permanent connection to the net, how can I - minimize the time I've got to be connected? - 7.2. So what was this thing about the Agent? - 7.3. I want to store article bodies on disk, too. How to do it? - 7.4. How to tell Gnus not to try to send mails / postings while - I'm offline? - -8. Getting help - - 8.1. How to find information and help inside Emacs? - 8.2. I can't find anything in the Gnus manual about X (e.g. - attachments, PGP, MIME...), is it not documented? - 8.3. Which websites should I know? - 8.4. Which mailing lists and newsgroups are there? - 8.5. Where to report bugs? - 8.6. I need real-time help, where to find it? - -9. Tuning Gnus - - 9.1. Starting Gnus is really slow, how to speed it up? - 9.2. How to speed up the process of entering a group? - 9.3. Sending mail becomes slower and slower, what's up? - -1. Installation FAQ - -1.1. What is the latest version of Gnus? - - Jingle please: Gnus 5.10.0 is released, get it while it's hot! As - well as the step in version number is rather small, Gnus 5.10 has - tons of new features which you shouldn't miss, however if you are - cautious, you might prefer to stay with 5.8.8 respectively 5.9 - (they are basically the same) until some bugfix releases are out. - -1.2. What's new in 5.10.0? - - First of all, you should have a look into the file GNUS-NEWS in the - toplevel directory of the Gnus tarball, there the most important - changes are listed. Here's a short list of the changes I find - especially important/interesting: - - * Major rewrite of the Gnus agent, Gnus agent is now active by - default. - - Many new article washing functions for dealing with ugly - formatted articles. - - Anti Spam features. - - message-utils now included in Gnus. - - New format specifiers for summary lines, e.g. %B for a complex - trn-style thread tree. - -1.3. Where and how to get Gnus? - - The latest released version of Gnus isn't included in Emacs 21 and - until now it also isn't available through the package system of - XEmacs 21.4, therefor you should get the Gnus tarball from http:// - www.gnus.org/dist/gnus.tar.gz [http://www.gnus.org/dist/ - gnus.tar.gz] or via anonymous FTP from ftp://ftp.gnus.org/pub/gnus/ - gnus.tar.gz [ftp://ftp.gnus.org/pub/gnus/gnus.tar.gz]. - -1.4. What to do with the tarball now? - - Untar it via tar xvzf gnus.tar.gz and do the common ./configure; - make; make install circle. (under MS-Windows either get the Cygwin - environment from http://www.cygwin.com [http://www.cygwin.com] - which allows you to do what's described above or unpack the tarball - with some packer (e.g. Winace from http://www.winace.com [http:// - www.winace.com]) and use the batch-file make.bat included in the - tarball to install Gnus. If you don't want to (or aren't allowed - to) install Gnus system-wide, you can install it in your home - directory and add the following lines to your ~/.xemacs/init.el or - ~/.emacs: - - (add-to-list 'load-path "/path/to/gnus/lisp") - (if (featurep 'xemacs) - (add-to-list 'Info-directory-list "/path/to/gnus/texi/") - (add-to-list 'Info-default-directory-list "/path/to/gnus/texi/")) - - - Make sure that you don't have any gnus related stuff before this - line, on MS Windows use something like "C:/path/to/lisp" (yes, "/ - "). - -1.5. Which version of Emacs do I need? - - Gnus 5.10.0 requires an Emacs version that is greater than or equal - to Emacs 20.7 or XEmacs 21.1. - -1.6. How do I run Gnus on both Emacs and XEmacs? - - You can't use the same copy of Gnus in both as the Lisp files are - byte-compiled to a format which is different depending on which - Emacs did the compilation. Get one copy of Gnus for Emacs and one - for XEmacs. - -2. Startup / Group buffer - -2.1. Every time I start Gnus I get a message "Gnus auto-save file - exists. Do you want to read it?", what does this mean and how to - prevent it? - - This message means that the last time you used Gnus, it wasn't - properly exited and therefor couldn't write its informations to - disk (e.g. which messages you read), you are now asked if you want - to restore those informations from the auto-save file. - - To prevent this message make sure you exit Gnus via q in group - buffer instead of just killing Emacs. - -2.2. Gnus doesn't remember which groups I'm subscribed to, what's this? - - You get the message described in the q/a pair above while starting - Gnus, right? It's an other symptom for the same problem, so read - the answer above. - -2.3. How to change the format of the lines in Group buffer? - - You've got to tweak the value of the variable - gnus-group-line-format. See the manual node "Group Line - Specification" for information on how to do this. An example for - this (guess from whose .gnus :-)): - - (setq gnus-group-line-format "%P%M%S[%5t]%5y : %(%g%)\n") - - -2.4. My group buffer becomes a bit crowded, is there a way to sort my - groups into categories so I can easier browse through them? - - Gnus offers the topic mode, it allows you to sort your groups in, - well, topics, e.g. all groups dealing with Linux under the topic - linux, all dealing with music under the topic music and all dealing - with scottish music under the topic scottish which is a subtopic of - music. - - To enter topic mode, just hit t while in Group buffer. Now you can - use T n to create a topic at point and T m to move a group to a - specific topic. For more commands see the manual or the menu. You - might want to include the %P specifier at the beginning of your - gnus-group-line-format variable to have the groups nicely indented. - -2.5. How to manually sort the groups in Group buffer? How to sort the - groups in a topic? - - Move point over the group you want to move and hit C-k, now move - point to the place where you want the group to be and hit C-y. - -3. Getting Messages - -3.1. I just installed Gnus, started it via M-x gnus but it only says - "nntp (news) open error", what to do? - - You've got to tell Gnus where to fetch the news from. Read the - documentation for information on how to do this. As a first start, - put those lines in ~/.gnus: - - (setq gnus-select-method '(nntp "news.yourprovider.net")) - (setq user-mail-address "you@yourprovider.net") - (setq user-full-name "Your Name") - - -3.2. I'm working under Windows and have no idea what ~/.gnus means. - - The ~/ means the home directory where Gnus and Emacs look for the - configuration files. However, you don't really need to know what - this means, it suffices that Emacs knows what it means :-) You can - type C-x C-f ~/.gnus RET (yes, with the forward slash, even on - Windows), and Emacs will open the right file for you. (It will most - likely be new, and thus empty.) However, I'd discourage you from - doing so, since the directory Emacs chooses will most certainly not - be what you want, so let's do it the correct way. The first thing - you've got to do is to create a suitable directory (no blanks in - directory name please) e.g. c:\myhome. Then you must set the - environment variable HOME to this directory. To do this under Win9x - or Me include the line - - SET HOME=C:\myhome - - - in your autoexec.bat and reboot. Under NT, 2000 and XP, hit - Winkey+Pause/Break to enter system options (if it doesn't work, go - to Control Panel -> System). There you'll find the possibility to - set environment variables, create a new one with name HOME and - value C:\myhome, a reboot is not necessary. - - Now to create ~/.gnus, say C-x C-f ~/.gnus RET C-x C-s. in Emacs. - -3.3. My news server requires authentication, how to store user name and - password on disk? - - Create a file ~/.authinfo which includes for each server a line - like this - - machine news.yourprovider.net login YourUserName password YourPassword - - . Make sure that the file isn't readable to others if you work on a - OS which is capable of doing so. (Under Unix say - - chmod 600 ~/.authinfo - - in a shell.) - -3.4. Gnus seems to start up OK, but I can't find out how to subscribe to - a group. - - If you know the name of the group say U name.of.group RET in group - buffer (use the tab-completion Luke). Otherwise hit ^ in group - buffer, this brings you to the server buffer. Now place point (the - cursor) over the server which carries the group you want, hit RET, - move point to the group you want to subscribe to and say u to - subscribe to it. - -3.5. Gnus doesn't show all groups / Gnus says I'm not allowed to post on - this server as well as I am, what's that? - - Some providers allow restricted anonymous access and full access - only after authorization. To make Gnus send authinfo to those - servers append - - force yes - - to the line for those servers in ~/.authinfo. - -3.6. I want Gnus to fetch news from several servers, is this possible? - - Of course. You can specify more sources for articles in the - variable gnus-secondary-select-methods. Add something like this in - ~/.gnus: - - (add-to-list 'gnus-secondary-select-methods '(nntp "news.yourSecondProvider.net")) - (add-to-list 'gnus-secondary-select-methods '(nntp "news.yourThirdProvider.net")) - - -3.7. And how about local spool files? - - No problem, this is just one more select method called nnspool, so - you want this: - - (add-to-list 'gnus-secondary-select-methods '(nnspool "")) - - - Or this if you don't want an NNTP Server as primary news source: - - (setq gnus-select-method '(nnspool "")) - - - Gnus will look for the spool file in /usr/spool/news, if you want - something different, change the line above to something like this: - - (add-to-list 'gnus-secondary-select-methods - '(nnspool "" (nnspool-directory "/usr/local/myspoolddir"))) - - - This sets the spool directory for this server only. You might have - to specify more stuff like the program used to post articles, see - the Gnus manual on how to do this. - -3.8. OK, reading news works now, but I want to be able to read my mail - with Gnus, too. How to do it? - - That's a bit harder since there are many possible sources for mail, - many possible ways for storing mail and many different ways for - sending mail. The most common cases are these: 1: You want to read - your mail from a pop3 server and send them directly to a SMTP - Server 2: Some program like fetchmail retrieves your mail and - stores it on disk from where Gnus shall read it. Outgoing mail is - sent by Sendmail, Postfix or some other MTA. Sometimes, you even - need a combination of the above cases. - - However, the first thing to do is to tell Gnus in which way it - should store the mail, in Gnus terminology which back end to use. - Gnus supports many different back ends, the most commonly used one - is nnml. It stores every mail in one file and is therefor quite - fast. However you might prefer a one file per group approach if - your file system has problems with many small files, the nnfolder - back end is then probably the choice for you. To use nnml add the - following to ~/.gnus: - - (add-to-list 'gnus-secondary-select-methods '(nnml "")) - - - As you might have guessed, if you want nnfolder, it's - - (add-to-list 'gnus-secondary-select-methods '(nnfolder "")) - - - Now we need to tell Gnus, where to get it's mail from. If it's a - POP3 server, then you need something like this: - - (eval-after-load "mail-source" - '(add-to-list 'mail-sources '(pop :server "pop.YourProvider.net" - :user "yourUserName" - :password "yourPassword")) - - - Make sure ~/.gnus isn't readable to others if you store your - password there. If you want to read your mail from a traditional - spool file on your local machine, it's - - (eval-after-load "mail-source" - '(add-to-list 'mail-sources '(file :path "/path/to/spool/file")) - - - If it's a Maildir, with one file per message as used by postfix, - Qmail and (optionally) fetchmail it's - - (eval-after-load "mail-source" - '(add-to-list 'mail-sources '(maildir :path "/path/to/Maildir/" - :subdirs ("cur" "new"))) - - - And finally if you want to read your mail from several files in one - directory, for example because procmail already split your mail, - it's - - (eval-after-load "mail-source" - '(add-to-list 'mail-sources '(directory :path "/path/to/procmail-dir/" - :suffix ".prcml")) - - - Where :suffix ".prcml" tells Gnus only to use files with the suffix - .prcml. - - OK, now you only need to tell Gnus how to send mail. If you want to - send mail via sendmail (or whichever MTA is playing the role of - sendmail on your system), you don't need to do anything. However, - if you want to send your mail to an SMTP Server you need the - following in your ~/.gnus - - (setq send-mail-function 'smtpmail-send-it) - (setq message-send-mail-function 'smtpmail-send-it) - (setq smtpmail-default-smtp-server "smtp.yourProvider.net") - - -3.9. And what about IMAP? - - There are two ways of using IMAP with Gnus. The first one is to use - IMAP like POP3, that means Gnus fetches the mail from the IMAP - server and stores it on disk. If you want to do this (you don't - really want to do this) add the following to ~/.gnus - - (add-to-list 'mail-sources '(imap :server "mail.mycorp.com" - :user "username" - :pass "password" - :stream network - :authentication login - :mailbox "INBOX" - :fetchflag "\\Seen")) - - - You might have to tweak the values for stream and/or - authentification, see the Gnus manual node "Mail Source Specifiers" - for possible values. - - If you want to use IMAP the way it's intended, you've got to follow - a different approach. You've got to add the nnimap back end to your - select method and give the information about the server there. - - (add-to-list 'gnus-secondary-select-methods - '(nnimap "Give the baby a name" - (nnimap-address "imap.yourProvider.net") - (nnimap-port 143) - (nnimap-list-pattern "archive.*"))) - - - Again, you might have to specify how to authenticate to the server - if Gnus can't guess the correct way, see the Manual Node "IMAP" for - detailed information. - -3.10. At the office we use one of those MS Exchange servers, can I use - Gnus to read my mail from it? - - Offer your administrator a pair of new running shoes for activating - IMAP on the server and follow the instructions above. - -3.11. Can I tell Gnus not to delete the mails on the server it retrieves - via POP3? - - First of all, that's not the way POP3 is intended to work, if you - have the possibility, you should use the IMAP Protocol if you want - your messages to stay on the server. Nevertheless there might be - situations where you need the feature, but sadly Gnus itself has no - predefined functionality to do so. - - However this is Gnus county so there are possibilities to achieve - what you want. The easiest way is to get an external program which - retrieves copies of the mail and stores them on disk, so Gnus can - read it from there. On Unix systems you could use e.g. fetchmail - for this, on MS Windows you can use Hamster, an excellent local - news and mail server. - - The other solution would be, to replace the method Gnus uses to get - mail from POP3 servers by one which is capable of leaving the mail - on the server. If you use XEmacs, get the package mail-lib, it - includes an enhanced pop3.el, look in the file, there's - documentation on how to tell Gnus to use it and not to delete the - retrieved mail. For GNU Emacs look for the file epop3.el which can - do the same (If you know the home of this file, please send me an - e-mail). You can also tell Gnus to use an external program (e.g. - fetchmail) to fetch your mail, see the info node "Mail Source - Specifiers" in the Gnus manual on how to do it. - -4. Reading messages - -4.1. When I enter a group, all read messages are gone. How to view them - again? - - If you enter the group by saying RET in summary buffer with point - over the group, only unread and ticked messages are loaded. Say C-u - RET instead to load all available messages. If you want only the - e.g. 300 newest say C-u 300 RET - - Loading only unread messages can be annoying if you have threaded - view enabled, say - - (setq gnus-fetch-old-headers 'some) - - - in ~/.gnus to load enough old articles to prevent teared threads, - replace 'some with t to load all articles (Warning: Both settings - enlarge the amount of data which is fetched when you enter a group - and slow down the process of entering a group). - - If you already use Gnus 5.10.0, you can say /o N In summary buffer - to load the last N messages, this feature is not available in 5.8.8 - - If you don't want all old messages, but the parent of the message - you're just reading, you can say ^, if you want to retrieve the - whole thread the message you're just reading belongs to, A T is - your friend. - -4.2. How to tell Gnus to show an important message every time I enter a - group, even when it's read? - - You can tick important messages. To do this hit u while point is in - summary buffer over the message. When you want to remove the mark, - hit either d (this deletes the tick mark and set's unread mark) or - M c (which deletes all marks for the message). - -4.3. How to view the headers of a message? - - Say t to show all headers, one more t hides them again. - -4.4. How to view the raw unformatted message? - - Say C-u g to show the raw message g returns to normal view. - -4.5. How can I change the headers Gnus displays by default at the top of - the article buffer? - - The variable gnus-visible-headers controls which headers are shown, - its value is a regular expression, header lines which match it are - shown. So if you want author, subject, date, and if the header - exists, Followup-To and MUA / NUA say this in ~/.gnus: - - (setq gnus-visible-headers - "^\\(From:\\|Subject:\\|Date:\\|Followup-To:\\|X-Newsreader:\\|User-Agent:\\|X-Mailer:\\)") - - -4.6. I'd like Gnus NOT to render HTML-mails but show me the text part if - it's available. How to do it? - - Say - - (eval-after-load "mm-decode" - '(progn - (add-to-list 'mm-discouraged-alternatives "text/html") - (add-to-list 'mm-discouraged-alternatives "text/richtext"))) - - - in ~/.gnus. If you don't want HTML rendered, even if there's no - text alternative add - - (setq mm-automatic-display (remove "text/html" mm-automatic-display)) - - - too. - -4.7. Can I use some other browser than w3 to render my HTML-mails? - - Only if you use Gnus 5.10.0 or younger. In this case you've got the - choice between w3, w3m, links, lynx and html2text, which one is - used can be specified in the variable mm-text-html-renderer, so if - you want links to render your mail say - - (setq mm-text-html-renderer 'links) - - -4.8. Is there anything I can do to make poorly formatted mails more - readable? - - Gnus offers you several functions to "wash" incoming mail, you can - find them if you browse through the menu, item Article->Washing. - The most interesting ones are probably "Wrap long lines" ( W w ), - "Decode ROT13" ( W r ) and "Outlook Deuglify" which repairs the - dumb quoting used by many users of Microsoft products ( W Y f gives - you full deuglify. See W Y C-h or have a look at the menus for - other deuglifications). Outlook deuglify is only available since - Gnus 5.10.0. - -4.9. Is there a way to automatically ignore posts by specific authors or - with specific words in the subject? And can I highlight more - interesting ones in some way? - - You want Scoring. Scoring means, that you define rules which assign - each message an integer value. Depending on the value the message - is highlighted in summary buffer (if it's high, say +2000) or - automatically marked read (if the value is low, say -800) or some - other action happens. - - There are basically three ways of setting up rules which assign the - scoring-value to messages. The first and easiest way is to set up - rules based on the article you are just reading. Say you're reading - a message by a guy who always writes nonsense and you want to - ignore his messages in the future. Hit L, to set up a rule which - lowers the score. Now Gnus asks you which the criteria for lowering - the Score shall be. Hit ? twice to see all possibilities, we want a - which means the author (the from header). Now Gnus wants to know - which kind of matching we want. Hit either e for an exact match or - s for substring-match and delete afterwards everything but the name - to score down all authors with the given name no matter which email - address is used. Now you need to tell Gnus when to apply the rule - and how long it should last, hit e.g. p to apply the rule now and - let it last forever. If you want to raise the score instead of - lowering it say I instead of L. - - You can also set up rules by hand. To do this say V f in summary - buffer. Then you are asked for the name of the score file, it's - name.of.group.SCORE for rules valid in only one group or all.Score - for rules valid in all groups. See the Gnus manual for the exact - syntax, basically it's one big list whose elements are lists again. - the first element of those lists is the header to score on, then - one more list with what to match, which score to assign, when to - expire the rule and how to do the matching. If you find me very - interesting, you could e.g. add the following to your all.Score: - - (("references" ("hschmi22.userfqdn.rz-online.de" 500 nil s)) - ("message-id" ("hschmi22.userfqdn.rz-online.de" 999 nil s))) - - - This would add 999 to the score of messages written by me and 500 - to the score of messages which are a (possibly indirect) answer to - a message written by me. Of course nobody with a sane mind would do - this :-) - - The third alternative is adaptive scoring. This means Gnus watches - you and tries to find out what you find interesting and what - annoying and sets up rules which reflect this. Adaptive scoring can - be a huge help when reading high traffic groups. If you want to - activate adaptive scoring say - - (setq gnus-use-adaptive-scoring t) - - - in ~/.gnus. - -4.10. How can I disable threading in some (e.g. mail-) groups, or set - other variables specific for some groups? - - While in group buffer move point over the group and hit G c, this - opens a buffer where you can set options for the group. At the - bottom of the buffer you'll find an item that allows you to set - variables locally for the group. To disable threading enter - gnus-show-threads as name of variable and nil as value. Hit button - done at the top of the buffer when you're ready. - -4.11. Can I highlight messages written by me and follow-ups to those? - - Stop those "Can I ..." questions, the answer is always yes in Gnus - Country :-). It's a three step process: First we make faces - (specifications of how summary-line shall look like) for those - postings, then we'll give them some special score and finally we'll - tell Gnus to use the new faces. You can find detailed instructions - on how to do it on my.gnus.org [http://my.gnus.org/Members/dzimmerm - /HowTo%2C2002-07-25%2C1027619165012198456/view] - -4.12. The number of total messages in a group which Gnus displays in - group buffer is by far to high, especially in mail groups. Is this - a bug? - - No, that's a matter of design of Gnus, fixing this would mean - reimplementation of major parts of Gnus' back ends. Gnus thinks - "highest-article-number - lowest-article-number = - total-number-of-articles". This works OK for Usenet groups, but if - you delete and move many messages in mail groups, this fails. To - cure the symptom, enter the group via C-u RET (this makes Gnus get - all messages), then hit M P b to mark all messages and then say B m - name.of.group to move all messages to the group they have been in - before, they get new message numbers in this process and the count - is right again (until you delete and move your mail to other groups - again). - -4.13. I don't like the layout of summary and article buffer, how to - change it? Perhaps even a three pane display? - - You can control the windows configuration by calling the function - gnus-add-configuration. The syntax is a bit complicated but - explained very well in the manual node "Window Layout". Some - popular examples: - - Instead 25% summary 75% article buffer 35% summary and 65% article - (the 1.0 for article means "take the remaining space"): - - (gnus-add-configuration '(article (vertical 1.0 (summary .35 point) (article 1.0)))) - - - A three pane layout, Group buffer on the left, summary buffer - top-right, article buffer bottom-right: - - (gnus-add-configuration - '(article - (horizontal 1.0 - (vertical 25 - (group 1.0)) - (vertical 1.0 - (summary 0.25 point) - (article 1.0))))) - (gnus-add-configuration - '(summary - (horizontal 1.0 - (vertical 25 - (group 1.0)) - (vertical 1.0 - (summary 1.0 point))))) - - -4.14. I don't like the way the Summary buffer looks, how to tweak it? - - You've got to play around with the variable - gnus-summary-line-format. It's value is a string of symbols which - stand for things like author, date, subject etc. A list of the - available specifiers can be found in the manual node "Summary - Buffer Lines" and the often forgotten node "Formatting Variables" - and it's sub-nodes. There you'll find useful things like - positioning the cursor and tabulators which allow you a summary in - table form, but sadly hard tabulators are broken in 5.8.8. - - Since 5.10.0, Gnus offers you some very nice new specifiers, e.g. - %B which draws a thread-tree and %&user-date which gives you a date - where the details are dependent of the articles age. Here's an - example which uses both: - - (setq gnus-summary-line-format ":%U%R %B %s %-60=|%4L |%-20,20f |%&user-date; \n") - - - resulting in: - - :O Re: [Richard Stallman] rfc2047.el | 13 |Lars Magne Ingebrigt |Sat 23:06 - :O Re: Revival of the ding-patches list | 13 |Lars Magne Ingebrigt |Sat 23:12 - :R > Re: Find correct list of articles for a gro| 25 |Lars Magne Ingebrigt |Sat 23:16 - :O \-> ... | 21 |Kai Grossjohann | 0:01 - :R > Re: Cry for help: deuglify.el - moving stuf| 28 |Lars Magne Ingebrigt |Sat 23:34 - :O \-> ... | 115 |Raymond Scholz | 1:24 - :O \-> ... | 19 |Lars Magne Ingebrigt |15:33 - :O Slow mailing list | 13 |Lars Magne Ingebrigt |Sat 23:49 - :O Re: `@' mark not documented | 13 |Lars Magne Ingebrigt |Sat 23:50 - :R > Re: Gnus still doesn't count messages prope| 23 |Lars Magne Ingebrigt |Sat 23:57 - :O \-> ... | 18 |Kai Grossjohann | 0:35 - :O \-> ... | 13 |Lars Magne Ingebrigt | 0:56 - - -4.15. How to split incoming mails in several groups? - - Gnus offers two possibilities for splitting mail, the easy - nnmail-split-methods and the more powerful Fancy Mail Splitting. - I'll only talk about the first one, refer to the manual, node - "Fancy Mail Splitting" for the latter. - - The value of nnmail-split-methods is a list, each element is a list - which stands for a splitting rule. Each rule has the form "group - where matching articles should go to", "regular expression which - has to be matched", the first rule which matches wins. The last - rule must always be a general rule (regular expression .*) which - denotes where articles should go which don't match any other rule. - If the folder doesn't exist yet, it will be created as soon as an - article lands there. By default the mail will be send to all groups - whose rules match. If you don't want that (you probably don't - want), say - - (setq nnmail-crosspost nil) - - - in ~/.gnus. - - An example might be better than thousand words, so here's my - nnmail-split-methods. Note that I send duplicates in a special - group and that the default group is spam, since I filter all mails - out which are from some list I'm subscribed to or which are - addressed directly to me before. Those rules kill about 80% of the - Spam which reaches me (Email addresses are changed to prevent - spammers from using them): - - (setq nnmail-split-methods - '(("duplicates" "^Gnus-Warning:.*duplicate") - ("XEmacs-NT" "^\\(To:\\|CC:\\).*localpart@xemacs.bla.*") - ("Gnus-Tut" "^\\(To:\\|CC:\\).*localpart@socha.bla.*") - ("tcsh" "^\\(To:\\|CC:\\).*localpart@mx.gw.bla.*") - ("BAfH" "^\\(To:\\|CC:\\).*localpart@.*uni-muenchen.bla.*") - ("Hamster-src" "^\\(CC:\\|To:\\).*hamster-sourcen@yahoogroups.\\(de\\|com\\).*") - ("Tagesschau" "^From: tagesschau $") - ("Replies" "^\\(CC:\\|To:\\).*localpart@Frank-Schmitt.bla.*") - ("EK" "^From:.*\\(localpart@privateprovider.bla\\|localpart@workplace.bla\\).*") - ("Spam" "^Content-Type:.*\\(ks_c_5601-1987\\|EUC-KR\\|big5\\|iso-2022-jp\\).*") - ("Spam" "^Subject:.*\\(This really work\\|XINGA\\|ADV:\\|XXX\\|adult\\|sex\\).*") - ("Spam" "^Subject:.*\\(\=\?ks_c_5601-1987\?\\|\=\?euc-kr\?\\|\=\?big5\?\\).*") - ("Spam" "^X-Mailer:\\(.*BulkMailer.*\\|.*MIME::Lite.*\\|\\)") - ("Spam" "^X-Mailer:\\(.*CyberCreek Avalanche\\|.*http\:\/\/GetResponse\.com\\)") - ("Spam" "^From:.*\\(verizon\.net\\|prontomail\.com\\|money\\|ConsumerDirect\\).*") - ("Spam" "^Delivered-To: GMX delivery to spamtrap@gmx.bla$") - ("Spam" "^Received: from link2buy.com") - ("Spam" "^CC: .*azzrael@t-online.bla") - ("Spam" "^X-Mailer-Version: 1.50 BETA") - ("Uni" "^\\(CC:\\|To:\\).*localpart@uni-koblenz.bla.*") - ("Inbox" "^\\(CC:\\|To:\\).*\\(my\ name\\|address@one.bla\\|adress@two.bla\\)") - ("Spam" ""))) - - -5. Composing messages - -5.1. What are the basic commands I need to know for sending mail and - postings? - - To start composing a new mail hit m either in Group or Summary - buffer, for a posting, it's either a in Group buffer and filling - the Newsgroups header manually or a in the Summary buffer of the - group where the posting shall be send to. Replying by mail is r if - you don't want to cite the author, or import the cited text - manually and R to cite the text of the original message. For a - follow up to a newsgroup, it's f and F (analog to r and R. - - Enter new headers above the line saying "--text follows this - line--", enter the text below the line. When ready hit C-c C-c, to - send the message, if you want to finish it later hit C-c C-d to - save it in the drafts group, where you can start editing it again - by saying D e. - -5.2. How to enable automatic word-wrap when composing messages? - - Say - - (add-hook 'message-mode-hook - (lambda () - (setq fill-column 72) - (turn-on-auto-fill))) - - - in ~/.gnus. You can reformat a paragraph by hitting M-q (as usual) - -5.3. How to set stuff like From, Organization, Reply-To, signature...? - - There are other ways, but you should use posting styles for this. - (See below why). This example should make the syntax clear: - - (setq gnus-posting-styles - '((".*" - (name "Frank Schmitt") - (address "me@there.bla") - (organization "Hamme net, kren mer och nimmi") - (signature-file "~/.signature") - ("X-SampleHeader" "foobar") - (eval (setq some-variable "Foo bar"))))) - - - The ".*" means that this settings are the default ones (see below), - valid values for the first element of the following lists are - signature, signature-file, organization, address, name or body. The - attribute name can also be a string. In that case, this will be - used as a header name, and the value will be inserted in the - headers of the article; if the value is `nil', the header name will - be removed. You can also say (eval (foo bar)), then the function - foo will be evaluated with argument bar and the result will be - thrown away. - -5.4. Can I set things like From, Signature etc group based on the group - I post too? - - That's the strength of posting styles. Before, we used ".*" to set - the default for all groups. You can use a regexp like "^gmane" and - the following settings are only applied to postings you send to the - gmane hierarchy, use ".*binaries" instead and they will be applied - to postings send to groups containing the string binaries in their - name etc. - - You can instead of specifying a regexp specify a function which is - evaluated, only if it returns true, the corresponding settings take - effect. Two interesting candidates for this are message-news-p - which returns t if the current Group is a newsgroup and the - corresponding message-mail-p. - - Note that all forms that match are applied, that means in the - example below, when I post to gmane.mail.spam.spamassassin.general, - the settings under ".*" are applied and the settings under - message-news-p and those under "^gmane" and those under "^gmane\ - \.mail\\.spam\\.spamassassin\\.general$". Because of this put - general settings at the top and specific ones at the bottom. - - (setq gnus-posting-styles - '((".*" ;;default - (name "Frank Schmitt") - (organization "Hamme net, kren mer och nimmi") - (signature-file "~/.signature") ) - ((message-news-p) ;;Usenet news? - (address "mySpamTrap@Frank-Schmitt.bla") - ("Reply-To" "hereRealRepliesOnlyPlease@Frank-Schmitt.bla") ) - ((message-mail-p) ;;mail? - (address "usedForMails@Frank-Schmitt.bla") ) - ("^gmane" ;;this is mail, too in fact - (address "usedForMails@Frank-Schmitt.net") - ("Reply-To" nil) ) - ("^gmane.mail.spam.spamassassin.general$" - (eval (setq mail-envelope-from "Azzrael@rz-online.de")) - (address "Azzrael@rz-online.de")) )) - - -5.5. Is there a spell-checker? Perhaps even on-the-fly spell-checking? - - You can use ispell.el to spell-check stuff in Emacs. So the first - thing to do is to make sure that you've got either ispell [http:// - fmg-www.cs.ucla.edu/fmg-members/geoff/ispell.html] or aspell [http: - //aspell.sourceforge.net/] installed and in your Path. Then you - need ispell.el [http://www.kdstevens.com/~stevens/ispell-page.html] - and for on-the-fly spell-checking flyspell.el [http:// - www-sop.inria.fr/mimosa/personnel/Manuel.Serrano/flyspell/ - flyspell.html]. Ispell.el is shipped with Gnus Emacs and available - through the Emacs package system, flyspell.el is shipped with Emacs - and part of XEmacs text-modes package which is available through - the package system, so there should be no need to install them - manually. - - Ispell.el assumes you use ispell, if you choose aspell say - - (setq ispell-program-name "aspell") - - in your Emacs configuration file. - - If you want your outgoing messages to be spell-checked, say - - (add-hook 'message-send-hook 'ispell-message) - - In your ~/.gnus, if you prefer on-the-fly spell-checking say - - (add-hook 'message-mode-hook (lambda () (flyspell-mode 1))) - -5.6. Can I set the dictionary based on the group I'm posting to? - - Yes, say something like - - (add-hook 'gnus-select-group-hook - (lambda () - (cond - ((string-match - "^de\\." (gnus-group-real-name gnus-newsgroup-name)) - (ispell-change-dictionary "deutsch8")) - (t - (ispell-change-dictionary "english"))))) - - - in ~/.gnus. Change "^de\\." and "deutsch8" to something that suits - your needs. - -5.7. Is there some kind of address-book, so I needn't remember all those - email addresses? - - There's an very basic solution for this, mail aliases. You can - store your mail addresses in a ~/.mailrc file using a simple alias - syntax: - - alias al "Al " - - - Then typing your alias (followed by a space or punctuation - character) on a To: or Cc: line in the message buffer will cause - gnus to insert the full address for you. See the node "Mail - Aliases" in Message (not Gnus) manual for details. - - However, what you really want is the Insidious Big Brother Database - bbdb. Get it through the XEmacs package system or from bbdb's - homepage [http://bbdb.sourceforge.net/]. Now place the following in - ~/.gnus, to activate bbdb for Gnus: - - (require 'bbdb) - (bbdb-initialize 'gnus 'message) - - - Now you probably want some general bbdb configuration, place them - in ~/.emacs: - - (require 'bbdb) - ;;If you don't live in Northern America, you should disable the - ;;syntax check for telephone numbers by saying - (setq bbdb-north-american-phone-numbers-p nil) - ;;Tell bbdb about your email address: - (setq bbdb-user-mail-names - (regexp-opt '("Your.Email@here.bla" - "Your.other@mail.there.bla"))) - ;;cycling while completing email addresses - (setq bbdb-complete-name-allow-cycling t) - ;;No popup-buffers - (setq bbdb-use-pop-up nil) - - - Now you should be ready to go. Say M-x bbdb RET RET to open a bbdb - buffer showing all entries. Say c to create a new entry, b to - search your BBDB and C-o to add a new field to an entry. If you - want to add a sender to the BBDB you can also just hit `:' on the - posting in the summary buffer and you are done. When you now - compose a new mail, hit TAB to cycle through know recipients. - -5.8. Sometimes I see little images at the top of article buffer. What's - that and how can I send one with my postings, too? - - Those images are called X-Faces. They are 48*48 pixel b/w pictures, - encoded in a header line. If you want to include one in your posts, - you've got to convert some image to a X-Face. So fire up some image - manipulation program (say Gimp), open the image you want to - include, cut out the relevant part, reduce color depth to 1 bit, - resize to 48*48 and save as bitmap. Now you should get the compface - package from this site [ftp://ftp.cs.indiana.edu:/pub/faces/]. and - create the actual X-face by saying - - cat file.xbm | xbm2ikon |compface > file.face - cat ./file.face | sed 's/\\/\\\\/g' | sed 's/\"/\\\"/g' > ./file.face.quoted - - - if you can't use compface, there's an online X-face converter at - http://www.dairiki.org/xface/ [http://www.dairiki.org/xface/]. If - you use MS Windows, you could also use the WinFace program from - http://www.xs4all.nl/~walterln/winface/ [http://www.xs4all.nl/ - ~walterln/winface/]. Now you only have to tell Gnus to include the - X-face in your postings by saying - - (setq message-default-headers - (with-temp-buffer - (insert "X-Face: ") - (insert-file-contents "~/.xemacs/xface") - (buffer-string))) - - - in ~/.gnus. - -5.9. Sometimes I accidentally hit r instead of f in newsgroups. Can Gnus - warn me, when I'm replying by mail in newsgroups? - - Put this in ~/.gnus: - - (setq gnus-confirm-mail-reply-to-news t) - - - if you already use Gnus 5.10.0, if you still use 5.8.8 or 5.9 try - this instead: - - (defadvice gnus-summary-reply (around reply-in-news activate) - (interactive) - (when (or (not (gnus-news-group-p gnus-newsgroup-name)) - (y-or-n-p "Really reply? ")) - ad-do-it)) - - -5.10. How to tell Gnus not to generate a sender header? - - Since 5.10.0 Gnus doesn't generate a sender header by default. For - older Gnus' try this in ~/.gnus: - - (eval-after-load "message" - '(add-to-list 'message-syntax-checks '(sender . disabled))) - - -5.11. I want gnus to locally store copies of my send mail and news, how - to do it? - - You must set the variable gnus-message-archive-group to do this. - You can set it to a string giving the name of the group where the - copies shall go or like in the example below use a function which - is evaluated and which returns the group to use. - - (setq gnus-message-archive-group - '((if (message-news-p) - "nnml:Send-News" - "nnml:Send-Mail"))) - - -5.12. People tell me my Message-IDs are not correct, why aren't they and - how to fix it? - - The message-ID is an unique identifier for messages you send. To - make it unique, Gnus need to know which machine name to put after - the "@". If the name of the machine where Gnus is running isn't - suitable (it probably isn't at most private machines) you can tell - Gnus what to use by saying: - - (defun message-make-message-id() - (concat "<"(message-unique-id)"@yourmachine.yourdomain.tld>")) - - - in ~/.gnus. If you have no idea what to insert for - "yourmachine.yourdomain.tld", you've got several choices. You can - either ask your provider if he allows you to use something like - yourUserName.userfqdn.provider.net, or you can use - somethingUnique.yourdomain.tld if you own the domain - yourdomain.tld, or you can register at a service which gives - private users a FQDN for free, e.g. http://www.stura.tu-freiberg.de - /~dlx/addfqdn.html [http://www.stura.tu-freiberg.de/~dlx/ - addfqdn.html]. (Sorry but this website is in German, if you know of - an English one offering the same, drop me a note). - - Finally you can tell Gnus not to generate a Message-ID for News at - all (and letting the server do the job) by saying - - (setq message-required-news-headers - (remove' Message-ID message-required-news-headers)) - - - you can also tell Gnus not to generate Message-IDs for mail by - saying - - (setq message-required-mail-headers - (remove' Message-ID message-required-mail-headers)) - - - , however some mail servers don't generate proper Message-IDs, too, - so test if your Mail Server behaves correctly by sending yourself a - Mail and looking at the Message-ID. - -6. Old messages - -6.1. How to import my old mail into Gnus? - - The easiest way is to tell your old mail program to export the - messages in mbox format. Most Unix mailers are able to do this, if - you come from the MS Windows world, you may find tools at http:// - mbx2mbox.sourceforge.net/ [http://mbx2mbox.sourceforge.net/]. - - Now you've got to import this mbox file into Gnus. To do this, - create a nndoc group based on the mbox file by saying G f /path/ - file.mbox RET in Group buffer. You now have read-only access to - your mail. If you want to import the messages to your normal Gnus - mail groups hierarchy, enter the nndoc group you've just created by - saying C-u RET (thus making sure all messages are retrieved), mark - all messages by saying M P b and either copy them to the desired - group by saying B c name.of.group RET or send them through - nnmail-split-methods (respool them) by saying B r. - -6.2. How to archive interesting messages? - - If you stumble across an interesting message, say in gnu.emacs.gnus - and want to archive it there are several solutions. The first and - easiest is to save it to a file by saying O f. However, wouldn't it - be much more convenient to have more direct access to the archived - message from Gnus? If you say yes, put this snippet by Frank Haun - in ~/.gnus: - - (defun my-archive-article (&optional n) - "Copies one or more article(s) to a corresponding `nnml:' group, e.g. - `gnus.ding' goes to `nnml:1.gnus.ding'. And `nnml:List-gnus.ding' goes - to `nnml:1.List-gnus-ding'. - - Use process marks or mark a region in the summary buffer to archive - more then one article." - (interactive "P") - (let ((archive-name - (format - "nnml:1.%s" - (if (featurep 'xemacs) - (replace-in-string gnus-newsgroup-name "^.*:" "") - (replace-regexp-in-string "^.*:" "" gnus-newsgroup-name))))) - (gnus-summary-copy-article n archive-name))) - - - You can now say M-x my-archive-article in summary buffer to archive - the article under the cursor in a nnml group. (Change nnml to your - preferred back end) - - Of course you can also make sure the cache is enabled by saying - - (setq gnus-use-cache t) - - - then you only have to set either the tick or the dormant mark for - articles you want to keep, setting the read mark will remove them - from cache. - -6.3. How to search for a specific message? - - There are several ways for this, too. For a posting from a Usenet - group the easiest solution is probably to ask groups.google.com - [http://groups.google.com], if you found the posting there, tell - Google to display the raw message, look for the message-id, and say - M-^ the@message.id RET in a summary buffer. Since Gnus 5.10.0 - there's also a Gnus interface for groups.google.com which you can - call with G W) in group buffer. - - Another idea which works for both mail and news groups is to enter - the group where the message you are searching is and use the - standard Emacs search C-s, it's smart enough to look at articles in - collapsed threads, too. If you want to search bodies, too try M-s - instead. Further on there are the gnus-summary-limit-to-foo - functions, which can help you, too. - - Of course you can also use grep to search through your local mail, - but this is both slow for big archives and inconvenient since you - are not displaying the found mail in Gnus. Here comes nnir into - action. Nnir is a front end to search engines like swish-e or - swish++ and others. You index your mail with one of those search - engines and with the help of nnir you can search trough the indexed - mail and generate a temporary group with all messages which met - your search criteria. If this sound cool to you get nnir.el from - ftp://ls6-ftp.cs.uni-dortmund.de/pub/src/emacs/ [ftp:// - ls6-ftp.cs.uni-dortmund.de/pub/src/emacs/] or ftp:// - ftp.is.informatik.uni-duisburg.de/pub/src/emacs/ [ftp:// - ftp.is.informatik.uni-duisburg.de/pub/src/emacs/]. Instructions on - how to use it are at the top of the file. - -6.4. How to get rid of old unwanted mail? - - You can of course just mark the mail you don't need anymore by - saying # with point over the mail and then say B DEL to get rid of - them forever. You could also instead of actually deleting them, - send them to a junk-group by saying B m nnml:trash-bin which you - clear from time to time, but both are not the intended way in Gnus. - - In Gnus, we let mail expire like news expires on a news server. - That means you tell Gnus the message is expirable (you tell Gnus "I - don't need this mail anymore") by saying E with point over the mail - in summary buffer. Now when you leave the group, Gnus looks at all - messages which you marked as expirable before and if they are old - enough (default is older than a week) they are deleted. - -6.5. I want that all read messages are expired (at least in some - groups). How to do it? - - If you want all read messages to be expired (e.g. in mailing lists - where there's an online archive), you've got two choices: - auto-expire and total-expire. Auto-expire means, that every article - which has no marks set and is selected for reading is marked as - expirable, Gnus hits E for you every time you read a message. - Total-expire follows a slightly different approach, here all - article where the read mark is set are expirable. - - To activate auto-expire, include auto-expire in the Group - parameters for the group. (Hit G c in summary buffer with point - over the group to change group parameters). For total-expire add - total-expire to the group-parameters. - - Which method you choose is merely a matter of taste: Auto-expire is - faster, but it doesn't play together with Adaptive Scoring, so if - you want to use this feature, you should use total-expire. - - If you want a message to be excluded from expiration in a group - where total or auto expire is active, set either tick (hit u) or - dormant mark (hit u), when you use auto-expire, you can also set - the read mark (hit d). - -6.6. I don't want expiration to delete my mails but to move them to - another group. - - Say something like this in ~/.gnus: - - (setq nnmail-expiry-target "nnml:expired") - - - (If you want to change the value of nnmail-expiry-target on a per - group basis see the question "How can I disable threading in some - (e.g. mail-) groups, or set other variables specific for some - groups?") - -7. Gnus in a dial-up environment - -7.1. I don't have a permanent connection to the net, how can I minimize - the time I've got to be connected? - - You've got basically two options: Either you use the Gnus Agent - (see below) for this, or you can install programs which fetch your - news and mail to your local disk and Gnus reads the stuff from your - local machine. - - If you want to follow the second approach, you need a program which - fetches news and offers them to Gnus, a program which does the same - for mail and a program which receives the mail you write from Gnus - and sends them when you're online. - - Let's talk about Unix systems first: For the news part, the easiest - solution is a small nntp server like Leafnode [http:// - www.leafnode.org/] or sn [http://infa.abo.fi/~patrik/sn/], of - course you can also install a full featured news server like inn - [http://www.isc.org/products/INN/]. Then you want to fetch your - Mail, popular choices are fetchmail [http://www.catb.org/~esr/ - fetchmail/] and getmail [http://www.qcc.ca/~charlesc/software/ - getmail-3.0/]. You should tell those to write the mail to your disk - and Gnus to read it from there. Last but not least the mail sending - part: This can be done with every MTA like sendmail [http:// - www.sendmail.org/], postfix [http://www.qmail.org/], exim [http:// - www.exim.org/] or qmail [http://www.qmail.org/]. - - On windows boxes I'd vote for Hamster [http://www.tglsoft.de/], - it's a small freeware, open-source program which fetches your mail - and news from remote servers and offers them to Gnus (or any other - mail and/or news reader) via nntp respectively POP3 or IMAP. It - also includes a smtp server for receiving mails from Gnus. - -7.2. So what was this thing about the Agent? - - The Gnus agent is part of Gnus, it allows you to fetch mail and - news and store them on disk for reading them later when you're - offline. It kind of mimics offline newsreaders like e.g. Forte - Agent. If you want to use the Agent place the following in ~/.gnus - if you are still using 5.8.8 or 5.9 (it's the default since - 5.10.0): - - (setq gnus-agent t) - - - Now you've got to select the servers whose groups can be stored - locally. To do this, open the server buffer (that is press ^ while - in the group buffer). Now select a server by moving point to the - line naming that server. Finally, agentize the server by typing J a - . If you make a mistake, or change your mind, you can undo this - action by typing J r. When you're done, type 'q' to return to the - group buffer. Now the next time you enter a group on a agentized - server, the headers will be stored on disk and read from there the - next time you enter the group. - -7.3. I want to store article bodies on disk, too. How to do it? - - You can tell the agent to automatically fetch the bodies of - articles which fulfill certain predicates, this is done in a - special buffer which can be reached by saying J c in group buffer. - Please refer to the documentation for information which predicates - are possible and how exactly to do it. - - Further on you can tell the agent manually which articles to store - on disk. There are two ways to do this: Number one: In the summary - buffer, process mark a set of articles that shall be stored in the - agent by saying # with point over the article and then type J s. - The other possibility is to set, again in the summary buffer, - downloadable (%) marks for the articles you want by typing @ with - point over the article and then typing J u. What's the difference? - Well, process marks are erased as soon as you exit the summary - buffer while downloadable marks are permanent. You can actually set - downloadable marks in several groups then use fetch session ('J s' - in the GROUP buffer) to fetch all of those articles. The only - downside is that fetch session also fetches all of the headers for - every selected group on an agentized server. Depending on the - volume of headers, the initial fetch session could take hours. - -7.4. How to tell Gnus not to try to send mails / postings while I'm - offline? - - All you've got to do is to tell Gnus when you are online (plugged) - and when you are offline (unplugged), the rest works automatically. - You can toggle plugged/unplugged state by saying J j in group - buffer. To start Gnus unplugged say M-x gnus-unplugged instead of - M-x gnus. Note that for this to work, the agent must be active. - -8. Getting help - -8.1. How to find information and help inside Emacs? - - The first stop should be the Gnus manual (Say C-h i d m Gnus RET to - start the Gnus manual, then walk through the menus or do a - full-text search with s). Then there are the general Emacs help - commands starting with C-h, type C-h ? ? to get a list of all - available help commands and their meaning. Finally M-x - apropos-command lets you search through all available functions and - M-x apropos searches the bound variables. - -8.2. I can't find anything in the Gnus manual about X (e.g. attachments, - PGP, MIME...), is it not documented? - - There's not only the Gnus manual but also the manuals for message, - emacs-mime, sieve and pgg. Those packages are distributed with Gnus - and used by Gnus but aren't really part of core Gnus, so they are - documented in different info files, you should have a look in those - manuals, too. - -8.3. Which websites should I know? - - The two most important ones are the official Gnus website [http:// - www.gnus.org]. and it's sister site my.gnus.org (MGO) [http:// - my.gnus.org], hosting an archive of lisp snippets, howtos, a (not - really finished) tutorial and this FAQ. - - Tell me about other sites which are interesting. - -8.4. Which mailing lists and newsgroups are there? - - There's the newsgroup gnu.emacs.gnus (pull it from e.g. - news.gnus.org) which deals with general questions and the ding - mailing list (ding@gnus.org) dealing with development of Gnus. You - can read the ding list via NNTP, too under the name gnus.ding from - news.gnus.org. - - If you want to stay in the big8, news.software.newssreaders is also - read by some Gnus users (but chances for qualified help are much - better in the above groups) and if you speak German, there's - de.comm.software.gnus. - -8.5. Where to report bugs? - - Say M-x gnus-bug, this will start a message to the gnus bug mailing - list [mailto:bugs@gnus.org] including information about your - environment which make it easier to help you. - -8.6. I need real-time help, where to find it? - - Point your IRC client to irc.my.gnus.org channel #mygnus. Don't be - afraid if people there speak German, they are willing and capable - of switching to English when people from outside Germany enter. - -9. Tuning Gnus - -9.1. Starting Gnus is really slow, how to speed it up? - - The reason for this could be the way Gnus reads it's active file, - see the node "The Active File" in the Gnus manual for things you - might try to speed the process up. An other idea would be to byte - compile your ~/.gnus (say M-x byte-compile-file RET ~/.gnus RET to - do it). Finally, if you have require statements in your .gnus, you - could replace them with eval-after-load, which loads the stuff not - at startup time, but when it's needed. Say you've got this in your - ~/.gnus: - - (require 'message) - (add-to-list 'message-syntax-checks '(sender . disabled)) - - - then as soon as you start Gnus, message.el is loaded. If you - replace it with - - (eval-after-load "message" - '(add-to-list 'message-syntax-checks '(sender . disabled))) - - - it's loaded when it's needed. - -9.2. How to speed up the process of entering a group? - - A speed killer is setting the variable gnus-fetch-old-headers to - anything different from nil, so don't do this if speed is an issue. - To speed up building of summary say - - (gnus-compile) - - - at the bottom of your ~/.gnus, this will make gnus byte-compile - things like gnus-summary-line-format. then you could increase the - value of gc-cons-threshold by saying something like - - (setq gc-cons-threshold 3500000) - - - in ~/.emacs. If you don't care about width of CJK characters or use - Gnus 5.10.0 or younger together with a recent GNU Emacs, you should - say - - (setq gnus-use-correct-string-widths nil) - - - in ~/.gnus (thanks to Jesper harder for the last two suggestions). - Finally if you are still using 5.8.8 or 5.9 and experience speed - problems with summary buffer generation, you definitely should - update to 5.10.0 since there quite some work on improving it has - been done. - -9.3. Sending mail becomes slower and slower, what's up? - - The reason could be that you told Gnus to archive the messages you - wrote by setting gnus-message-archive-group. Try to use a nnml - group instead of an archive group, this should bring you back to - normal speed. - -Glossary - -~/.gnus - - When the term ~/.gnus is used it just means your Gnus - configuration file. You might as well call it ~/.gnus.el or - specify another name. - -Back End - - In Gnus terminology a back end is a virtual server, a layer - between core Gnus and the real NNTP-, POP3-, IMAP- or - whatever-server which offers Gnus a standardized interface to - functions like "get message", "get Headers" etc. - -Emacs +Subject: Gnus FAQ (Frequently Asked Questions) +Message-ID: - When the term Emacs is used in this FAQ, it means either GNU - Emacs or XEmacs. +The Gnus FAQ is distributed within the Gnus manual. The home page of +the Gnus FAQ is , where you can find the +most recent version in HTML various other formats. -Message +To browse the FAQ now, put the cursor at the end of the following line +and press `C-x C-e': - In this FAQ message means a either a mail or a posting to a - Usenet Newsgroup or to some other fancy back end, no matter of - which kind it is. + (info "(gnus)Frequently Asked Questions") -MUA +On older XEmacs version, use: - MUA is an acronym for Mail User Agent, it's the program you use - to read and write e-mails. + (Info-goto-node "(gnus)Frequently Asked Questions") + +Or simply use RET or the middle mouse button, if the above is displayed +as a clickable button. -NUA - NUA is an acronym for News User Agent, it's the program you use - to read and write Usenet news. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e979c6b..f2f699f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,2728 @@ +2004-01-04 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.10.6 is released. + +2004-01-04 Kai Grossjohann + + * gnus-sum.el (gnus-summary-print-article): Doc fix. + +2004-01-04 Lars Magne Ingebrigtsen + + * gnus.el (gnus-version-number): Bump. + +2004-01-04 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.10.5 is released. + +2004-01-03 Lars Magne Ingebrigtsen + + * gnus-fun.el (gnus-face-from-file): Message 9. + +2004-01-03 Romain FRANCOISE + + * gnus-fun.el (gnus-face-from-file): Use gnus-message. + +2004-01-03 Reiner Steib + + * gnus-art.el (gnus-button-mid-or-mail-heuristic): Treat Gmane + addresses specially. Fix returned value and messages. + + * mm-decode.el (mm-enable-external): New variable. + (mm-display-part): Use it. + (mm-display-external): Fix message in case of nil handle. + + * Update copyright for several files. + + * spam-report.el (spam-report-gmane): Adjust verbosity. + Delete trailing whitespace. Update copyright. + + * spam.el: Fix many (but not all) checkdoc complaints. + Delete trailing whitespace. + + * message.el (message-header-synonyms): Defcustom. + (message-get-reply-headers): Catch `Original-To'. + (message-carefully-insert-headers): Added comment. + + * gnus-sum.el (gnus-summary-make-menu-bar): Improved "Washing" menu. + +2004-01-03 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-select-newsgroup): Use cat. + + * gnus-agent.el (gnus-agent-cat-enable-undownloaded-faces): New + cat. + + * gnus.el (gnus-user-agent): Moved here. + + * gnus-msg.el (gnus-user-agent): Moved from here. + + * gnus.el (gnus-version-number): Bump. + +2004-01-03 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.10.4 is released. + +2004-01-02 Reiner Steib + + * 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 + + * gnus-dired.el (gnus-dired-mode-map): Change keymaps. + +2004-01-02 Arne J,Ax(Brgensen + + * smime.el (smime-crl-check): Doc fix. + +2004-01-02 Edwin Steiner + + * gnus-nocem.el (gnus-nocem-enter-article): Use the real group + hashtb (tiny patch). + +2004-01-02 Kai Grossjohann + + * nnml.el (nnml-save-mail): Grok compressed articles. From + Michael Albinus . + +2004-01-02 Teodor Zlatanov + + * 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 + + * mml-sec.el (mml-default-encrypt-method) + (mml-default-sign-method): Defcustom. + +2003-12-31 Lars Magne Ingebrigtsen + + * 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 + + * mml.el (mml-generate-mime-1): Use mml-compute-boundary (tiny + change). + +2003-12-30 Reiner Steib + + * 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 + + * gnus-score.el (gnus-score-edit-file-at-point): Use + gnus-point-at-*, for portability. + +2003-12-30 Reiner Steib + + * 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 . + (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 + + * smime.el (smime-crl-check): New. + (smime-verify-region): Use it. From Arne J,Ax(Brgensen + in <87llpk9v5q.fsf@seamus.arnested.dk> (tiny + change). + +2003-12-30 Reiner Steib + + * gnus-score.el (gnus-score-edit-file-at-point): Consider the + whole match element. From Karl Pfl,Ad(Bsterer . + (gnus-score-find-trace): Use it. Added `f' and `t' commands, + added quick help. With some suggestions from Karl Pfl,Ad(Bsterer + . + + * 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 + + * gnus-sum.el (gnus-summary-make-menu-bar): Add ellipses. + +2003-12-30 Lars Magne Ingebrigtsen + + * 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 + + * gnus.el: Gnus v5.10.3 is released. + +2003-12-29 Simon Josefsson + + * gnus-agent.el (gnus-agentize): Improve auto-agentizing logic. + Suggested by Steinar Bang . + (gnus-agent-auto-agentize-methods): Customize. + +2003-12-29 Kevin Greiner + * gnus.el (gnus-server-to-method): Fixed bug in 2003-12-22 + check-in. + +2003-12-28 Adrian Lanz + + * mail-source.el (mail-source-fetch-imap): Prevent storing of + identical entries for imap mail sources, when retrieving mail + messages from an imap server within the same Gnus session several + times (tiny change). + +2003-12-28 Jesper Harder + + * mm-view.el (mm-text-html-washer-alist): Use + mm-inline-wash-with-stdin for w3m-standalone. + + * mm-decode.el (mm-text-html-renderer): Add w3m-standalone. + + * mml1991.el (mml1991-pgg-encrypt): Decode according to CTE before + encrypting. + +2003-12-28 Jesper Harder + + * mml1991.el (mml1991-pgg-sign): Use unibyte when re-encoding. + From Ivan Boldyrev (tiny change). + +2003-12-26 Katsumi Yamaoka + + * dgnushack.el: Add an advice to byte-optimize-form-code-walker to + avoid the warning ``...called for effect'' for the pop form when + running Emacs 21.3. + +2003-12-26 Jesper Harder + + * mm-bodies.el (mm-body-encoding): Don't use 7bit if the body + contains "^From " and mm-use-ultra-safe-encoding is true. + +2003-12-25 Jesper Harder + + * mml1991.el (mml1991-pgg-sign): Encode and decode according to + CTE header. Don't insert gpg output as unibyte. + +2003-12-25 Katsumi Yamaoka + + * lpath.el: Remove display-time-event-handler and open-ssl-stream; + add delete-extent for Emacs; rearrange bindings assuming w3 may + not be available and XEmacs without the file-coding feature may be + used. + +2003-12-24 Katsumi Yamaoka + + * dgnushack.el (dgnushack-compile): Increase the value for + max-specpdl-size when compiling Gnus with Emacs 20. + +2003-12-22 Kevin Greiner + * gnus-int.el (gnus-open-server): Fixed the server status such + that an agentized server, when opened offline, has a status of + offline. Also fixes bug whereby the agent's backend was called + twice to open each server. + + * gnus-start.el (gnus-get-unread-articles-in-group): Autoload + gnus-agent-possibly-alter-active rather than inline to resolve + compiler warnings. + + * gnus.el (gnus-server-to-method): Added fallback of iterating + over gnus-newsrc-alist to resolve names of foreign servers. + Should fix recent agent bug. + +2003-12-22 Reiner Steib + + * gnus-score.el (gnus-summary-lower-score) + (gnus-summary-increase-score): Mention symbolic prefix in the + doc-string. Suggested by Karl Pfl,Ad(Bsterer . + +2003-12-21 Jesper Harder + + * gnus-agent.el (gnus-agent-read-agentview): Use + car-less-than-car. + +2003-12-20 Artem Chuprina (tiny change) + + * message.el (message-yank-buffer): Bind message-reply-buffer to + a buffer rather than a string. + +2003-12-19 Jesper Harder + + * gnus-msg.el (gnus-summary-followup): Correct documentation. + +2003-12-18 Jesper Harder + + * gnus-msg.el (gnus-inews-add-send-actions): `yanked' can be a + list of lists. Reported by Dmitri Paduchikh . + +2003-12-18 Reiner Steib + + * mm-url.el (mm-url-insert-file-contents-external) + (mm-url-insert-file-contents): Added doc-strings. Autoload. + +2003-12-18 Jesper Harder + + * gnus-cus.el (defvar): defvar + gnus-agent-cat-disable-undownloaded-faces. + +2003-12-17 Katsumi Yamaoka + + * message.el (message-forward-subject-name-subject): Use + gnus-extract-address-components instead of + mail-header-parse-address because it may be called with non-ascii + text. + +2003-12-16 Per Abrahamsen + + * nnmail.el (nnmail-split-fancy): The widget now supports + restrictions. + +2003-12-16 Katsumi Yamaoka + + * nnheader.el (nnheader-find-etc-directory): Find the newest one. + +2003-12-16 Simon Josefsson + + * sha1-el.el (autoload): Don't use ignore-errors. + (sha1-use-external): Use condition-case. Suggested by Katsumi + Yamaoka . + +2003-12-15 Katsumi Yamaoka + + * nnmail.el (nnmail-split-fancy): Make it customizable with Emacs + 20 as well. + +2003-12-15 Simon Josefsson + + * sha1-el.el (autoload): Ignore errors for + executable-find. (XEmacs ecrypto does not require sh-script where + executable.el is located.) + (sha1-use-external): Likewise. + + * sha1-el.el (sha1): Add defgroup. + (sha1-maximum-internal-length, sha1-program, sha1-use-external) + (sha1-program): Use 'sha1sum' from GNU CoreUtils instead of OpenSSL. + (sha1): Autoload. + + * nndraft.el (nndraft-request-move-article): Copy definition of + nnmh-request-move-article instead of calling it, because the nnmh + version uses nnmh-request-article which isn't the same as the + nndraft version. + +2003-12-13 Teodor Zlatanov + + * spam.el: added some gnus-registry autoloads + (spam-split-symbolic-return): makes spam-split return 'spam + instead of the value of spam-split-group when spam is detected + (spam-split-symbolic-return-positive): makes spam-split return + 'ham instead of nil when ham is detected + (spam-autodetect-recheck-messages): tells spam.el whether it + should recheck all messages in a group, or only the unseen ones + (spam-split-last-successful-check): spam-split will set this to + the last successful check; this was seen as a cleaner approach + than returning a cell like '(spam spam-use-bogofilter) + (spam-list-of-checks): documentation appended + (spam-split): accomodate the spam-split-symbolic-return and + spam-split-symbolic-return-positive variables + (spam-find-spam): new function called when the summary is built + (spam-log-registered-p): checks if a ham or spam registration has + already been done for an article + (spam-check-regex-headers, spam-check-blackholes, spam-check-BBDB) + (spam-check-ifile, spam-check-stat, spam-check-whitelist) + (spam-check-blacklist, spam-check-bogofilter-headers) + (spam-check-spamoracle): respect the spam-split-symbolic-return + and spam-split-symbolic-return-positive variables + (spam-initialize): add spam-find-spam to gnus-summary-prepare-hook + (spam-unload-hook): remove spam-find-spam from + gnus-summary-prepare-hook + + * gnus.el (spam-autodetect, spam-autodetect-methods): new + configuration items for spam autodetection + +2003-12-12 Reiner Steib + + * gnus-draft.el (gnus-draft-mode-map): Bind `e' to + `gnus-draft-edit-message'. We still have `B w' for + `gnus-summary-edit-article'. + +2003-12-12 Katsumi Yamaoka + + * nnheaderxm.el (nnheader-xmas-run-at-time): Use a simple function + definition if there is not a bug in start-itimer. + + * pgg.el (pgg-run-at-time): Ditto. + +2003-12-11 Kevin Greiner + + * gnus-agent.el (gnus-agent-possibly-alter-active): New Function. + (gnus-agent-regenerate-group): When necessary, alter the group's + active range to include articles newly recognized as being + downloaded. + (gnus-agent-regenerate): Removed code that updated the agent's + active file as the new gnus-agent-possibly-alter-active function + obsolesced it. + + * gnus-cus.el (gnus-agent-customize-category): Added missing + agent-disable-undownloaded-faces parameter. + + * gnus-start.el (gnus-activate-group): Backed out my 2003-11-29 + patch as it was too late at adjusting the active range. + (gnus-get-unread-articles-in-group): Added call to new + gnus-agent-possibly-alter-active to adjust the active range. + +2003-12-10 Jesper Harder + + * message.el (message-get-reply-headers): Narrow to headers. + +2003-12-10 Teodor Zlatanov + + * spam.el (spam-disable-spam-split-during-ham-respool): new + variable. From lorentey@elte.hu (L,Bu(Brentey K,Ba(Broly) + (spam-ham-copy-or-move-routine): respect + spam-disable-spam-split-during-ham-respool. From + lorentey@elte.hu (L,Bu(Brentey K,Ba(Broly) + (spam-split-disabled): new variable. From + lorentey@elte.hu (L,Bu(Brentey K,Ba(Broly) + (spam-split): respect spam-split-disabled. From + lorentey@elte.hu (L,Bu(Brentey K,Ba(Broly) + +2003-12-10 Katsumi Yamaoka + + * nnheaderxm.el (nnheader-xmas-run-at-time): Make it work + correctly for the first argument. + + * pgg.el (pgg-run-at-time): New function. + (pgg-add-passphrase-cache): Use it. + +2003-12-10 Simon Josefsson + + * pgg-parse.el (pgg-decode-packets): Rewrite to handle corrupt + input. + (pgg-decode-armor-region): Don't parse packet if decoding fail. + +2003-12-09 Teodor Zlatanov + + * spam.el (spam-check-bogofilter): run in the correct buffer. + From lorentey@elte.hu (L,Bu(Brentey K,Ba(Broly). + (spam-bogofilter-database-directory): correct customization + group. From Xavier Maillard . + +2003-12-09 Per Abrahamsen + + * nnmail.el (nnmail-lazy, nnmail-split-fancy): New widgets. + (nnmail-split-fancy): Use it. + +2003-12-08 Joel Ray Holveck (tiny change) + + * gnus-sum.el (gnus-summary-save-parts-1): Consider the "name" + parameter of Content-Type. + +2003-12-08 Katsumi Yamaoka + + * gnus-util.el: Revert 2003-12-03 change, instead, provide the + compiler macro for rmail-select-summary if rmail is not available, + and bind rmail-summary-displayed and rmail-maybe-display-summary + in order to silence the compiler even if tm is not available. + +2003-12-08 Simon Josefsson + + * flow-fill.el (fill-flowed-encode-tests, fill-flowed-test): Add. + +2003-12-08 Jesper Harder + + * gnus-msg.el (gnus-extended-version): Bind float-output-format to + nil. + +2003-12-08 Simon Josefsson + + * mml-smime.el (mml-smime-sign): Replace CRLF with LF in OpenSSL + output. Reported by Arne J,Ax(Brgensen . + +2003-12-07 Simon Josefsson + + * pgg-gpg.el (pgg-gpg-recipient-arg): Add. + (pgg-gpg-encrypt-region): Use it. Tiny patch from Lloyd Zusman + . + (pgg-gpg-recipient-argument): Doc fix. Renamed fro p-g-r-a. + (pgg-gpg-encrypt-region): Update. + +2003-12-07 Jesper Harder + + * spam.el (spam-check-spamoracle, spam-spamoracle-learn): Don't + use = or zerop to test the return value of call-process, because + it can be a string. + + * mail-source.el (mail-source-fetch-with-program): do. + + * mailcap.el (mailcap-viewer-passes-test): do. + + * gnus-uu.el (gnus-uu-treat-archive, gnus-uu-post-encode-mime) + (gnus-uu-post-encode-file): do. + + * gnus-soup.el (gnus-soup-pack, gnus-soup-unpack-packet): do. + + * message.el (message-fix-before-sending): Fix detection of + non-printables. Don't replace unencodable utf-8. + +2003-12-05 Jesper Harder + + * mm-url.el (mm-url-predefined-programs): Add user-agent for wget. + (mm-url-insert-file-contents-external): Signal an error if program + fails. + +2003-12-04 Teodor Zlatanov + + * spam-report.el (spam-report-gmane): iterate over articles + instead of a single one; remove interactive usage + +2003-12-03 Katsumi Yamaoka + + * dns.el: Fix misplaced eval-when-compile. + + * gnus-util.el: Require alist and provide tm-view when compiling + with XEmacs. + +2003-12-03 Steve Youngs + + * gnus-xmas.el: Add autoloads for macros defined in gnus.el. + From Jerry James . + + * gnus-util.el: Get rmail definitions when compiling. + From Jerry James . + + * dns.el: Require gnus-xmas at compile time instead of trying to + autoload `gnus-xmas-open-network-stream' because it wasn't picking + up the macro. + From Jerry James . + +2003-12-01 Kevin Greiner + * gnus-agent.el (gnus-agent-consider-all-articles): Updated + docstring. + (gnus-predicate-implies-unread, gnus-predicate-implies-unread-1): + Fixed implementation such that the predicate `true' no longer + evaluates to t. + +2003-12-01 Teodor Zlatanov + + * spam.el (spam-check-bogofilter): check the bogofilter headers + AFTER the save-excursion scope is over. From Adrian Lanz + . + (spam-fetch-field-message-id-fast): doc fix + +2003-12-01 Simon Josefsson + + * gnus-agent.el (gnus-agent-expire-days): Doc fix. + +2003-11-30 Simon Josefsson + + * gnus-agent.el (gnus-agent-expire-group-1): Bind message-log-max + when messaging "X % completed" to inhibit logging them to the + message buffer. + (gnus-agent-expire-group-1): Mention group name in messages. + (gnus-agent-expire-group-1): Only print a message for an article + when there actually was something done to it. + + * mm-util.el (mm-enable-multibyte): Call set-buffer-multibyte with + 'to argument. Fixes something or other in Emacs 22, and is + backwards compatible. From Kenichi Handa . + + * gnus-agent.el (gnus-agent-expire-unagentized-dirs): Custom fix. + +2003-11-30 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-covered-methods): Remove nil methods. + +2003-11-29 Kevin Greiner + * gnus-start.el (gnus-activate-group): The active range of the + group must include the articles known to the agent. + + * gnus.el (gnus-agent-method-p): Accept a server name as the + method being tested. + +2003-11-29 Alexander Kreuzer (tiny change) + + * nnrss.el (nnrss-check-group): Set xml when nnrss-use-local is t. + +2003-11-29 Jesper Harder + + * gnus-group.el (gnus-group-make-menu-bar): Add + gnus-group-make-rss-group. + +2003-11-28 Reiner Steib + + * message.el: Added custom-manual links to all variables that have + an index entry in the message manual. + (message-generate-headers-first): Fixed doc-string. + +2003-11-27 Katsumi Yamaoka + + * gnus-msg.el (gnus-summary-yank-message): Don't bind + gnus-display-mime-function to nil so that non-ascii text is + decoded and attachments are not shown. + + * message.el (message-cite-original-without-signature): Replace + the value of message-reply-headers with the yanked article since + it may be a different article from the original. + (message-cite-original): Ditto. + +2003-11-25 Teodor Zlatanov + + * spam.el (spam-blacklist-ignored-regexes): new variable, so + blacklisting can ignore certain regular expressions (e.g. the + user's e-mail address) + (spam-bogofilter-spam-strong-switch, + spam-bogofilter-ham-strong-switch): options used when articles are + already registered as the opposite classification + (spam-old-ham-articles, spam-old-spam-articles): lists of ham and + spam articles, generated when a summary buffer is entered, and + consulted when it's exited so we know what articles are changing + state from spam to ham or vice-versa + (spam-xor): everyone needs a little convenience + (spam-list-of-processors): lookup table for old-style spam/ham + exits processors + (spam-group-processor-p): support old-style and new-style spam/ham + exit processors + (spam-group-processor-multiple-p): handle new-style spam/ham exit + processors + (spam-summary-prepare): use spam-old-{ham,spam}-articles; change + logic to iterate over list of processors instead of manual + individual lookup, unregister any articles that change from ham to + spam or vice-versa in the course of the summary buffer usage; use + the new spam-register-routine + (spam-ham-copy-routine, spam-ham-move-routine, + spam-mark-spam-as-expired-and-move-routine): check that the list + of groups is not nil, because apply doesn't like to apply a + function across nil + (spam-registration-functions): variable for looking up spam/ham + registration/unregistration functions based on a spam-use-* symbol + (spam-classification-valid-p, spam-process-type-valid-p) + (spam-registration-check-valid-p) + (spam-unregistration-check-valid-p): convenience functions + (spam-registration-function, spam-unregistration-function): look + up the registration/unregistration function based on a + classification and the check (spam-use-* symbol) + (spam-list-articles): generate list of spam/ham articles from a + given list of articles + (spam-register-routine): do the heavy work of registering and + unregistering articles, using all the articles in the group or + specific ones as needed + (spam-generic-register-routine): removed, no longer used + (spam-log-unregistration-needed-p, spam-log-undo-registration): + handle article registration/unregistration with a given spam/ham + processor and group + (BBDB, ifile, spam-stat, blacklists, whitelists, spam-report, + bogofilter, spamoracle): rewrite registration/unregistration + functions to take a list of articles and the unregister option. + Much hilarity ensues. + (spam-initialize): spam-stat-maybe-{save,load} already respect spam-use-stat + (spam-stat-register-ham-routine, spam-stat-register-spam-routine): + don't load and save unnecessarily + + * spam-stat.el (spam-stat-dirty): new variable, set when the stats + database is modified + (spam-stat-buffer-is-spam, spam-stat-buffer-is-non-spam) + (spam-stat-buffer-change-to-spam, spam-stat-to-hash-table) + (spam-stat-buffer-change-to-non-spam): set spam-stat-dirty when + needed + (spam-stat-save): respect spam-stat-dirty, unless the force + parameter is specified + (spam-stat-load): clear spam-stat-dirty + + * gnus.el (gnus-install-group-spam-parameters): marked the + old-style exit processors as obsolete in the docs, added the + new-style exit processors while the old ones are still allowed + + +2003-11-25 Jesper Harder + + * gnus-art.el (article-hide-boring-headers): Don't hide Reply-To + unless its list of addresses is identical to From. + +2003-11-25 Katsumi Yamaoka + + * dgnushack.el (mapc): Add the compiler macro for Emacs 20. + +2003-11-24 Kevin Greiner + * gnus-srvr.el (gnus-server-insert-server-line): The server names + used in gnus-agent are different (for example, the native server + uses the alias "native") from the names in gnus-srvr. + Compensating by adding a second text property storing the name + expected by gnus-agent. + (gnus-server-named-server): New function. + * gnus-agent.el (gnus-agent-remove-server, gnus-agent-add-server): + No longer expect an argument as it was ignored anyway. Uses the + new gnus-server-named-server function to get gnus-agent compatible + names from the server buffer. + +2003-11-20 Kevin Greiner + + * gnus.el (gnus-agent-covered-methods): Documented use of + named servers, not methods, to identity agentized groups. + Users may now change their server configurations without having + the server become "unagentized". + (gnus-agent-covered-methods): Removed from gnus-variable-list to + avoid storing two copies of gnus-agent-covered-methods, one in + .newsrc.eld and the other in agent/lib/servers. + (gnus-server-to-method): Do not cache server for the nil method. + (gnus-method-to-server): New function. Associate named server + with all, even foreign, methods. + (gnus-agent-method-p, gnus-agent-method-p-cache): Incorporated + simple last-response cache to offset performance lose of having to + always convert methods to named servers. + * gnus-agent.el (gnus-agent-expire-days): Removed obsolete + documentation. + (gnus-agentize, gnus-agent-add-server, gnus-agent-remove-server): + Modified to support new definition of gnus-agent-covered-method. + (gnus-agent-read-servers): Rewritten to convert old method data + into server names. + (gnus-agent-read-servers-validate) + (gnus-agent-read-servers-validate-native): New functions. + (gnus-agent-write-servers): No longer use gnus-method-simplify as + it failed to simplify foreign methods. + (gnus-agent-close-connections, gnus-agent-synchronize-flags) + (gnus-agent-possibly-synchronize-flags, gnus-agent-fetch-session) + (gnus-agent-regenerate): Uses new gnus-agent-covered-methods + function as gnus-agent-covered-methods variable no longer provides + methods. + (gnus-agent-covered-methods): New function + (gnus-agent-expire-group, gnus-agent-expire): Final message will, + if gnus-verbose is greater than 4, report statistics of NOV + entries and files deleted as well as total bytes recovered. + (gnus-agent-expire-done-message): New function + (gnus-agent-unread-articles): Bug fix. No longer drops last + unread article onto read list. + (gnus-agent-regenerate-group): Changed prompt to use typical + style. + (gnus-agent-group-covered-p): Rewrote to internally use + gnus-agent-method-p. + * gnus-int.el (gnus-start-news-server): Partially convert old + gnus-agent-covered-methods to new format so that gnus-open-server + functions correctly. + * gnus-srvr.el (gnus-server-insert-server-line): Replaced + gnus-agent-covered-methods with gnus-agent-method-p. + * gnus-start.el (gnus-clear-system): Added + gnus-agent-covered-methods to compensate for removing it from + gnus-variable-list. + (gnus-setup-news): Complete conversion of old + gnus-agent-covered-methods to new format so that secondary and + foreign servers can be correctly opened. + +2003-11-20 Teodor Zlatanov + + * spam.el (spam-ham-copy-or-move-routine): add respooling + support, not working well yet + + * gnus.el (ham-process-destination): make 'respool option the + only one, so it can't be chosen together with other groups + +2003-11-19 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-track-extra): make it a set of + choices instead of a boolean + (gnus-registry-track-subject-p, gnus-registry-track-sender-p): + new convenience functions + (gnus-registry-split-fancy-with-parent): use convenience + functions, also don't return extra tracking info if sender or + subject is found in more than one groups + (gnus-registry-add-group): use new convenience functions to + decide if sender and subject should be tracked + + * gnus.el (ham-process-destination): add 'respool option, + unused by spam.el yet + +2003-11-19 Katsumi Yamaoka + + * gnus-score.el (gnus-decay-score): Return a surely smaller value + than the argument in XEmacs. + +2003-11-18 Reiner Steib + + * message.el (message-insert-to): Don't use `gnus-message'. + (message-header-synonyms): New variable. + (message-carefully-insert-headers): Use it (check for synonyms). + Added doc-string. From Sam Steingold . + +2003-11-17 Lars Magne Ingebrigtsen + + * html2text.el (html2text-remove-tags): Remove the tag in a + simpler way to avoid inflooping. + +2003-11-17 Simon Josefsson + + * imap.el (imap-gssapi-auth-p): Don't check capability (some + servers remove AUTH=GSSAPI from capability response returned after + successful authentication). + +2003-11-16 Jesper Harder + + * gnus.el (gnus-getenv-nntpserver): Fix regexp and simplify. + Reported by Artem Chuprina . + +2003-11-14 Simon Josefsson + + * mm-util.el (mm-charset-synonym-alist): Map BIG5-HKSCS to BIG5 + when it isn't available. + +2003-11-13 Alex Schroeder + + * nnrss.el (nnrss-check-group): Use dc:contributor if neither + rss:author nor dc:creator is provided. + +2003-11-13 Katsumi Yamaoka + + * mm-decode.el (mm-dissect-buffer): Save start="" value + contained in Content-Type header of multipart/related messages. + + * mm-view.el (mm-w3m-cid-retrieve-1): New function. + (mm-w3m-cid-retrieve): Use it. + + * mml.el (mml-generate-mime-1): Add start="" to Content-Type. + (mml-insert-mime-headers): Insert Content-ID header. + (mml-insert-mml-markup): Insert start="" value. + +2003-11-12 Teodor Zlatanov + + * nnml.el (nnml-request-accept-article): pass sender to + nnmail-cache-insert + + * nnmh.el (nnmh-request-accept-article): pass sender to + nnmail-cache-insert + + * nnmbox.el (nnmbox-request-accept-article): pass sender to + nnmail-cache-insert + + * nnfolder.el (nnfolder-request-accept-article): pass sender to + nnmail-cache-insert + + * nnbabyl.el (nnbabyl-request-accept-article): pass sender to + nnmail-cache-insert + + * nnmail.el (nnmail-cache-insert): accept sender parameter and + pass it to the nnmail-spool-hook + + * gnus-registry.el (gnus-registry-track-extra): clarify doc + (gnus-registry-action): add sender lexical var and pass it to + gnus-registry-add-group + (gnus-registry-spool-action): take a sender parameter, pass to + gnus-registry-add-group + (gnus-registry-split-fancy-with-parent): trace by sender in + addition to subject + (gnus-registry-fetch-sender-fast): new function + (gnus-registry-add-group): accept sender parameter + +2003-11-11 Teodor Zlatanov + + * spam.el (spam-ham-copy-routine, spam-ham-move-routine) + (spam-mark-spam-as-expired-and-move-routine): allow for the + groups to be a list of a single item + + * gnus.el (gnus-install-group-spam-parameters): + ham-process-destination and spam-process-destination allow lists now + +2003-11-10 Reiner Steib + + * message.el (message-insert-to): Do error out when the user + requested no Cc. Don't insert empty To. Can be added to + `message-setup-hook' now. From Sam Steingold . + (message-mode-field-menu): Moved some entries, added + `message-insert-wide-reply'. + (message-change-subject): Fixed comment. + +2003-11-10 Simon Josefsson + + * pgg-def.el (pgg-encrypt-for-me): Change default from nil to t. + +2003-11-09 Simon Josefsson + + * pgg-gpg.el (pgg-gpg-encrypt-region): Cache passphrase under hex + key id too (for decryption). + (pgg-gpg-sign-region): Likewise. + +2003-11-09 Simon Josefsson + + * pgg-gpg.el (pgg-gpg-all-secret-keys): New variable. + (pgg-gpg-lookup-all-secret-keys): New function. + (pgg-gpg-select-matching-key): Likewise. + (pgg-gpg-decrypt-region): Use new functions. From Satyaki Das + . + +2003-11-07 Teodor Zlatanov + + * nnmail.el (nnmail-cache-insert): make sure that the + nnmail-spool-hook is called with a valid newsgroup name (though + it may be wrong) + + * gnus.el (gnus-group-real-prefix): return nil if group is not a + string, instead of triggering an error + +2003-11-06 Teodor Zlatanov + + * gnus.el (gnus-group-guess-full-name-from-command-method): new function + + * gnus-registry.el (gnus-registry-fetch-group): use long names if + requested + (gnus-registry-split-fancy-with-parent): when long names are in + use, strip the name if we're in the native server, or else return nothing + (gnus-registry-spool-action, gnus-registry-action): use + gnus-group-guess-full-name-from-command-method instead of + gnus-group-guess-full-name + + * spam.el (spam-mark-spam-as-expired-and-move-routine) + (spam-ham-copy-or-move-routine): prevent article deletions or + moves unless the backend allows it + + * gnus.el (gnus-install-group-spam-parameters): fixed parameters + to list spamoracle as well, suggested by Jean-Marc Lasgouttes + + + * spam.el (spam-spamoracle): doc change, suggested by Jean-Marc + Lasgouttes + +2003-11-04 Katsumi Yamaoka + + * gnus-score.el (gnus-decay-score): Protect against arithmetic + errors. Tiny patch from Norbert Koch . + +2003-10-31 Teodor Zlatanov + + * spam.el + (spam-log-processing-to-registry): improved message and comments + (spam-log-unregistration-needed-p): new function + (spam-ifile-register-spam-routine) + (spam-ifile-register-ham-routine, spam-stat-register-spam-routine) + (spam-stat-register-ham-routine) + (spam-blacklist-register-routine) + (spam-whitelist-register-routine) + (spam-bogofilter-register-spam-routine) + (spam-bogofilter-register-ham-routine) + (spam-spamoracle-learn-ham, spam-spamoracle-learn-spam): change + spam-log-processing-to-registry invocations appropriately + +2003-10-31 Simon Josefsson + + * imap.el (imap-kerberos4-open): Ignore output from ATHENA imtest. + Tiny patch from Derek Atkins . + (imap-process-connection-type): Improve docstring. Suggested by + Derek Atkins . + +2003-10-31 Teodor Zlatanov + + * spam.el (autoload): autoload the gnus-registry functions we'll + need + (spam-log-to-registry): new variable for interfacing with the + gnus-registry + (spam-install-hooks): variable had the wrong customization group + (spam-fetch-field-message-id-fast): convenience function for fetch + a message ID quickly + (spam-log-processing-to-registry): new function + (spam-ifile-register-spam-routine) + (spam-ifile-register-ham-routine, spam-stat-register-spam-routine) + (spam-stat-register-ham-routine) + (spam-blacklist-register-routine) + (spam-whitelist-register-routine) + (spam-bogofilter-register-spam-routine) + (spam-bogofilter-register-ham-routine) + (spam-spamoracle-learn-ham, spam-spamoracle-learn-spam): add + spam-log-processing-to-registry invocations + + * gnus-registry.el: fixed docs in the preface to mention + gnus-registry-initialize + (gnus-registry-store-extra): remove cached extra entry + information when new extra entry is stored + +2003-10-29 Simon Josefsson + + * message.el (message-forward-make-body-plain): Fix ARG=1 mode + after separating m-f-m-b. + +2003-10-29 Simon Josefsson + + * message.el (message-forward-make-body-plain): Remove ignored + headers. Tiny patch from Andre Srinivasan . + (message-forward-make-body-plain): Fix ARG=1. + +2003-10-28 Jesper Harder + + * message.el (message-forward-subject-name-subject) + (message-forward-subject-author-subject): Decode non-ASCII + newsgroup names. + (autoload): Autoload gnus-group-decoded-name. + +2003-10-27 Simon Josefsson + + * pgg-gpg.el (pgg-gpg-possibly-cache-passphrase): New optional + parameter key, overrides the key id used to store passphrase + under (uses true key id from gpg output if nil). + (pgg-gpg-encrypt-region): Search for passphrase using user suplied + string STR, instead of (pgg-lookup-key STR t). + (pgg-gpg-encrypt-region): Store passphrase under user suplied + string, instead of real key id taken from gpg output. + (pgg-gpg-decrypt-region): Likewise. + (pgg-gpg-sign-region): Likewise. + * pgg.el (pgg-decrypt-region): Don't set pgg-default-user-id. + +2003-10-27 Romain FRANCOISE + + * gnus-art.el (gnus-article-goto-prev-page): Doc fix. + +2003-10-27 Simon Josefsson + + * mm-bodies.el (mm-body-encoding): Don't use QP when message body + only consists of short lines and ASCII, when + mm-use-ultra-safe-encoding. Refer to 'About foo' thread in + gnus-bug, e.g. , for more discussion. + This make it possible to pipe the raw RFC 822 message into 'gpg' + and have the signature work. Potential problem: what if message + contain data that would be dash-escaped by OpenPGP + implementations? Then PGP 2.x might not be able to parse the raw + RFC 822 message correctly. If that problem is worth fixing, it + should be fixed by detecting the situation, instead of applying QP + to everything. Based on discussion with "John A. Martin" + . + +2003-10-27 Teodor Zlatanov + + * spam.el (spam-mark-spam-as-expired-and-move-routine) + (spam-ham-copy-or-move-routine): don't ask when deleting copied + articles, and use move instead of copy when possible + (spam-split): added the option of specifying a string as a + spam-split parameter; such a string will override + spam-split-group temporarily. + + * nnmail.el (nnmail-cache-insert): protect from nil message IDs, + but should we do something else? + + * gnus-registry.el (gnus-registry-spool-action): protect from nil + message IDs + +2003-10-26 Simon Josefsson + + * gnus-art.el (gnus-button-alist): Allow & in mailto URLs. + (gnus-header-button-alist): Likewise. + (gnus-url-mailto): Handle ?to parameters. Replace \r\n with \n. + Reverse parameter list to use same order as in the URL. Reported + by f95-msv@f.kth.se (M,Ae(Brten Svantesson). + +2003-10-25 Teodor Zlatanov + + * spam.el (spam-move-spam-nonspam-groups-only): documentation fix + for the variable + +2003-10-25 Steve Youngs + + * Makefile.in (clean-some): Remove auto-autoloads.* and + custom-load.* as well. + (distclean): Ditto. + + * dgnushack.el (dgnushack-make-load): Add a local vars section to + the dummy gnus-load.el. + +2003-10-24 Teodor Zlatanov + + * spam.el (spam-ham-copy-or-move-routine): do not delete if copy + is t, also don't intepret the list of groups as a list of lists + (spam-mark-spam-as-expired-and-move-routine) + (spam-ham-copy-or-move-routine): delete articles only if 1 or + more groups were specified (and "copy" was not specified for + spam-ham-copy-or-move-routine) (fixed twice) + +2003-10-24 Katsumi Yamaoka + + * nndoc.el (nndoc-guess-type): Reverse the sort order. Suggested + by ARISAWA Akihiro . + (nndoc-dissect-buffer): Don't miss even-numbered articles. + +2003-10-24 Steve Youngs + + * dgnushack.el (dgnushack-gnus-load-file): Set to + "auto-autoloads.el" if building with XEmacs. + (dgnushack-cus-load-file): Set to "custom-load.el" if building + with XEmacs. + (dgnushack-make-cus-load): We don't delete the resulting file if + building with XEmacs so byte-compile it. + (dgnushack-make-load): When building with XEmacs do nothing except + byte-compile the autoload file and create a dummy gnus-load.el + file. + +2003-10-23 Katsumi Yamaoka + + * message.el (message-make-fqdn): Bind case-fold-search. + Suggested by Christopher Richards . + +2003-10-23 Teodor Zlatanov + + * gnus.el (spam-process-destination, ham-process-destination): + allow multiple groups as a choice + + * spam.el (spam-check-blackholes): remove "[IP address]" + requirement, now just "IP address" is enough for detection for + blackhole checking + (spam-check-blackholes): oops, the dots were not escaped + (spam-mark-spam-as-expired-and-move-routine): added multiple group + support (multiple copies, then delete) + (spam-ham-copy-routine): new function + (spam-ham-move-routine): new function + (spam-ham-copy-or-move-routine): new function (used to be + spam-ham-move-routine), handle multiple groups + (spam-summary-prepare-exit): call the new functions + +2003-10-23 Simon Josefsson + + * flow-fill.el (fill-flowed-encode, fill-flowed): Autoload. + +2003-10-22 Katsumi Yamaoka + + * gnus-art.el (gnus-emphasis-strikethru): Use the :strike-through + attribute in Emacs. + +2003-10-21 Katsumi Yamaoka + + * message.el (message-bounce): Don't erase except bounced header. + +2003-10-21 Teodor Zlatanov + + * spam.el (spam-reverse-ip-string): new function to reverse an IP + address in a string + (spam-check-blackholes): use spam-reverse-ip-string + +2003-10-21 Katsumi Yamaoka + + * gnus-art.el (gnus-narrow-to-page): Clear as well as set the + value for gnus-page-broken. + + * gnus-sum.el (gnus-summary-beginning-of-article): Use + gnus-break-pages instead of gnus-page-broken. + (gnus-summary-end-of-article): Use gnus-break-pages instead of + gnus-page-broken; narrow to the end of a page beforehand. + (gnus-summary-toggle-header): Use gnus-break-pages instead of + gnus-page-broken; remove delimiter buttons unless gnus-break-pages + is non-nil. + +2003-10-21 Lars Magne Ingebrigtsen + + * gnus-picon.el (gnus-picon-transform-address): Protect against + errors. + +2003-10-20 Katsumi Yamaoka + + * gnus-msg.el (nnspool-rejected-article-hook): Remove defvar. + (xemacs-codename): Move defvar to gnus-util.el. + + * gnus-util.el (xemacs-codename): Defvar when compiling. + +2003-10-20 Lars Magne Ingebrigtsen + + * spam-report.el (spam-report-url-ping-plain): Include a + User-Agent. + + * gnus-msg.el (gnus-extended-version): Use it. + + * gnus-util.el (gnus-emacs-version): Separated out into own + function. + +2003-10-19 Reiner Steib + + * message.el (message-mode-field-menu): Added + message-generate-unsubscribed-mail-followup-to. + (message-forward-subject-fwd): Avoid double "Fwd: " + (message-change-subject): Added comment. + +2003-10-19 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-nov-parse-line): Remove condition-cases. + + * mml.el (mml-insert-mime): Quote mml. + +2003-10-19 Katsumi Yamaoka + + * gnus-sum.el (gnus-remove-odd-characters): Use + mm-subst-char-in-string instead of subst-char-in-string. + (gnus-summary-refer-article): Use gnus-replace-in-string instead + of replace-regexp-in-string. + +2003-10-19 Jesper Harder + + * gnus-uu.el (gnus-uu-uustrip-article): Really strip directory + from file name. + +2003-10-18 Jesper Harder + + * gnus-sum.el (gnus-summary-save-parts-last-directory): Default + to mm-default-directory. + (gnus-summary-save-parts-1): Use mm-file-name-rewrite-functions. + +2003-10-18 Lars Magne Ingebrigtsen + + * pop3.el (pop3-read-response): Check whether the process is + alive. + + * gnus-sum.el (gnus-summary-refer-article): Strip spaces. + + * rfc2047.el (rfc2047-encode-region): Do error out on invalid + strings. + + * nntp.el (nntp-retrieve-headers-with-xover): Get error messages + right. + + * gnus-agent.el (gnus-agent-read-servers): Remove sit-for. + + * gnus-art.el (article-treat-dumbquotes): Doc fix. + + * message.el (message-field-value): New function. + (message-insert-disposition-notification-to): Use Reply-To, too. + + * imap.el (imap-mailbox-status): Upcase STATUS commands. + + * gnus-sum.el (gnus-remove-odd-characters): New function. + (gnus-nov-parse-line): Use it. + +2003-10-18 Matt Swift + + * mm-decode.el (mm-inline-media-tests): Recognize pjpeg as jpeg. + +2003-10-18 Romain FRANCOISE + + * message.el (message-forward-make-body): does both + m-f-make-body-mml and m-f-make-body-plain, resulting in a strange + message buffer. + +2003-10-18 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-narrow-to-page): Only break page if it's + broken. + + * nnrss.el (nnrss-find-rss-via-syndic8): Return nil if xml-rpc + isn't available. + + * message.el (message-hidden-headers): Doc fix. + +2003-10-18 Jesper Harder + + * gnus-msg.el (gnus-summary-resend-message-edit): Avoid error when + fields aren't found. + +2003-10-18 Simon Josefsson + + * message.el (message-forward-make-body-plain) + (message-forward-make-body-mime, message-forward-make-body-mml) + (message-forward-make-body-digest-plain) + (message-forward-make-body-digest-mime) + (message-forward-make-body-digest): New, derived from + message-forward-make-body. + (message-forward-make-body): Use them. + (message-forward-show-mml): New default 'best. + (message-forward-make-body): Support it. + +2003-10-18 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-mode): Set gnus-page-broken to nil. + (gnus-article-prepare): Don't set to t. + (gnus-narrow-to-page): Set to t if we break. + +2003-06-11 Daniel N,Ai(Bri + + * message.el (message-resend): Generate Resent-Message-ID header. + +2003-10-18 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-next-page): Don't go to the next line + before checking end-of-buffer. + (gnus-mime-delete-part): Don't insert parts twice. + +2003-10-17 Lars Magne Ingebrigtsen + + * gnus-art.el (article-update-date-lapsed): Make sure point + doesn't move around (much). + +2003-07-28 Vasily Korytov + + * mail-source.el (mail-source-keyword-map): List "cur" before + "new" for maildirs. + +2003-10-17 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-enter-digest-group): ogroup, nor + group. + + * gnus-msg.el (gnus-inews-insert-archive-gcc): Use the parent + name for gcc-self. + (gnus-inews-insert-archive-gcc): Paren mistake. + + * gnus-sum.el (gnus-summary-enter-digest-group): Add + parent-group. + + * gnus-art.el (gnus-ignored-headers): Add more headers. + + * rfc2047.el (rfc2047-encode): See which encoding is shorter -- + base64 or QP. + + * nnmail.el (nnmail-article-group): Default to "bogus". + + * mail-source.el (mail-source-delete-incoming): Change to nil. + +2003-10-16 Katsumi Yamaoka + + * mail-source.el (mail-source-fetch-imap): Fix mismatched parens. + +2003-10-16 Lars Magne Ingebrigtsen + + * mail-source.el (defvar): Add post/pre/scripts. + (mail-source-fetch-imap): Use them. + + * nndraft.el (nndraft-request-move-article): Fix infinite + recursion. + + * gnus-group.el (gnus-group-mark-regexp): Jump to groups. + +2003-10-16 Ed L. Cashin + + * imap.el (imap-interactive-login): Set imap-password to nil if + login fails. + +2003-10-16 Lars Magne Ingebrigtsen + + * message.el (message-inserted-headers): New variable. + (message-mode): Make local. + (message-mode): Set all the local action variables to nil. + +2003-10-16 Katsumi Yamaoka + + * mm-decode.el (mm-inline-text-html-with-images): Doc fix. + (mm-w3m-safe-url-regexp): Doc fix. + +2003-10-12 Jesper Harder + + * gnus-sum.el (gnus-summary-respool-query): Don't narrow to head, + it's done by nnmail-article-group. + + * gnus-uu.el (gnus-uu-grab-articles): Fix misplaced parens. + From Mark Hood (tiny change) + +2003-10-10 Jesper Harder + + * mm-decode.el (mm-file-name-delete-gotchas): Avoid infloop in + XEmacs. + +2003-10-10 Teodor Zlatanov + + * spam.el (spam-initialize): new function, does the spam-face + update and all the hooks, replaces spam-install-hooks-function + + * gnus-registry.el (gnus-registry-initialize): new autoloaded + function to explicitly initialize the registry + +2003-10-10 Katsumi Yamaoka + + * mm-decode.el (mm-w3m-safe-url-regexp): Doc fix. + + * mm-view.el (mm-w3m-mode-map): Doc fix. + (mm-inline-text-html-render-with-w3m): Add a comment. + +2003-10-10 Lars Magne Ingebrigtsen + + * gnus-group.el: Remove superfluous eval-when-compiles. + +2003-10-10 Jesper Harder + + * gnus-group.el (gnus-group-suspend): Reset gnus-backlog-articles. + +2003-10-08 Lars Magne Ingebrigtsen + + * dns.el (query-dns): Don't error out on malformed resolv files. + +2003-10-06 Jesper Harder + + * gnus.el (gnus-group-faq-directory): Update .tw entry. From + Albert Chun-Chieh Huang + +2003-10-03 Teodor Zlatanov + + * spam.el (spam-check-blackholes): exit the loop if matches are + found (idea from Adrian Lanz ) + (spam-check-bogofilter-headers, spam-check-blackholes, spam-check-BBDB) + (spam-from-listed-p): use nnmail-fetch-field instead of message-fetch-field + + +2003-10-03 Katsumi Yamaoka + + * mm-decode.el (mm-attachment-file-modes): Change the default + value into 384 from ?\600 which doesn't mean an integer in XEmacs. + +2003-10-03 Jesper Harder + + * mm-decode.el (mm-file-name-delete-control) + (mm-file-name-delete-gotchas): New functions. + (mm-file-name-rewrite-functions): Use them. + (mm-attachment-file-modes): New option. + (mm-save-part-to-file): Use it. + +2003-10-02 Reiner Steib + + * spam.el (spam-install-hooks-function): Added Autoload cookie. + +2003-10-02 Jesper Harder + + * pgg-def.el (pgg-default-keyserver-address): Change to + subkeys.pgp.net. From Michael Shields + +2003-10-01 Simon Josefsson + + * message.el (message-idna-to-ascii-rhs-1): RHS can be terminated + by ',', as in 'foo@example.org, bar@example.org'. + +2003-10-01 Jesper Harder + + * message.el (message-send): Fix reversed logic of supersedes + check. + +2003-09-30 Reiner Steib + + * gnus-art.el (gnus-article-view-part-as-charset): Doc fix, + suggested by Norbert Koch . + +2003-09-29 Katsumi Yamaoka + + * gnus-topic.el (gnus-topic-goto-missing-topic): Revert 2003-02-09 + change in order to correct the position where an invisible topic + (because gnus-topic-display-empty-topics is nil) may be inserted. + +2003-09-22 Katsumi Yamaoka + + * message.el (message-ignored-supersedes-headers): Add X-Payment. + +2003-09-20 Jesper Harder + + * rfc2047.el (rfc2047-encode): Limit line length to 76 characters. + +2003-09-20 Simon Josefsson + + * tls.el (tls-process-connection-type): Doc fix. + + * imap.el (imap-starttls-open): Rewrite, should support both old + starttls.el and new starttls.el that uses GNUTLS. + +2003-09-18 Katsumi Yamaoka + + * gnus-art.el (gnus-treat-display-x-face): Use set-default instead + of custom-set-default which isn't available in old XEmacsen. + +2003-09-17 Jesper Harder + + * gnus-msg.el (gnus-summary-resend-message-edit): Don't convert + to MML. MIME -> MML -> MIME does not work for PGP/MIME. + + * message.el (message-bounce, message-forward-show-mml): do. + +2003-09-13 Jesper Harder + + * rfc2047.el (rfc2047-charset-encoding-alist): Add viscii. + (rfc2047-encode): Add factors for big5, gb2312 and euc-kr. + + * nnweb.el (nnweb-google-parse-1): Fix parsing. + +2003-09-12 Jesper Harder + + * gnus-group.el (gnus-group-fetch-control): ISC changed + compression from .Z to .gz. + + * rfc2047.el (rfc2047-header-encoding-alist): Add "Approved" to + address-mime. + +2003-09-11 Jesper Harder + + * rfc2047.el (rfc2047-encode): Restrict encoded-words to 75 + characters. + +2003-09-10 Jesper Harder + + * gnus.el (gnus-group-charter-alist): Update. + +2003-09-10 Teodor Zlatanov + + * spam-report.el: use mm-url.el functions for external URL + loading when the built-in HTTP GET is insufficient (e.g. proxies + are in the way). From Eric Knauel + . + (spam-report-url-ping-function): new option, defaults to the + built-in HTTP GET (spam-report-url-ping-plain) + (spam-report-url-ping): calls spam-report-url-ping-function now + (spam-report-url-ping-plain): new function, does what + spam-report-url-ping used to do + (spam-report-url-ping-mm-url): function that delegates to + mm-url.el (autoloaded) + +2003-09-08 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-delete-id): function to + completely delete an ID, including all the cache hashtables + (gnus-registry-delete-group): use gnus-registry-delete-id + (gnus-registry-simplify-subject): only run if the argument is a + string, return nil otherwise + +2003-09-07 Jesper Harder + + * gnus-msg.el (gnus-summary-resend-bounced-mail): Docstring fix. + +2003-09-05 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-split-fancy-with-parent): yet + another error *sigh* + + * gnus-registry.el (gnus-registry-fetch-extra-entry): don't use + puthash unless gnus-registry-entry-caching is on + (gnus-registry-split-fancy-with-parent): misplaced parenthesis + made everything a part of the 'else' + (gnus-registry-save): used 'entry-caching' instead of 'caching' + +2003-09-05 Jesper Harder + + * gnus-art.el (gnus-button-alist): Improve Info regexp. + +2003-09-04 Teodor Zlatanov + + * gnus-registry.el: added brief explanation of basics + (gnus-registry-track-extra): new variable for tracking of message + subjects + (gnus-registry-entry-caching): caching parameter, used for extra + data + (gnus-registry-minimum-subject-length): minimum subject length + before it's considered when tracing subjects + (gnus-registry-save): accomodate extra data entry caching + (gnus-registry-action): change function name, add the subject and + pass it to gnus-registry-add-group + (gnus-registry-spool-action): change function name, add the + subject and pass it to gnus-registry-add-group + (gnus-registry-split-fancy-with-parent): add subject tracking + (gnus-registry-register-message-ids): pass subject to + gnus-registry-add-group + (gnus-registry-simplify-subject) + (gnus-registry-fetch-simplified-message-subject-fast): new + functions + (gnus-registry-fetch-extra, gnus-registry-fetch-extra-entry): add + extra data entry caching + (gnus-registry-add-group): handle the extra subject parameter + (gnus-registry-install-hooks, gnus-registry-unload-hook): fix the + gnus-register-* function names + + * nnmail.el (nnmail-cache-insert): add subject parameter, pass it + on to the nnmail-spool-hook + + * nnbabyl.el (nnbabyl-request-accept-article): added subject to + nnmail-cache-insert call + + * nndiary.el (nndiary-request-accept-article): added subject to + nnmail-cache-insert call + + * nnfolder.el (nnfolder-request-accept-article): added subject to + nnmail-cache-insert call + + * nnimap.el (nnimap-split-articles): added subject to + nnmail-cache-insert call + (nnimap-request-accept-article): added subject to + nnmail-cache-insert call + + * nnmbox.el (nnmbox-request-accept-article): added subject to + nnmail-cache-insert call + + * nnmh.el (nnmh-request-accept-article): added subject to + nnmail-cache-insert call + + * nnml.el (nnml-request-accept-article): added subject to + nnmail-cache-insert call + +2003-09-04 Jesper Harder + + * gnus-art.el (gnus-button-handle-info-url) + (gnus-button-handle-info-url-gnome) + (gnus-button-handle-info-url-kde, gnus-button-alist): Handle GNOME + and KDE style Info URLs. + + * gnus-util.el (gnus-url-unhex-string): Don't replace "+" with " ". + +2003-09-02 Jesper Harder + + * rfc2047.el (rfc2047-fold-region): Don't fold at the beginning + of the field. + +2003-09-01 Simon Josefsson + + * mml.el (mml-insert-mime-headers-always): New variable. + (mml-insert-mime-headers): Use it. Based on (tiny) patch from + Lars Balker Rasmussen . + +2003-08-30 Simon Josefsson + + * mail-source.el (mail-source-fetch-imap): Pass correct buffer to + imap-open, reverts 2003-03-17 change. Reverse remove before + calling gnus-compress-sequence. From Gaute Strokkenes + (tiny change). + +2003-08-29 Simon Josefsson + + * gnus-group.el (gnus-group-delete-group): Doc fix. Suggested by + Jochen K,A|(Bpper . + +2003-08-29 Katsumi Yamaoka + + * gnus-art.el (article-display-x-face): Make it possible to set + the gnus-article-x-face-command variable to the lambda form. + +2003-08-27 Simon Josefsson + + * mm-decode.el (mm-remove-part): Try to kill external displayers + cleanly first (if it refuses, C-g aborts loop and kill process + unconditionally). Also make sure process is dead before we remove + the files it may be using. Reported by David Coe + . + +2003-08-27 Jesper Harder + + * gnus-cache.el (gnus-cache-generate-active): Fix bug in + replacement. From Vagn Johansen (tiny + change). + +2003-08-25 Katsumi Yamaoka + + * gnus-art.el: Don't use defvaralias. + (gnus-treat-display-x-face): Warn if the obsolete variable + `gnus-treat-display-xface' exists. + +2003-08-25 Jesper Harder + + * gnus-art.el (gnus-treat-display-face): Fix typo. + (gnus-treat-display-xface): Rename to gnus-treat-display-x-face + (reported by Jochen K,A|(Bpper ) + +2003-08-24 Jesper Harder + + * gnus-art.el (gnus-header-button-alist, gnus-button-alist): Fix + type. + +2003-08-22 Jesper Harder + + * message.el (message-make-forward-subject-function): Fix + customize mismatch. + + * gnus.el (gnus-message-archive-method): do. + +2003-08-20 Reiner Steib + + * gnus.el (gnus-read-group): Offer to continue only if the invalid + char is `/' and add more information for the user. + + * gnus-art.el (gnus-button-alist): Add `+' (gnus-button-handle-man). + (gnus-header-button-alist): Added `In-Reply-To'. + + * nnimap.el (nnimap-open-connection): Allow different user names + on the same server (and in the same authinfo file). + +2003-08-20 Jesper Harder + + * gnus-sieve.el (gnus-sieve-crosspost): Fix type. + + * message.el (message-make-forward-subject-function): Add + message-forward-subject-name-subject to choices. + + * gnus-art.el (gnus-article-edit-done, gnus-article-edit-exit): + Redisplay article after editing. + +2003-08-20 Simon Josefsson + + * gnus.el (gnus-read-group): Added check to ask confirmation if + Group name contains invalid character. You can use '/' in IMAP, + but not in filenames. G m cannot know what the user is creating, + so let user decide. See thread m2oeysiev3.fsf@naima.lensflare.org. + Tiny patch from letters@hotpop.com (Jari Aalto+mail.linux). + +2003-08-13 Reiner Steib + + * gnus-score.el (gnus-summary-score-effect): Fix interactive use. + +2003-08-10 Teodor Zlatanov + + * gnus-draft.el (gnus-draft-send-all-messages): ask if all drafts + should be sent unless gnus-expert-user is on + +2003-08-09 Jesper Harder + + * pgg-gpg.el (pgg-gpg-extra-args): Fix customization type. + +2003-08-07 Jesper Harder + + * pgg-gpg.el (pgg-gpg-process-region): Bind + default-enable-multibyte-characters to nil. + +2003-08-07 Katsumi Yamaoka + + * canlock.el (canlock-password): Fix customization type. + (canlock-password-for-verify): Ditto. + * deuglify.el (gnus-outlook-deuglify-unwrap-min): Ditto. + (gnus-outlook-deuglify-unwrap-max): Ditto. + (gnus-outlook-deuglify-unwrap-stop-chars): Ditto. + * gnus-sum.el (gnus-sum-thread-tree-root): Ditto. + (gnus-sum-thread-tree-false-root): Ditto. + (gnus-sum-thread-tree-single-indent): Ditto. + * message.el (message-archive-note): Ditto. + (message-subscribed-address-file): Ditto. + (message-user-fqdn): Ditto. + * spam-report.el (spam-report-gmane-regex): Ditto. + * spam.el (spam-blackhole-good-server-regex): Ditto. + + * gnus-start.el (gnus-save-killed-list): Fix last change. + * message.el (message-courtesy-message): Ditto. + +2003-08-07 Jesper Harder + + * gnus-art.el (gnus-header-face-alist): Revert previous change. + (gnus-header-newsgroups-face): Explain that it's only used for + crossposts. + +2003-08-07 Katsumi Yamaoka + + * gnus-registry.el (gnus-registry-max-entries): Fix customization + type. + * gnus-score.el (gnus-adaptive-word-length-limit): Ditto. + * gnus.el (gnus-refer-article-method): Ditto. + * message.el (message-courtesy-message): Ditto. + +2003-08-06 Jesper Harder + + * gnus-art.el (gnus-header-face-alist): Fix "Newsgroups" entry. + From Chunyu Wang (tiny patch) + +2003-08-05 Katsumi Yamaoka + + * gnus-start.el (gnus-save-killed-list): Fix customization type. + * gnus-sum.el (gnus-thread-hide-subtree): Ditto. + * gnus.el (gnus-use-long-file-name): Ditto. + +2003-08-04 Jesper Harder + + * gnus-group.el (gnus-group-rename-group): Don't allow renaming to + an existing name. + + * gnus-sum.el (gnus-summary-highlight): Add uncached to docstring. + + * nnmail.el (nnmail-large-newsgroup): Docstring fix. + + * nntp.el (nntp-large-newsgroup): do. + + * nnspool.el (nnspool-large-newsgroup): do. + + * gnus-cus.el (gnus-group-parameters): Typo. + +2003-07-31 Simon Josefsson + + * mml-sec.el (mml-signencrypt-style-alist): Use separate S/MIME + method by default (revert partial 2003-07-10 patch). + +2003-07-28 Dave Love + + * pgg-gpg.el, pgg-pgp.el, pgg-pgp5.el: Require cl when compiling. + +2003-07-26 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-install): add an initial + registry read to the loading when gnus-registry-install is set + +2003-07-26 Kai Gro,A_(Bjohann + + * flow-fill.el (fill-flowed): Empty lines separate paragraphs + even if the preceding line ends with a soft break. Tiny patch + from Mark Thomas . + +2003-07-25 Teodor Zlatanov + + * spam.el (spam-use-regex-body, spam-regex-body-spam) + (spam-regex-body-ham): new variables, default to nil/empty/empty + (spam-install-hooks): added spam-use-regex-body to list or + pre-install conditions + (spam-list-of-checks): added spam-use-regex-body and + spam-check-regex-body to list of checks + (spam-list-of-statistical-checks): added spam-use-regex-body to + list of statistical checks + (spam-check-regex-body): invokes spam-check-regex-headers with + appropriate variable masking + (spam-check-regex-headers): changes to print "body" or "header" + where appropriate + +2003-07-25 Jesper Harder + + * smime.el (smime-ask-passphrase): Use read-passwd rather than + comint-read-noecho. The former is more secure. + +2003-07-24 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-cache-whitespace): make "adding + whitespace" message level 5 instead of 4 + (gnus-registry-clean-empty-function): new function to remove empty + registry entries + (gnus-registry-clean-empty): new variable to enable cleaning the + registry when saving it by calling gnus-registry-clean-empty-function + + * spam.el (spam-summary-prepare-exit): use spam-process-ham-in-spam-groups + (spam-process-ham-in-spam-groups): new variable + +2003-07-24 Jesper Harder + + * pgg-gpg.el (pgg-gpg-process-region): Add "--yes" to options. + + * pgg-gpg.el, pgg-pgp.el, pgg-pgp5.el, pgg.el: Reapply changes + from 2003-04-03 to fix security problem. See + http://www.debian.org/security/2003/dsa-339 + +2003-07-23 Teodor Zlatanov + + * gnus.el (gnus-install-group-spam-parameters): add the + gnus-ticked-mark to the possible choices of ham marks + + * spam.el (spam-process-ham-in-nonham-groups): new variable + (spam-summary-prepare-exit): use spam-process-ham-in-nonham-groups + +2003-07-23 Jesper Harder + + * rfc2047.el (rfc2047-header-encoding-alist): Add Mail-Followup-To + and Mail-Copies-To to address-mime. + (rfc2047-narrow-to-field): Use rfc2047-point-at-bol. + +2003-07-19 Jesper Harder + + * mm-util.el (mm-coding-system-priorities): Docstring improvement. + +2003-07-17 Jesper Harder + + * gnus-sum.el (gnus-thread-latest-date): Move condition-case to + the right place. + +2003-07-14 Simon Josefsson + + * mail-source.el (mail-source-fetch-imap): Don't assume + imap-error-text returns something. + +2003-07-12 Nevin Kapur + + * nnimap.el (nnimap-request-newgroups): Use the pattern in + nnimap-list-pattern instead of "*". + +2003-07-10 Simon Josefsson + + * mml-sec.el (mml-signencrypt-style-alist): Use "combined" by + default. Improve docstring. + +2003-07-10 Kai Gro,A_(Bjohann + + * imap.el (imap-arrival-filter): Fix test for missing process + buffer. + +2003-07-09 Kai Gro,A_(Bjohann + From Gaute B Strokkenes (tiny patch). + + * imap.el (imap-wait-for-tag): Clarify comment. Use timeout zero + for second, after-process-has-died, accept-process-output. + (imap-arrival-filter): If PROC has no buffer, do nothing. + +2003-07-09 Jesper Harder + + * flow-fill.el: Docstring and message fixes. + + * deuglify.el: do. + + * gnus-int.el: do. + + * gnus-msg.el: do. + + * gnus-util.el: do. + + * gnus-draft.el: do. + + * gnus-start.el: do. + + * gnus.el: do. + + * gnus-group.el: do. + + * gnus-art.el: do. + + * gnus-sum.el: do. + + * mail-source.el (mail-source-movemail): Handle non-numerical + return values. + +2003-07-08 Jesper Harder + + * mailcap.el (mailcap-parse-args-syntax-table) + (mailcap-viewer-passes-test): Docstring fix. + + * mm-bodies.el (mm-long-lines-p): Docstring fix. + + * mm-decode.el (mm-w3m-safe-url-regexp, mm-verify-option) + (mm-decrypt-option, mm-handle-set-external-undisplayer) + (mm-file-name-replace-whitespace): Docstring fix. + + * mm-uu.el (mm-uu-emacs-sources-regexp): Docstring fix. + (mm-uu-pgp-signed-test): Fix message. + + * mml.el (mml-tweak-sexp-alist): Docstring fix. + (mml-parse-1, mml-insert-mime-headers): Fix message. + + * message.el (message-archive-header) + (message-subscribed-address-functions) + (message-subscribed-addresses, message-subscribed-regexps) + (message-canlock-generate) + (message-generate-new-buffer-clone-locals): Docstring fixes. + +2003-07-07 Kai Gro,A_(Bjohann + + * imap.el (imap-wait-for-tag): After the process has died, look + for more output still pending. From Gaute B Strokkenes + (tiny patch). + +2003-07-07 Teodor Zlatanov + + * spam.el (spam-bogofilter-score): redisplay article normally + after spam-bogofilter-score is called + +2003-07-06 Jesper Harder + + * message.el (message-send-mail-with-sendmail): Handle + non-numeric return values. + + * gnus-sum.el (gnus-print-buffer): Apply emphasis. + From Michael Piotrowski (tiny change). + + * gnus-start.el (gnus-clear-system): Revert change from + 2003-06-19. + +2003-07-04 Dave Love + + * rfc2047.el (rfc2047-q-encode-region): Exclude especials from + characters not encoded, and make the list more legible. + +2003-07-04 Jesper Harder + + * message.el (message-make-from): Revert change from 2002-01-08. + +2003-06-29 Lars Magne Ingebrigtsen + + * nnheader.el (nnheader-init-server-buffer): Don't add + nntp-server-buffer to list of Gnus buffers. + +2003-06-25 Teodor Zlatanov + + * spam.el (spam-parse-list): prevent empty ("") strings + +2003-06-24 Teodor Zlatanov + + * spam.el (spam-parse-list): use gnus-extract-address-components + instead of ietf-drums-parse-addresses + (spam-from-listed-p): let* was unnecessary + +2003-06-24 Lars Magne Ingebrigtsen + + * gnus-ems.el (gnus-put-image): Mark the right text segment with + gnus-image-category. + + * gnus-srvr.el (gnus-browse-unsubscribe-group): Strip prefix from + native groups. + + * gnus-topic.el (gnus-group-prepare-topics): Update topic line + format specs. + + * gnus-picon.el: Written by moi, moi, moi. + + * gnus-group.el (gnus-group-kill-group): Clean up. + +2003-06-23 Teodor Zlatanov + + * spam.el (spam-from-listed-p, spam-parse-list): use + ietf-drums-parse-addresses to extract the address portion of the + whitelist/blacklist file if it looks like an address can be found + +2003-06-23 Didier Verna + + * gnus-ems.el (gnus-put-image): New argument CATEGORY. Add it as a + text property. + (gnus-remove-image): New argument CATEGORY. Only remove if + category matches. + * gnus-xmas.el (gnus-xmas-put-image): + (gnus-xmas-remove-image): Ditto, with extents. + * gnus-art.el (gnus-delete-images): Pass CATEGORY argument to + gnus-[xmas-]remove-image. + (article-display-face): Don't always act as a toggle. Call + `gnus-put-image' with CATEGORY argument. + (article-display-x-face): Call `gnus-put-image' with CATEGORY + argument. + * smiley.el (smiley-region): Ditto. + * gnus-fun.el (gnus-display-x-face-in-from): Ditto. + * gnus-picon.el (gnus-picon-insert-glyph): Ditto. + (gnus-treat-mail-picon): Don't always act as a toggle. + * gnus-picon.el (gnus-treat-newsgroups-picon): Ditto. + +2003-06-23 Didier Verna + + * gnus-art.el (article-display-face): Check for existence of the + original article buffer before switching to it. + +2003-06-20 Jesper Harder + + * mm-util.el (mm-append-to-file): Say "Appended to". Suggested by + Dan Jacobson . + + * mm-view.el (mm-inline-message): Bind + gnus-original-article-buffer to the buffer in the mml handle + holding the message. + +2003-06-20 Katsumi Yamaoka + + * message.el (sender, from): No need to bind them. + +2003-06-19 Teodor Zlatanov + + * spam.el (spam-enter-list): search-forward specified wrong + +2003-06-19 Lars Magne Ingebrigtsen + + * gnus-art.el: Comment fix. + +2003-06-20 Jesper Harder + + * gnus-msg.el (gnus-configure-posting-styles): Remove unused + variable. From Jan Rychter . + + * spam.el (spam-spamoracle-learn): insert-string is obsolete. + +2003-06-19 Teodor Zlatanov + + * spam.el (spam-enter-list): do not enter duplicate addresses into + the whitelist/blacklist + +2003-06-19 Jesper Harder + + * nnheader.el (nnheader-init-server-buffer): Add + nntp-server-buffer to gnus-buffers. + + * gnus-start.el (gnus-clear-system): Now we don't need to kill + nntp-server-buffer separately. + +2003-06-18 Didier Verna + + * gnus-art.el (article-display-face): Correctly toggle between + display and hiding. Handle multiple Face headers. + +2003-06-17 Dave Love + + * nnimap.el: Require cl when compiling. + + * message.el (message-fix-before-sending): Reinstate nullifying + the invisible text property. + (sender, from): Defvar when compiling. + (message-is-yours-p): Remove autoload cookie. + +2003-06-17 Reiner Steib + + * gnus-util.el (gnus-extract-address-components): Added + doc-string. + +2003-06-16 Kai Gro,A_(Bjohann + + * nnml.el (nnml-current-group-article-to-file-alist): Don't read + overview when using compressed files. From Michael Albinus + . + +2003-06-16 Katsumi Yamaoka + + * gnus-sum.el (gnus-summary-refer-parent-article): Extract + Message-ID from In-Reply-To header. + +2003-06-16 Katsumi Yamaoka + + * message.el (message-is-yours-p): Narrow to head; extract from + and sender by itself. + (message-cancel-news, message-supersede): Remove useless things. + +2003-06-15 Reiner Steib + + * gnus-sum.el (gnus-summary-force-verify-and-decrypt): Bind + `gnus-article-emulate-mime'. + +2003-06-15 Kai Gro,A_(Bjohann + From Tommi Vainikainen . + + * message.el (message-is-yours-p): New function. Separated common + code from message-cancel-news and message-supersede. Added + matching code which uses message-alternative-emails regexp as last + resort. + (message-cancel-news, message-supersede): Use message-is-yours-p. + +2003-06-13 Kai Gro,A_(Bjohann + + * nnimap.el (nnimap-split-articles): Narrow the right buffer to + the headers. From Niklas Morberg . + +2003-06-12 Dave Love + + * nnheader.el (nnheader-functionp): Deleted. + + * nnmail.el (nnmail-split-fancy-syntax-table): Define all in + defvar. + (nnmail-version): Deleted. + (nnmail-check-duplication, nnmail-expiry-target-group): Don't use + nnheader-functionp. + +2003-06-10 Teodor Zlatanov + + * spam.el (spam-check-bogofilter-headers): fix for when the score + is requested but the message is not spam + +2003-06-09 Teodor Zlatanov + From Eric + + + * spam.el (spam-use-spamoracle): new variable + (spam-install-hooks): add spamoracle to the list of conditions + for activation of spam-install-hooks + (spam-spamoracle): new variable customization group + (spam-spamoracle, spam-spamoracle): new variables + (spam-group-spam-processor-spamoracle-p) + (spam-group-ham-processor-spamoracle-p): new functions + (spam-summary-prepare-exit): added spamoracle ham/spam exit processing + (spam-list-of-checks, spam-list-of-statistical-checks): add + spam-use-spamoracle + (spam-check-spamoracle, spam-spamoracle-learn) + (spam-spamoracle-learn-ham, spam-spamoracle-learn-spam): new functions + + * gnus.el (gnus-group-spam-exit-processor-spamoracle) + (gnus-group-ham-exit-processor-spamoracle): new variables for SpamOracle + (spam-process, ham-process): added spamoracle spam/ham processors + +2003-06-08 Jesper Harder + + * message.el (message-beginning-of-line): Docstring improvement. + Suggested by Michael R. Wolf + +2003-06-07 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-make-menu-bar): Removed ["Add buttons" + gnus-summary-display-buttonized t] + +2003-06-07 Kai Gro,A_(Bjohann + + * nnmail.el (nnmail-split-fancy-match-partial-words): Doc string + fix. Reported by Johan Bockg,Ae(Brd . + +2003-06-07 Jesper Harder + + * message.el (message-beginning-of-line): Docstring improvement. + +2003-06-06 Jesper Harder + + * gnus-srvr.el (gnus-browse-foreign-server): Parse garbage NNTP + groups correctly. + +2003-06-06 Kai Gro,A_(Bjohann + From Benjamin Rutt . + + * message.el (message-fetch-field): Augment documentation to state + the narrowed-to-headers restriction. + (message-change-subject, message-reduce-to-to-cc) + (message-generate-unsubscribed-mail-followup-to) + (message-insert-importance-high, message-insert-importance-low) + (message-insert-or-toggle-importance) + (message-insert-disposition-notification-to): Narrow to headers + before calling message-fetch-field or message-remove-header. + +2003-06-06 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-trim): fix for when + gnus-registry-max-entries is nil + +2003-06-05 Lars Magne Ingebrigtsen + + * qp.el (quoted-printable-decode-region): Don't error out on + malformed text. + +2003-06-04 Lars Magne Ingebrigtsen + + * rfc2047.el (rfc2047-encode-region): Don't error out on invalid + strings. + +2003-06-04 Jesper Harder + + * mml1991.el (mml1991-pgg-sign): Insert pgg output as unibyte. + From: Ivan Boldyrev (tiny + change) + +2003-06-03 Dave Love + + * gnus-soup.el (gnus-soup-send-packet): Don't use + message-functionp. + + * gnus.el (gnus-agent-cache): Doc fix. + (gnus-other-frame): Quote lambda used as hook. + + * message.el: Doc fixes. + (message-functionp): Deleted. Callers changed. + (message-fix-before-sending): Highlight with overlays. Clarify + `illegible text' messages. + (rmail-enable-mime-composing, gnus-message-group-art): Defvar when + compiling. + (gnus-find-method-for-group, nnvirtual-find-group-art): Autoload. + +2003-06-03 Kai Gro,A_(Bjohann + + * nnmail.el (nnmail-split-fancy-match-partial-words): New user + option. + (nnmail-split-it): Obey it. Don't let-bind regexp twice. + + * message.el (message-fetch-field): Mention narrow-to-headers + requirement. + +2003-06-03 Jesper Harder + + * gnus-xmas.el (gnus-xmas-create-image): Use + insert-file-contents-literally. From: Eric Eide + + +2003-06-02 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-fetch-group): always return the + short name of the group + +2003-06-02 Jesper Harder + + * gnus-cus.el (defvar): Silence byte-compiler warnings. + + * gnus-sum.el (gnus-get-newsgroup-headers): Unfold headers. + +2003-05-31 Jesper Harder + + * gnus-art.el (article-unsplit-urls): Use gnus-treat-article + rather than gnus-display-mime-function. + +2003-05-30 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-use-long-group-names): new variable + (gnus-registry-add-group): use it + (gnus-registry-trim-articles-without-groups): new variable + (gnus-registry-delete-group): use it + (gnus-registry-unload-hook): uninstall all the hooks + + * spam.el (spam-install-hooks-function, spam-unload-hook): new + functions so users that load spam.el for customization don't get + all the hooks installed + (spam-install-hooks): new variable, set to t by default if user + has one of the spam-use-* variables set + + * spam-stat.el (spam-stat-install-hooks, spam-stat-unload-hook): new + functions so users that load spam-stat.el for customization don't get + all the hooks installed + +2003-05-30 Dave Love + + * rfc2047.el (rfc2047-decode): Don't use + mm-with-unibyte-current-buffer. + + * qp.el (quoted-printable-decode-string): Use + mm-with-unibyte-buffer. + +2003-05-29 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-save): allow forced saving even + when registry is not dirty. Use gnus-registry-trim to shorten the + gnus-registry-alist. + (gnus-registry-max-entries): new variable + (gnus-registry-trim): new function, trim gnus-registry-alist to + size gnus-registry-max-entries, sorting by entry mtime so the + newest entries stick around + + * gnus-start.el (gnus-gnus-to-quick-newsrc-format): instead of + just one specific variable, allow a list of specific variables + +2003-05-28 Dave Love + + * rfc2047.el (rfc2047-encode-region): Skip ASCII at beginning and + end of region. + +2003-05-28 Jesper Harder + + * lpath.el: Add put-char-table and get-char-table. + +2003-05-28 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-dirty): flag for modified registry + (gnus-registry-save, gnus-registry-read) + (gnus-registry-store-extra, gnus-registry-clear): use it (note + that gnus-registry-store-extra is invoked for all modifications to + set the mtime, so gnus-registry-dirty only needs to be set there) + +2003-05-23 Simon Josefsson + + * mml1991.el (mml1991-pgg-sign): Use mml-sender instead of + message-sender. + + * gnus-art.el (gnus-use-idna): Check if idna-program is installed. + + * message.el (message-use-idna): Ditto. + +2003-05-20 Dave Love + + * rfc2047.el (rfc2047-q-encoding-alist): Deleted. + (rfc2047-q-encode-region): Don't use it. + (rfc2047-encode-message-header) <(eq method 'mime)>: Bind + rfc2047-encoding-type to `mime'. + (rfc2047-encode-string, rfc2047-encode): Doc fix. + +2003-05-20 Jesper Harder + + * message.el (message-send-mail): Don't insert a courtesy copy + notice in base64 encoded messages. + +2003-05-16 Katsumi Yamaoka + + * gnus-sum.el (gnus-summary-move-article): Don't copy expirable + marks if the destination group is not auto-expirable. + +2003-05-14 Katsumi Yamaoka + + * dgnushack.el (assq-delete-all): Removed the compiler macro. + +2003-05-14 Kevin Greiner + + * gnus-agent.el (gnus-agentize): Updated documentation to match + usage. + (gnus-agent-expire-group-1): Do not skip over a group when the + force argument is set. + * gnus.el (gnus-agent): Updated documentation to reflect that + gnus-agent now defaults to t. + +2003-05-14 Lars Magne Ingebrigtsen + + * gnus.el (gnus-version-number): Bump. + +2003-05-14 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.10.2 is released. + +2003-05-14 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-delete-incoming): Changed to t. + + * rfc2047.el (rfc2047-syntax-table): Funcall. + + * lpath.el ((featurep 'xemacs)): Added set-char-table-range. + ((featurep 'xemacs)): No, don't. + + * rfc2047.el (rfc2047-encodable-p): Use the header charset. + + * gnus-sum.el (gnus-summary-reselect-current-group): Supply + leave-hidden. + +2003-05-14 Jonathan Kamens + + * gnus-sum.el (gnus-summary-exit): Added `leave-hidden'. (Tiny + patch.) + +2003-05-13 Lars Magne Ingebrigtsen + + * gnus-registry.el (gnus-registry-store-extra-entry): Use + gnus-assq-delete-all. + + * gnus-xmas.el (gnus-xmas-assq-delete-all): New function. + + * message.el (message-ignored-bounced-headers): Add Delivered-To. + + * gnus-sum.el (gnus-summary-find-next): Indent. + (gnus-summary-find-prev): Ditto. + (gnus-summary-catchup): Doc fix. + (gnus-summary-mark-current-read-and-unread-as-read): New function. + (gnus-summary-catchup): Really mark after point. + + * gnus-util.el (gnus-user-date): Use %d instead of %m. + (gnus-user-date): Use floating point time so that we don't get + overflows. + + * gnus-sum.el (gnus-summary-local-variables): Clean up. + + * gnus-fun.el (gnus-display-x-face-in-from): Don't use centering + since none of the other image things do. + +2003-05-13 Katsumi Yamaoka + + * dgnushack.el (assq-delete-all): New compiler macro for Emacs 20. + +2003-05-12 Katsumi Yamaoka + + * lpath.el: Fbind find-coding-system. + + * dgnushack.el (dgnushack-make-load): Remove redundant format call + in message. Suggested by Yoichi NAKAYAMA . + * pop3.el (pop3-movemail): Ditto. + +2003-05-12 Colin Marquardt (tiny change) + + * gnus.el (gnus-agent): Docstring fix. + +2003-05-12 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-install): new variable + (gnus-registry-fetch-extra, gnus-registry-fetch-extra-entry) + (gnus-registry-store-extra-entry, gnus-registry-delete-group) + (gnus-registry-add-group): add a modification timestamp to each entry + (gnus-registry-install-hooks): new function + +2003-05-12 Kevin Greiner + + * gnus-agent.el (gnus-agent-cat-name): Eval macro while compiling. + (gnus-agent-cat-disable-undownloaded-faces): New function. + Accessor for new agent property + 'agent-disable-undownloaded-faces'. + gnus-cus.el (gnus-agent-parameters): Added + agent-disable-undownloaded-faces and corrected documentation. + (gnus-agent-cat-prepare-category-field, + gnus-agent-customize-category): Changed to avoid creating free + references to each field's symbol. + gnus-sum.el (gnus-summary-use-undownloaded-faces): New local variable. + (gnus-select-newgroup): Initialize it. + (gnus-summary-highlight-line): Use it. + +2003-05-12 Dave Love + + * mm-util.el (mm-read-charset): Deleted. + (mm-coding-system-mime-charset): New. + (mm-read-coding-system, mm-mule-charset-to-mime-charset) + (mm-charset-to-coding-system, mm-mime-charset) + (mm-find-mime-charset-region): Use it. + (mm-default-multibyte-p): Fix non-mule case. + + * rfc2047.el (rfc2047-point-at-bol, rfc2047-point-at-bol): Eval + and compile. + (rfc2047-syntax-table): Fix building table to work in Emacs 22. + (rfc2047-unfold-region): Delete unused var `leading'. + +2003-05-12 Simon Josefsson + + * pgg.el (pgg-temp-buffer-show-function): Reuse existing visible + output window if one is available. Tiny patch from Ville Skytt,Ad(B + . + +2003-05-11 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-expire-unagentized-dirs): Added + space. + +2003-05-11 Jesper Harder + + * gnus-sum.el (gnus-summary-enter-digest-group): Don't do article + washing etc. + (gnus-handle-ephemeral-exit): Don't reload article after exiting. + + * nndoc.el (nndoc-type-alist): `mime-digest' should be before + `mime-parts'. + +2003-05-10 Jesper Harder + + * gnus-cite.el (gnus-article-hide-citation-maybe): Make toggling + work. Update mode-line. + +2003-05-10 Lars Magne Ingebrigtsen + + * gnus.el (gnus-logo-color-alist): Added no colours. + +2003-05-09 Dave Love + + * utf7.el (mm-util): Require. + (utf7-direct-encoding-chars, utf7-imap-direct-encoding-chars): + Defconst, not defvar. + (utf7-utf-16-coding-system): New. + (utf7-encode-internal): Hoist concat out of loop. + (utf7-fragment-encode): Use mm-with-unibyte-current-buffer. + (utf7-get-u16char-converter) [utf7-utf-16-coding-system]: New + case. + (utf7-latin1-u16-char-converter): Encode the region. + (utf7-u16-latin1-char-converter): Decode the region. + (utf7-encode, utf7-decode): Fix multibyteness. + + * mm-bodies.el (mm-body-7-or-8): Don't special-case mule. + (mm-encode-body): Use mm-read-coding-system, not mm-read-charset. + (mm-uu-yenc-decode-function): Defvar when compiling. + (mm-encode-body, mm-decode-body): Doc fix. + +2003-05-09 Teodor Zlatanov + + * gnus-registry.el (gnus-registry-unregistered-group-regex): + removed in favor of the group/topic/global variables + (gnus-registry-register-message-ids): fixed test to omit + gnus-registry-unregistered-group-regex + + * gnus.el (gnus-variable-list): removed gnus-registry-alist and + gnus-registry-headers-alist from the list + (gnus-registry-headers-alist): removed + (registry-ignore): new parameter, with accompanying + gnus-registry-ignored-groups global variable + + * gnus-start.el (gnus-clear-system): no need to clear the + registry, we can do it ourselves + (gnus-gnus-to-quick-newsrc-format): extra parameters so it can be + used by gnus-registry.el + + * gnus-registry.el (gnus-registry-cache-file): new file variable + (gnus-registry-cache-read, gnus-registry-cache-save): new + functions + (gnus-registry-cache-whitespace): new function. From Dan + Christensen + (gnus-registry-save, gnus-registry-read): use the new + gnus-registry-cache-{read|save} functions, and change the name + from gnus-registry-translate-{from|to}-alist + (gnus-registry-clear): fixed so it doesn't refer to old function name + +2003-05-09 Jesper Harder + + * gnus-picon.el (gnus-picon-transform-address): Parse the encoded + address. + +2003-05-08 Teodor Zlatanov + + * gnus-start.el (gnus-clear-system): added gnus-registry-alist to + the list of cleared variables + + * gnus-registry.el (gnus-registry-split-fancy-with-parent): + nnmail-split-fancy-with-parent-ignore-groups can be a single regex + in addition to a list of regexes. + + * spam.el (spam-use-regex-headers): docstring fix. From Niklas + Morberg + +2003-05-08 Kai Gro,A_(Bjohann + + * gnus-sum.el (gnus-summary-next-page): Mention + `gnus-article-skip-boring' in docstring. + +2003-05-08 Jesper Harder + + * rfc2231.el (rfc2231-parse-string): "=" should have whitespace + syntax here. + + * ietf-drums.el (ietf-drums-syntax-table): "=" should not have + whitespace syntax class when parsing email addresses. + + * message.el (message-forward-subject-name-subject): Don't use + mail-decode-encoded-word-string before parsing from. + +2003-05-07 ShengHuo ZHU + + * message.el (message-setup-1): Setup alternative email before + generate-headers. + + (message-forward-subject-name-subject): Fix the case when the + field "from" doesn't exist. + +2003-05-07 Dave Love + + * rfc2047.el (rfc2047-encode-region): Skip \n as whitespace. + + * mm-util.el (mm-find-mime-charset-region): Expurgate utf-16 from + possible values. + +2003-05-07 Jesper Harder + + * message.el (message-kill-to-signature): Fix. + +2003-05-06 Jesper Harder + + * gnus-sum.el (gnus-auto-goto-ignores): Docstring fix. + + * gnus-art.el (gnus-mime-display-multipart-as-mixed) + (gnus-mime-display-multipart-related-as-mixed) + (gnus-button-mid-or-mail-heuristic-alist): do. + +2003-05-05 Dave Love + + * mm-util.el (mm-default-multibyte-p): New. + (mm-coding-system-p): Maybe use find-coding-systems. + +2003-05-04 Dave Love + + * rfc2047.el (with-syntax-table): Define if necessary. + (rfc2047-syntax-table): Fix last change for XEmacs. + (rfc2047-parse-and-decode): Revert last change. + +2003-05-03 Jesper Harder + + * gnus.el: Don't test for `mm-guess-mime-charset'. + + * mm-util.el (mm-guess-mime-charset): Remove. Not used any more. + + * gnus.el (gnus-default-charset): Set default value to + `undecided'. + + * gnus-art.el (article-decode-charset): Don't supply 4th arg to + mm-decode-body. + + * mm-bodies.el (mm-decode-coding-region-safely): Remove. + (mm-decode-body): Don't use mm-decode-coding-region-safely. + +2003-05-03 Vasily Korytov (tiny change) + + * gnus-util.el (gnus-multiple-choice): Add ", ?". + +2003-05-03 Dave Love + + * rfc2047.el (rfc2047-syntax-table): Don't call make-char-table + with 2 args. + (rfc2047-decode-string): Don't set the buffer multibyte before + calling buffer-string. + + * mm-encode.el (mm-long-lines-p): Autoload. + (mm-encode-content-transfer-encoding): Doc fix. Don't make buffer + unibyte. Signal error on unknown encoding. + (mm-encode-buffer, mm-qp-or-base64): Doc fix. + + * rfc2047.el (rfc2047-point-at-bol, rfc2047-point-at-eol): New. + Callers of gnus- versions changed to use them. + (rfc2047-header-encoding-alist): Add `address-mime' part. Doc + fixes. + (rfc2047-encoding-type): New. + (rfc2047-encode-message-header): Use mm-charset-to-coding-system. + Don't include header name field in encoding. Add `address-mime' + case and bind rfc2047-encoding-type for `mime' case. + (rfc2047-encodable-p): Deleted. + (rfc2047-syntax-table): New. + (rfc2047-encode-region, rfc2047-encode): Rewritten to take account + of rfc2047 rules with respect to rfc2822 tokens and to do encoding + in place rather than by passing strings. + (rfc2047-encode-string): Doc fix. + (rfc2047-q-encode-region): Don't use + mm-with-unibyte-current-buffer. + (rfc2047-encoded-word-regexp): eval-and-compile. + (rfc2047-decode-region): Avoid concatenation in loop. + (rfc2047-parse-and-decode): Remove useless disjunction. + +2003-05-02 Dave Love + + * rfc2047.el (rfc2047-q-encode-region, rfc2047-decode): Use + mm-with-unibyte-current-buffer. + (ietf-drums, gnus-util): don't require. + + * sieve.el (sieve-manage-mode-menu): Define before use. + + * mml-smime.el (message-narrow-to-headers): Autoload. + + * mm-util.el (mm-coding-system-p): Don't override nil from + coding-system-p. + (mm-mule4-p, mm-disable-multibyte-mule4) + (mm-with-unibyte-current-buffer-mule4): Deleted. + (mm-multibyte-p): Use defun, not defalias. + (mm-make-temp-file): Moved to group at top of file. + (mm-point-at-eol, mm-point-at-bol): New. + + * gnus-cite.el (gnus-art): Require. + + * gnus-ems.el (gnus-get-buffer-create) + (nnheader-find-etc-directory, message-text-with-property): + Autoload. + (gnus-tmp-unread, gnus-tmp-replied, gnus-tmp-score-char) + (gnus-tmp-indentation, gnus-tmp-opening-bracket, gnus-tmp-lines) + (gnus-tmp-name, gnus-tmp-closing-bracket, gnus-tmp-subject-or-nil) + (gnus-check-before-posting): Only defvar when compiling. + + * gnus-int.el (gnus-agent-expire): Autoload, don't defun. + + * gnus-util.el (rmail-default-rmail-file, mm-text-coding-system): + Defvar when compiling. + (gnus-output-to-rmail): Require mm-util. + + * mail-source.el (mail-source-callback): Use mm-make-temp-file. + (mail-source-make-complex-temp-name): Deleted. + + * message.el (message-use-idna): Use mm-coding-system-p. + (message-tokenize-header, message-make-organization) + (message-make-from): Use with-temp-buffer. + (message-set-work-buffer): Deleted. + (message-fill-paragraph): Use `if' not `and' for compiler warning. + (message-check-news-header-syntax): Remove useless lambda. + (message-forward-make-body): Use mm-disable-multibyte, + mm-with-unibyte-current-buffer, mm-enable-multibyte. + (message-replace-chars-in-string): Deleted. + + * mm-extern.el (mm-extern-local-file): Use mm-disable-multibyte. + (mm-extern-url): Use mm-with-unibyte-current-buffer, + mm-disable-multibyte. + (mm-extern-anon-ftp): Use mm-disable-multibyte. + + * mml1991.el (mml1991-mailcrypt-encrypt, mml1991-gpg-encrypt): Use + mm-with-unibyte-current-buffer. + + * mml2015.el (mml): Require. + (mml2015-mailcrypt-encrypt, mml2015-gpg-encrypt): Use + mm-with-unibyte-current-buffer. + + * nnheader.el (gnus-util): Require. + + * nntp.el (format-spec, format-spec-make, open-tls-stream): + Autoload. + + * rfc2231.el (mail-header-remove-comments, mm-encode-body) + (mail-header-remove-whitespace): Autoload. + + * sieve-manage.el (starttls-negotiate): Autoload. + +2003-05-01 Lars Magne Ingebrigtsen + + * nnrss.el (nnrss-find-rss-via-syndic8): Indent. + +2003-05-01 Mark A. Hershberger + + * nnrss.el (nnrss-find-rss-via-syndic8): Don't error out. + +2003-05-01 Lars Magne Ingebrigtsen + + * gnus.el (gnus-version-number): Bump. + +2003-05-01 Teodor Zlatanov + + * spam-report.el (spam-report-gmane-regex): docstring fix. From + Jon Ericson (tiny change) + + * gnus.el (gnus-install-group-spam-parameters): docstring fix. + From Jon Ericson (tiny change) + + * gnus-registry.el (gnus-registry-fetch-extra) + (gnus-registry-store-extra, gnus-registry-group-count): new functions + (gnus-registry-fetch-group, gnus-registry-delete-group) + (gnus-registry-add-group): changed to work with extra data element + if present + +2003-05-01 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.10.1 is released. + 2003-05-01 Lars Magne Ingebrigtsen * gnus.el: Oort Gnus v0.24 is released. @@ -23,12 +2748,12 @@ 2003-05-01 Lars Magne Ingebrigtsen - * spam-stat.el (spam-stat-test-directory): Compare against zero. + * spam-stat.el (spam-stat-test-directory): Compare against zero. 2003-05-01 Trey Jackson (tiny change) * spam-stat.el (spam-stat-test-directory): Skip 0 length files. - + 2003-05-01 Lars Magne Ingebrigtsen * message.el (message-forward-subject-name-subject): Decode @@ -76,7 +2801,7 @@ 2003-05-01 Lars Magne Ingebrigtsen * message.el (message-check-news-header-syntax): Alter "posting" - message. + message. * nnrss.el (nnrss-node-text): Don't use char classes. @@ -178,7 +2903,7 @@ (gnus-registry-add-group): new function (gnus-register-spool-action): use it (gnus-register-action): use it - (gnus-registry-translate-from-alist) + (gnus-registry-translate-from-alist) (gnus-registry-translate-to-alist): remove the headers registry for now @@ -248,8 +2973,8 @@ 2003-04-27 Reiner Steib - * gnus-art.el (gnus-mime-display-multipart-as-mixed) - (gnus-mime-display-multipart-alternative-as-mixed) + * gnus-art.el (gnus-mime-display-multipart-as-mixed) + (gnus-mime-display-multipart-alternative-as-mixed) (gnus-mime-display-multipart-related-as-mixed): Added doc-strings, allow customization. @@ -260,7 +2985,7 @@ 2003-04-27 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-catchup): Don't mark ticked messages. + * gnus-sum.el (gnus-summary-catchup): Don't mark ticked messages. (gnus-summary-mark-read-and-unread-as-read): Take an optional mark. @@ -280,13 +3005,13 @@ * gnus-sum.el (gnus-summary-catchup-from-here): Doc fix. * nnrss.el (nnrss-node-text): Use only one - gnus-replace-in-string. + gnus-replace-in-string. * gnus.el: Remove gnus-functionp throughout. * gnus-util.el (gnus-functionp): Removed. - * gnus-msg.el (gnus-summary-wide-reply-with-original): Doc fix. + * gnus-msg.el (gnus-summary-wide-reply-with-original): Doc fix. * message.el (message-required-headers): Add In-Reply-To. @@ -340,7 +3065,7 @@ systems property. * mml-sec.el (mml2015, mml1991): Don't require. - (mml2015-sign, mml2015-encrypt, mml1991-sign, mml1991-encrypt) + (mml2015-sign, mml2015-encrypt, mml1991-sign, mml1991-encrypt) (message-goto-body, mml-insert-tag): Autoload. * mm-decode.el (mm-tmp-directory): Re-write to help avoid warnings. @@ -359,7 +3084,7 @@ 2003-04-24 Reiner Steib - * gnus-group.el (gnus-large-ephemeral-newsgroup) + * gnus-group.el (gnus-large-ephemeral-newsgroup) (gnus-fetch-old-ephemeral-headers): News variables. (gnus-group-read-ephemeral-group): Use them. @@ -649,7 +3374,7 @@ * message.el (message-hide-headers): Don't do intangible. * gnus.el (gnus-group-prefixed-name): Comment out the test for - colon. + colon. * gnus-srvr.el (gnus-browse-read-group): Don't give the real name to the ephemeral entry, but the prefixed name. @@ -678,7 +3403,7 @@ 2003-04-13 Lars Magne Ingebrigtsen - * gnus-draft.el (gnus-draft-send): Add message-hidden-headers. + * gnus-draft.el (gnus-draft-send): Add message-hidden-headers. 2003-04-12 Lars Magne Ingebrigtsen @@ -689,7 +3414,7 @@ * message.el (message-newline-and-reformat): Place a boundary before filling. (message-make-forward-subject-function): Changed default to - message-forward-subject-name-subject. + message-forward-subject-name-subject. (message-forward-subject-name-subject): New function. * nnimap.el (nnimap-split-fancy): Ditto. @@ -705,7 +3430,7 @@ (message-fix-before-sending): Make hidden headers visible. (message-hide-headers): Bind after-change-functions to nil. (message-forbidden-properties): Put invisible and intangible - back. + back. (message-strip-forbidden-properties): Ignore message-hidden text. * gnus-msg.el: Hide headers. @@ -715,7 +3440,7 @@ (message-hide-header-p): New function. (message-hide-header-p): Change logic. (message-forbidden-properties): Remove intangible nil invisible - nil. + nil. (message-hide-headers): Narrow to headers. * lpath.el (featurep): Bind Info-directory, Info-menu. @@ -854,7 +3579,7 @@ (pgg-pgp5-snarf-keys-region, pgg-pgp5-process-region): do. * pgg.el (pgg-make-temp-file, pgg-temporary-file-directory): do. - + 2003-04-05 Teodor Zlatanov * spam.el (spam-split): (save-excursion) around (widen) @@ -972,7 +3697,7 @@ nnheader-accept-process-output. (pop3-retr): Ditto. - * mm-view.el (mm-text-html-renderer-alist): Add -nolist to Lynx. + * mm-view.el (mm-text-html-renderer-alist): Add -nolist to Lynx. (mm-text-html-washer-alist): Ditto. 2003-03-31 Simon Josefsson @@ -1016,7 +3741,7 @@ 2003-03-30 Lars Magne Ingebrigtsen - * nndoc.el (nndoc-type-alist): Move mime-parts further ahead. + * nndoc.el (nndoc-type-alist): Move mime-parts further ahead. * gnus-registry.el (gnus-registry-translate-to-alist): Make a valid lambda. diff --git a/lisp/Makefile.in b/lisp/Makefile.in index 00ae7ed..cd5408e 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -26,7 +26,7 @@ all total: clean-some gnus-load.el $(EMACS_COMP) -f dgnushack-compile clean-some: - rm -f *.elc gnus-load.el + rm -f *.elc gnus-load.el auto-autoloads.* custom-load.* warn: clean-some gnus-load.el $(EMACS_COMP) --eval '(dgnushack-compile t)' 2>&1 | egrep -v "variable G|inhibit-point-motion-hooks|coding-system|temp-results|variable gnus|variable nn|scroll-in-place|deactivate-mark|filladapt-mode|byte-code-function-p|print-quoted|ps-right-header|ps-left-header|article-inhibit|print-escape|ssl-program-arguments|message-log-max" @@ -73,9 +73,6 @@ install-package-manifest: $(EMACS_COMP) -f dgnushack-install-package-manifest \ $(PACKAGEDIR) $(GNUS_PRODUCT_NAME) -compose-package: gnus-load.el - $(EMACS_COMP) -f dgnushack-compose-package - remove-extra-files-in-package: $(EMACS_COMP) -f dgnushack-remove-extra-files-in-package \ $(PACKAGEDIR) $(GNUS_PRODUCT_NAME) diff --git a/lisp/canlock.el b/lisp/canlock.el index ee97fd3..55b2e59 100644 --- a/lisp/canlock.el +++ b/lisp/canlock.el @@ -83,12 +83,14 @@ (defcustom canlock-password nil "Password to use when signing a Cancel-Lock or a Cancel-Key header." - :type 'string + :type '(radio (const :format "Not specified " nil) + (string :tag "Password" :size 0)) :group 'canlock) (defcustom canlock-password-for-verify canlock-password "Password to use when verifying a Cancel-Lock or a Cancel-Key header." - :type 'string + :type '(radio (const :format "Not specified " nil) + (string :tag "Password" :size 0)) :group 'canlock) (defcustom canlock-force-insert-header nil diff --git a/lisp/deuglify.el b/lisp/deuglify.el index 89be369..ef10ac4 100644 --- a/lisp/deuglify.el +++ b/lisp/deuglify.el @@ -204,7 +204,7 @@ ;; Renamed `gnus-outlook-deuglify-article' to ;; `gnus-article-outlook-deuglify-article'. ;; Made it easier to deuglify the article while being in Gnus' Article -;; Edit Mode. (suggested by Phil Nitschke) +;; Edit Mode. (suggested by Phil Nitschke) ;; ;; ;; Revision 1.3 2002/01/02 23:35:54 rscholz @@ -235,13 +235,13 @@ ;;;###autoload (defcustom gnus-outlook-deuglify-unwrap-min 45 "Minimum length of the cited line above the (possibly) wrapped line." - :type 'number + :type 'integer :group 'gnus-outlook-deuglify) ;;;###autoload (defcustom gnus-outlook-deuglify-unwrap-max 95 "Maximum length of the cited line after unwrapping." - :type 'number + :type 'integer :group 'gnus-outlook-deuglify) (defcustom gnus-outlook-deuglify-cite-marks ">|#%" @@ -251,7 +251,8 @@ (defcustom gnus-outlook-deuglify-unwrap-stop-chars nil ;; ".?!" or nil "Characters that inhibit unwrapping if they are the last one on the cited line above the possible wrapped line." - :type 'string + :type '(radio (const :format "None " nil) + (string :size 0 :value ".?!")) :group 'gnus-outlook-deuglify) (defcustom gnus-outlook-deuglify-no-wrap-chars "`" @@ -300,10 +301,10 @@ It is run after `gnus-article-prepare-hook'." ;;;###autoload (defun gnus-article-outlook-unwrap-lines (&optional nodisplay) - "Unwrap lines that appear to be wrapped citation lines. + "Unwrap lines that appear to be wrapped citation lines. You can control what lines will be unwrapped by frobbing `gnus-outlook-deuglify-unwrap-min' and `gnus-outlook-deuglify-unwrap-max', -indicating the miminum and maximum length of an unwrapped citation line. If +indicating the minimum and maximum length of an unwrapped citation line. If NODISPLAY is non-nil, don't redisplay the article buffer." (interactive "P") (save-excursion @@ -330,7 +331,7 @@ NODISPLAY is non-nil, don't redisplay the article buffer." (unless nodisplay (gnus-outlook-display-article-buffer))) (defun gnus-outlook-rearrange-article (attr-start) - "Put the text from `attr-start' to the end of buffer at the top of the article buffer." + "Put the text from ATTR-START to the end of buffer at the top of the article buffer." (save-excursion (let ((inhibit-read-only t) (cite-marks gnus-outlook-deuglify-cite-marks)) diff --git a/lisp/dgnushack.el b/lisp/dgnushack.el index 505f844..97670f4 100644 --- a/lisp/dgnushack.el +++ b/lisp/dgnushack.el @@ -99,6 +99,43 @@ ; (cons 'progn (cdr form))) ;(defalias 'byte-compile-file-form-defsubst 'byte-compile-file-form-defun) +(when (and (not (featurep 'xemacs)) + (= emacs-major-version 21) + (= emacs-minor-version 3) + (condition-case code + (let ((byte-compile-error-on-warn t)) + (byte-optimize-form (quote (pop x)) t) + nil) + (error (string-match "called for effect" + (error-message-string code))))) + (defadvice byte-optimize-form-code-walker (around silence-warn-for-pop + (form for-effect) + activate) + "Silence the warning \"...called for effect\" for the `pop' form. +It is effective only when the `pop' macro is defined by cl.el rather +than subr.el." + (let (tmp) + (if (and (eq (car-safe form) 'car) + for-effect + (setq tmp (get 'car 'side-effect-free)) + (not byte-compile-delete-errors) + (not (eq tmp 'error-free)) + (eq (car-safe (cadr form)) 'prog1) + (let ((var (cadr (cadr form))) + (last (nth 2 (cadr form)))) + (and (symbolp var) + (null (nthcdr 3 (cadr form))) + (eq (car-safe last) 'setq) + (eq (cadr last) var) + (eq (car-safe (nth 2 last)) 'cdr) + (eq (cadr (nth 2 last)) var)))) + (progn + (put 'car 'side-effect-free 'error-free) + (unwind-protect + ad-do-it + (put 'car 'side-effect-free tmp))) + ad-do-it)))) + (when (boundp 'MULE) (let (current-load-list) ;; Make the function to be silent at compile-time. @@ -537,9 +574,6 @@ Try to re-configure with --with-addpath=FLIM_PATH and run make again. (defconst dgnushack-unexporting-files (append '("dgnushack.el" "dgnuspath.el" "dgnuskwds.el" "lpath.el") - (condition-case nil - (progn (require 'shimbun) nil) - (error '("nnshimbun.el"))) (unless (or (condition-case code (require 'w3-parse) (error @@ -605,7 +639,9 @@ Try to re-configure with --with-addpath=FLIM_PATH and run make again. (when (and (fboundp 'md5) (subrp (symbol-function 'md5))) '("md5.el")) (unless (boundp 'MULE) - '("canlock-om.el"))) + '("canlock-om.el")) + (when (featurep 'xemacs) + '("gnus-load.el"))) "Files which will not be installed.") (defconst dgnushack-exporting-files @@ -620,7 +656,8 @@ Try to re-configure with --with-addpath=FLIM_PATH and run make again. (princ (mapconcat 'identity dgnushack-exporting-files " "))) (defconst dgnushack-dont-compile-files - '("mm-bodies.el" "mm-decode.el" "mm-encode.el" "mm-extern.el" + '("gnus-load.el" + "mm-bodies.el" "mm-decode.el" "mm-encode.el" "mm-extern.el" "mm-partial.el" "mm-url.el" "mm-uu.el" "mm-view.el" "mml-sec.el" "mml-smime.el" "mml.el" "mml1991.el" "mml2015.el") "Files which should not be byte-compiled.") @@ -632,15 +669,11 @@ dgnushack-compile-verbosely. All other users should continue to use dgnushack-compile." (dgnushack-compile t)) -(defun dgnushack-compile-verbosely () - "Call dgnushack-compile with warnings ENABLED. If you are compiling -patches to gnus, you should consider modifying make.bat to call -dgnushack-compile-verbosely. All other users should continue to use -dgnushack-compile." - (dgnushack-compile t)) - (defun dgnushack-compile (&optional warn) ;;(setq byte-compile-dynamic t) + (when (and (not (featurep 'xemacs)) + (< emacs-major-version 21)) + (setq max-specpdl-size 1200)) (unless warn (setq byte-compile-warnings '(free-vars unresolved callargs redefine))) @@ -685,18 +718,33 @@ Modify to suit your needs.")) (require 'gnus) (byte-recompile-directory "." 0)) -(defvar dgnushack-gnus-load-file (expand-file-name "gnus-load.el" srcdir)) -(defvar dgnushack-cus-load-file (expand-file-name "cus-load.el" srcdir)) -(defvar dgnushack-auto-load-file (expand-file-name "auto-autoloads.el" srcdir)) +(defvar dgnushack-gnus-load-file + (if (featurep 'xemacs) + (expand-file-name "auto-autoloads.el" srcdir) + (expand-file-name "gnus-load.el" srcdir))) + +(defvar dgnushack-cus-load-file + (if (featurep 'xemacs) + (expand-file-name "custom-load.el" srcdir) + (expand-file-name "cus-load.el" srcdir))) (defun dgnushack-make-cus-load () (when (condition-case nil (load "cus-dep") - (error nil)) + (error + (when (boundp 'MULE) + (if (file-exists-p "../contrib/cus-dep.el") + ;; Use cus-dep.el of the version of Emacs 20.7. + (load-file "../contrib/cus-dep.el") + (error "\ +You need contrib/cus-dep.el to build T-gnus with Mule 2.3@19.34; exiting."))))) (let ((cusload-base-file dgnushack-cus-load-file)) (if (fboundp 'custom-make-dependencies) (custom-make-dependencies) - (Custom-make-dependencies))))) + (Custom-make-dependencies)) + (when (featurep 'xemacs) + (message "Compiling %s..." dgnushack-cus-load-file) + (byte-compile-file dgnushack-cus-load-file))))) (defun dgnushack-make-auto-load () (require 'autoload) @@ -718,11 +766,8 @@ Modify to suit your needs.")) (make-backup-files nil) (autoload-package-name "gnus")) (if (featurep 'xemacs) - (progn - (if (file-exists-p generated-autoload-file) - (delete-file generated-autoload-file)) - (if (file-exists-p dgnushack-auto-load-file) - (delete-file dgnushack-auto-load-file))) + (if (file-exists-p generated-autoload-file) + (delete-file generated-autoload-file)) (with-temp-file generated-autoload-file (insert ?\014))) (if (featurep 'xemacs) @@ -741,55 +786,44 @@ Modify to suit your needs.")) (batch-update-autoloads)))) (defun dgnushack-make-load () - (message (format "Generating %s..." dgnushack-gnus-load-file)) - (with-temp-file dgnushack-gnus-load-file - (if (file-exists-p dgnushack-cus-load-file) - (progn - (insert-file-contents dgnushack-cus-load-file) - (delete-file dgnushack-cus-load-file) - (goto-char (point-min)) - (search-forward ";;; Code:") - (forward-line) - (delete-region (point-min) (point)) - (unless (re-search-forward "\ -^[\t ]*(autoload[\t\n ]+\\('\\|(quote[\t\n ]+\\)custom-add-loads[\t\n ]" - nil t) - (insert "\n(autoload 'custom-add-loads \"cus-load\")\n")) - (goto-char (point-min)) - (insert "\ + (unless (featurep 'xemacs) + (message "Generating %s..." dgnushack-gnus-load-file) + (with-temp-file dgnushack-gnus-load-file + (insert-file-contents dgnushack-cus-load-file) + (delete-file dgnushack-cus-load-file) + (goto-char (point-min)) + (search-forward ";;; Code:") + (forward-line) + (delete-region (point-min) (point)) + (insert "\ ;;; gnus-load.el --- automatically extracted custom dependencies and autoload ;; ;;; Code: ") - (goto-char (point-max)) - (if (search-backward "custom-versions-load-alist" nil t) - (forward-line -1) - (forward-line -1) - (while (eq (char-after) ?\;) - (forward-line -1)) - (forward-line)) - (delete-region (point) (point-max)) - (insert "\n")) + (goto-char (point-max)) + (if (search-backward "custom-versions-load-alist" nil t) + (forward-line -1) + (forward-line -1) + (while (eq (char-after) ?\;) + (forward-line -1)) + (forward-line)) + (delete-region (point) (point-max)) + (insert "\n") + ;; smiley-* are duplicated. Remove them all. + (let ((point (point))) + (insert-file-contents dgnushack-gnus-load-file) + (goto-char point) + (while (search-forward "smiley-" nil t) + (beginning-of-line) + (if (looking-at "(autoload ") + (delete-region (point) (progn (forward-sexp) (point))) + (forward-line)))) + ;; + (goto-char (point-max)) + (when (search-backward "\n(provide " nil t) + (forward-line -1) + (delete-region (point) (point-max))) (insert "\ -;;; gnus-load.el --- automatically extracted autoload -;; -;;; Code: -")) - ;; smiley-* are duplicated. Remove them all. - (let ((point (point))) - (insert-file-contents dgnushack-gnus-load-file) - (goto-char point) - (while (search-forward "smiley-" nil t) - (beginning-of-line) - (if (looking-at "(autoload ") - (delete-region (point) (progn (forward-sexp) (point))) - (forward-line)))) - ;; - (goto-char (point-max)) - (when (search-backward "\n(provide " nil t) - (forward-line -1) - (delete-region (point) (point-max))) - (insert "\ \(provide 'gnus-load) @@ -800,72 +834,22 @@ Modify to suit your needs.")) ;;; End: ;;; gnus-load.el ends here ") - ;; Workaround the bug in some version of XEmacs. - (when (featurep 'xemacs) - (condition-case nil - (require 'cus-load) - (error nil)) - (goto-char (point-min)) - (when (and (fboundp 'custom-add-loads) - (not (search-forward "\n(autoload 'custom-add-loads " nil t))) - (search-forward "\n;;; Code:" nil t) - (forward-line 1) - (insert "\n(autoload 'custom-add-loads \"cus-load\")\n")))) - (message (format "Compiling %s..." dgnushack-gnus-load-file)) - (byte-compile-file dgnushack-gnus-load-file)) - - -(defun dgnushack-compose-package () - "Re-split the file gnus-load.el into custom-load.el and -auto-autoloads.el. It is silly, should be improved!" - (message " -Re-splitting gnus-load.el into custom-load.el and auto-autoloads.el...") - (let ((customload (expand-file-name "custom-load.el" srcdir)) - (autoloads (expand-file-name "auto-autoloads.el" srcdir)) - start) - (with-temp-buffer - (insert-file-contents dgnushack-gnus-load-file) - (delete-file dgnushack-gnus-load-file) - (when (file-exists-p (concat dgnushack-gnus-load-file "c")) - (delete-file (concat dgnushack-gnus-load-file "c"))) - (while (prog1 - (looking-at "[\t ;]") - (forward-line 1))) - (setq start (point)) + )) + (message "Compiling %s..." dgnushack-gnus-load-file) + (byte-compile-file dgnushack-gnus-load-file) + (when (featurep 'xemacs) + (message "Creating dummy gnus-load.el...") + (with-temp-file (expand-file-name "gnus-load.el") (insert "\ -;;; custom-load.el --- automatically extracted custom dependencies\n -;;; Code:\n\n") - (goto-char (point-max)) - (while (progn - (forward-line -1) - (not (looking-at "[\t ]*(custom-add-loads[\t\n ]")))) - (forward-list 1) - (forward-line 1) - (insert "\n;;; custom-load.el ends here\n") - (write-region start (point) customload) - (while (looking-at "[\t ]*$") - (forward-line 1)) - (setq start (point)) - (if (re-search-forward "^[\t\n ]*(if[\t\n ]+(featurep[\t\n ]" nil t) - (let ((from (goto-char (match-beginning 0)))) - (delete-region from (progn - (forward-list 1) - (forward-line 1) - (point)))) - (while (looking-at "[\t ;]") - (forward-line 1))) - (insert "(if (featurep 'gnus-autoloads) (error \"Already loaded\"))\n") - (goto-char (point-max)) - (while (progn - (forward-line -1) - (not (looking-at "[\t ]*(provide[\t\n ]")))) - (insert "(provide 'gnus-autoloads)\n") - (write-region start (point) autoloads)) - (byte-compile-file customload) - (byte-compile-file autoloads)) - (message "\ -Re-splitting gnus-load.el into custom-load.el and auto-autoloads.el...done -\n")) + +\(provide 'gnus-load) + +;;; Local Variables: +;;; version-control: never +;;; no-byte-compile: t +;;; no-update-autoloads: t +;;; End: +;;; gnus-load.el ends here")))) (defconst dgnushack-info-file-regexp-en diff --git a/lisp/dns.el b/lisp/dns.el index 44a002a..f21bb99 100644 --- a/lisp/dns.el +++ b/lisp/dns.el @@ -281,8 +281,9 @@ If TCP-P, the first two bytes of the package with be the length field." (setq dns-servers (nreverse dns-servers))))) ;;; Interface functions. - -(autoload 'gnus-xmacs-open-network-stream "gnus-xmas" nil nil 'macro) +(eval-when-compile + (when (featurep 'xemacs) + (require 'gnus-xmas))) (defmacro dns-make-network-process (server) (if (featurep 'xemacs) @@ -313,45 +314,46 @@ If TCP-P, the first two bytes of the package with be the length field." If FULLP, return the entire record returned." (setq type (or type 'A)) (unless dns-servers - (dns-parse-resolv-conf) - (unless dns-servers - (error "No DNS server configuration found"))) - (mm-with-unibyte-buffer - (let ((process (condition-case () - (dns-make-network-process (car dns-servers)) - (error - (message "dns: Got an error while trying to talk to %s" - (car dns-servers)) - nil))) - (tcp-p (and (not (fboundp 'make-network-process)) - (not (featurep 'xemacs)))) - (step 100) - (times (* dns-timeout 1000)) - (id (random 65000))) - (when process - (process-send-string - process - (dns-write `((id ,id) - (opcode query) - (queries ((,name (type ,type)))) - (recursion-desired-p t)) - tcp-p)) - (while (and (zerop (buffer-size)) - (> times 0)) - (accept-process-output process 0 step) - (decf times step)) - (ignore-errors - (delete-process process)) - (when tcp-p - (goto-char (point-min)) - (delete-region (point) (+ (point) 2))) - (unless (zerop (buffer-size)) - (let ((result (dns-read (buffer-string)))) - (if fullp - result - (let ((answer (car (dns-get 'answers result)))) - (when (eq type (dns-get 'type answer)) - (dns-get 'data answer)))))))))) + (dns-parse-resolv-conf)) + + (if (not dns-servers) + (message "No DNS server configuration found") + (mm-with-unibyte-buffer + (let ((process (condition-case () + (dns-make-network-process (car dns-servers)) + (error + (message "dns: Got an error while trying to talk to %s" + (car dns-servers)) + nil))) + (tcp-p (and (not (fboundp 'make-network-process)) + (not (featurep 'xemacs)))) + (step 100) + (times (* dns-timeout 1000)) + (id (random 65000))) + (when process + (process-send-string + process + (dns-write `((id ,id) + (opcode query) + (queries ((,name (type ,type)))) + (recursion-desired-p t)) + tcp-p)) + (while (and (zerop (buffer-size)) + (> times 0)) + (accept-process-output process 0 step) + (decf times step)) + (ignore-errors + (delete-process process)) + (when tcp-p + (goto-char (point-min)) + (delete-region (point) (+ (point) 2))) + (unless (zerop (buffer-size)) + (let ((result (dns-read (buffer-string)))) + (if fullp + result + (let ((answer (car (dns-get 'answers result)))) + (when (eq type (dns-get 'type answer)) + (dns-get 'data answer))))))))))) (provide 'dns) diff --git a/lisp/flow-fill.el b/lisp/flow-fill.el index 987113d..f72bf5b 100644 --- a/lisp/flow-fill.el +++ b/lisp/flow-fill.el @@ -1,6 +1,6 @@ ;;; flow-fill.el --- interprete RFC2646 "flowed" text -;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ;; Author: Simon Josefsson ;; Keywords: mail @@ -47,6 +47,7 @@ ;; 2000-10-23 don't flow "-- " lines, make "quote-depth wins" rule ;; work when first line is at level 0. ;; 2002-01-12 probably incomplete encoding support +;; 2003-12-08 started working on test harness. ;;; Code: @@ -54,7 +55,7 @@ (defcustom fill-flowed-display-column 'fill-column "Column beyond which format=flowed lines are wrapped, when displayed. -This can be a lisp expression or an integer." +This can be a Lisp expression or an integer." :type '(choice (const :tag "Standard `fill-column'" fill-column) (const :tag "Fit Window" (- (window-width) 5)) (sexp) @@ -62,7 +63,7 @@ This can be a lisp expression or an integer." (defcustom fill-flowed-encode-column 66 "Column beyond which format=flowed lines are wrapped, in outgoing messages. -This can be a lisp expression or an integer. +This can be a Lisp expression or an integer. RFC 2646 suggests 66 characters for readability." :type '(choice (const :tag "Standard fill-column" fill-column) (const :tag "RFC 2646 default (66)" 66) @@ -80,6 +81,7 @@ RFC 2646 suggests 66 characters for readability." 'point-at-eol 'line-end-position))) +;;;###autoload (defun fill-flowed-encode (&optional buffer) (with-current-buffer (or buffer (current-buffer)) ;; No point in doing this unless hard newlines is used. @@ -101,6 +103,7 @@ RFC 2646 suggests 66 characters for readability." (goto-char (setq start (1+ end))))) t))) +;;;###autoload (defun fill-flowed (&optional buffer) (save-excursion (set-buffer (or (current-buffer) buffer)) @@ -127,7 +130,7 @@ RFC 2646 suggests 66 characters for readability." (save-excursion (unless (eobp) (forward-char 1) - (looking-at (format "^\\(%s\\)\\([^>]\\)" + (looking-at (format "^\\(%s\\)\\([^>\n\r]\\)" (or quote " ?")))))) (save-excursion (replace-match (if (string= (match-string 2) " ") @@ -147,6 +150,71 @@ RFC 2646 suggests 66 characters for readability." (forward-line 1) nil)))))))) +;; Test vectors. + +(eval-when-compile + (defvar show-trailing-whitespace)) + +(defvar fill-flowed-encode-tests + '( + ;; The syntax of each list element is: + ;; (INPUT . EXPECTED-OUTPUT) + ("> Thou villainous ill-breeding spongy dizzy-eyed +> reeky elf-skinned pigeon-egg! +>> Thou artless swag-bellied milk-livered +>> dismal-dreaming idle-headed scut! +>>> Thou errant folly-fallen spleeny reeling-ripe +>>> unmuzzled ratsbane! +>>>> Henceforth, the coding style is to be strictly +>>>> enforced, including the use of only upper case. +>>>>> I've noticed a lack of adherence to the coding +>>>>> styles, of late. +>>>>>> Any complaints? +" . "> Thou villainous ill-breeding spongy dizzy-eyed reeky elf-skinned +> pigeon-egg! +>> Thou artless swag-bellied milk-livered dismal-dreaming idle-headed +>> scut! +>>> Thou errant folly-fallen spleeny reeling-ripe unmuzzled ratsbane! +>>>> Henceforth, the coding style is to be strictly enforced, +>>>> including the use of only upper case. +>>>>> I've noticed a lack of adherence to the coding styles, of late. +>>>>>> Any complaints? +") +; (" +;> foo +;> +;> +;> bar +;" . " +;> foo bar +;") + )) + +(defun fill-flowed-test () + (interactive "") + (switch-to-buffer (get-buffer-create "*Format=Flowed test output*")) + (erase-buffer) + (setq show-trailing-whitespace t) + (dolist (test fill-flowed-encode-tests) + (let (start output) + (insert "***** BEGIN TEST INPUT *****\n") + (insert (car test)) + (insert "***** END TEST INPUT *****\n\n") + (insert "***** BEGIN TEST OUTPUT *****\n") + (setq start (point)) + (insert (car test)) + (save-restriction + (narrow-to-region start (point)) + (fill-flowed)) + (setq output (buffer-substring start (point-max))) + (insert "***** END TEST OUTPUT *****\n") + (unless (string= output (cdr test)) + (insert "\n***** BEGIN TEST EXPECTED OUTPUT *****\n") + (insert (cdr test)) + (insert "***** END TEST EXPECTED OUTPUT *****\n")) + (insert "\n\n"))) + (goto-char (point-max))) + (provide 'flow-fill) ;;; flow-fill.el ends here diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index 247de0a..4b2eea2 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -74,11 +74,9 @@ (defcustom gnus-agent-expire-days 7 "Read articles older than this will be expired. -This can also be a list of regexp/day pairs. The regexps will be -matched against group names." +If you wish to disable Agent expiring, see `gnus-agent-enable-expiration'." :group 'gnus-agent - :type '(choice (number :tag "days") - (sexp :tag "List" nil))) + :type '(number :tag "days")) (defcustom gnus-agent-expire-all nil "If non-nil, also expire unread, ticked and dormant articles. @@ -158,7 +156,13 @@ If this is `ask' the hook will query the user." :group 'gnus-agent) (defcustom gnus-agent-consider-all-articles nil - "If non-nil, consider also the read articles for downloading." + "When non-`nil', the agent will let the agent predicate decide +whether articles need to be downloaded or not, for all articles. When +`nil', the default, the agent will only let the predicate decide +whether unread articles are downloaded or not. If you enable this, +groups with large active ranges may open slower and you may also want +to look into the agent expiry settings to block the expiration of +read articles as they would just be downloaded again." :version "21.4" :type 'boolean :group 'gnus-agent) @@ -182,9 +186,19 @@ enable expiration per categories, topics, and groups." (const :format "Disable " DISABLE))) (defcustom gnus-agent-expire-unagentized-dirs t -"Have gnus-agent-expire scan the directories under -\(gnus-agent-directory) for groups that are no longer agentized. When -found, offer to remove them.") + "*Whether expiration should expire in unagentized directories. +Have gnus-agent-expire scan the directories under +\(gnus-agent-directory) for groups that are no longer agentized. +When found, offer to remove them." + :type 'boolean + :group 'gnus-agent) + +(defcustom gnus-agent-auto-agentize-methods '(nntp nnimap) + "Initially, all servers from these methods are agentized. +The user may remove or add servers using the Server buffer. +See Info node `(gnus)Server Buffer'." + :type '(repeat symbol) + :group 'gnus-agent) ;;; Internal variables @@ -214,11 +228,6 @@ NOTES: (defvar gnus-agent-file-loading-cache nil) (defvar gnus-agent-file-header-cache nil) -(defvar gnus-agent-auto-agentize-methods '(nntp nnimap) - "Initially, all servers from these methods are agentized. -The user may remove or add servers using the Server buffer. See Info -node `(gnus)Server Buffer'.") - ;; Dynamic variables (defvar gnus-headers) (defvar gnus-score) @@ -322,29 +331,33 @@ manipulated as follows: value)) (list (quote ,name) --category--temp--) ; access-form ))))) - - (defmacro gnus-agent-cat-name (category) - `(car ,category)) ) +(defmacro gnus-agent-cat-name (category) + `(car ,category)) + +(gnus-agent-cat-defaccessor + gnus-agent-cat-days-until-old agent-days-until-old) +(gnus-agent-cat-defaccessor + gnus-agent-cat-enable-expiration agent-enable-expiration) (gnus-agent-cat-defaccessor - gnus-agent-cat-days-until-old agent-days-until-old) + gnus-agent-cat-groups agent-groups) (gnus-agent-cat-defaccessor - gnus-agent-cat-enable-expiration agent-enable-expiration) + gnus-agent-cat-high-score agent-high-score) (gnus-agent-cat-defaccessor - gnus-agent-cat-groups agent-groups) + gnus-agent-cat-length-when-long agent-length-when-long) (gnus-agent-cat-defaccessor - gnus-agent-cat-high-score agent-high-score) + gnus-agent-cat-length-when-short agent-length-when-short) (gnus-agent-cat-defaccessor - gnus-agent-cat-length-when-long agent-length-when-long) + gnus-agent-cat-low-score agent-low-score) (gnus-agent-cat-defaccessor - gnus-agent-cat-length-when-short agent-length-when-short) + gnus-agent-cat-predicate agent-predicate) (gnus-agent-cat-defaccessor - gnus-agent-cat-low-score agent-low-score) + gnus-agent-cat-score-file agent-score-file) (gnus-agent-cat-defaccessor - gnus-agent-cat-predicate agent-predicate) + gnus-agent-cat-disable-undownloaded-faces agent-disable-undownloaded-faces) (gnus-agent-cat-defaccessor - gnus-agent-cat-score-file agent-score-file) + gnus-agent-cat-enable-undownloaded-faces agent-enable-undownloaded-faces) (eval-when-compile (defsetf gnus-agent-cat-groups (category) (groups) @@ -567,7 +580,7 @@ manipulated as follows: (defun gnus-agent-close-connections () "Close all methods covered by the Gnus agent." - (let ((methods gnus-agent-covered-methods)) + (let ((methods (gnus-agent-covered-methods))) (while methods (gnus-close-server (pop methods))))) @@ -595,10 +608,10 @@ manipulated as follows: ;;;###autoload (defun gnus-agentize () "Allow Gnus to be an offline newsreader. -The normal usage of this command is to put the following as the -last form in your `.gnus.el' file: -\(gnus-agentize) +The gnus-agentize function is now called internally by gnus when +gnus-agent is set. If you wish to avoid calling gnus-agentize, +customize gnus-agent to nil. This will modify the `gnus-setup-news-hook', and `message-send-mail-real-function' variables, and install the Gnus agent @@ -609,18 +622,24 @@ minor mode in all Gnus buffers." (unless gnus-agent-send-mail-function (setq gnus-agent-send-mail-function (or message-send-mail-real-function - message-send-mail-function) + message-send-mail-function) message-send-mail-real-function 'gnus-agent-send-mail)) - (unless gnus-agent-covered-methods - (mapcar - (lambda (server) - (if (memq (car (gnus-server-to-method server)) - gnus-agent-auto-agentize-methods) - (setq gnus-agent-covered-methods - (cons (gnus-server-to-method server) - gnus-agent-covered-methods )))) - (append (list gnus-select-method) gnus-secondary-select-methods)))) + ;; If the servers file doesn't exist, auto-agentize some servers and + ;; save the servers file so this auto-agentizing isn't invoked + ;; again. + (unless (file-exists-p (nnheader-concat gnus-agent-directory "lib/servers")) + (gnus-message 3 "First time agent user, agentizing remote groups...") + (mapc + (lambda (server-or-method) + (let ((method (gnus-server-to-method server-or-method))) + (when (memq (car method) + gnus-agent-auto-agentize-methods) + (push (gnus-method-to-server method) + gnus-agent-covered-methods) + (setq gnus-agent-method-p-cache nil)))) + (cons gnus-select-method gnus-secondary-select-methods)) + (gnus-agent-write-servers))) (defun gnus-agent-queue-setup (&optional group-name) "Make sure the queue group exists. @@ -758,7 +777,7 @@ be a select method." "Synchronize unplugged flags with servers." (interactive) (save-excursion - (dolist (gnus-command-method gnus-agent-covered-methods) + (dolist (gnus-command-method (gnus-agent-covered-methods)) (when (file-exists-p (gnus-agent-lib-file "flags")) (gnus-agent-synchronize-flags-server gnus-command-method))))) @@ -766,7 +785,7 @@ be a select method." "Synchronize flags according to `gnus-agent-synchronize-flags'." (interactive) (save-excursion - (dolist (gnus-command-method gnus-agent-covered-methods) + (dolist (gnus-command-method (gnus-agent-covered-methods)) (when (file-exists-p (gnus-agent-lib-file "flags")) (gnus-agent-possibly-synchronize-flags-server gnus-command-method))))) @@ -801,46 +820,80 @@ be a select method." ;;; Server mode commands ;;; -(defun gnus-agent-add-server (server) +(defun gnus-agent-add-server () "Enroll SERVER in the agent program." - (interactive (list (gnus-server-server-name))) - (unless server - (error "No server on the current line")) - (let ((method (gnus-server-get-method nil (gnus-server-server-name)))) + (interactive) + (let* ((server (gnus-server-server-name)) + (named-server (gnus-server-named-server)) + (method (and server + (gnus-server-get-method nil server)))) + (unless server + (error "No server on the current line")) + (when (gnus-agent-method-p method) (error "Server already in the agent program")) - (push method gnus-agent-covered-methods) + + (push named-server gnus-agent-covered-methods) + + (setq gnus-agent-method-p-cache nil) (gnus-server-update-server server) (gnus-agent-write-servers) (gnus-message 1 "Entered %s into the Agent" server))) -(defun gnus-agent-remove-server (server) +(defun gnus-agent-remove-server () "Remove SERVER from the agent program." - (interactive (list (gnus-server-server-name))) - (unless server - (error "No server on the current line")) - (let ((method (gnus-server-get-method nil (gnus-server-server-name)))) - (unless (gnus-agent-method-p method) + (interactive) + (let* ((server (gnus-server-server-name)) + (named-server (gnus-server-named-server))) + (unless server + (error "No server on the current line")) + + (unless (member named-server gnus-agent-covered-methods) (error "Server not in the agent program")) - (setq gnus-agent-covered-methods - (delete method gnus-agent-covered-methods)) + + (setq gnus-agent-covered-methods + (delete named-server gnus-agent-covered-methods) + gnus-agent-method-p-cache nil) + (gnus-server-update-server server) (gnus-agent-write-servers) (gnus-message 1 "Removed %s from the agent" server))) (defun gnus-agent-read-servers () "Read the alist of covered servers." - (mapcar (lambda (m) - (let ((method (gnus-server-get-method - nil - (or m "native")))) - (if method - (unless (member method gnus-agent-covered-methods) - (push method gnus-agent-covered-methods)) - (gnus-message 1 "Ignoring disappeared server `%s'" m) - (sit-for 1)))) - (gnus-agent-read-file - (nnheader-concat gnus-agent-directory "lib/servers")))) + (setq gnus-agent-covered-methods + (gnus-agent-read-file + (nnheader-concat gnus-agent-directory "lib/servers")) + gnus-agent-method-p-cache nil) + + ;; I am called so early in start-up that I can not validate server + ;; names. When that is the case, I skip the validation. That is + ;; alright as the gnus startup code calls the validate methods + ;; directly. + (if gnus-server-alist + (gnus-agent-read-servers-validate))) + +(defun gnus-agent-read-servers-validate () + (mapcar (lambda (server-or-method) + (let* ((server (if (stringp server-or-method) + server-or-method + (gnus-method-to-server server-or-method))) + (method (gnus-server-to-method server))) + (if method + (unless (member server gnus-agent-covered-methods) + (push server gnus-agent-covered-methods) + (setq gnus-agent-method-p-cache nil)) + (gnus-message 1 "Ignoring disappeared server `%s'" server)))) + (prog1 gnus-agent-covered-methods + (setq gnus-agent-covered-methods nil)))) + +(defun gnus-agent-read-servers-validate-native (native-method) + (setq gnus-agent-covered-methods + (mapcar (lambda (method) + (if (or (not method) + (equal method native-method)) + "native" + method)) gnus-agent-covered-methods))) (defun gnus-agent-write-servers () "Write the alist of covered servers." @@ -850,7 +903,7 @@ be a select method." (file-name-coding-system nnmail-pathname-coding-system) (pathname-coding-system nnmail-pathname-coding-system)) (with-temp-file (nnheader-concat gnus-agent-directory "lib/servers") - (prin1 (mapcar 'gnus-method-simplify gnus-agent-covered-methods) + (prin1 gnus-agent-covered-methods (current-buffer))))) ;;; @@ -1122,6 +1175,27 @@ This can be added to `gnus-select-article-hook' or ;; will add it while reading the file. (gnus-write-active-file file old nil)))) +(defun gnus-agent-possibly-alter-active (group active) + "Possibly expand a group's active range to include articles +downloaded into the agent." + +;; I can't use the agent's active file here as there is no practical +;; mechanism to update the active ranges in that file as the oldest +;; articles are removed from the agent. + (let* ((gnus-command-method (or gnus-command-method + (gnus-find-method-for-group group))) + (alist (gnus-agent-load-alist group))) + + (let ((new-min (or (caar gnus-agent-article-alist) + (car active))) + (new-max (or (caar (last gnus-agent-article-alist)) + (cdr active)))) + + (when (< new-min (car active)) + (setcar active new-min)) + (when (> new-max (cdr active)) + (setcdr active new-max))))) + (defun gnus-agent-save-groups (method) (gnus-agent-save-active-1 method 'gnus-groups-to-gnus-format)) @@ -1191,6 +1265,10 @@ This can be added to `gnus-select-article-hook' or (require 'nnagent) 'nnagent)) +(defun gnus-agent-covered-methods () + "Return the subset of methods that are covered by the agent." + (delq nil (mapcar #'gnus-server-to-method gnus-agent-covered-methods))) + ;;; History functions (defun gnus-agent-history-buffer () @@ -1468,14 +1546,14 @@ variables. Returns the first non-nil value found." (symbol-value (cdr (assq symbol - '((agent-short-article . gnus-agent-short-article) - (agent-long-article . gnus-agent-long-article) - (agent-low-score . gnus-agent-low-score) - (agent-high-score . gnus-agent-high-score) - (agent-days-until-old . gnus-agent-expire-days) - (agent-enable-expiration - . gnus-agent-enable-expiration) - (agent-predicate . gnus-agent-predicate))))))) + '((agent-short-article . gnus-agent-short-article) + (agent-long-article . gnus-agent-long-article) + (agent-low-score . gnus-agent-low-score) + (agent-high-score . gnus-agent-high-score) + (agent-days-until-old . gnus-agent-expire-days) + (agent-enable-expiration + . gnus-agent-enable-expiration) + (agent-predicate . gnus-agent-predicate))))))) (defun gnus-agent-fetch-headers (group &optional force) "Fetch interesting headers into the agent. The group's overview @@ -1719,9 +1797,7 @@ FILE and places the combined headers into `nntp-server-buffer'." (setq uncomp (cons (cons article-id state) uncomp))) sequence))) alist) - (setq alist (sort uncomp - (lambda (first second) - (< (car first) (car second)))))))) + (setq alist (sort uncomp 'car-less-than-car))))) (when changed-version (let ((gnus-agent-article-alist alist)) (gnus-agent-save-alist gnus-agent-read-agentview))) @@ -1804,7 +1880,7 @@ FILE and places the combined headers into `nntp-server-buffer'." (error "No servers are covered by the Gnus agent")) (unless gnus-plugged (error "Can't fetch articles while Gnus is unplugged")) - (let ((methods gnus-agent-covered-methods) + (let ((methods (gnus-agent-covered-methods)) groups group gnus-command-method) (save-excursion (while methods @@ -2425,22 +2501,58 @@ The following commands are available: (defun gnus-predicate-implies-unread (predicate) "Say whether PREDICATE implies unread articles only. It is okay to miss some cases, but there must be no false positives. -That is, if this function returns true, then indeed the predicate must +That is, if this predicate returns true, then indeed the predicate must return only unread articles." - (gnus-function-implies-unread-1 (gnus-category-make-function predicate))) + (eq t (gnus-function-implies-unread-1 + (gnus-category-make-function-1 predicate)))) (defun gnus-function-implies-unread-1 (function) - (cond ((eq function (symbol-function 'gnus-agent-read-p)) - nil) - ((not function) - nil) - ((functionp function) - 'ignore) - ((memq (car function) '(or and not)) - (apply (car function) - (mapcar 'gnus-function-implies-unread-1 (cdr function)))) - (t - (error "Unknown function: %s" function)))) + "Recursively evaluate a predicate function to determine whether it can select +any read articles. Returns t if the function is known to never +return read articles, nil when it is known to always return read +articles, and t_nil when the function may return both read and unread +articles." + (let ((func (car function)) + (args (mapcar 'gnus-function-implies-unread-1 (cdr function)))) + (cond ((eq func 'and) + (cond ((memq t args) ; if any argument returns only unread articles + ;; then that argument constrains the result to only unread articles. + t) + ((memq 't_nil args) ; if any argument is indeterminate + ;; then the result is indeterminate + 't_nil))) + ((eq func 'or) + (cond ((memq nil args) ; if any argument returns read articles + ;; then that argument ensures that the results includes read articles. + nil) + ((memq 't_nil args) ; if any argument is indeterminate + ;; then that argument ensures that the results are indeterminate + 't_nil) + (t ; if all arguments return only unread articles + ;; then the result returns only unread articles + t))) + ((eq func 'not) + (cond ((eq (car args) 't_nil) ; if the argument is indeterminate + ; then the result is indeterminate + (car args)) + (t ; otherwise + ; toggle the result to be the opposite of the argument + (not (car args))))) + ((eq func 'gnus-agent-read-p) + nil) ; The read predicate NEVER returns unread articles + ((eq func 'gnus-agent-false) + t) ; The false predicate returns t as the empty set excludes all read articles + ((eq func 'gnus-agent-true) + nil) ; The true predicate ALWAYS returns read articles + ((catch 'found-match + (let ((alist gnus-category-predicate-alist)) + (while alist + (if (eq func (cdar alist)) + (throw 'found-match t) + (setq alist (cdr alist)))))) + 't_nil) ; All other predicates return read and unread articles + (t + (error "Unknown predicate function: %s" function))))) (defun gnus-group-category (group) "Return the category GROUP belongs to." @@ -2479,29 +2591,32 @@ FORCE is equivalent to setting the expiration predicates to true." (if (not group) (gnus-agent-expire articles group force) - (if (or (not (eq articles t)) - (yes-or-no-p - (concat "Are you sure that you want to " - "expire all articles in " group "."))) - (let ((gnus-command-method (gnus-find-method-for-group group)) - (overview (gnus-get-buffer-create " *expire overview*")) - orig) - (unwind-protect - (let ((active-file (gnus-agent-lib-file "active"))) - (when (file-exists-p active-file) - (with-temp-buffer - (nnheader-insert-file-contents active-file) - (gnus-active-to-gnus-format - gnus-command-method - (setq orig (gnus-make-hashtable - (count-lines (point-min) (point-max)))))) - (save-excursion - (gnus-agent-expire-group-1 - group overview (gnus-gethash-safe group orig) - articles force)) - (gnus-agent-write-active active-file orig t))) - (kill-buffer overview)))) - (gnus-message 4 "Expiry...done"))) + (let ( ;; Bind gnus-agent-expire-stats to enable tracking of + ;; expiration statistics of this single group + (gnus-agent-expire-stats (list 0 0 0.0))) + (if (or (not (eq articles t)) + (yes-or-no-p + (concat "Are you sure that you want to " + "expire all articles in " group "."))) + (let ((gnus-command-method (gnus-find-method-for-group group)) + (overview (gnus-get-buffer-create " *expire overview*")) + orig) + (unwind-protect + (let ((active-file (gnus-agent-lib-file "active"))) + (when (file-exists-p active-file) + (with-temp-buffer + (nnheader-insert-file-contents active-file) + (gnus-active-to-gnus-format + gnus-command-method + (setq orig (gnus-make-hashtable + (count-lines (point-min) (point-max)))))) + (save-excursion + (gnus-agent-expire-group-1 + group overview (gnus-gethash-safe group orig) + articles force)) + (gnus-agent-write-active active-file orig t))) + (kill-buffer overview)))) + (gnus-message 4 (gnus-agent-expire-done-message))))) (defun gnus-agent-expire-group-1 (group overview active articles force) ;; Internal function - requires caller to have set @@ -2514,12 +2629,18 @@ FORCE is equivalent to setting the expiration predicates to true." (cons dir (symbol-value 'gnus-agent-expire-current-dirs)))) - (if (eq 'DISABLE (gnus-agent-find-parameter group - 'agent-enable-expiration)) + (if (and (not force) + (eq 'DISABLE (gnus-agent-find-parameter group + 'agent-enable-expiration))) (gnus-message 5 "Expiry skipping over %s" group) (gnus-message 5 "Expiring articles in %s" group) (gnus-agent-load-alist group) - (let* ((info (gnus-get-info group)) + (let* ((stats (if (boundp 'gnus-agent-expire-stats) + ;; Use the list provided by my caller + (symbol-value 'gnus-agent-expire-stats) + ;; otherwise use my own temporary list + (list 0 0 0.0))) + (info (gnus-get-info group)) (alist gnus-agent-article-alist) (day (- (time-to-days (current-time)) (gnus-agent-find-parameter group 'agent-days-until-old))) @@ -2559,7 +2680,7 @@ FORCE is equivalent to setting the expiration predicates to true." (cons (caar alist) (caar (last alist)))) (sort articles '<))))) - (marked ;; More articles that are exluded from the + (marked ;; More articles that are excluded from the ;; expiration process (cond (gnus-agent-expire-all ;; All articles are unmarked by global decree @@ -2697,7 +2818,8 @@ line." (point) nov-file))) (while dlist (let ((new-completed (truncate (* 100.0 (/ (setq cnt (1+ cnt)) - len))))) + len)))) + message-log-max) (when (> new-completed completed) (setq completed new-completed) (gnus-message 7 "%3d%% completed..." completed))) @@ -2711,16 +2833,16 @@ line." (point) nov-file))) ;; Kept articles are unread, marked, or special. (keep (gnus-agent-message 10 - "gnus-agent-expire: Article %d: Kept %s article." - article-number keep) + "gnus-agent-expire: %s:%d: Kept %s article%s." + group article-number keep (if fetch-date " and file" "")) (when fetch-date (unless (file-exists-p (concat dir (number-to-string article-number))) (setf (nth 1 entry) nil) (gnus-agent-message 3 "gnus-agent-expire cleared \ -download flag on article %d as the cached article file is missing." - (caar dlist))) +download flag on %s:%d as the cached article file is missing." + group (caar dlist))) (unless marker (gnus-message 1 "gnus-agent-expire detected a \ missing NOV entry. Run gnus-agent-regenerate-group to restore it."))) @@ -2756,8 +2878,11 @@ missing NOV entry. Run gnus-agent-regenerate-group to restore it."))) (let ((actions nil)) (when (memq type '(forced expired)) (ignore-errors ; Just being paranoid. - (delete-file (concat dir (number-to-string - article-number))) + (let ((file-name (concat dir (number-to-string + article-number)))) + (incf (nth 2 stats) (nth 7 (file-attributes file-name))) + (incf (nth 1 stats)) + (delete-file file-name)) (push "expired cached article" actions)) (setf (nth 1 entry) nil) ) @@ -2765,7 +2890,13 @@ missing NOV entry. Run gnus-agent-regenerate-group to restore it."))) (when marker (push "NOV entry removed" actions) (goto-char marker) - (gnus-delete-line)) + + (incf (nth 0 stats)) + + (let ((from (gnus-point-at-bol)) + (to (progn (forward-line 1) (point)))) + (incf (nth 2 stats) (- to from)) + (delete-region from to))) ;; If considering all articles is set, I can only ;; expire article IDs that are no longer in the @@ -2779,13 +2910,14 @@ missing NOV entry. Run gnus-agent-regenerate-group to restore it."))) (push (format "Removed %s article number from \ article alist" type) actions)) - (gnus-agent-message 8 "gnus-agent-expire: Article %d: %s" - article-number - (mapconcat 'identity actions ", ")))) + (when actions + (gnus-agent-message 8 "gnus-agent-expire: %s:%d: %s" + group article-number + (mapconcat 'identity actions ", "))))) (t (gnus-agent-message - 10 "gnus-agent-expire: Article %d: Article kept as \ -expiration tests failed." article-number) + 10 "gnus-agent-expire: %s:%d: Article kept as \ +expiration tests failed." group article-number) (gnus-agent-append-to-list tail-alist (cons article-number fetch-date))) ) @@ -2839,10 +2971,13 @@ FORCE is equivalent to setting the expiration predicates to true." (if (or (not (eq articles t)) (yes-or-no-p "Are you sure that you want to expire all \ articles in every agentized group.")) - (let ((methods gnus-agent-covered-methods) + (let ((methods (gnus-agent-covered-methods)) ;; Bind gnus-agent-expire-current-dirs to enable tracking ;; of agent directories. (gnus-agent-expire-current-dirs nil) + ;; Bind gnus-agent-expire-stats to enable tracking of + ;; expiration statistics across all groups + (gnus-agent-expire-stats (list 0 0 0.0)) gnus-command-method overview orig) (setq overview (gnus-get-buffer-create " *expire overview*")) (unwind-protect @@ -2867,7 +3002,25 @@ articles in every agentized group.")) (gnus-agent-write-active active-file orig t)))) (kill-buffer overview)) (gnus-agent-expire-unagentized-dirs) - (gnus-message 4 "Expiry...done"))))) + (gnus-message 4 (gnus-agent-expire-done-message)))))) + +(defun gnus-agent-expire-done-message () + (if (and (> gnus-verbose 4) + (boundp 'gnus-agent-expire-stats)) + (let* ((stats (symbol-value 'gnus-agent-expire-stats)) + (size (nth 2 stats)) + (units '(B KB MB GB))) + (while (and (> size 1024.0) + (cdr units)) + (setq size (/ size 1024.0) + units (cdr units))) + + (format "Expiry recovered %d NOV entries, deleted %d files,\ + and freed %f %s." + (nth 0 stats) + (nth 1 stats) + size (car units))) + "Expiry...done")) (defun gnus-agent-expire-unagentized-dirs () (when (and gnus-agent-expire-unagentized-dirs @@ -2932,7 +3085,7 @@ articles in every agentized group.")) deleting them?"))) (while to-remove (let ((dir (pop to-remove))) - (if (gnus-y-or-n-p (format "Delete %s?" dir)) + (if (gnus-y-or-n-p (format "Delete %s? " dir)) (let* (delete-recursive (delete-recursive (function @@ -2978,7 +3131,12 @@ articles in every agentized group.")) (gnus-agent-append-to-list tail-unread candidate) nil) ((> candidate max) - (setq read (cdr read)))))))) + (setq read (cdr read)) + ;; return t so that I always loop one more + ;; time. If I just iterated off the end of + ;; read, min will become nil and the current + ;; candidate will be added to the unread list. + t)))))) (while known (gnus-agent-append-to-list tail-unread (car (pop known)))) (cdr unread))) @@ -3182,237 +3340,228 @@ If REREAD is not nil, downloaded articles are marked as unread." def) def select))) - (intern-soft - (read-string - "Reread (nil)? (t=>all, nil=>none, some=>all downloaded): ")))) - (gnus-message 5 "Regenerating in %s" group) - (let* ((gnus-command-method (or gnus-command-method - (gnus-find-method-for-group group))) - (file (gnus-agent-article-name ".overview" group)) - (dir (file-name-directory file)) - point - (downloaded (if (file-exists-p dir) - (sort (mapcar (lambda (name) (string-to-int name)) - (directory-files dir nil "^[0-9]+$" t)) - '>) - (progn (gnus-make-directory dir) nil))) - dl nov-arts - alist header - regenerated) - - (mm-with-unibyte-buffer - (if (file-exists-p file) - (let ((nnheader-file-coding-system - gnus-agent-file-coding-system)) - (nnheader-insert-file-contents file))) - (set-buffer-modified-p nil) - - ;; Load the article IDs found in the overview file. As a - ;; side-effect, validate the file contents. - (let ((load t)) - (while load - (setq load nil) - (goto-char (point-min)) - (while (< (point) (point-max)) - (cond ((and (looking-at "[0-9]+\t") - (<= (- (match-end 0) (match-beginning 0)) 9)) - (push (read (current-buffer)) nov-arts) - (forward-line 1) - (let ((l1 (car nov-arts)) - (l2 (cadr nov-arts))) - (cond ((not l2) - nil) - ((< l1 l2) - (gnus-message 3 "gnus-agent-regenerate-group: NOV\ + (catch 'mark + (while (let ((c (read-char-exclusive + "Mark as unread: (n)one / (a)ll / all (d)ownloaded articles? (n)" + ))) + (cond ((or (eq c ?\r) (eq c ?n) (eq c ?N)) + (throw 'mark nil)) + ((or (eq c ?a) (eq c ?A)) + (throw 'mark t)) + ((or (eq c ?d) (eq c ?D)) + (throw 'mark 'some))) + (message "Ignoring unexpected input") + (sit-for 1) + t))))) + + (when group + (gnus-message 5 "Regenerating in %s" group) + (let* ((gnus-command-method (or gnus-command-method + (gnus-find-method-for-group group))) + (file (gnus-agent-article-name ".overview" group)) + (dir (file-name-directory file)) + point + (downloaded (if (file-exists-p dir) + (sort (mapcar (lambda (name) (string-to-int name)) + (directory-files dir nil "^[0-9]+$" t)) + '>) + (progn (gnus-make-directory dir) nil))) + dl nov-arts + alist header + regenerated) + + (mm-with-unibyte-buffer + (if (file-exists-p file) + (let ((nnheader-file-coding-system + gnus-agent-file-coding-system)) + (nnheader-insert-file-contents file))) + (set-buffer-modified-p nil) + + ;; Load the article IDs found in the overview file. As a + ;; side-effect, validate the file contents. + (let ((load t)) + (while load + (setq load nil) + (goto-char (point-min)) + (while (< (point) (point-max)) + (cond ((and (looking-at "[0-9]+\t") + (<= (- (match-end 0) (match-beginning 0)) 9)) + (push (read (current-buffer)) nov-arts) + (forward-line 1) + (let ((l1 (car nov-arts)) + (l2 (cadr nov-arts))) + (cond ((not l2) + nil) + ((< l1 l2) + (gnus-message 3 "gnus-agent-regenerate-group: NOV\ entries are NOT in ascending order.") - ;; Don't sort now as I haven't verified - ;; that every line begins with a number - (setq load t)) - ((= l1 l2) - (forward-line -1) - (gnus-message 4 "gnus-agent-regenerate-group: NOV\ + ;; Don't sort now as I haven't verified + ;; that every line begins with a number + (setq load t)) + ((= l1 l2) + (forward-line -1) + (gnus-message 4 "gnus-agent-regenerate-group: NOV\ entries contained duplicate of article %s. Duplicate deleted." l1) - (gnus-delete-line) - (setq nov-arts (cdr nov-arts)))))) - (t - (gnus-message 1 "gnus-agent-regenerate-group: NOV\ + (gnus-delete-line) + (setq nov-arts (cdr nov-arts)))))) + (t + (gnus-message 1 "gnus-agent-regenerate-group: NOV\ entries contained line that did not begin with an article number. Deleted\ line.") - (gnus-delete-line)))) - (if load - (progn - (gnus-message 5 "gnus-agent-regenerate-group: Sorting NOV\ + (gnus-delete-line)))) + (if load + (progn + (gnus-message 5 "gnus-agent-regenerate-group: Sorting NOV\ entries into ascending order.") - (sort-numeric-fields 1 (point-min) (point-max)) + (sort-numeric-fields 1 (point-min) (point-max)) (setq nov-arts nil))))) - (gnus-agent-check-overview-buffer) - - ;; Construct a new article alist whose nodes match every header - ;; in the .overview file. As a side-effect, missing headers are - ;; reconstructed from the downloaded article file. - (while (or downloaded nov-arts) - (cond ((and downloaded - (or (not nov-arts) - (> (car downloaded) (car nov-arts)))) - ;; This entry is missing from the overview file - (gnus-message 3 "Regenerating NOV %s %d..." group - (car downloaded)) - (let ((file (concat dir (number-to-string (car downloaded))))) - (mm-with-unibyte-buffer - (nnheader-insert-file-contents file) - (nnheader-remove-body) - (setq header (nnheader-parse-naked-head))) - (mail-header-set-number header (car downloaded)) - (if nov-arts - (let ((key (concat "^" (int-to-string (car nov-arts)) - "\t"))) - (or (re-search-backward key nil t) - (re-search-forward key)) - (forward-line 1)) - (goto-char (point-min))) - (nnheader-insert-nov header)) - (setq nov-arts (cons (car downloaded) nov-arts))) - ((eq (car downloaded) (car nov-arts)) - ;; This entry in the overview has been downloaded - (push (cons (car downloaded) - (time-to-days - (nth 5 (file-attributes - (concat dir (number-to-string - (car downloaded))))))) alist) - (setq downloaded (cdr downloaded)) - (setq nov-arts (cdr nov-arts))) - (t - ;; This entry in the overview has not been downloaded - (push (cons (car nov-arts) nil) alist) - (setq nov-arts (cdr nov-arts))))) - - ;; When gnus-agent-consider-all-articles is set, - ;; gnus-agent-regenerate-group should NOT remove article IDs from - ;; the alist. Those IDs serve as markers to indicate that an - ;; attempt has been made to fetch that article's header. - - ;; When gnus-agent-consider-all-articles is NOT set, - ;; gnus-agent-regenerate-group can remove the article ID of every - ;; article (with the exception of the last ID in the list - it's - ;; special) that no longer appears in the overview. In this - ;; situtation, the last article ID in the list implies that it, - ;; and every article ID preceeding it, have been fetched from the - ;; server. - (if gnus-agent-consider-all-articles - ;; Restore all article IDs that were not found in the overview file. - (let* ((n (cons nil alist)) - (merged n) - (o (gnus-agent-load-alist group))) - (while o - (let ((nID (caadr n)) - (oID (caar o))) - (cond ((not nID) - (setq n (setcdr n (list (list oID)))) - (setq o (cdr o))) - ((< oID nID) - (setcdr n (cons (list oID) (cdr n))) - (setq o (cdr o))) - ((= oID nID) - (setq o (cdr o)) - (setq n (cdr n))) - (t - (setq n (cdr n)))))) - (setq alist (cdr merged))) - ;; Restore the last article ID if it is not already in the new alist - (let ((n (last alist)) - (o (last (gnus-agent-load-alist group)))) - (cond ((not o) - nil) - ((not n) - (push (cons (caar o) nil) alist)) - ((< (caar n) (caar o)) - (setcdr n (list (car o))))))) - - (let ((inhibit-quit t)) - (if (setq regenerated (buffer-modified-p)) - (write-region-as-coding-system - gnus-agent-file-coding-system - (point-min) (point-max) file nil 'silent)) - - (setq regenerated (or regenerated - (and reread gnus-agent-article-alist) - (not (equal alist gnus-agent-article-alist))) - ) - - (setq gnus-agent-article-alist alist) - - (when regenerated - (gnus-agent-save-alist group))) - ) - - (when (and reread gnus-agent-article-alist) - (gnus-make-ascending-articles-unread - group - (delq nil (mapcar (function (lambda (c) - (cond ((eq reread t) - (car c)) - ((cdr c) - (car c))))) - gnus-agent-article-alist))) - - (when (gnus-buffer-live-p gnus-group-buffer) - (gnus-group-update-group group t) - (sit-for 0)) - ) - - (gnus-message 5 nil) - regenerated)) + (gnus-agent-check-overview-buffer) + + ;; Construct a new article alist whose nodes match every header + ;; in the .overview file. As a side-effect, missing headers are + ;; reconstructed from the downloaded article file. + (while (or downloaded nov-arts) + (cond ((and downloaded + (or (not nov-arts) + (> (car downloaded) (car nov-arts)))) + ;; This entry is missing from the overview file + (gnus-message 3 "Regenerating NOV %s %d..." group + (car downloaded)) + (let ((file (concat dir (number-to-string (car downloaded))))) + (mm-with-unibyte-buffer + (nnheader-insert-file-contents file) + (nnheader-remove-body) + (setq header (nnheader-parse-naked-head))) + (mail-header-set-number header (car downloaded)) + (if nov-arts + (let ((key (concat "^" (int-to-string (car nov-arts)) + "\t"))) + (or (re-search-backward key nil t) + (re-search-forward key)) + (forward-line 1)) + (goto-char (point-min))) + (nnheader-insert-nov header)) + (setq nov-arts (cons (car downloaded) nov-arts))) + ((eq (car downloaded) (car nov-arts)) + ;; This entry in the overview has been downloaded + (push (cons (car downloaded) + (time-to-days + (nth 5 (file-attributes + (concat dir (number-to-string + (car downloaded))))))) alist) + (setq downloaded (cdr downloaded)) + (setq nov-arts (cdr nov-arts))) + (t + ;; This entry in the overview has not been downloaded + (push (cons (car nov-arts) nil) alist) + (setq nov-arts (cdr nov-arts))))) + + ;; When gnus-agent-consider-all-articles is set, + ;; gnus-agent-regenerate-group should NOT remove article IDs from + ;; the alist. Those IDs serve as markers to indicate that an + ;; attempt has been made to fetch that article's header. + + ;; When gnus-agent-consider-all-articles is NOT set, + ;; gnus-agent-regenerate-group can remove the article ID of every + ;; article (with the exception of the last ID in the list - it's + ;; special) that no longer appears in the overview. In this + ;; situtation, the last article ID in the list implies that it, + ;; and every article ID preceeding it, have been fetched from the + ;; server. + + (if gnus-agent-consider-all-articles + ;; Restore all article IDs that were not found in the overview file. + (let* ((n (cons nil alist)) + (merged n) + (o (gnus-agent-load-alist group))) + (while o + (let ((nID (caadr n)) + (oID (caar o))) + (cond ((not nID) + (setq n (setcdr n (list (list oID)))) + (setq o (cdr o))) + ((< oID nID) + (setcdr n (cons (list oID) (cdr n))) + (setq o (cdr o))) + ((= oID nID) + (setq o (cdr o)) + (setq n (cdr n))) + (t + (setq n (cdr n)))))) + (setq alist (cdr merged))) + ;; Restore the last article ID if it is not already in the new alist + (let ((n (last alist)) + (o (last (gnus-agent-load-alist group)))) + (cond ((not o) + nil) + ((not n) + (push (cons (caar o) nil) alist)) + ((< (caar n) (caar o)) + (setcdr n (list (car o))))))) + + (let ((inhibit-quit t)) + (if (setq regenerated (buffer-modified-p)) + (write-region-as-coding-system + gnus-agent-file-coding-system + (point-min) (point-max) file nil 'silent)) + + (setq regenerated (or regenerated + (and reread gnus-agent-article-alist) + (not (equal alist gnus-agent-article-alist)))) + + (setq gnus-agent-article-alist alist) + + (when regenerated + (gnus-agent-save-alist group) + + ;; I have to alter the group's active range NOW as + ;; gnus-make-ascending-articles-unread will use it to + ;; recalculate the number of unread articles in the group + + (let ((group (gnus-group-real-name group)) + (group-active (gnus-active group))) + (when group-active + (let ((new-min (or (caar gnus-agent-article-alist) + (car group-active))) + (new-max (or (caar (last gnus-agent-article-alist)) + (cdr group-active)))) + + (when (< new-min (car group-active)) + (setcar group-active new-min)) + + (when (> new-max (cdr group-active)) + (setcdr group-active new-max)))))))) + + (when (and reread gnus-agent-article-alist) + (gnus-make-ascending-articles-unread + group + (delq nil (mapcar (function (lambda (c) + (cond ((eq reread t) + (car c)) + ((cdr c) + (car c))))) + gnus-agent-article-alist))) + + (when (gnus-buffer-live-p gnus-group-buffer) + (gnus-group-update-group group t) + (sit-for 0))) + + (gnus-message 5 nil) + regenerated))) ;;;###autoload (defun gnus-agent-regenerate (&optional clean reread) "Regenerate all agent covered files. -If CLEAN, don't read existing active files." +If CLEAN, obsolete (ignore)." (interactive "P") (let (regenerated) (gnus-message 4 "Regenerating Gnus agent files...") - (dolist (gnus-command-method gnus-agent-covered-methods) - (let ((active-file (gnus-agent-lib-file "active")) - active-hashtb active-changed - point) - (gnus-make-directory (file-name-directory active-file)) - (if clean - (setq active-hashtb (gnus-make-hashtable 1000)) - (mm-with-unibyte-buffer - (if (file-exists-p active-file) - (let ((nnheader-file-coding-system - gnus-agent-file-coding-system)) - (nnheader-insert-file-contents active-file)) - (setq active-changed t)) - (gnus-active-to-gnus-format - nil (setq active-hashtb - (gnus-make-hashtable - (count-lines (point-min) (point-max))))))) + (dolist (gnus-command-method (gnus-agent-covered-methods)) (dolist (group (gnus-groups-from-server gnus-command-method)) (setq regenerated (or (gnus-agent-regenerate-group group reread) - regenerated)) - (let ((min (or (caar gnus-agent-article-alist) 1)) - (max (or (caar (last gnus-agent-article-alist)) 0)) - (active (gnus-gethash-safe (gnus-group-real-name group) - active-hashtb)) - (read (gnus-info-read (gnus-get-info group)))) - (if (not active) - (progn - (setq active (cons min max) - active-changed t) - (gnus-sethash group active active-hashtb)) - (when (> (car active) min) - (setcar active min) - (setq active-changed t)) - (when (< (cdr active) max) - (setcdr active max) - (setq active-changed t))))) - (when active-changed - (setq regenerated t) - (gnus-message 4 "Regenerate %s" active-file) - (let ((nnmail-active-file-coding-system - gnus-agent-file-coding-system)) - (gnus-write-active-file active-file active-hashtb))))) + regenerated)))) (gnus-message 4 "Regenerating Gnus agent files...done") + regenerated)) (defun gnus-agent-go-online (&optional force) @@ -3441,8 +3590,7 @@ If CLEAN, don't read existing active files." (if (eq status 'offline) 'online 'offline)))) (defun gnus-agent-group-covered-p (group) - (member (gnus-group-method group) - gnus-agent-covered-methods)) + (gnus-agent-method-p (gnus-group-method group))) (add-hook 'gnus-group-prepare-hook (lambda () diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index 9c5399e..549117a 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -41,6 +41,10 @@ (require 'gnus-win) (require 'alist) (require 'mime-view) +(when (static-if (featurep 'xemacs) + (console-on-window-system-p) + window-system) + (require 'mime-image)) (require 'wid-edit) ;; Avoid byte-compile warnings. @@ -159,7 +163,7 @@ "X-Virus-Scanned" "X-Delivery-Agent" "Posted-Date" "X-Gateway" "X-Local-Origin" "X-Local-Destination" "X-UserInfo1" "X-Received-Date" "X-Hashcash" "Face" "X-DMCA-Notifications" - "X-Abuse-and-DMCA-Info" "X-Postfilter")) + "X-Abuse-and-DMCA-Info" "X-Postfilter" "X-Gpg-.*" "X-Disclaimer")) "*All headers that start with this regexp will be hidden. This variable can also be a list of regexps of headers to be ignored. If `gnus-visible-headers' is non-nil, this variable will be ignored." @@ -253,8 +257,8 @@ regexp. If it matches, the text in question is not a signature." :type 'sexp :group 'gnus-article-hiding) -;; Fixme: This isn't the right thing for mixed graphical and and -;; non-graphical frames in a session. +;; Fixme: This isn't the right thing for mixed graphical and non-graphical +;; frames in a session. (defcustom gnus-article-x-face-command (cond (noninteractive @@ -434,7 +438,9 @@ and the latter avoids underlining any whitespace at all." Example: (_/*word*/_)." :group 'gnus-article-emphasis) -(defface gnus-emphasis-strikethru '((t (:strikethru t))) +(defface gnus-emphasis-strikethru (if (featurep 'xemacs) + '((t (:strikethru t))) + '((t (:strike-through t)))) "Face used for displaying strike-through text (-word-)." :group 'gnus-article-emphasis) @@ -680,7 +686,9 @@ Obsolete; use the face `gnus-signature-face' for customizations instead." (:foreground "MidnightBlue" :italic t)) (t (:italic t))) - "Face used for displaying newsgroups headers." + "Face used for displaying newsgroups headers. +In the default setup this face is only used for crossposted +articles." :group 'gnus-article-headers :group 'gnus-article-highlight) @@ -715,17 +723,17 @@ Obsolete; use the face `gnus-signature-face' for customizations instead." ("Subject" nil gnus-header-subject-face) ("Newsgroups:.*," nil gnus-header-newsgroups-face) ("" gnus-header-name-face gnus-header-content-face)) - "*Controls highlighting of article header. + "*Controls highlighting of article headers. An alist of the form (HEADER NAME CONTENT). -HEADER is a regular expression which should match the name of an -header header and NAME and CONTENT are either face names or nil. +HEADER is a regular expression which should match the name of a +header and NAME and CONTENT are either face names or nil. The name of each header field will be displayed using the face -specified by the first element in the list where HEADER match the -header name and NAME is non-nil. Similarly, the content will be -displayed by the first non-nil matching CONTENT face." +specified by the first element in the list where HEADER matches +the header name and NAME is non-nil. Similarly, the content will +be displayed by the first non-nil matching CONTENT face." :group 'gnus-article-headers :group 'gnus-article-highlight :type '(repeat (list (regexp :tag "Header") @@ -1034,7 +1042,7 @@ See Info node `(gnus)Customizing Articles' for details." :link '(custom-manual "(gnus)Customizing Articles") :type gnus-article-treat-custom) -(make-obsolete-variable 'gnus-treat-strip-pgp +(make-obsolete-variable 'gnus-treat-strip-pgp "This option is obsolete in Gnus 5.10.") (defcustom gnus-treat-strip-pem nil @@ -1196,7 +1204,10 @@ See Info node `(gnus)Customizing Articles' for details." :type gnus-article-treat-custom) (put 'gnus-treat-overstrike 'highlight t) -(defcustom gnus-treat-display-xface +(make-obsolete-variable 'gnus-treat-display-xface + 'gnus-treat-display-x-face) + +(defcustom gnus-treat-display-x-face (and (not noninteractive) (or (memq gnus-article-x-face-command '(x-face-decode-message-header @@ -1216,8 +1227,25 @@ See Info node `(gnus)Customizing Articles' and Info node ;;:version "21.1" :link '(custom-manual "(gnus)Customizing Articles") :link '(custom-manual "(gnus)X-Face") - :type gnus-article-treat-head-custom) -(put 'gnus-treat-display-xface 'highlight t) + :type gnus-article-treat-head-custom + :set (lambda (symbol value) + (set-default + symbol + (cond ((or (boundp symbol) (get symbol 'saved-value)) + value) + ((boundp 'gnus-treat-display-xface) + (message "\ +** gnus-treat-display-xface is an obsolete variable;\ + use gnus-treat-display-x-face instead") + (default-value 'gnus-treat-display-xface)) + ((get 'gnus-treat-display-xface 'saved-value) + (message "\ +** gnus-treat-display-xface is an obsolete variable;\ + use gnus-treat-display-x-face instead") + (eval (car (get 'gnus-treat-display-xface 'saved-value)))) + (t + value))))) +(put 'gnus-treat-display-x-face 'highlight t) (defcustom gnus-article-should-use-smiley-mule (not (or (featurep 'xemacs) @@ -1340,12 +1368,12 @@ See Info node `(gnus)Customizing Articles' and Info node 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. @@ -1433,7 +1461,8 @@ It is a string, such as \"PGP\". If nil, ask user." "Function used for converting HTML into text.") (defcustom gnus-use-idna (and (condition-case nil (require 'idna) (file-error)) - (mm-coding-system-p 'utf-8)) + (mm-coding-system-p 'utf-8) + (executable-find idna-program)) "Whether IDNA decoding of headers is used when viewing messages. This requires GNU Libidn, and by default only enabled if it is found." :group 'gnus-article-headers @@ -1498,7 +1527,7 @@ This requires GNU Libidn, and by default only enabled if it is found." (gnus-treat-fold-headers gnus-article-treat-fold-headers) ;; Displaying X-Face should be done after unfolding headers ;; to protect bitmap lines. - (gnus-treat-display-xface gnus-article-display-x-face) + (gnus-treat-display-x-face gnus-article-display-x-face) (gnus-treat-fold-newsgroups gnus-article-treat-fold-newsgroups) (gnus-treat-buttonize-head gnus-article-add-buttons-to-head) (gnus-treat-display-smileys gnus-treat-smiley) @@ -1797,12 +1826,19 @@ always hide." (gnus-article-hide-header "reply-to") (let ((from (message-fetch-field "from")) (reply-to (message-fetch-field "reply-to"))) - (when (and - from reply-to - (ignore-errors - (gnus-string-equal - (nth 1 (mail-extract-address-components from)) - (nth 1 (mail-extract-address-components reply-to))))) + (when + (and + from reply-to + (ignore-errors + (equal + (sort (mapcar + (lambda (x) (downcase (cadr x))) + (mail-extract-address-components from t)) + 'string<) + (sort (mapcar + (lambda (x) (downcase (cadr x))) + (mail-extract-address-components reply-to t)) + 'string<)))) (gnus-article-hide-header "reply-to"))))) ((eq elem 'date) (let ((date (message-fetch-field "date"))) @@ -1890,14 +1926,15 @@ always hide." (forward-line 1)))))) (defun article-treat-dumbquotes () - "Translate M****s*** sm*rtq**t*s into proper text. + "Translate M****s*** sm*rtq**t*s and other symbols into proper text. Note that this function guesses whether a character is a sm*rtq**t* or not, so it should only be used interactively. -Sm*rtq**t*s are M****s***'s unilateral extension to the character map -in an attempt to provide more quoting characters. If you see -something like \\222 or \\264 where you're expecting some kind of -apostrophe or quotation mark, then try this wash." +Sm*rtq**t*s are M****s***'s unilateral extension to the +iso-8859-1 character map in an attempt to provide more quoting +characters. If you see something like \\222 or \\264 where +you're expecting some kind of apostrophe or quotation mark, then +try this wash." (interactive) (article-translate-strings gnus-article-dumbquotes-map)) @@ -2118,20 +2155,40 @@ unfolded." (defun article-display-face () "Display any Face headers in the header." (interactive) - (gnus-with-article-headers - (let ((face (message-fetch-field "face"))) - (when face - (let ((png (gnus-convert-face-to-png face)) - image) - (when png - (setq image (gnus-create-image png 'png t)) - (gnus-article-goto-header "from") - (when (bobp) - (insert "From: [no `from' set]\n") - (forward-char -17)) - (gnus-add-wash-type 'face) - (gnus-add-image 'face image) - (gnus-put-image image))))))) + (let ((wash-face-p buffer-read-only)) + (gnus-with-article-headers + ;; When displaying parts, this function can be called several times on + ;; the same article, without any intended toggle semantic (as typing `W + ;; D d' would have). So face deletion must occur only when we come from + ;; an interactive command, that is when the *Article* buffer is + ;; read-only. + (if (and wash-face-p (memq 'face gnus-article-wash-types)) + (gnus-delete-images 'face) + (let (face faces) + (save-excursion + (when (and wash-face-p + (progn + (goto-char (point-min)) + (not (re-search-forward "^Face:[\t ]*" nil t))) + (gnus-buffer-live-p gnus-original-article-buffer)) + (set-buffer gnus-original-article-buffer)) + (save-restriction + (mail-narrow-to-head) + (while (gnus-article-goto-header "Face") + (push (mail-header-field-value) faces)))) + (while (setq face (pop faces)) + (let ((png (gnus-convert-face-to-png face)) + image) + (when png + (setq image (gnus-create-image png 'png t)) + (gnus-article-goto-header "from") + (when (bobp) + (insert "From: [no `from' set]\n") + (forward-char -17)) + (gnus-add-wash-type 'face) + (gnus-add-image 'face image) + (gnus-put-image image nil 'face)))))) + ))) (defun article-display-x-face (&optional force) "Look for an X-Face header and display it if present." @@ -2141,7 +2198,8 @@ unfolded." ;; Delete the old process, if any. (when (process-status "article-x-face") (delete-process "article-x-face")) - (if (memq 'xface gnus-article-wash-types) + ;; See the comment in `article-display-face'. + (if (and wash-face-p (memq 'xface gnus-article-wash-types)) ;; We have already displayed X-Faces, so we remove them ;; instead. (gnus-delete-images 'xface) @@ -2176,23 +2234,25 @@ unfolded." (not (string-match gnus-article-x-face-too-ugly from))))) ;; We display the face. - (if (symbolp gnus-article-x-face-command) - ;; The command is a lisp function, so we call it. - (if (functionp gnus-article-x-face-command) - (funcall gnus-article-x-face-command face) - (error "%s is not a function" gnus-article-x-face-command)) - ;; The command is a string, so we interpret the command - ;; as a, well, command, and fork it off. - (let ((process-connection-type nil)) - (process-kill-without-query - (start-process - "article-x-face" nil shell-file-name shell-command-switch - gnus-article-x-face-command)) - (with-temp-buffer - (insert face) - (process-send-region "article-x-face" - (point-min) (point-max))) - (process-send-eof "article-x-face"))))))))) + (cond ((stringp gnus-article-x-face-command) + ;; The command is a string, so we interpret the command + ;; as a, well, command, and fork it off. + (let ((process-connection-type nil)) + (process-kill-without-query + (start-process + "article-x-face" nil shell-file-name + shell-command-switch gnus-article-x-face-command)) + (with-temp-buffer + (insert face) + (process-send-region "article-x-face" + (point-min) (point-max))) + (process-send-eof "article-x-face"))) + ((functionp gnus-article-x-face-command) + ;; The command is a lisp function, so we call it. + (funcall gnus-article-x-face-command face)) + (t + (error "%s is not a function" + gnus-article-x-face-command))))))))) (defun article-decode-mime-words () "Decode all MIME-encoded words in the article." @@ -2251,7 +2311,7 @@ If PROMPT (the prefix), prompt for a coding system to use." (mm-decode-body charset (and cte (intern (downcase (gnus-strip-whitespace cte)))) - (car ctl) prompt)))))) + (car ctl))))))) (defun article-decode-encoded-words () "Remove encoded-word encoding from headers." @@ -2408,8 +2468,8 @@ If READ-CHARSET, ask for a coding system." (while (re-search-forward "^\\(\\(https?\\|ftp\\)://\\S-+\\) *\n\\(\\S-+\\)" nil t) (replace-match "\\1\\3" t))) - (when (and gnus-display-mime-function (interactive-p)) - (funcall gnus-display-mime-function)))) + (when (interactive-p) + (gnus-treat-article nil)))) (defun article-wash-html (&optional read-charset) @@ -3054,9 +3114,12 @@ function and want to see what the date was before converting." (lambda (w) (set-buffer (window-buffer w)) (when (eq major-mode 'gnus-article-mode) - (goto-char (point-min)) - (when (re-search-forward "^X-Sent:" nil t) - (article-date-lapsed t)))) + (let ((mark (point-marker))) + (goto-char (point-min)) + (when (re-search-forward "^X-Sent:" nil t) + (article-date-lapsed t)) + (goto-char (marker-position mark)) + (move-marker mark nil)))) nil 'visible))))) (defun gnus-start-date-timer (&optional n) @@ -3402,7 +3465,7 @@ The directory to save in defaults to `gnus-article-save-directory'." (shell-command-on-region (point-min) (point-max) command nil))) (setq gnus-last-shell-command command)) -(defmacro gnus-read-string (prompt &optional initial-contents history +(defmacro gnus-read-string (prompt &optional initial-contents history default-value) "Like `read-string' but allow for older XEmacsen that don't have the 5th arg." (if (and (featurep 'xemacs) @@ -3756,7 +3819,7 @@ commands: (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map))) (gnus-update-format-specifications nil 'article-mode) (set (make-local-variable 'page-delimiter) gnus-page-delimiter) - (make-local-variable 'gnus-page-broken) + (set (make-local-variable 'gnus-page-broken) nil) (make-local-variable 'gnus-button-marker-list) (make-local-variable 'gnus-article-current-summary) (make-local-variable 'gnus-article-mime-handles) @@ -3994,10 +4057,8 @@ If ALL-HEADERS is non-nil, no headers are hidden." (gnus-article-prepare-display) ;; Do page break. (goto-char (point-min)) - (setq gnus-page-broken - (when gnus-break-pages - (gnus-narrow-to-page) - t))) + (when gnus-break-pages + (gnus-narrow-to-page))) (let ((gnus-article-mime-handle-alist-1 gnus-article-mime-handle-alist)) (gnus-set-mode-line 'article)) @@ -4347,8 +4408,6 @@ Replace it with some information about the removed part." (erase-buffer) (insert (concat - "<#part type=text/plain nofile=yes disposition=attachment" - " description=\"Deleted attachment (" bsize " Byte)\">" ",----\n" "| The following attachment has been deleted:\n" "|\n" @@ -4356,10 +4415,12 @@ Replace it with some information about the removed part." "| Filename: " filename "\n" "| Size (encoded): " bsize " Byte\n" "| Description: " description "\n" - "`----\n" - "<#/part>")) + "`----\n")) (setcdr data - (cdr (mm-make-handle nil `("text/plain")))))) + (cdr (mm-make-handle + nil `("text/plain") nil nil + (list "attachment") + (format "Deleted attachment (%s bytes)" bsize)))))) (set-buffer gnus-summary-buffer) ;; FIXME: maybe some of the following code (borrowed from ;; `gnus-mime-save-part-and-strip') isn't necessary? @@ -4485,7 +4546,7 @@ The uncompress method used is derived from `buffer-file-name'." (message "%s %s..." message basename)) (unwind-protect (unless (memq (apply 'call-process-region - (point-min) (point-max) + (point-min) (point-max) prog t (list t err-file) nil args) @@ -4672,7 +4733,8 @@ If no internal viewer is available, use an external viewer." (gnus-article-part-wrapper n 'gnus-mime-copy-part)) (defun gnus-article-view-part-as-charset (n) - "Copy MIME part N, which is the numerical prefix." + "View MIME part N using a specified charset. +N is the numerical prefix." (interactive "p") (gnus-article-part-wrapper n 'gnus-mime-view-part-as-charset)) @@ -4900,7 +4962,7 @@ If no internal viewer is available, use an external viewer." (defcustom gnus-mime-display-multipart-as-mixed nil "Display \"multipart\" parts as \"multipart/mixed\". -If `t', it overrides `nil' values of +If t, it overrides nil values of `gnus-mime-display-multipart-alternative-as-mixed' and `gnus-mime-display-multipart-related-as-mixed'." :group 'gnus-article-mime @@ -4916,7 +4978,7 @@ If `t', it overrides `nil' values of If displaying \"text/html\" is discouraged \(see `mm-discouraged-alternatives'\) images or other material inside a -\"multipart/related\" part might be overlooked when this variable is `nil'." +\"multipart/related\" part might be overlooked when this variable is nil." :group 'gnus-article-mime :type 'boolean) @@ -5222,7 +5284,7 @@ is the string to use when it is inactive.") "Delete all images in CATEGORY." (let ((entry (assq category gnus-article-image-alist))) (dolist (image (cdr entry)) - (gnus-remove-image image)) + (gnus-remove-image image category)) (setq gnus-article-image-alist (delq entry gnus-article-image-alist)) (gnus-delete-wash-type category))) @@ -5267,27 +5329,32 @@ If given a numerical ARG, move forward ARG pages." (let ((buffer-read-only nil)) (gnus-remove-text-with-property 'gnus-prev) (gnus-remove-text-with-property 'gnus-next))) - (when + (if (cond ((< arg 0) (re-search-backward page-delimiter nil 'move (1+ (abs arg)))) ((> arg 0) (re-search-forward page-delimiter nil 'move arg))) - (goto-char (match-end 0))) - (narrow-to-region - (point) - (if (re-search-forward page-delimiter nil 'move) - (match-beginning 0) - (point))) - (when (and (gnus-visual-p 'page-marker) - (not (= (point-min) 1))) + (goto-char (match-end 0)) (save-excursion (goto-char (point-min)) - (gnus-insert-prev-page-button))) - (when (and (gnus-visual-p 'page-marker) - (< (+ (point-max) 2) (buffer-size))) - (save-excursion - (goto-char (point-max)) - (gnus-insert-next-page-button))))) + (setq gnus-page-broken + (and (re-search-forward page-delimiter nil t) t)))) + (when gnus-page-broken + (narrow-to-region + (point) + (if (re-search-forward page-delimiter nil 'move) + (match-beginning 0) + (point))) + (when (and (gnus-visual-p 'page-marker) + (not (= (point-min) 1))) + (save-excursion + (goto-char (point-min)) + (gnus-insert-prev-page-button))) + (when (and (gnus-visual-p 'page-marker) + (< (+ (point-max) 2) (buffer-size))) + (save-excursion + (goto-char (point-max)) + (gnus-insert-next-page-button)))))) ;; Article mode commands @@ -5300,7 +5367,7 @@ If given a numerical ARG, move forward ARG pages." (defun gnus-article-goto-prev-page () - "Show the next page of the article." + "Show the previous page of the article." (interactive) (if (bobp) (gnus-article-read-summary-keys nil (gnus-character-to-event ?p)) @@ -5334,7 +5401,8 @@ Argument LINES specifies lines to be scrolled up." (if (or (not gnus-page-broken) (save-excursion (save-restriction - (widen) (forward-line 1) (eobp)))) ;Real end-of-buffer? + (widen) + (eobp)))) ;Real end-of-buffer? (progn (when gnus-article-over-scroll (gnus-article-next-page-1 lines)) @@ -5966,7 +6034,8 @@ groups." (set-window-configuration winconf) (set-buffer buf) (set-window-start (get-buffer-window buf) start) - (set-window-point (get-buffer-window buf) (point)))) + (set-window-point (get-buffer-window buf) (point))) + (gnus-summary-show-article)) (defun gnus-article-edit-exit () "Exit the article editing without updating." @@ -5987,7 +6056,8 @@ groups." (save-current-buffer (set-buffer curbuf) (set-window-start (get-buffer-window (current-buffer)) window-start) - (goto-char p)))))) + (goto-char p)))) + (gnus-summary-show-article))) (defun gnus-article-edit-full-stops () "Interactively repair spacing at end of sentences." @@ -6181,7 +6251,8 @@ It should match all directories in the top level of `gnus-ctan-url'." :type 'regexp) (defcustom gnus-button-mid-or-mail-regexp - (concat "\\b\\(\")!;:,{}\n\t ]*@" + (concat "\\b\\(\")!;:,{}\n\t ]*@" + ;; Felix Wiemann in <87oeuomcz9.fsf@news2.ososo.de> gnus-button-valid-fqdn-regexp ">?\\)\\b") "Regular expression that matches a message ID or a mail address." @@ -6258,7 +6329,7 @@ must return `mid', `mail', `invalid' or `ask'." "An alist of \(RATE . REGEXP\) pairs for `gnus-button-mid-or-mail-heuristic'. A negative RATE indicates a message IDs, whereas a positive indicates a mail -address. The REGEXP is processed with `case-fold-search' set to `nil'." +address. The REGEXP is processed with `case-fold-search' set to nil." :group 'gnus-article-buttons :type '(repeat (cons (number :tag "Rate") (regexp :tag "Regexp")))) @@ -6276,13 +6347,14 @@ address, `ask' if unsure and `invalid' if the string is invalid." ;; Certain special cases... (when (string-match (concat - "^0[0-9]+-[0-9][0-9][0-9][0-9]@t-online\\.de$" "\\|" - "^[0-9]+\.[0-9]+\@compuserve") + "^0[0-9]+-[0-9][0-9][0-9][0-9]@t-online\\.de$\\|" + "^[0-9]+\\.[0-9]+@compuserve\\|" + "@public\\.gmane\\.org") mid-or-mail) - (gnus-message 8 "`%s' is a known mail address.") + (gnus-message 8 "`%s' is a known mail address." mid-or-mail) (setq result 'mail)) (when (string-match "@.*@\\| " mid-or-mail) - (gnus-message 8 "`%s' is invalid.") + (gnus-message 8 "`%s' is invalid." mid-or-mail) (setq result 'invalid)) ;; Nothing more to do, if result is not a number here... (when (numberp result) @@ -6324,8 +6396,10 @@ address, `ask' if unsure and `invalid' if the string is invalid." (gnus-message 9 "`%s', rate `%s', result `%s'." mid-or-mail 5.0 result))))) (gnus-message 8 "`%s': Final rate is `%s'." mid-or-mail result) + ;; Maybe we should make this a customizable alist: (condition . 'result) (cond - ;; Maybe we should make this a customizable alist: (condition . 'result) + ((symbolp result) result) + ;; Now convert number into proper results: ((< result -10.0) 'mid) ((> result 10.0) 'mail) (t 'ask)))) @@ -6437,7 +6511,7 @@ Calls `describe-variable' or `describe-function'." "*Integer that says how many TeX-related buttons Gnus will show. The higher the number, the more buttons will appear and the more false positives are possible. Note that you can set this variable local to -specifific groups. Setting it higher in TeX groups is probably a good idea. +specific groups. Setting it higher in TeX groups is probably a good idea. See Info node `(gnus)Group Parameters' and the variable `gnus-parameters' on how to set variables in specific groups." :group 'gnus-article-buttons @@ -6448,7 +6522,7 @@ how to set variables in specific groups." "*Integer that says how many man-related buttons Gnus will show. The higher the number, the more buttons will appear and the more false positives are possible. Note that you can set this variable local to -specifific groups. Setting it higher in Unix groups is probably a good idea. +specific groups. Setting it higher in Unix groups is probably a good idea. See Info node `(gnus)Group Parameters' and the variable `gnus-parameters' on how to set variables in specific groups." :group 'gnus-article-buttons @@ -6459,7 +6533,7 @@ how to set variables in specific groups." "*Integer that says how many emacs-related buttons Gnus will show. The higher the number, the more buttons will appear and the more false positives are possible. Note that you can set this variable local to -specifific groups. Setting it higher in Emacs or Gnus related groups is +specific groups. Setting it higher in Emacs or Gnus related groups is probably a good idea. See Info node `(gnus)Group Parameters' and the variable `gnus-parameters' on how to set variables in specific groups." :group 'gnus-article-buttons @@ -6491,11 +6565,15 @@ positives are possible." 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) ("\\( \n\t]+\\)>" 0 (>= gnus-button-message-level 0) gnus-url-mailto 2) - ("mailto:\\([-a-z.@_+0-9%=?]+\\)" + ;; RFC 2368 (The mailto URL scheme) + ("mailto:\\([-a-z.@_+0-9%=?&]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) ("\\bmailto:\\([^ \n\t]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) @@ -6513,9 +6591,15 @@ positives are possible." gnus-button-ctan-directory-regexp "/[-_.a-z0-9]+/[-_./a-z0-9]+[/a-z0-9]\\)") 1 (>= gnus-button-tex-level 8) gnus-button-handle-ctan 1) - ;; This is info - ("\\binfo:\\(//\\)?\\([^'\">\n\t ]+\\)" - 0 (>= gnus-button-emacs-level 1) gnus-button-handle-info-url 2) + ;; This is info (home-grown style) + ("\\binfo://\\([^'\">\n\t ]+\\)" + 0 (>= gnus-button-emacs-level 1) gnus-button-handle-info-url 1) + ;; Info GNOME style + ("\\binfo:\\([^('\n\t\r \"><][^'\n\t\r \"><]*\\)" + 0 (>= gnus-button-emacs-level 1) gnus-button-handle-info-url-gnome 1) + ;; Info KDE style + ("<\\(info:\\(([^)]+)[^>\n\r]*\\)\\)>" + 1 (>= gnus-button-emacs-level 1) gnus-button-handle-info-url-kde 2) ("\\((Info-goto-node\\|(info\\)[ \t\n]*\\(\"[^\"]*\"\\))" 0 (>= gnus-button-emacs-level 1) gnus-button-handle-info-url 2) ("\\b\\(C-h\\|?\\)[ \t\n]+i[ \t\n]+d?[ \t\n]?m[ \t\n]+\\([^ ]+ ?[^ ]+\\)[ \t\n]+RET" @@ -6548,6 +6632,8 @@ positives are possible." 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\\|?\\)[ \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\\|?\\)[ \t\n]+v[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET" @@ -6556,9 +6642,15 @@ positives are possible." ;; 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)... ("]*\\)>" 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 0 (>= gnus-button-browse-level 0) browse-url 0) @@ -6572,7 +6664,7 @@ positives are possible." gnus-button-handle-man 1) ;; even more: Apache::PerlRun(3pm), PDL::IO::FastRaw(3pm), ;; SoWWWAnchor(3iv), XSelectInput(3X11), X(1), X(7) - ("\\b\\([a-z][-_.:a-z0-9]+\\)([1-9][X1a-z]*)\\W\\|\\b\\(X\\)([1-9])\\W" + ("\\b\\([a-z][-+_.:a-z0-9]+\\)([1-9][X1a-z]*)\\W\\|\\b\\(X\\)([1-9])\\W" 0 (>= gnus-button-man-level 5) gnus-button-handle-man 1) ;; MID or mail: To avoid too many false positives we don't try to catch ;; all kind of allowed MIDs or mail addresses. Domain part must contain @@ -6585,9 +6677,9 @@ positives are possible." Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where REGEXP: is the string (case insensitive) matching text around the button (can -also be lisp expression evaluating to a string), +also be Lisp expression evaluating to a string), BUTTON: is the number of the regexp grouping actually matching the button, -FORM: is a lisp expression which must eval to true for the button to +FORM: is a Lisp expression which must eval to true for the button to be added, CALLBACK: is the function to call when the user push this button, and each PAR: is a number of a regexp grouping whose text will be passed to CALLBACK. @@ -6595,7 +6687,7 @@ PAR: is a number of a regexp grouping whose text will be passed to CALLBACK. CALLBACK can also be a variable, in that case the value of that variable it the real callback function." :group 'gnus-article-buttons - :type '(repeat (list (choice regexp variable) + :type '(repeat (list (choice regexp variable sexp) (integer :tag "Button") (sexp :tag "Form") (function :tag "Callback") @@ -6604,7 +6696,7 @@ variable it the real callback function." (integer :tag "Regexp group"))))) (defcustom gnus-header-button-alist - '(("^\\(References\\|Message-I[Dd]\\):" "<[^<>]+>" + '(("^\\(References\\|Message-I[Dd]\\|^In-Reply-To\\):" "<[^<>]+>" 0 (>= gnus-button-message-level 0) gnus-button-message-id 0) ("^\\(From\\|Reply-To\\):" ": *\\(.+\\)$" 1 (>= gnus-button-message-level 0) gnus-button-reply 1) @@ -6616,7 +6708,7 @@ variable it the real callback function." 0 (>= gnus-button-browse-level 0) browse-url 0) ("^[^:]+:" gnus-button-url-regexp 0 (>= gnus-button-browse-level 0) browse-url 0) - ("^[^:]+:" "\\bmailto:\\([-a-z.@_+0-9%=?]+\\)" + ("^[^:]+:" "\\bmailto:\\([-a-z.@_+0-9%=?&]+\\)" 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) ("^[^:]+:" "\\(<\\(url: \\)?\\(nntp\\|news\\):\\([^>\n ]*\\)>\\)" 1 (>= gnus-button-message-level 0) gnus-button-message-id 4)) @@ -6632,7 +6724,7 @@ HEADER is a regexp to match a header. For a fuller explanation, see :group 'gnus-article-buttons :group 'gnus-article-headers :type '(repeat (list (regexp :tag "Header") - regexp + (choice regexp variable) (integer :tag "Button") (sexp :tag "Form") (function :tag "Callback") @@ -7010,6 +7102,7 @@ specified by `gnus-button-alist'." (defun gnus-button-handle-info-url (url) "Fetch an info URL." + (setq url (mm-subst-char-in-string ?+ ?\ url)) (cond ((string-match "^\\([^:/]+\\)?/\\(.*\\)" url) (gnus-info-find-node @@ -7023,6 +7116,24 @@ specified by `gnus-button-alist'." (gnus-info-find-node url)) (t (error "Can't parse %s" url)))) +(defun gnus-button-handle-info-url-gnome (url) + "Fetch GNOME style info URL." + (setq url (mm-subst-char-in-string ?_ ?\ url)) + (if (string-match "\\([^#]+\\)#?\\(.*\\)" url) + (gnus-info-find-node + (concat "(" + (gnus-url-unhex-string + (match-string 1 url)) + ")" + (or (gnus-url-unhex-string + (match-string 2 url)) + "Top"))) + (error "Can't parse %s" url))) + +(defun gnus-button-handle-info-url-kde (url) + "Fetch KDE style info URL." + (gnus-info-find-node (gnus-url-unhex-string url))) + (defun gnus-button-handle-info-keystrokes (url) "Call `info' when pushing the corresponding URL button." ;; For links like `C-h i d m gnus RET', `C-h i d m CC Mode RET'. @@ -7079,12 +7190,14 @@ specified by `gnus-button-alist'." (when (string-match "mailto:/*\\(.*\\)" url) (setq url (substring url (match-beginning 1) nil))) (let (to args subject func) - (if (string-match (regexp-quote "?") url) - (setq to (gnus-url-unhex-string (substring url 0 (match-beginning 0))) - args (gnus-url-parse-query-string - (substring url (match-end 0) nil) t)) - (setq to (gnus-url-unhex-string url))) - (setq args (cons (list "to" to) args) + (setq args (gnus-url-parse-query-string + (if (string-match "^\\?" url) + (substring url 1) + (if (string-match "^\\([^?]+\\)\\?\\(.*\\)" url) + (concat "to=" (match-string 1 url) "&" + (match-string 2 url)) + (concat "to=" url))) + t) subject (cdr-safe (assoc "subject" args))) (gnus-msg-mail) (while args @@ -7092,7 +7205,9 @@ specified by `gnus-button-alist'." (if (fboundp func) (funcall func) (message-position-on-field (caar args))) - (insert (mapconcat 'identity (cdar args) ", ")) + (insert (gnus-replace-in-string + (mapconcat 'identity (reverse (cdar args)) ", ") + "\r\n" "\n" t)) (setq args (cdr args))) (if subject (message-goto-body) @@ -7200,7 +7315,7 @@ specified by `gnus-button-alist'." This variable is a list of FUNCTION or (REGEXP . FUNCTION). If item is FUNCTION, FUNCTION will be apply to all newsgroups. If item is a -\(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups +\(REGEXP . FUNCTION), FUNCTION will be only apply to the newsgroups whose names match REGEXP. For example: diff --git a/lisp/gnus-cache.el b/lisp/gnus-cache.el index 8fc0e93..0484732 100644 --- a/lisp/gnus-cache.el +++ b/lisp/gnus-cache.el @@ -681,7 +681,7 @@ If LOW, update the lower bound instead." (gnus-message 5 "Generating the cache active file...") (setq gnus-cache-active-hashtb (gnus-make-hashtable 123))) (when (string-match "^\\(nn[^_]+\\)_" group) - (setq group (replace-match "\\1:" t t group))) + (setq group (replace-match "\\1:" t nil group))) ;; Separate articles from all other files and directories. (while files (if (string-match "^[0-9]+$" (file-name-nondirectory (car files))) diff --git a/lisp/gnus-cite.el b/lisp/gnus-cite.el index 31ee34a..779163a 100644 --- a/lisp/gnus-cite.el +++ b/lisp/gnus-cite.el @@ -31,6 +31,7 @@ (require 'gnus) (require 'gnus-range) +(require 'gnus-art) (require 'message) ; for message-cite-prefix-regexp ;;; Customization: @@ -619,41 +620,44 @@ cited text with attributions. When called interactively, these two variables are ignored. See also the documentation for `gnus-article-highlight-citation'." (interactive (append (gnus-article-hidden-arg) '(force))) - (unless (gnus-article-check-hidden-text 'cite arg) - (save-excursion - (set-buffer gnus-article-buffer) - (gnus-cite-parse-maybe force) - (article-goto-body) - (let ((start (point)) - (atts gnus-cite-attribution-alist) - (buffer-read-only nil) - (inhibit-point-motion-hooks t) - (hidden 0) - total) - (goto-char (point-max)) - (gnus-article-search-signature) - (setq total (count-lines start (point))) - (while atts - (setq hidden (+ hidden (length (cdr (assoc (cdar atts) - gnus-cite-prefix-alist)))) - atts (cdr atts))) - (when (or force - (and (> (* 100 hidden) (* gnus-cite-hide-percentage total)) - (> hidden gnus-cite-hide-absolute))) - (setq atts gnus-cite-attribution-alist) + (with-current-buffer gnus-article-buffer + (gnus-delete-wash-type 'cite) + (unless (gnus-article-check-hidden-text 'cite arg) + (save-excursion + (gnus-cite-parse-maybe force) + (article-goto-body) + (let ((start (point)) + (atts gnus-cite-attribution-alist) + (buffer-read-only nil) + (inhibit-point-motion-hooks t) + (hidden 0) + total) + (goto-char (point-max)) + (gnus-article-search-signature) + (setq total (count-lines start (point))) (while atts - (setq total (cdr (assoc (cdar atts) gnus-cite-prefix-alist)) - atts (cdr atts)) - (while total - (setq hidden (car total) - total (cdr total)) - (goto-char (point-min)) - (forward-line (1- hidden)) - (unless (assq hidden gnus-cite-attribution-alist) - (gnus-add-text-properties - (point) (progn (forward-line 1) (point)) - (nconc (list 'article-type 'cite) - gnus-hidden-properties)))))))))) + (setq hidden (+ hidden (length (cdr (assoc (cdar atts) + gnus-cite-prefix-alist)))) + atts (cdr atts))) + (when (or force + (and (> (* 100 hidden) (* gnus-cite-hide-percentage total)) + (> hidden gnus-cite-hide-absolute))) + (gnus-add-wash-type 'cite) + (setq atts gnus-cite-attribution-alist) + (while atts + (setq total (cdr (assoc (cdar atts) gnus-cite-prefix-alist)) + atts (cdr atts)) + (while total + (setq hidden (car total) + total (cdr total)) + (goto-char (point-min)) + (forward-line (1- hidden)) + (unless (assq hidden gnus-cite-attribution-alist) + (gnus-add-text-properties + (point) (progn (forward-line 1) (point)) + (nconc (list 'article-type 'cite) + gnus-hidden-properties))))))))) + (gnus-set-mode-line 'article))) (defun gnus-article-hide-citation-in-followups () "Hide cited text in non-root articles." diff --git a/lisp/gnus-cus.el b/lisp/gnus-cus.el index f991297..7ebcce2 100644 --- a/lisp/gnus-cus.el +++ b/lisp/gnus-cus.el @@ -204,8 +204,7 @@ Which articles to display on entering the group. An arbitrary comment on the group.") (visible (const :tag "Permanently visible" t) "\ -Always display this group, even when there are no unread articles -in it..") +Always display this group, even when there are no unread articles in it.") (highlight-words (choice :tag "Highlight words" @@ -310,16 +309,26 @@ has been stored locally for at least this many days." gnus-agent-cat-days-until-old) (agent-enable-expiration (radio :tag "Expire in this Group or Topic" :value nil -; (const :format "Inherit " nil) (const :format "Enable " ENABLE) (const :format "Disable " DISABLE)) "\nEnable, or disable, agent expiration in this group or topic." - gnus-agent-cat-enable-expiration) ) + gnus-agent-cat-enable-expiration) + (agent-disable-undownloaded-faces + (boolean :tag "Disable Agent Faces") + "Have the summary buffer ignore the agent's undownloaded faces. +These faces, when used, act as a warning that an article has not been +fetched into either the agent nor the cache. This is of most use to +users who use the agent as a cache (i.e. they only operate on articles +that have been downloaded). Disable to display normal article faces +even when the article hasn't been downloaded." + gnus-agent-cat-disable-undownloaded-faces)) "Alist of group parameters that are not also topic parameters. -Each entry has the form (NAME TYPE DOC), where NAME is the parameter -itself (a symbol), TYPE is the parameters type (a sexp widget), and -DOC is a documentation string for the parameter.")) +Each entry has the form (NAME TYPE DOC ACCESSOR), where NAME is the +parameter itself (a symbol), TYPE is the parameters type (a sexp +widget), DOC is a documentation string for the parameter, and ACCESSOR +is a function (symbol) that extracts the current value from the +category.")) (defvar gnus-custom-params) (defvar gnus-custom-method) @@ -879,16 +888,17 @@ articles in the thread. (eval-when-compile (defvar category-fields nil) - (defvar gnus-agent-cat-predicate nil) - (defvar gnus-agent-cat-score-file nil) - (defvar gnus-agent-cat-length-when-short nil) - (defvar gnus-agent-cat-length-when-long nil) - (defvar gnus-agent-cat-low-score nil) - (defvar gnus-agent-cat-high-score nil) - (defvar gnus-agent-cat-groups nil) - (defvar gnus-agent-cat-enable-expiration nil) - (defvar gnus-agent-cat-days-until-old nil) - (defvar gnus-agent-cat-name nil) + (defvar gnus-agent-cat-name) + (defvar gnus-agent-cat-score-file) + (defvar gnus-agent-cat-length-when-short) + (defvar gnus-agent-cat-length-when-long) + (defvar gnus-agent-cat-low-score) + (defvar gnus-agent-cat-high-score) + (defvar gnus-agent-cat-enable-expiration) + (defvar gnus-agent-cat-days-until-old) + (defvar gnus-agent-cat-predicate) + (defvar gnus-agent-cat-groups) + (defvar gnus-agent-cat-disable-undownloaded-faces) ) (defun gnus-trim-whitespace (s) @@ -906,7 +916,8 @@ articles in the thread. (val (,field info)) (deflt (if (,field defaults) (concat " [" (gnus-trim-whitespace - (pp-to-string (,field defaults))) "]")))) + (pp-to-string (,field defaults))) "]"))) + symb) (if (eq (car type) 'radio) (let* ((rtype (nreverse type)) @@ -929,13 +940,14 @@ articles in the thread. (widget-insert "\n") - (set (make-local-variable ',field) - (if val - (widget-create type :value val) - (widget-create type))) - (widget-put ,field :default val) - (widget-put ,field :accessor ',field) - (push ,field category-fields)))) + (setq val (if val + (widget-create type :value val) + (widget-create type)) + symb (set (make-local-variable ',field) val)) + + (widget-put symb :default val) + (widget-put symb :accessor ',field) + (push symb category-fields)))) (defun gnus-agent-customize-category (category) "Edit the CATEGORY." @@ -1002,34 +1014,42 @@ articles in the thread. ;; gnus-agent-cat-prepare-category-field as I don't want the ;; group list to appear when customizing a topic. (widget-insert "\n") - (set (make-local-variable 'gnus-agent-cat-groups) - (widget-create - `(choice - :format "%[Select Member Groups%]\n%v" :value ignore - (const :menu-tag "do not change" :tag "" :value ignore) - (checklist :entry-format "%b %v" - :menu-tag "display group selectors" - :greedy t - :value ,(delq nil - (mapcar - (lambda (newsrc) - (car (member - (gnus-info-group newsrc) - (gnus-agent-cat-groups info)))) - (cdr gnus-newsrc-alist))) - ,@(mapcar (lambda (newsrc) - `(const ,(gnus-info-group newsrc))) - (cdr gnus-newsrc-alist)))))) - - (widget-put gnus-agent-cat-groups :default (gnus-agent-cat-groups info)) - (widget-put gnus-agent-cat-groups :accessor 'gnus-agent-cat-groups) - (push gnus-agent-cat-groups category-fields) + + (let ((symb + (set + (make-local-variable 'gnus-agent-cat-groups) + (widget-create + `(choice + :format "%[Select Member Groups%]\n%v" :value ignore + (const :menu-tag "do not change" :tag "" :value ignore) + (checklist :entry-format "%b %v" + :menu-tag "display group selectors" + :greedy t + :value + ,(delq nil + (mapcar + (lambda (newsrc) + (car (member + (gnus-info-group newsrc) + (gnus-agent-cat-groups info)))) + (cdr gnus-newsrc-alist))) + ,@(mapcar (lambda (newsrc) + `(const ,(gnus-info-group newsrc))) + (cdr gnus-newsrc-alist)))))))) + + (widget-put symb :default (gnus-agent-cat-groups info)) + (widget-put symb :accessor 'gnus-agent-cat-groups) + (push symb category-fields)) (widget-insert "\nExpiration Settings ") (gnus-agent-cat-prepare-category-field agent-enable-expiration) (gnus-agent-cat-prepare-category-field agent-days-until-old) + (widget-insert "\nVisual Settings ") + + (gnus-agent-cat-prepare-category-field agent-disable-undownloaded-faces) + (use-local-map widget-keymap) (widget-setup) (buffer-enable-undo)))) diff --git a/lisp/gnus-dired.el b/lisp/gnus-dired.el index cf54427..1fa657f 100644 --- a/lisp/gnus-dired.el +++ b/lisp/gnus-dired.el @@ -1,6 +1,6 @@ ;;; gnus-dired.el --- utility functions where gnus and dired meet -;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003 +;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004 ;; Free Software Foundation, Inc. ;; Authors: Benjamin Rutt , @@ -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. diff --git a/lisp/gnus-draft.el b/lisp/gnus-draft.el index 4bad775..a0774ef 100644 --- a/lisp/gnus-draft.el +++ b/lisp/gnus-draft.el @@ -48,6 +48,7 @@ (gnus-define-keys gnus-draft-mode-map "Dt" gnus-draft-toggle-sending + "e" gnus-draft-edit-message ;; Use `B w' for `gnus-summary-edit-article' "De" gnus-draft-edit-message "Ds" gnus-draft-send-message "DS" gnus-draft-send-all-messages)) @@ -186,8 +187,12 @@ (defun gnus-draft-send-all-messages () "Send all the sendable drafts." (interactive) - (gnus-uu-mark-buffer) - (gnus-draft-send-message)) + (when (or + gnus-expert-user + (gnus-y-or-n-p + "Send all drafts? ")) + (gnus-uu-mark-buffer) + (gnus-draft-send-message))) (defun gnus-group-send-queue () "Send all sendable articles from the queue group." @@ -219,7 +224,7 @@ (dolist (group '("nndraft:drafts" "nndraft:queue")) (setq active (gnus-activate-group group)) (if (and active (>= (cdr active) (car active))) - (if (y-or-n-p "There are unsent drafts. Confirm to exit?") + (if (y-or-n-p "There are unsent drafts. Confirm to exit? ") (throw 'continue t) (error "Stop!")))))))) diff --git a/lisp/gnus-ems.el b/lisp/gnus-ems.el index aa535b4..d2dde41 100644 --- a/lisp/gnus-ems.el +++ b/lisp/gnus-ems.el @@ -46,13 +46,18 @@ (eval-and-compile (autoload 'gnus-xmas-define "gnus-xmas") (autoload 'gnus-xmas-redefine "gnus-xmas") - (autoload 'appt-select-lowest-window "appt")) + (autoload 'appt-select-lowest-window "appt") + (autoload 'gnus-get-buffer-create "gnus") + (autoload 'nnheader-find-etc-directory "nnheader")) (if (or (featurep 'xemacs) (>= emacs-major-version 21)) (autoload 'smiley-region "smiley") (autoload 'smiley-region "smiley-mule")) +;; Fixme: shouldn't require message +(autoload 'message-text-with-property "message") + (defun gnus-kill-all-overlays () "Delete all overlays in the current buffer." (let* ((overlayss (overlay-lists)) @@ -75,16 +80,19 @@ (defvar gnus-mouse-face-prop 'mouse-face "Property used for highlighting mouse regions."))) -(defvar gnus-tmp-unread) -(defvar gnus-tmp-replied) -(defvar gnus-tmp-score-char) -(defvar gnus-tmp-indentation) -(defvar gnus-tmp-opening-bracket) -(defvar gnus-tmp-lines) -(defvar gnus-tmp-name) -(defvar gnus-tmp-closing-bracket) -(defvar gnus-tmp-subject-or-nil) -(defvar gnus-check-before-posting) +(eval-when-compile + (defvar gnus-tmp-unread) + (defvar gnus-tmp-replied) + (defvar gnus-tmp-score-char) + (defvar gnus-tmp-indentation) + (defvar gnus-tmp-opening-bracket) + (defvar gnus-tmp-lines) + (defvar gnus-tmp-name) + (defvar gnus-tmp-closing-bracket) + (defvar gnus-tmp-subject-or-nil) + (defvar gnus-check-before-posting) + (defvar gnus-mouse-face) + (defvar gnus-group-buffer)) (defun gnus-ems-redefine () (cond @@ -225,16 +233,20 @@ (setq props (plist-put props :background (face-background face)))) (apply 'create-image file type data-p props))) -(defun gnus-put-image (glyph &optional string) - (insert-image glyph (or string " ")) - (unless string - (put-text-property (1- (point)) (point) - 'gnus-image-text-deletable t)) - glyph) +(defun gnus-put-image (glyph &optional string category) + (let ((point (point))) + (insert-image glyph (or string " ")) + (put-text-property point (point) 'gnus-image-category category) + (unless string + (put-text-property (1- (point)) (point) + 'gnus-image-text-deletable t)) + glyph)) -(defun gnus-remove-image (image) +(defun gnus-remove-image (image &optional category) (dolist (position (message-text-with-property 'display)) - (when (equal (get-text-property position 'display) image) + (when (and (equal (get-text-property position 'display) image) + (equal (get-text-property position 'gnus-image-category) + category)) (put-text-property position (1+ position) 'display nil) (when (get-text-property position 'gnus-image-text-deletable) (delete-region position (1+ position)))))) diff --git a/lisp/gnus-fun.el b/lisp/gnus-fun.el index 8791640..b293d4e 100644 --- a/lisp/gnus-fun.el +++ b/lisp/gnus-fun.el @@ -119,8 +119,8 @@ Output to the current buffer, replace text, and don't mingle error." (if (> (length attempt) 726) (progn (setq quant (- quant 2)) - (message "Length %d; trying quant %d" - (length attempt) quant)) + (gnus-message 9 "Length %d; trying quant %d" + (length attempt) quant)) (setq done t))) (if done (mm-with-unibyte-buffer @@ -190,9 +190,9 @@ colors of the displayed X-Faces." (if (gnus-image-type-available-p 'xface) (gnus-create-image (concat "X-Face: " data) - 'xface t :ascent 'center :face 'gnus-x-face) + 'xface t :face 'gnus-x-face) (gnus-create-image - pbm 'pbm t :ascent 'center :face 'gnus-x-face)))) + pbm 'pbm t :face 'gnus-x-face)) nil 'xface)) (gnus-add-wash-type 'xface)))))) (defun gnus-grab-cam-x-face () diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index a3ca7cf..e934383 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -181,8 +181,8 @@ with some simple extensions. %E Icon as defined by `gnus-group-icon-list'. %u User defined specifier. The next character in the format string should be a letter. Gnus will call the function gnus-user-format-function-X, - where X is the letter following %u. The function will be passed a - single dummy parameter as argument.. The function should return a + where X is the letter following %u. The function will be passed a + single dummy parameter as argument. The function should return a string, which will be inserted into the buffer just like information from any other group specifier. @@ -535,214 +535,214 @@ simple manner.") (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-n" gnus-namazu-search - "\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 - "n" gnus-group-make-shimbun-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 - "G" gnus-group-make-nnir-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-n" gnus-namazu-search + "\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 + "n" gnus-group-make-shimbun-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 + "G" gnus-group-make-nnir-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'." - (and (boundp 'gnus-topic-mode) + (and (boundp 'gnus-topic-mode) (symbol-value 'gnus-topic-mode))) (defun gnus-group-make-menu-bar () @@ -760,7 +760,7 @@ simple manner.") ["Select" gnus-group-select-group :included (not (gnus-topic-mode-p)) :active (gnus-group-group-name)] - ["Select " gnus-topic-select-group + ["Select " gnus-topic-select-group :included (gnus-topic-mode-p)] ["See old articles" (gnus-group-select-group 'all) :keys "C-u SPC" :active (gnus-group-group-name)] @@ -769,7 +769,7 @@ simple manner.") :active (gnus-group-group-name) ,@(if (featurep 'xemacs) nil '(:help "Mark unread articles in the current group as read"))] - ["Catch up " gnus-topic-catchup-articles + ["Catch up " gnus-topic-catchup-articles :included (gnus-topic-mode-p) ,@(if (featurep 'xemacs) nil '(:help "Mark unread articles in the current group or topic as read"))] @@ -804,13 +804,13 @@ simple manner.") '(:help "Display the archived control message for the current group"))] ;; Actually one should check, if any of the marked groups gives t for ;; (gnus-check-backend-function 'request-expire-articles ...) - ["Expire articles" gnus-group-expire-articles + ["Expire articles" gnus-group-expire-articles :included (not (gnus-topic-mode-p)) :active (or (and (gnus-group-group-name) (gnus-check-backend-function 'request-expire-articles (gnus-group-group-name))) gnus-group-marked)] - ["Expire articles " gnus-topic-expire-articles + ["Expire articles " gnus-topic-expire-articles :included (gnus-topic-mode-p)] ["Set group level..." gnus-group-set-current-level (gnus-group-group-name)] @@ -902,6 +902,7 @@ simple manner.") ["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 RSS group..." gnus-group-make-rss-group t] ["Rename group..." gnus-group-rename-group (gnus-check-backend-function 'request-rename-group (gnus-group-group-name))] @@ -1427,7 +1428,7 @@ if it is a string, only list groups matching REGEXP." (gnus-tmp-qualified-group (gnus-group-name-decode (gnus-group-real-name gnus-tmp-group) group-name-charset)) - (gnus-tmp-comment + (gnus-tmp-comment (or (gnus-group-get-parameter gnus-tmp-group 'comment t) gnus-tmp-group)) (gnus-tmp-newsgroup-description @@ -1503,7 +1504,7 @@ if it is a string, only list groups matching REGEXP." (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 @@ -1776,9 +1777,11 @@ If UNMARK, remove the mark instead." (interactive "sMark (regexp): ") (let ((alist (cdr gnus-newsrc-alist)) group) - (while alist - (when (string-match regexp (setq group (gnus-info-group (pop alist)))) - (gnus-group-set-mark group)))) + (save-excursion + (while alist + (when (string-match regexp (setq group (gnus-info-group (pop alist)))) + (gnus-group-jump-to-group group) + (gnus-group-set-mark group))))) (gnus-group-position-point)) (defun gnus-group-remove-mark (group &optional test-marked) @@ -2023,6 +2026,14 @@ If SELECT-ARTICLES, only select those articles. 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))) @@ -2282,7 +2293,7 @@ ADDRESS." (forward-line -1) (gnus-group-position-point) - ;; Load the backend and try to make the backend create + ;; Load the back end and try to make the back end create ;; the group as well. (when (assoc (symbol-name (setq backend (car (gnus-server-get-method nil meth)))) @@ -2307,21 +2318,23 @@ ADDRESS." (lambda (group) (gnus-group-delete-group group nil t)))))) -(eval-when-compile (defvar gnus-cache-active-altered)) +(defvar gnus-cache-active-altered) (defun gnus-group-delete-group (group &optional force no-prompt) "Delete the current group. Only meaningful with editable groups. If FORCE (the prefix) is non-nil, all the articles in the group will be deleted. This is \"deleted\" as in \"removed forever from the face of the Earth\". There is no undo. The user will be prompted before -doing the deletion." +doing the deletion. +Note that you also have to specify FORCE if you want the group to +be removed from the server, even when it's empty." (interactive (list (gnus-group-group-name) current-prefix-arg)) (unless group (error "No group to delete")) (unless (gnus-check-backend-function 'request-delete-group group) - (error "This backend does not support group deletion")) + (error "This back end does not support group deletion")) (prog1 (if (and (not no-prompt) (not (gnus-yes-or-no-p @@ -2353,12 +2366,12 @@ and NEW-NAME will be prompted for." (progn (unless (gnus-check-backend-function 'request-rename-group (gnus-group-group-name)) - (error "This backend does not support renaming groups")) + (error "This back end does not support renaming groups")) (gnus-read-group "Rename group to: " (gnus-group-real-name (gnus-group-group-name)))))) (unless (gnus-check-backend-function 'request-rename-group group) - (error "This backend does not support renaming groups")) + (error "This back end does not support renaming groups")) (unless group (error "No group to rename")) (when (equal (gnus-group-real-name group) new-name) @@ -2374,6 +2387,9 @@ and NEW-NAME will be prompted for." (gnus-group-real-name new-name) (gnus-info-method (gnus-get-info group))))) + (when (gnus-active new-name) + (error "The group %s already exists" new-name)) + (gnus-message 6 "Renaming group %s to %s..." group new-name) (prog1 (if (progn @@ -2426,13 +2442,16 @@ and NEW-NAME will be prompted for." (local-set-key "\C-c\C-i" (gnus-create-info-command - (cond - ((eq part 'method) - "(gnus)Select Methods") - ((eq part 'params) - "(gnus)Group Parameters") - (t - "(gnus)Group Info")))))) + (format "(%s)%s" + (or gnus-info-filename + (get-language-info current-language-environment 'gnus-info) + "gnus") + (cond ((eq part 'method) + "Select Methods") + ((eq part 'params) + "Group Parameters") + (t + "Group Info"))))))) (defun gnus-group-edit-group-method (group) "Edit the select method of GROUP." @@ -2592,22 +2611,23 @@ If SOLID (the prefix), create a solid group." (cons (current-buffer) (if (eq major-mode 'gnus-summary-mode) 'summary 'group)))))) -(eval-when-compile (defvar nnrss-group-alist) - (defun nnrss-discover-feed (arg)) - (defun nnrss-save-server-data (arg))) +(eval-when-compile + (defvar nnrss-group-alist) + (defun nnrss-discover-feed (arg)) + (defun nnrss-save-server-data (arg))) (defun gnus-group-make-rss-group (&optional url) - "Given a URL, discover if there is an RSS feed. If there is, -use Gnus' to create an nnrss group" + "Given a URL, discover if there is an RSS feed. +If there is, use Gnus to create an nnrss group" (interactive) (require 'nnrss) (if (not url) (setq url (read-from-minibuffer "URL to Search for RSS: "))) (let ((feedinfo (nnrss-discover-feed url))) (if feedinfo - (let ((title (read-from-minibuffer "Title: " - (cdr (assoc 'title + (let ((title (read-from-minibuffer "Title: " + (cdr (assoc 'title feedinfo)))) - (desc (read-from-minibuffer "Description: " + (desc (read-from-minibuffer "Description: " (cdr (assoc 'description feedinfo)))) (href (cdr (assoc 'href feedinfo)))) @@ -2694,7 +2714,7 @@ mail messages or news articles in files that have numeric names." (gnus-group-real-name group) (list 'nndir (gnus-group-real-name group) (list 'nndir-directory dir))))) -(eval-when-compile (defvar nnkiboze-score-file)) +(defvar nnkiboze-score-file) (defun gnus-group-make-kiboze-group (group address scores) "Create an nnkiboze group. The user will be prompted for a name, a regexp to match groups, and @@ -2899,7 +2919,7 @@ If REVERSE, sort in reverse order." (gnus-group-sort-groups 'gnus-group-sort-by-rank reverse)) (defun gnus-group-sort-groups-by-method (&optional reverse) - "Sort the group buffer alphabetically by backend name. + "Sort the group buffer alphabetically by back end name. If REVERSE, sort in reverse order." (interactive "P") (gnus-group-sort-groups 'gnus-group-sort-by-method reverse)) @@ -2988,7 +3008,7 @@ sort in reverse order." (gnus-group-sort-selected-groups n 'gnus-group-sort-by-rank reverse)) (defun gnus-group-sort-selected-groups-by-method (&optional n reverse) - "Sort the group buffer alphabetically by backend name. + "Sort the group buffer alphabetically by back end name. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." (interactive (gnus-interactive "P\ny")) @@ -3017,7 +3037,7 @@ sort in reverse order." (< (gnus-info-level info1) (gnus-info-level info2))) (defun gnus-group-sort-by-method (info1 info2) - "Sort alphabetically by backend name." + "Sort alphabetically by back end name." (string< (car (gnus-find-method-for-group (gnus-info-group info1) info1)) (car (gnus-find-method-for-group @@ -3239,15 +3259,18 @@ Uses the process/prefix convention." (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)) @@ -3276,26 +3299,22 @@ Uses the process/prefix convention." "Toggle subscription of the current group. If given numerical prefix, toggle the N next groups." (interactive "P") - (let ((groups (gnus-group-process-prefix n)) - group) - (while groups - (setq group (car groups) - groups (cdr groups)) - (gnus-group-remove-mark group) - (gnus-group-unsubscribe-group - group - (cond - ((eq do-sub 'unsubscribe) - gnus-level-default-unsubscribed) - ((eq do-sub 'subscribe) - gnus-level-default-subscribed) - ((<= (gnus-group-group-level) gnus-level-subscribed) - gnus-level-default-unsubscribed) - (t - gnus-level-default-subscribed)) - t) - (gnus-group-update-group-line)) - (gnus-group-next-group 1))) + (dolist (group (gnus-group-process-prefix n)) + (gnus-group-remove-mark group) + (gnus-group-unsubscribe-group + group + (cond + ((eq do-sub 'unsubscribe) + gnus-level-default-unsubscribed) + ((eq do-sub 'subscribe) + gnus-level-default-subscribed) + ((<= (gnus-group-group-level) gnus-level-subscribed) + gnus-level-default-unsubscribed) + (t + gnus-level-default-subscribed)) + t) + (gnus-group-update-group-line)) + (gnus-group-next-group 1)) (defun gnus-group-unsubscribe-group (group &optional level silent) "Toggle subscription to GROUP. @@ -3411,29 +3430,27 @@ of groups killed." (message "Killed group %s" group)) ;; If there are lots and lots of groups to be killed, we use ;; this thing instead. - (let (entry) - (setq groups (nreverse groups)) - (while groups - (gnus-group-remove-mark (setq group (pop groups))) - (gnus-delete-line) - (push group gnus-killed-list) - (setq gnus-newsrc-alist - (delq (assoc group gnus-newsrc-alist) - gnus-newsrc-alist)) - (when gnus-group-change-level-function - (funcall gnus-group-change-level-function - group gnus-level-killed 3)) - (cond - ((setq entry (gnus-gethash group gnus-newsrc-hashtb)) - (push (cons (car entry) (nth 2 entry)) - gnus-list-of-killed-groups) - (setcdr (cdr entry) (cdddr entry))) - ((member group gnus-zombie-list) - (setq gnus-zombie-list (delete group gnus-zombie-list)))) - ;; There may be more than one instance displayed. - (while (gnus-group-goto-group group) - (gnus-delete-line))) - (gnus-make-hashtable-from-newsrc-alist))) + (dolist (group (nreverse groups)) + (gnus-group-remove-mark group) + (gnus-delete-line) + (push group gnus-killed-list) + (setq gnus-newsrc-alist + (delq (assoc group gnus-newsrc-alist) + gnus-newsrc-alist)) + (when gnus-group-change-level-function + (funcall gnus-group-change-level-function + group gnus-level-killed 3)) + (cond + ((setq entry (gnus-gethash group gnus-newsrc-hashtb)) + (push (cons (car entry) (nth 2 entry)) + gnus-list-of-killed-groups) + (setcdr (cdr entry) (cdddr entry))) + ((member group gnus-zombie-list) + (setq gnus-zombie-list (delete group gnus-zombie-list)))) + ;; There may be more than one instance displayed. + (while (gnus-group-goto-group group) + (gnus-delete-line))) + (gnus-make-hashtable-from-newsrc-alist)) (gnus-group-position-point) (if (< (length out) 2) (car out) (nreverse out)))) @@ -3498,7 +3515,7 @@ yanked) a list of yanked groups is returned." (defun gnus-group-list-all-groups (&optional arg) "List all newsgroups with level ARG or lower. -Default is gnus-level-unsubscribed, which lists all subscribed and most +Default is `gnus-level-unsubscribed', which lists all subscribed and most unsubscribed groups." (interactive "P") (gnus-group-list-groups (or arg gnus-level-unsubscribed) t)) @@ -3711,7 +3728,7 @@ If given a prefix argument, prompt for a group." (browse-url (eval url)) (setq url (concat "http://" hierarchy ".news-admin.org/charters/" name)) - (if (and (fboundp 'url-http-file-exists-p) + (if (and (fboundp 'url-http-file-exists-p) (url-http-file-exists-p url)) (browse-url url) (gnus-group-fetch-control group)))))) @@ -3732,14 +3749,14 @@ If given a prefix argument, prompt for a group." (setq hierarchy (match-string 1 name)) (if gnus-group-fetch-control-use-browse-url (browse-url (concat "ftp://ftp.isc.org/usenet/control/" - hierarchy "/" name ".Z")) + hierarchy "/" name ".gz")) (let ((enable-local-variables nil)) (gnus-group-read-ephemeral-group group - `(nndoc ,group (nndoc-address + `(nndoc ,group (nndoc-address ,(find-file-noselect - (concat "/ftp@ftp.isc.org:/usenet/control/" - hierarchy "/" name ".Z"))) + (concat "/ftp@ftp.isc.org:/usenet/control/" + hierarchy "/" name ".gz"))) (nndoc-article-type mbox)) t nil nil)))))) (defun gnus-group-describe-group (force &optional group) @@ -3837,7 +3854,7 @@ If given a prefix argument, prompt for a group." (pop-to-buffer obuf))) (defun gnus-group-description-apropos (regexp) - "List all newsgroups that have names or descriptions that match a regexp." + "List all newsgroups that have names or descriptions that match REGEXP." (interactive "sGnus description apropos (regexp): ") (when (not (or gnus-description-hashtb (gnus-read-all-descriptions-files))) @@ -3936,10 +3953,12 @@ If GROUP, edit that local kill file instead." (interactive) (gnus-save-newsrc-file)) +(defvar gnus-backlog-articles) + (defun gnus-group-suspend () "Suspend the current Gnus session. In fact, cleanup buffers except for group mode buffer. -The hook gnus-suspend-gnus-hook is called before actually suspending." +The hook `gnus-suspend-gnus-hook' is called before actually suspending." (interactive) (gnus-run-hooks 'gnus-suspend-gnus-hook) (gnus-offer-save-summaries) @@ -3953,6 +3972,7 @@ The hook gnus-suspend-gnus-hook is called before actually suspending." (eq major-mode 'message-mode)))) (gnus-kill-buffer buf))) (gnus-buffers)) + (setq gnus-backlog-articles nil) (gnus-kill-gnus-frames) (when group-buf (bury-buffer group-buf) @@ -4025,10 +4045,10 @@ If not, METHOD should be a list where the first element is the method and the second element is the address." (interactive (list (let ((how (completing-read - "Which backend: " + "Which back end: " (append gnus-valid-select-methods gnus-server-alist) nil t (cons "nntp" 0) 'gnus-method-history))) - ;; We either got a backend name or a virtual server name. + ;; We either got a back end name or a virtual server name. ;; If the first, we also need an address. (if (assoc how gnus-valid-select-methods) (list (intern how) diff --git a/lisp/gnus-int.el b/lisp/gnus-int.el index 835cb91..49c9ed6 100644 --- a/lisp/gnus-int.el +++ b/lisp/gnus-int.el @@ -33,8 +33,8 @@ (require 'message) (require 'gnus-range) -(eval-when-compile - (defun gnus-agent-expire (&optional a b c))) +(autoload 'gnus-agent-expire "gnus-agent") +(autoload 'gnus-agent-read-servers-validate-native "gnus-agent") (defcustom gnus-open-server-hook nil "Hook called just before opening connection to the news server." @@ -107,6 +107,18 @@ If CONFIRM is non-nil, the user will be asked for an NNTP server." (require 'nntp))) (setq gnus-current-select-method gnus-select-method) (gnus-run-hooks 'gnus-open-server-hook) + + ;; Partially validate agent covered methods now that the + ;; gnus-select-method is known. + + (if gnus-agent + ;; NOTE: This is here for one purpose only. By validating + ;; the current select method, it converts the old 5.10.3, + ;; and earlier, format to the current format. That enables + ;; the agent code within gnus-open-server to function + ;; correctly. + (gnus-agent-read-servers-validate-native gnus-select-method)) + (or ;; gnus-open-server-hook might have opened it (gnus-server-opened gnus-select-method) @@ -202,52 +214,66 @@ If it is down, start it up (again)." (gnus-message 1 "Denied server") nil) ;; Open the server. - (let ((result - (condition-case err - (funcall (gnus-get-function gnus-command-method 'open-server) - (nth 1 gnus-command-method) - (nthcdr 2 gnus-command-method)) - (error - (gnus-message 1 (format + (let* ((open-server-function (gnus-get-function gnus-command-method 'open-server)) + (result + (condition-case err + (funcall open-server-function + (nth 1 gnus-command-method) + (nthcdr 2 gnus-command-method)) + (error + (gnus-message 1 (format "Unable to open server due to: %s" (error-message-string err))) nil) - (quit - (gnus-message 1 "Quit trying to open server") - nil)))) + (quit + (gnus-message 1 "Quit trying to open server") + nil))) + open-offline) ;; If this hasn't been opened before, we add it to the list. (unless elem (setq elem (list gnus-command-method nil) gnus-opened-servers (cons elem gnus-opened-servers))) ;; Set the status of this server. - (setcar (cdr elem) - (if result - (if (eq (cadr elem) 'offline) - 'offline - 'ok) - (if (and gnus-agent - (not (eq (cadr elem) 'offline)) - (gnus-agent-method-p gnus-command-method)) - (or gnus-server-unopen-status - (if (gnus-y-or-n-p - (format "Unable to open %s:%s, go offline? " - (car gnus-command-method) - (cadr gnus-command-method))) - 'offline - 'denied)) - 'denied))) - ;; Return the result from the "open" call. - (cond ((eq (cadr elem) 'offline) - ;; I'm avoiding infinite recursion by binding unopen - ;; status to denied (The logic of this routine - ;; guarantees that I can't get to this point with - ;; unopen status already bound to denied). - (unless (eq gnus-server-unopen-status 'denied) - (let ((gnus-server-unopen-status 'denied)) - (gnus-open-server gnus-command-method))) - t) - (t - result)))))) + (setcar (cdr elem) + (cond (result + (if (eq open-server-function #'nnagent-open-server) + ;; The agent's backend has a "special" status + 'offline + 'ok)) + ((and gnus-agent + (gnus-agent-method-p gnus-command-method)) + (cond (gnus-server-unopen-status + ;; Set the server's status to the unopen + ;; status. If that status is offline, + ;; recurse to open the agent's backend. + (setq open-offline (eq gnus-server-unopen-status 'offline)) + gnus-server-unopen-status) + ((gnus-y-or-n-p + (format "Unable to open %s:%s, go offline? " + (car gnus-command-method) + (cadr gnus-command-method))) + (setq open-offline t) + 'offline) + (t + ;; This agentized server was still denied + 'denied))) + (t + ;; This unagentized server must be denied + 'denied))) + + ;; NOTE: I MUST set the server's status to offline before this + ;; recursive call as this status will drive the + ;; gnus-get-function (called above) to return the agent's + ;; backend. + (if open-offline + ;; Recursively open this offline server to perform the + ;; open-server function of the agent's backend. + (let ((gnus-server-unopen-status 'denied)) + ;; Bind gnus-server-unopen-status to avoid recursively + ;; prompting with "go offline?". This is only a concern + ;; when the agent's backend fails to open the server. + (gnus-open-server gnus-command-method)) + result))))) (defun gnus-close-server (gnus-command-method) "Close the connection to GNUS-COMMAND-METHOD." @@ -289,8 +315,8 @@ If it is down, start it up (again)." (defun gnus-status-message (gnus-command-method) "Return the status message from GNUS-COMMAND-METHOD. -If GNUS-COMMAND-METHOD is a string, it is interpreted as a group name. The method -this group uses will be queried." +If GNUS-COMMAND-METHOD is a string, it is interpreted as a group +name. The method this group uses will be queried." (let ((gnus-command-method (if (stringp gnus-command-method) (gnus-find-method-for-group gnus-command-method) @@ -385,7 +411,7 @@ If FETCH-OLD, retrieve all headers (or some subset thereof) in the group." (gnus-group-real-name group) article)))) (defun gnus-request-set-mark (group action) - "Set marks on articles in the backend." + "Set marks on articles in the back end." (let ((gnus-command-method (gnus-find-method-for-group group))) (if (not (gnus-check-backend-function 'request-set-mark (car gnus-command-method))) @@ -395,7 +421,7 @@ If FETCH-OLD, retrieve all headers (or some subset thereof) in the group." (nth 1 gnus-command-method))))) (defun gnus-request-update-mark (group article mark) - "Allow the backend to change the mark the user tries to put on an article." + "Allow the back end to change the mark the user tries to put on an article." (let ((gnus-command-method (gnus-find-method-for-group group))) (if (not (gnus-check-backend-function 'request-update-mark (car gnus-command-method))) diff --git a/lisp/gnus-logic.el b/lisp/gnus-logic.el index 20fe9e0..06c46fb 100644 --- a/lisp/gnus-logic.el +++ b/lisp/gnus-logic.el @@ -95,6 +95,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) diff --git a/lisp/gnus-mailcap.el b/lisp/gnus-mailcap.el index 1752cf7..232b019 100644 --- a/lisp/gnus-mailcap.el +++ b/lisp/gnus-mailcap.el @@ -47,7 +47,7 @@ (modify-syntax-entry ?{ "(" table) (modify-syntax-entry ?} ")" table) table) - "A syntax table for parsing sgml attributes.") + "A syntax table for parsing SGML attributes.") (eval-and-compile (when (featurep 'xemacs) @@ -627,7 +627,7 @@ Also return non-nil if no test clause is present." (defun mailcap-viewer-passes-test (viewer-info type-info) "Return non-nil iff viewer specified by VIEWER-INFO passes its test clause. -Also retun non-nil if it has no test clause. TYPE-INFO is an argument +Also return non-nil if it has no test clause. TYPE-INFO is an argument to supply to the test." (let* ((test-info (assq 'test viewer-info)) (test (cdr test-info)) @@ -656,7 +656,7 @@ to supply to the test." test (list shell-file-name nil nil nil shell-command-switch test) status (apply 'call-process test)) - (= 0 status)))) + (eq 0 status)))) (push (list otest result) mailcap-viewer-test-cache) result))) diff --git a/lisp/gnus-msg.el b/lisp/gnus-msg.el index 6d2e1b0..479979e 100644 --- a/lisp/gnus-msg.el +++ b/lisp/gnus-msg.el @@ -1,5 +1,5 @@ ;;; gnus-msg.el --- mail and post interface for Semi-gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 ;; Free Software Foundation, Inc. ;; Author: Masanobu UMEDA @@ -274,7 +274,7 @@ See also the `mml-default-encrypt-method' variable." (defcustom gnus-message-replysignencrypted t - "Setting this causes automatically encryped messages to also be signed." + "Setting this causes automatically encrypted messages to also be signed." :group 'gnus-message :type 'boolean) @@ -308,24 +308,6 @@ If nil, the address field will always be empty after invoking :group 'gnus-message :type 'boolean) -(defcustom gnus-user-agent 'emacs-gnus-type - "Which information should be exposed in the User-Agent header. - -It can be one of the symbols `gnus' \(show only Gnus version\), `emacs-gnus' -\(show only Emacs and Gnus versions\), `emacs-gnus-config' \(same as -`emacs-gnus' plus system configuration\), `emacs-gnus-type' \(same as -`emacs-gnus' plus system type\) or a custom string. If you set it to a -string, be sure to use a valid format, see RFC 2616." - :group 'gnus-message - :type '(choice - (item :tag "Show Gnus and Emacs versions and system type" - emacs-gnus-type) - (item :tag "Show Gnus and Emacs versions and system configuration" - emacs-gnus-config) - (item :tag "Show Gnus and Emacs versions" emacs-gnus) - (item :tag "Show only Gnus version" gnus) - (string :tag "Other"))) - ;;; Internal variables. (defvar gnus-inhibit-posting-styles nil @@ -559,14 +541,16 @@ Gcc: header for archiving purposes." (setq message-post-method `(lambda (arg) (gnus-post-method arg ,gnus-newsgroup-name))) - (setq message-user-agent (gnus-extended-version)) + (setq message-user-agent (gnus-message-make-user-agent)) (unless message-use-multi-frames (message-add-action `(if (gnus-buffer-exists-p ,buffer) (set-window-configuration ,winconf)) 'exit 'postpone 'kill)) (let ((to-be-marked (cond - (yanked yanked) + (yanked + (mapcar + (lambda (x) (if (listp x) (car x) x)) yanked)) (article (if (listp article) article (list article))) (t nil)))) (message-add-action @@ -618,7 +602,7 @@ If ARG is 1, prompt for group name to post to. This function prepares a news even when using mail groups. This is useful for posting messages to mail groups without actually sending them over the -network. The corresponding backend must have a 'request-post method." +network. The corresponding back end must have a 'request-post method." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. @@ -697,7 +681,7 @@ If ARG, don't do that. If ARG is 1, prompt for group name to post to. This function prepares a news even when using mail groups. This is useful for posting messages to mail groups without actually sending them over the -network. The corresponding backend must have a 'request-post method." +network. The corresponding back end must have a 'request-post method." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. @@ -751,8 +735,7 @@ a news." If prefix argument YANK is non-nil, the original article is yanked automatically. YANK is a list of elements, where the car of each element is the -article number, and the two following numbers is the region to be -yanked." +article number, and the cdr is the string to be yanked." (interactive (list (and current-prefix-arg (gnus-summary-work-articles 1)))) @@ -1122,17 +1105,23 @@ If SILENT, don't prompt the user." (t gnus-select-method)))) +;; Dummies to avoid byte-compile warning. +(eval-when-compile + (defvar xemacs-codename)) + (defun gnus-message-make-user-agent (&optional include-mime-info max-column newline-product) "Return a user-agent info. If INCLUDE-MIME-INFO is non-nil and the variable `mime-edit-user-agent-value' is bound, the value will be -included in the return value. If MAX-COLUMN is specified, the return -value will be folded up as it were filled. NEWLINE-PRODUCT specifies -whether a newline should be inserted in front of each product-token. -If the value is t or `hard', it works strictly. Otherwise, if it is -non-nil (e.g. `soft'), it works semi-strictly. +included in the return value, and `gnus-user-agent' is ignored. If +MAX-COLUMN is specified, the return value will be folded up as it were +filled. NEWLINE-PRODUCT specifies whether a newline should be +inserted in front of each product-token. If the value is t or `hard', +it works strictly. Otherwise, if it is non-nil (e.g. `soft'), it +works semi-strictly. -Here is an example of how to use this function: +Here is an odd example, which inserts a User-Agent: header when you +begin to compose a message: \(add-hook 'gnus-message-setup-hook (lambda nil @@ -1145,12 +1134,23 @@ Here is an example of how to use this function: (gnus-message-make-user-agent t 76 'soft) \"\\n\"))))) " - (let ((user-agent (if (and include-mime-info - (boundp 'mime-edit-user-agent-value)) - (concat (gnus-extended-version) - " " - mime-edit-user-agent-value) - (gnus-extended-version)))) + (let ((gnus-v (gnus-extended-version)) + user-agent) + (cond ((and include-mime-info + (boundp 'mime-edit-user-agent-value)) + (setq user-agent (concat gnus-v " " mime-edit-user-agent-value))) + ((eq gnus-user-agent 'gnus-mime-edit) + (setq user-agent + (if (boundp 'mime-edit-user-agent-value) + (concat gnus-v " " mime-edit-user-agent-value) + gnus-v))) + (t + (setq user-agent (if (stringp gnus-user-agent) + gnus-user-agent + (concat gnus-v + (let ((emacs-v (gnus-emacs-version))) + (when emacs-v + (concat " " emacs-v)))))))) (when max-column (unless (natnump max-column) (setq max-column 76)) @@ -1226,7 +1226,7 @@ If VERY-WIDE, make a very wide reply." (gnus-summary-work-articles 1)))) ;; Allow user to require confirmation before replying by mail to the ;; author of a news article (or mail message). - (when (or + (when (or (not (or (gnus-news-group-p gnus-newsgroup-name) gnus-confirm-treat-mail-like-news)) (not (cond ((stringp gnus-confirm-mail-reply-to-news) @@ -1494,8 +1494,8 @@ composing a new message." (goto-char (point-max)) (insert mail-header-separator) (goto-char (point-min)) - (re-search-forward "^To:\\|^Newsgroups:" nil 'move) - (forward-char 1) + (when (re-search-forward "^To:\\|^Newsgroups:" nil 'move) + (forward-char 1)) (widen))))) (defun gnus-summary-post-forward (&optional full-headers) @@ -1591,7 +1591,7 @@ The current group name will be inserted at \"%s\".") ;; This mail group doesn't have a `to-list', so we add one ;; here. Magic! (when (gnus-y-or-n-p - (format "Do you want to add this as `to-list': %s " to-address)) + (format "Do you want to add this as `to-list': %s? " to-address)) (gnus-group-add-parameter group (cons 'to-list to-address)))))) (defun gnus-put-message () @@ -1789,7 +1789,7 @@ The source file has to be in the Emacs load path." (defun gnus-summary-resend-bounced-mail (&optional fetch) "Re-mail the current message. -This only makes sense if the current message is a bounce message than +This only makes sense if the current message is a bounce message that contains some mail you have written which has been bounced back to you. If FETCH, try to fetch the article that this is a reply to, if indeed @@ -1960,9 +1960,14 @@ this is a reply." (if (string-match " " gcc-self-val) (concat "\"" gcc-self-val "\"") gcc-self-val) - (if (string-match " " group) - (concat "\"" group "\"") - group))) + ;; In nndoc groups, we use the parent group name + ;; instead of the current group. + (let ((group (or (gnus-group-find-parameter + gnus-newsgroup-name 'parent-group) + group))) + (if (string-match " " group) + (concat "\"" group "\"") + group)))) (if (not (eq gcc-self-val 'none)) (insert "\n") (gnus-delete-line))) diff --git a/lisp/gnus-namazu.el b/lisp/gnus-namazu.el index 5ef95eb..ee43a56 100644 --- a/lisp/gnus-namazu.el +++ b/lisp/gnus-namazu.el @@ -1,6 +1,6 @@ ;;; gnus-namazu.el --- Search mail with Namazu -*- coding: iso-2022-7bit; -*- -;; Copyright (C) 2000,2001,2002 TSUCHIYA Masatoshi +;; Copyright (C) 2000,2001,2002,2003 TSUCHIYA Masatoshi ;; Author: TSUCHIYA Masatoshi ;; Keywords: mail searching namazu @@ -315,121 +315,76 @@ options make any sense in this context." ,query ,@gnus-namazu-index-directories)))) -(defsubst gnus-namazu/group-prefixed-name (group method) - "Return the whole name from GROUP and METHOD." - (if gnus-namazu-case-sensitive-filesystem - (gnus-group-prefixed-name group method) - (let* ((orig (gnus-group-prefixed-name group method)) - (name (downcase orig))) - (catch 'found-group - (mapatoms (lambda (sym) - (when (string= name (downcase (symbol-name sym))) - (throw 'found-group (symbol-name sym)))) - gnus-newsrc-hashtb) - orig)))) - -(defun gnus-namazu/real-group-name (cond str) - "Generate the real group name from the partial path, STR." - (if cond - str - (catch 'found-group - (dolist (group (gnus-namazu/possible-real-groups - (nnheader-replace-chars-in-string str ?/ ?.))) - (when (gnus-gethash group gnus-newsrc-hashtb) - (throw 'found-group group)))))) - -(defun gnus-namazu/possible-real-groups (str) - "Regard the string STR as the partial path of the cached article and -generate possible group names from it." - (if (string-match "_\\(_\\(_\\)?\\)?" str) - (let ((prefix (substring str 0 (match-beginning 0))) - (suffix (substring str (match-end 0)))) - (cond - ((match-beginning 2) ;; The number of discoverd underscores = 3 - (nconc - (gnus-namazu/possible-real-groups (concat prefix "/__" suffix)) - (gnus-namazu/possible-real-groups (concat prefix ".._" suffix)))) - ((match-beginning 1) ;; The number of discoverd underscores = 2 - (nconc - (gnus-namazu/possible-real-groups (concat prefix "//" suffix)) - (gnus-namazu/possible-real-groups (concat prefix ".." suffix)))) - (t ;; The number of discoverd underscores = 1 - (gnus-namazu/possible-real-groups (concat prefix "/" suffix))))) - (if (string-match "\\." str) - ;; Handle the first occurence of period. - (list (concat (substring str 0 (match-beginning 0)) - ":" - (substring str (match-end 0))) - str) - (list str)))) +(defvar gnus-namazu/directory-table nil) +(defun gnus-namazu/make-directory-table (&optional force) + (interactive (list t)) + (unless (and (not force) + gnus-namazu/directory-table + (eq gnus-namazu-case-sensitive-filesystem + (car gnus-namazu/directory-table))) + (let ((table (make-vector (length gnus-newsrc-hashtb) 0)) + cache agent alist dir method) + (mapatoms + (lambda (group) + (unless (gnus-ephemeral-group-p (setq group (symbol-name group))) + (when (file-directory-p + (setq dir (file-name-as-directory + (gnus-cache-file-name group "")))) + (push (cons dir group) cache)) + (when (file-directory-p + (setq dir (gnus-agent-group-pathname group))) + (push (cons dir group) agent)) + (when (memq (car (setq method (gnus-find-method-for-group group))) + '(nnml nnmh)) + (when (file-directory-p + (setq dir (nnmail-group-pathname + (gnus-group-short-name group) + (gnus-namazu/server-directory method)))) + (push (cons dir group) alist))))) + gnus-newsrc-hashtb) + (dolist (pair (nconc agent cache alist)) + (set (intern (if gnus-namazu-case-sensitive-filesystem + (car pair) + (downcase (car pair))) + table) + (cdr pair))) + (setq gnus-namazu/directory-table + (cons gnus-namazu-case-sensitive-filesystem table))))) (defun gnus-namazu/search (groups query) + (gnus-namazu/make-directory-table) (with-temp-buffer (let ((exit-status (gnus-namazu/call-namazu query))) (unless (zerop exit-status) - (error "Namazu finished abnormally: %d" exit-status)) - (let* ((articles) - (server-alist - (delq nil - (let (dir) - (mapcar - (lambda (s) - (when (setq dir (gnus-namazu/server-directory s)) - (cons (file-name-as-directory dir) s))) - (gnus-namazu/indexed-servers))))) - (topdir-regexp (regexp-opt (mapcar 'car server-alist))) - (cache-regexp (concat - (regexp-quote - (file-name-as-directory - (expand-file-name gnus-cache-directory))) - "\\(.*\\)/\\([0-9]+\\)$")) - (agent-regexp (concat - (regexp-quote - (file-name-as-directory - (expand-file-name gnus-agent-directory))) - "\\(.*\\)/\\([0-9]+\\)$"))) - (gnus-namazu/normalize-results) - (goto-char (point-min)) - (while (not (eobp)) - (let (server group file) - (and (or - ;; Check the discoverd file is the persistent article. - (and (looking-at cache-regexp) - (setq file (match-string-no-properties 2) - group (gnus-namazu/real-group-name - (gnus-use-long-file-name 'not-cache) - (match-string-no-properties 1)))) - ;; Check the discoverd file is covered by the agent. - (and (looking-at agent-regexp) - (setq file (match-string-no-properties 2) - group (gnus-namazu/real-group-name - nnmail-use-long-file-names - (match-string-no-properties 1)))) - ;; Check the discovered file is managed by Gnus servers. - (and (looking-at topdir-regexp) - (setq file (buffer-substring-no-properties - (match-end 0) (gnus-point-at-eol)) - server (cdr (assoc (match-string-no-properties 0) - server-alist))) - ;; Check validity of the file name. - (string-match "/\\([0-9]+\\)\\'" file) - (progn - (setq group (substring file 0 (match-beginning 0)) - file (match-string 1 file)) - (setq group - (gnus-namazu/group-prefixed-name - (if nnmail-use-long-file-names - group - (nnheader-replace-chars-in-string group - ?/ ?.)) - server))))) - (or (not groups) - (member group groups)) - (push (gnus-namazu/make-article group (string-to-number file)) - articles))) - (forward-line 1)) - (nreverse articles))))) - + (error "Namazu finished abnormally: %d" exit-status))) + (gnus-namazu/normalize-results) + (goto-char (point-min)) + (let (articles group) + (while (not (eobp)) + (setq group (buffer-substring-no-properties + (point) + (progn + (end-of-line) + ;; NOTE: Only numeric characters are permitted + ;; as file names of articles. + (skip-chars-backward "0-9") + (point)))) + (and (setq group + (symbol-value + (intern-soft (if gnus-namazu-case-sensitive-filesystem + group + (downcase group)) + (cdr gnus-namazu/directory-table)))) + (or (not groups) + (member group groups)) + (push (gnus-namazu/make-article + group + (string-to-number + (buffer-substring-no-properties (point) + (gnus-point-at-eol)))) + articles)) + (forward-line 1)) + (nreverse articles)))) ;;; User Interface: (defun gnus-namazu/get-target-groups () @@ -754,7 +709,8 @@ and make a virtual group contains its results." (gnus-namazu/mknmz-cleanup directory)) (message "Make index at %s...done" directory) (unless force - (kill-buffer (current-buffer))))))) + (kill-buffer (current-buffer))))) + (gnus-namazu/make-directory-table t))) (defun gnus-namazu/lapse-seconds (start end) "Return lapse seconds from START to END. @@ -834,15 +790,17 @@ than the period that is set to `gnus-namazu-index-update-interval'" nil))))) ;;;###autoload -(defun gnus-namazu-update-all-indices (&optional directories force) +(defun gnus-namazu-update-all-indices (&optional force) "Update all indices which is set to `gnus-namazu-index-directories'." - (interactive (list nil t)) + (interactive (list t)) + (gnus-namazu-update-indices gnus-namazu-index-directories force)) + +(defun gnus-namazu-update-indices (&optional directories force) (when (setq directories - (delq nil (mapcar - (lambda (d) (gnus-namazu/update-p d force)) - (or directories gnus-namazu-index-directories)))) - (setq gnus-namazu/update-directories (cdr directories)) - (gnus-namazu-update-index (car directories)))) + (delq nil (mapcar (lambda (d) (gnus-namazu/update-p d force)) + directories))) + (setq gnus-namazu/update-directories (cons force (cdr directories))) + (gnus-namazu-update-index (car directories) force))) (defun gnus-namazu/update-sentinel (process event) (let ((buffer (process-buffer process))) @@ -862,8 +820,9 @@ than the period that is set to `gnus-namazu-index-update-interval'" (unless (or debug-on-error debug-on-quit) (kill-buffer buffer))))))) (setq gnus-namazu/update-process nil) - (when gnus-namazu/update-directories - (gnus-namazu-update-all-indices gnus-namazu/update-directories))) + (unless (gnus-namazu-update-indices (cdr gnus-namazu/update-directories) + (car gnus-namazu/update-directories)) + (gnus-namazu/make-directory-table t))) ;;;###autoload (defun gnus-namazu-stop-update () diff --git a/lisp/gnus-nocem.el b/lisp/gnus-nocem.el index 38bd552..086b9f4 100644 --- a/lisp/gnus-nocem.el +++ b/lisp/gnus-nocem.el @@ -1,6 +1,6 @@ ;;; gnus-nocem.el --- NoCeM pseudo-cancellation treatment -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2004 ;; Free Software Foundation, Inc. @@ -298,7 +298,8 @@ valid issuer, which is much faster if you are selective about the issuers." (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)) diff --git a/lisp/gnus-picon.el b/lisp/gnus-picon.el index ae2d107..7c6c5e1 100644 --- a/lisp/gnus-picon.el +++ b/lisp/gnus-picon.el @@ -1,9 +1,9 @@ ;;; gnus-picon.el --- displaying pretty icons in Gnus -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 ;; Free Software Foundation, Inc. -;; Author: Wes Hardaker +;; Author: Lars Magne Ingebrigtsen ;; Keywords: news xpm annotation glyph faces ;; This file is part of GNU Emacs. @@ -35,7 +35,9 @@ ;; domain/dom/subdomain/unknown/face.gif ;; Groups: comp.lang.lisp ;; news/comp/lang/lisp/unknown/face.gif - +;; +;; Original implementation by Wes Hardaker . +;; ;;; Code: (eval-when-compile (require 'cl)) @@ -141,7 +143,7 @@ GLYPH can be either a glyph or a string." (insert glyph) (gnus-add-wash-type category) (gnus-add-image category (car glyph)) - (gnus-put-image (car glyph) (cdr glyph)))) + (gnus-put-image (car glyph) (cdr glyph) category))) (defun gnus-picon-create-glyph (file) (or (cdr (assoc file gnus-picon-glyph-alist)) @@ -153,7 +155,14 @@ GLYPH can be either a glyph or a string." (defun gnus-picon-transform-address (header category) (gnus-with-article-headers (let ((addresses - (mail-header-parse-addresses (mail-fetch-field header))) + (mail-header-parse-addresses + ;; mail-header-parse-addresses does not work (reliably) on + ;; decoded headers. + (or + (ignore-errors + (mail-encode-encoded-word-string + (or (mail-fetch-field header) ""))) + (mail-fetch-field header)))) spec file point cache) (dolist (address addresses) (setq address (car address)) @@ -229,37 +238,46 @@ GLYPH can be either a glyph or a string." ;;; Commands: +;; #### NOTE: the test for buffer-read-only is the same as in +;; article-display-[x-]face. See the comment up there. + ;;;###autoload (defun gnus-treat-from-picon () "Display picons in the From header. If picons are already displayed, remove them." (interactive) - (gnus-with-article-buffer - (if (memq 'from-picon gnus-article-wash-types) - (gnus-delete-images 'from-picon) - (gnus-picon-transform-address "from" 'from-picon)))) + (let ((wash-picon-p buffer-read-only)) + (gnus-with-article-buffer + (if (and wash-picon-p (memq 'from-picon gnus-article-wash-types)) + (gnus-delete-images 'from-picon) + (gnus-picon-transform-address "from" 'from-picon))) + )) ;;;###autoload (defun gnus-treat-mail-picon () "Display picons in the Cc and To headers. If picons are already displayed, remove them." (interactive) - (gnus-with-article-buffer - (if (memq 'mail-picon gnus-article-wash-types) - (gnus-delete-images 'mail-picon) - (gnus-picon-transform-address "cc" 'mail-picon) - (gnus-picon-transform-address "to" 'mail-picon)))) + (let ((wash-picon-p buffer-read-only)) + (gnus-with-article-buffer + (if (and wash-picon-p (memq 'mail-picon gnus-article-wash-types)) + (gnus-delete-images 'mail-picon) + (gnus-picon-transform-address "cc" 'mail-picon) + (gnus-picon-transform-address "to" 'mail-picon))) + )) ;;;###autoload (defun gnus-treat-newsgroups-picon () "Display picons in the Newsgroups and Followup-To headers. If picons are already displayed, remove them." (interactive) - (gnus-with-article-buffer - (if (memq 'newsgroups-picon gnus-article-wash-types) - (gnus-delete-images 'newsgroups-picon) - (gnus-picon-transform-newsgroups "newsgroups") - (gnus-picon-transform-newsgroups "followup-to")))) + (let ((wash-picon-p buffer-read-only)) + (gnus-with-article-buffer + (if (and wash-picon-p (memq 'newsgroups-picon gnus-article-wash-types)) + (gnus-delete-images 'newsgroups-picon) + (gnus-picon-transform-newsgroups "newsgroups") + (gnus-picon-transform-newsgroups "followup-to"))) + )) (provide 'gnus-picon) diff --git a/lisp/gnus-registry.el b/lisp/gnus-registry.el index 324155d..900eeab 100644 --- a/lisp/gnus-registry.el +++ b/lisp/gnus-registry.el @@ -24,6 +24,34 @@ ;;; Commentary: +;; This is the gnus-registry.el package, works with other backends +;; besides nnmail. The major issue is that it doesn't go across +;; backends, so for instance if an article is in nnml:sys and you see +;; a reference to it in nnimap splitting, the article will end up in +;; nnimap:sys + +;; gnus-registry.el intercepts article respooling, moving, deleting, +;; and copying for all backends. If it doesn't work correctly for +;; you, submit a bug report and I'll be glad to fix it. It needs +;; documentation in the manual (also on my to-do list). + +;; Put this in your startup file (~/.gnus.el for instance) + +;; (setq gnus-registry-max-entries 2500 +;; gnus-registry-use-long-group-names t) + +;; (gnus-registry-initialize) + +;; Then use this in your fancy-split: + +;; (: gnus-registry-split-fancy-with-parent) + +;; TODO: + +;; - get the correct group on spool actions + +;; - articles that are spooled to a different backend should be handled + ;;; Code: (eval-when-compile (require 'cl)) @@ -33,6 +61,9 @@ (require 'gnus-sum) (require 'nnmail) +(defvar gnus-registry-dirty t + "Boolean set to t when the registry is modified") + (defgroup gnus-registry nil "The Gnus registry." :group 'gnus) @@ -40,19 +71,63 @@ (defvar gnus-registry-hashtb nil "*The article registry by Message ID.") -(defvar gnus-registry-headers-hashtb nil - "*The article header registry by Message ID. Unused for now.") - (defcustom gnus-registry-unfollowed-groups '("delayed" "drafts" "queue") "List of groups that gnus-registry-split-fancy-with-parent won't follow. The group names are matched, they don't have to be fully qualified." :group 'gnus-registry :type '(repeat string)) -(defcustom gnus-registry-unregistered-group-regex "^nntp" - "Group name regex that gnus-registry-register-message-ids won't process." +(defcustom gnus-registry-install nil + "Whether the registry should be installed." :group 'gnus-registry - :type 'regexp) + :type 'boolean) + +(defcustom gnus-registry-clean-empty t + "Whether the empty registry entries should be deleted. +Registry entries are considered empty when they have no groups." + :group 'gnus-registry + :type 'boolean) + +(defcustom gnus-registry-use-long-group-names nil + "Whether the registry should use long group names (BUGGY)." + :group 'gnus-registry + :type 'boolean) + +(defcustom gnus-registry-track-extra nil + "Whether the registry should track extra data about a message. +The Subject and Sender (From:) headers are currently tracked this +way." + :group 'gnus-registry + :type + '(set :tag "Tracking choices" + (const :tag "Track by subject (Subject: header)" subject) + (const :tag "Track by sender (From: header)" sender))) + +(defcustom gnus-registry-entry-caching t + "Whether the registry should cache extra information." + :group 'gnus-registry + :type 'boolean) + +(defcustom gnus-registry-minimum-subject-length 5 + "The minimum length of a subject before it's considered trackable." + :group 'gnus-registry + :type 'integer) + +(defcustom gnus-registry-trim-articles-without-groups t + "Whether the registry should clean out message IDs without groups." + :group 'gnus-registry + :type 'boolean) + +(defcustom gnus-registry-cache-file "~/.gnus.registry.eld" + "File where the Gnus registry will be stored." + :group 'gnus-registry + :type 'file) + +(defcustom gnus-registry-max-entries nil + "Maximum number of entries in the registry, nil for unlimited." + :group 'gnus-registry + :type '(radio (const :format "Unlimited " nil) + (integer :format "Maximum number: %v\n" :size 0))) ;; Function(s) missing in Emacs 20 (when (memq nil (mapcar 'fboundp '(puthash))) @@ -61,11 +136,155 @@ The group names are matched, they don't have to be fully qualified." ;; alias puthash is missing from Emacs 20 cl-extra.el (defalias 'puthash 'cl-puthash))) -(defun gnus-registry-translate-to-alist () - (setq gnus-registry-alist (hashtable-to-alist gnus-registry-hashtb))) +(defun gnus-registry-track-subject-p () + (memq 'subject gnus-registry-track-extra)) + +(defun gnus-registry-track-sender-p () + (memq 'sender gnus-registry-track-extra)) -(defun gnus-registry-translate-from-alist () - (setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist))) +(defun gnus-registry-cache-read () + "Read the registry cache file." + (interactive) + (let ((file gnus-registry-cache-file)) + (when (file-exists-p file) + (gnus-message 5 "Reading %s..." file) + (gnus-load file) + (gnus-message 5 "Reading %s...done" file)))) + +(defun gnus-registry-cache-save () + "Save the registry cache file." + (interactive) + (let ((file gnus-registry-cache-file)) + (save-excursion + (set-buffer (gnus-get-buffer-create " *Gnus-registry-cache*")) + (make-local-variable 'version-control) + (setq version-control gnus-backup-startup-file) + (setq buffer-file-name file) + (setq default-directory (file-name-directory buffer-file-name)) + (buffer-disable-undo) + (erase-buffer) + (gnus-message 5 "Saving %s..." file) + (if gnus-save-startup-file-via-temp-buffer + (let ((coding-system-for-write gnus-ding-file-coding-system) + (standard-output (current-buffer))) + (gnus-gnus-to-quick-newsrc-format t "gnus registry startup file" 'gnus-registry-alist) + (gnus-registry-cache-whitespace file) + (save-buffer)) + (let ((coding-system-for-write gnus-ding-file-coding-system) + (version-control gnus-backup-startup-file) + (startup-file file) + (working-dir (file-name-directory file)) + working-file + (i -1)) + ;; Generate the name of a non-existent file. + (while (progn (setq working-file + (format + (if (and (eq system-type 'ms-dos) + (not (gnus-long-file-names))) + "%s#%d.tm#" ; MSDOS limits files to 8+3 + (if (memq system-type '(vax-vms axp-vms)) + "%s$tmp$%d" + "%s#tmp#%d")) + working-dir (setq i (1+ i)))) + (file-exists-p working-file))) + + (unwind-protect + (progn + (gnus-with-output-to-file working-file + (gnus-gnus-to-quick-newsrc-format t "gnus registry startup file" 'gnus-registry-alist)) + + ;; These bindings will mislead the current buffer + ;; into thinking that it is visiting the startup + ;; file. + (let ((buffer-backed-up nil) + (buffer-file-name startup-file) + (file-precious-flag t) + (setmodes (file-modes startup-file))) + ;; Backup the current version of the startup file. + (backup-buffer) + + ;; Replace the existing startup file with the temp file. + (rename-file working-file startup-file t) + (set-file-modes startup-file setmodes))) + (condition-case nil + (delete-file working-file) + (file-error nil))))) + + (gnus-kill-buffer (current-buffer)) + (gnus-message 5 "Saving %s...done" file)))) + +;; Idea from Dan Christensen +;; Save the gnus-registry file with extra line breaks. +(defun gnus-registry-cache-whitespace (filename) + (gnus-message 5 "Adding whitespace to %s" filename) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^(\\|(\\\"" nil t) + (replace-match "\n\\&" t)) + (goto-char (point-min)) + (while (re-search-forward " $" nil t) + (replace-match "" t t)))) + +(defun gnus-registry-save (&optional force) + (when (or gnus-registry-dirty force) + (let ((caching gnus-registry-entry-caching)) + ;; turn off entry caching, so mtime doesn't get recorded + (setq gnus-registry-entry-caching nil) + ;; remove entry caches + (maphash + (lambda (key value) + (if (hash-table-p value) + (remhash key gnus-registry-hashtb))) + gnus-registry-hashtb) + ;; remove empty entries + (when gnus-registry-clean-empty + (gnus-registry-clean-empty-function)) + ;; now trim the registry appropriately + (setq gnus-registry-alist (gnus-registry-trim + (hashtable-to-alist gnus-registry-hashtb))) + ;; really save + (gnus-registry-cache-save) + (setq gnus-registry-entry-caching caching) + (setq gnus-registry-dirty nil)))) + +(defun gnus-registry-clean-empty-function () + "Remove all empty entries from the registry. Returns count thereof." + (let ((count 0)) + (maphash + (lambda (key value) + (unless (gnus-registry-fetch-group key) + (incf count) + (remhash key gnus-registry-hashtb))) + gnus-registry-hashtb) + count)) + +(defun gnus-registry-read () + (gnus-registry-cache-read) + (setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist)) + (setq gnus-registry-dirty nil)) + +(defun gnus-registry-trim (alist) + "Trim alist to size, using gnus-registry-max-entries." + (if (null gnus-registry-max-entries) + alist ; just return the alist + ;; else, when given max-entries, trim the alist + (let ((timehash (make-hash-table + :size 4096 + :test 'equal))) + (maphash + (lambda (key value) + (puthash key (gnus-registry-fetch-extra key 'mtime) timehash)) + gnus-registry-hashtb) + + ;; we use the return value of this setq, which is the trimmed alist + (setq alist + (nthcdr + (- (length alist) gnus-registry-max-entries) + (sort alist + (lambda (a b) + (time-less-p + (cdr (gethash (car a) timehash)) + (cdr (gethash (car b) timehash)))))))))) (defun alist-to-hashtable (alist) "Build a hashtable from the values in ALIST." @@ -87,12 +306,15 @@ The group names are matched, they don't have to be fully qualified." hash) list)) -(defun gnus-register-action (action data-header from &optional to method) +(defun gnus-registry-action (action data-header from &optional to method) (let* ((id (mail-header-id data-header)) - (from (gnus-group-guess-full-name from)) - (to (if to (gnus-group-guess-full-name to) nil)) - (to-name (if to to "the Bit Bucket")) - (old-entry (gethash id gnus-registry-hashtb))) + (subject (gnus-registry-simplify-subject + (mail-header-subject data-header))) + (sender (mail-header-from data-header)) + (from (gnus-group-guess-full-name-from-command-method from)) + (to (if to (gnus-group-guess-full-name-from-command-method to) nil)) + (to-name (if to to "the Bit Bucket")) + (old-entry (gethash id gnus-registry-hashtb))) (gnus-message 5 "Registry: article %s %s from %s to %s" id (if method "respooling" "going") @@ -103,21 +325,18 @@ The group names are matched, they don't have to be fully qualified." (gnus-registry-delete-group id from) (when (equal 'copy action) - (gnus-registry-add-group id from)) ; undo the delete - - (gnus-registry-add-group id to))) - -(defun gnus-register-spool-action (id group) - ;; do not process the draft IDs -; (unless (string-match "totally-fudged-out-message-id" id) -; (let ((group (gnus-group-guess-full-name group))) - (when (string-match "\r$" id) - (setq id (substring id 0 -1))) - (gnus-message 5 "Registry: article %s spooled to %s" - id - group) - (gnus-registry-add-group id group)) -;) + (gnus-registry-add-group id from subject sender)) ; undo the delete + + (gnus-registry-add-group id to subject sender))) + +(defun gnus-registry-spool-action (id group &optional subject sender) + (let ((group (gnus-group-guess-full-name-from-command-method group))) + (when (and (stringp id) (string-match "\r$" id)) + (setq id (substring id 0 -1))) + (gnus-message 5 "Registry: article %s spooled to %s" + id + group) + (gnus-registry-add-group id group subject sender))) ;; Function for nn{mail|imap}-split-fancy: look up all references in ;; the cache and if a match is found, return that group. @@ -134,37 +353,120 @@ see which group that message was put in. This group is returned. See the Info node `(gnus)Fancy Mail Splitting' for more details." (let ((refstr (or (message-fetch-field "references") (message-fetch-field "in-reply-to"))) - (references nil) - (res nil)) - (when refstr - (setq references (nreverse (gnus-split-references refstr))) - (mapcar (lambda (x) - (setq res (or (gnus-registry-fetch-group x) res)) - (when (or (gnus-registry-grep-in-list - res - gnus-registry-unfollowed-groups) - (gnus-registry-grep-in-list - res - nnmail-split-fancy-with-parent-ignore-groups)) - (setq res nil))) - references) - (gnus-message - 5 - "gnus-registry-split-fancy-with-parent traced %s to group %s" - refstr (if res res "nil")) - res))) + (nnmail-split-fancy-with-parent-ignore-groups + (if (listp nnmail-split-fancy-with-parent-ignore-groups) + nnmail-split-fancy-with-parent-ignore-groups + (list nnmail-split-fancy-with-parent-ignore-groups))) + references res) + (if refstr + (progn + (setq references (nreverse (gnus-split-references refstr))) + (mapcar (lambda (x) + (setq res (or (gnus-registry-fetch-group x) res)) + (when (or (gnus-registry-grep-in-list + res + gnus-registry-unfollowed-groups) + (gnus-registry-grep-in-list + res + nnmail-split-fancy-with-parent-ignore-groups)) + (setq res nil))) + references)) + + ;; else: there were no references, now try the extra tracking + (let ((sender (message-fetch-field "from")) + (subject (gnus-registry-simplify-subject + (message-fetch-field "subject"))) + (single-match t)) + (when (and single-match + (gnus-registry-track-sender-p) + sender) + (maphash + (lambda (key value) + (let ((this-sender (cdr + (gnus-registry-fetch-extra key 'sender)))) + (when (and single-match + this-sender + (equal sender this-sender)) + ;; too many matches, bail + (unless (equal res (gnus-registry-fetch-group key)) + (setq single-match nil)) + (setq res (gnus-registry-fetch-group key)) + (gnus-message + ;; raise level of messaging if gnus-registry-track-extra + (if gnus-registry-track-extra 5 9) + "%s (extra tracking) traced sender %s to group %s" + "gnus-registry-split-fancy-with-parent" + sender + (if res res "nil"))))) + gnus-registry-hashtb)) + (when (and single-match + (gnus-registry-track-subject-p) + subject + (< gnus-registry-minimum-subject-length (length subject))) + (maphash + (lambda (key value) + (let ((this-subject (cdr + (gnus-registry-fetch-extra key 'subject)))) + (when (and single-match + this-subject + (equal subject this-subject)) + ;; too many matches, bail + (unless (equal res (gnus-registry-fetch-group key)) + (setq single-match nil)) + (setq res (gnus-registry-fetch-group key)) + (gnus-message + ;; raise level of messaging if gnus-registry-track-extra + (if gnus-registry-track-extra 5 9) + "%s (extra tracking) traced subject %s to group %s" + "gnus-registry-split-fancy-with-parent" + subject + (if res res "nil"))))) + gnus-registry-hashtb)) + (unless single-match + (gnus-message + 5 + "gnus-registry-split-fancy-with-parent: too many extra matches for %s" + refstr) + (setq res nil)))) + (gnus-message + 5 + "gnus-registry-split-fancy-with-parent traced %s to group %s" + refstr (if res res "nil")) + + (when (and res gnus-registry-use-long-group-names) + (let ((m1 (gnus-find-method-for-group res)) + (m2 (or gnus-command-method + (gnus-find-method-for-group gnus-newsgroup-name))) + (short-res (gnus-group-short-name res))) + (if (gnus-methods-equal-p m1 m2) + (progn + (gnus-message + 9 + "gnus-registry-split-fancy-with-parent stripped group %s to %s" + res + short-res) + (setq res short-res)) + ;; else... + (gnus-message + 5 + "gnus-registry-split-fancy-with-parent ignored foreign group %s" + res) + (setq res nil)))) + res)) (defun gnus-registry-register-message-ids () "Register the Message-ID of every article in the group" - (unless (and gnus-registry-unregistered-group-regex - (string-match gnus-registry-unregistered-group-regex gnus-newsgroup-name)) + (unless (gnus-parameter-registry-ignore gnus-newsgroup-name) (dolist (article gnus-newsgroup-articles) (let ((id (gnus-registry-fetch-message-id-fast article))) (unless (gnus-registry-fetch-group id) (gnus-message 9 "Registry: Registering article %d with group %s" article gnus-newsgroup-name) - (gnus-registry-add-group (gnus-registry-fetch-message-id-fast article) - gnus-newsgroup-name)))))) + (gnus-registry-add-group + (gnus-registry-fetch-message-id-fast article) + gnus-newsgroup-name + (gnus-registry-fetch-simplified-message-subject-fast article) + (gnus-registry-fetch-sender-fast article))))))) (defun gnus-registry-fetch-message-id-fast (article) "Fetch the Message-ID quickly, using the internal gnus-data-list function" @@ -173,6 +475,28 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (mail-header-id (gnus-data-header (assoc article (gnus-data-list nil)))) nil)) +(defun gnus-registry-simplify-subject (subject) + (if (stringp subject) + (gnus-simplify-subject subject) + nil)) + +(defun gnus-registry-fetch-simplified-message-subject-fast (article) + "Fetch the Subject quickly, using the internal gnus-data-list function" + (if (and (numberp article) + (assoc article (gnus-data-list nil))) + (gnus-registry-simplify-subject + (mail-header-subject (gnus-data-header + (assoc article (gnus-data-list nil))))) + nil)) + +(defun gnus-registry-fetch-sender-fast (article) + "Fetch the Sender quickly, using the internal gnus-data-list function" + (if (and (numberp article) + (assoc article (gnus-data-list nil))) + (mail-header-from (gnus-data-header + (assoc article (gnus-data-list nil)))) + nil)) + (defun gnus-registry-grep-in-list (word list) (when word (memq nil @@ -182,18 +506,91 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (string-match x word)) list))))) +(defun gnus-registry-fetch-extra (id &optional entry) + "Get the extra data of a message, based on the message ID. +Returns the first place where the trail finds a nonstring." + (let ((entry-cache (gethash entry gnus-registry-hashtb))) + (if (and entry + (hash-table-p entry-cache) + (gethash id entry-cache)) + (gethash id entry-cache) + ;; else, if there is no caching possible... + (let ((trail (gethash id gnus-registry-hashtb))) + (when (listp trail) + (dolist (crumb trail) + (unless (stringp crumb) + (return (gnus-registry-fetch-extra-entry crumb entry id))))))))) + +(defun gnus-registry-fetch-extra-entry (alist &optional entry id) + "Get the extra data of a message, or a specific entry in it. +Update the entry cache if needed." + (if (and entry id) + (let ((entry-cache (gethash entry gnus-registry-hashtb)) + entree) + (when gnus-registry-entry-caching + ;; create the hash table + (unless (hash-table-p entry-cache) + (setq entry-cache (make-hash-table + :size 4096 + :test 'equal)) + (puthash entry entry-cache gnus-registry-hashtb)) + + ;; get the entree from the hash table or from the alist + (setq entree (gethash id entry-cache))) + + (unless entree + (setq entree (assq entry alist)) + (when gnus-registry-entry-caching + (puthash id entree entry-cache))) + entree) + alist)) + +(defun gnus-registry-store-extra (id extra) + "Store the extra data of a message, based on the message ID. +The message must have at least one group name." + (when (gnus-registry-group-count id) + ;; we now know the trail has at least 1 group name, so it's not empty + (let ((trail (gethash id gnus-registry-hashtb)) + (old-extra (gnus-registry-fetch-extra id)) + entry-cache) + (dolist (crumb trail) + (unless (stringp crumb) + (dolist (entry crumb) + (setq entry-cache (gethash (car entry) gnus-registry-hashtb)) + (when entry-cache + (remhash id entry-cache)))) + (puthash id (cons extra (delete old-extra trail)) + gnus-registry-hashtb) + (setq gnus-registry-dirty t))))) + +(defun gnus-registry-store-extra-entry (id key value) + "Put a specific entry in the extras field of the registry entry for id." + (let* ((extra (gnus-registry-fetch-extra id)) + (alist (cons (cons key value) + (gnus-assq-delete-all key (gnus-registry-fetch-extra id))))) + (gnus-registry-store-extra id alist))) + (defun gnus-registry-fetch-group (id) "Get the group of a message, based on the message ID. -Returns the first place where the trail finds a spool action." - (when id +Returns the first place where the trail finds a group name." + (when (gnus-registry-group-count id) + ;; we now know the trail has at least 1 group name (let ((trail (gethash id gnus-registry-hashtb))) - (if trail - (car trail) - nil)))) + (dolist (crumb trail) + (when (stringp crumb) + (return (if gnus-registry-use-long-group-names + crumb + (gnus-group-short-name crumb)))))))) + +(defun gnus-registry-group-count (id) + "Get the number of groups of a message, based on the message ID." + (let ((trail (gethash id gnus-registry-hashtb))) + (if (and trail (listp trail)) + (apply '+ (mapcar (lambda (x) (if (stringp x) 1 0)) trail)) + 0))) (defun gnus-registry-delete-group (id group) - "Get the group of a message, based on the message ID. -Returns the first place where the trail finds a spool action." + "Delete a group for a message, based on the message ID." (when group (when id (let ((trail (gethash id gnus-registry-hashtb)) @@ -202,41 +599,101 @@ Returns the first place where the trail finds a spool action." (delete group trail) nil) gnus-registry-hashtb)) - ;; now, clear the entry if it's empty - (unless (gethash id gnus-registry-hashtb) - (remhash id gnus-registry-hashtb))))) + ;; now, clear the entry if there are no more groups + (when gnus-registry-trim-articles-without-groups + (unless (gnus-registry-group-count id) + (gnus-registry-delete-id id))) + (gnus-registry-store-extra-entry id 'mtime (current-time))))) + +(defun gnus-registry-delete-id (id) + "Delete a message ID from the registry." + (when (stringp id) + (remhash id gnus-registry-hashtb) + (maphash + (lambda (key value) + (when (hash-table-p value) + (remhash id value))) + gnus-registry-hashtb))) -(defun gnus-registry-add-group (id group) - "Get the group of a message, based on the message ID. -Returns the first place where the trail finds a spool action." - ;; make sure there are no duplicate entries +(defun gnus-registry-add-group (id group &optional subject sender) + "Add a group for a message, based on the message ID." (when group - (when id - (let ((group (gnus-group-short-name group))) - (gnus-registry-delete-group id group) + (when (and id + (not (string-match "totally-fudged-out-message-id" id))) + (let ((full-group group) + (group (if gnus-registry-use-long-group-names + group + (gnus-group-short-name group)))) + (gnus-registry-delete-group id group) + + (unless gnus-registry-use-long-group-names ;; unnecessary in this case + (gnus-registry-delete-group id full-group)) + (let ((trail (gethash id gnus-registry-hashtb))) (puthash id (if trail (cons group trail) (list group)) - gnus-registry-hashtb)))))) + gnus-registry-hashtb) + + (when (and (gnus-registry-track-subject-p) + subject) + (gnus-registry-store-extra-entry + id + 'subject + (gnus-registry-simplify-subject subject))) + (when (and (gnus-registry-track-sender-p) + sender) + (gnus-registry-store-extra-entry + id + 'sender + sender)) + + (gnus-registry-store-extra-entry id 'mtime (current-time))))))) (defun gnus-registry-clear () "Clear the Gnus registry." (interactive) - (setq gnus-registry-alist nil - gnus-registry-headers-alist nil) - (gnus-registry-translate-from-alist)) - -; also does copy, respool, and crosspost -(add-hook 'gnus-summary-article-move-hook 'gnus-register-action) -(add-hook 'gnus-summary-article-delete-hook 'gnus-register-action) -(add-hook 'gnus-summary-article-expire-hook 'gnus-register-action) -(add-hook 'nnmail-spool-hook 'gnus-register-spool-action) + (setq gnus-registry-alist nil) + (setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist)) + (setq gnus-registry-dirty t)) -(add-hook 'gnus-save-newsrc-hook 'gnus-registry-translate-to-alist) -(add-hook 'gnus-read-newsrc-el-hook 'gnus-registry-translate-from-alist) +;;;###autoload +(defun gnus-registry-initialize () + (interactive) + (setq gnus-registry-install t) + (gnus-registry-install-hooks) + (gnus-registry-read)) -(add-hook 'gnus-summary-prepare-hook 'gnus-registry-register-message-ids) +;;;###autoload +(defun gnus-registry-install-hooks () + "Install the registry hooks." + (interactive) + (add-hook 'gnus-summary-article-move-hook 'gnus-registry-action) + (add-hook 'gnus-summary-article-delete-hook 'gnus-registry-action) + (add-hook 'gnus-summary-article-expire-hook 'gnus-registry-action) + (add-hook 'nnmail-spool-hook 'gnus-registry-spool-action) + + (add-hook 'gnus-save-newsrc-hook 'gnus-registry-save) + (add-hook 'gnus-read-newsrc-el-hook 'gnus-registry-read) + + (add-hook 'gnus-summary-prepare-hook 'gnus-registry-register-message-ids)) + +(defun gnus-registry-unload-hook () + "Uninstall the registry hooks." + (interactive) + (remove-hook 'gnus-summary-article-move-hook 'gnus-registry-action) + (remove-hook 'gnus-summary-article-delete-hook 'gnus-registry-action) + (remove-hook 'gnus-summary-article-expire-hook 'gnus-registry-action) + (remove-hook 'nnmail-spool-hook 'gnus-registry-spool-action) + + (remove-hook 'gnus-save-newsrc-hook 'gnus-registry-save) + (remove-hook 'gnus-read-newsrc-el-hook 'gnus-registry-read) + + (remove-hook 'gnus-summary-prepare-hook 'gnus-registry-register-message-ids)) + +(when gnus-registry-install + (gnus-registry-install-hooks) + (gnus-registry-read)) ;; TODO: a lot of things diff --git a/lisp/gnus-score.el b/lisp/gnus-score.el index 865ecdc..d9015b6 100644 --- a/lisp/gnus-score.el +++ b/lisp/gnus-score.el @@ -239,7 +239,8 @@ This variable allows the same syntax as `gnus-home-score-file'." (defcustom gnus-adaptive-word-length-limit nil "*Words of a length lesser than this limit will be ignored when doing adaptive scoring." :group 'gnus-score-adapt - :type 'integer) + :type '(radio (const :format "Unlimited " nil) + (integer :format "Maximum length: %v\n" :size 0))) (defcustom gnus-ignored-adaptive-words nil "List of words to be ignored when doing adaptive word scoring." @@ -526,7 +527,8 @@ of the last successful match.") "Make a score entry based on the current article. The user will be prompted for header to score on, match type, permanence, and the string to be used. The numerical prefix will be -used as score." +used as score. A symbolic prefix of `a' says to use the `all.SCORE' +file for the command instead of the current score file." (interactive (gnus-interactive "P\ny")) (gnus-summary-increase-score (- (gnus-score-delta-default score)) symp)) @@ -540,7 +542,8 @@ used as score." "Make a score entry based on the current article. The user will be prompted for header to score on, match type, permanence, and the string to be used. The numerical prefix will be -used as score." +used as score. A symbolic prefix of `a' says to use the `all.SCORE' +file for the command instead of the current score file." (interactive (gnus-interactive "P\ny")) (let* ((nscore (gnus-score-delta-default score)) (prefix (if (< nscore 0) ?L ?I)) @@ -909,7 +912,7 @@ If optional argument `EXTRA' is non-nil, it's a non-standard overview header." ;; Return the new scoring rule. new)) -(defun gnus-summary-score-effect (header match type score extra) +(defun gnus-summary-score-effect (header match type score &optional extra) "Simulate the effect of a score file entry. HEADER is the header being scored. MATCH is the string we are looking for. @@ -921,8 +924,8 @@ EXTRA is the possible non-standard header." (lambda (x) (fboundp (nth 2 x))) t) (read-string "Match: ") - (y-or-n-p "Use regexp match? ") - (prefix-numeric-value current-prefix-arg))) + (if (y-or-n-p "Use regexp match? ") 'r 's) + (string-to-int (read-string "Score: ")))) (save-excursion (unless (and (stringp match) (> (length match) 0)) (error "No match")) @@ -1138,21 +1141,38 @@ EXTRA is the possible non-standard header." 4 (substitute-command-keys "\\\\[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. @@ -2386,7 +2406,10 @@ score in `gnus-newsgroup-scored' by SCORE." (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) @@ -2396,18 +2419,44 @@ score in `gnus-newsgroup-scored' by SCORE." 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) @@ -2952,13 +3001,19 @@ If ADAPT, return the home adaptive file instead." (defun gnus-decay-score (score) "Decay SCORE according to `gnus-score-decay-constant' and `gnus-score-decay-scale'." - (floor - (- score - (* (if (< score 0) -1 1) - (min (abs score) - (max gnus-score-decay-constant - (* (abs score) - gnus-score-decay-scale))))))) + (let ((n (- score + (* (if (< score 0) -1 1) + (min (abs score) + (max gnus-score-decay-constant + (* (abs score) + gnus-score-decay-scale))))))) + (if (and (featurep 'xemacs) + ;; XEmacs' floor can handle only the floating point + ;; number below the half of the maximum integer. + (> (abs n) (lsh -1 -2))) + (string-to-number + (car (split-string (number-to-string n) "\\."))) + (floor n)))) (defun gnus-decay-scores (alist day) "Decay non-permanent scores in ALIST." diff --git a/lisp/gnus-sieve.el b/lisp/gnus-sieve.el index b11ade5..824e66c 100644 --- a/lisp/gnus-sieve.el +++ b/lisp/gnus-sieve.el @@ -66,7 +66,7 @@ For example: \"nnimap:mailbox\"" (defcustom gnus-sieve-crosspost t "Whether the generated Sieve script should do crossposting." - :type 'bool + :type 'boolean :group 'gnus-sieve) (defcustom gnus-sieve-update-shell-command "echo put %f | sieveshell %s" diff --git a/lisp/gnus-soup.el b/lisp/gnus-soup.el index 59b641d..2b9d305 100644 --- a/lisp/gnus-soup.el +++ b/lisp/gnus-soup.el @@ -358,9 +358,9 @@ If NOT-ALL, don't pack ticked articles." (gnus-make-directory dir) (setq gnus-soup-areas nil) (gnus-message 4 "Packing %s..." packer) - (if (zerop (call-process shell-file-name - nil nil nil shell-command-switch - (concat "cd " dir " ; " packer))) + (if (eq 0 (call-process shell-file-name + nil nil nil shell-command-switch + (concat "cd " dir " ; " packer))) (progn (call-process shell-file-name nil nil nil shell-command-switch (concat "cd " dir " ; rm " files)) @@ -497,10 +497,10 @@ Return whether the unpacking was successful." (gnus-make-directory dir) (gnus-message 4 "Unpacking: %s" (format unpacker packet)) (prog1 - (zerop (call-process - shell-file-name nil nil nil shell-command-switch - (format "cd %s ; %s" (expand-file-name dir) - (format unpacker packet)))) + (eq 0 (call-process + shell-file-name nil nil nil shell-command-switch + (format "cd %s ; %s" (expand-file-name dir) + (format unpacker packet)))) (gnus-message 4 "Unpacking...done"))) (defun gnus-soup-send-packet (packet) @@ -550,7 +550,7 @@ Return whether the unpacking was successful." (sit-for 1) (let ((message-syntax-checks 'dont-check-for-anything-just-trust-me) - (method (if (message-functionp message-post-method) + (method (if (functionp message-post-method) (funcall message-post-method) message-post-method)) result) diff --git a/lisp/gnus-srvr.el b/lisp/gnus-srvr.el index c759d19..bfc3d08 100644 --- a/lisp/gnus-srvr.el +++ b/lisp/gnus-srvr.el @@ -281,8 +281,7 @@ The following commands are available: "(closed)") ((error) "(error)"))))) (gnus-tmp-agent (if (and gnus-agent - (member method - gnus-agent-covered-methods)) + (gnus-agent-method-p method)) " (agent)" ""))) (beginning-of-line) @@ -291,7 +290,8 @@ The following commands are available: (prog1 (1+ (point)) ;; Insert the text. (eval gnus-server-line-format-spec)) - (list 'gnus-server (intern gnus-tmp-name))))) + (list 'gnus-server (intern gnus-tmp-name) + 'gnus-named-server (intern (gnus-method-to-server method)))))) (defun gnus-enter-server-buffer () "Set up the server buffer." @@ -345,6 +345,12 @@ The following commands are available: (let ((server (get-text-property (gnus-point-at-bol) 'gnus-server))) (and server (symbol-name server)))) +(defun gnus-server-named-server () + "Returns a server name that matches one of the names returned by +gnus-method-to-server." + (let ((server (get-text-property (gnus-point-at-bol) 'gnus-named-server))) + (and server (symbol-name server)))) + (defalias 'gnus-server-position-point 'gnus-goto-colon) (defconst gnus-server-edit-buffer "*Gnus edit server*") @@ -713,31 +719,46 @@ The following commands are available: 1 "Couldn't request list: %s" (gnus-status-message method)) nil) (t - (save-excursion - (set-buffer nntp-server-buffer) + (with-current-buffer nntp-server-buffer (let ((cur (current-buffer))) (goto-char (point-min)) (unless (string= gnus-ignored-newsgroups "") (delete-matching-lines gnus-ignored-newsgroups)) - (while (not (eobp)) - (ignore-errors - (push (cons - (if (eq (char-after) ?\") - (read cur) - (let ((p (point)) (name "")) - (skip-chars-forward "^ \t\\\\") - (setq name (buffer-substring p (point))) - (while (eq (char-after) ?\\) - (setq p (1+ (point))) - (forward-char 2) + ;; We treat NNTP as a special case to avoid problems with + ;; garbage group names like `"foo' that appear in some badly + ;; managed active files. -jh. + (if (eq (car method) 'nntp) + (while (not (eobp)) + (ignore-errors + (push (cons + (buffer-substring + (point) + (progn + (skip-chars-forward "^ \t") + (point))) + (let ((last (read cur))) + (cons (read cur) last))) + groups)) + (forward-line)) + (while (not (eobp)) + (ignore-errors + (push (cons + (if (eq (char-after) ?\") + (read cur) + (let ((p (point)) (name "")) (skip-chars-forward "^ \t\\\\") - (setq name (concat name (buffer-substring - p (point))))) - name)) - (let ((last (read cur))) - (cons (read cur) last))) - groups)) - (forward-line)))) + (setq name (buffer-substring p (point))) + (while (eq (char-after) ?\\) + (setq p (1+ (point))) + (forward-char 2) + (skip-chars-forward "^ \t\\\\") + (setq name (concat name (buffer-substring + p (point))))) + name)) + (let ((last (read cur))) + (cons (read cur) last))) + groups)) + (forward-line))))) (setq groups (sort groups (lambda (l1 l2) (string< (car l1) (car l2))))) @@ -896,6 +917,8 @@ buffer. (unless (eq (char-after) ? ) (setq sub t)) (setq group (gnus-browse-group-name)) + (when (gnus-server-equal gnus-browse-current-method "native") + (setq group (gnus-group-real-name group))) (if sub (progn ;; Make sure the group has been properly removed before we diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index bee9b60..122288a 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -36,6 +36,8 @@ (require 'gnus-range) (require 'gnus-util) (autoload 'message-make-date "message") +(autoload 'gnus-agent-read-servers-validate "gnus-agent") +(autoload 'gnus-agent-possibly-alter-active "gnus-agent") (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc") "Your `.newsrc' file. @@ -250,7 +252,12 @@ nil if you set this variable to nil. This variable can also be a regexp. In that case, all groups that do not match this regexp will be removed before saving the list." :group 'gnus-newsrc - :type 'boolean) + :type '(radio (sexp :format "Non-nil\n" + :match (lambda (widget value) + (and value (not (stringp value)))) + :value t) + (const nil) + (regexp :format "%t: %v\n" :size 0))) (defcustom gnus-ignored-newsgroups (mapconcat 'identity @@ -289,8 +296,8 @@ claim them." (repeat function))) (defcustom gnus-subscribe-newsgroup-hooks nil - "*Hooks run after you subscribe to a new group. The hooks will be called -with new group's name as argument." + "*Hooks run after you subscribe to a new group. +The hooks will be called with new group's name as argument." :group 'gnus-group-new :type 'hook) @@ -389,7 +396,7 @@ This hook is called as the first thing when Gnus is started." :group 'gnus-start :type 'hook) -(defcustom gnus-setup-news-hook +(defcustom gnus-setup-news-hook '(gnus-fixup-nnimap-unread-after-getting-new-news) "A hook after reading the .newsrc file, but before generating the buffer." :group 'gnus-start @@ -563,7 +570,7 @@ Can be used to turn version control on or off." (gnus-subscribe-newsgroup newsgroup)) (defun gnus-subscribe-alphabetically (newgroup) - "Subscribe new NEWSGROUP and insert it in alphabetical order." + "Subscribe new NEWGROUP and insert it in alphabetical order." (let ((groups (cdr gnus-newsrc-alist)) before) (while (and (not before) groups) @@ -573,7 +580,7 @@ Can be used to turn version control on or off." (gnus-subscribe-newsgroup newgroup before))) (defun gnus-subscribe-hierarchically (newgroup) - "Subscribe new NEWSGROUP and insert it in hierarchical newsgroup order." + "Subscribe new NEWGROUP and insert it in hierarchical newsgroup order." ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams) (save-excursion (set-buffer (nnheader-find-file-noselect gnus-current-startup-file)) @@ -676,6 +683,8 @@ the first newsgroup." ;; Clear other internal variables. (setq gnus-list-of-killed-groups nil gnus-have-read-active-file nil + gnus-agent-covered-methods nil + gnus-server-method-cache nil gnus-newsrc-alist nil gnus-newsrc-hashtb nil gnus-killed-list nil @@ -972,6 +981,15 @@ If LEVEL is non-nil, the news will be set up at level LEVEL." (eq gnus-read-active-file 'some)) (gnus-update-active-hashtb-from-killed)) + ;; Validate agent covered methods now that gnus-server-alist has + ;; been initialized. + ;; NOTE: This is here for one purpose only. By validating the + ;; agentized server's, it converts the old 5.10.3, and earlier, + ;; format to the current format. That enables the agent code + ;; within gnus-read-active-file to function correctly. + (if gnus-agent + (gnus-agent-read-servers-validate)) + ;; Read the active file and create `gnus-active-hashtb'. ;; If `gnus-read-active-file' is nil, then we just create an empty ;; hash table. The partial filling out of the hash table will be @@ -1267,7 +1285,7 @@ for new groups, and subscribe the new groups as zombies." (gnus-message 7 "`A k' to list killed groups")))))) (defun gnus-subscribe-group (group &optional previous method) - "Subcribe GROUP and put it after PREVIOUS." + "Subscribe GROUP and put it after PREVIOUS." (gnus-group-change-level (if method (list t group gnus-level-default-subscribed nil nil method) @@ -1515,6 +1533,7 @@ newsgroup." (zerop (cdr active)) (gnus-active group)) (gnus-active group) + (gnus-set-active group active) ;; Return the new active info. active))))) @@ -1534,6 +1553,12 @@ newsgroup." (when (and gnus-use-cache info) (inline (gnus-cache-possibly-alter-active (gnus-info-group info) active))) + + ;; 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)) + ;; Modify the list of read articles according to what articles ;; are available; then tally the unread articles and add the ;; number to the group hash table entry. @@ -1620,7 +1645,10 @@ newsgroup." 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 +1667,25 @@ newsgroup." ;; 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))) @@ -1983,7 +2024,7 @@ newsgroup." (gnus-message 5 "%sdone" mesg))))))) (defun gnus-read-active-file-2 (groups method) - "Read an active file for GROUPS in METHOD using gnus-retrieve-groups." + "Read an active file for GROUPS in METHOD using `gnus-retrieve-groups'." (when groups (save-excursion (set-buffer nntp-server-buffer) @@ -2715,16 +2756,21 @@ If FORCE is non-nil, the .newsrc file is read." (gnus-offer-save-summaries) (gnus-save-newsrc-file))) -(defun gnus-gnus-to-quick-newsrc-format () - "Print Gnus variables such as gnus-newsrc-alist in lisp format." +(defun gnus-gnus-to-quick-newsrc-format (&optional minimal name &rest specific-variables) + "Print Gnus variables such as `gnus-newsrc-alist' in Lisp format." (princ ";; -*- emacs-lisp -*-\n") - (princ ";; Gnus startup file.\n") - (princ "\ + (if name + (princ (format ";; %s\n" name)) + (princ ";; Gnus startup file.\n")) + + (unless minimal + (princ "\ ;; Never delete this file -- if you want to force Gnus to read the ;; .newsrc file (if you have one), touch .newsrc instead.\n") - (princ "(setq gnus-newsrc-file-version ") - (princ (gnus-prin1-to-string gnus-version)) - (princ ")\n") + (princ "(setq gnus-newsrc-file-version ") + (princ (gnus-prin1-to-string gnus-version)) + (princ ")\n")) + (let* ((print-quoted t) (print-readably t) (print-escape-multibyte nil) @@ -2738,10 +2784,11 @@ If FORCE is non-nil, the .newsrc file is read." (gnus-strip-killed-list) gnus-killed-list)) (variables - (if gnus-save-killed-list gnus-variable-list - ;; Remove the `gnus-killed-list' from the list of variables - ;; to be saved, if required. - (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))) + (or specific-variables + (if gnus-save-killed-list gnus-variable-list + ;; Remove the `gnus-killed-list' from the list of variables + ;; to be saved, if required. + (delq 'gnus-killed-list (copy-sequence gnus-variable-list))))) ;; Peel off the "dummy" group. (gnus-newsrc-alist (cdr gnus-newsrc-alist)) variable) @@ -3061,7 +3108,7 @@ If FORCE is non-nil, the .newsrc file is read." ;;;###autoload (defun gnus-declare-backend (name &rest abilities) - "Declare backend NAME with ABILITIES as a Gnus backend." + "Declare back end NAME with ABILITIES as a Gnus back end." (setq gnus-valid-select-methods (nconc gnus-valid-select-methods (list (apply 'list name abilities)))) @@ -3077,7 +3124,7 @@ If this variable is nil, don't do anything." default-directory))) (eval-and-compile -(defalias 'gnus-display-time-event-handler +(defalias 'gnus-display-time-event-handler (if (gnus-boundp 'display-time-timer) 'display-time-event-handler (lambda () "Does nothing as `display-time-timer' is not bound. diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index acdac21..a8938f3 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -1,5 +1,5 @@ ;;; gnus-sum.el --- summary mode commands for Semi-gnus -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -41,7 +41,6 @@ (require 'gnus-undo) (require 'gnus-util) (require 'nnoo) -(require 'mime-view) (eval-when-compile (require 'mime-play) @@ -264,7 +263,12 @@ If threads are hidden, you have to run the command `gnus-summary-show-thread' by hand or use `gnus-select-article-hook' to expose hidden threads." :group 'gnus-thread - :type 'boolean) + :type '(radio (sexp :format "Non-nil\n" + :match (lambda (widget value) + (not (or (consp value) (functionp value)))) + :value t) + (const nil) + (sexp :tag "Predicate specifier" :size 0))) (defcustom gnus-thread-hide-killed t "*If non-nil, hide killed threads automatically." @@ -367,7 +371,7 @@ the first unread article." (defcustom gnus-auto-goto-ignores 'unfetched "*Says how to handle unfetched articles when maneuvering. -This variable can either be the symbols `nil' (maneuver to any +This variable can either be the symbols nil (maneuver to any article), `undownloaded' (maneuvering while unplugged ignores articles that have not been fetched), `always-undownloaded' (maneuvering always ignores articles that have not been fetched), `unfetched' (maneuvering @@ -977,7 +981,8 @@ default: The default article score. default-high: The default score for high scored articles. default-low: The default score for low scored articles. below: The score below which articles are automatically marked as read. -mark: The articles mark." +mark: The article's mark. +uncached: Non-nil if the article is uncached." :group 'gnus-summary-visual :type '(repeat (cons (sexp :tag "Form" nil) face))) @@ -1108,7 +1113,7 @@ type of files to save." (defcustom gnus-read-all-available-headers nil "Whether Gnus should parse all headers made available to it. -This is mostly relevant for slow backends where the user may +This is mostly relevant for slow back ends where the user may wish to widen the summary buffer to include all headers that were fetched. Say, for nnultimate groups." :group 'gnus-summary @@ -1277,6 +1282,7 @@ end position and text.") (defvar gnus-newsgroup-data-reverse nil) (defvar gnus-newsgroup-limit nil) (defvar gnus-newsgroup-limits nil) +(defvar gnus-summary-use-undownloaded-faces nil) (defvar gnus-newsgroup-unreads nil "Sorted list of unread articles in the current newsgroup.") @@ -1421,6 +1427,7 @@ This list will always be a subset of gnus-newsgroup-undownloaded.") gnus-newsgroup-data gnus-newsgroup-data-reverse gnus-newsgroup-limit gnus-newsgroup-limits gnus-newsgroup-charset gnus-newsgroup-display + gnus-summary-use-undownloaded-faces gnus-newsgroup-incorporated) "Variables that are buffer-local to the summary buffers.") @@ -2152,7 +2159,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) ["Word wrap" gnus-article-fill-cited-article t] ["Fill long lines" gnus-article-fill-long-lines t] ["Capitalize sentences" gnus-article-capitalize-sentences t] - ["CR" gnus-article-remove-cr t] + ["Remove CR" gnus-article-remove-cr t] ["Rot 13" gnus-summary-caesar-message ,@(if (featurep 'xemacs) '(t) '(:help "\"Caesar rotate\" article by 13"))] @@ -2167,9 +2174,9 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) ["Unfold headers" gnus-article-treat-unfold-headers t] ["Fold newsgroups" gnus-article-treat-fold-newsgroups t] ["Html" gnus-article-wash-html t] - ["URLs" gnus-article-unsplit-urls t] + ["Unsplit URLs" gnus-article-unsplit-urls t] ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t] - ["HZ" gnus-article-decode-HZ t] + ["Decode HZ" gnus-article-decode-HZ t] ("(Outlook) Deuglify" ["Unwrap lines" gnus-article-outlook-unwrap-lines t] ["Repair attribution" gnus-article-outlook-repair-attribution t] @@ -2178,20 +2185,20 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) 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] @@ -2625,7 +2632,7 @@ and backwards while displaying articles, type `\\[gnus-summary-next-unread-artic 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 @@ -3272,7 +3279,7 @@ buffer that was in action when the last article was fetched." gnus-unseen-mark) (t gnus-no-mark))) (gnus-tmp-downloaded - (cond (undownloaded + (cond (undownloaded gnus-undownloaded-mark) (gnus-newsgroup-agentized gnus-downloaded-mark) @@ -3648,7 +3655,7 @@ If SHOW-ALL is non-nil, already read articles are also listed." (gnus-run-hooks 'gnus-summary-prepare-hook))) (defsubst gnus-general-simplify-subject (subject) - "Simply subject by the same rules as gnus-gather-threads-by-subject." + "Simplify subject by the same rules as `gnus-gather-threads-by-subject'." (setq subject (cond ;; Truncate the subject. @@ -3975,6 +3982,13 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (setq heads nil))))) gnus-newsgroup-dependencies))) +(defsubst gnus-remove-odd-characters (string) + "Translate STRING into something that doesn't contain weird characters." + (mm-subst-char-in-string + ?\r ?\- + (mm-subst-char-in-string + ?\n ?\- string))) + ;; This function has to be called with point after the article number ;; on the beginning of the line. (defsubst gnus-nov-parse-line (number dependencies &optional force-new) @@ -4084,7 +4098,7 @@ the id of the parent article (if any)." (forward-line 1))))))) (defun gnus-summary-update-article-line (article header) - "Update the line for ARTICLE using HEADERS." + "Update the line for ARTICLE using HEADER." (let* ((id (mail-header-id header)) (thread (gnus-id-to-thread id))) (unless thread @@ -4100,7 +4114,7 @@ the id of the parent article (if any)." (let ((inserted (- (point) (progn (gnus-summary-insert-line - header level nil + header level nil (memq article gnus-newsgroup-undownloaded) (gnus-article-mark article) (memq article gnus-newsgroup-replied) @@ -4127,7 +4141,7 @@ the id of the parent article (if any)." (point))))) (when (cdr datal) (gnus-data-update-list - (cdr datal) + (cdr datal) (- (gnus-data-pos data) (gnus-data-pos (cadr datal)) inserted))))))) (defun gnus-summary-update-article (article &optional iheader) @@ -4525,10 +4539,10 @@ Unscored articles will be counted as having a score of zero." (mapcar (lambda (header) (setq previous-time - (time-to-seconds - (condition-case () - (mail-header-parse-date (mail-header-date header)) - (error previous-time))))) + (condition-case () + (time-to-seconds (mail-header-parse-date + (mail-header-date header))) + (error previous-time)))) (sort (message-flatten-list thread) (lambda (h1 h2) @@ -4566,17 +4580,17 @@ Unscored articles will be counted as having a score of zero." (defcustom gnus-sum-thread-tree-root "> " "With %B spec, used for the root of a thread. If nil, use subject instead." - :type 'string + :type '(radio (const :format "%v " nil) (string :size 0)) :group 'gnus-thread) (defcustom gnus-sum-thread-tree-false-root "> " "With %B spec, used for a false root of a thread. If nil, use subject instead." - :type 'string + :type '(radio (const :format "%v " nil) (string :size 0)) :group 'gnus-thread) (defcustom gnus-sum-thread-tree-single-indent "" "With %B spec, used for a thread with just one message. If nil, use subject instead." - :type 'string + :type '(radio (const :format "%v " nil) (string :size 0)) :group 'gnus-thread) (defcustom gnus-sum-thread-tree-vertical "| " "With %B spec, used for drawing a vertical line." @@ -4819,7 +4833,7 @@ or a straight list of headers." gnus-unseen-mark) (t gnus-no-mark)) gnus-tmp-downloaded - (cond ((memq number gnus-newsgroup-undownloaded) + (cond ((memq number gnus-newsgroup-undownloaded) gnus-undownloaded-mark) (gnus-newsgroup-agentized gnus-downloaded-mark) @@ -5025,7 +5039,12 @@ If SELECT-ARTICLES, only select those articles from GROUP." (active (gnus-active group))) (if (and (car alist) (< (caar alist) (car active))) - (gnus-set-active group (cons (caar alist) (cdr active)))))) + (gnus-set-active group (cons (caar alist) (cdr active))))) + + (setq gnus-summary-use-undownloaded-faces + (gnus-agent-find-parameter + group + 'agent-enable-undownloaded-faces))) (setq gnus-newsgroup-name group gnus-newsgroup-unselected nil @@ -5340,7 +5359,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." 'list)) (defun gnus-article-unpropagatable-p (mark) - "Return whether MARK should be propagated to backend." + "Return whether MARK should be propagated to back end." (memq mark gnus-article-unpropagated-mark-lists)) (defun gnus-adjust-marked-articles (info) @@ -5707,6 +5726,7 @@ The resulting hash table is returned, or nil if no Xrefs were found." ;; Translate all TAB characters into SPACE characters. (subst-char-in-region (point-min) (point-max) ?\t ? t) (subst-char-in-region (point-min) (point-max) ?\r ? t) + (ietf-drums-unfold-fws) (gnus-run-hooks 'gnus-parse-headers-hook) (let ((case-fold-search t) in-reply-to header p lines chars ctype) @@ -6091,7 +6111,8 @@ If EXCLUDE-GROUP, do not go to this group." (gnus-group-best-unread-group exclude-group)))) (defun gnus-summary-find-next (&optional unread article backward) - (if backward (gnus-summary-find-prev unread article) + (if backward + (gnus-summary-find-prev unread article) (let* ((dummy (gnus-summary-article-intangible-p)) (article (or article (gnus-summary-article-number))) (data (gnus-data-find-list article)) @@ -6105,15 +6126,19 @@ If EXCLUDE-GROUP, do not go to this group." (if unread (progn (while data - (unless (memq (gnus-data-number (car data)) - (cond ((eq gnus-auto-goto-ignores 'always-undownloaded) - gnus-newsgroup-undownloaded) - (gnus-plugged - nil) - ((eq gnus-auto-goto-ignores 'unfetched) - gnus-newsgroup-unfetched) - ((eq gnus-auto-goto-ignores 'undownloaded) - gnus-newsgroup-undownloaded))) + (unless (memq (gnus-data-number (car data)) + (cond + ((eq gnus-auto-goto-ignores + 'always-undownloaded) + gnus-newsgroup-undownloaded) + (gnus-plugged + nil) + ((eq gnus-auto-goto-ignores + 'unfetched) + gnus-newsgroup-unfetched) + ((eq gnus-auto-goto-ignores + 'undownloaded) + gnus-newsgroup-undownloaded))) (when (gnus-data-unread-p (car data)) (setq result (car data) data nil))) @@ -6138,14 +6163,18 @@ If EXCLUDE-GROUP, do not go to this group." (progn (while data (unless (memq (gnus-data-number (car data)) - (cond ((eq gnus-auto-goto-ignores 'always-undownloaded) - gnus-newsgroup-undownloaded) - (gnus-plugged - nil) - ((eq gnus-auto-goto-ignores 'unfetched) - gnus-newsgroup-unfetched) - ((eq gnus-auto-goto-ignores 'undownloaded) - gnus-newsgroup-undownloaded))) + (cond + ((eq gnus-auto-goto-ignores + 'always-undownloaded) + gnus-newsgroup-undownloaded) + (gnus-plugged + nil) + ((eq gnus-auto-goto-ignores + 'unfetched) + gnus-newsgroup-unfetched) + ((eq gnus-auto-goto-ignores + 'undownloaded) + gnus-newsgroup-undownloaded))) (when (gnus-data-unread-p (car data)) (setq result (car data) data nil))) @@ -6347,7 +6376,7 @@ displayed, no centering will be performed." (defun gnus-summary-toggle-truncation (&optional arg) "Toggle truncation of summary lines. -With arg, turn line truncation on if arg is positive." +With ARG, turn line truncation on if ARG is positive." (interactive "P") (setq truncate-lines (if (null arg) (not truncate-lines) @@ -6380,7 +6409,7 @@ The prefix argument ALL means to select all articles." (let ((current-subject (gnus-summary-find-for-reselect)) (group gnus-newsgroup-name)) (setq gnus-newsgroup-begin nil) - (gnus-summary-exit) + (gnus-summary-exit nil 'leave-hidden) ;; We have to adjust the point of group mode buffer because ;; point was moved to the next unread newsgroup by exiting. (gnus-summary-jump-to-group group) @@ -6446,7 +6475,7 @@ If FORCE (the prefix), also save the .newsrc file(s)." (gnus-save-newsrc-file) (gnus-dribble-save))) -(defun gnus-summary-exit (&optional temporary) +(defun gnus-summary-exit (&optional temporary leave-hidden) "Exit reading current newsgroup, and then return to group selection mode. `gnus-exit-group-hook' is called with no arguments if that value is non-nil." (interactive) @@ -6529,11 +6558,14 @@ If FORCE (the prefix), also save the .newsrc file(s)." (when (eq mode 'gnus-summary-mode) (gnus-kill-buffer buf))) (setq gnus-current-select-method gnus-select-method) - (pop-to-buffer gnus-group-buffer) + (if leave-hidden + (set-buffer gnus-group-buffer) + (pop-to-buffer gnus-group-buffer)) (if (not quit-config) (progn (goto-char group-point) - (gnus-configure-windows 'group 'force) + (unless leave-hidden + (gnus-configure-windows 'group 'force)) (unless (pos-visible-in-window-p) (forward-line (/ (static-if (featurep 'xemacs) (window-displayed-height) @@ -6615,7 +6647,10 @@ The state which existed when entering the ephemeral is reset." (progn ;; The current article may be from the ephemeral group ;; thus it is best that we reload this article - (gnus-summary-show-article) + ;; + ;; If we're exiting from a large digest, this can be + ;; extremely slow. So, it's better not to reload it. -- jh. + ;;(gnus-summary-show-article) (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode)) (gnus-configure-windows 'pick 'force) (gnus-configure-windows (cdr quit-config) 'force))) @@ -6811,7 +6846,7 @@ If prefix argument NO-ARTICLE is non-nil, no article is selected initially." "Go to the first subject satisfying any non-nil constraint. If UNREAD is non-nil, the article should be unread. If UNDOWNLOADED is non-nil, the article should be undownloaded. -If UNSEED is non-nil, the article should be unseen. +If UNSEEN is non-nil, the article should be unseen. Returns the article selected or nil if there are no matching articles." (interactive "P") (cond @@ -6836,7 +6871,7 @@ Returns the article selected or nil if there are no matching articles." (and unseen (memq num gnus-newsgroup-unseen))))))) (setq data (cdr data))) - (prog1 + (prog1 (if data (progn (goto-char (gnus-data-pos (car data))) @@ -7016,6 +7051,7 @@ be displayed." (interactive) (let ((mm-verify-option 'known) (mm-decrypt-option 'known) + (gnus-article-emulate-mime t) (gnus-buttonized-mime-types (append (list "multipart/signed" "multipart/encrypted") gnus-buttonized-mime-types))) @@ -7166,7 +7202,9 @@ If CIRCULAR is non-nil, go to the start of the article instead of selecting the next article when reaching the end of the current article. -If STOP is non-nil, just stop when reaching the end of the message." +If STOP is non-nil, just stop when reaching the end of the message. + +Also see the variable `gnus-article-skip-boring'." (interactive "P") (setq gnus-summary-buffer (current-buffer)) (gnus-set-global-variables) @@ -7409,7 +7447,7 @@ is a number, it is the line the article is to be displayed on." 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))) @@ -7678,7 +7716,7 @@ article." (gnus-summary-position-point)))) (defun gnus-summary-insert-dormant-articles () - "Insert all the dormat articles for this group into the current buffer." + "Insert all the dormant articles for this group into the current buffer." (interactive) (let ((gnus-verbose (max 6 gnus-verbose))) (if (not gnus-newsgroup-dormant) @@ -7831,7 +7869,7 @@ If ALL, mark even excluded ticked and dormants as read." thread) (defun gnus-cut-threads (threads) - "Cut off all uninteresting articles from the beginning of threads." + "Cut off all uninteresting articles from the beginning of THREADS." (when (or (eq gnus-fetch-old-headers 'some) (eq gnus-fetch-old-headers 'invisible) (numberp gnus-fetch-old-headers) @@ -8001,7 +8039,8 @@ The difference between N and the number of articles fetched is returned." (set-buffer gnus-original-article-buffer) (nnheader-narrow-to-headers) (unless (setq ref (message-fetch-field "references")) - (setq ref (message-fetch-field "in-reply-to"))) + (when (setq ref (message-fetch-field "in-reply-to")) + (setq ref (gnus-extract-message-id-from-in-reply-to ref)))) (widen)) (setq ref ;; It's not the current article, so we take a bet on @@ -8064,7 +8103,7 @@ of what's specified by the `gnus-refer-thread-limit' variable." gnus-newsgroup-name limit)) 'nov) (gnus-build-all-threads) - (error "Can't fetch thread from backends that don't support NOV")) + (error "Can't fetch thread from back ends that don't support NOV")) (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name)) (gnus-summary-limit-include-thread id))) @@ -8073,12 +8112,16 @@ of what's specified by the `gnus-refer-thread-limit' variable." (interactive "sMessage-ID: ") (when (and (stringp message-id) (not (zerop (length message-id)))) + (setq message-id (gnus-replace-in-string message-id " " "")) ;; Construct the correct Message-ID if necessary. ;; Suggested by tale@pawl.rpi.edu. (unless (string-match "^<" message-id) (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 @@ -8148,8 +8191,12 @@ If FORCE, force a digest interpretation. If not, try to guess what the document format is." (interactive "P") (let ((conf gnus-current-window-configuration)) - (save-excursion - (gnus-summary-select-article)) + (save-window-excursion + (save-excursion + (let (gnus-article-prepare-hook + gnus-display-mime-function + gnus-break-pages) + (gnus-summary-select-article)))) (setq gnus-current-window-configuration conf) (let* ((name (format "%s-%d" (gnus-group-prefixed-name @@ -8160,6 +8207,7 @@ to guess what the document format is." (ogroup gnus-newsgroup-name) (params (append (gnus-info-params (gnus-get-info ogroup)) (list (cons 'to-group ogroup)) + (list (cons 'parent-group ogroup)) (list (cons 'save-article-group ogroup)))) (case-fold-search t) (buf (current-buffer)) @@ -8358,7 +8406,7 @@ If BACKWARD, search backward instead." gnus-treat-highlight-citation gnus-treat-highlight-signature gnus-treat-overstrike - gnus-treat-display-xface + gnus-treat-display-x-face gnus-treat-buttonize-head gnus-treat-decode-article-as-default-mime-charset)) (static-if (featurep 'xemacs) @@ -8366,8 +8414,8 @@ If BACKWARD, search backward instead." (cons '(x-face-mule-delete-x-face-field (quote never)) items)))) - (gnus-treat-display-xface - (when (, x-face) gnus-treat-display-xface))) + (gnus-treat-display-x-face + (when (, x-face) gnus-treat-display-x-face))) (gnus-article-prepare-mime-display))) (goto-char (if (, backward) start end)) (when (, x-face) @@ -8575,7 +8623,7 @@ article. If BACKWARD (the prefix) is non-nil, search backward instead." (gnus-eval-in-buffer-window gnus-article-buffer (widen) (goto-char (point-min)) - (when gnus-page-broken + (when gnus-break-pages (gnus-narrow-to-page)))) (defun gnus-summary-end-of-article () @@ -8587,7 +8635,9 @@ article. If BACKWARD (the prefix) is non-nil, search backward instead." (widen) (goto-char (point-max)) (recenter -3) - (when gnus-page-broken + (when gnus-break-pages + (when (re-search-backward page-delimiter nil t) + (narrow-to-region (match-end 0) (point-max))) (gnus-narrow-to-page)))) (defun gnus-summary-print-truncate-and-quote (string &optional len) @@ -8598,10 +8648,16 @@ article. If BACKWARD (the prefix) is non-nil, search backward instead." "[()]" "\\\\\\&")) (defun gnus-summary-print-article (&optional filename n) - "Generate and print a PostScript image of the N next (mail) articles. + "Generate and print a PostScript image of the process-marked (mail) articles. -If N is negative, print the N previous articles. If N is nil and articles -have been marked with the process mark, print these instead. +If used interactively, print the current article if none are +process-marked. With prefix arg, prompt the user for the name of the +file to save in. + +When used from Lisp, accept two optional args FILENAME and N. N means +to print the next N articles. If N is negative, print the N previous +articles. If N is nil and articles have been marked with the process +mark, print these instead. If the optional first argument FILENAME is nil, send the image to the printer. If FILENAME is a string, save the PostScript image in a file with @@ -8621,14 +8677,15 @@ to save in." (progn (copy-to-buffer buffer (point-min) (point-max)) (set-buffer buffer) - (gnus-article-delete-invisible-text) (gnus-remove-text-with-property 'gnus-decoration) (when (gnus-visual-p 'article-highlight 'highlight) ;; Copy-to-buffer doesn't copy overlay. So redo ;; highlight. (let ((gnus-article-buffer buffer)) (gnus-article-highlight-citation t) - (gnus-article-highlight-signature))) + (gnus-article-highlight-signature) + (gnus-article-emphasize) + (gnus-article-delete-invisible-text))) (let ((ps-left-header (list (concat "(" @@ -8760,6 +8817,9 @@ If ARG is a negative number, hide the unwanted header lines." (1- (point)) (point-max)))) (insert-buffer-substring gnus-original-article-buffer s e) + ;; In T-gnus, gnus-article-decode-hook doesn't contain + ;; article-decode-encoded-words by default. + (article-decode-encoded-words) (run-hooks 'gnus-article-decode-hook) (if hidden (let ((gnus-treat-hide-headers nil) @@ -8770,10 +8830,12 @@ If ARG is a negative number, hide the unwanted header lines." (widen) (if window (set-window-start window (goto-char (point-min)))) - (setq gnus-page-broken - (when gnus-break-pages - (gnus-narrow-to-page) - t)) + (if gnus-break-pages + (gnus-narrow-to-page) + (when (gnus-visual-p 'page-marker) + (let ((buffer-read-only nil)) + (gnus-remove-text-with-property 'gnus-prev) + (gnus-remove-text-with-property 'gnus-next)))) (gnus-set-mode-line 'article))))) (defun gnus-summary-show-all-headers () @@ -8885,9 +8947,6 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (crosspost "Crosspost" "Crossposting"))) (copy-buf (save-excursion (nnheader-set-temp-buffer " *copy article*"))) - (default-marks gnus-article-mark-lists) - (no-expire-marks (delete '(expirable . expire) - (copy-sequence gnus-article-mark-lists))) art-group to-method new-xref article to-groups) (unless (assq action names) (error "Unknown action %s" action)) @@ -9018,8 +9077,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." ;; See whether the article is to be put in the cache. (let ((marks (if (gnus-group-auto-expirable-p to-group) - default-marks - no-expire-marks)) + gnus-article-mark-lists + (delete '(expirable . expire) + (copy-sequence gnus-article-mark-lists)))) (to-article (cdr art-group))) ;; Enter the article into the cache in the new group, @@ -9082,9 +9142,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." article gnus-newsgroup-name (current-buffer)))) ;; run the move/copy/crosspost/respool hook - (run-hook-with-args 'gnus-summary-article-move-hook + (run-hook-with-args 'gnus-summary-article-move-hook action - (gnus-data-header + (gnus-data-header (assoc article (gnus-data-list nil))) gnus-newsgroup-name to-newsgroup @@ -9371,7 +9431,7 @@ confirmation before the articles are deleted." (unless (memq (car articles) not-deleted) (gnus-summary-mark-article (car articles) gnus-canceled-mark)) (let* ((article (car articles)) - (id (mail-header-id (gnus-data-header + (id (mail-header-id (gnus-data-header (assoc article (gnus-data-list nil)))))) (run-hook-with-args 'gnus-summary-article-delete-hook 'delete id gnus-newsgroup-name nil @@ -9517,15 +9577,13 @@ groups." (gnus-summary-select-article) (save-excursion (set-buffer gnus-original-article-buffer) - (save-restriction - (message-narrow-to-head) - (let ((groups (nnmail-article-group 'identity trace))) - (unless silent - (if groups - (message "This message would go to %s" - (mapconcat 'car groups ", ")) - (message "This message would go to no groups")) - groups)))))) + (let ((groups (nnmail-article-group 'identity trace))) + (unless silent + (if groups + (message "This message would go to %s" + (mapconcat 'car groups ", ")) + (message "This message would go to no groups")) + groups))))) (defun gnus-summary-respool-trace () "Trace where the respool algorithm would put this article. @@ -9941,7 +9999,7 @@ If NO-EXPIRE, auto-expiry will be inhibited." (defun gnus-summary-update-download-mark (article) "Update the download mark." (gnus-summary-update-mark - (cond ((memq article gnus-newsgroup-undownloaded) + (cond ((memq article gnus-newsgroup-undownloaded) gnus-undownloaded-mark) (gnus-newsgroup-agentized gnus-downloaded-mark) @@ -10100,6 +10158,14 @@ The difference between N and the number of marks cleared is returned." (gnus-summary-mark-article gnus-current-article (or new-mark gnus-read-mark))))) +(defun gnus-summary-mark-current-read-and-unread-as-read (&optional new-mark) + "Intended to be used by `gnus-summary-mark-article-hook'." + (let ((mark (gnus-summary-article-mark))) + (when (or (gnus-unread-mark-p mark) + (gnus-read-mark-p mark)) + (gnus-summary-mark-article (gnus-summary-article-number) + (or new-mark gnus-read-mark))))) + (defun gnus-summary-mark-unread-as-ticked () "Intended to be used by `gnus-summary-mark-article-hook'." (when (memq gnus-current-article gnus-newsgroup-unreads) @@ -10202,10 +10268,14 @@ even ticked and dormant ones." If prefix argument ALL is non-nil, ticked and dormant articles will also be marked as read. If QUIETLY is non-nil, no questions will be asked. + If TO-HERE is non-nil, it should be a point in the buffer. All -articles before (after, if REVERSE is set) this point will be marked as read. +articles before (after, if REVERSE is set) this point will be marked +as read. + Note that this function will only catch up the unread article in the current summary buffer limitation. + The number of articles marked as read is returned." (interactive "P") (prog1 @@ -10239,7 +10309,8 @@ The number of articles marked as read is returned." (if (and to-here reverse) (progn (goto-char to-here) - (gnus-summary-mark-read-and-unread-as-read gnus-catchup-mark) + (gnus-summary-mark-current-read-and-unread-as-read + gnus-catchup-mark) (while (gnus-summary-find-next (not all)) (gnus-summary-mark-article-as-read gnus-catchup-mark))) (when (gnus-summary-first-subject (not all)) @@ -11011,13 +11082,17 @@ If REVERSE, save parts that do not match TYPE." (not (string-match type (mm-handle-media-type handle))) (string-match type (mm-handle-media-type handle))) (let ((file (expand-file-name - (file-name-nondirectory - (or - (mail-content-type-get - (mm-handle-disposition handle) 'filename) - (concat gnus-newsgroup-name - "." (number-to-string - (cdr gnus-article-current))))) + (gnus-map-function + mm-file-name-rewrite-functions + (file-name-nondirectory + (or + (mail-content-type-get + (mm-handle-disposition handle) 'filename) + (mail-content-type-get + (mm-handle-type handle) 'name) + (concat gnus-newsgroup-name + "." (number-to-string + (cdr gnus-article-current)))))) dir))) (unless (file-exists-p file) (mm-save-part-to-file handle file)))))) @@ -11249,7 +11324,7 @@ If REVERSE, save parts that do not match TYPE." (defvar gnus-summary-highlight-line-trigger nil) (defun gnus-summary-highlight-line-0 () - (if (and (eq gnus-summary-highlight-line-trigger + (if (and (eq gnus-summary-highlight-line-trigger gnus-summary-highlight) gnus-summary-highlight-line-cached) gnus-summary-highlight-line-cached @@ -11277,8 +11352,8 @@ If REVERSE, save parts that do not match TYPE." (default gnus-summary-default-score) (default-high gnus-summary-default-high-score) (default-low gnus-summary-default-low-score) - (uncached (memq article gnus-newsgroup-undownloaded)) - (downloaded (not uncached))) + (uncached (and gnus-summary-use-undownloaded-faces + (memq article gnus-newsgroup-undownloaded)))) (let ((face (funcall (gnus-summary-highlight-line-0)))) (unless (eq face (get-text-property beg 'face)) (gnus-put-text-property-excluding-characters-with-faces diff --git a/lisp/gnus-topic.el b/lisp/gnus-topic.el index 07d501c..2352e2b 100644 --- a/lisp/gnus-topic.el +++ b/lisp/gnus-topic.el @@ -436,6 +436,8 @@ If LOWEST is non-nil, list all newsgroups of level LOWEST or higher." (and gnus-group-listed-groups (copy-sequence gnus-group-listed-groups)))) + (gnus-update-format-specifications nil 'topic) + (when (or (not gnus-topic-alist) (not gnus-topology-checked-p)) (gnus-topic-check-topology)) @@ -753,7 +755,7 @@ articles in the topic and its subtopics." (not (gnus-topic-goto-topic (caaar tp)))) (pop tp)) (if tp - (forward-line 1) + (gnus-topic-forward-topic 1) (gnus-topic-goto-missing-topic (caadr top))))) nil)) @@ -928,8 +930,8 @@ articles in the topic and its subtopics." ? )) (yanked (list group)) alist talist end) - ;; Then we enter the yanked groups into the topics they belong - ;; to. + ;; Then we enter the yanked groups into the topics + ;; they belong to. (when (setq alist (assoc (save-excursion (forward-line -1) (or diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index 0033120..09cf62b 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -30,6 +30,9 @@ ;; used by Gnus and may be used by any other package without loading ;; Gnus first. +;; [Unfortunately, it does depend on other parts of Gnus, e.g. the +;; autoloads below...] + ;;; Code: (eval-when-compile @@ -161,7 +164,7 @@ ;; It's harmless, though, so the main purpose of this alias is to shut ;; up the byte compiler. (defalias 'gnus-make-local-hook - (if (eq (get 'make-local-hook 'byte-compile) + (if (eq (get 'make-local-hook 'byte-compile) 'byte-compile-obsolete) 'ignore ; Emacs 'make-local-hook)) ; XEmacs @@ -193,6 +196,11 @@ (cons 'progn (cddr fval))))) (defun gnus-extract-address-components (from) + "Extract address components from a From header. +Given an RFC-822 address FROM, extract full name and canonical address. +Returns a list of the form (FULL-NAME CANONICAL-ADDRESS). Much more simple +solution than `mail-extract-address-components', which works much better, but +is slower." (let (name address) ;; First find the address - the thing with the @ in it. This may ;; not be accurate in mail addresses, but does the trick most of @@ -358,19 +366,20 @@ ;; age-depending date representations. (e.g. just the time if it's ;; from today, the day of the week if it's within the last 7 days and ;; the full date if it's older) + (defun gnus-seconds-today () - "Returns the number of seconds passed today" + "Return the number of seconds passed today." (let ((now (decode-time (current-time)))) (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600)))) (defun gnus-seconds-month () - "Returns the number of seconds passed this month" + "Return the number of seconds passed this month." (let ((now (decode-time (current-time)))) (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600) (* (- (car (nthcdr 3 now)) 1) 3600 24)))) (defun gnus-seconds-year () - "Returns the number of seconds passed this year" + "Return the number of seconds passed this year." (let ((now (decode-time (current-time))) (days (format-time-string "%j" (current-time)))) (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600) @@ -401,30 +410,25 @@ seconds passed since the start of today, of this month, of this year, respectively.") (defun gnus-user-date (messy-date) - "Format the messy-date acording to gnus-user-date-format-alist. + "Format the messy-date according to gnus-user-date-format-alist. Returns \" ? \" if there's bad input or if an other error occurs. Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"." (condition-case () - (let* ((messy-date (safe-date-to-time messy-date)) - (now (current-time)) + (let* ((messy-date (time-to-seconds (safe-date-to-time messy-date))) + (now (time-to-seconds (current-time))) ;;If we don't find something suitable we'll use this one - (my-format "%b %m '%y") - (high (lsh (- (car now) (car messy-date)) 16))) - (if (and (> high -1) (= (logand high 65535) 0)) - ;;overflow and bad input - (let* ((difference (+ high (- (car (cdr now)) - (car (cdr messy-date))))) - (templist gnus-user-date-format-alist) - (top (eval (caar templist)))) - (while (if (numberp top) (< top difference) (not top)) - (progn - (setq templist (cdr templist)) - (setq top (eval (caar templist))))) - (if (stringp (cdr (car templist))) - (setq my-format (cdr (car templist)))))) - (format-time-string (eval my-format) messy-date)) + (my-format "%b %d '%y")) + (let* ((difference (- now messy-date)) + (templist gnus-user-date-format-alist) + (top (eval (caar templist)))) + (while (if (numberp top) (< top difference) (not top)) + (progn + (setq templist (cdr templist)) + (setq top (eval (caar templist))))) + (if (stringp (cdr (car templist))) + (setq my-format (cdr (car templist))))) + (format-time-string (eval my-format) (seconds-to-time messy-date))) (error " ? "))) -;;end of Frank's code (defun gnus-dd-mmm (messy-date) "Return a string like DD-MMM from a big messy string." @@ -611,7 +615,7 @@ If N, return the Nth ancestor instead." gname))) (defun gnus-make-sort-function (funs) - "Return a composite sort condition based on the functions in FUNC." + "Return a composite sort condition based on the functions in FUNS." (cond ;; Just a simple function. ((functionp funs) funs) @@ -628,7 +632,7 @@ If N, return the Nth ancestor instead." (car funs)))) (defun gnus-make-sort-function-1 (funs) - "Return a composite sort condition based on the functions in FUNC." + "Return a composite sort condition based on the functions in FUNS." (let ((function (car funs)) (first 't1) (last 't2)) @@ -846,10 +850,31 @@ with potentially long computations." ;;; Functions for saving to babyl/mail files. -(defvar rmail-default-rmail-file) +(eval-when-compile + (condition-case nil + (progn + (require 'rmail) + (autoload 'rmail-update-summary "rmailsum")) + (error + (define-compiler-macro rmail-select-summary (&rest body) + ;; Rmail of the XEmacs version is supplied by the package, and + ;; requires tm and apel packages. However, there may be those + ;; who haven't installed those packages. This macro helps such + ;; people even if they install those packages later. + `(eval '(rmail-select-summary ,@body))) + ;; If there's rmail but there's no tm (or there's apel of the + ;; mainstream, not the XEmacs version), loading rmail of the XEmacs + ;; version fails halfway, however it provides the rmail-select-summary + ;; macro which uses the following functions: + (autoload 'rmail-summary-displayed "rmail") + (autoload 'rmail-maybe-display-summary "rmail"))) + (defvar rmail-default-rmail-file) + (defvar mm-text-coding-system)) + (defun gnus-output-to-rmail (filename &optional ask) "Append the current article to an Rmail file named FILENAME." (require 'rmail) + (require 'mm-util) ;; Most of these codes are borrowed from rmailout.el. (setq filename (expand-file-name filename)) (setq rmail-default-rmail-file filename) @@ -975,7 +1000,7 @@ with potentially long computations." (insert "\^_"))) (defun gnus-map-function (funs arg) - "Applies the result of the first function in FUNS to the second, and so on. + "Apply the result of the first function in FUNS to the second, and so on. ARG is passed to the first function." (while funs (setq arg (funcall (pop funs) arg))) @@ -1032,7 +1057,7 @@ Return the modified alist." `(setq ,alist (delq (,fun ,key ,alist) ,alist)))) (defun gnus-globalify-regexp (re) - "Returns a regexp that matches a whole line, iff RE matches a part of it." + "Return a regexp that matches a whole line, iff RE matches a part of it." (concat (unless (string-match "^\\^" re) "^.*") re (unless (string-match "\\$$" re) ".*$"))) @@ -1232,7 +1257,6 @@ If you find some problem with the directory separator character, try If optional second argument ALLOW-NEWLINES is non-nil, then allow the decoding of carriage returns and line feeds in the string, which is normally forbidden in URL encoding." - (setq str (or (mm-subst-char-in-string ?+ ? str) "")) ; why `or'? (let ((tmp "") (case-fold-search t)) (while (string-match "%[0-9a-f][0-9a-f]" str) @@ -1277,8 +1301,8 @@ SPEC is a predicate specifier that contains stuff like `or', `and', (t (list 'local-map map)))) -(defmacro gnus-completing-read-maybe-default (prompt table &optional predicate - require-match initial-contents +(defmacro gnus-completing-read-maybe-default (prompt table &optional predicate + require-match initial-contents history default) "Like `completing-read', allowing for non-existent 7th arg in older XEmacsen." `(completing-read ,prompt ,table ,predicate ,require-match @@ -1347,8 +1371,9 @@ CHOICE is a list of the choice char and help message at IDX." (while (not tchar) (message "%s (%s): " prompt - (mapconcat (lambda (s) (char-to-string (car s))) - choice ", ")) + (concat + (mapconcat (lambda (s) (char-to-string (car s))) + choice ", ") ", ?")) (setq tchar (read-char)) (when (not (assq tchar choice)) (setq tchar nil) @@ -1485,6 +1510,47 @@ predicate on the elements." (push (pop list1) res))) (nconc (nreverse res) list1 list2)))) +(eval-when-compile + (defvar xemacs-codename)) + +(defun gnus-emacs-version () + "Stringified Emacs version." + (let ((system-v + (cond + ((eq gnus-user-agent 'emacs-gnus-config) + system-configuration) + ((eq gnus-user-agent 'emacs-gnus-type) + (symbol-name system-type)) + (t nil)))) + (cond + ((eq gnus-user-agent 'gnus) + nil) + ((string-match "^\\(\\([.0-9]+\\)*\\)\\.[0-9]+$" emacs-version) + (concat (format (if (boundp 'MULE) + "Mule/2.3 (based on Emacs %s)" + "Emacs/%s") + (match-string 1 emacs-version)) + (if system-v + (concat " (" system-v ")") + ""))) + ((string-match + "\\([A-Z]*[Mm][Aa][Cc][Ss]\\)[^(]*\\(\\((beta.*)\\|'\\)\\)?" + emacs-version) + (concat + (match-string 1 emacs-version) + (format "/%d.%d" emacs-major-version emacs-minor-version) + (if (match-beginning 3) + (match-string 3 emacs-version) + "") + (if (boundp 'xemacs-codename) + (concat + " (" xemacs-codename + (if system-v + (concat ", " system-v ")") + ")")) + ""))) + (t emacs-version)))) + (provide 'gnus-util) ;;; gnus-util.el ends here diff --git a/lisp/gnus-uu.el b/lisp/gnus-uu.el index 5cb9f64..c6703be 100644 --- a/lisp/gnus-uu.el +++ b/lisp/gnus-uu.el @@ -1329,23 +1329,23 @@ When called interactively, prompt for REGEXP." (setq process-state (list 'error)) (gnus-message 2 "No begin part at the beginning") (sleep-for 2)) - (setq state 'middle))) - + (setq state 'middle)))) + ;; When there are no result-files, then something must be wrong. - (if result-files - (message "") - (cond - ((not has-been-begin) - (gnus-message 2 "Wrong type file")) - ((memq 'error process-state) - (gnus-message 2 "An error occurred during decoding")) - ((not (or (memq 'ok process-state) - (memq 'end process-state))) - (gnus-message 2 "End of articles reached before end of file"))) - ;; Make unsuccessfully decoded articles unread. - (when gnus-uu-unmark-articles-not-decoded - (while article-series - (gnus-summary-tick-article (pop article-series) t))))) + (if result-files + (message "") + (cond + ((not has-been-begin) + (gnus-message 2 "Wrong type file")) + ((memq 'error process-state) + (gnus-message 2 "An error occurred during decoding")) + ((not (or (memq 'ok process-state) + (memq 'end process-state))) + (gnus-message 2 "End of articles reached before end of file"))) + ;; Make unsuccessfully decoded articles unread. + (when gnus-uu-unmark-articles-not-decoded + (while article-series + (gnus-summary-tick-article (pop article-series) t)))) ;; The original article buffer is hosed, shoot it down. (gnus-kill-buffer gnus-original-article-buffer) @@ -1610,7 +1610,7 @@ Gnus might fail to display all of it.") (gnus-message 5 "Unpacking: %s..." (gnus-uu-command action file-path)) - (if (= 0 (call-process shell-file-name nil + (if (eq 0 (call-process shell-file-name nil (gnus-get-buffer-create gnus-uu-output-buffer-name) nil shell-command-switch command)) (message "") @@ -1904,8 +1904,8 @@ The user will be asked for a file name." ;; Encodes with base64 and adds MIME headers (defun gnus-uu-post-encode-mime (path file-name) - (when (zerop (call-process shell-file-name nil t nil shell-command-switch - (format "%s %s -o %s" "mmencode" path file-name))) + (when (eq 0 (call-process shell-file-name nil t nil shell-command-switch + (format "%s %s -o %s" "mmencode" path file-name))) (gnus-uu-post-make-mime file-name "base64") t)) @@ -1930,8 +1930,8 @@ The user will be asked for a file name." ;; Encodes a file PATH with COMMAND, leaving the result in the ;; current buffer. (defun gnus-uu-post-encode-file (command path file-name) - (= 0 (call-process shell-file-name nil t nil shell-command-switch - (format "%s %s %s" command path file-name)))) + (eq 0 (call-process shell-file-name nil t nil shell-command-switch + (format "%s %s %s" command path file-name)))) (defun gnus-uu-post-news-inews () "Posts the composed news article and encoded file. diff --git a/lisp/gnus-vers.el b/lisp/gnus-vers.el index cdd5bef..0f64bfe 100644 --- a/lisp/gnus-vers.el +++ b/lisp/gnus-vers.el @@ -40,15 +40,15 @@ ;; Product information of this gnus. (product-provide 'gnus-vers (product-define "T-gnus" nil - (list 6 15 24 + (list 6 16 6 (string-to-number gnus-revision-number)))) -(defconst gnus-original-version-number "0.24" +(defconst gnus-original-version-number "5.10.6" "Version number for this version of Gnus.") (provide 'running-pterodactyl-gnus-0_73-or-later) -(defconst gnus-original-product-name "Oort Gnus" +(defconst gnus-original-product-name "Gnus" "Product name of the original version of Gnus.") (defconst gnus-product-name (product-name (product-find 'gnus-vers)) diff --git a/lisp/gnus-xmas.el b/lisp/gnus-xmas.el index 7fa13d7..6fff59e 100644 --- a/lisp/gnus-xmas.el +++ b/lisp/gnus-xmas.el @@ -28,6 +28,14 @@ ;;; Code: +(eval-when-compile + (autoload 'gnus-active "gnus" nil nil 'macro) + (autoload 'gnus-group-entry "gnus" nil nil 'macro) + (autoload 'gnus-info-level "gnus" nil nil 'macro) + (autoload 'gnus-info-marks "gnus" nil nil 'macro) + (autoload 'gnus-info-method "gnus" nil nil 'macro) + (autoload 'gnus-info-score "gnus" nil nil 'macro)) + (require 'text-props) (defvar menu-bar-mode (featurep 'menubar)) (require 'messagexmas) @@ -391,6 +399,7 @@ call it with the value of the `gnus-data' text property." (defalias 'gnus-put-text-property 'gnus-xmas-put-text-property) (defalias 'gnus-deactivate-mark 'ignore) (defalias 'gnus-window-edges 'window-pixel-edges) + (defalias 'gnus-assq-delete-all 'gnus-xmas-assq-delete-all) (if (and (<= emacs-major-version 19) (< emacs-minor-version 14)) @@ -888,7 +897,7 @@ XEmacs compatibility workaround." (with-temp-buffer (if data-p (insert file) - (insert-file-contents file)) + (insert-file-contents-literally file)) (shell-command-on-region (point-min) (point-max) "ppmtoxpm 2>/dev/null" t) (setq file (buffer-string) @@ -900,7 +909,7 @@ XEmacs compatibility workaround." (with-temp-buffer (if data-p (insert file) - (insert-file-contents file)) + (insert-file-contents-literally file)) (make-glyph (vector (or (intern type) @@ -910,7 +919,7 @@ XEmacs compatibility workaround." (set-glyph-face glyph face)) glyph)) -(defun gnus-xmas-put-image (glyph &optional string) +(defun gnus-xmas-put-image (glyph &optional string category) "Insert STRING, but display GLYPH. Warning: Don't insert text immediately after the image." (let ((begin (point)) @@ -921,21 +930,21 @@ Warning: Don't insert text immediately after the image." (insert string) (setq begin (1- begin))) (setq extent (make-extent begin (point))) - (set-extent-property extent 'gnus-image t) + (set-extent-property extent 'gnus-image category) (set-extent-property extent 'duplicable t) (if string (set-extent-property extent 'invisible t)) (set-extent-property extent 'end-glyph glyph)) glyph) -(defun gnus-xmas-remove-image (image) +(defun gnus-xmas-remove-image (image &optional category) (map-extents (lambda (ext unused) (when (equal (extent-end-glyph ext) image) (set-extent-property ext 'invisible nil) (set-extent-property ext 'end-glyph nil)) nil) - nil nil nil nil nil 'gnus-image)) + nil nil nil nil nil 'gnus-image category)) (defun gnus-xmas-completing-read (prompt table &optional predicate require-match history) @@ -962,6 +971,12 @@ Warning: Don't insert text immediately after the image." `(open-network-stream ,name ,buffer ,host ,service ,protocol) `(open-network-stream ,name ,buffer ,host ,service))) +(defun gnus-xmas-assq-delete-all (key alist) + (let ((elem nil)) + (while (setq elem (assq key alist)) + (setq alist (delq elem alist))) + alist)) + (provide 'gnus-xmas) ;;; gnus-xmas.el ends here diff --git a/lisp/gnus.el b/lisp/gnus.el index 336c361..85f57a8 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -1,7 +1,7 @@ ;;; gnus.el --- a newsreader for GNU Emacs ;; Copyright (C) 1987, 1988, 1989, 1990, 1993, 1994, 1995, 1996, 1997, -;; 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +;; 1998, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Masanobu UMEDA ;; Lars Magne Ingebrigtsen @@ -318,6 +318,7 @@ be set in `.emacs' instead." (defalias 'gnus-appt-select-lowest-window 'appt-select-lowest-window) (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names) (defalias 'gnus-character-to-event 'identity) + (defalias 'gnus-assq-delete-all 'assq-delete-all) (defalias 'gnus-add-text-properties 'add-text-properties) (defalias 'gnus-put-text-property 'put-text-property) (defvar gnus-mode-line-image-cache t) @@ -337,7 +338,9 @@ be set in `.emacs' instead." (: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))) @@ -852,6 +855,7 @@ be set in `.emacs' instead." (storm "#666699" "#99ccff") (pdino "#9999cc" "#99ccff") (purp "#9999cc" "#666699") + (no "#000000" "#ff0000") (neutral "#b4b4b4" "#878787") (september "#bf9900" "#ffcc00")) "Color alist used for the Gnus logo.") @@ -1128,21 +1132,17 @@ used to 899, you would say something along these lines: :group 'gnus-server :type 'file) -;; This function is used to check both the environment variable -;; NNTPSERVER and the /etc/nntpserver file to see whether one can find -;; an nntp server name default. (defun gnus-getenv-nntpserver () + "Find default nntp server. +Check the NNTPSERVER environment variable and the +`gnus-nntpserver-file' file." (or (getenv "NNTPSERVER") (and (file-readable-p gnus-nntpserver-file) - (save-excursion - (set-buffer (gnus-get-buffer-create " *gnus nntp*")) + (with-temp-buffer (insert-file-contents gnus-nntpserver-file) (let ((name (buffer-string))) - (prog1 - (if (string-match "\\'[ \t\n]*$" name) - nil - name) - (kill-buffer (current-buffer)))))))) + (unless (string-match "\\`[ \t\n]*$" name) + name)))))) (defcustom gnus-select-method (condition-case nil @@ -1184,7 +1184,8 @@ see the manual for details." This should be a mail method." :group 'gnus-server :group 'gnus-message - :type 'gnus-select-method) + :type '(choice (const :tag "Default archive method" "archive") + gnus-select-method)) (defcustom gnus-message-archive-group nil "*Name of the group in which to save the messages you've written. @@ -1273,6 +1274,7 @@ It can also be a list of select methods, as well as the special symbol list, Gnus will try all the methods in the list until it finds a match." :group 'gnus-server :type '(choice (const :tag "default" nil) + (const current) (const :tag "Google" (nnweb "refer" (nnweb-type google))) gnus-select-method (repeat :menu-tag "Try multiple" @@ -1293,7 +1295,7 @@ list, Gnus will try all the methods in the list until it finds a match." "/ftp@rtfm.mit.edu:/pub/usenet/" "/ftp@ftp.uni-paderborn.de:/pub/FAQ/" "/ftp@ftp.sunet.se:/pub/usenet/" - "/ftp@nctuccca.edu.tw:/USENET/FAQ/" + "/ftp@nctuccca.nctu.edu.tw:/pub/Documents/rtfm/usenet-by-group/" "/ftp@hwarang.postech.ac.kr:/pub/usenet/" "/ftp@ftp.hk.super.net:/mirror/faqs/") "*Directory where the group FAQs are stored. @@ -1317,7 +1319,7 @@ If the default site is too slow, try one of these: src.doc.ic.ac.uk /usenet/news-FAQS ftp.sunet.se /pub/usenet ftp.pasteur.fr /pub/FAQ - Asia: nctuccca.edu.tw /USENET/FAQ + Asia: nctuccca.nctu.edu.tw /pub/Documents/rtfm/usenet-by-group/ hwarang.postech.ac.kr /pub/usenet ftp.hk.super.net /mirror/faqs" :group 'gnus-group-various @@ -1330,22 +1332,21 @@ If the default site is too slow, try one of these: ("dk" . (concat "http://www.usenet.dk/grupper.pl?get=" name)) ("england" . (concat "http://england.news-admin.org/charters/" name)) ("fr" . (concat "http://www.usenet-fr.net/fur/chartes/" name ".html")) - ("europa" . (concat "http://www.europa.usenet.eu.org/chartas/charta-en-" + ("europa" . (concat "http://www.europa.usenet.eu.org/chartas/charta-en-" (gnus-replace-in-string name "europa\\." "") ".html")) ("nl" . (concat "http://www.xs4all.nl/~sister/usenet/charters/" name)) - ("aus" . (concat "http://aus.news-admin.org/groupinfo.php/" name)) + ("aus" . (concat "http://aus.news-admin.org/groupinfo.cgi/" name)) ("pl" . (concat "http://www.usenet.pl/opisy/" name)) ("ch" . (concat "http://www.use-net.ch/Usenet/charter.html#" name)) ("at" . (concat "http://www.usenet.at/chartas/" name "/charta")) ("uk" . (concat "http://www.usenet.org.uk/" name ".html")) - ("wales" . (concat "http://www.wales-usenet.org/english/groups/" name ".html")) ("dfw" . (concat "http://www.cirr.com/dfw/charters/" name ".html")) - ("se" . (concat "http://www.usenet-se.net/Reglementen/" + ("se" . (concat "http://www.usenet-se.net/Reglementen/" (gnus-replace-in-string name "\\." "_") ".html")) - ("milw" . (concat "http://usenet.mil.wi.us/" + ("milw" . (concat "http://usenet.mil.wi.us/" (gnus-replace-in-string name "milw\\." "") "-charter")) ("ca" . (concat "http://www.sbay.org/ca/charter-" name ".html")) - ("netins" . (concat "http://www.netins.net/usenet/charter/" + ("netins" . (concat "http://www.netins.net/usenet/charter/" (gnus-replace-in-string name "\\." "-") "-charter.html"))) "*An alist of (HIERARCHY . FORM) pairs used to construct the URL of a charter. When FORM is evaluated `name' is bound to the name of the group." @@ -1399,7 +1400,14 @@ Note that the default for this variable varies according to what system type you're using. On `usg-unix-v' and `xenix' this variable defaults to nil while on all other systems it defaults to t." :group 'gnus-start - :type 'boolean) + :type '(radio (sexp :format "Non-nil\n" + :match (lambda (widget value) + (and value (not (listp value)))) + :value t) + (const nil) + (checklist (const :format "%v " not-score) + (const :format "%v " not-save) + (const not-kill)))) (defcustom gnus-kill-files-directory gnus-directory "*Name of the directory where kill files will be stored (default \"~/News\")." @@ -1482,7 +1490,7 @@ It calls `gnus-summary-expire-articles' by default." :type 'hook) (defcustom gnus-novice-user t - "*Non-nil means that you are a usenet novice. + "*Non-nil means that you are a Usenet novice. If non-nil, verbose messages may be displayed and confirmations may be required." :group 'gnus-meta @@ -1613,7 +1621,7 @@ If this variable is nil, screen refresh may be quicker." (defcustom gnus-mode-non-string-length nil "*Max length of mode-line non-string contents. If this is nil, Gnus will take space as is needed, leaving the rest -of the modeline intact. Note that the default of nil is unlikely +of the mode line intact. Note that the default of nil is unlikely to be desirable; see the manual for further details." :group 'gnus-various :type '(choice (const nil) @@ -1789,9 +1797,29 @@ articles to list when the group is a large newsgroup (see `gnus-large-newsgroup'). If it is nil, the default value is the total number of articles in the group.") +;; The Gnus registry's ignored groups +(gnus-define-group-parameter + registry-ignore + :type list + :function-document + "Whether this group should be ignored by the registry." + :variable gnus-registry-ignored-groups + :variable-default nil + :variable-document + "*Groups in which the registry should be turned off." + :variable-group gnus-registry + :variable-type '(repeat + (list + (regexp :tag "Group Name Regular Expression") + (boolean :tag "Ignored"))) + + :parameter-type '(boolean :tag "Group Ignored by the Registry") + :parameter-document + "Whether the Gnus Registry should ignore this group.") + ;; group parameters for spam processing added by Ted Zlatanov (defcustom gnus-install-group-spam-parameters t - "*Disable the group parameters for spam detection. + "*Disable the group parameters for spam detection. Enable if `G c' in XEmacs is giving you trouble, and make sure to submit a bug report." :type 'boolean :group 'gnus-start) @@ -1826,7 +1854,7 @@ regexps that should match all groups in which to do automatic spam tagging, associated with a classification (spam, ham, or neither). This only makes sense for mail groups." :variable-group spam - :variable-type '(repeat + :variable-type '(repeat (list :tag "Group contents spam/ham classification" (regexp :tag "Group") (choice @@ -1844,97 +1872,224 @@ This only makes sense for mail groups." When a spam group is entered, all unread articles are marked as spam.") (defvar gnus-group-spam-exit-processor-ifile "ifile" - "The ifile summary exit spam processor.") + "OBSOLETE: The ifile summary exit spam processor.") (defvar gnus-group-spam-exit-processor-stat "stat" - "The spam-stat summary exit spam processor.") + "OBSOLETE: The spam-stat summary exit spam processor.") (defvar gnus-group-spam-exit-processor-bogofilter "bogofilter" - "The Bogofilter summary exit spam processor.") + "OBSOLETE: The Bogofilter summary exit spam processor.") (defvar gnus-group-spam-exit-processor-blacklist "blacklist" - "The Blacklist summary exit spam processor.") + "OBSOLETE: The Blacklist summary exit spam processor.") (defvar gnus-group-spam-exit-processor-report-gmane "report-gmane" - "The Gmane reporting summary exit spam processor. + "OBSOLETE: The Gmane reporting summary exit spam processor. Only applicable to NNTP groups with articles from Gmane. See spam-report.el") + (defvar gnus-group-spam-exit-processor-spamoracle "spamoracle-spam" + "OBSOLETE: The spamoracle summary exit spam processor.") + (defvar gnus-group-ham-exit-processor-ifile "ifile-ham" - "The ifile summary exit ham processor. + "OBSOLETE: The ifile summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") (defvar gnus-group-ham-exit-processor-bogofilter "bogofilter-ham" - "The Bogofilter summary exit ham processor. + "OBSOLETE: The Bogofilter summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") (defvar gnus-group-ham-exit-processor-stat "stat-ham" - "The spam-stat summary exit ham processor. + "OBSOLETE: The spam-stat summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") (defvar gnus-group-ham-exit-processor-whitelist "whitelist" - "The whitelist summary exit ham processor. + "OBSOLETE: The whitelist summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") (defvar gnus-group-ham-exit-processor-BBDB "bbdb" - "The BBDB summary exit ham processor. + "OBSOLETE: The BBDB summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") (defvar gnus-group-ham-exit-processor-copy "copy" - "The ham copy exit ham processor. + "OBSOLETE: The ham copy exit ham processor. +Only applicable to non-spam (unclassified and ham) groups.") + + (defvar gnus-group-ham-exit-processor-spamoracle "spamoracle-ham" + "OBSOLETE: The spamoracle summary exit ham processor. Only applicable to non-spam (unclassified and ham) groups.") (gnus-define-group-parameter spam-process :type list - :parameter-type '(choice :tag "Spam Summary Exit Processor" - :value nil - (list :tag "Spam Summary Exit Processor Choices" - (set - (variable-item gnus-group-spam-exit-processor-ifile) - (variable-item gnus-group-spam-exit-processor-stat) - (variable-item gnus-group-spam-exit-processor-bogofilter) - (variable-item gnus-group-spam-exit-processor-blacklist) - (variable-item gnus-group-spam-exit-processor-report-gmane) - (variable-item gnus-group-ham-exit-processor-bogofilter) - (variable-item gnus-group-ham-exit-processor-ifile) - (variable-item gnus-group-ham-exit-processor-stat) - (variable-item gnus-group-ham-exit-processor-whitelist) - (variable-item gnus-group-ham-exit-processor-BBDB) - (variable-item gnus-group-ham-exit-processor-copy)))) + :parameter-type + '(choice + :tag "Spam Summary Exit Processor" + :value nil + (list :tag "Spam Summary Exit Processor Choices" + (set + (variable-item gnus-group-spam-exit-processor-ifile) + (variable-item gnus-group-spam-exit-processor-stat) + (variable-item gnus-group-spam-exit-processor-bogofilter) + (variable-item gnus-group-spam-exit-processor-blacklist) + (variable-item gnus-group-spam-exit-processor-spamoracle) + (variable-item gnus-group-spam-exit-processor-report-gmane) + (variable-item gnus-group-ham-exit-processor-bogofilter) + (variable-item gnus-group-ham-exit-processor-ifile) + (variable-item gnus-group-ham-exit-processor-stat) + (variable-item gnus-group-ham-exit-processor-whitelist) + (variable-item gnus-group-ham-exit-processor-BBDB) + (variable-item gnus-group-ham-exit-processor-spamoracle) + (variable-item gnus-group-ham-exit-processor-copy) + (const :tag "Spam: Gmane Report" (spam spam-use-gmane)) + (const :tag "Spam: Bogofilter" (spam spam-use-bogofilter)) + (const :tag "Spam: Blacklist" (spam spam-use-blacklist)) + (const :tag "Spam: ifile" (spam spam-use-ifile)) + (const :tag "Spam: Spam-stat" (spam spam-use-stat)) + (const :tag "Spam: Spam Oracle" (spam spam-use-spamoracle)) + (const :tag "Ham: ifile" (ham spam-use-ifile)) + (const :tag "Ham: Bogofilter" (ham spam-use-bogofilter)) + (const :tag "Ham: Spam-stat" (ham spam-use-stat)) + (const :tag "Ham: Whitelist" (ham spam-use-whitelist)) + (const :tag "Ham: BBDB" (ham spam-use-BBDB)) + (const :tag "Ham: Copy" (ham spam-use-ham-copy)) + (const :tag "Ham: Spam Oracle" (ham spam-use-spamoracle))))) :function-document - "Which spam or ham processors will be applied to the GROUP articles at summary exit." + "Which spam or ham processors will be applied when the summary is exited." :variable gnus-spam-process-newsgroups :variable-default nil :variable-document "*Groups in which to automatically process spam or ham articles with a backend on summary exit. If non-nil, this should be a list of group name regexps that should match all groups in which to do automatic -spam processing, associated with the appropriate processor. This only makes sense -for mail groups." +spam processing, associated with the appropriate processor." :variable-group spam - :variable-type '(repeat :tag "Spam/Ham Processors" - (list :tag "Spam Summary Exit Processor Choices" - (regexp :tag "Group Regexp") - (set :tag "Spam/Ham Summary Exit Processor" - (variable-item gnus-group-spam-exit-processor-ifile) - (variable-item gnus-group-spam-exit-processor-stat) - (variable-item gnus-group-spam-exit-processor-bogofilter) - (variable-item gnus-group-spam-exit-processor-blacklist) - (variable-item gnus-group-spam-exit-processor-report-gmane) - (variable-item gnus-group-ham-exit-processor-bogofilter) - (variable-item gnus-group-ham-exit-processor-ifile) - (variable-item gnus-group-ham-exit-processor-stat) - (variable-item gnus-group-ham-exit-processor-whitelist) - (variable-item gnus-group-ham-exit-processor-BBDB) - (variable-item gnus-group-ham-exit-processor-copy)))) + :variable-type + '(repeat :tag "Spam/Ham Processors" + (list :tag "Spam Summary Exit Processor Choices" + (regexp :tag "Group Regexp") + (set + :tag "Spam/Ham Summary Exit Processor" + (variable-item gnus-group-spam-exit-processor-ifile) + (variable-item gnus-group-spam-exit-processor-stat) + (variable-item gnus-group-spam-exit-processor-bogofilter) + (variable-item gnus-group-spam-exit-processor-blacklist) + (variable-item gnus-group-spam-exit-processor-spamoracle) + (variable-item gnus-group-spam-exit-processor-report-gmane) + (variable-item gnus-group-ham-exit-processor-bogofilter) + (variable-item gnus-group-ham-exit-processor-ifile) + (variable-item gnus-group-ham-exit-processor-stat) + (variable-item gnus-group-ham-exit-processor-whitelist) + (variable-item gnus-group-ham-exit-processor-BBDB) + (variable-item gnus-group-ham-exit-processor-spamoracle) + (variable-item gnus-group-ham-exit-processor-copy) + (const :tag "Spam: Gmane Report" (spam spam-use-gmane)) + (const :tag "Spam: Bogofilter" (spam spam-use-bogofilter)) + (const :tag "Spam: Blacklist" (spam spam-use-blacklist)) + (const :tag "Spam: ifile" (spam spam-use-ifile)) + (const :tag "Spam: Spam-stat" (spam spam-use-stat)) + (const :tag "Spam: Spam Oracle" (spam spam-use-spamoracle)) + (const :tag "Ham: ifile" (ham spam-use-ifile)) + (const :tag "Ham: Bogofilter" (ham spam-use-bogofilter)) + (const :tag "Ham: Spam-stat" (ham spam-use-stat)) + (const :tag "Ham: Whitelist" (ham spam-use-whitelist)) + (const :tag "Ham: BBDB" (ham spam-use-BBDB)) + (const :tag "Ham: Copy" (ham spam-use-ham-copy)) + (const :tag "Ham: Spam Oracle" (ham spam-use-spamoracle))))) + :parameter-document - "Which spam processors will be applied to the spam or ham GROUP articles at summary exit.") + "Which spam or ham processors will be applied when the summary is exited.") + + (gnus-define-group-parameter + spam-autodetect + :type list + :parameter-type + '(boolean :tag "Spam autodetection") + :function-document + "Should spam be autodetected (with spam-split) in this group?" + :variable gnus-spam-autodetect + :variable-default nil + :variable-document + "*Groups in which spam should be autodetected when they are entered. + Only unseen articles will be examined, unless + spam-autodetect-recheck-messages is set." + :variable-group spam + :variable-type + '(repeat + :tag "Autodetection setting" + (list + (regexp :tag "Group Regexp") + boolean)) + :parameter-document + "Spam autodetection. +Only unseen articles will be examined, unless +spam-autodetect-recheck-messages is set.") + + (gnus-define-group-parameter + spam-autodetect-methods + :type list + :parameter-type + '(choice :tag "Spam autodetection-specific methods" + (const none) + (const default) + (set :tag "Use specific methods" + (variable-item spam-use-blacklist) + (variable-item spam-use-regex-headers) + (variable-item spam-use-regex-body) + (variable-item spam-use-whitelist) + (variable-item spam-use-BBDB) + (variable-item spam-use-ifile) + (variable-item spam-use-spamoracle) + (variable-item spam-use-stat) + (variable-item spam-use-blackholes) + (variable-item spam-use-hashcash) + (variable-item spam-use-bogofilter-headers) + (variable-item spam-use-bogofilter))) + :function-document + "Methods to be used for autodetection in each group" + :variable gnus-spam-autodetect-methods + :variable-default nil + :variable-document + "*Methods for autodetecting spam per group. +Requires the spam-autodetect parameter. Only unseen articles +will be examined, unless spam-autodetect-recheck-messages is +set." + :variable-group spam + :variable-type + '(repeat + :tag "Autodetection methods" + (list + (regexp :tag "Group Regexp") + (choice + (const none) + (const default) + (set :tag "Use specific methods" + (variable-item spam-use-blacklist) + (variable-item spam-use-regex-headers) + (variable-item spam-use-regex-body) + (variable-item spam-use-whitelist) + (variable-item spam-use-BBDB) + (variable-item spam-use-ifile) + (variable-item spam-use-spamoracle) + (variable-item spam-use-stat) + (variable-item spam-use-blackholes) + (variable-item spam-use-hashcash) + (variable-item spam-use-bogofilter-headers) + (variable-item spam-use-bogofilter))))) + :parameter-document + "Spam autodetection methods. +Requires the spam-autodetect parameter. Only unseen articles +will be examined, unless spam-autodetect-recheck-messages is +set.") (gnus-define-group-parameter spam-process-destination - :parameter-type '(choice :tag "Destination for spam-processed articles at summary exit" - (string :tag "Move to a group") - (const :tag "Expire" nil)) + :type list + :parameter-type + '(choice :tag "Destination for spam-processed articles at summary exit" + (string :tag "Move to a group") + (repeat :tag "Move to multiple groups" + (string :tag "Destination group")) + (const :tag "Expire" nil)) :function-document "Where spam-processed articles will go at summary exit." :variable gnus-spam-process-destinations @@ -1947,23 +2102,31 @@ to do spam-processed article moving, associated with the destination group or nil for explicit expiration. This only makes sense for mail groups." :variable-group spam - :variable-type '(repeat - :tag "Spam-processed articles destination" - (list - (regexp :tag "Group Regexp") - (choice - :tag "Destination for spam-processed articles at summary exit" - (string :tag "Move to a group") - (const :tag "Expire" nil)))) + :variable-type + '(repeat + :tag "Spam-processed articles destination" + (list + (regexp :tag "Group Regexp") + (choice + :tag "Destination for spam-processed articles at summary exit" + (string :tag "Move to a group") + (repeat :tag "Move to multiple groups" + (string :tag "Destination group")) + (const :tag "Expire" nil)))) :parameter-document "Where spam-processed articles will go at summary exit.") - + (gnus-define-group-parameter ham-process-destination - :parameter-type '(choice - :tag "Destination for ham articles at summary exit from a spam group" - (string :tag "Move to a group") - (const :tag "Do nothing" nil)) + :type list + :parameter-type + '(choice + :tag "Destination for ham articles at summary exit from a spam group" + (string :tag "Move to a group") + (repeat :tag "Move to multiple groups" + (string :tag "Destination group")) + (const :tag "Respool" respool) + (const :tag "Do nothing" nil)) :function-document "Where ham articles will go at summary exit from a spam group." :variable gnus-ham-process-destinations @@ -1976,24 +2139,29 @@ to do ham article moving, associated with the destination group or nil for explicit ignoring. This only makes sense for mail groups, and only works in spam groups." :variable-group spam - :variable-type '(repeat - :tag "Ham articles destination" - (list - (regexp :tag "Group Regexp") - (choice - :tag "Destination for ham articles at summary exit from spam group" - (string :tag "Move to a group") - (const :tag "Expire" nil)))) + :variable-type + '(repeat + :tag "Ham articles destination" + (list + (regexp :tag "Group Regexp") + (choice + :tag "Destination for ham articles at summary exit from spam group" + (string :tag "Move to a group") + (repeat :tag "Move to multiple groups" + (string :tag "Destination group")) + (const :tag "Respool" respool) + (const :tag "Expire" nil)))) :parameter-document "Where ham articles will go at summary exit from a spam group.") - (gnus-define-group-parameter + (gnus-define-group-parameter ham-marks :type 'list :parameter-type '(list :tag "Ham mark choices" - (set + (set (variable-item gnus-del-mark) (variable-item gnus-read-mark) + (variable-item gnus-ticked-mark) (variable-item gnus-killed-mark) (variable-item gnus-kill-file-mark) (variable-item gnus-low-score-mark))) @@ -2002,20 +2170,20 @@ mail groups, and only works in spam groups." "Marks considered ham (positively not spam). Such articles will be processed as ham (non-spam) on group exit. When nil, the global spam-ham-marks variable takes precedence." - :variable-default '((".*" ((gnus-del-mark + :variable-default '((".*" ((gnus-del-mark gnus-read-mark - gnus-killed-mark + gnus-killed-mark gnus-kill-file-mark gnus-low-score-mark)))) :variable-group spam :variable-document "*Groups in which to explicitly set the ham marks to some value.") - (gnus-define-group-parameter + (gnus-define-group-parameter spam-marks :type 'list :parameter-type '(list :tag "Spam mark choices" - (set + (set (variable-item gnus-spam-mark) (variable-item gnus-killed-mark) (variable-item gnus-kill-file-mark) @@ -2154,14 +2322,15 @@ face." "Whether Gnus is plugged or not.") (defcustom gnus-agent-cache t - "Controls use of the agent cache while plugged. When set, Gnus will prefer -using the locally stored content rather than re-fetching it from the server. -You also need to enable `gnus-agent' for this to have any affect." + "Controls use of the agent cache while plugged. +When set, Gnus will prefer using the locally stored content rather +than re-fetching it from the server. You also need to enable +`gnus-agent' for this to have any affect." :version "21.3" :group 'gnus-agent :type 'boolean) -(defcustom gnus-default-charset 'iso-8859-1 +(defcustom gnus-default-charset 'undecided "Default charset assumed to be used when viewing non-ASCII characters. This variable is overridden on a group-to-group basis by the `gnus-group-charset-alist' variable and is only used on groups not @@ -2169,9 +2338,13 @@ covered by that variable." :type 'symbol :group 'gnus-charset) +;; Fixme: Doc reference to agent. (defcustom gnus-agent t "Whether we want to use the Gnus agent or not. -Putting (gnus-agentize) in ~/.gnus is obsolete by (setq gnus-agent t)." + +You may customize gnus-agent to disable its use. However, some +back ends have started to use the agent as a client-side cache. +Disabling the agent may result in noticeable loss of performance." :version "21.3" :group 'gnus-agent :type 'boolean) @@ -2196,11 +2369,36 @@ This should be an alist for Emacs, or a plist for XEmacs." (symbol :tag "Parameter") (sexp :tag "Value"))))) +(defcustom gnus-user-agent 'gnus-mime-edit + "Which information should be exposed in the User-Agent header. + +It can be one of the symbols `gnus' \(show only Gnus version\), `emacs-gnus' +\(show only Emacs and Gnus versions\), `emacs-gnus-config' \(same as +`emacs-gnus' plus system configuration\), `emacs-gnus-type' \(same as +`emacs-gnus' plus system type\), `gnus-mime-edit' \(show Gnus version and +MIME Edit User-Agent\) or a custom string. If you set it to a string, +be sure to use a valid format, see RFC 2616." + :group 'gnus-message + :type '(choice + (item :tag "Show Gnus version and MIME Edit User-Agent" + gnus-mime-edit) + (item :tag "Show Gnus and Emacs versions and system type" + emacs-gnus-type) + (item :tag "Show Gnus and Emacs versions and system configuration" + emacs-gnus-config) + (item :tag "Show Gnus and Emacs versions" emacs-gnus) + (item :tag "Show only Gnus version" gnus) + (string :tag "Other"))) + ;;; Internal variables (defvar gnus-agent-gcc-header "X-Gnus-Agent-Gcc") (defvar gnus-agent-meta-information-header "X-Gnus-Agent-Meta-Information") +(defvar gnus-agent-method-p-cache nil + ; Reset each time gnus-agent-covered-methods is changed else + ; gnus-agent-method-p may mis-report a methods status. + ) (defvar gnus-agent-target-move-group-header "X-Gnus-Agent-Move-To") (defvar gnus-draft-meta-information-header "X-Draft-From") (defvar gnus-group-get-parameter-function 'gnus-group-get-parameter) @@ -2212,7 +2410,8 @@ This should be an alist for Emacs, or a plist for XEmacs." (defvar gnus-agent-fetching nil "Whether Gnus agent is in fetching mode.") -(defvar gnus-agent-covered-methods nil) +(defvar gnus-agent-covered-methods nil + "A list of servers, NOT methods, showing which servers are covered by the agent.") (defvar gnus-command-method nil "Dynamically bound variable that says what the current back end is.") @@ -2332,11 +2531,8 @@ This variable can be nil, gnus or gnus-ja." '(gnus-newsrc-options gnus-newsrc-options-n gnus-newsrc-last-checked-date gnus-newsrc-alist gnus-server-alist - gnus-registry-alist - gnus-registry-headers-alist gnus-killed-list gnus-zombie-list - gnus-topic-topology gnus-topic-alist - gnus-agent-covered-methods) + gnus-topic-topology gnus-topic-alist) "Gnus variables saved in the quick startup file.") (defvar gnus-product-variable-file-list @@ -2375,24 +2571,20 @@ It has an effect on the values of `gnus-*-line-format-spec'." (defvar gnus-newsrc-alist nil "Assoc list of read articles. -gnus-newsrc-hashtb should be kept so that both hold the same information.") +`gnus-newsrc-hashtb' should be kept so that both hold the same information.") (defvar gnus-registry-alist nil "Assoc list of registry data. gnus-registry.el will populate this if it's loaded.") -(defvar gnus-registry-headers-alist nil - "Assoc list of registry header data. -gnus-registry.el will populate this if it's loaded.") - (defvar gnus-newsrc-hashtb nil - "Hashtable of gnus-newsrc-alist.") + "Hashtable of `gnus-newsrc-alist'.") (defvar gnus-killed-list nil "List of killed newsgroups.") (defvar gnus-killed-hashtb nil - "Hash table equivalent of gnus-killed-list.") + "Hash table equivalent of `gnus-killed-list'.") (defvar gnus-zombie-list nil "List of almost dead newsgroups.") @@ -3181,10 +3373,59 @@ that that variable is buffer-local to the summary buffers." (not (equal server (format "%s:%s" (caar servers) (cadar servers))))) (pop servers)) - (car servers))))) - (push (cons server result) gnus-server-method-cache) + (car servers)) + ;; This could be some sort of foreign server that I + ;; simply haven't opened (yet). Do a brute-force scan + ;; of the entire gnus-newsrc-alist for the server name + ;; of every method. As a side-effect, loads the + ;; gnus-server-method-cache so this only happens once, + ;; if at all. + (let (match) + (mapcar + (lambda (info) + (let ((info-method (gnus-info-method info))) + (unless (stringp info-method) + (let ((info-server (gnus-method-to-server info-method))) + (when (equal server info-server) + (setq match info-method)))))) + (cdr gnus-newsrc-alist)) + match)))) + (when result + (push (cons server result) gnus-server-method-cache)) result))) +(defsubst gnus-method-to-server (method) + (catch 'server-name + (setq method (or method gnus-select-method)) + + ;; Perhaps it is already in the cache. + (mapc (lambda (name-method) + (if (equal (cdr name-method) method) + (throw 'server-name (car name-method)))) + gnus-server-method-cache) + + (mapc + (lambda (server-alist) + (mapc (lambda (name-method) + (when (gnus-methods-equal-p (cdr name-method) method) + (unless (member name-method gnus-server-method-cache) + (push name-method gnus-server-method-cache)) + (throw 'server-name (car name-method)))) + server-alist)) + (let ((alists (list gnus-server-alist + gnus-predefined-server-alist))) + (if gnus-select-method + (push (list (cons "native" gnus-select-method)) alists)) + alists)) + + (let* ((name (if (member (cadr method) '(nil "")) + (format "%s" (car method)) + (format "%s:%s" (car method) (cadr method)))) + (name-method (cons name method))) + (unless (member name-method gnus-server-method-cache) + (push name-method gnus-server-method-cache)) + name))) + (defsubst gnus-server-get-method (group method) ;; Input either a server name, and extended server name, or a ;; select method, and return a select method. @@ -3290,8 +3531,7 @@ server is native)." group))) (defun gnus-group-full-name (group method) - "Return the full name from GROUP and METHOD, even if the method is -native." + "Return the full name from GROUP and METHOD, even if the method is native." (gnus-group-prefixed-name group method t)) (defun gnus-group-guess-full-name (group) @@ -3300,11 +3540,19 @@ native." group (gnus-group-full-name group (gnus-find-method-for-group group)))) +(defun gnus-group-guess-full-name-from-command-method (group) + "Guess the full name from GROUP, even if the method is native." + (if (gnus-group-prefixed-p group) + group + (gnus-group-full-name group gnus-command-method))) + (defun gnus-group-real-prefix (group) "Return the prefix of the current group name." - (if (string-match "^[^:]+:" group) - (substring group 0 (match-end 0)) - "")) + (if (stringp group) + (if (string-match "^[^:]+:" group) + (substring group 0 (match-end 0)) + "") + nil)) (defun gnus-group-short-name (group) "Return the short group name." @@ -3353,10 +3601,10 @@ You should probably use `gnus-find-method-for-group' instead." (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)) @@ -3766,8 +4014,22 @@ Disallow invalid group names." (setq group (read-string (concat prefix prompt) (cons (or default "") 0) 'gnus-group-history))) - (setq prefix (format "Invalid group name: \"%s\". " group) - group nil))) + (let ((match (match-string 0 group))) + ;; 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 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 permanently.")) + (setq prefix (format "Invalid group name: \"%s\". " group) + group nil))))) group)) (defun gnus-read-method (prompt) @@ -3811,7 +4073,13 @@ Allow completion over sensible values." (defun gnus-agent-method-p (method) "Say whether METHOD is covered by the agent." - (member method gnus-agent-covered-methods)) + (or (eq (car gnus-agent-method-p-cache) method) + (setq gnus-agent-method-p-cache + (cons method + (member (if (stringp method) + method + (gnus-method-to-server method)) gnus-agent-covered-methods)))) + (cdr gnus-agent-method-p-cache)) (defun gnus-online (method) (not @@ -3894,17 +4162,17 @@ current display is used." (switch-to-buffer gnus-group-buffer) (funcall gnus-other-frame-function arg) (add-hook 'gnus-exit-gnus-hook - (lambda nil - (when (and (frame-live-p gnus-other-frame-object) - (cdr (frame-list))) - (delete-frame gnus-other-frame-object)) - (setq gnus-other-frame-object nil))))))) + '(lambda nil + (when (and (frame-live-p gnus-other-frame-object) + (cdr (frame-list))) + (delete-frame gnus-other-frame-object)) + (setq gnus-other-frame-object nil))))))) ;;;###autoload (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)) diff --git a/lisp/html2text.el b/lisp/html2text.el index 4b89f8f..41fea4b 100644 --- a/lisp/html2text.el +++ b/lisp/html2text.el @@ -463,9 +463,7 @@ See the documentation for that variable." (dolist (tag tag-list) (html2text-buffer-head) (while (re-search-forward (format "\\(]*>\\)" tag) (point-max) t) - (let ((p1 (point))) - (search-backward "<") - (delete-region (point) p1))))) + (delete-region (match-beginning 0) (match-end 0))))) (defun html2text-format-tags () "See the variable \"html2text-format-tag-list\" for documentation" diff --git a/lisp/ietf-drums.el b/lisp/ietf-drums.el index aa48c3a..c546316 100644 --- a/lisp/ietf-drums.el +++ b/lisp/ietf-drums.el @@ -64,7 +64,6 @@ backslash and doublequote.") (modify-syntax-entry ?> ")" table) (modify-syntax-entry ?@ "w" table) (modify-syntax-entry ?/ "w" table) - (modify-syntax-entry ?= " " table) (modify-syntax-entry ?* " " table) (modify-syntax-entry ?\; " " table) (modify-syntax-entry ?\' " " table) diff --git a/lisp/imap.el b/lisp/imap.el index 88dda14..0c7f5dc 100644 --- a/lisp/imap.el +++ b/lisp/imap.el @@ -125,6 +125,7 @@ ;; o Don't use `read' at all (important places already fixed) ;; o Accept list of articles instead of message set string in most ;; imap-message-* functions. +;; o Send strings as literal if they contain, e.g., ". ;; ;; Revision history: ;; @@ -219,7 +220,13 @@ until a successful connection is made." :type '(repeat string)) (defcustom imap-process-connection-type nil - "*Value for `process-connection-type' to use for Kerberos4 and GSSAPI." + "*Value for `process-connection-type' to use for Kerberos4, GSSAPI and SSL. +The `process-connection-type' variable control type of device +used to communicate with subprocesses. Values are nil to use a +pipe, or t or `pty' to use a pty. The value has no effect if the +system has no ptys or if all ptys are busy: then a pipe is used +in any case. The value takes effect when a IMAP server is +opened, changing it after that has no effect.." :group 'imap :type 'boolean) @@ -426,6 +433,10 @@ sure of changing the value of `foo'." (setcdr alist (imap-remassoc key (cdr alist))) alist))) +(defmacro imap-disable-multibyte () + "Enable multibyte in the current buffer." + '(set-buffer-multibyte nil)) + (defsubst imap-utf7-encode (string) (if imap-use-utf7 (and string @@ -489,6 +500,13 @@ sure of changing the value of `foo'." (while (and (memq (process-status process) '(open run)) (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-min)) + ;; Athena IMTEST can output SSL verify errors + (or (while (looking-at "^verify error:num=") + (forward-line)) + t) + (or (while (looking-at "^TLS connection established") + (forward-line)) + t) ;; cyrus 1.6.x (13? < x <= 22) queries capabilities (or (while (looking-at "^C:") (forward-line)) @@ -509,6 +527,7 @@ sure of changing the value of `foo'." (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) @@ -572,6 +591,7 @@ sure of changing the value of `foo'." (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) @@ -621,6 +641,7 @@ sure of changing the value of `foo'." (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) @@ -650,7 +671,7 @@ sure of changing the value of `foo'." (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) - (set-buffer-multibyte nil) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) @@ -672,6 +693,7 @@ sure of changing the value of `foo'." (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) @@ -709,6 +731,7 @@ sure of changing the value of `foo'." (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) @@ -729,36 +752,36 @@ sure of changing the value of `foo'." (let* ((port (or port imap-default-port)) (process (as-binary-process (starttls-open-stream name buffer server port))) - done) + done tls-info) (message "imap: Connecting with STARTTLS...") (when process (while (and (memq (process-status process) '(open run)) (set-buffer buffer) ;; XXX "blue moon" nntp.el bug - (goto-char (point-min)) + (goto-char (point-max)) + (forward-line -1) (not (imap-parse-greeting))) (accept-process-output process 1) (sit-for 1)) + (imap-send-command "STARTTLS") + (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug + (goto-char (point-max)) + (forward-line -1) + (not (re-search-forward "[0-9]+ OK.*\r?\n" nil t))) + (accept-process-output process 1) + (sit-for 1)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) - (let ((imap-process process)) - (unwind-protect - (progn - (set-process-filter imap-process 'imap-arrival-filter) - (when (and (eq imap-stream 'starttls) - (imap-ok-p (imap-send-command-wait "STARTTLS"))) - (starttls-negotiate imap-process))) - (set-process-filter imap-process nil))) - (when (memq (process-status process) '(open run)) + (when (and (setq tls-info (starttls-negotiate process)) + (memq (process-status process) '(open run))) (setq done process))) - (if done - (progn - (message "imap: Connecting with STARTTLS...done") - done) - (message "imap: Connecting with STARTTLS...failed") - nil))) + (if (stringp tls-info) + (message "imap: STARTTLS info: %s" tls-info)) + (message "imap: Connecting with STARTTLS...%s" (if done "done" "failed")) + done)) ;; Server functions; authenticator stuff: @@ -794,6 +817,7 @@ Returns t if login was successful, nil otherwise." (setq imap-password passwd))) (message "Login failed...") (setq passwd nil) + (setq imap-password nil) (sit-for 1)))) ;; (quit (with-current-buffer buffer ;; (setq user nil @@ -804,8 +828,7 @@ Returns t if login was successful, nil otherwise." ret))) (defun imap-gssapi-auth-p (buffer) - (and (imap-capability 'AUTH=GSSAPI buffer) - (eq imap-stream 'gssapi))) + (eq imap-stream 'gssapi)) (defun imap-gssapi-auth (buffer) (message "imap: Authenticating using GSSAPI...%s" @@ -942,7 +965,7 @@ necessary. If nil, the buffer name is generated." (if (imap-opened buffer) (imap-close buffer)) (mapcar 'make-local-variable imap-local-variables) - (set-buffer-multibyte nil) + (imap-disable-multibyte) (buffer-disable-undo) (setq imap-server (or server imap-server)) (setq imap-port (or port imap-port)) @@ -965,7 +988,7 @@ necessary. If nil, the buffer name is generated." (with-current-buffer (get-buffer-create (generate-new-buffer-name " *temp*")) (mapcar 'make-local-variable imap-local-variables) - (set-buffer-multibyte nil) + (imap-disable-multibyte) (buffer-disable-undo) (setq imap-server (or server imap-server)) (setq imap-port (or port imap-port)) @@ -1319,10 +1342,11 @@ returned, if ITEMS is a symbol only its value is returned." (imap-send-command-wait (list "STATUS \"" (imap-utf7-encode mailbox) "\" " - (format "%s" - (if (listp items) - items - (list items)))))) + (upcase + (format "%s" + (if (listp items) + items + (list items))))))) (if (listp items) (mapcar (lambda (item) (imap-mailbox-get item mailbox)) @@ -1650,6 +1674,7 @@ on failure." (setq cmdstr (concat cmdstr imap-client-eol)) (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert cmdstr))) @@ -1685,7 +1710,7 @@ on failure." (imap-send-command-1 cmdstr) (setq cmdstr nil) (if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE)) - (setq command nil);; abort command if no cont-req + (setq command nil) ;; abort command if no cont-req (let ((process imap-process) (stream imap-stream) (eol imap-client-eol)) @@ -1693,6 +1718,7 @@ on failure." (and imap-log (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring cmd))) @@ -1705,7 +1731,7 @@ on failure." (setq cmdstr nil) (unwind-protect (if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE)) - (setq command nil);; abort command if no cont-req + (setq command nil) ;; abort command if no cont-req (setq command (cons (funcall cmd imap-continuation) command))) (setq imap-continuation nil))) @@ -1731,6 +1757,13 @@ on failure." (truncate (* (- imap-read-timeout (truncate imap-read-timeout)) 1000))))) + ;; A process can die _before_ we have processed everything it + ;; has to say. Moreover, this can happen in between the call to + ;; accept-process-output and the call to process-status in an + ;; iteration of the loop above. + (when (and (null imap-continuation) + (< imap-reached-tag tag)) + (accept-process-output imap-process 0 0)) (when imap-have-messaged (message "")) (and (memq (process-status imap-process) '(open run)) @@ -1757,33 +1790,37 @@ Return nil if no complete line has arrived." (defun imap-arrival-filter (proc string) "IMAP process filter." - (with-current-buffer (process-buffer proc) - (goto-char (point-max)) - (insert string) - (and imap-log - (with-current-buffer (get-buffer-create imap-log-buffer) - (buffer-disable-undo) - (goto-char (point-max)) - (insert string))) - (let (end) - (goto-char (point-min)) - (while (setq end (imap-find-next-line)) - (save-restriction - (narrow-to-region (point-min) end) - (delete-backward-char (length imap-server-eol)) - (goto-char (point-min)) - (unwind-protect - (cond ((eq imap-state 'initial) - (imap-parse-greeting)) - ((or (eq imap-state 'auth) - (eq imap-state 'nonauth) - (eq imap-state 'selected) - (eq imap-state 'examine)) - (imap-parse-response)) - (t - (message "Unknown state %s in arrival filter" - imap-state))) - (delete-region (point-min) (point-max)))))))) + ;; Sometimes, we are called even though the process has died. + ;; Better abstain from doing stuff in that case. + (when (buffer-name (process-buffer proc)) + (with-current-buffer (process-buffer proc) + (goto-char (point-max)) + (insert string) + (and imap-log + (with-current-buffer (get-buffer-create imap-log-buffer) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert string))) + (let (end) + (goto-char (point-min)) + (while (setq end (imap-find-next-line)) + (save-restriction + (narrow-to-region (point-min) end) + (delete-backward-char (length imap-server-eol)) + (goto-char (point-min)) + (unwind-protect + (cond ((eq imap-state 'initial) + (imap-parse-greeting)) + ((or (eq imap-state 'auth) + (eq imap-state 'nonauth) + (eq imap-state 'selected) + (eq imap-state 'examine)) + (imap-parse-response)) + (t + (message "Unknown state %s in arrival filter" + imap-state))) + (delete-region (point-min) (point-max))))))))) ;; Imap parser. @@ -2409,31 +2446,31 @@ Return nil if no complete line has arrived." (defun imap-parse-envelope () (when (eq (char-after) ?\() (imap-forward) - (vector (prog1 (imap-parse-nstring);; date + (vector (prog1 (imap-parse-nstring) ;; date (imap-forward)) - (prog1 (imap-parse-nstring);; subject + (prog1 (imap-parse-nstring) ;; subject (imap-forward)) - (prog1 (imap-parse-address-list);; from + (prog1 (imap-parse-address-list) ;; from (imap-forward)) - (prog1 (imap-parse-address-list);; sender + (prog1 (imap-parse-address-list) ;; sender (imap-forward)) - (prog1 (imap-parse-address-list);; reply-to + (prog1 (imap-parse-address-list) ;; reply-to (imap-forward)) - (prog1 (imap-parse-address-list);; to + (prog1 (imap-parse-address-list) ;; to (imap-forward)) - (prog1 (imap-parse-address-list);; cc + (prog1 (imap-parse-address-list) ;; cc (imap-forward)) - (prog1 (imap-parse-address-list);; bcc + (prog1 (imap-parse-address-list) ;; bcc (imap-forward)) - (prog1 (imap-parse-nstring);; in-reply-to + (prog1 (imap-parse-nstring) ;; in-reply-to (imap-forward)) - (prog1 (imap-parse-nstring);; message-id + (prog1 (imap-parse-nstring) ;; message-id (imap-forward))))) ;; body-fld-param = "(" string SP string *(SP string SP string) ")" / nil (defsubst imap-parse-string-list () - (cond ((eq (char-after) ?\();; body-fld-param + (cond ((eq (char-after) ?\() ;; body-fld-param (let (strlist str) (imap-forward) (while (setq str (imap-parse-string)) @@ -2481,7 +2518,7 @@ Return nil if no complete line has arrived." (defsubst imap-parse-body-ext () (let (ext) - (when (eq (char-after) ?\ );; body-fld-dsp + (when (eq (char-after) ?\ ) ;; body-fld-dsp (imap-forward) (let (dsp) (if (eq (char-after) ?\() @@ -2493,12 +2530,12 @@ Return nil if no complete line has arrived." (imap-forward)) (assert (imap-parse-nil) t "In imap-parse-body-ext")) (push (nreverse dsp) ext)) - (when (eq (char-after) ?\ );; body-fld-lang + (when (eq (char-after) ?\ ) ;; body-fld-lang (imap-forward) (if (eq (char-after) ?\() (push (imap-parse-string-list) ext) (push (imap-parse-nstring) ext)) - (while (eq (char-after) ?\ );; body-extension + (while (eq (char-after) ?\ ) ;; body-extension (imap-forward) (setq ext (append (imap-parse-body-extension) ext))))) ext)) @@ -2579,38 +2616,38 @@ Return nil if no complete line has arrived." (imap-forward)) (push subbody body)) (imap-forward) - (push (imap-parse-string) body);; media-subtype - (when (eq (char-after) ?\ );; body-ext-mpart: + (push (imap-parse-string) body) ;; media-subtype + (when (eq (char-after) ?\ ) ;; body-ext-mpart: (imap-forward) - (if (eq (char-after) ?\();; body-fld-param + (if (eq (char-after) ?\() ;; body-fld-param (push (imap-parse-string-list) body) (push (and (imap-parse-nil) nil) body)) (setq body - (append (imap-parse-body-ext) body)));; body-ext-... + (append (imap-parse-body-ext) body))) ;; body-ext-... (assert (eq (char-after) ?\)) t "In imap-parse-body") (imap-forward) (nreverse body)) - (push (imap-parse-string) body);; media-type + (push (imap-parse-string) body) ;; media-type (imap-forward) - (push (imap-parse-string) body);; media-subtype + (push (imap-parse-string) body) ;; media-subtype (imap-forward) ;; next line for Sun SIMS bug (and (eq (char-after) ? ) (imap-forward)) - (if (eq (char-after) ?\();; body-fld-param + (if (eq (char-after) ?\() ;; body-fld-param (push (imap-parse-string-list) body) (push (and (imap-parse-nil) nil) body)) (imap-forward) - (push (imap-parse-nstring) body);; body-fld-id + (push (imap-parse-nstring) body) ;; body-fld-id (imap-forward) - (push (imap-parse-nstring) body);; body-fld-desc + (push (imap-parse-nstring) body) ;; body-fld-desc (imap-forward) ;; next `or' for Sun SIMS bug, it regard body-fld-enc as a ;; nstring and return nil instead of defaulting back to 7BIT ;; as the standard says. - (push (or (imap-parse-nstring) "7BIT") body);; body-fld-enc + (push (or (imap-parse-nstring) "7BIT") body) ;; body-fld-enc (imap-forward) - (push (imap-parse-number) body);; body-fld-octets + (push (imap-parse-number) body) ;; body-fld-octets ;; ok, we're done parsing the required parts, what comes now is one ;; of three things: @@ -2625,27 +2662,27 @@ Return nil if no complete line has arrived." (when (eq (char-after) ?\ ) (imap-forward) (let (lines) - (cond ((eq (char-after) ?\();; body-type-msg: - (push (imap-parse-envelope) body);; envelope + (cond ((eq (char-after) ?\() ;; body-type-msg: + (push (imap-parse-envelope) body) ;; envelope (imap-forward) - (push (imap-parse-body) body);; body + (push (imap-parse-body) body) ;; body ;; buggy stalker communigate pro 3.0 doesn't print ;; number of lines in message/rfc822 attachment (if (eq (char-after) ?\)) (push 0 body) (imap-forward) (push (imap-parse-number) body))) ;; body-fld-lines - ((setq lines (imap-parse-number)) ;; body-type-text: - (push lines body)) ;; body-fld-lines + ((setq lines (imap-parse-number)) ;; body-type-text: + (push lines body)) ;; body-fld-lines (t - (backward-char))))) ;; no match... + (backward-char))))) ;; no match... ;; ...and then parse the third one here... - (when (eq (char-after) ?\ );; body-ext-1part: + (when (eq (char-after) ?\ ) ;; body-ext-1part: (imap-forward) - (push (imap-parse-nstring) body);; body-fld-md5 - (setq body (append (imap-parse-body-ext) body)));; body-ext-1part.. + (push (imap-parse-nstring) body) ;; body-fld-md5 + (setq body (append (imap-parse-body-ext) body))) ;; body-ext-1part.. (assert (eq (char-after) ?\)) t "In imap-parse-body 2") (imap-forward) diff --git a/lisp/lpath.el b/lisp/lpath.el index fc48c59..0529e9a 100644 --- a/lisp/lpath.el +++ b/lisp/lpath.el @@ -11,39 +11,35 @@ (maybe-fbind '(Info-directory Info-menu bbdb-create-internal bbdb-records create-image - display-graphic-p display-time-event-handler find-image - image-size image-type-available-p insert-image - make-mode-line-mouse-map make-temp-file open-ssl-stream - propertize put-image replace-regexp-in-string + display-graphic-p find-coding-system find-image image-size + image-type-available-p insert-image make-mode-line-mouse-map + make-temp-file propertize put-image replace-regexp-in-string rmail-msg-is-pruned rmail-msg-restore-non-pruned-header sort-coding-systems spam-BBDB-register-routine spam-enter-ham-BBDB string-to-multibyte tool-bar-add-item tool-bar-add-item-from-menu tool-bar-local-item-from-menu - url-http-file-exists-p vcard-pretty-print w32-focus-frame - w3m-charset-to-coding-system x-focus-frame)) + url-generic-parse-url url-http-file-exists-p + url-insert-file-contents vcard-pretty-print w32-focus-frame + w3m-charset-to-coding-system w3m-region x-focus-frame)) (maybe-bind '(filladapt-mode - mc-pgp-always-sign mm-w3m-mode-map rmail-enable-mime-composing - rmail-insert-mime-forwarded-message-function + mc-pgp-always-sign rmail-insert-mime-forwarded-message-function + url-current-object url-package-name url-package-version + w3-meta-charset-content-type-regexp + w3-meta-content-type-charset-regexp w3m-cid-retrieve-function-alist w3m-current-buffer w3m-display-inline-images w3m-meta-content-type-charset-regexp w3m-minor-mode-map)) (if (featurep 'xemacs) (progn - (maybe-fbind '(Info-directory - Info-menu ccl-execute-on-string char-charset charsetp - coding-system-get coding-system-list coding-system-p - decode-coding-region decode-coding-string - define-ccl-program delete-overlay detect-coding-region - encode-coding-region encode-coding-string + (maybe-fbind '(delete-overlay event-click-count event-end event-start - find-charset-region find-coding-systems-for-charsets + find-coding-systems-for-charsets find-coding-systems-region find-coding-systems-string - get-charset-property mail-abbrevs-setup - mouse-minibuffer-check mouse-movement-p mouse-scroll-subr - overlay-lists pgg-parse-crc24-string posn-point - posn-window read-event set-buffer-multibyte track-mouse - window-edges w3m-region)) + mail-abbrevs-setup mouse-minibuffer-check + mouse-movement-p mouse-scroll-subr overlay-lists + posn-point posn-window read-event set-buffer-multibyte + track-mouse window-edges)) (maybe-bind '(adaptive-fill-first-line-regexp buffer-display-table buffer-file-coding-system current-language-environment @@ -51,25 +47,38 @@ enable-multibyte-characters gnus-agent-expire-current-dirs language-info-alist mark-active mouse-selection-click-count mouse-selection-click-count-buffer pgg-parse-crc24 - temporary-file-directory transient-mark-mode - w3-meta-content-type-charset-regexp - w3-meta-charset-content-type-regexp))) + temporary-file-directory transient-mark-mode))) (maybe-fbind '(bbdb-complete-name - delete-annotation device-connection dfw-device + delete-annotation delete-extent device-connection dfw-device events-to-keys font-lock-set-defaults frame-device - glyph-height glyph-width mail-aliases-setup make-annotation - make-event make-glyph make-network-process map-extents - message-xmas-redefine set-extent-property temp-directory - url-generic-parse-url url-insert-file-contents + get-char-table glyph-height glyph-width mail-aliases-setup + make-annotation make-event make-glyph make-network-process + map-extents message-xmas-redefine put-char-table + set-extent-property temp-directory valid-image-instantiator-format-p w3-coding-system-for-mime-charset w3-do-setup - w3-prepare-buffer w3-region w3m-region window-pixel-height + w3-prepare-buffer w3-region window-pixel-height window-pixel-width)) - (maybe-bind '(help-echo-owns-message - mail-mode-hook - url-current-object url-package-name url-package-version - w3-meta-charset-content-type-regexp - w3-meta-content-type-charset-regexp))) + (maybe-bind '(help-echo-owns-message mail-mode-hook mm-w3m-mode-map))) + +(when (and (featurep 'xemacs) + (not (featurep 'mule))) + (maybe-fbind '(ccl-execute-on-string + char-charset charsetp coding-system-get define-ccl-program + find-charset-region get-charset-property + pgg-parse-crc24-string)) + (unless (featurep 'file-coding) + (maybe-fbind '(coding-system-base + coding-system-list coding-system-p decode-coding-region + decode-coding-string detect-coding-region + encode-coding-region encode-coding-string)))) + +(defun nnkiboze-score-file (a) + ) + +(defun split-line (&optional arg) + ) + ;; T-gnus. (let ((functions @@ -84,6 +93,7 @@ coding-system-to-mime-charset compose-mail file-name-extension find-coding-systems-for-charsets find-coding-systems-region function-max-args get-charset-property + read-passwd ;; See the Mule23@1934 file. smiley-encode-buffer smtpmail-send-it)) (t '(function-max-args smiley-encode-buffer)))) @@ -107,16 +117,4 @@ (maybe-bind variables) (maybe-bind common-vars)) -(when (and (featurep 'xemacs) - (not (featurep 'mule))) - (progn - (maybe-fbind '(coding-system-base find-charset-string)))) - - -(defun nnkiboze-score-file (a) - ) - -(defun split-line (&optional arg) - ) - (provide 'lpath) diff --git a/lisp/mail-source.el b/lisp/mail-source.el index e84f79c..061530e 100644 --- a/lisp/mail-source.el +++ b/lisp/mail-source.el @@ -1,5 +1,6 @@ ;;; mail-source.el --- functions for fetching mail -;; Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news, mail @@ -261,7 +262,7 @@ If non-nil, this maildrop will be checked periodically for new mail." :group 'mail-source :type 'integer) -(defcustom mail-source-delete-incoming nil +(defcustom mail-source-delete-incoming t "*If non-nil, delete incoming files after handling. If t, delete immediately, if nil, never delete. If a positive number, delete files older than number of days." @@ -345,7 +346,7 @@ Common keywords should be listed here.") (:leave)) (maildir (:path (or (getenv "MAILDIR") "~/Maildir/")) - (:subdirs ("new" "cur")) + (:subdirs ("cur" "new")) (:function)) (imap (:server (getenv "MAILHOST")) @@ -358,6 +359,9 @@ Common keywords should be listed here.") (:mailbox "INBOX") (:predicate "UNSEEN UNDELETED") (:fetchflag "\\Deleted") + (:prescript) + (:prescript-delay) + (:postscript) (:dontexpunge)) (webmail (:subtype hotmail) @@ -512,17 +516,6 @@ Return the number of files that were found." (error "Cannot get new mail")) 0))))))))) -(eval-and-compile - (if (fboundp 'make-temp-file) - (defalias 'mail-source-make-complex-temp-name 'make-temp-file) - (defun mail-source-make-complex-temp-name (prefix) - (let ((newname (make-temp-name prefix)) - (newprefix prefix)) - (while (file-exists-p newname) - (setq newprefix (concat newprefix "x")) - (setq newname (make-temp-name newprefix))) - newname)))) - (defun mail-source-delete-old-incoming (&optional age confirm) "Remove incoming files older than AGE days. If CONFIRM is non-nil, ask for confirmation before removing a file." @@ -567,7 +560,7 @@ Pass INFO on to CALLBACK." (if (eq mail-source-delete-incoming t) (delete-file mail-source-crash-box) (let ((incoming - (mail-source-make-complex-temp-name + (mm-make-temp-file (expand-file-name mail-source-incoming-file-prefix mail-source-directory)))) @@ -620,7 +613,8 @@ Pass INFO on to CALLBACK." (set-file-modes to mail-source-default-file-modes)) (if (and (or (not (buffer-modified-p errors)) (zerop (buffer-size errors))) - (zerop result)) + (and (numberp result) + (zerop result))) ;; No output => movemail won. t (set-buffer errors) @@ -656,8 +650,8 @@ Pass INFO on to CALLBACK." (delete-file from))) (defun mail-source-fetch-with-program (program) - (zerop (call-process shell-file-name nil nil nil - shell-command-switch program))) + (eq 0 (call-process shell-file-name nil nil nil + shell-command-switch program))) (defun mail-source-run-script (script spec &optional delay) (when script @@ -987,14 +981,17 @@ This only works when `display-time' is enabled." (defun mail-source-fetch-imap (source callback) "Fetcher for imap sources." (mail-source-bind (imap source) - (let* ((from (format "%s:%s:%s" server user port)) - (found 0) - (buffer-name " *imap source*") - (buf (get-buffer-create (generate-new-buffer-name buffer-name))) - (mail-source-string (format "imap:%s:%s" server mailbox)) - (imap-shell-program (or (list program) imap-shell-program)) - remove) - (if (and (imap-open server port stream authentication buffer-name) + (mail-source-run-script + prescript (format-spec-make ?p password ?t mail-source-crash-box + ?s server ?P port ?u user) + prescript-delay) + (let ((from (format "%s:%s:%s" server user port)) + (found 0) + (buf (generate-new-buffer " *imap source*")) + (mail-source-string (format "imap:%s:%s" server mailbox)) + (imap-shell-program (or (list program) imap-shell-program)) + remove) + (if (and (imap-open server port stream authentication buf) (imap-authenticate user (or (cdr (assoc from mail-source-password-cache)) password) buf) @@ -1008,8 +1005,8 @@ This only works when `display-time' is enabled." (set-buffer-multibyte nil) ;; remember password (with-current-buffer buf - (when (or imap-password - (assoc from mail-source-password-cache)) + (when (and imap-password + (not (assoc from mail-source-password-cache))) (push (cons from imap-password) mail-source-password-cache))) ;; if predicate is nil, use all uids (dolist (uid (imap-search (or predicate "1:*") buf)) @@ -1028,6 +1025,7 @@ This only works when `display-time' is enabled." (nnheader-ms-strip-cr)) (incf found (mail-source-callback callback server)) (when (and remove fetchflag) + (setq remove (nreverse remove)) (imap-message-flags-add (imap-range-to-message-set (gnus-compress-sequence remove)) fetchflag nil buf)) @@ -1041,8 +1039,12 @@ This only works when `display-time' is enabled." (setq mail-source-password-cache (delq (assoc from mail-source-password-cache) mail-source-password-cache)) - (error (imap-error-text buf))) + (error "IMAP error: %s" (imap-error-text buf))) (kill-buffer buf) + (mail-source-run-script + postscript + (format-spec-make ?p password ?t mail-source-crash-box + ?s server ?P port ?u user)) found))) (eval-and-compile diff --git a/lisp/message.el b/lisp/message.el index 25355f8..6784330 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -1,5 +1,5 @@ ;;; message.el --- composing mail and news messages -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -39,6 +39,7 @@ (eval-when-compile (require 'cl) (require 'smtp) + (defvar gnus-message-group-art) (defvar gnus-list-identifiers)) ; gnus-sum is required where necessary (eval-and-compile (if (boundp 'MULE) @@ -64,8 +65,11 @@ (require 'rfc822) (eval-and-compile + (autoload 'customize-save-variable "cus-edit") ;; for Mule 2. (autoload 'sha1 "sha1-el") - (autoload 'customize-save-variable "cus-edit"));; for Mule 2. + (autoload 'gnus-find-method-for-group "gnus") + (autoload 'nnvirtual-find-group-art "nnvirtual") + (autoload 'gnus-group-decoded-name "gnus-group")) (defgroup message '((user-mail-address custom-variable) (user-full-name custom-variable)) @@ -175,9 +179,10 @@ If the string contains the format spec \"%s\", the Newsgroups the article has been posted to will be inserted there. If this variable is nil, no such courtesy message will be added." :group 'message-sending - :type 'string) + :type '(radio (string :format "%t: %v\n" :size 0) (const nil))) -(defcustom message-ignored-bounced-headers "^\\(Received\\|Return-Path\\):" +(defcustom message-ignored-bounced-headers + "^\\(Received\\|Return-Path\\|Delivered-To\\):" "*Regexp that matches headers to be removed in resent bounced mail." :group 'message-interface :type 'regexp) @@ -190,7 +195,6 @@ If this variable is nil, no such courtesy message will be added." ;;; Start of variables adopted from `message-utils.el'. (defcustom message-subject-trailing-was-query 'ask - ;; should it default to nil or ask? "*What to do with trailing \"(was: )\" in subject lines. If nil, leave the subject unchanged. If it is the symbol `ask', query the user what do do. In this case, the subject is matched against @@ -201,6 +205,7 @@ used." :type '(choice (const :tag "never" nil) (const :tag "always strip" t) (const ask)) + :link '(custom-manual "(message)Message Headers") :group 'message-various) (defcustom message-subject-trailing-was-ask-regexp @@ -214,6 +219,7 @@ the variable is t instead of `ask', use It is okay to create some false positives here, as the user is asked." :group 'message-various + :link '(custom-manual "(message)Message Headers") :type 'regexp) (defcustom message-subject-trailing-was-regexp @@ -225,8 +231,11 @@ matched against `message-subject-trailing-was-regexp' in `message-strip-subject-trailing-was'. You should use a regexp creating very few false positives here." :group 'message-various + :link '(custom-manual "(message)Message Headers") :type 'regexp) +;; Fixme: Why are all these things autoloaded? + ;;; marking inserted text ;;;###autoload @@ -234,6 +243,7 @@ few false positives here." "--8<---------------cut here---------------start------------->8---\n" "How to mark the beginning of some inserted text." :type 'string + :link '(custom-manual "(message)Insertion Variables") :group 'message-various) ;;;###autoload @@ -241,14 +251,16 @@ few false positives here." "--8<---------------cut here---------------end--------------->8---\n" "How to mark the end of some inserted text." :type 'string + :link '(custom-manual "(message)Insertion Variables") :group 'message-various) ;;;###autoload (defcustom message-archive-header "X-No-Archive: Yes\n" "Header to insert when you don't want your article to be archived. -Archives \(such as groups.googgle.com\) respect this header." +Archives \(such as groups.google.com\) respect this header." :type 'string + :link '(custom-manual "(message)Header Commands") :group 'message-various) ;;;###autoload @@ -256,7 +268,9 @@ Archives \(such as groups.googgle.com\) respect this header." "X-No-Archive: Yes - save http://groups.google.com/" "Note to insert why you wouldn't want this posting archived. If nil, don't insert any text in the body." - :type 'string + :type '(radio (string :format "%t: %v\n" :size 0) + (const nil)) + :link '(custom-manual "(message)Header Commands") :group 'message-various) ;;; Crossposts and Followups @@ -342,7 +356,8 @@ Checks include `subject-cmsg', `multiple-headers', `sendsys', `approved', `sender', `empty', `empty-headers', `message-id', `from', `subject', `shorten-followup-to', `existing-newsgroups', `buffer-file-name', `unchanged', `newsgroups', `reply-to', -'continuation-headers', and `long-header-lines'." +`continuation-headers', `long-header-lines', `invisible-text' and +`illegible-text'." :group 'message-news :type '(repeat sexp)) ; Fixme: improve this @@ -353,12 +368,14 @@ Also see `message-required-news-headers' and `message-required-mail-headers'." :group 'message-news :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type '(repeat sexp)) (defcustom message-draft-headers '(References From) "*Headers to be generated when saving a draft message." :group 'message-news :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type '(repeat sexp)) (defcustom message-required-news-headers @@ -372,6 +389,7 @@ User-Agent are optional. If don't you want message to insert some header, remove it from this list." :group 'message-news :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type '(repeat sexp)) (defcustom message-required-mail-headers @@ -382,11 +400,13 @@ It is recommended that From, Date, To, Subject and Message-ID be included. Organization and User-Agent are optional." :group 'message-mail :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type '(repeat sexp)) (defcustom message-deletable-headers '(Message-ID Date Lines) "Headers to be deleted if they already exist and were generated by message previously." :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type 'sexp) (defcustom message-ignored-news-headers @@ -394,6 +414,7 @@ included. Organization and User-Agent are optional." "*Regexp of headers to be removed unconditionally before posting." :group 'message-news :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type 'regexp) (defcustom message-ignored-mail-headers @@ -401,13 +422,15 @@ included. Organization and User-Agent are optional." "*Regexp of headers to be removed unconditionally before mailing." :group 'message-mail :group 'message-headers + :link '(custom-manual "(message)Mail Headers") :type 'regexp) -(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|^X-Complaints-To:\\|^Cancel-Lock:\\|^Cancel-Key:\\|^X-Hashcash:" +(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|^X-Complaints-To:\\|^Cancel-Lock:\\|^Cancel-Key:\\|^X-Hashcash:\\|^X-Payment:" "*Header lines matching this regexp will be deleted before posting. It's best to delete old Path and Date headers before posting to avoid any confusion." :group 'message-interface + :link '(custom-manual "(message)Superseding") :type 'regexp) (defcustom message-supersede-setup-function @@ -420,6 +443,7 @@ any confusion." "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*" "*Regexp matching \"Re: \" in the subject line." :group 'message-various + :link '(custom-manual "(message)Message Headers") :type 'regexp) ;;; Some sender agents encode the whole subject including leading "Re: ". @@ -452,6 +476,7 @@ any confusion." Unlike `message-subject-re-regexp', this regexp matches \"Re: \" within an encoded-word." :group 'message-various + :link '(custom-manual "(message)Message Headers") :type 'regexp) (defcustom message-use-subject-re t @@ -467,6 +492,7 @@ is the symbol `guess', try to detect \"Re: \" within an encoded-word." (defcustom message-signature-separator "^-- *$" "Regexp matching the signature separator." :type 'regexp + :link '(custom-manual "(message)Various Message Variables") :group 'message-various) (defcustom message-signature-separator-for-insertion "-- \n" @@ -479,6 +505,7 @@ value may go against RFC-1036 and draft-ietf-usefor-article-05.txt. " (defcustom message-elide-ellipsis "\n[...]\n\n" "*The string which is inserted for elided text." :type 'string + :link '(custom-manual "(message)Insertion Variables") :group 'message-various) (defcustom message-interactive t @@ -486,6 +513,7 @@ value may go against RFC-1036 and draft-ietf-usefor-article-05.txt. " nil means let mailer mail back a message to report errors." :group 'message-sending :group 'message-mail + :link '(custom-manual "(message)Sending Variables") :type 'boolean) (defcustom message-generate-new-buffers 'unique @@ -494,6 +522,7 @@ If this is a function, call that function with three parameters: The type, the to address and the group name. (Any of these may be nil.) The function should return the new buffer name." :group 'message-buffers + :link '(custom-manual "(message)Message Buffers") :type '(choice (const :tag "off" nil) (const :tag "unique" unique) (const :tag "unsent" unsent) @@ -502,6 +531,7 @@ should return the new buffer name." (defcustom message-kill-buffer-on-exit nil "*Non-nil means that the message buffer will be killed after sending a message." :group 'message-buffers + :link '(custom-manual "(message)Message Buffers") :type 'boolean) (defcustom message-kill-buffer-query-function 'yes-or-no-p @@ -538,6 +568,7 @@ If t, use `message-user-organization-file'." (defcustom message-user-organization-file "/usr/lib/news/organization" "*Local news organization file." :type 'file + :link '(custom-manual "(message)News Headers") :group 'message-headers) (defcustom message-forward-start-separator @@ -559,49 +590,64 @@ If t, use `message-user-organization-file'." :type 'regexp) (defcustom message-make-forward-subject-function - 'message-forward-subject-name-subject + #'message-forward-subject-name-subject "*List of functions called to generate subject headers for forwarded messages. The subject generated by the previous function is passed into each successive function. The provided functions are: -* `message-forward-subject-author-subject' (Source of article (author or - newsgroup)), in brackets followed by the subject -* `message-forward-subject-name-subject' (Source of article (name of author - or newsgroup)), in brackets followed by the subject -* `message-forward-subject-fwd' (Subject of article with 'Fwd:' prepended +* `message-forward-subject-author-subject' Source of article (author or + newsgroup), in brackets followed by the subject +* `message-forward-subject-name-subject' Source of article (name of author + or newsgroup), in brackets followed by the subject +* `message-forward-subject-fwd' Subject of article with 'Fwd:' prepended to it." :group 'message-forwarding + :link '(custom-manual "(message)Forwarding") :type '(radio (function-item message-forward-subject-author-subject) (function-item message-forward-subject-fwd) + (function-item message-forward-subject-name-subject) (repeat :tag "List of functions" function))) (defcustom message-forward-as-mime t - "*If non-nil, forward messages as an inline/rfc822 MIME section. Otherwise, directly inline the old message in the forwarded message." + "*Non-nil means forward messages as an inline/rfc822 MIME section. +Otherwise, directly inline the old message in the forwarded message." :version "21.1" :group 'message-forwarding + :link '(custom-manual "(message)Forwarding") :type 'boolean) -(defcustom message-forward-show-mml t - "*If non-nil, forward messages are shown as mml. Otherwise, forward messages are unchanged." +(defcustom message-forward-show-mml 'best + "*Non-nil means show forwarded messages as MML (decoded from MIME). +Otherwise, forwarded messages are unchanged. +Can also be the symbol `best' to indicate that MML should be +used, except when it is a bad idea to use MML. One example where +it is a bad idea is when forwarding a signed or encrypted +message, because converting MIME to MML would invalidate the +digital signature." :version "21.1" :group 'message-forwarding - :type 'boolean) + :type '(choice (const :tag "use MML" t) + (const :tag "don't use MML " nil) + (const :tag "use MML when appropriate" best))) (defcustom message-forward-before-signature t - "*If non-nil, put forwarded message before signature, else after." + "*Non-nil means put forwarded message before signature, else after." :group 'message-forwarding :type 'boolean) (defcustom message-wash-forwarded-subjects nil - "*If non-nil, try to remove as much old cruft as possible from the subject of messages before generating the new subject of a forward." + "*Non-nil means try to remove as much cruft as possible from the subject. +Done before generating the new subject of a forward." :group 'message-forwarding + :link '(custom-manual "(message)Forwarding") :type 'boolean) (defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From " "*All headers that match this regexp will be deleted when resending a message." :group 'message-interface + :link '(custom-manual "(message)Resending") :type 'regexp) (defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus" @@ -614,6 +660,7 @@ The provided functions are: (defcustom message-ignored-cited-headers "." "*Delete these headers from the messages you yank." :group 'message-insertion + :link '(custom-manual "(message)Insertion Variables") :type 'regexp) (defcustom message-cite-prefix-regexp @@ -636,11 +683,13 @@ The provided functions are: "]\\)+>+\\|[ \t]*[]>|}+]\\)+")))) "*Regexp matching the longest possible citation prefix on a line." :group 'message-insertion + :link '(custom-manual "(message)Insertion Variables") :type 'regexp) (defcustom message-cancel-message "I am canceling my own article.\n" "Message to be inserted in the cancel message." :group 'message-interface + :link '(custom-manual "(message)Canceling News") :type 'string) ;; Useful to set in site-init.el @@ -665,6 +714,7 @@ See also `send-mail-function'." (function-item feedmail-send-it) (function :tag "Other")) :group 'message-sending + :link '(custom-manual "(message)Mail Variables") :group 'message-mail) ;; 1997-09-29 by MORIOKA Tomohiko @@ -674,6 +724,7 @@ The headers should be delimited by a line whose contents match the variable `mail-header-separator'." :group 'message-sending :group 'message-news + :link '(custom-manual "(message)News Variables") :type 'function) (defcustom message-reply-to-function nil @@ -681,6 +732,7 @@ variable `mail-header-separator'." This function should pick out addresses from the To, Cc, and From headers and respond with new To and Cc headers." :group 'message-interface + :link '(custom-manual "(message)Reply") :type '(choice function (const nil))) (defcustom message-wide-reply-to-function nil @@ -688,6 +740,7 @@ and respond with new To and Cc headers." This function should pick out addresses from the To, Cc, and From headers and respond with new To and Cc headers." :group 'message-interface + :link '(custom-manual "(message)Wide Reply") :type '(choice function (const nil))) (defcustom message-followup-to-function nil @@ -695,6 +748,7 @@ and respond with new To and Cc headers." This function should pick out addresses from the To, Cc, and From headers and respond with new To and Cc headers." :group 'message-interface + :link '(custom-manual "(message)Followup") :type '(choice function (const nil))) (defcustom message-use-followup-to 'ask @@ -704,6 +758,7 @@ query before using the \"poster\" value. If it is the symbol `ask', always query the user whether to use the value. If it is the symbol `use', always use the value." :group 'message-interface + :link '(custom-manual "(message)Followup") :type '(choice (const :tag "ignore" nil) (const :tag "use & query" t) (const :tag "maybe" t) @@ -717,6 +772,7 @@ query before using the value other than \"always\" or \"never\". If it is the symbol `ask', always query the user whether to use the value. If it is the symbol `use', always use the value." :group 'message-interface + :link '(custom-manual "(message)Mailing Lists") :type '(choice (const :tag "ignore" nil) (const :tag "maybe" t) (const :tag "always" use) @@ -748,12 +804,13 @@ query the user whether to use the value. If it is t or the symbol (defcustom message-subscribed-address-functions nil "*Specifies functions for determining list subscription. -If nil, do not attempt to determine list subscribtion with functions. +If nil, do not attempt to determine list subscription with functions. If non-nil, this variable contains a list of functions which return regular expressions to match lists. These functions can be used in conjunction with `message-subscribed-regexps' and `message-subscribed-addresses'." :group 'message-interface + :link '(custom-manual "(message)Mailing Lists") :type '(repeat sexp)) (defcustom message-subscribed-address-file nil @@ -761,22 +818,26 @@ conjunction with `message-subscribed-regexps' and If nil, do not look at any files to determine list subscriptions. If non-nil, each line of this file should be a mailing list address." :group 'message-interface - :type 'string) + :link '(custom-manual "(message)Mailing Lists") + :type '(radio (file :format "%t: %v\n" :size 0) + (const nil))) (defcustom message-subscribed-addresses nil "*Specifies a list of addresses the user is subscribed to. If nil, do not use any predefined list subscriptions. This list of -addresses can be used in conjuction with +addresses can be used in conjunction with `message-subscribed-address-functions' and `message-subscribed-regexps'." :group 'message-interface + :link '(custom-manual "(message)Mailing Lists") :type '(repeat string)) (defcustom message-subscribed-regexps nil "*Specifies a list of addresses the user is subscribed to. If nil, do not use any predefined list subscriptions. This list of -regular expressions can be used in conjuction with +regular expressions can be used in conjunction with `message-subscribed-address-functions' and `message-subscribed-addresses'." :group 'message-interface + :link '(custom-manual "(message)Mailing Lists") :type '(repeat regexp)) (defcustom message-allow-no-recipients 'ask @@ -785,6 +846,7 @@ If it is the symbol `always', the posting is allowed. If it is the symbol `never', the posting is not allowed. If it is the symbol `ask', you are prompted." :group 'message-interface + :link '(custom-manual "(message)Message Headers") :type '(choice (const always) (const never) (const ask))) @@ -793,6 +855,7 @@ symbol `never', the posting is not allowed. If it is the symbol "*Non-nil means don't add \"-f username\" to the sendmail command line. Doing so would be even more evil than leaving it out." :group 'message-sending + :link '(custom-manual "(message)Mail Variables") :type 'boolean) (defcustom message-sendmail-envelope-from nil @@ -802,12 +865,14 @@ If this is nil, use `user-mail-address'. If it is the symbol :type '(choice (string :tag "From name") (const :tag "Use From: header from message" header) (const :tag "Use `user-mail-address'" nil)) + :link '(custom-manual "(message)Mail Variables") :group 'message-sending) ;; qmail-related stuff (defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject" "Location of the qmail-inject program." :group 'message-sending + :link '(custom-manual "(message)Mail Variables") :type 'file) (defcustom message-qmail-inject-args nil @@ -819,6 +884,7 @@ For e.g., if you wish to set the envelope sender address so that bounces go to the right place or to deal with listserv's usage of that address, you might set this variable to '(\"-f\" \"you@some.where\")." :group 'message-sending + :link '(custom-manual "(message)Mail Variables") :type '(choice (function) (repeat string))) @@ -852,16 +918,16 @@ variable isn't used." ;; will *not* have a `References:' header if `message-generate-headers-first' ;; is nil. See: http://article.gmane.org/gmane.emacs.gnus.general/51138 (defcustom message-generate-headers-first '(references) - "*If non-nil, generate all required headers before composing. -The variables `message-required-news-headers' and + "Which headers should be generated before starting to compose a message. +If `t', generate all required headers. This can also be a list of headers to +generate. The variables `message-required-news-headers' and `message-required-mail-headers' specify which headers to generate. -This can also be a list of headers that should be generated before -composing. Note that the variable `message-deletable-headers' specifies headers which are to be deleted and then re-generated before sending, so this variable will not have a visible effect for those headers." :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type '(choice (const :tag "None" nil) (const :tag "References" '(references)) (const :tag "All" t) @@ -871,11 +937,13 @@ will not have a visible effect for those headers." "Normal hook, run each time a new outgoing message is initialized. The function `message-setup' runs this hook." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-cancel-hook nil "Hook run when cancelling articles." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-signature-setup-hook nil @@ -883,6 +951,7 @@ The function `message-setup' runs this hook." It is run after the headers have been inserted and before the signature is inserted." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-bounce-setup-hook nil @@ -910,6 +979,7 @@ The function `message-supersede' runs this hook." (defcustom message-header-setup-hook nil "Hook called narrowed to the headers when setting up a message buffer." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-minibuffer-local-map @@ -927,6 +997,7 @@ Note that Gnus provides a feature where the reader can click on people who read your message will have to change their Gnus configuration. See the variable `gnus-cite-attribution-suffix'." :type 'function + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) ;;;###autoload @@ -935,6 +1006,7 @@ configuration. See the variable `gnus-cite-attribution-suffix'." Fix `message-cite-prefix-regexp' if it is set to an abnormal value. See also `message-yank-cited-prefix'." :type 'string + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) (defcustom message-yank-add-new-references t @@ -960,12 +1032,14 @@ an article is yanked by the command `message-yank-original' interactively." Fix `message-cite-prefix-regexp' if it is set to an abnormal value. See also `message-yank-prefix'." :type 'string + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) (defcustom message-indentation-spaces 3 "*Number of spaces to insert at the beginning of each cited line. Used by `message-yank-original' via `message-yank-cite'." :group 'message-insertion + :link '(custom-manual "(message)Insertion Variables") :type 'integer) ;;;###autoload @@ -979,6 +1053,7 @@ Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil." (function-item mu-cite-original) (function-item sc-cite-original) (function :tag "Other")) + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) ;;;###autoload @@ -999,6 +1074,7 @@ This can also be a list of functions. Each function can find the citation between (point) and (mark t). And each function should leave point and mark around the citation text as modified." :type 'function + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) ;;;###autoload @@ -1008,6 +1084,7 @@ If t, the `message-signature-file' file will be inserted instead. If a function, the result from the function will be used instead. If a form, the result from the form will be used instead." :type 'sexp + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) ;;;###autoload @@ -1016,18 +1093,21 @@ If a form, the result from the form will be used instead." Ignored if the named file doesn't exist. If nil, don't insert a signature." :type '(choice file (const :tags "None" nil)) + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) ;;;###autoload (defcustom message-signature-insert-empty-line t "*If non-nil, insert an empty line before the signature separator." :type 'boolean + :link '(custom-manual "(message)Insertion Variables") :group 'message-insertion) (defcustom message-distribution-function nil "*Function called to return a Distribution header." :group 'message-news :group 'message-headers + :link '(custom-manual "(message)News Headers") :type '(choice function (const nil))) (defcustom message-expires 14 @@ -1077,18 +1157,21 @@ It is a vector of the following headers: It is inserted before you edit the message, so you can edit or delete these lines." :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type 'message-header-lines) (defcustom message-default-mail-headers "" "*A string of header lines to be inserted in outgoing mails." :group 'message-headers :group 'message-mail + :link '(custom-manual "(message)Mail Headers") :type 'message-header-lines) (defcustom message-default-news-headers "" "*A string of header lines to be inserted in outgoing news articles." :group 'message-headers :group 'message-news + :link '(custom-manual "(message)News Headers") :type 'message-header-lines) ;; Note: could use /usr/ucb/mail instead of sendmail; @@ -1116,6 +1199,7 @@ these lines." The value should be an expression to test whether the problem will actually occur." :group 'message-sending + :link '(custom-manual "(message)Mail Variables") :type 'sexp) ;;; XXX: This symbol is overloaded! See below. @@ -1161,6 +1245,7 @@ mail aliases off." "*Directory where Message auto-saves buffers if Gnus isn't running. If nil, Message won't auto-save." :group 'message-buffers + :link '(custom-manual "(message)Various Message Variables") :type '(choice directory (const :tag "Don't auto-save" nil))) (defcustom message-default-charset @@ -1168,6 +1253,7 @@ If nil, Message won't auto-save." "Default charset used in non-MULE XEmacsen." :version "21.1" :group 'message + :link '(custom-manual "(message)Various Message Variables") :type 'symbol) (defcustom message-dont-reply-to-names @@ -1176,6 +1262,7 @@ If nil, Message won't auto-save." A value of nil means exclude your own user name only." :version "21.1" :group 'message + :link '(custom-manual "(message)Wide Reply") :type '(choice (const :tag "Yourself" nil) regexp)) @@ -1198,8 +1285,9 @@ candidates: (defcustom message-hidden-headers nil "Regexp of headers to be hidden when composing new messages. This can also be a list of regexps to match headers. Or a list -starting with `not' and followed by regexps.." +starting with `not' and followed by regexps." :group 'message + :link '(custom-manual "(message)Message Headers") :type '(repeat regexp)) ;;; Internal variables. @@ -1413,6 +1501,7 @@ The cdr of each entry is a function for applying the face to a region.") This hook is run quite early when sending." :group 'message-various :options '(ispell-message) + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-send-mail-hook nil @@ -1420,6 +1509,7 @@ This hook is run quite early when sending." This hook is run very late -- just before the message is sent as mail." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-send-news-hook nil @@ -1427,6 +1517,7 @@ mail." This hook is run very late -- just before the message is sent as news." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'hook) (defcustom message-sent-hook nil @@ -1459,6 +1550,7 @@ The lower bound of message size in characters, beyond which the message should be sent in several parts. If it is nil, the size is unlimited." :version "21.1" :group 'message-buffers + :link '(custom-manual "(message)Mail Variables") :type '(choice (const :tag "unlimited" nil) (integer 1000000))) @@ -1466,6 +1558,7 @@ should be sent in several parts. If it is nil, the size is unlimited." "A regexp to match the alternative email addresses. The first matched address (not primary one) is used in the From field." :group 'message-headers + :link '(custom-manual "(message)Message Headers") :type '(choice (const :tag "Always use primary" nil) regexp)) @@ -1511,21 +1604,24 @@ answers yes, reply to all recipients as usual. If the user answers no, only reply back to the author." :version "21.3" :group 'message-headers + :link '(custom-manual "(message)Wide Reply") :type 'boolean) (defcustom message-user-fqdn nil "*Domain part of Messsage-Ids." :group 'message-headers :link '(custom-manual "(message)News Headers") - :type 'string) + :type '(radio (const :format "%v " nil) + (string :format "FQDN: %v\n" :size 0))) (defcustom message-use-idna (and (condition-case nil (require 'idna) (file-error)) - (fboundp 'coding-system-p) - (coding-system-p 'utf-8) + (mm-coding-system-p 'utf-8) + (executable-find idna-program) 'ask) "Whether to encode non-ASCII in domain names into ASCII according to IDNA." :group 'message-headers + :link '(custom-manual "(message)IDNA") :type '(choice (const :tag "Ask" ask) (const :tag "Never" nil) (const :tag "Always" t))) @@ -1539,6 +1635,7 @@ no, only reply back to the author." (defvar message-draft-article nil) (defvar message-mime-part nil) (defvar message-posting-charset nil) +(defvar message-inserted-headers nil) ;; Byte-compiler warning (eval-when-compile @@ -1672,6 +1769,9 @@ no, only reply back to the author." (autoload 'rmail-output "rmailout") (autoload 'gnus-delay-article "gnus-delay") (autoload 'gnus-make-local-hook "gnus-util") + (autoload 'gnus-extract-address-components "gnus-util")) + +(eval-and-compile (autoload 'mu-cite-original "mu-cite")) @@ -1728,8 +1828,8 @@ is used by default." (beg 1) (first t) quoted elems paren) - (save-excursion - (message-set-work-buffer) + (with-temp-buffer + (set-buffer-multibyte t) (insert header) (goto-char (point-min)) (while (not (eobp)) @@ -1764,7 +1864,9 @@ is used by default." (looking-at message-unix-mail-delimiter)))) (defun message-fetch-field (header &optional not-all) - "The same as `mail-fetch-field', only remove all newlines." + "The same as `mail-fetch-field', only remove all newlines. +The buffer is expected to be narrowed to just the header of the message; +see `message-narrow-to-headers-or-head'." (let* ((inhibit-point-motion-hooks t) (case-fold-search t) (value (mail-fetch-field header nil (not not-all)))) @@ -1774,6 +1876,13 @@ is used by default." (set-text-properties 0 (length value) nil value) value))) +(defun message-field-value (header &optional not-all) + "The same as `message-fetch-field', only narrow to the headers first." + (save-excursion + (save-restriction + (message-narrow-to-headers-or-head) + (message-fetch-field header not-all)))) + (defun message-narrow-to-field () "Narrow the buffer to the header on the current line." (beginning-of-line) @@ -1823,20 +1932,6 @@ is used by default." (mail-narrow-to-head) (message-fetch-field header)))) -(defun message-set-work-buffer () - (if (get-buffer " *message work*") - (progn - (set-buffer " *message work*") - (erase-buffer)) - (set-buffer (get-buffer-create " *message work*")) - (kill-all-local-variables))) - -(defun message-functionp (form) - "Return non-nil if FORM is funcallable." - (or (and (symbolp form) (fboundp form)) - (and (listp form) (eq (car form) 'lambda)) - (byte-code-function-p form))) - (defun message-strip-list-identifiers (subject) "Remove list identifiers in `gnus-list-identifiers' from string SUBJECT." (require 'gnus-sum) ; for gnus-list-identifiers @@ -1897,6 +1992,7 @@ Leading \"Re: \" is not stripped by this function. Use the function ;;;###autoload (defun message-change-subject (new-subject) "Ask for NEW-SUBJECT header, append (was: )." + ;; (interactive (list (read-from-minibuffer "New subject: "))) @@ -1904,7 +2000,10 @@ Leading \"Re: \" is not stripped by this function. Use the function (zerop (string-width new-subject)) (string-match "^[ \t]*$" new-subject)))) (save-excursion - (let ((old-subject (message-fetch-field "Subject"))) + (let ((old-subject + (save-restriction + (message-narrow-to-headers) + (message-fetch-field "Subject")))) (cond ((not old-subject) (error "No current subject")) ((not (string-match @@ -1928,7 +2027,7 @@ Leading \"Re: \" is not stripped by this function. Use the function See `message-mark-insert-begin' and `message-mark-insert-end'." (interactive "r") (save-excursion - ; add to the end of the region first, otherwise end would be invalid + ;; add to the end of the region first, otherwise end would be invalid (goto-char end) (insert message-mark-insert-end) (goto-char beg) @@ -2090,19 +2189,26 @@ With prefix-argument just set Follow-Up, don't cross-post." (defun message-reduce-to-to-cc () "Replace contents of To: header with contents of Cc: or Bcc: header." (interactive) - (let ((cc-content (message-fetch-field "cc")) + (let ((cc-content + (save-restriction (message-narrow-to-headers) + (message-fetch-field "cc"))) (bcc nil)) (if (and (not cc-content) - (setq cc-content (message-fetch-field "bcc"))) + (setq cc-content + (save-restriction + (message-narrow-to-headers) + (message-fetch-field "bcc")))) (setq bcc t)) (cond (cc-content (save-excursion (message-goto-to) (message-delete-line) (insert (concat "To: " cc-content "\n")) - (message-remove-header (if bcc - "bcc" - "cc"))))))) + (save-restriction + (message-narrow-to-headers) + (message-remove-header (if bcc + "bcc" + "cc")))))))) ;;; End of functions adopted from `message-utils.el'. @@ -2401,9 +2507,6 @@ Point is left at the beginning of the narrowed-to region." (easy-menu-define message-mode-field-menu message-mode-map "" `("Field" - ["Fetch To" message-insert-to t] - ["Fetch Newsgroups" message-insert-newsgroups t] - "----" ["To" message-goto-to t] ["From" message-goto-from t] ["Subject" message-goto-subject t] @@ -2427,6 +2530,7 @@ Point is left at the beginning of the narrowed-to region." ["Summary" message-goto-summary t] ["Keywords" message-goto-keywords t] ["Newsgroups" message-goto-newsgroups t] + ["Fetch Newsgroups" message-insert-newsgroups t] ["Followup-To" message-goto-followup-to t] ;; ["Followup-To (with note in body)" message-cross-post-followup-to t] ["Crosspost / Followup-To..." message-cross-post-followup-to t] @@ -2434,10 +2538,21 @@ Point is left at the beginning of the narrowed-to region." ["X-No-Archive:" message-add-archive-header t ] "----" ;; (typical) mailing-lists stuff + ["Fetch To" message-insert-to + ,@(if (featurep 'xemacs) '(t) + '(:help "Insert a To header that points to the author."))] + ["Fetch To and Cc" message-insert-wide-reply + ,@(if (featurep 'xemacs) '(t) + '(:help + "Insert To and Cc headers as if you were doing a wide reply."))] + "----" ["Send to list only" message-to-list-only t] ["Mail-Followup-To" message-goto-mail-followup-to t] ["Mail-Reply-To" message-goto-mail-reply-to t] ["Mail-Copies-To" message-goto-mail-copies-to t] + ["Unsubscribed list post" message-generate-unsubscribed-mail-followup-to + ,@(if (featurep 'xemacs) '(t) + '(:help "Insert a reasonable `Mail-Followup-To:' header."))] ["Reduce To: to Cc:" message-reduce-to-to-cc t] "----" ["Sort Headers" message-sort-headers t] @@ -2467,6 +2582,7 @@ packages requires these properties to be present in order to work. If you use one of these packages, turn this option off, and hope the message composition doesn't break too bad." :group 'message-various + :link '(custom-manual "(message)Various Message Variables") :type 'boolean) (defconst message-forbidden-properties @@ -2552,11 +2668,12 @@ C-c M-f `message-mark-insert-file' (insert file marked with enclosing tags). M-RET `message-newline-and-reformat' (break the line and reformat)." (setq local-abbrev-table text-mode-abbrev-table) (set (make-local-variable 'message-reply-buffer) nil) - (make-local-variable 'message-send-actions) - (make-local-variable 'message-exit-actions) - (make-local-variable 'message-kill-actions) - (make-local-variable 'message-postpone-actions) - (make-local-variable 'message-draft-article) + (set (make-local-variable 'message-inserted-headers) nil) + (set (make-local-variable 'message-send-actions) nil) + (set (make-local-variable 'message-exit-actions) nil) + (set (make-local-variable 'message-kill-actions) nil) + (set (make-local-variable 'message-postpone-actions) nil) + (set (make-local-variable 'message-draft-article) nil) (setq buffer-offer-save t) (set (make-local-variable 'facemenu-add-face-function) (lambda (face end) @@ -2598,7 +2715,8 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (when (eq message-mail-alias-type 'abbrev) (if (fboundp 'mail-abbrevs-setup) (mail-abbrevs-setup) - (mail-aliases-setup))) + (if (fboundp 'mail-aliases-setup) ; warning avoidance + (mail-aliases-setup)))) (unless buffer-file-name (message-set-auto-save-file-name)) (set (make-local-variable 'indent-tabs-mode) nil)) ;No tabs for indentation. @@ -2782,11 +2900,14 @@ If the optional argument INCLUDE-CC is non-nil, the addresses in the Cc: header are also put into the MFT." (interactive "P") - (message-remove-header "Mail-Followup-To") - (let* ((cc (and include-cc (message-fetch-field "Cc"))) - (tos (if cc - (concat (message-fetch-field "To") "," cc) - (message-fetch-field "To")))) + (let* (cc tos) + (save-restriction + (message-narrow-to-headers) + (message-remove-header "Mail-Followup-To") + (setq cc (and include-cc (message-fetch-field "Cc"))) + (setq tos (if cc + (concat (message-fetch-field "To") "," cc) + (message-fetch-field "To")))) (message-goto-mail-followup-to) (insert (concat tos ", " user-mail-address)))) @@ -2794,22 +2915,24 @@ Cc: header are also put into the MFT." (defun message-insert-to (&optional force) "Insert a To header that points to the author of the article being replied to. -If the original author requested not to be sent mail, the function signals -an error. -With the prefix argument FORCE, insert the header anyway." +If the original author requested not to be sent mail, don't insert unless the +prefix FORCE is given." (interactive "P") - (let ((co (message-fetch-reply-field "mail-copies-to"))) - (when (and (null force) - co - (or (equal (downcase co) "never") - (equal (downcase co) "nobody"))) - (error "The user has requested not to have copies sent via mail"))) - (message-carefully-insert-headers - (list (cons 'To - (or (message-fetch-reply-field "mail-reply-to") - (message-fetch-reply-field "reply-to") - (message-fetch-reply-field "from") - ""))))) + (let* ((mct (message-fetch-reply-field "mail-copies-to")) + (dont (and mct (or (equal (downcase mct) "never") + (equal (downcase mct) "nobody")))) + (to (or (message-fetch-reply-field "mail-reply-to") + (message-fetch-reply-field "reply-to") + (message-fetch-reply-field "from")))) + (when (and dont to) + (message + (if force + "Ignoring the user request not to have copies sent via mail" + "Complying with the user request not to have copies sent via mail"))) + (when (and force (not to)) + (error "No mail address in the article")) + (when (and to (or force (not dont))) + (message-carefully-insert-headers (list (cons 'To to)))))) (defun message-insert-wide-reply () "Insert To and Cc headers as if you were doing a wide reply." @@ -2818,15 +2941,40 @@ With the prefix argument FORCE, insert the header anyway." (message-get-reply-headers t)))) (message-carefully-insert-headers headers))) +(defcustom message-header-synonyms + '((To Cc Bcc)) + "List of lists of header synonyms. +E.g., if this list contains a member list with elements `Cc' and `To', +then `message-carefully-insert-headers' will not insert a `To' header +when the message is already `Cc'ed to the recipient." + :group 'message-headers + :link '(custom-manual "(message)Message Headers") + :type '(repeat sexp)) + (defun message-carefully-insert-headers (headers) + "Insert the HEADERS, an alist, into the message buffer. +Does not insert the headers when they are already present there +or in the synonym headers, defined by `message-header-synonyms'." + ;; FIXME: Should compare only the address and not the full name. Comparison + ;; should be done case-folded (and with `string=' rather than + ;; `string-match'). (dolist (header headers) - (let ((header-name (symbol-name (car header)))) - (when (and (message-position-on-field header-name) - (mail-fetch-field header-name) - (not (string-match "\\` *\\'" - (mail-fetch-field header-name)))) - (insert ", ")) - (insert (cdr header))))) + (let* ((header-name (symbol-name (car header))) + (new-header (cdr header)) + (synonyms (loop for synonym in message-header-synonyms + when (memq (car header) synonym) return synonym)) + (old-header + (loop for synonym in synonyms + for old-header = (mail-fetch-field (symbol-name synonym)) + when (and old-header (string-match new-header old-header)) + return synonym))) + (if old-header + (message "already have `%s' in `%s'" new-header old-header) + (when (and (message-position-on-field header-name) + (setq old-header (mail-fetch-field header-name)) + (not (string-match "\\` *\\'" old-header))) + (insert ", ")) + (insert new-header))))) (defun message-widen-reply () "Widen the reply to include maximum recipients." @@ -2890,7 +3038,7 @@ With the prefix argument FORCE, insert the header anyway." (let ((point (point))) (message-goto-signature) (unless (eobp) - (forward-line -2)) + (end-of-line -1)) (kill-region point (point)) (unless (bolp) (insert "\n")))) @@ -2986,7 +3134,7 @@ Prefix arg means justify as well." (defun message-fill-paragraph (&optional arg) "Like `fill-paragraph'." (interactive (list (if current-prefix-arg 'full))) - (if (and (boundp 'filladapt-mode) filladapt-mode) + (if (if (boundp 'filladapt-mode) filladapt-mode) nil (message-newline-and-reformat arg t) t)) @@ -3019,7 +3167,7 @@ Prefix arg means justify as well." ((and (null message-signature) force) t) - ((message-functionp message-signature) + ((functionp message-signature) (funcall message-signature)) ((listp message-signature) (eval message-signature)) @@ -3051,7 +3199,9 @@ Prefix arg means justify as well." "Insert header to mark message as important." (interactive) (save-excursion - (message-remove-header "Importance") + (save-restriction + (message-narrow-to-headers) + (message-remove-header "Importance")) (message-goto-eoh) (insert "Importance: high\n"))) @@ -3059,7 +3209,9 @@ Prefix arg means justify as well." "Insert header to mark message as unimportant." (interactive) (save-excursion - (message-remove-header "Importance") + (save-restriction + (message-narrow-to-headers) + (message-remove-header "Importance")) (message-goto-eoh) (insert "Importance: low\n"))) @@ -3072,14 +3224,16 @@ and `low'." (let ((valid '("high" "normal" "low")) (new "high") cur) - (when (setq cur (message-fetch-field "Importance")) - (message-remove-header "Importance") - (setq new (cond ((string= cur "high") - "low") - ((string= cur "low") - "normal") - (t - "high")))) + (save-restriction + (message-narrow-to-headers) + (when (setq cur (message-fetch-field "Importance")) + (message-remove-header "Importance") + (setq new (cond ((string= cur "high") + "low") + ((string= cur "low") + "normal") + (t + "high"))))) (message-goto-eoh) (insert (format "Importance: %s\n" new))))) @@ -3088,10 +3242,14 @@ and `low'." Note that this should not be used in newsgroups." (interactive) (save-excursion - (message-remove-header "Disposition-Notification-To") + (save-restriction + (message-narrow-to-headers) + (message-remove-header "Disposition-Notification-To")) (message-goto-eoh) (insert (format "Disposition-Notification-To: %s\n" - (or (message-fetch-field "From") (message-make-from)))))) + (or (message-field-value "Reply-to") + (message-field-value "From") + (message-make-from)))))) (defun message-elide-region (b e) "Elide the text in the region. @@ -3319,8 +3477,9 @@ be added to the \"References\" field." refs) ;; If the References field has been changed, we make it ;; visible in the header. - (mail-header-set-message-id message-reply-headers nil) - (mail-header-set-references message-reply-headers nil) + (when message-reply-headers + (mail-header-set-message-id message-reply-headers nil) + (mail-header-set-references message-reply-headers nil)) (widen) (message-narrow-to-headers) (if (let ((case-fold-search t)) @@ -3354,7 +3513,7 @@ be added to the \"References\" field." (defun message-yank-buffer (buffer) "Insert BUFFER into the current buffer and quote it." (interactive "bYank buffer: ") - (let ((message-reply-buffer buffer)) + (let ((message-reply-buffer (get-buffer buffer))) (save-window-excursion (message-yank-original)))) @@ -3656,7 +3815,7 @@ It should typically alter the sending method in some way or other." (when (and (or (not (memq (car elem) message-sent-message-via)) - (not (message-fetch-field "supersedes")) + (message-fetch-field "supersedes") (if (or (message-gnksa-enable-p 'multiple-copies) (not (eq (car elem) 'news))) (y-or-n-p @@ -3762,9 +3921,12 @@ used to distinguish whether the invisible text is a MIME part or not." (dolist (point points) (add-text-properties point (1+ point) '(invisible nil intangible nil))))) - ;; Delete all invisible text except for the mime parts which might - ;; be inserted by the MIME-Edit. + ;; Make invisible text visible except for mime parts which may be + ;; inserted by the MIME-Edit. + ;; It doesn't seem as if this is useful, since the invisible property + ;; is clobbered by an after-change hook anyhow. (message-check 'invisible-text + ;; FIXME T-gnus: It should also detect invisible overlays. (let (from (to (point-min)) mime-from mime-to hidden-start) @@ -3791,52 +3953,61 @@ used to distinguish whether the invisible text is a MIME part or not." (goto-char hidden-start) (set-window-start (selected-window) (gnus-point-at-bol)) (unless (yes-or-no-p - "Invisible text found and made visible; continue posting? ") + "Invisible text found and made visible; continue sending? ") (error "Invisible text found and made visible"))))) - (message-check 'illegible-text - (let ((mm-7bit-chars "\x20-\x7f\r\n\t\x7\x8\xb\xc\x1f\x1b") - found choice) - (message-goto-body) - (skip-chars-forward mm-7bit-chars) - (while (not (eobp)) - (when (let ((char (char-after))) - (or (< (mm-char-int char) 128) - (and (mm-multibyte-p) - (memq (char-charset char) - '(eight-bit-control eight-bit-graphic - control-1))))) - (add-text-properties (point) (1+ (point)) - '(font-lock-face highlight face highlight)) - (setq found t)) - (forward-char) - (skip-chars-forward mm-7bit-chars)) - (when found - (setq choice - (gnus-multiple-choice - "Illegible text found. Continue posting?" - '((?d "Remove and continue posting") - (?r "Replace with dots and continue posting") - (?i "Ignore and continue posting") - (?e "Continue editing")))) - (if (eq choice ?e) - (error "Illegible text found")) - (message-goto-body) - (skip-chars-forward mm-7bit-chars) - (while (not (eobp)) - (when (let ((char (char-after))) - (or (< (mm-char-int char) 128) - (and (mm-multibyte-p) - (memq (char-charset char) - '(eight-bit-control eight-bit-graphic - control-1))))) - (if (eq choice ?i) - (remove-text-properties (point) (1+ (point)) - '(font-lock-face highlight face highlight)) - (delete-char 1) - (when (eq choice ?r) - (insert ".")))) - (forward-char) - (skip-chars-forward mm-7bit-chars)))))) +;; The following check is needless to T-gnus since T-gnus determines +;; a MIME charset forcibly (even if it cannot be determined properly, +;; the value of the `default-mime-charset-for-write' variable is used). +;; (message-check 'illegible-text +;; (let (found choice) +;; (message-goto-body) +;; (skip-chars-forward mm-7bit-chars) +;; (while (not (eobp)) +;; (when (let ((char (char-after))) +;; (or (< (mm-char-int char) 128) +;; (and (mm-multibyte-p) +;; (memq (char-charset char) +;; '(eight-bit-control eight-bit-graphic +;; control-1)) +;; (not (get-text-property +;; (point) 'untranslated-utf-8))))) +;; (message-overlay-put (message-make-overlay (point) (1+ (point))) +;; 'face 'highlight) +;; (setq found t)) +;; (forward-char) +;; (skip-chars-forward mm-7bit-chars)) +;; (when found +;; (setq choice +;; (gnus-multiple-choice +;; "Non-printable characters found. Continue sending?" +;; '((?d "Remove non-printable characters and send") +;; (?r "Replace non-printable characters with dots and send") +;; (?i "Ignore non-printable characters and send") +;; (?e "Continue editing")))) +;; (if (eq choice ?e) +;; (error "Non-printable characters")) +;; (message-goto-body) +;; (skip-chars-forward mm-7bit-chars) +;; (while (not (eobp)) +;; (when (let ((char (char-after))) +;; (or (< (mm-char-int char) 128) +;; (and (mm-multibyte-p) +;; ;; Fixme: Wrong for Emacs 22 and for things +;; ;; like undecable utf-8. Should at least +;; ;; use find-coding-systems-region. +;; (memq (char-charset char) +;; '(eight-bit-control eight-bit-graphic +;; control-1)) +;; (not (get-text-property +;; (point) 'untranslated-utf-8))))) +;; (if (eq choice ?i) +;; (message-kill-all-overlays) +;; (delete-char 1) +;; (when (eq choice ?r) +;; (insert ".")))) +;; (forward-char) +;; (skip-chars-forward mm-7bit-chars))))) + ) (defun message-add-action (action &rest types) "Add ACTION to be performed when doing an exit of type TYPES." @@ -3858,7 +4029,7 @@ used to distinguish whether the invisible text is a MIME part or not." (ignore-errors (cond ;; A simple function. - ((message-functionp (car actions)) + ((functionp (car actions)) (funcall (car actions))) ;; Something to be evaled. (t @@ -4033,6 +4204,9 @@ This sub function is for exclusive use of `message-send-mail'." (or (= (preceding-char) ?\n) (insert ?\n)) (message-cleanup-headers) + ;; FIXME: we're inserting the courtesy copy after encoding. + ;; This is wrong if the courtesy copy string contains + ;; non-ASCII characters. -- jh (when (save-restriction (message-narrow-to-headers) @@ -4040,10 +4214,16 @@ This sub function is for exclusive use of `message-send-mail'." (or (message-fetch-field "cc") (message-fetch-field "bcc") (message-fetch-field "to")) - (let ((ct (mime-read-Content-Type))) - (or (not ct) - (and (eq 'text (cdr (assq 'type ct))) - (eq 'plain (cdr (assq 'subtype ct)))))))) + (let ((content-type (mime-read-Content-Type))) + (and + (or + (not content-type) + (and + (eq 'text (cdr (assq 'type content-type))) + (eq 'plain (cdr (assq 'subtype content-type))))) + (not + (string= "base64" + (mime-read-Content-Transfer-Encoding))))))) (message-insert-courtesy-copy)) (setq failure (message-maybe-split-and-send-mail))) (kill-buffer tembuf)) @@ -4111,7 +4291,7 @@ This sub function is for exclusive use of `message-send-mail'." (if resend-to-addresses (list resend-to-addresses) '("-t"))))))) - (unless (or (null cpr) (zerop cpr)) + (unless (or (null cpr) (and (numberp cpr) (zerop cpr))) (error "Sending...failed with exit value %d" cpr))) (when message-interactive (save-excursion @@ -4254,7 +4434,7 @@ documentation for the function `mail-source-touch-pop'." (smtpmail-send-it)) (defun message-canlock-generate () - "Return a string that is non-trival to guess. + "Return a string that is non-trivial to guess. Do not use this for anything important, it is cryptographically weak." (let (sha1-maximum-internal-length) (sha1 (concat (message-unique-id) @@ -4279,7 +4459,7 @@ Otherwise, generate and save a value for `canlock-password' first." (defun message-send-news (&optional arg) (let* ((tembuf (message-generate-new-buffer-clone-locals " *message temp*")) (case-fold-search nil) - (method (if (message-functionp message-post-method) + (method (if (functionp message-post-method) (funcall message-post-method arg) message-post-method)) (newsgroups-field (save-restriction @@ -4484,7 +4664,7 @@ Otherwise, generate and save a value for `canlock-password' first." (length (setq to (completing-read "Followups to (default: no Followup-To header) " - (mapcar (lambda (g) (list g)) + (mapcar #'list (cons "poster" (message-tokenize-header newsgroups))))))))) @@ -4525,7 +4705,7 @@ Otherwise, generate and save a value for `canlock-password' first." (if followup-to (concat newsgroups "," followup-to) newsgroups))) - (post-method (if (message-functionp message-post-method) + (post-method (if (functionp message-post-method) (funcall message-post-method) message-post-method)) ;; KLUDGE to handle nnvirtual groups. Doing this right @@ -4643,7 +4823,7 @@ Otherwise, generate and save a value for `canlock-password' first." nil) ((or (not (string-match "@[^\\.]*\\." - (setq ad (nth 1 (mail-extract-address-components + (setq ad (nth 1 (std11-extract-address-components from))))) ;larsi@ifi (string-match "\\.\\." ad) ;larsi@ifi..uio (string-match "@\\." ad) ;larsi@.ifi.uio @@ -4676,7 +4856,7 @@ Otherwise, generate and save a value for `canlock-password' first." reply-to))) ((or (not (string-match "@[^\\.]*\\." - (setq ad (nth 1 (mail-extract-address-components + (setq ad (nth 1 (std11-extract-address-components reply-to))))) ;larsi@ifi (string-match "\\.\\." ad) ;larsi@ifi..uio (string-match "@\\." ad) ;larsi@.ifi.uio @@ -5020,11 +5200,11 @@ If NOW, use that time instead." "Make an Organization header." (let* ((organization (when message-user-organization - (if (message-functionp message-user-organization) + (if (functionp message-user-organization) (funcall message-user-organization) message-user-organization)))) - (save-excursion - (message-set-work-buffer) + (with-temp-buffer + (set-buffer-multibyte t) (cond ((stringp organization) (insert organization)) ((and (eq t organization) @@ -5075,7 +5255,7 @@ If NOW, use that time instead." (defun message-make-distribution () "Make a Distribution header." (let ((orig-distribution (message-fetch-reply-field "distribution"))) - (cond ((message-functionp message-distribution-function) + (cond ((functionp message-distribution-function) (funcall message-distribution-function)) (t orig-distribution)))) @@ -5108,8 +5288,8 @@ If NOW, use that time instead." (user-full-name)))) (when (string= fullname "&") (setq fullname (user-login-name))) - (save-excursion - (message-set-work-buffer) + (with-temp-buffer + (set-buffer-multibyte t) (cond ((or (null style) (equal fullname "")) @@ -5125,6 +5305,16 @@ If NOW, use that time instead." (aset tmp (1- (match-end 0)) ?-)) (string-match "[\\()]" tmp))))) (insert fullname) + (goto-char (point-min)) + ;; Look for a character that cannot appear unquoted + ;; according to RFC 822. + (when (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" nil 1) + ;; Quote fullname, escaping specials. + (goto-char (point-min)) + (insert "\"") + (while (re-search-forward "[\"\\]" nil 1) + (replace-match "\\\\\\&" t)) + (insert "\"")) (insert " <" login ">")) (t ; 'parens or default (insert login " (") @@ -5169,7 +5359,7 @@ give as trustworthy answer as possible." (defun message-sendmail-envelope-from () "Return the envelope from." (cond ((eq message-sendmail-envelope-from 'header) - (nth 1 (mail-extract-address-components + (nth 1 (std11-extract-address-components (message-fetch-field "from")))) ((stringp message-sendmail-envelope-from) message-sendmail-envelope-from) @@ -5183,7 +5373,8 @@ give as trustworthy answer as possible." (user-domain (if (and user-mail (string-match "@\\(.*\\)\\'" user-mail)) - (match-string 1 user-mail)))) + (match-string 1 user-mail))) + (case-fold-search t)) (cond ((and message-user-fqdn (stringp message-user-fqdn) @@ -5209,7 +5400,8 @@ give as trustworthy answer as possible." user-domain) ;; Default to this bogus thing. (t - (concat system-name ".i-did-not-set--mail-host-address--so-tickle-me"))))) + (concat system-name + ".i-did-not-set--mail-host-address--so-tickle-me"))))) (defun message-make-host-name () "Return the name of the host." @@ -5286,26 +5478,14 @@ subscribed address (and not the additional To and Cc header contents)." (defun message-make-user-agent () "Return user-agent info if the value `message-user-agent' is non-nil. If the -\"User-Agent\" field has already exist, it's value will be added in the return -string." +\"User-Agent\" field has already exist, remove it." (when message-user-agent (save-excursion (goto-char (point-min)) - (let ((case-fold-search t) - user-agent start p end) - (if (re-search-forward - (concat "^User-Agent:[\t ]*\\(" - (regexp-quote gnus-product-name) - "/[0-9.]+\\([ \t\r\n]*([^)]+)\\)*\\)?[\t ]*") - nil t) - (progn - (setq start (match-beginning 0) - p (match-end 0) - end (std11-field-end) - user-agent (buffer-substring-no-properties p end)) - (delete-region start (1+ end)) - (concat message-user-agent " " user-agent)) - message-user-agent))))) + (let ((case-fold-search t)) + (when (re-search-forward "^User-Agent:[\t ]*" nil t) + (delete-region (match-beginning 0) (1+ (std11-field-end))))))) + message-user-agent) (defun message-idna-inside-rhs-p () "Return t iff point is inside a RHS (heuristically). @@ -5334,7 +5514,7 @@ I.e., calling it on a Subject: header is useless." (let (rhs ace start startpos endpos ovl) (goto-char (point-min)) (while (re-search-forward (concat "^" header) nil t) - (while (re-search-forward "@\\([^ \t\r\n>]+\\)" + (while (re-search-forward "@\\([^ \t\r\n>,]+\\)" (or (save-excursion (re-search-forward "^[^ \t]" nil t)) (point-max)) @@ -5393,7 +5573,7 @@ Headers already prepared in the buffer are not modified." (Expires (message-make-expires)) (case-fold-search t) (optionalp nil) - header value elem) + header value elem header-string) ;; First we remove any old generated headers. (let ((headers message-deletable-headers)) (unless (buffer-modified-p) @@ -5418,13 +5598,12 @@ Headers already prepared in the buffer are not modified." optionalp t) (setq header (car elem))) (setq header elem)) + (setq header-string (if (stringp header) + header + (symbol-name header))) (when (or (not (re-search-forward (concat "^" - (regexp-quote - (downcase - (if (stringp header) - header - (symbol-name header)))) + (regexp-quote (downcase header-string)) ":") nil t)) (progn @@ -5437,12 +5616,13 @@ Headers already prepared in the buffer are not modified." (setq value (cond ((and (consp elem) - (eq (car elem) 'optional)) + (eq (car elem) 'optional) + (not (member header-string message-inserted-headers))) ;; This is an optional header. If the cdr of this ;; is something that is nil, then we do not insert ;; this header. (setq header (cdr elem)) - (or (and (message-functionp (cdr elem)) + (or (and (functionp (cdr elem)) (funcall (cdr elem))) (and (boundp (cdr elem)) (symbol-value (cdr elem))))) @@ -5453,7 +5633,7 @@ Headers already prepared in the buffer are not modified." ;; this function. (or (and (stringp (cdr elem)) (cdr elem)) - (and (message-functionp (cdr elem)) + (and (functionp (cdr elem)) (funcall (cdr elem))))) ((and (boundp header) (symbol-value header)) @@ -5477,9 +5657,7 @@ Headers already prepared in the buffer are not modified." (cdr (assq header message-header-format-alist)))) (if formatter (funcall formatter header value) - (insert (if (stringp header) - header (symbol-name header)) - ": " value)) + (insert header-string ": " value)) ;; We check whether the value was ended by a ;; newline. If now, we insert one. (unless (bolp) @@ -5491,6 +5669,7 @@ Headers already prepared in the buffer are not modified." ;; If the header is optional, and the header was ;; empty, we can't insert it anyway. (unless optionalp + (push header-string message-inserted-headers) (insert value) (when (bolp) (delete-char -1)))) @@ -5594,7 +5773,6 @@ If the current line has `message-yank-prefix', insert it on the new line." (error (split-line)))) - (defun message-fill-header (header value) (let ((begin (point)) (fill-column 78) @@ -5694,12 +5872,25 @@ than 988 characters long, and if they are not, trim them until they are." (sit-for 0))) (defcustom message-beginning-of-line t - "Whether C-a goes to beginning of header values." + "Whether \\\\[message-beginning-of-line]\ + goes to beginning of header values." :group 'message-buffers + :link '(custom-manual "(message)Movement") :type 'boolean) (defun message-beginning-of-line (&optional n) - "Move point to beginning of header value or to beginning of line." + "Move point to beginning of header value or to beginning of line. +The prefix argument N is passed directly to `beginning-of-line'. + +This command is identical to `beginning-of-line' if point is +outside the message header or if the option `message-beginning-of-line' +is nil. + +If point is in the message header and on a (non-continued) header +line, move point to the beginning of the header value. If point +is already there, move point to beginning of line. Therefore, +repeated calls will toggle point between beginning of field and +beginning of line." (interactive "p") (let ((zrs 'zmacs-region-stays)) (when (and (interactive-p) (boundp zrs)) @@ -5731,14 +5922,14 @@ than 988 characters long, and if they are not, trim them until they are." "*"))) ;; Check whether `message-generate-new-buffers' is a function, ;; and if so, call it. - ((message-functionp message-generate-new-buffers) + ((functionp message-generate-new-buffers) (funcall message-generate-new-buffers type to group)) ((eq message-generate-new-buffers 'unsent) (generate-new-buffer-name (concat "*unsent " type (if to (concat " to " - (or (car (mail-extract-address-components to)) + (or (car (std11-extract-address-components to)) to) "") "") (if (and group (not (string= group ""))) (concat " on " group) "") @@ -5811,7 +6002,7 @@ than 988 characters long, and if they are not, trim them until they are." (setq name (cond (to (concat "*sent mail to " - (or (car (mail-extract-address-components to)) + (or (car (std11-extract-address-components to)) to) "*")) ((and group (not (string= group ""))) (concat "*sent posting on " group "*")) @@ -5927,6 +6118,11 @@ are not included." (when message-default-mail-headers (insert message-default-mail-headers) (or (bolp) (insert ?\n))) + (save-restriction + (message-narrow-to-headers) + (if (and replybuffer + message-alternative-emails) + (message-use-alternative-email-as-from))) (when message-generate-headers-first (message-generate-headers (message-headers-to-generate @@ -5938,9 +6134,6 @@ are not included." (message-insert-signature) (save-restriction (message-narrow-to-headers) - (if (and replybuffer - message-alternative-emails) - (message-use-alternative-email-as-from)) (run-hooks 'message-header-setup-hook)) (set-buffer-modified-p nil) (setq buffer-undo-list nil) @@ -6034,20 +6227,28 @@ OTHER-HEADERS is an alist of header/value pairs." (defun message-get-reply-headers (wide &optional to-address address-headers) (let (follow-to mct never-mct to cc author mft recipients) ;; Find all relevant headers we need. - (let ((mrt (when message-use-mail-reply-to - (message-fetch-field "mail-reply-to"))) - (reply-to (message-fetch-field "reply-to"))) - (setq to (message-fetch-field "to") - cc (message-fetch-field "cc") - mct (when message-use-mail-copies-to - (message-fetch-field "mail-copies-to")) - author (or mrt - reply-to - (message-fetch-field "from") - "") - mft (when (and (not (or to-address mrt reply-to)) - message-use-mail-followup-to) - (message-fetch-field "mail-followup-to")))) + (save-restriction + (message-narrow-to-headers-or-head) + (let ((mrt (when message-use-mail-reply-to + (message-fetch-field "mail-reply-to"))) + (reply-to (message-fetch-field "reply-to"))) + ;; Gmane renames "To". Look at "Original-To", too, if it is present in + ;; message-header-synonyms. + (setq to (or (message-fetch-field "to") + (and (loop for synonym in message-header-synonyms + when (memq 'Original-To synonym) + return t) + (message-fetch-field "original-to"))) + cc (message-fetch-field "cc") + mct (when message-use-mail-copies-to + (message-fetch-field "mail-copies-to")) + author (or mrt + reply-to + (message-fetch-field "from") + "") + mft (when (and (not (or to-address mrt reply-to)) + message-use-mail-followup-to) + (message-fetch-field "mail-followup-to"))))) (save-match-data ;; Handle special values of Mail-Copies-To. @@ -6197,11 +6398,11 @@ responses here are directed to other addresses."))) ;; Allow customizations to have their say. (if (not wide) ;; This is a regular reply. - (when (message-functionp message-reply-to-function) + (when (functionp message-reply-to-function) (save-excursion (setq follow-to (funcall message-reply-to-function)))) ;; This is a followup. - (when (message-functionp message-wide-reply-to-function) + (when (functionp message-wide-reply-to-function) (save-excursion (setq follow-to (funcall message-wide-reply-to-function))))) @@ -6265,7 +6466,7 @@ If TO-NEWSGROUPS, use that as the new Newsgroups line." followup-to distribution newsgroups gnus-warning posted-to) (save-restriction (message-narrow-to-head) - (when (message-functionp message-followup-to-function) + (when (functionp message-followup-to-function) (setq follow-to (funcall message-followup-to-function))) (setq from (message-fetch-field "from") @@ -6406,6 +6607,49 @@ that further discussion should take place only in " ,@(and distribution (list (cons 'Distribution distribution)))) cur))) +(defun message-is-yours-p () + "Non-nil means current article is yours. +If you have added 'cancel-messages to 'message-shoot-gnksa-feet', all articles +are yours except those that have Cancel-Lock header not belonging to you. +Instead of shooting GNKSA feet, you should modify 'message-alternative-emails' +regexp to match all of yours addresses." + ;; Canlock-logic as suggested by Per Abrahamsen + ;; + ;; + ;; IF article has cancel-lock THEN + ;; IF we can verify it THEN + ;; issue cancel + ;; ELSE + ;; error: cancellock: article is not yours + ;; ELSE + ;; Use old rules, comparing sender... + (save-excursion + (save-restriction + (message-narrow-to-head-1) + (if (message-fetch-field "Cancel-Lock") + (if (null (canlock-verify)) + t + (error "Failed to verify Cancel-lock: This article is not yours")) + (let (sender from) + (or + (message-gnksa-enable-p 'cancel-messages) + (and (setq sender (message-fetch-field "sender")) + (string-equal (downcase sender) + (downcase (message-make-sender)))) + ;; Email address in From field equals to our address + (and (setq from (message-fetch-field "from")) + (string-equal + (downcase (cadr (std11-extract-address-components from))) + (downcase (cadr (std11-extract-address-components + (message-make-from)))))) + ;; Email address in From field matches + ;; 'message-alternative-emails' regexp + (and from + message-alternative-emails + (string-match + message-alternative-emails + (cadr (std11-extract-address-components from)))))))))) + ;;;###autoload (defun message-cancel-news (&optional arg) "Cancel an article you posted. @@ -6413,42 +6657,17 @@ If ARG, allow editing of the cancellation message." (interactive "P") (unless (message-news-p) (error "This is not a news article; canceling is impossible")) - (let (from newsgroups message-id distribution buf sender) + (let (from newsgroups message-id distribution buf) (save-excursion ;; Get header info from original article. (save-restriction (message-narrow-to-head-1) (setq from (message-fetch-field "from") - sender (message-fetch-field "sender") newsgroups (message-fetch-field "newsgroups") message-id (message-fetch-field "message-id" t) distribution (message-fetch-field "distribution"))) ;; Make sure that this article was written by the user. - (unless (or - ;; Canlock-logic as suggested by Per Abrahamsen - ;; - ;; - ;; IF article has cancel-lock THEN - ;; IF we can verify it THEN - ;; issue cancel - ;; ELSE - ;; error: cancellock: article is not yours - ;; ELSE - ;; Use old rules, comparing sender... - (if (message-fetch-field "Cancel-Lock") - (if (null (canlock-verify)) - t - (error "Failed to verify Cancel-lock: This article is not yours")) - nil) - (message-gnksa-enable-p 'cancel-messages) - (and sender - (string-equal - (downcase sender) - (downcase (message-make-sender)))) - (string-equal - (downcase (cadr (std11-extract-address-components from))) - (downcase (cadr (std11-extract-address-components - (message-make-from)))))) + (unless (message-is-yours-p) (error "This article is not yours")) (when (yes-or-no-p "Do you really want to cancel this article? ") ;; Make control message. @@ -6486,35 +6705,9 @@ If ARG, allow editing of the cancellation message." This is done simply by taking the old article and adding a Supersedes header line with the old Message-ID." (interactive) - (let ((cur (current-buffer)) - (sender (message-fetch-field "sender")) - (from (message-fetch-field "from"))) + (let ((cur (current-buffer))) ;; Check whether the user owns the article that is to be superseded. - (unless (or - ;; Canlock-logic as suggested by Per Abrahamsen - ;; - ;; - ;; IF article has cancel-lock THEN - ;; IF we can verify it THEN - ;; issue cancel - ;; ELSE - ;; error: cancellock: article is not yours - ;; ELSE - ;; Use old rules, comparing sender... - (if (message-fetch-field "Cancel-Lock") - (if (null (canlock-verify)) - t - (error "Failed to verify Cancel-lock: This article is not yours")) - nil) - (message-gnksa-enable-p 'cancel-messages) - (and sender - (string-equal - (downcase sender) - (downcase (message-make-sender)))) - (string-equal - (downcase (cadr (std11-extract-address-components from))) - (downcase (cadr (std11-extract-address-components - (message-make-from)))))) + (unless (message-is-yours-p) (error "This article is not yours")) ;; Get a normal message buffer. (message-pop-to-buffer (message-buffer-name "supersede")) @@ -6594,38 +6787,44 @@ Previous forwarders, replyers, etc. may add it." (defvar message-forward-decoded-p nil "Non-nil means the original message is decoded.") -(defun message-forward-subject-author-subject (subject) +(defun message-forward-subject-name-subject (subject) "Generate a SUBJECT for a forwarded message. The form is: [Source] Subject, where if the original message was mail, -Source is the sender, and if the original message was news, Source is -the list of newsgroups is was posted to." +Source is the name of the sender, and if the original message was +news, Source is the list of newsgroups is was posted to." (concat "[" - (let ((prefix (message-fetch-field "newsgroups"))) - (or prefix - (and (setq prefix (message-fetch-field "from")) - (nnheader-decode-from prefix)) - "(nowhere)")) + (let ((group (message-fetch-field "newsgroups")) + from) + (if group + (gnus-group-decoded-name group) + (or (and (setq from (message-fetch-field "from")) + (car (std11-extract-address-components + (nnheader-decode-from from)))) + "(nowhere)"))) "] " subject)) -(defun message-forward-subject-name-subject (subject) +(defun message-forward-subject-author-subject (subject) "Generate a SUBJECT for a forwarded message. The form is: [Source] Subject, where if the original message was mail, -Source is the name of the sender, and if the original message was -news, Source is the list of newsgroups is was posted to." +Source is the sender, and if the original message was news, Source is +the list of newsgroups is was posted to." (concat "[" - (let ((prefix (message-fetch-field "newsgroups"))) - (or prefix - (and (setq prefix (message-fetch-field "from")) - (car (std11-extract-address-components - (nnheader-decode-from prefix)))) - "(nowhere)")) + (let ((group (message-fetch-field "newsgroups")) + from) + (if group + (gnus-group-decoded-name group) + (if (setq from (message-fetch-field "from")) + (nnheader-decode-from from) + "(nowhere)"))) "] " subject)) (defun message-forward-subject-fwd (subject) "Generate a SUBJECT for a forwarded message. The form is: Fwd: Subject, where Subject is the original subject of the message." - (concat "Fwd: " subject)) + (if (string-match "^Fwd: " subject) + subject + (concat "Fwd: " subject))) (defun message-make-forward-subject () "Return a Subject header suitable for the message in the current buffer." @@ -6649,7 +6848,7 @@ the message." ;; Apply funcs in order, passing subject generated by previous ;; func to the next one. (while funcs - (when (message-functionp (car funcs)) + (when (functionp (car funcs)) (setq subject (funcall (car funcs) subject))) (setq funcs (cdr funcs))) subject)))) @@ -6666,6 +6865,108 @@ Optional NEWS will use news to forward instead of mail." (message-mail nil subject)) (message-forward-make-body cur))) +(defun message-forward-make-body-plain (forward-buffer) + (insert + "\n-------------------- Start of forwarded message --------------------\n") + (let ((b (point)) e) + (insert + (with-temp-buffer + (mm-disable-multibyte) + (insert + (with-current-buffer forward-buffer + (mm-with-unibyte-current-buffer (buffer-string)))) + (mm-enable-multibyte) + (mime-to-mml) + (goto-char (point-min)) + (when (looking-at "From ") + (replace-match "X-From-Line: ")) + (buffer-string))) + (setq e (point)) + (insert + "\n-------------------- End of forwarded message --------------------\n") + (when (and (not current-prefix-arg) + message-forward-ignored-headers) + (save-restriction + (narrow-to-region b e) + (goto-char b) + (narrow-to-region (point) + (or (search-forward "\n\n" nil t) (point))) + (message-remove-header message-forward-ignored-headers t))))) + +(defun message-forward-make-body-mime (forward-buffer) + (insert "\n\n<#part type=message/rfc822 disposition=inline raw=t>\n") + (let ((b (point)) e) + (save-restriction + (narrow-to-region (point) (point)) + (mml-insert-buffer forward-buffer) + (goto-char (point-min)) + (when (looking-at "From ") + (replace-match "X-From-Line: ")) + (goto-char (point-max))) + (setq e (point)) + (insert "<#/part>\n"))) + +(defun message-forward-make-body-mml (forward-buffer) + (insert "\n\n<#mml type=message/rfc822 disposition=inline>\n") + (let ((b (point)) e) + (if (not message-forward-decoded-p) + (insert + (with-temp-buffer + (mm-disable-multibyte) + (insert + (with-current-buffer forward-buffer + (mm-with-unibyte-current-buffer (buffer-string)))) + (mm-enable-multibyte) + (mime-to-mml) + (goto-char (point-min)) + (when (looking-at "From ") + (replace-match "X-From-Line: ")) + (buffer-string))) + (save-restriction + (narrow-to-region (point) (point)) + (mml-insert-buffer forward-buffer) + (goto-char (point-min)) + (when (looking-at "From ") + (replace-match "X-From-Line: ")) + (goto-char (point-max)))) + (setq e (point)) + (insert "<#/mml>\n") + (when (and (not current-prefix-arg) + message-forward-ignored-headers) + (save-restriction + (narrow-to-region b e) + (goto-char b) + (narrow-to-region (point) + (or (search-forward "\n\n" nil t) (point))) + (message-remove-header message-forward-ignored-headers t))))) + +(defun message-forward-make-body-digest-plain (forward-buffer) + (insert + "\n-------------------- Start of forwarded message --------------------\n") + (let ((b (point)) e) + (mml-insert-buffer forward-buffer) + (setq e (point)) + (insert + "\n-------------------- End of forwarded message --------------------\n"))) + +(defun message-forward-make-body-digest-mime (forward-buffer) + (insert "\n<#multipart type=digest>\n") + (let ((b (point)) e) + (insert-buffer-substring forward-buffer) + (setq e (point)) + (insert "<#/multipart>\n") + (save-restriction + (narrow-to-region b e) + (goto-char b) + (narrow-to-region (point) + (or (search-forward "\n\n" nil t) (point))) + (delete-region (point-min) (point-max))))) + +(defun message-forward-make-body-digest (forward-buffer) + (if message-forward-as-mime + (message-forward-make-body-digest-mime forward-buffer) + (message-forward-make-body-digest-plain forward-buffer))) + ;;;###autoload (defun message-forward-make-body (forward-buffer) ;; Put point where we want it before inserting the forwarded @@ -6707,9 +7008,12 @@ Optional NEWS will use news to forward instead of mail." (rmail-msg-restore-non-pruned-header))) (message-forward-make-body forward-buffer)) +(eval-when-compile (defvar rmail-enable-mime-composing)) + +;; Fixme: Should have defcustom. ;;;###autoload (defun message-insinuate-rmail () - "Let RMAIL uses message to forward." + "Let RMAIL use message to forward." (interactive) (setq rmail-enable-mime-composing t) (setq rmail-insert-mime-forwarded-message-function @@ -6732,7 +7036,7 @@ Optional NEWS will use news to forward instead of mail." message-setup-hook) (message-setup `((To . ,address)))) ;; Insert our usual headers. - (message-generate-headers '(From Date To)) + (message-generate-headers '(From Date To Message-ID)) (message-narrow-to-headers) ;; Remove X-Draft-From header etc. (message-remove-header message-ignored-mail-headers t) @@ -6783,32 +7087,36 @@ contains some mail you have written which has been bounced back to you." (interactive) (let ((cur (current-buffer)) - boundary) + mime-boundary boundary) (message-pop-to-buffer (message-buffer-name "bounce")) (insert-buffer-substring cur) (undo-boundary) (message-narrow-to-head) (if (and (message-fetch-field "MIME-Version") - (setq boundary (message-fetch-field "Content-Type"))) - (if (string-match "boundary=\"\\([^\"]+\\)\"" boundary) - (setq boundary (concat (match-string 1 boundary) " *\n" - "Content-Type: message/rfc822")) - (setq boundary nil))) + (setq mime-boundary (message-fetch-field "Content-Type"))) + (if (string-match "boundary=\"\\([^\"]+\\)\"" mime-boundary) + (setq mime-boundary (concat (regexp-quote + (match-string 1 mime-boundary)) + " *\nContent-Type: message/rfc822")) + (setq mime-boundary nil))) (widen) (goto-char (point-min)) - (search-forward "\n\n" nil t) - (if (or (and boundary - (re-search-forward boundary nil t) - (forward-line 2)) - (and (re-search-forward message-unsent-separator nil t) + (re-search-forward "\n\n+" nil t) + (setq boundary (point)) + ;; We remove everything before the bounced mail. + (if (or (and mime-boundary + (re-search-forward mime-boundary nil t) (forward-line 1)) - (re-search-forward "^Return-Path:.*\n" nil t)) - ;; We remove everything before the bounced mail. - (delete-region - (point-min) - (if (re-search-forward "^[^ \n\t]+:" nil t) - (match-beginning 0) - (point))) + (re-search-forward message-unsent-separator nil t) + (progn + (search-forward "\n\n" nil 'move) + (re-search-backward "^Return-Path:.*\n" boundary t))) + (progn + (forward-line 1) + (delete-region (point-min) + (if (re-search-forward "^[^ \n\t]+:" nil t) + (match-beginning 0) + (point)))) (when (re-search-backward "^.?From .*\n" nil t) (delete-region (match-beginning 0) (match-end 0)))) (save-restriction @@ -6921,6 +7229,10 @@ which specify the range to operate on." (defalias 'message-make-overlay 'make-overlay) (defalias 'message-delete-overlay 'delete-overlay) (defalias 'message-overlay-put 'overlay-put) +(defun message-kill-all-overlays () + (if (featurep 'xemacs) + (map-extents (lambda (extent ignore) (delete-extent extent))) + (mapcar #'delete-overlay (overlays-in (point-min) (point-max))))) ;; Support for toolbar (eval-when-compile @@ -7007,6 +7319,7 @@ which specify the range to operate on." "*Function to execute when `message-tab' (TAB) is executed in the body. If nil, the function bound in `text-mode-map' or `global-map' is executed." :group 'message + :link '(custom-manual "(message)Various Commands") :type 'function) (defun message-tab () @@ -7098,10 +7411,10 @@ The following arguments may contain lists of values." (list list)))) (defun message-generate-new-buffer-clone-locals (name &optional varstr) - "Create and return a buffer with name based on NAME using `generate-new-buffer.' + "Create and return a buffer with name based on NAME using `generate-new-buffer'. Then clone the local variables and values from the old buffer to the new one, cloning only the locals having a substring matching the -regexp varstr." +regexp VARSTR." (let ((oldbuf (current-buffer))) (save-excursion (set-buffer (generate-new-buffer name)) @@ -7127,7 +7440,6 @@ regexp varstr." (cdr local))))) locals))) - ;;; @ for MIME Edit mode ;;; @@ -7166,24 +7478,6 @@ regexp varstr." (set-alist 'mime-edit-message-inserter-alist 'message-mode (function message-mime-insert-article)) -;;; Miscellaneous functions - -;; stolen (and renamed) from nnheader.el -(static-if (fboundp 'subst-char-in-string) - (defsubst message-replace-chars-in-string (string from to) - (subst-char-in-string from to string)) - (defun message-replace-chars-in-string (string from to) - "Replace characters in STRING from FROM to TO." - (let ((string (substring string 0)) ;Copy string. - (len (length string)) - (idx 0)) - ;; Replace all occurrences of FROM with TO. - (while (< idx len) - (when (= (aref string idx) from) - (aset string idx to)) - (setq idx (1+ idx))) - string))) - ;;; ;;; MIME functions ;;; diff --git a/lisp/mm-bodies.el b/lisp/mm-bodies.el index ee14049..3475168 100644 --- a/lisp/mm-bodies.el +++ b/lisp/mm-bodies.el @@ -47,6 +47,8 @@ (iso-2022-jp-2 . 7bit) ;; We MUST encode UTF-16 because it can contain \0's which is ;; known to break servers. + ;; Note: UTF-16 variants are invalid for text parts [RFC 2781], + ;; so this can't happen :-/. (utf-16 . base64) (utf-16be . base64) (utf-16le . base64)) @@ -63,9 +65,9 @@ Valid encodings are `7bit', `8bit', `quoted-printable' and `base64'." (defun mm-encode-body (&optional charset) "Encode a body. Should be called narrowed to the body that is to be encoded. -If there is more than one non-ASCII MULE charset, then list of found -MULE charsets are returned. -If CHARSET is non-nil, it is used. +If there is more than one non-ASCII MULE charset in the body, then the +list of MULE charsets found is returned. +If CHARSET is non-nil, it is used as the MIME charset to encode the body. If successful, the MIME charset is returned. If no encoding was done, nil is returned." (if (not (mm-multibyte-p)) @@ -79,7 +81,7 @@ If no encoding was done, nil is returned." (message-options-get 'mm-encody-body-charset) (message-options-set 'mm-encody-body-charset - (mm-read-charset "Charset used in the article: "))) + (mm-read-coding-system "Charset used in the article: "))) ;; The logic in `mml-generate-mime-1' confirms that it's OK ;; to return nil here. nil))) @@ -107,7 +109,7 @@ If no encoding was done, nil is returned." )))))) (defun mm-long-lines-p (length) - "Say whether any of the lines in the buffer is longer than LINES." + "Say whether any of the lines in the buffer is longer than LENGTH." (save-excursion (goto-char (point-min)) (end-of-line) @@ -128,8 +130,9 @@ If no encoding was done, nil is returned." (longp (mm-long-lines-p 1000))) (require 'message) (cond - ((and (not mm-use-ultra-safe-encoding) - (not longp) + ((and (not longp) + (not (and mm-use-ultra-safe-encoding + (save-excursion (re-search-forward "^From " nil t)))) (eq bits '7bit)) bits) ((and (not mm-use-ultra-safe-encoding) @@ -150,32 +153,19 @@ If no encoding was done, nil is returned." (defun mm-body-7-or-8 () "Say whether the body is 7bit or 8bit." - (cond - ((not (featurep 'mule)) - (if (save-excursion - (goto-char (point-min)) - (skip-chars-forward mm-7bit-chars) - (eobp)) - '7bit - '8bit)) - (t - ;; Mule version - (if (and (null (delq 'ascii - (mm-find-charset-region (point-min) (point-max)))) - ;;!!!The following is necessary because the function - ;;!!!above seems to return the wrong result under - ;;!!!Emacs 20.3. Sometimes. - (save-excursion - (goto-char (point-min)) - (skip-chars-forward mm-7bit-chars) - (eobp))) - '7bit - '8bit)))) + (if (save-excursion + (goto-char (point-min)) + (skip-chars-forward mm-7bit-chars) + (eobp)) + '7bit + '8bit)) ;;; ;;; Functions for decoding ;;; +(eval-when-compile (defvar mm-uu-yenc-decode-function)) + (defun mm-decode-content-transfer-encoding (encoding &optional type) "Decodes buffer encoded with ENCODING, returning success status. If TYPE is `text/plain' CRLF->LF translation may occur." @@ -234,66 +224,42 @@ If TYPE is `text/plain' CRLF->LF translation may occur." (while (search-forward "\r\n" nil t) (replace-match "\n" t t))))) -(defun mm-decode-body (charset &optional encoding type force) - "Decode the current article that has been encoded with ENCODING. -The characters in CHARSET should then be decoded. If FORCE is non-nil -use the supplied charset unconditionally." - (let ((charset-supplied charset)) - (when (stringp charset) - (setq charset (intern (downcase charset)))) - (when (or (not charset) - (eq 'gnus-all mail-parse-ignored-charsets) - (memq 'gnus-all mail-parse-ignored-charsets) - (memq charset mail-parse-ignored-charsets)) - (setq charset mail-parse-charset - charset-supplied nil)) - (save-excursion - (when encoding - (mm-decode-content-transfer-encoding encoding type)) - (when (featurep 'mule) - (let ((coding-system (mm-charset-to-coding-system charset))) - (if (and (not coding-system) - (listp mail-parse-ignored-charsets) - (memq 'gnus-unknown mail-parse-ignored-charsets)) - (setq coding-system - (mm-charset-to-coding-system mail-parse-charset))) - (when (and charset coding-system - ;; buffer-file-coding-system - ;;Article buffer is nil coding system - ;;in XEmacs - (mm-multibyte-p) - (or (not (eq coding-system 'ascii)) - (setq coding-system mail-parse-charset)) - (not (eq coding-system 'gnus-decoded))) - (if (or force - ;; If a charset was supplied, then use the - ;; supplied charset unconditionally. - charset-supplied) - (mm-decode-coding-region (point-min) (point-max) - coding-system) - ;; Otherwise allow Emacs to auto-detect the charset. - (mm-decode-coding-region-safely (point-min) (point-max) - coding-system))) - (setq buffer-file-coding-system - (if (boundp 'last-coding-system-used) - (symbol-value 'last-coding-system-used) - coding-system))))))) - -(defun mm-decode-coding-region-safely (start end coding-system) - "Decode region between START and END with CODING-SYSTEM. -If CODING-SYSTEM is not a valid coding system for the text, let Emacs -decide which coding system to use." - (let* ((orig (buffer-substring start end)) - charsets) - (save-restriction - (narrow-to-region start end) - (mm-decode-coding-region (point-min) (point-max) coding-system) - (setq charsets (find-charset-region (point-min) (point-max))) - (when (or (memq 'eight-bit-control charsets) - (memq 'eight-bit-graphic charsets)) - (delete-region (point-min) (point-max)) - (insert orig) - (mm-decode-coding-region (point-min) (point-max) 'undecided))))) +(defun mm-decode-body (charset &optional encoding type) + "Decode the current article that has been encoded with ENCODING to CHARSET. +ENCODING is a MIME content transfer encoding. +CHARSET is the MIME charset with which to decode the data after transfer +decoding. If it is nil, default to `mail-parse-charset'." + (when (stringp charset) + (setq charset (intern (downcase charset)))) + (when (or (not charset) + (eq 'gnus-all mail-parse-ignored-charsets) + (memq 'gnus-all mail-parse-ignored-charsets) + (memq charset mail-parse-ignored-charsets)) + (setq charset mail-parse-charset)) + (save-excursion + (when encoding + (mm-decode-content-transfer-encoding encoding type)) + (when (featurep 'mule) ; Fixme: Wrong test for unibyte session. + (let ((coding-system (mm-charset-to-coding-system charset))) + (if (and (not coding-system) + (listp mail-parse-ignored-charsets) + (memq 'gnus-unknown mail-parse-ignored-charsets)) + (setq coding-system + (mm-charset-to-coding-system mail-parse-charset))) + (when (and charset coding-system + ;; buffer-file-coding-system + ;;Article buffer is nil coding system + ;;in XEmacs + (mm-multibyte-p) + (or (not (eq coding-system 'ascii)) + (setq coding-system mail-parse-charset)) + (not (eq coding-system 'gnus-decoded))) + (mm-decode-coding-region (point-min) (point-max) + coding-system)) + (setq buffer-file-coding-system + (if (boundp 'last-coding-system-used) + (symbol-value 'last-coding-system-used) + coding-system)))))) (defun mm-decode-string (string charset) "Decode STRING with CHARSET." diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index d7b1c73..0fcc1be 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -1,6 +1,6 @@ ;;; mm-decode.el --- Functions for decoding MIME things -;; Copyright (C) 1998, 1999, 2000, 2001, 2002, -;; 2003 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 +;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; MORIOKA Tomohiko @@ -100,20 +100,23 @@ (defcustom mm-text-html-renderer (cond ((locate-library "w3") 'w3) ((locate-library "w3m") 'w3m) + ((executable-find "w3m") 'w3m-standalone) ((executable-find "links") 'links) ((executable-find "lynx") 'lynx) (t 'html2text)) "Render of HTML contents. It is one of defined renderer types, or a rendering function. The defined renderer types are: -`w3' : using Emacs/W3; -`w3m' : using emacs-w3m; -`links': using links; -`lynx' : using lynx; -`html2text' : using html2text; -nil : using external viewer." +`w3' : use Emacs/W3; +`w3m' : use emacs-w3m; +`w3m-standalone': use w3m; +`links': use links; +`lynx' : use lynx; +`html2text' : use html2text; +nil : use external viewer." :type '(choice (const w3) (const w3m) + (const w3m-standalone) (const links) (const lynx) (const html2text) @@ -127,20 +130,24 @@ nil : using external viewer." It is suggested to customize `mm-text-html-renderer' instead.") (defcustom mm-inline-text-html-with-images nil - "If non-nil, Gnus will allow retrieving images in the HTML contents -with tags. It has no effect on Emacs/w3. See also -the documentation for the option `mm-w3m-safe-url-regexp'." + "If non-nil, Gnus will allow retrieving images in HTML contents with +the tags. It has no effect on Emacs/w3. See also the +documentation for the `mm-w3m-safe-url-regexp' variable." :type 'boolean :group 'mime-display) (defcustom mm-w3m-safe-url-regexp "\\`cid:" - "Regexp that matches safe url names. Some HTML mails might have a -trick of spammers using tags. It is likely to be intended to -verify whether you have read the mail. You can prevent your personal -informations from leaking by setting this to the regexp which matches -the safe url names. The value of the variable `w3m-safe-url-regexp' -will be bound with this value. You may set this value to nil if you -consider all the urls to be safe." + "Regexp matching URLs which are considered to be safe. +Some HTML mails might contain a nasty trick used by spammers, using +the tag which is far more evil than the [Click Here!] button. +It is most likely intended to check whether the ominous spam mail has +reached your eyes or not, in which case the spammer knows for sure +that your email address is valid. It is done by embedding an +identifier string into a URL that you might automatically retrieve +when displaying the image. The default value is \"\\\\`cid:\" which only +matches parts embedded to the Multipart/Related type MIME contents and +Gnus will never connect to the spammer's site arbitrarily. You may +set this variable to nil if you consider all urls to be safe." :type '(choice (regexp :tag "Regexp") (const :tag "All URLs are safe" nil)) :group 'mime-display) @@ -150,8 +157,20 @@ consider all the urls to be safe." :type 'boolean :group 'mime-display) +(defcustom mm-enable-external t + "Indicate whether external MIME handlers should be used. + +If t, all defined external MIME handlers are used. If nil, files are saved by +`mailcap-save-binary-file'. If it is the symbol `ask', you are prompted +before the external MIME handler is invoked." + :version "21.4" + :type '(choice (const :tag "Always" t) + (const :tag "Never" nil) + (const :tag "Ask" ask)) + :group 'mime-display) + (defcustom mm-inline-media-tests - '(("image/jpeg" + '(("image/p?jpeg" mm-inline-image (lambda (handle) (mm-valid-and-fit-image-p 'jpeg handle))) @@ -237,7 +256,7 @@ consider all the urls to be safe." ;; Default to displaying as text (".*" mm-inline-text mm-readable-p)) "Alist of media types/tests saying whether types can be displayed inline." - :type '(repeat (list (string :tag "MIME type") + :type '(repeat (list (regexp :tag "MIME type") (function :tag "Display function") (function :tag "Display test"))) :group 'mime-display) @@ -322,11 +341,14 @@ to: :type 'boolean :group 'mime-display) -(defvar mm-file-name-rewrite-functions nil +(defvar mm-file-name-rewrite-functions + '(mm-file-name-delete-control mm-file-name-delete-gotchas) "*List of functions used for rewriting file names of MIME parts. Each function takes a file name as input and returns a file name. Ready-made functions include +`mm-file-name-delete-control' +`mm-file-name-delete-gotchas' `mm-file-name-delete-whitespace', `mm-file-name-trim-whitespace', `mm-file-name-collapse-whitespace', @@ -351,6 +373,11 @@ If not set, `default-directory' will be used." :type '(choice directory (const :tag "Default" nil)) :group 'mime-display) +(defcustom mm-attachment-file-modes 384 + "Set the mode bits of saved attachments to this integer." + :type 'integer + :group 'mime-display) + (defcustom mm-external-terminal-program "xterm" "The program to start an external terminal." :type 'string @@ -384,7 +411,7 @@ If not set, `default-directory' will be used." (defcustom mm-verify-option 'never "Option of verifying signed parts. `never', not verify; `always', always verify; -`known', only verify known protocols. Otherwise, ask user." +`known', only verify known protocols. Otherwise, ask user." :type '(choice (item always) (item never) (item :tag "only known protocols" known) @@ -402,7 +429,7 @@ If not set, `default-directory' will be used." (defcustom mm-decrypt-option nil "Option of decrypting encrypted parts. `never', not decrypt; `always', always decrypt; -`known', only decrypt known protocols. Otherwise, ask user." +`known', only decrypt known protocols. Otherwise, ask user." :type '(choice (item always) (item never) (item :tag "only known protocols" known) @@ -458,8 +485,9 @@ The original alist is not modified. See also `destructive-alist-to-plist'." (throw 'found t)))))) (defun mm-handle-set-external-undisplayer (handle function) - "Set the undisplayer for this handle; postpone undisplaying of viewers -for types in mm-keep-viewer-alive-types." + "Set the undisplayer for HANDLE to FUNCTION. +Postpone undisplaying of viewers for types in +`mm-keep-viewer-alive-types'." (if (mm-keep-viewer-alive-p handle) (let ((new-handle (copy-sequence handle))) (mm-handle-set-undisplayer new-handle function) @@ -515,7 +543,8 @@ for types in mm-keep-viewer-alive-types." ((equal type "multipart") (let ((mm-dissect-default-type (if (equal subtype "digest") "message/rfc822" - "text/plain"))) + "text/plain")) + (start (cdr (assq 'start (cdr ctl))))) (add-text-properties 0 (length (car ctl)) (mm-alist-to-plist (cdr ctl)) (car ctl)) @@ -525,10 +554,9 @@ for types in mm-keep-viewer-alive-types." ;; the mm-handle API so we simply store the multipart buffert ;; name as a text property of the "multipart/whatever" string. (add-text-properties 0 (length (car ctl)) - (list 'buffer (mm-copy-to-buffer)) - (car ctl)) - (add-text-properties 0 (length (car ctl)) - (list 'from from) + (list 'buffer (mm-copy-to-buffer) + 'from from + 'start start) (car ctl)) (cons (car ctl) (mm-dissect-multipart ctl)))) (t @@ -621,7 +649,13 @@ external if displayed external." (if (mm-handle-displayed-p handle) (mm-remove-part handle) (let* ((type (mm-handle-media-type handle)) - (method (mailcap-mime-info type))) + (method (mailcap-mime-info type)) + (filename (or (mail-content-type-get + (mm-handle-disposition handle) 'filename) + (mail-content-type-get + (mm-handle-type handle) 'name) + "")) + (external mm-enable-external)) (if (and (mm-inlinable-p handle) (mm-inlined-p handle)) (progn @@ -636,8 +670,27 @@ external if displayed external." (forward-line 1) (mm-insert-inline handle (mm-get-part handle)) 'inline) - (mm-display-external - handle (or method 'mailcap-save-binary-file))))))))) + (if (and method ;; If nil, we always use "save". + (stringp method) ;; 'mailcap-save-binary-file + (or (eq mm-enable-external t) + (and (eq mm-enable-external 'ask) + (y-or-n-p + (concat + "Display part (" type + ") using external program" + ;; Can non-string method ever happen? + (if (stringp method) + (concat + " \"" (format method filename) "\"") + "") + "? "))))) + (setq external t) + (setq external nil)) + (if external + (mm-display-external + handle (or method 'mailcap-save-binary-file)) + (mm-display-external + handle 'mailcap-save-binary-file))))))))) (defun mm-display-external (handle method) "Display HANDLE using METHOD." @@ -658,7 +711,8 @@ external if displayed external." (mm-set-buffer-file-coding-system mm-binary-coding-system) (insert-buffer-substring cur) (goto-char (point-min)) - (message "Viewing with %s" method) + (when method + (message "Viewing with %s" method)) (let ((mm (current-buffer)) (non-viewer (assq 'non-viewer (mailcap-mime-info @@ -846,9 +900,18 @@ external if displayed external." (funcall object)) ;; Externally displayed part. ((consp object) + (condition-case () + (while (get-buffer-process (cdr object)) + (interrupt-process (get-buffer-process (cdr object))) + (message "Waiting for external displayer to die...") + (sit-for 1)) + (quit) + (error)) + (ignore-errors (and (cdr object) (kill-buffer (cdr object)))) + (message "Waiting for external displayer to die...done") (ignore-errors (delete-file (car object))) - (ignore-errors (delete-directory (file-name-directory (car object)))) - (ignore-errors (and (cdr object) (kill-buffer (cdr object))))) + (ignore-errors (delete-directory (file-name-directory + (car object))))) ((bufferp object) (when (buffer-live-p object) (kill-buffer object))))) @@ -1005,13 +1068,22 @@ external if displayed external." (defun mm-file-name-replace-whitespace (file-name) "Replace whitespace characters in FILE-NAME with underscores. -Set `mm-file-name-replace-whitespace' to any other string if you do not -like underscores." +Set the option `mm-file-name-replace-whitespace' to any other +string if you do not like underscores." (let ((s (or mm-file-name-replace-whitespace "_"))) (while (string-match "\\s-" file-name) (setq file-name (replace-match s t t file-name)))) file-name) +(defun mm-file-name-delete-control (filename) + "Delete control characters from FILENAME." + (gnus-replace-in-string filename "[\x00-\x1f\x7f]" "")) + +(defun mm-file-name-delete-gotchas (filename) + "Delete shell gotchas from FILENAME." + (setq filename (gnus-replace-in-string filename "[<>|]" "")) + (gnus-replace-in-string filename "^[.-]+" "")) + (defun mm-save-part (handle) "Write HANDLE to a file." (let* ((name (mail-content-type-get (mm-handle-type handle) 'name)) @@ -1037,13 +1109,17 @@ like underscores." (mm-with-unibyte-buffer (mm-insert-part handle) (let ((coding-system-for-write 'binary) + (current-file-modes (default-file-modes)) ;; Don't re-compress .gz & al. Arguably we should make ;; `file-name-handler-alist' nil, but that would chop ;; ange-ftp, which is reasonable to use here. (inhibit-file-name-operation 'write-region) (inhibit-file-name-handlers (cons 'jka-compr-handler inhibit-file-name-handlers))) - (write-region (point-min) (point-max) file)))) + (set-default-file-modes mm-attachment-file-modes) + (unwind-protect + (write-region (point-min) (point-max) file) + (set-default-file-modes current-file-modes))))) (defun mm-pipe-part (handle) "Pipe HANDLE to a process." diff --git a/lisp/mm-encode.el b/lisp/mm-encode.el index 770d106..cb17414 100644 --- a/lisp/mm-encode.el +++ b/lisp/mm-encode.el @@ -29,7 +29,8 @@ (require 'mail-parse) (require 'gnus-mailcap) (eval-and-compile - (autoload 'mm-body-7-or-8 "mm-bodies")) + (autoload 'mm-body-7-or-8 "mm-bodies") + (autoload 'mm-long-lines-p "mm-bodies")) (defcustom mm-content-transfer-encoding-defaults '(("text/x-patch" 8bit) @@ -85,7 +86,7 @@ This variable should never be set directly, but bound before a call to (mailcap-extension-to-mime (match-string 0 file)))) (defun mm-safer-encoding (encoding) - "Return a safer but similar encoding." + "Return an encoding similar to ENCODING but safer than it." (cond ((memq encoding '(7bit 8bit quoted-printable)) 'quoted-printable) ;; The remaining encodings are binary and base64 (and perhaps some @@ -93,33 +94,38 @@ This variable should never be set directly, but bound before a call to (t 'base64))) (defun mm-encode-content-transfer-encoding (encoding &optional type) + "Encode the current buffer with ENCODING for MIME type TYPE. +ENCODING can be: nil (do nothing); one of `quoted-printable', `base64'; +`7bit', `8bit' or `binary' (all do nothing); a function to do the encoding." (cond ((eq encoding 'quoted-printable) - (mm-with-unibyte-current-buffer-mule4 - (quoted-printable-encode-region (point-min) (point-max) t))) + ;; This used to try to make a multibyte buffer unibyte. That's + ;; completely wrong, since you'd get QP-encoded emacs-mule. If + ;; this gets run on multibyte text it's an error that needs + ;; fixing, and the encoding function will signal an error. + ;; Likewise base64 below. + (quoted-printable-encode-region (point-min) (point-max) t)) ((eq encoding 'base64) (when (equal type "text/plain") (goto-char (point-min)) (while (search-forward "\n" nil t) (replace-match "\r\n" t t))) - (condition-case error - (base64-encode-region (point-min) (point-max)) - (error - (message "Error while decoding: %s" error) - nil))) + (base64-encode-region (point-min) (point-max))) ((memq encoding '(7bit 8bit binary)) ;; Do nothing. ) ((null encoding) ;; Do nothing. ) + ;; Fixme: Ignoring errors here looks bogus. ((functionp encoding) (ignore-errors (funcall encoding (point-min) (point-max)))) (t - (message "Unknown encoding %s; treating it as 8bit" encoding)))) + (error "Unknown encoding %s" encoding)))) (defun mm-encode-buffer (type) - "Encode the buffer which contains data of TYPE. + "Encode the buffer which contains data of MIME type TYPE. +TYPE is a string or a list of the components. The encoding used is returned." (let* ((mime-type (if (stringp type) type (car type))) (encoding @@ -165,6 +171,8 @@ The encoding used is returned." (pop rules))))) (defun mm-qp-or-base64 () + "Return the type with which to encode the buffer. +This is either `base64' or `quoted-printable'." (if (equal mm-use-ultra-safe-encoding '(sign . "pgp")) ;; perhaps not always accurate? 'quoted-printable diff --git a/lisp/mm-extern.el b/lisp/mm-extern.el index 2627397..b063ee8 100644 --- a/lisp/mm-extern.el +++ b/lisp/mm-extern.el @@ -49,7 +49,7 @@ (coding-system-for-read mm-binary-coding-system)) (unless name (error "The filename is not specified")) - (mm-disable-multibyte-mule4) + (mm-disable-multibyte) (if (file-exists-p name) (mm-insert-file-contents name nil nil nil nil t) (error (format "File %s is gone" name))))) @@ -61,9 +61,9 @@ (coding-system-for-read mm-binary-coding-system)) (unless url (error "URL is not specified")) - (mm-with-unibyte-current-buffer-mule4 + (mm-with-unibyte-current-buffer (mm-url-insert-file-contents url)) - (mm-disable-multibyte-mule4) + (mm-disable-multibyte) (setq buffer-file-name name))) (defun mm-extern-anon-ftp (handle) @@ -79,7 +79,7 @@ (coding-system-for-read mm-binary-coding-system)) (unless name (error "The filename is not specified")) - (mm-disable-multibyte-mule4) + (mm-disable-multibyte) (mm-insert-file-contents path nil nil nil nil t))) (defun mm-extern-ftp (handle) diff --git a/lisp/mm-url.el b/lisp/mm-url.el index 42d3fce..7ff8140 100644 --- a/lisp/mm-url.el +++ b/lisp/mm-url.el @@ -53,7 +53,7 @@ :group 'mm-url) (defvar mm-url-predefined-programs - '((wget "wget" "-q" "-O" "-") + '((wget "wget" "--user-agent=mm-url" "-q" "-O" "-") (w3m "w3m" "-dump_source") (lynx "lynx" "-source") (curl "curl"))) @@ -272,7 +272,10 @@ This is taken from RFC 2396.") (require 'w3-vars) (require 'url))) +;;;###autoload (defun mm-url-insert-file-contents (url) + "Insert file contents of URL. +If `mm-url-use-external' is non-nil, use `mm-url-program'." (if mm-url-use-external (progn (if (string-match "^file:/+" url) @@ -280,7 +283,7 @@ This is taken from RFC 2396.") (mm-url-insert-file-contents-external url)) (goto-char (point-min)) (if (fboundp 'url-generic-parse-url) - (setq url-current-object + (setq url-current-object (url-generic-parse-url url))) (list url (buffer-size))) (mm-url-load-url) @@ -303,7 +306,9 @@ This is taken from RFC 2396.") (car result)))) result))) +;;;###autoload (defun mm-url-insert-file-contents-external (url) + "Insert file contents of URL using `mm-url-program'." (let (program args) (if (symbolp mm-url-program) (let ((item (cdr (assq mm-url-program mm-url-predefined-programs)))) @@ -311,7 +316,8 @@ This is taken from RFC 2396.") args (append (cdr item) (list url)))) (setq program mm-url-program args (append mm-url-arguments (list url)))) - (apply 'call-process program nil t nil args))) + (unless (eq 0 (apply 'call-process program nil t nil args)) + (error "Couldn't fetch %s" url)))) (defvar mm-url-timeout 30 "The number of seconds before timing out an URL fetch.") diff --git a/lisp/mm-util.el b/lisp/mm-util.el index 08d9284..5c1ea1e 100644 --- a/lisp/mm-util.el +++ b/lisp/mm-util.el @@ -75,6 +75,16 @@ (string-make-unibyte . identity) (string-as-multibyte . identity) (multibyte-string-p . ignore) + ;; It is not a MIME function, but some MIME functions use it. + (make-temp-file . (lambda (prefix &optional dir-flag) + (let ((file (expand-file-name + (make-temp-name prefix) + (if (fboundp 'temp-directory) + (temp-directory) + temporary-file-directory)))) + (if dir-flag + (make-directory file)) + file))) (insert-byte . insert-char) (multibyte-char-to-unibyte . identity)))) @@ -85,6 +95,14 @@ ((fboundp 'char-valid-p) 'char-valid-p) (t 'identity)))) +;; Fixme: This seems always to be used to read a MIME charset, so it +;; should be re-named and fixed (in Emacs) to offer completion only on +;; proper charset names (base coding systems which have a +;; mime-charset defined). XEmacs doesn't believe in mime-charset; +;; test with +;; `(or (coding-system-get 'iso-8859-1 'mime-charset) +;; (coding-system-get 'iso-8859-1 :mime-charset))' +;; Actually, there should be an `mm-coding-system-mime-charset'. (eval-and-compile (defalias 'mm-read-coding-system (cond @@ -106,10 +124,15 @@ (or mm-coding-system-list (setq mm-coding-system-list (mm-coding-system-list)))) -(defun mm-coding-system-p (sym) - "Return non-nil if SYM is a coding system." - (or (and (fboundp 'coding-system-p) (coding-system-p sym)) - (memq sym (mm-get-coding-system-list)))) +(defun mm-coding-system-p (cs) + "Return non-nil if CS is a symbol naming a coding system. +In XEmacs, also return non-nil if CS is a coding system object." + (if (fboundp 'find-coding-system) + (find-coding-system cs) + (if (fboundp 'coding-system-p) + (coding-system-p cs) + ;; Is this branch ever actually useful? + (memq cs (mm-get-coding-system-list))))) (defvar mm-charset-synonym-alist `( @@ -122,9 +145,12 @@ ;; Apparently not defined in Emacs 20, but is a valid MIME name. ,@(unless (mm-coding-system-p 'gb2312) '((gb2312 . cn-gb-2312))) - ;; ISO-8859-15 is very similar to ISO-8859-1. - ,@(unless (mm-coding-system-p 'iso-8859-15) ; Emacs 21 defines it. + ;; ISO-8859-15 is very similar to ISO-8859-1. But it's _different_! + ,@(unless (mm-coding-system-p 'iso-8859-15) '((iso-8859-15 . iso-8859-1))) + ;; BIG-5HKSCS is similar to, but different than, BIG-5. + ,@(unless (mm-coding-system-p 'big5-hkscs) + '((big5-hkscs . big5))) ;; Windows-1252 is actually a superset of Latin-1. See also ;; `gnus-article-dumbquotes-map'. ,@(unless (mm-coding-system-p 'windows-1252) @@ -288,12 +314,12 @@ Valid elements include: ;; Japanese users may prefer iso-2022-jp to shift-jis. '(iso-2022-jp iso-2022-jp-2 japanese-shift-jis iso-latin-1 utf-8))))) - "Preferred coding systems for encoding outgoing mails. + "Preferred coding systems for encoding outgoing messages. -More than one suitable coding system may be found for some text. By -default, the coding system with the highest priority is used to encode -outgoing mails (see `sort-coding-systems'). If this variable is set, -it overrides the default priority." +More than one suitable coding system may be found for some text. +By default, the coding system with the highest priority is used +to encode outgoing messages (see `sort-coding-systems'). If this +variable is set, it overrides the default priority." :type '(repeat (symbol :tag "Coding system")) :group 'mime) @@ -383,19 +409,14 @@ used as the line break code type of the coding system." (boundp 'default-enable-multibyte-characters) default-enable-multibyte-characters (fboundp 'set-buffer-multibyte)) - "Emacs mule.") - - (defvar mm-mule4-p (and mm-emacs-mule - (fboundp 'charsetp) - (not (charsetp 'eight-bit-control))) - "Mule version 4.") + "True in Emacs with Mule.") (if mm-emacs-mule (defun mm-enable-multibyte () "Set the multibyte flag of the current buffer. Only do this if the default value of `enable-multibyte-characters' is non-nil. This is a no-op in XEmacs." - (set-buffer-multibyte t)) + (set-buffer-multibyte 'to)) (defalias 'mm-enable-multibyte 'ignore)) (if mm-emacs-mule @@ -403,27 +424,14 @@ non-nil. This is a no-op in XEmacs." "Unset the multibyte flag of in the current buffer. This is a no-op in XEmacs." (set-buffer-multibyte nil)) - (defalias 'mm-disable-multibyte 'ignore)) - - (if mm-mule4-p - (defun mm-enable-multibyte-mule4 () - "Enable multibyte in the current buffer. -Only used in Emacs Mule 4." - (set-buffer-multibyte t)) - (defalias 'mm-enable-multibyte-mule4 'ignore)) - - (if mm-mule4-p - (defun mm-disable-multibyte-mule4 () - "Disable multibyte in the current buffer. -Only used in Emacs Mule 4." - (set-buffer-multibyte nil)) - (defalias 'mm-disable-multibyte-mule4 'ignore))) + (defalias 'mm-disable-multibyte 'ignore))) (defun mm-preferred-coding-system (charset) ;; A typo in some Emacs versions. (or (get-charset-property charset 'preferred-coding-system) (get-charset-property charset 'prefered-coding-system))) +;; Mule charsets shouldn't be used. (defsubst mm-guess-charset () "Guess Mule charset from the language environment." (or @@ -454,7 +462,7 @@ If the charset is `composition', return the actual one." (setq charset 'ascii) ;; charset-after is fake in some Emacsen. (setq charset (and (fboundp 'char-charset) (char-charset char))) - (if (eq charset 'composition) + (if (eq charset 'composition) ; Mule 4 (let ((p (or pos (point)))) (cadr (find-charset-region p (1+ p)))) (if (and charset (not (memq charset '(ascii eight-bit-control @@ -490,13 +498,23 @@ If the charset is `composition', return the actual one." (setq result (cons head result))) (nreverse result))) -(if (and (not (featurep 'xemacs)) - (boundp 'enable-multibyte-characters)) - (defalias 'mm-multibyte-p - (lambda () - "Say whether multibyte is enabled in the current buffer." - enable-multibyte-characters)) - (defalias 'mm-multibyte-p (lambda () (featurep 'mule)))) +;; Fixme: This is used in places when it should be testing the +;; default multibyteness. See mm-default-multibyte-p. +(eval-and-compile + (if (and (not (featurep 'xemacs)) + (boundp 'enable-multibyte-characters)) + (defun mm-multibyte-p () + "Non-nil if multibyte is enabled in the current buffer." + enable-multibyte-characters) + (defun mm-multibyte-p () (featurep 'mule)))) + +(defun mm-default-multibyte-p () + "Return non-nil if the session is multibyte. +This affects whether coding conversion should be attempted generally." + (if (featurep 'mule) + (if (boundp 'default-enable-multibyte-characters) + default-enable-multibyte-characters + t))) (defun mm-iso-8859-x-to-15-region (&optional b e) (if (fboundp 'char-charset) @@ -553,16 +571,24 @@ charset, and a longer list means no appropriate charset." ;; `compound-text' is not in the IANA list. We ;; shouldn't normally use anything here with a ;; mime-charset having an `x-' prefix. - ;; Fixme: allow this to be overridden, since + ;; Fixme: Allow this to be overridden, since ;; there is existing use of x-ctext. ;; Also people apparently need the coding system - ;; `iso-2022-jp-3', which Mule-UCS defines. + ;; `iso-2022-jp-3' (which Mule-UCS defines with + ;; mime-charset, though it's not valid). (if (and cs - (not (string-match "^[Xx]-" (symbol-name cs)))) + (not (string-match "^[Xx]-" (symbol-name cs))) + ;; UTF-16 of any variety is invalid for + ;; text parts and, unfortunately, has + ;; mime-charset defined both in Mule-UCS + ;; and versions of Emacs. (The name + ;; might be `mule-utf-16...' or + ;; `utf-16...'.) + (not (string-match "utf-16" (symbol-name cs)))) (setq systems nil charsets (list cs)))))) charsets)) - ;; Otherwise we're not multibyte, we're XEmacs or a single + ;; Otherwise we're not multibyte, we're XEmacs, or a single ;; coding system won't cover it. (setq charsets (mm-delete-duplicates @@ -595,7 +621,7 @@ Equivalent to `progn' in XEmacs" (let ((multibyte (make-symbol "multibyte")) (buffer (make-symbol "buffer"))) `(if mm-emacs-mule - (let ((,multibyte enable-multibyte-characters) + (let ((,multibyte enable-multibyte-characters) (,buffer (current-buffer))) (unwind-protect (let (default-enable-multibyte-characters) @@ -608,25 +634,6 @@ Equivalent to `progn' in XEmacs" (put 'mm-with-unibyte-current-buffer 'lisp-indent-function 0) (put 'mm-with-unibyte-current-buffer 'edebug-form-spec '(body)) -(defmacro mm-with-unibyte-current-buffer-mule4 (&rest forms) - "Evaluate FORMS there like `progn' in current buffer. -Mule4 only." - (let ((multibyte (make-symbol "multibyte")) - (buffer (make-symbol "buffer"))) - `(if mm-mule4-p - (let ((,multibyte enable-multibyte-characters) - (,buffer (current-buffer))) - (unwind-protect - (let (default-enable-multibyte-characters) - (set-buffer-multibyte nil) - ,@forms) - (set-buffer ,buffer) - (set-buffer-multibyte ,multibyte))) - (let (default-enable-multibyte-characters) - ,@forms)))) -(put 'mm-with-unibyte-current-buffer-mule4 'lisp-indent-function 0) -(put 'mm-with-unibyte-current-buffer-mule4 'edebug-form-spec '(body)) - (defmacro mm-with-unibyte (&rest forms) "Eval the FORMS with the default value of `enable-multibyte-characters' nil, ." `(let (default-enable-multibyte-characters) @@ -699,10 +706,10 @@ Mule4 only." (defun mm-insert-file-contents (filename &optional visit beg end replace inhibit) - "Like `insert-file-contents', q.v., but only reads in the file. + "Like `insert-file-contents', but only reads in the file. A buffer may be modified in several ways after reading into the buffer due to advanced Emacs features, such as file-name-handlers, format decoding, -find-file-hooks, etc. +`find-file-hooks', etc. If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'. This function ensures that none of these modifications will take place." (let ((format-alist nil) @@ -741,7 +748,8 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'." (append mm-inhibit-file-name-handlers inhibit-file-name-handlers) inhibit-file-name-handlers))) - (append-to-file start end filename))) + (write-region start end filename t 'no-message) + (message "Appended to %s" filename))) (defun mm-write-region (start end filename &optional append visit lockname coding-system inhibit) @@ -771,6 +779,7 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'." (push dir result)) (push path result)))) +;; Fixme: This doesn't look useful where it's used. (if (fboundp 'detect-coding-region) (defun mm-detect-coding-region (start end) "Like `detect-coding-region' except returning the best one." @@ -796,44 +805,6 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'." (let ((cs (mm-detect-coding-region start end))) cs))) -(defun mm-guess-mime-charset () - "Guess the default MIME charset from the language environment." - (let ((language-info - (and (boundp 'current-language-environment) - (assoc current-language-environment - language-info-alist))) - item) - (cond - ((null language-info) - 'iso-8859-1) - ((setq item - (cadr - (or (assq 'coding-priority language-info) - (assq 'coding-system language-info)))) - (if (fboundp 'coding-system-get) - (or (coding-system-get item 'mime-charset) - item) - item)) - ((setq item (car (last (assq 'charset language-info)))) - (if (eq item 'ascii) - 'iso-8859-1 - (mm-mime-charset item))) - (t - 'iso-8859-1)))) - -;; It is not a MIME function, but some MIME functions use it. -(defalias 'mm-make-temp-file - (if (fboundp 'make-temp-file) - 'make-temp-file - (lambda (prefix &optional dir-flag) - (let ((file (expand-file-name - (make-temp-name prefix) - (if (fboundp 'temp-directory) - (temp-directory) - temporary-file-directory)))) - (if dir-flag - (make-directory file)) - file)))) (provide 'mm-util) diff --git a/lisp/mm-uu.el b/lisp/mm-uu.el index a3cad89..269a787 100644 --- a/lisp/mm-uu.el +++ b/lisp/mm-uu.el @@ -76,7 +76,7 @@ decoder, such as hexbin." This can be either \"inline\" or \"attachment\".") (defvar mm-uu-emacs-sources-regexp "gnu\\.emacs\\.sources" - "The regexp of emacs sources groups.") + "The regexp of Emacs sources groups.") (defcustom mm-uu-diff-groups-regexp "gnus\\.commits" "*Regexp matching diff groups." @@ -335,7 +335,7 @@ Return that buffer." ((eq mm-verify-option 'never) nil) ((eq mm-verify-option 'always) t) ((eq mm-verify-option 'known) t) - (t (y-or-n-p "Verify pgp signed part?"))))) + (t (y-or-n-p "Verify pgp signed part? "))))) (eval-when-compile (defvar gnus-newsgroup-charset)) diff --git a/lisp/mm-view.el b/lisp/mm-view.el index 4fba52b..27a873f 100644 --- a/lisp/mm-view.el +++ b/lisp/mm-view.el @@ -54,7 +54,7 @@ (defvar mm-text-html-washer-alist '((w3 . gnus-article-wash-html-with-w3) (w3m . gnus-article-wash-html-with-w3m) - (w3m-standalone mm-inline-render-with-stdin nil + (w3m-standalone mm-inline-wash-with-stdin nil "w3m" "-dump" "-T" "text/html") (links mm-inline-wash-with-file mm-links-remove-leading-blank @@ -197,27 +197,33 @@ (setq mm-w3m-setup t)) (setq w3m-display-inline-images mm-inline-text-html-with-images)) +(defun mm-w3m-cid-retrieve-1 (url handle) + (dolist (elem handle) + (when (and (listp elem) + (equal url (mm-handle-id elem))) + (mm-insert-part elem) + (throw 'found-handle (mm-handle-media-type elem))))) + (defun mm-w3m-cid-retrieve (url &rest args) "Insert a content pointed by URL if it has the cid: scheme." (when (string-match "\\`cid:" url) (setq url (concat "<" (substring url (match-end 0)) ">")) (catch 'found-handle - (dolist (handle (with-current-buffer w3m-current-buffer - gnus-article-mime-handles)) - (when (and (listp handle) - (equal url (mm-handle-id handle))) - (mm-insert-part handle) - (throw 'found-handle (mm-handle-media-type handle))))))) + (let ((handles (with-current-buffer w3m-current-buffer + gnus-article-mime-handles))) + (if (mm-multiple-handles handles) + (dolist (handle handles) + (mm-w3m-cid-retrieve-1 url handle)) + (mm-w3m-cid-retrieve-1 url handles)))))) (eval-and-compile (unless (or (featurep 'xemacs) (>= emacs-major-version 21)) (defvar mm-w3m-mode-map nil - "Keymap for text/html part rendered by `mm-w3m-preview-text/html'. -This map is overwritten by `mm-w3m-local-map-property' based on the -value of `w3m-minor-mode-map'. Therefore, in order to add some -commands to this map, add them to `w3m-minor-mode-map' instead of this -map."))) + "Keymap for text/html parts rendered by emacs-w3m. +This keymap will be bound only when Emacs 20 is running and overwritten +by the value of `w3m-minor-mode-map'. In order to add some commands to +this keymap, add them to `w3m-minor-mode-map' instead of this keymap."))) (defun mm-w3m-local-map-property () (when (and (boundp 'w3m-minor-mode-map) w3m-minor-mode-map) @@ -255,6 +261,7 @@ map."))) (add-text-properties (point-min) (point-max) (nconc (mm-w3m-local-map-property) + ;; Put the mark meaning this part was rendered by emacs-w3m. '(mm-inline-text-html-with-w3m t))))) (mm-handle-set-undisplayer handle @@ -439,7 +446,8 @@ map."))) gnus-article-prepare-hook (gnus-newsgroup-charset (or charset gnus-newsgroup-charset))) - (run-hooks 'gnus-article-decode-hook) + (let ((gnus-original-article-buffer (mm-handle-buffer handle))) + (run-hooks 'gnus-article-decode-hook)) (gnus-article-prepare-display) (setq handles gnus-article-mime-handles)) (goto-char (point-min)) diff --git a/lisp/mml-sec.el b/lisp/mml-sec.el index c18cf2f..c1a494b 100644 --- a/lisp/mml-sec.el +++ b/lisp/mml-sec.el @@ -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 @@ -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,29 +57,39 @@ ("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) - ("pgp" separate) - ("pgpauto" separate) - ("pgpmime" separate)) + ("pgp" combined) + ("pgpauto" combined) + ("pgpmime" combined)) "Alist specifying if `signencrypt' results in two separate operations or not. The first entry indicates the MML security type, valid entries include the strings \"smime\", \"pgp\", and \"pgpmime\". The second entry is a symbol `separate' or `combined' where `separate' means that MML signs and encrypt messages in a two step process, and `combined' means that MML signs and encrypt the message in one step. -Note that the `combined' mode is NOT supported by all OpenPGP implementations, -in particular PGP version 2 does not support it!" + +Note that the output generated by using a `combined' mode is NOT +understood by all PGP implementations, in particular PGP version +2 does not support it! See Info node `(message)Security' for +details." :type '(repeat (list (choice (const :tag "S/MIME" "smime") (const :tag "PGP" "pgp") (const :tag "PGP/MIME" "pgpmime") (string :tag "User defined")) (choice (const :tag "Separate" separate) (const :tag "Combined" combined))))) - + ;;; Configuration/helper functions (defun mml-signencrypt-style (method &optional style) diff --git a/lisp/mml-smime.el b/lisp/mml-smime.el index bccc8a1..45e06d7 100644 --- a/lisp/mml-smime.el +++ b/lisp/mml-smime.el @@ -27,12 +27,16 @@ (require 'smime) (require 'mm-decode) +(autoload 'message-narrow-to-headers "message") (defun mml-smime-sign (cont) (when (null smime-keys) (customize-variable 'smime-keys) (error "No S/MIME keys configured, use customize to add your key")) (smime-sign-buffer (cdr (assq 'keyfile cont))) + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n" t t)) (goto-char (point-max))) (defun mml-smime-encrypt (cont) diff --git a/lisp/mml.el b/lisp/mml.el index 415102d..cdec507 100644 --- a/lisp/mml.el +++ b/lisp/mml.el @@ -54,6 +54,12 @@ These parameters are generated in Content-Disposition header if exists." :type '(repeat (symbol :tag "Parameter")) :group 'message) +(defcustom mml-insert-mime-headers-always nil + "If non-nil, always put Content-Type: text/plain at top of empty parts. +It is necessary to work against a bug in certain clients." + :type 'boolean + :group 'message) + (defvar mml-tweak-type-alist nil "A list of (TYPE . FUNCTION) for tweaking MML parts. TYPE is a string containing a regexp to match the MIME type. FUNCTION @@ -70,7 +76,7 @@ handle to tweak the part.") (defvar mml-tweak-sexp-alist '((mml-externalize-attachments . mml-tweak-externalize-attachments)) "A list of (SEXP . FUNCTION) for tweaking MML parts. -SEXP is a s-expression. If the evaluation of SEXP is non-nil, FUNCTION +SEXP is an s-expression. If the evaluation of SEXP is non-nil, FUNCTION is called. FUNCTION is a Lisp function which is called with the MML handle to tweak the part.") @@ -210,12 +216,12 @@ one charsets.") (if (or (memq 'unknown-encoding mml-confirmation-set) (message-options-get 'unknown-encoding) (and (y-or-n-p "\ -Message contains characters with unknown encoding. Really send?") +Message contains characters with unknown encoding. Really send? ") (message-options-set 'unknown-encoding t))) (if (setq use-ascii (or (memq 'use-ascii mml-confirmation-set) (message-options-get 'use-ascii) - (and (y-or-n-p "Use ASCII as charset?") + (and (y-or-n-p "Use ASCII as charset? ") (message-options-set 'use-ascii t)))) (setq charsets (delq nil charsets)) (setq warn nil)) @@ -424,8 +430,7 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." (+ (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"))) @@ -524,8 +529,11 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." (funcall (cdr handler) cont) ;; No specific handler. Use default one. (let ((mml-boundary (mml-compute-boundary cont))) - (insert (format "Content-Type: multipart/%s; boundary=\"%s\"\n" - type mml-boundary)) + (insert (format "Content-Type: multipart/%s; boundary=\"%s\"" + type mml-boundary) + (if (cdr (assq 'start cont)) + (format "; start=\"%s\"\n" (cdr (assq 'start cont))) + "\n")) (let ((cont cont) part) (while (setq part (pop cont)) ;; Skip `multipart' and attributes. @@ -601,17 +609,18 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." mml-base-boundary)) (defun mml-insert-mime-headers (cont type charset encoding flowed) - (let (parameters disposition description) + (let (parameters id disposition description) (setq parameters (mml-parameter-string cont mml-content-type-parameters)) (when (or charset parameters flowed - (not (equal type mml-generate-default-type))) + (not (equal type mml-generate-default-type)) + mml-insert-mime-headers-always) (when (consp charset) (error - "Can't encode a part with several charsets.")) + "Can't encode a part with several charsets")) (insert "Content-Type: " type) (when charset (insert "; " (mail-header-encode-parameter @@ -622,6 +631,8 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." (mml-insert-parameter-string cont mml-content-type-parameters)) (insert "\n")) + (when (setq id (cdr (assq 'id cont))) + (insert "Content-ID: " id "\n")) (setq parameters (mml-parameter-string cont mml-content-disposition-parameters)) @@ -748,10 +759,12 @@ If HANDLES is non-nil, use it instead reparsing the buffer." (insert "<#/multipart>\n")) (textp (let ((charset (mail-content-type-get - (mm-handle-type handle) 'charset))) + (mm-handle-type handle) 'charset)) + (start (point))) (if (eq charset 'gnus-decoded) (mm-insert-part handle) - (insert (mm-decode-string (mm-get-part handle) charset)))) + (insert (mm-decode-string (mm-get-part handle) charset))) + (mml-quote-region start (point))) (goto-char (point-max))) (t (insert "<#/part>\n"))))) @@ -759,8 +772,12 @@ If HANDLES is non-nil, use it instead reparsing the buffer." (defun mml-insert-mml-markup (handle &optional buffer nofile mmlp) "Take a MIME handle and insert an MML tag." (if (stringp (car handle)) - (insert "<#multipart type=" (mm-handle-media-subtype handle) - ">\n") + (progn + (insert "<#multipart type=" (mm-handle-media-subtype handle)) + (let ((start (mm-handle-multipart-ctl-parameter handle 'start))) + (when start + (insert " start=\"" start "\""))) + (insert ">\n")) (if mmlp (insert "<#mml type=" (mm-handle-media-type handle)) (insert "<#part type=" (mm-handle-media-type handle))) @@ -768,6 +785,8 @@ If HANDLES is non-nil, use it instead reparsing the buffer." (cdr (mm-handle-disposition handle)))) (unless (symbolp (cdr elem)) (insert " " (symbol-name (car elem)) "=\"" (cdr elem) "\""))) + (when (mm-handle-id handle) + (insert " id=\"" (mm-handle-id handle) "\"")) (when (mm-handle-disposition handle) (insert " disposition=" (car (mm-handle-disposition handle)))) (when buffer @@ -916,6 +935,19 @@ See Info node `(emacs-mime)Composing'. (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") @@ -958,7 +990,7 @@ See Info node `(emacs-mime)Composing'. ;;; 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]'. @@ -969,10 +1001,14 @@ description of the attachment." (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. @@ -1041,6 +1077,8 @@ If RAW, don't highlight the article." (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) diff --git a/lisp/mml1991.el b/lisp/mml1991.el index 741cfe2..dbd980b 100644 --- a/lisp/mml1991.el +++ b/lisp/mml1991.el @@ -104,7 +104,7 @@ (while (looking-at "^Content[^ ]+:") (forward-line)) (unless (bobp) (delete-region (point-min) (point))) - (mm-with-unibyte-current-buffer-mule4 + (mm-with-unibyte-current-buffer (with-temp-buffer (setq cipher (current-buffer)) (insert-buffer-substring text) @@ -178,7 +178,7 @@ (while (looking-at "^Content[^ ]+:") (forward-line)) (unless (bobp) (delete-region (point-min) (point))) - (mm-with-unibyte-current-buffer-mule4 + (mm-with-unibyte-current-buffer (with-temp-buffer (flet ((gpg-encrypt-func (sign plaintext ciphertext result recipients &optional @@ -223,7 +223,7 @@ (defvar pgg-errors-buffer) (defun mml1991-pgg-sign (cont) - (let (headers) + (let (headers cte) ;; Don't sign headers. (goto-char (point-min)) (while (not (looking-at "^$")) @@ -232,31 +232,39 @@ (setq headers (buffer-substring (point-min) (point))) (forward-line) ;; skip header/body separator (delete-region (point-min) (point))) - (quoted-printable-decode-region (point-min) (point-max)) + (when (string-match "^Content-Transfer-Encoding: \\(.+\\)" headers) + (setq cte (intern (match-string 1 headers)))) + (mm-decode-content-transfer-encoding cte) (unless (let ((pgg-default-user-id - (or (message-options-get 'message-sender) + (or (message-options-get 'mml-sender) pgg-default-user-id))) (pgg-sign-region (point-min) (point-max) t)) (pop-to-buffer pgg-errors-buffer) (error "Encrypt error")) (delete-region (point-min) (point-max)) - (insert-buffer-substring pgg-output-buffer) - (goto-char (point-min)) - (while (re-search-forward "\r+$" nil t) - (replace-match "" t t)) - (quoted-printable-encode-region (point-min) (point-max)) - (goto-char (point-min)) - (if headers (insert headers)) - (insert "\n") + (mm-with-unibyte-current-buffer + (insert-buffer-substring pgg-output-buffer) + (goto-char (point-min)) + (while (re-search-forward "\r+$" nil t) + (replace-match "" t t)) + (mm-encode-content-transfer-encoding cte) + (goto-char (point-min)) + (when headers + (insert headers)) + (insert "\n")) t)) (defun mml1991-pgg-encrypt (cont &optional sign) - (let (headers) + (let (cte) ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED (goto-char (point-min)) - (while (looking-at "^Content[^ ]+:") (forward-line)) + (while (looking-at "^Content[^ ]+:") + (when (looking-at "^Content-Transfer-Encoding: \\(.+\\)") + (setq cte (intern (match-string 1)))) + (forward-line)) (unless (bobp) (delete-region (point-min) (point))) + (mm-decode-content-transfer-encoding cte) (unless (pgg-encrypt-region (point-min) (point-max) (split-string diff --git a/lisp/mml2015.el b/lisp/mml2015.el index ef2fe9f..6bf4f4e 100644 --- a/lisp/mml2015.el +++ b/lisp/mml2015.el @@ -32,6 +32,7 @@ (eval-when-compile (require 'gnus-clfns)) (require 'mm-decode) (require 'mm-util) +(require 'mml) (defvar mml2015-use (or (progn @@ -277,8 +278,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) @@ -330,7 +330,7 @@ (or (y-or-n-p "Sign the message? ") 'not)))) 'never))) - (mm-with-unibyte-current-buffer-mule4 + (mm-with-unibyte-current-buffer (mc-encrypt-generic (or (message-options-get 'message-recipients) (message-options-set 'message-recipients @@ -341,8 +341,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 +543,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,11 +576,10 @@ (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-mule4 + (mm-with-unibyte-current-buffer (with-temp-buffer ;; set up a function to call the correct gpg encrypt routine ;; with the right arguments. (FIXME: this should be done @@ -807,7 +804,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 +826,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 diff --git a/lisp/nnbabyl.el b/lisp/nnbabyl.el index 8cecb1e..0dd568d 100644 --- a/lisp/nnbabyl.el +++ b/lisp/nnbabyl.el @@ -350,7 +350,10 @@ (while (re-search-backward "^X-Gnus-Newsgroup: " beg t) (delete-region (point) (progn (forward-line 1) (point))))) (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject") + (nnmail-fetch-field "from"))) (setq result (if (stringp group) (list (cons group (nnbabyl-active-number group))) @@ -366,7 +369,10 @@ (insert-buffer-substring buf) (when last (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject") + (nnmail-fetch-field "from"))) (save-buffer) (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)) result)))) diff --git a/lisp/nndiary.el b/lisp/nndiary.el index 42cb838..51cbd9a 100644 --- a/lisp/nndiary.el +++ b/lisp/nndiary.el @@ -759,7 +759,9 @@ all. This may very well take some time.") (when (nndiary-schedule) (let (result) (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject"))) (if (stringp group) (and (nnmail-activate 'nndiary) diff --git a/lisp/nndoc.el b/lisp/nndoc.el index 73a7582..2c008f3 100644 --- a/lisp/nndoc.el +++ b/lisp/nndoc.el @@ -58,6 +58,13 @@ from the document.") `((mmdf (article-begin . "^\^A\^A\^A\^A\n") (body-end . "^\^A\^A\^A\^A\n")) + (mime-digest + (article-begin . "") + (head-begin . "^ ?\n") + (head-end . "^ ?$") + (body-end . "") + (file-end . "") + (subtype digest guess)) (mime-parts (generate-head-function . nndoc-generate-mime-parts-head) (article-transform-function . nndoc-transform-mime-parts)) @@ -94,13 +101,7 @@ from the document.") (head-end . "^\t") (generate-head-function . nndoc-generate-clari-briefs-head) (article-transform-function . nndoc-transform-clari-briefs)) - (mime-digest - (article-begin . "") - (head-begin . "^ ?\n") - (head-end . "^ ?$") - (body-end . "") - (file-end . "") - (subtype digest guess)) + (standard-digest (first-article . ,(concat "^" (make-string 70 ?-) "\n *\n+")) (article-begin . ,(concat "^\n" (make-string 30 ?-) "\n *\n+")) @@ -393,7 +394,7 @@ from the document.") (error "Document is not of any recognized type")) (if result (car entry) - (cadar (sort results 'car-less-than-car))))) + (cadar (last (sort results 'car-less-than-car)))))) ;;; ;;; Built-in type predicates and functions @@ -771,7 +772,7 @@ from the document.") "Go through the document and partition it into heads/bodies/articles." (let ((i 0) (first t) - head-begin head-end body-begin body-end) + art-begin head-begin head-end body-begin body-end) (setq nndoc-dissection-alist nil) (save-excursion (set-buffer nndoc-current-buffer) @@ -787,8 +788,11 @@ from the document.") ;; Go through the file. (while (if (and first nndoc-first-article) (nndoc-search nndoc-first-article) - (nndoc-article-begin)) - (setq first nil) + (if art-begin + (goto-char art-begin) + (nndoc-article-begin))) + (setq first nil + art-begin nil) (cond (nndoc-head-begin-function (funcall nndoc-head-begin-function)) (nndoc-head-begin @@ -808,7 +812,8 @@ from the document.") (funcall nndoc-body-end-function)) (and nndoc-body-end (nndoc-search nndoc-body-end)) - (nndoc-article-begin) + (and (nndoc-article-begin) + (setq art-begin (point))) (progn (goto-char (point-max)) (when nndoc-file-end diff --git a/lisp/nndraft.el b/lisp/nndraft.el index bd27cfe..0f978cb 100644 --- a/lisp/nndraft.el +++ b/lisp/nndraft.el @@ -199,9 +199,19 @@ (deffoo nndraft-request-move-article (article group server accept-form &optional last) (nndraft-possibly-change-group group) - (let ((nnmh-allow-delete-final t)) - (nnoo-parent-function 'nndraft 'nndraft-request-move-article - (list article group server accept-form last)))) + (let ((buf (get-buffer-create " *nndraft move*")) + result) + (and + (nndraft-request-article article group server) + (save-excursion + (set-buffer buf) + (erase-buffer) + (insert-buffer-substring nntp-server-buffer) + (setq result (eval accept-form)) + (kill-buffer (current-buffer)) + result) + (null (nndraft-request-expire-articles (list article) group server 'force)) + result))) (deffoo nndraft-request-expire-articles (articles group &optional server force) (nndraft-possibly-change-group group) diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el index 448ada4..1102078 100644 --- a/lisp/nnfolder.el +++ b/lisp/nnfolder.el @@ -526,7 +526,10 @@ the group. Then the marks file will be regenerated properly by Gnus.") (while (re-search-backward (concat "^" nnfolder-article-marker) nil t) (delete-region (point) (progn (forward-line 1) (point)))) (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject") + (nnmail-fetch-field "from"))) (setq result (if (stringp group) (list (cons group (nnfolder-active-number group))) (setq art-group @@ -722,15 +725,15 @@ deleted. Point is left where the deleted region was." (setq nnfolder-current-group group nnfolder-current-buffer nil) (let (inf file) - ;; If we have to change groups, see if we don't already have the - ;; folder in memory. If we do, verify the modtime and destroy - ;; the folder if needed so we can rescan it. + ;; If we have to change groups, see if we don't already have + ;; the folder in memory. If we do, verify the modtime and + ;; destroy the folder if needed so we can rescan it. (setq nnfolder-current-buffer (nth 1 (assoc group nnfolder-buffer-alist))) - ;; If the buffer is not live, make sure it isn't in the alist. If it - ;; is live, verify that nobody else has touched the file since last - ;; time. + ;; If the buffer is not live, make sure it isn't in the + ;; alist. If it is live, verify that nobody else has + ;; touched the file since last time. (when (and nnfolder-current-buffer (not (gnus-buffer-live-p nnfolder-current-buffer))) (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist) @@ -873,6 +876,7 @@ deleted. Point is left where the deleted region was." (let ((nnheader-file-coding-system nnfolder-file-coding-system)) (nnheader-find-file-noselect file))))) + (set-buffer-multibyte t) ;; Use multibyte buffer for future copying. (if (equal (cadr (assoc group nnfolder-scantime-alist)) (nth 5 (file-attributes file))) ;; This looks up-to-date, so we don't do any scanning. @@ -916,12 +920,12 @@ deleted. Point is left where the deleted region was." (setq articles (nreverse articles)))) (goto-char (point-min)) - ;; Anytime the active number is 1 or 0, it is suspect. In that - ;; case, search the file manually to find the active number. Or, - ;; of course, if we're being paranoid. (This would also be the - ;; place to build other lists from the header markers, such as - ;; expunge lists, etc., if we ever desired to abandon the active - ;; file entirely for mboxes.) + ;; Anytime the active number is 1 or 0, it is suspect. In + ;; that case, search the file manually to find the active + ;; number. Or, of course, if we're being paranoid. (This + ;; would also be the place to build other lists from the + ;; header markers, such as expunge lists, etc., if we ever + ;; desired to abandon the active file entirely for mboxes.) (when (or nnfolder-ignore-active-file novbuf (< maxid 2)) @@ -948,10 +952,11 @@ deleted. Point is left where the deleted region was." (setcdr active (max maxid (cdr active))) (goto-char (point-min))) - ;; As long as we trust that the user will only insert unmarked mail - ;; at the end, go to the end and search backwards for the last - ;; marker. Find the start of that message, and begin to search for - ;; unmarked messages from there. + ;; As long as we trust that the user will only insert + ;; unmarked mail at the end, go to the end and search + ;; backwards for the last marker. Find the start of that + ;; message, and begin to search for unmarked messages from + ;; there. (when (not (or nnfolder-distrust-mbox (< maxid 2))) (goto-char (point-max)) @@ -961,9 +966,9 @@ deleted. Point is left where the deleted region was." ;; (goto-char (point-min))) ) - ;; Keep track of the active number on our own, and insert it back - ;; into the active list when we're done. Also, prime the pump to - ;; cut down on the number of searches we do. + ;; Keep track of the active number on our own, and insert it + ;; back into the active list when we're done. Also, prime + ;; the pump to cut down on the number of searches we do. (unless (nnmail-search-unix-mail-delim) (goto-char (point-max))) (setq end (point-marker)) @@ -994,7 +999,8 @@ deleted. Point is left where the deleted region was." (widen))) (set-marker end nil) - ;; Make absolutely sure that the active list reflects reality! + ;; Make absolutely sure that the active list reflects + ;; reality! (nnfolder-save-active nnfolder-group-alist nnfolder-active-file) ;; Set the scantime for this group. diff --git a/lisp/nnheader.el b/lisp/nnheader.el index b994e58..49f2ba5 100644 --- a/lisp/nnheader.el +++ b/lisp/nnheader.el @@ -39,6 +39,7 @@ ;;(eval-when-compile (require 'gnus-util)) (require 'mail-utils) +(require 'gnus-util) ;; Reduce the required value of `recursive-load-depth-limit' for Emacs 21. (require 'pces) @@ -82,10 +83,10 @@ Integer values will in effect be rounded up to the nearest multiple of (defvar nnheader-read-timeout (if (string-match "windows-nt\\|os/2\\|emx\\|cygwin" (symbol-name system-type)) - 1.0 + 1.0 ; why? 0.1) "How long nntp should wait between checking for the end of output. -Shorter values mean quicker response, but is more CPU intensive.") +Shorter values mean quicker response, but are more CPU intensive.") (defvar nnheader-file-name-translation-alist (let ((case-fold-search t)) @@ -311,16 +312,18 @@ nil, ." ;; mail-parse stuff. (unless (featurep 'mail-parse) - ;; Should keep track of `rfc2047-narrow-to-field' in rfc2047.el. - (defun-maybe std11-narrow-to-field () - "Narrow the buffer to the header on the current line." - (forward-line 0) - (narrow-to-region (point) - (progn - (std11-field-end) - (when (eolp) (forward-line 1)) - (point))) - (goto-char (point-min))) + (unless (fboundp 'std11-narrow-to-field) + (defalias 'std11-narrow-to-field + ;; Should keep track of `rfc2047-narrow-to-field' in rfc2047.el. + (lambda () + "Narrow the buffer to the header on the current line." + (forward-line 0) + (narrow-to-region (point) + (progn + (std11-field-end) + (when (eolp) (forward-line 1)) + (point))) + (goto-char (point-min))))) (defalias 'mail-header-narrow-to-field 'std11-narrow-to-field) ;; Should keep track of `ietf-drums-narrow-to-header' in ietf-drums.el. @@ -333,128 +336,136 @@ nil, ." (point-max))) (goto-char (point-min))) - ;; Should keep track of `rfc2047-fold-region' in rfc2047.el. - (defun-maybe std11-fold-region (b e) - "Fold long lines in region B to E." - (save-restriction - (narrow-to-region b e) - (goto-char (point-min)) - (let ((break nil) - (qword-break nil) - (first t) - (bol (save-restriction - (widen) - (gnus-point-at-bol)))) - (while (not (eobp)) - (when (and (or break qword-break) - (> (- (point) bol) 76)) - (goto-char (or break qword-break)) - (setq break nil - qword-break nil) - (if (looking-at "[ \t]") - (insert "\n") - (insert "\n ")) - (setq bol (1- (point))) - ;; Don't break before the first non-LWSP characters. - (skip-chars-forward " \t") - (unless (eobp) - (forward-char 1))) - (cond - ((eq (char-after) ?\n) - (forward-char 1) - (setq bol (point) - break nil - qword-break nil) - (skip-chars-forward " \t") - (unless (or (eobp) (eq (char-after) ?\n)) - (forward-char 1))) - ((eq (char-after) ?\r) - (forward-char 1)) - ((memq (char-after) '(? ?\t)) - (skip-chars-forward " \t") - (if first - ;; Don't break just after the header name. - (setq first nil) - (setq break (1- (point))))) - ((not break) - (if (not (looking-at "=\\?[^=]")) - (if (eq (char-after) ?=) - (forward-char 1) - (skip-chars-forward "^ \t\n\r=")) - (setq qword-break (point)) - (skip-chars-forward "^ \t\n\r"))) - (t - (skip-chars-forward "^ \t\n\r")))) - (when (and (or break qword-break) - (> (- (point) bol) 76)) - (goto-char (or break qword-break)) - (setq break nil - qword-break nil) - (if (looking-at "[ \t]") - (insert "\n") - (insert "\n ")) - (setq bol (1- (point))) - ;; Don't break before the first non-LWSP characters. - (skip-chars-forward " \t") - (unless (eobp) - (forward-char 1)))))) - - ;; Should keep track of `rfc2047-fold-field' in rfc2047.el. - (defun-maybe std11-fold-field () - "Fold the current line." - (save-excursion - (save-restriction - (std11-narrow-to-field) - (std11-fold-region (point-min) (point-max))))) - + (unless (fboundp 'std11-fold-region) + (defalias 'std11-fold-region + ;; Should keep track of `rfc2047-fold-region' in rfc2047.el. + (lambda (b e) + "Fold long lines in region B to E." + (save-restriction + (narrow-to-region b e) + (goto-char (point-min)) + (let ((break nil) + (qword-break nil) + (first t) + (bol (save-restriction + (widen) + (gnus-point-at-bol)))) + (while (not (eobp)) + (when (and (or break qword-break) + (> (- (point) bol) 76)) + (goto-char (or break qword-break)) + (setq break nil + qword-break nil) + (if (looking-at "[ \t]") + (insert "\n") + (insert "\n ")) + (setq bol (1- (point))) + ;; Don't break before the first non-LWSP characters. + (skip-chars-forward " \t") + (unless (eobp) + (forward-char 1))) + (cond + ((eq (char-after) ?\n) + (forward-char 1) + (setq bol (point) + break nil + qword-break nil) + (skip-chars-forward " \t") + (unless (or (eobp) (eq (char-after) ?\n)) + (forward-char 1))) + ((eq (char-after) ?\r) + (forward-char 1)) + ((memq (char-after) '(? ?\t)) + (skip-chars-forward " \t") + (if first + ;; Don't break just after the header name. + (setq first nil) + (setq break (1- (point))))) + ((not break) + (if (not (looking-at "=\\?[^=]")) + (if (eq (char-after) ?=) + (forward-char 1) + (skip-chars-forward "^ \t\n\r=")) + (setq qword-break (point)) + (skip-chars-forward "^ \t\n\r"))) + (t + (skip-chars-forward "^ \t\n\r")))) + (when (and (or break qword-break) + (> (- (point) bol) 76)) + (goto-char (or break qword-break)) + (setq break nil + qword-break nil) + (if (looking-at "[ \t]") + (insert "\n") + (insert "\n ")) + (setq bol (1- (point))) + ;; Don't break before the first non-LWSP characters. + (skip-chars-forward " \t") + (unless (eobp) + (forward-char 1)))))))) + + (unless (fboundp 'std11-fold-field) + (defalias 'std11-fold-field + ;; Should keep track of `rfc2047-fold-field' in rfc2047.el. + (lambda () + "Fold the current line." + (save-excursion + (save-restriction + (std11-narrow-to-field) + (std11-fold-region (point-min) (point-max))))))) (defalias 'mail-header-fold-field 'std11-fold-field) - ;; Should keep track of `rfc2047-unfold-region' in rfc2047.el. - (defun-maybe std11-unfold-region (b e) - "Unfold lines in region B to E." - (save-restriction - (narrow-to-region b e) - (goto-char (point-min)) - (let ((bol (save-restriction - (widen) - (gnus-point-at-bol))) - (eol (gnus-point-at-eol))) - (forward-line 1) - (while (not (eobp)) - (if (and (looking-at "[ \t]") - (< (- (gnus-point-at-eol) bol) 76)) - (delete-region eol (progn - (goto-char eol) - (skip-chars-forward "\r\n") - (point))) - (setq bol (gnus-point-at-bol))) - (setq eol (gnus-point-at-eol)) - (forward-line 1))))) - - ;; Should keep track of `rfc2047-unfold-field' in rfc2047.el. - (defun-maybe std11-unfold-field () - "Fold the current line." - (save-excursion - (save-restriction - (std11-narrow-to-field) - (std11-unfold-region (point-min) (point-max))))) - + (unless (fboundp 'std11-unfold-region) + (defalias 'std11-unfold-region + ;; Should keep track of `rfc2047-unfold-region' in rfc2047.el. + (lambda (b e) + "Unfold lines in region B to E." + (save-restriction + (narrow-to-region b e) + (goto-char (point-min)) + (let ((bol (save-restriction + (widen) + (gnus-point-at-bol))) + (eol (gnus-point-at-eol))) + (forward-line 1) + (while (not (eobp)) + (if (and (looking-at "[ \t]") + (< (- (gnus-point-at-eol) bol) 76)) + (delete-region eol (progn + (goto-char eol) + (skip-chars-forward "\r\n") + (point))) + (setq bol (gnus-point-at-bol))) + (setq eol (gnus-point-at-eol)) + (forward-line 1))))))) + + (unless (fboundp 'std11-unfold-field) + (defalias 'std11-unfold-field + ;; Should keep track of `rfc2047-unfold-field' in rfc2047.el. + (lambda () + "Fold the current line." + (save-excursion + (save-restriction + (std11-narrow-to-field) + (std11-unfold-region (point-min) (point-max))))))) (defalias 'mail-header-unfold-field 'std11-unfold-field) - ;; This is the original function in T-gnus. - (defun-maybe std11-extract-addresses-components (string) - "Extract a list of full name and canonical address from STRING. Each + (unless (fboundp 'std11-extract-addresses-components) + (defalias 'std11-extract-addresses-components + ;; This is the original function in T-gnus. + (lambda (string) + "Extract a list of full name and canonical address from STRING. Each element looks like a list of the form (FULL-NAME CANONICAL-ADDRESS). If no name can be extracted, FULL-NAME will be nil." - (when string - (let (addresses) - (dolist (structure (std11-parse-addresses-string - (std11-unfold-string string)) - addresses) - (push (list (std11-full-name-string structure) - (std11-address-string structure)) - addresses)) - (nreverse addresses)))) + (when string + (let (addresses) + (dolist (structure (std11-parse-addresses-string + (std11-unfold-string string)) + addresses) + (push (list (std11-full-name-string structure) + (std11-address-string structure)) + addresses)) + (nreverse addresses)))))) ;; Should keep track of `ietf-drums-parse-addresses' in ietf-drums.el. (defun mail-header-parse-addresses (string) @@ -485,7 +496,6 @@ given, the return value will not contain the last newline." (setq value (buffer-substring start (point))))) (goto-char begin) value)) - (defalias 'mail-header-field-value 'std11-field-value)) ;; ietf-drums stuff. @@ -1450,11 +1460,6 @@ without formatting." ((numberp file) (int-to-string file)) (t file)))) -(defun nnheader-functionp (form) - "Return non-nil if FORM is funcallable." - (or (and (symbolp form) (fboundp form)) - (and (listp form) (eq (car form) 'lambda)))) - (defun nnheader-concat (dir &rest files) "Concat DIR as directory to FILES." (apply 'concat (file-name-as-directory dir) files)) @@ -1468,13 +1473,15 @@ without formatting." "Return the file size of FILE or 0." (or (nth 7 (file-attributes file)) 0)) -(defun nnheader-find-etc-directory (package &optional file) +(defun nnheader-find-etc-directory (package &optional file first) "Go through `load-path' and find the \"../etc/PACKAGE\" directory. This function will look in the parent directory of each `load-path' entry, and look for the \"etc\" directory there. -If FILE, find the \".../etc/PACKAGE\" file instead." +If FILE, find the \".../etc/PACKAGE\" file instead. +If FIRST is non-nil, return the directory or the file found at the +first. Otherwise, find the newest one, though it may take a time." (let ((path load-path) - dir result) + dir results) ;; We try to find the dir by looking at the load path, ;; stripping away the last component and adding "etc/". (while path @@ -1486,10 +1493,14 @@ If FILE, find the \".../etc/PACKAGE\" file instead." "etc/" package (if file "" "/")))) (or file (file-directory-p dir))) - (setq result dir - path nil) + (progn + (or (member dir results) + (push dir results)) + (setq path (if first nil (cdr path)))) (setq path (cdr path)))) - result)) + (if (or first (not (cdr results))) + (car results) + (car (sort results 'file-newer-than-file-p))))) (eval-when-compile (defvar ange-ftp-path-format) diff --git a/lisp/nnheaderxm.el b/lisp/nnheaderxm.el index ea5df2f..af0979c 100644 --- a/lisp/nnheaderxm.el +++ b/lisp/nnheaderxm.el @@ -1,6 +1,6 @@ ;;; nnheaderxm.el --- making Gnus backends work under XEmacs -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -28,12 +28,67 @@ ;;; Code: -(defun nnheader-xmas-run-at-time (time repeat function &rest args) - (start-itimer - "nnheader-run-at-time" - `(lambda () - (,function ,@args)) - time repeat)) +(if (condition-case nil + (progn + (unless (or itimer-process itimer-timer) + (itimer-driver-start)) + ;; Check whether there is a bug to which the difference of + ;; the present time and the time when the itimer driver was + ;; woken up is subtracted from the initial itimer value. + (let* ((inhibit-quit t) + (ctime (current-time)) + (itimer-timer-last-wakeup + (prog1 + ctime + (setcar ctime (1- (car ctime))))) + (itimer-list nil) + (itimer (start-itimer "nnheader-run-at-time" 'ignore 5))) + (sleep-for 0.1) ;; Accept the timeout interrupt. + (prog1 + (> (itimer-value itimer) 0) + (delete-itimer itimer)))) + (error nil)) + (defun nnheader-xmas-run-at-time (time repeat function &rest args) + "Emulating function run as `run-at-time'. +TIME should be nil meaning now, or a number of seconds from now. +Return an itimer object which can be used in either `delete-itimer' +or `cancel-timer'." + (apply #'start-itimer "nnheader-run-at-time" + function (if time (max time 1e-9) 1e-9) + repeat nil t args)) + (defun nnheader-xmas-run-at-time (time repeat function &rest args) + "Emulating function run as `run-at-time' in the right way. +TIME should be nil meaning now, or a number of seconds from now. +Return an itimer object which can be used in either `delete-itimer' +or `cancel-timer'." + (let ((itimers (list nil))) + (setcar + itimers + (apply #'start-itimer "nnheader-run-at-time" + (lambda (itimers repeat function &rest args) + (let ((itimer (car itimers))) + (if repeat + (progn + (set-itimer-function + itimer + (lambda (itimer repeat function &rest args) + (set-itimer-restart itimer repeat) + (set-itimer-function itimer function) + (set-itimer-function-arguments itimer args) + (apply function args))) + (set-itimer-function-arguments + itimer + (append (list itimer repeat function) args))) + (set-itimer-function + itimer + (lambda (itimer function &rest args) + (delete-itimer itimer) + (apply function args))) + (set-itimer-function-arguments + itimer + (append (list itimer function) args))))) + 1e-9 (if time (max time 1e-9) 1e-9) + nil t itimers repeat function args))))) (defun nnheader-xmas-Y-or-n-p (prompt) "Ask user a \"Y/n\" question. Return t if answer is neither \"n\", \"N\" nor \"C-g\"." diff --git a/lisp/nnimap.el b/lisp/nnimap.el index 306f54e..7001a0d 100644 --- a/lisp/nnimap.el +++ b/lisp/nnimap.el @@ -72,6 +72,8 @@ (require 'gnus-start) (require 'gnus-int) +(eval-when-compile (require 'cl)) + (nnoo-declare nnimap) (defconst nnimap-version "nnimap 1.0") @@ -720,9 +722,11 @@ If EXAMINE is non-nil the group is selected read-only." (port (if nnimap-server-port (int-to-string nnimap-server-port) "imap")) - (alist (gnus-netrc-machine list (or nnimap-server-address - nnimap-address server) - port "imap")) + (alist (or (gnus-netrc-machine list server port "imap") + (gnus-netrc-machine list + (or nnimap-server-address + nnimap-address) + port "imap"))) (user (gnus-netrc-get alist "login")) (passwd (gnus-netrc-get alist "password"))) (if (imap-authenticate user passwd nnimap-server-buffer) @@ -1272,7 +1276,7 @@ function is generally only called when Gnus is shutting down." nnimap-split-download-body-default nnimap-split-download-body) (and (nnimap-request-article article) - (mail-narrow-to-head)) + (with-current-buffer nntp-server-buffer (mail-narrow-to-head))) (nnimap-request-head article)) ;; copy article to right group(s) (setq removeorig nil) @@ -1291,7 +1295,9 @@ function is generally only called when Gnus is shutting down." (let (msgid) (and (setq msgid (nnmail-fetch-field "message-id")) - (nnmail-cache-insert msgid to-group))))) + (nnmail-cache-insert msgid + to-group + (nnmail-fetch-field "subject")))))) ;; Add the group-art list to the history list. (push (list (cons to-group 0)) nnmail-split-history)) (t @@ -1325,7 +1331,7 @@ function is generally only called when Gnus is shutting down." (nnimap-before-find-minmax-bugworkaround) (dolist (pattern (nnimap-pattern-to-list-arguments nnimap-list-pattern)) - (dolist (mbx (imap-mailbox-lsub "*" (car pattern) nil + (dolist (mbx (imap-mailbox-lsub (cdr pattern) (car pattern) nil nnimap-server-buffer)) (or (catch 'found (dolist (mailbox (imap-mailbox-get 'list-flags mbx @@ -1468,7 +1474,8 @@ function is generally only called when Gnus is shutting down." (replace-match "\r\n")) (when nnmail-cache-accepted-message-ids (nnmail-cache-insert (nnmail-fetch-field "message-id") - group))) + group + (nnmail-fetch-field "subject")))) (when (and last nnmail-cache-accepted-message-ids) (nnmail-cache-close)) ;; this 'or' is for Cyrus server bug diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 06ee776..3e52196 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -355,13 +355,81 @@ discarded after running the split process." :type 'hook) (defcustom nnmail-large-newsgroup 50 - "*The number of the articles which indicates a large newsgroup or nil. -If the number of the articles is greater than the value, verbose + "*The number of articles which indicates a large newsgroup or nil. +If the number of articles is greater than the value, verbose messages will be shown to indicate the current status." :group 'nnmail-various :type '(choice (const :tag "infinite" nil) (number :tag "count"))) +(define-widget 'nnmail-lazy 'default + "Base widget for recursive datastructures. + +This is copy of the `lazy' widget in Emacs 21.4 provided for compatibility." + :format "%{%t%}: %v" + :convert-widget 'widget-value-convert-widget + :value-create (lambda (widget) + (let ((value (widget-get widget :value)) + (type (widget-get widget :type))) + (widget-put widget :children + (list (widget-create-child-value + widget (widget-convert type) value))))) + :value-delete 'widget-children-value-delete + :value-get (lambda (widget) + (widget-value (car (widget-get widget :children)))) + :value-inline (lambda (widget) + (widget-apply (car (widget-get widget :children)) + :value-inline)) + :default-get (lambda (widget) + ;;(widget-default-get + ;; (widget-convert (widget-get widget :type)))) + ;; `widget-default-get' isn't available in Mule 2. + (let ((w (widget-convert (widget-get widget :type)))) + (or (widget-get w :value) + (widget-apply w :default-get)))) + :match (lambda (widget value) + (widget-apply (widget-convert (widget-get widget :type)) + :match value)) + :validate (lambda (widget) + (widget-apply (car (widget-get widget :children)) :validate))) + +(define-widget 'nnmail-split-fancy 'nnmail-lazy + "Widget for customizing splits in the variable of the same name." + :tag "Split" + :type '(menu-choice :value (any ".*value.*" "misc") + :tag "Type" + (string :tag "Destination") + (list :tag "Use first match (|)" :value (|) + (const :format "" |) + (editable-list :inline t nnmail-split-fancy)) + (list :tag "Use all matches (&)" :value (&) + (const :format "" &) + (editable-list :inline t nnmail-split-fancy)) + (list :tag "Function with fixed arguments (:)" + :value (: nil) + (const :format "" :value :) + function + (editable-list :inline t (sexp :tag "Arg")) + ) + (list :tag "Function with split arguments (!)" + :value (! nil) + (const :format "" !) + function + (editable-list :inline t nnmail-split-fancy)) + (list :tag "Field match" + (choice :tag "Field" + regexp symbol) + (choice :tag "Match" + regexp + (symbol :value mail)) + (repeat :inline t + :tag "Restrictions" + (group :inline t + (const :format "" -) + regexp)) + nnmail-split-fancy) + (const :tag "Junk (delete mail)" junk))) + (defcustom nnmail-split-fancy "mail.misc" "Incoming mail can be split according to this fancy variable. To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'. @@ -437,8 +505,7 @@ Example: ;; Unmatched mail goes to the catch all group. \"misc.misc\"))" :group 'nnmail-split - ;; Sigh! - :type 'sexp) + :type 'nnmail-split-fancy) (defcustom nnmail-split-abbrev-alist '((any . "from\\|to\\|cc\\|sender\\|apparently-to\\|resent-from\\|resent-to\\|resent-cc") @@ -502,6 +569,15 @@ parameter. It should return nil, `warn' or `delete'." :group 'nnmail :type 'boolean) +(defcustom nnmail-split-fancy-match-partial-words nil + "Whether to match partial words when fancy splitting. +Normally, regexes given in `nnmail-split-fancy' are implicitly surrounded +by \"\\=\\<...\\>\". If this variable is true, they are not implicitly\ + surrounded +by anything." + :group 'nnmail + :type 'boolean) + ;;; Internal variables. (defvar nnmail-article-buffer " *nnmail incoming*" @@ -510,13 +586,12 @@ parameter. It should return nil, `warn' or `delete'." (defvar nnmail-split-history nil "List of group/article elements that say where the previous split put messages.") -(defvar nnmail-split-fancy-syntax-table nil +(defvar nnmail-split-fancy-syntax-table + (let ((table (make-syntax-table))) + ;; support the %-hack + (modify-syntax-entry ?\% "." table) + table) "Syntax table used by `nnmail-split-fancy'.") -(unless (syntax-table-p nnmail-split-fancy-syntax-table) - (setq nnmail-split-fancy-syntax-table - (copy-syntax-table (standard-syntax-table))) - ;; support the %-hack - (modify-syntax-entry ?\% "." nnmail-split-fancy-syntax-table)) (defvar nnmail-prepare-save-mail-hook nil "Hook called before saving mail.") @@ -526,11 +601,6 @@ parameter. It should return nil, `warn' or `delete'." -(defconst nnmail-version "nnmail 1.0" - "nnmail version.") - - - (defun nnmail-request-post (&optional server) (mail-send-and-exit nil)) @@ -1103,7 +1173,10 @@ FUNC will be called with the group name to determine the article number." (unless group-art (setq group-art (list (cons (car method) - (funcall func (car method))))))))) + (funcall func (car method)))))))) + ;; Fall back on "bogus" if all else fails. + (unless group-art + (setq group-art (list (cons "bogus" (funcall func "bogus")))))) ;; Produce a trace if non-empty. (when (and trace nnmail-split-trace) (let ((restore (current-buffer))) @@ -1343,8 +1416,9 @@ See the documentation for the variable `nnmail-split-fancy' for details." (t (let* ((field (nth 0 split)) (value (nth 1 split)) - partial-front regexp - partial-rear regexp) + partial-front + partial-rear + regexp) (if (symbolp value) (setq value (cdr (assq value nnmail-split-abbrev-alist)))) (if (and (>= (length value) 2) @@ -1356,6 +1430,9 @@ See the documentation for the variable `nnmail-split-fancy' for details." (string= ".*" (substring value -2))) (setq value (substring value 0 -2) partial-rear "")) + (when nnmail-split-fancy-match-partial-words + (setq partial-front "" + partial-rear "")) (setq regexp (concat "^\\(\\(" (if (symbolp field) (cdr (assq field nnmail-split-abbrev-alist)) @@ -1486,31 +1563,34 @@ See the documentation for the variable `nnmail-split-fancy' for details." (defvar group) (defvar group-art-list) (defvar group-art) -(defun nnmail-cache-insert (id grp) - (run-hook-with-args 'nnmail-spool-hook - id grp) - (when nnmail-treat-duplicates - ;; Store some information about the group this message is written - ;; to. This is passed in as the grp argument -- all locations this - ;; has been called from have been checked and the group is available. - ;; The only ambiguous case is nnmail-check-duplication which will only - ;; pass the first (of possibly >1) group which matches. -Josh - (unless (gnus-buffer-live-p nnmail-cache-buffer) - (nnmail-cache-open)) - (save-excursion - (set-buffer nnmail-cache-buffer) - (goto-char (point-max)) - (if (and grp (not (string= "" grp)) - (gnus-methods-equal-p gnus-command-method - (nnmail-cache-primary-mail-backend))) - (let ((regexp (if (consp nnmail-cache-ignore-groups) - (mapconcat 'identity nnmail-cache-ignore-groups - "\\|") - nnmail-cache-ignore-groups))) - (unless (and regexp (string-match regexp grp)) - (insert id "\t" grp "\n"))) - (insert id "\n"))))) - +(defun nnmail-cache-insert (id grp &optional subject sender) + (when (stringp id) + ;; this will handle cases like `B r' where the group is nil + (let ((grp (or grp gnus-newsgroup-name "UNKNOWN"))) + (run-hook-with-args 'nnmail-spool-hook + id grp subject sender)) + (when nnmail-treat-duplicates + ;; Store some information about the group this message is written + ;; to. This is passed in as the grp argument -- all locations this + ;; has been called from have been checked and the group is available. + ;; The only ambiguous case is nnmail-check-duplication which will only + ;; pass the first (of possibly >1) group which matches. -Josh + (unless (gnus-buffer-live-p nnmail-cache-buffer) + (nnmail-cache-open)) + (save-excursion + (set-buffer nnmail-cache-buffer) + (goto-char (point-max)) + (if (and grp (not (string= "" grp)) + (gnus-methods-equal-p gnus-command-method + (nnmail-cache-primary-mail-backend))) + (let ((regexp (if (consp nnmail-cache-ignore-groups) + (mapconcat 'identity nnmail-cache-ignore-groups + "\\|") + nnmail-cache-ignore-groups))) + (unless (and regexp (string-match regexp grp)) + (insert id "\t" grp "\n"))) + (insert id "\n")))))) + (defun nnmail-cache-primary-mail-backend () (let ((be-list (cons gnus-select-method gnus-secondary-select-methods)) (be nil) @@ -1597,7 +1677,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (cond ((memq nnmail-treat-duplicates '(warn delete)) nnmail-treat-duplicates) - ((nnheader-functionp nnmail-treat-duplicates) + ((functionp nnmail-treat-duplicates) (funcall nnmail-treat-duplicates message-id)) (t nnmail-treat-duplicates)))) @@ -1763,7 +1843,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (let (nnmail-cache-accepted-message-ids) ;; Don't enter Message-IDs into cache. ;; Let users hack it in TARGET function. - (when (nnheader-functionp target) + (when (functionp target) (setq target (funcall target group))) (unless (eq target 'delete) (when (or (gnus-request-group target) diff --git a/lisp/nnmbox.el b/lisp/nnmbox.el index 7477a31..efa5e5a 100644 --- a/lisp/nnmbox.el +++ b/lisp/nnmbox.el @@ -333,7 +333,10 @@ (while (re-search-backward "^X-Gnus-Newsgroup: " nil t) (delete-region (point) (progn (forward-line 1) (point)))) (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject") + (nnmail-fetch-field "from"))) (setq result (if (stringp group) (list (cons group (nnmbox-active-number group))) (nnmail-article-group 'nnmbox-active-number))) diff --git a/lisp/nnmh.el b/lisp/nnmh.el index d4e1483..cfefeb4 100644 --- a/lisp/nnmh.el +++ b/lisp/nnmh.el @@ -325,7 +325,10 @@ as unread by Gnus.") (not (equal group "draft"))) (nnmail-check-syntax)) (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject") + (nnmail-fetch-field "from"))) (nnheader-init-server-buffer) (prog1 (if (stringp group) diff --git a/lisp/nnml.el b/lisp/nnml.el index de2daa5..7b0ae9c 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -375,7 +375,10 @@ marks file will be regenerated properly by Gnus.") (nnmail-check-syntax) (let (result) (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id") group)) + (nnmail-cache-insert (nnmail-fetch-field "message-id") + group + (nnmail-fetch-field "subject") + (nnmail-fetch-field "from"))) (if (stringp group) (and (nnmail-activate 'nnml) @@ -625,8 +628,12 @@ marks file will be regenerated properly by Gnus.") (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) @@ -641,7 +648,8 @@ marks file will be regenerated properly by Gnus.") (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) @@ -893,7 +901,8 @@ Use the nov database for that directory if available." (defun nnml-current-group-article-to-file-alist () "Return an alist of article/file pairs in the current group. Use the nov database for the current group if available." - (if (or gnus-nov-is-evil + (if (or nnml-use-compressed-files + gnus-nov-is-evil nnml-nov-is-evil (not (file-exists-p (expand-file-name nnml-nov-file-name diff --git a/lisp/nnrss.el b/lisp/nnrss.el index 6e94f09..89494fa 100644 --- a/lisp/nnrss.el +++ b/lisp/nnrss.el @@ -428,7 +428,7 @@ ARTICLE is the article number of the current headline.") (nnrss-translate-file-chars (concat group ".xml")) nnrss-directory)))) - (nnrss-fetch file t) + (setq xml (nnrss-fetch file t)) (setq url (or (nth 2 (assoc group nnrss-server-data)) (second (assoc group nnrss-group-alist)))) (unless url @@ -461,7 +461,8 @@ ARTICLE is the article number of the current headline.") (setq extra (or (nnrss-node-text content-ns 'encoded item) (nnrss-node-text rss-ns 'description item))) (setq author (or (nnrss-node-text rss-ns 'author item) - (nnrss-node-text dc-ns 'creator item))) + (nnrss-node-text dc-ns 'creator item) + (nnrss-node-text dc-ns 'contributor item))) (setq date (or (nnrss-node-text dc-ns 'date item) (nnrss-node-text rss-ns 'pubDate item) (message-make-date))) @@ -688,48 +689,50 @@ whether they are `offsite' or `onsite'." (defun nnrss-find-rss-via-syndic8 (url) "query syndic8 for the rss feeds it has for the url." - (if (locate-library "xml-rpc") - (progn (require 'xml-rpc) - (let ((feedid (xml-rpc-method-call - "http://www.syndic8.com/xmlrpc.php" - 'syndic8.FindSites - url))) - (if feedid - (let* ((feedinfo (xml-rpc-method-call - "http://www.syndic8.com/xmlrpc.php" - 'syndic8.GetFeedInfo - feedid)) - (urllist - (delq nil - (mapcar - (lambda (listinfo) - (if (string-equal - (cdr (assoc "status" listinfo)) - "Syndicated") - (cons - (cdr (assoc "sitename" listinfo)) - (list - (cons 'title - (cdr (assoc - "sitename" listinfo))) - (cons 'href - (cdr (assoc - "dataurl" listinfo))))))) - feedinfo)))) - (if (> (length urllist) 1) - (let ((completion-ignore-case t) - (selection - (mapcar (lambda (listinfo) - (cons (cdr (assoc "sitename" listinfo)) - (string-to-int - (cdr (assoc "feedid" listinfo))))) - feedinfo))) - (cdr (assoc - (completing-read - "Multiple feeds found. Select one: " - selection nil t) urllist))) - (cdar urllist)))))) - (error (message "XML-RPC is not available... not checking Syndic8.")))) + (if (not (locate-library "xml-rpc")) + (progn + (message "XML-RPC is not available... not checking Syndic8.") + nil) + (require 'xml-rpc) + (let ((feedid (xml-rpc-method-call + "http://www.syndic8.com/xmlrpc.php" + 'syndic8.FindSites + url))) + (when feedid + (let* ((feedinfo (xml-rpc-method-call + "http://www.syndic8.com/xmlrpc.php" + 'syndic8.GetFeedInfo + feedid)) + (urllist + (delq nil + (mapcar + (lambda (listinfo) + (if (string-equal + (cdr (assoc "status" listinfo)) + "Syndicated") + (cons + (cdr (assoc "sitename" listinfo)) + (list + (cons 'title + (cdr (assoc + "sitename" listinfo))) + (cons 'href + (cdr (assoc + "dataurl" listinfo))))))) + feedinfo)))) + (if (not (> (length urllist) 1)) + (cdar urllist) + (let ((completion-ignore-case t) + (selection + (mapcar (lambda (listinfo) + (cons (cdr (assoc "sitename" listinfo)) + (string-to-int + (cdr (assoc "feedid" listinfo))))) + feedinfo))) + (cdr (assoc + (completing-read + "Multiple feeds found. Select one: " + selection nil t) urllist))))))))) (defun nnrss-rss-p (data) "Test if data is an RSS feed. Simply ensures that the first diff --git a/lisp/nnspool.el b/lisp/nnspool.el index a799687..add0e7e 100644 --- a/lisp/nnspool.el +++ b/lisp/nnspool.el @@ -74,8 +74,8 @@ If you are using Cnews, you probably should set this variable to nil.") "Local news active date file.") (defvoo nnspool-large-newsgroup 50 - "The number of the articles which indicates a large newsgroup. -If the number of the articles is greater than the value, verbose + "The number of articles which indicates a large newsgroup. +If the number of articles is greater than the value, verbose messages will be shown to indicate the current status.") (defvoo nnspool-nov-is-evil nil diff --git a/lisp/nntp.el b/lisp/nntp.el index 62a6b16..784d7c0 100644 --- a/lisp/nntp.el +++ b/lisp/nntp.el @@ -175,8 +175,8 @@ If non-nil, there will be no prompt for a login name.") This variable is used by the `nntp-open-via-telnet-and-telnet' method.") (defvoo nntp-large-newsgroup 50 - "*The number of the articles which indicates a large newsgroup. -If the number of the articles is greater than the value, verbose + "*The number of articles which indicates a large newsgroup. +If the number of articles is greater than the value, verbose messages will be shown to indicate the current status.") (defvoo nntp-maximum-request 400 @@ -475,8 +475,7 @@ be restored and the command retried." (goto-char pos) (if (looking-at (regexp-quote command)) (delete-region pos (progn (forward-line 1) - (gnus-point-at-bol)))) - ))) + (gnus-point-at-bol))))))) (nnheader-report 'nntp "Couldn't open connection to %s." nntp-address)))) @@ -1208,6 +1207,10 @@ password contained in '~/.nntp-authinfo'." (open-network-stream-as-binary "nntpd" buffer nntp-address nntp-port-number)) +(autoload 'format-spec "format") +(autoload 'format-spec-make "format") +(autoload 'open-tls-stream "tls") + (defun nntp-open-ssl-stream (buffer) (let* ((process-connection-type nil) (proc (as-binary-process @@ -1487,8 +1490,7 @@ password contained in '~/.nntp-authinfo'." in-process-buffer-p (buf nntp-server-buffer) (process-buffer (nntp-find-connection-buffer nntp-server-buffer)) - first - last) + first last status) ;; We have to check `nntp-server-xover'. If it gets set to nil, ;; that means that the server does not understand XOVER, but we ;; won't know that until we try. @@ -1522,15 +1524,22 @@ password contained in '~/.nntp-authinfo'." (while (progn (goto-char (or last-point (point-min))) ;; Count replies. - (while (re-search-forward "^[0-9][0-9][0-9] .*\n" nil t) - (incf received)) + (while (re-search-forward "^\\([0-9][0-9][0-9]\\) .*\n" + nil t) + (incf received) + (setq status (match-string 1)) + (if (string-match "^[45]" status) + (setq status 'error) + (setq status 'ok))) (setq last-point (point)) (or (< received count) - ;; I haven't started reading the final response - (progn - (goto-char (point-max)) - (forward-line -1) - (not (looking-at "^\\.\r?\n"))))) + (if (eq status 'error) + nil + ;; I haven't started reading the final response + (progn + (goto-char (point-max)) + (forward-line -1) + (not (looking-at "^\\.\r?\n")))))) ;; I haven't read the end of the final response (nntp-accept-response) (set-buffer process-buffer)))) diff --git a/lisp/nnweb.el b/lisp/nnweb.el index 8c83eda..d71f595 100644 --- a/lisp/nnweb.el +++ b/lisp/nnweb.el @@ -358,7 +358,7 @@ Valid types include `google', `dejanews', and `gmane'.") (setq Subject (buffer-string)) (goto-char (point-max)) (widen) - (forward-line 1) + (forward-line 2) (when (looking-at "
]+>") (goto-char (match-end 0))) (if (not (looking-at "]+>")) diff --git a/lisp/pop3.el b/lisp/pop3.el index 2b1373e..c47a2e4 100644 --- a/lisp/pop3.el +++ b/lisp/pop3.el @@ -225,6 +225,9 @@ Argument PORT specifies connecting port." (+ 1 (or (string-match ">" response) -1))))) process))) +(eval-when-compile + (autoload 'open-ssl-stream "ssl")) + (defun pop3-open-ssl-stream-1 (name buffer host service extra-arg) (require 'ssl) (let* ((ssl-program-name @@ -293,7 +296,8 @@ Return the response string if optional second argument RETURN is non-nil." (save-excursion (set-buffer (process-buffer process)) (goto-char pop3-read-point) - (while (not (search-forward "\r\n" nil t)) + (while (and (memq (process-status process) '(open run)) + (not (search-forward "\r\n" nil t))) (nnheader-accept-process-output process) (goto-char pop3-read-point)) (setq match-end (point)) @@ -511,18 +515,16 @@ If NOW, use that time instead." ;; tree, `md5' might have been defined in w3/md5.el, ./lpath.el or one ;; of some other libraries and `md5' will accept only 3 arguments. We ;; will deceive the byte-compiler not to say warnings. -(eval-and-compile - (if (fboundp 'eval-when) - ;; `eval-when' might not be provided when loading .el file. - (eval-when 'compile - (let ((def (assq 'md5 byte-compile-function-environment))) - (if def - (setcdr def '(lambda (object &optional start end - coding-system noerror))) - (setq byte-compile-function-environment - (cons '(md5 . (lambda (object &optional start end - coding-system noerror))) - byte-compile-function-environment))))))) +(eval-when-compile + (if (boundp 'byte-compile-function-environment) + (let ((def (assq 'md5 byte-compile-function-environment))) + (if def + (setcdr def '(lambda (object &optional start end + coding-system noerror))) + (setq byte-compile-function-environment + (cons '(md5 . (lambda (object &optional start end + coding-system noerror))) + byte-compile-function-environment)))))) ;; Note that `pop3-md5' should never encode a given string to use for ;; the apop authentication. @@ -705,6 +707,7 @@ If msgno is invalid, return nil. Otherwise, return a string." (set-buffer (process-buffer process)) (goto-char start) (while (not (re-search-forward "^\\.\r\n" nil t)) + ;; Fixme: Shouldn't depend on nnheader. (nnheader-accept-process-output process) (goto-char start)) (setq pop3-read-point (point-marker)) diff --git a/lisp/qp.el b/lisp/qp.el index 149d30a..f87ec66 100644 --- a/lisp/qp.el +++ b/lisp/qp.el @@ -74,15 +74,17 @@ them into characters should be done separately." (mm-insert-byte byte 1) (delete-char 3))) (t - (error "Malformed quoted-printable text") + (message "Malformed quoted-printable text") (forward-char))))) (if coding-system (mm-decode-coding-region (point-min) (point-max) coding-system))))) (defun quoted-printable-decode-string (string &optional coding-system) "Decode the quoted-printable encoded STRING and return the result. -If CODING-SYSTEM is non-nil, decode the region with coding-system." - (with-temp-buffer +If CODING-SYSTEM is non-nil, decode the region with coding-system. +Use of CODING-SYSTEM is deprecated; this function should deal with +raw bytes, and coding conversion should be done separately." + (mm-with-unibyte-buffer (insert string) (quoted-printable-decode-region (point-min) (point-max) coding-system) (buffer-string))) diff --git a/lisp/rfc2047.el b/lisp/rfc2047.el index 81005a9..3453f7b 100644 --- a/lisp/rfc2047.el +++ b/lisp/rfc2047.el @@ -1,5 +1,5 @@ -;;; rfc2047.el --- Functions for encoding and decoding rfc2047 messages -;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +;;; rfc2047.el --- functions for encoding and decoding rfc2047 messages +;; Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; MORIOKA Tomohiko @@ -29,23 +29,50 @@ (eval-when-compile (require 'cl) - (defvar message-posting-charset)) + (defvar message-posting-charset) + (unless (fboundp 'with-syntax-table) ; not in Emacs 20 + (defmacro with-syntax-table (table &rest body) + "Evaluate BODY with syntax table of current buffer set to TABLE. +The syntax table of the current buffer is saved, BODY is evaluated, and the +saved table is restored, even in case of an abnormal exit. +Value is what BODY returns." + (let ((old-table (make-symbol "table")) + (old-buffer (make-symbol "buffer"))) + `(let ((,old-table (syntax-table)) + (,old-buffer (current-buffer))) + (unwind-protect + (progn + (set-syntax-table ,table) + ,@body) + (save-current-buffer + (set-buffer ,old-buffer) + (set-syntax-table ,old-table)))))))) (require 'qp) (require 'mm-util) -(require 'ietf-drums) +;; Fixme: Avoid this (used for mail-parse-charset) mm dependence on gnus. (require 'mail-prsvr) (require 'base64) -;; Fixme: Avoid this (for gnus-point-at-...) mm dependence on gnus. -(require 'gnus-util) (autoload 'mm-body-7-or-8 "mm-bodies") +(eval-and-compile + ;; Avoid gnus-util for mm- code. + (defalias 'rfc2047-point-at-bol + (if (fboundp 'point-at-bol) + 'point-at-bol + 'line-beginning-position)) + + (defalias 'rfc2047-point-at-eol + (if (fboundp 'point-at-eol) + 'point-at-eol + 'line-end-position))) + (defvar rfc2047-header-encoding-alist '(("Newsgroups" . nil) ("Followup-To" . nil) ("Message-ID" . nil) - ("\\(Resent-\\)?\\(From\\|Cc\\|To\\|Bcc\\|Reply-To\\|Sender\\)" . - "-A-Za-z0-9!*+/=_") + ("\\(Resent-\\)?\\(From\\|Cc\\|To\\|Bcc\\|Reply-To\\|Sender\ +\\|Mail-Followup-To\\|Mail-Copies-To\\|Approved\\)" . address-mime) (t . mime)) "*Header/encoding method alist. The list is traversed sequentially. The keys can either be @@ -55,10 +82,11 @@ The values can be: 1) nil, in which case no encoding is done; 2) `mime', in which case the header will be encoded according to RFC2047; -3) a charset, in which case it will be encoded as that charset; -4) `default', in which case the field will be encoded as the rest - of the article. -5) a string, like `mime', expect for using it as word-chars.") +3) `address-mime', like `mime', but takes account of the rules for address + fields (where quoted strings and comments must be treated separately); +4) a charset, in which case it will be encoded as that charset; +5) `default', in which case the field will be encoded as the rest + of the article.") (defvar rfc2047-charset-encoding-alist '((us-ascii . nil) @@ -82,7 +110,8 @@ The values can be: (cn-gb-2312 . B) (euc-kr . B) (iso-2022-jp-2 . B) - (iso-2022-int-1 . B)) + (iso-2022-int-1 . B) + (viscii . Q)) "Alist of MIME charsets to RFC2047 encodings. Valid encodings are nil, `Q' and `B'. These indicate binary (no) encoding, quoted-printable and base64 respectively.") @@ -93,15 +122,6 @@ quoted-printable and base64 respectively.") (nil . ignore)) "Alist of RFC2047 encodings to encoding functions.") -(defvar rfc2047-q-encoding-alist - '(("\\(Resent-\\)?\\(From\\|Cc\\|To\\|Bcc\\|Reply-To\\|Sender\\):" - . "-A-Za-z0-9!*+/" ) - ;; = (\075), _ (\137), ? (\077) are used in the encoded word. - ;; Avoid using 8bit characters. - ;; Equivalent to "^\000-\007\011\013\015-\037\200-\377=_?" - ("." . "\010\012\014\040-\074\076\100-\136\140-\177")) - "Alist of header regexps and valid Q characters.") - ;;; ;;; Functions for encoding RFC2047 messages ;;; @@ -114,9 +134,7 @@ quoted-printable and base64 respectively.") (progn (forward-line 1) (if (re-search-forward "^[^ \n\t]" nil t) - (progn - (beginning-of-line) - (point)) + (rfc2047-point-at-bol) (point-max)))) (goto-char (point-min))) @@ -128,6 +146,12 @@ quoted-printable and base64 respectively.") (re-search-forward ":[ \t\n]*" nil t) (buffer-substring (point) (point-max))))) +(defvar rfc2047-encoding-type 'address-mime + "The type of encoding done by `rfc2047-encode-region'. +This should be dynamically bound around calls to +`rfc2047-encode-region' to either `mime' or `address-mime'. See +`rfc2047-header-encoding-alist', for definitions.") + (defun rfc2047-encode-message-header () "Encode the message header according to `rfc2047-header-encoding-alist'. Should be called narrowed to the head of the message." @@ -145,11 +169,10 @@ Should be called narrowed to the head of the message." (mm-coding-system-p (car message-posting-charset))) ;; 8 bit must be decoded. - ;; Is message-posting-charset a coding system? (mm-encode-coding-region (point-min) (point-max) - (car message-posting-charset)) - nil) + (mm-charset-to-coding-system + (car message-posting-charset)))) ;; No encoding necessary, but folding is nice (rfc2047-fold-region (save-excursion @@ -168,46 +191,46 @@ Should be called narrowed to the head of the message." (eq (car elem) t)) (setq alist nil method (cdr elem)))) + (goto-char (point-min)) + (re-search-forward "^[^:]+: *" nil t) (cond - ((stringp method) - (rfc2047-encode-region (point-min) (point-max) method)) + ((eq method 'address-mime) + (rfc2047-encode-region (point) (point-max))) ((eq method 'mime) - (rfc2047-encode-region (point-min) (point-max))) + (let ((rfc2047-encoding-type 'mime)) + (rfc2047-encode-region (point) (point-max)))) ((eq method 'default) (if (and (featurep 'mule) (if (boundp 'default-enable-multibyte-characters) default-enable-multibyte-characters) mail-parse-charset) - (mm-encode-coding-region (point-min) (point-max) + (mm-encode-coding-region (point) (point-max) mail-parse-charset))) ;; We get this when CC'ing messsages to newsgroups with - ;; 8-bit names. The group name mail copy just get + ;; 8-bit names. The group name mail copy just got ;; unconditionally encoded. Previously, it would ask ;; whether to encode, which was quite confusing for the ;; user. If the new behaviour is wrong, tell me. I have ;; left the old code commented out below. ;; -- Per Abrahamsen Date: 2001-10-07. + ;; Modified by Dave Love, with the commented-out code changed + ;; in accordance with changes elsewhere. ((null method) - (when (delq 'ascii - (mm-find-charset-region (point-min) (point-max))) - (rfc2047-encode-region (point-min) (point-max)))) -;;; ((null method) -;;; (and (delq 'ascii -;;; (mm-find-charset-region (point-min) -;;; (point-max))) -;;; (if (or (message-options-get -;;; 'rfc2047-encode-message-header-encode-any) -;;; (message-options-set -;;; 'rfc2047-encode-message-header-encode-any -;;; (y-or-n-p -;;; "Some texts are not encoded. Encode anyway?"))) -;;; (rfc2047-encode-region (point-min) (point-max)) -;;; (error "Cannot send unencoded text")))) + (rfc2047-encode-region (point) (point-max))) +;;; ((null method) +;;; (if (or (message-options-get +;;; 'rfc2047-encode-message-header-encode-any) +;;; (message-options-set +;;; 'rfc2047-encode-message-header-encode-any +;;; (y-or-n-p +;;; "Some texts are not encoded. Encode anyway?"))) +;;; (rfc2047-encode-region (point-min) (point-max)) +;;; (error "Cannot send unencoded text"))) ((mm-coding-system-p method) (if (and (featurep 'mule) (if (boundp 'default-enable-multibyte-characters) default-enable-multibyte-characters)) - (mm-encode-coding-region (point-min) (point-max) method))) + (mm-encode-coding-region (point) (point-max) method))) ;; Hm. (t))) (goto-char (point-max))))))) @@ -221,137 +244,230 @@ Should be called narrowed to the head of the message." The buffer may be narrowed." (require 'message) ; for message-posting-charset (let ((charsets - (mapcar - 'mm-mime-charset - (mm-find-charset-region (point-min) (point-max)))) - (cs (list 'us-ascii (car message-posting-charset))) - found) - (while charsets - (unless (memq (pop charsets) cs) - (setq found t))) - found)) - -(defun rfc2047-dissect-region (b e &optional word-chars) - "Dissect the region between B and E into words." - (unless word-chars - ;; Anything except most CTLs, WSP - (setq word-chars "\010\012\014\041-\177")) - (let (mail-parse-mule-charset - words point current - result word) - (save-restriction - (narrow-to-region b e) - (goto-char (point-min)) - (skip-chars-forward "\000-\177") - (while (not (eobp)) - (setq point (point)) - (skip-chars-backward word-chars b) - (unless (eq b (point)) - (push (cons (buffer-substring b (point)) nil) words)) - (setq b (point)) - (goto-char point) - (setq current (mm-charset-after)) - (forward-char 1) - (skip-chars-forward word-chars) - (while (and (not (eobp)) - (eq (mm-charset-after) current)) - (forward-char 1) - (skip-chars-forward word-chars)) - (unless (eq b (point)) - (push (cons (buffer-substring b (point)) current) words)) - (setq b (point)) - (skip-chars-forward "\000-\177")) - (unless (eq b (point)) - (push (cons (buffer-substring b (point)) nil) words))) - ;; merge adjacent words - (setq word (pop words)) - (while word - (if (and (cdr word) - (caar words) - (not (cdar words)) - (not (string-match "[^ \t]" (caar words)))) - (if (eq (cdr (nth 1 words)) (cdr word)) - (progn - (setq word (cons (concat - (car (nth 1 words)) (caar words) - (car word)) - (cdr word))) - (pop words) - (pop words)) - (push (cons (concat (caar words) (car word)) (cdr word)) - result) - (pop words) - (setq word (pop words))) - (push word result) - (setq word (pop words)))) - result)) - -(defun rfc2047-encode-region (b e &optional word-chars) - "Encode all encodable words in region B to E." - (let ((words (rfc2047-dissect-region b e word-chars)) word) - (save-restriction - (narrow-to-region b e) - (delete-region (point-min) (point-max)) - (while (setq word (pop words)) - (if (not (cdr word)) - (insert (car word)) - (rfc2047-fold-region (gnus-point-at-bol) (point)) - (goto-char (point-max)) - (if (> (- (point) (save-restriction - (widen) - (gnus-point-at-bol))) 76) - (insert "\n ")) - ;; Insert blank between encoded words - (if (eq (char-before) ?=) (insert " ")) - (rfc2047-encode (point) - (progn (insert (car word)) (point)) - (cdr word)))) - (rfc2047-fold-region (point-min) (point-max))))) - -(defun rfc2047-encode-string (string &optional word-chars) - "Encode words in STRING." + (mm-find-mime-charset-region (point-min) (point-max)))) + (and charsets + (not (equal charsets (list (car message-posting-charset))))))) + +;; Use this syntax table when parsing into regions that may need +;; encoding. Double quotes are string delimiters, backslash is +;; character quoting, and all other RFC 2822 special characters are +;; treated as punctuation so we can use forward-sexp/forward-word to +;; skip to the end of regions appropriately. Nb. ietf-drums does +;; things differently. +(defconst rfc2047-syntax-table + ;; (make-char-table 'syntax-table '(2)) only works in Emacs. + (let ((table (make-syntax-table))) + ;; The following is done to work for setting all elements of the table + ;; in Emacs 21 and 22 and XEmacs; it appears to be the cleanest way. + ;; Play safe and don't assume the form of the word syntax entry -- + ;; copy it from ?a. + (if (fboundp 'set-char-table-range) ; Emacs + (funcall (intern "set-char-table-range") + table t (aref (standard-syntax-table) ?a)) + (if (fboundp 'put-char-table) + (if (fboundp 'get-char-table) ; warning avoidance + (put-char-table t (get-char-table ?a (standard-syntax-table)) + table)))) + (modify-syntax-entry ?\\ "\\" table) + (modify-syntax-entry ?\" "\"" table) + (modify-syntax-entry ?\( "." table) + (modify-syntax-entry ?\) "." table) + (modify-syntax-entry ?\< "." table) + (modify-syntax-entry ?\> "." table) + (modify-syntax-entry ?\[ "." table) + (modify-syntax-entry ?\] "." table) + (modify-syntax-entry ?: "." table) + (modify-syntax-entry ?\; "." table) + (modify-syntax-entry ?, "." table) + (modify-syntax-entry ?@ "." table) + table)) + +(defun rfc2047-encode-region (b e) + "Encode words in region B to E that need encoding. +By default, the region is treated as containing RFC2822 addresses. +Dynamically bind `rfc2047-encoding-type' to change that." + (save-restriction + (narrow-to-region b e) + (if (eq 'mime rfc2047-encoding-type) + ;; Simple case. Treat as single word after any initial ASCII + ;; part and before any tailing ASCII part. The leading ASCII + ;; is relevant for instance in Subject headers with `Re:' for + ;; interoperability with non-MIME clients, and we might as + ;; well avoid the tail too. + (progn + (goto-char (point-min)) + ;; Does it need encoding? + (skip-chars-forward "\000-\177") + (unless (eobp) + (skip-chars-backward "^ \n") ; beginning of space-delimited word + (rfc2047-encode (point) (progn + (goto-char e) + (skip-chars-backward "\000-\177") + (skip-chars-forward "^ \n") + ;; end of space-delimited word + (point))))) + ;; `address-mime' case -- take care of quoted words, comments. + (with-syntax-table rfc2047-syntax-table + (let ((start) ; start of current token + end ; end of current token + ;; Whether there's an encoded word before the current + ;; token, either immediately or separated by space. + last-encoded) + (goto-char (point-min)) + (condition-case nil ; in case of unbalanced quotes + ;; Look for rfc2822-style: sequences of atoms, quoted + ;; strings, specials, whitespace. (Specials mustn't be + ;; encoded.) + (while (not (eobp)) + (setq start (point)) + ;; Skip whitespace. + (unless (= 0 (skip-chars-forward " \t\n")) + (setq start (point))) + (cond + ((not (char-after))) ; eob + ;; else token start + ((eq ?\" (char-syntax (char-after))) + ;; Quoted word. + (forward-sexp) + (setq end (point)) + ;; Does it need encoding? + (goto-char start) + (skip-chars-forward "\000-\177" end) + (if (= end (point)) + (setq last-encoded nil) + ;; It needs encoding. Strip the quotes first, + ;; since encoded words can't occur in quotes. + (goto-char end) + (delete-backward-char 1) + (goto-char start) + (delete-char 1) + (when last-encoded + ;; There was a preceding quoted word. We need + ;; to include any separating whitespace in this + ;; word to avoid it getting lost. + (skip-chars-backward " \t") + ;; A space is needed between the encoded words. + (insert ? ) + (setq start (point) + end (1+ end))) + ;; Adjust the end position for the deleted quotes. + (rfc2047-encode start (- end 2)) + (setq last-encoded t))) ; record that it was encoded + ((eq ?. (char-syntax (char-after))) + ;; Skip other delimiters, but record that they've + ;; potentially separated quoted words. + (forward-char) + (setq last-encoded nil)) + (t ; normal token/whitespace sequence + ;; Find the end. + (forward-word 1) + (skip-chars-backward " \t") + (setq end (point)) + ;; Deal with encoding and leading space as for + ;; quoted words. + (goto-char start) + (skip-chars-forward "\000-\177" end) + (if (= end (point)) + (setq last-encoded nil) + (when last-encoded + (goto-char start) + (skip-chars-backward " \t") + (insert ? ) + (setq start (point) + end (1+ end))) + (rfc2047-encode start end) + (setq last-encoded t))))) + (error + (error "Invalid data for rfc2047 encoding: %s" + (buffer-substring b e))))))) + (rfc2047-fold-region b (point)))) + +(defun rfc2047-encode-string (string) + "Encode words in STRING. +By default, the string is treated as containing addresses (see +`rfc2047-encoding-type')." (with-temp-buffer (insert string) - (rfc2047-encode-region (point-min) (point-max) word-chars) + (rfc2047-encode-region (point-min) (point-max)) (buffer-string))) -(defun rfc2047-encode (b e charset) - "Encode the word in the region B to E with CHARSET." - (let* ((mime-charset (mm-mime-charset charset)) - (cs (mm-charset-to-coding-system mime-charset)) +(defun rfc2047-encode (b e) + "Encode the word(s) in the region B to E. +By default, the region is treated as containing addresses (see +`rfc2047-encoding-type')." + (let* ((mime-charset (mm-find-mime-charset-region b e)) + (cs (if (> (length mime-charset) 1) + ;; Fixme: Instead of this, try to break region into + ;; parts that can be encoded separately. + (error "Can't rfc2047-encode `%s'" + (buffer-substring b e)) + (setq mime-charset (car mime-charset)) + (mm-charset-to-coding-system mime-charset))) + ;; Fixme: Better, calculate the number of non-ASCII + ;; characters, at least for 8-bit charsets. (encoding (or (cdr (assq mime-charset rfc2047-charset-encoding-alist)) - 'B)) + ;; For the charsets that don't have a preferred + ;; encoding, choose the one that's shorter. + (save-restriction + (narrow-to-region b e) + (if (eq (mm-qp-or-base64) 'base64) + 'B + 'Q)))) (start (concat "=?" (downcase (symbol-name mime-charset)) "?" (downcase (symbol-name encoding)) "?")) + (factor (case mime-charset + ((iso-8859-5 iso-8859-7 iso-8859-8 koi8-r) 1) + ((big5 gb2312 euc-kr) 2) + (utf-8 4) + (t 8))) + (pre (- b (save-restriction + (widen) + (rfc2047-point-at-bol)))) + ;; encoded-words must not be longer than 75 characters, + ;; including charset, encoding etc. This leaves us with + ;; 75 - (length start) - 2 - 2 characters. The last 2 is for + ;; possible base64 padding. In the worst case (iso-2022-*) + ;; each character expands to 8 bytes which is expanded by a + ;; factor of 4/3 by base64 encoding. + (length (floor (- 75 (length start) 4) (* factor (/ 4.0 3.0)))) + ;; Limit line length to 76 characters. + (length1 (max 1 (floor (- 76 (length start) 4 pre) + (* factor (/ 4.0 3.0))))) (first t)) - (save-restriction - (narrow-to-region b e) - (when (eq encoding 'B) - ;; break into lines before encoding - (goto-char (point-min)) - (while (not (eobp)) - (goto-char (min (point-max) (+ 15 (point)))) - (unless (eobp) - (insert "\n")))) - (if (and (mm-multibyte-p) - (mm-coding-system-p cs)) - (mm-encode-coding-region (point-min) (point-max) cs)) - (funcall (cdr (assq encoding rfc2047-encoding-function-alist)) - (point-min) (point-max)) - (goto-char (point-min)) - (while (not (eobp)) - (unless first - (insert " ")) - (setq first nil) - (insert start) - (end-of-line) - (insert "?=") - (forward-line 1))))) + (if mime-charset + (save-restriction + (narrow-to-region b e) + (when (eq encoding 'B) + ;; break into lines before encoding + (goto-char (point-min)) + (while (not (eobp)) + (if first + (progn + (goto-char (min (point-max) (+ length1 (point)))) + (setq first nil)) + (goto-char (min (point-max) (+ length (point))))) + (unless (eobp) + (insert ?\n))) + (setq first t)) + (if (and (mm-multibyte-p) + (mm-coding-system-p cs)) + (mm-encode-coding-region (point-min) (point-max) cs)) + (funcall (cdr (assq encoding rfc2047-encoding-function-alist)) + (point-min) (point-max)) + (goto-char (point-min)) + (while (not (eobp)) + (unless first + (insert ? )) + (setq first nil) + (insert start) + (end-of-line) + (insert "?=") + (forward-line 1)))))) (defun rfc2047-fold-field () - "Fold the current line." + "Fold the current header field." (save-excursion (save-restriction (rfc2047-narrow-to-field) @@ -367,7 +483,7 @@ The buffer may be narrowed." (first t) (bol (save-restriction (widen) - (gnus-point-at-bol)))) + (rfc2047-point-at-bol)))) (while (not (eobp)) (when (and (or break qword-break) (> (- (point) bol) 76)) @@ -375,7 +491,7 @@ The buffer may be narrowed." (setq break nil qword-break nil) (if (looking-at "[ \t]") - (insert "\n") + (insert ?\n) (insert "\n ")) (setq bol (1- (point))) ;; Don't break before the first non-LWSP characters. @@ -404,7 +520,9 @@ The buffer may be narrowed." (if (eq (char-after) ?=) (forward-char 1) (skip-chars-forward "^ \t\n\r=")) - (setq qword-break (point)) + ;; Don't break at the start of the field. + (unless (= (point) b) + (setq qword-break (point))) (skip-chars-forward "^ \t\n\r"))) (t (skip-chars-forward "^ \t\n\r")))) @@ -414,7 +532,7 @@ The buffer may be narrowed." (setq break nil qword-break nil) (if (looking-at "[ \t]") - (insert "\n") + (insert ?\n) (insert "\n ")) (setq bol (1- (point))) ;; Don't break before the first non-LWSP characters. @@ -436,18 +554,18 @@ The buffer may be narrowed." (goto-char (point-min)) (let ((bol (save-restriction (widen) - (gnus-point-at-bol))) - (eol (gnus-point-at-eol))) + (rfc2047-point-at-bol))) + (eol (rfc2047-point-at-eol))) (forward-line 1) (while (not (eobp)) (if (and (looking-at "[ \t]") - (< (- (gnus-point-at-eol) bol) 76)) + (< (- (rfc2047-point-at-eol) bol) 76)) (delete-region eol (progn (goto-char eol) (skip-chars-forward "\r\n") (point))) - (setq bol (gnus-point-at-bol))) - (setq eol (gnus-point-at-eol)) + (setq bol (rfc2047-point-at-bol))) + (setq eol (rfc2047-point-at-eol)) (forward-line 1))))) (defun rfc2047-b-encode-region (b e) @@ -465,18 +583,21 @@ The buffer may be narrowed." (save-excursion (save-restriction (narrow-to-region (goto-char b) e) - (let ((alist rfc2047-q-encoding-alist) - (bol (save-restriction + (let ((bol (save-restriction (widen) - (gnus-point-at-bol)))) - (while alist - (when (looking-at (caar alist)) - (mm-with-unibyte-current-buffer-mule4 - (quoted-printable-encode-region - (point-min) (point-max) nil (cdar alist))) - (subst-char-in-region (point-min) (point-max) ? ?_) - (setq alist nil)) - (pop alist)) + (rfc2047-point-at-bol)))) + (quoted-printable-encode-region + b e nil + ;; = (\075), _ (\137), ? (\077) are used in the encoded word. + ;; Avoid using 8bit characters. + ;; This list excludes `especials' (see the RFC2047 syntax), + ;; meaning that some characters in non-structured fields will + ;; get encoded when they con't need to be. The following is + ;; what it used to be. +;;; ;; Equivalent to "^\000-\007\011\013\015-\037\200-\377=_?" +;;; "\010\012\014\040-\074\076\100-\136\140-\177") + "-\b\n\f !#-'*+0-9A-Z\\^`-~\d") + (subst-char-in-region (point-min) (point-max) ? ?_) ;; The size of QP encapsulation is about 20, so set limit to ;; 56=76-20. (unless (< (- (point-max) (point-min)) 56) @@ -487,15 +608,27 @@ The buffer may be narrowed." (goto-char (min (point-max) (+ 56 bol))) (search-backward "=" (- (point) 2) t) (unless (or (bobp) (eobp)) - (insert "\n") + (insert ?\n) (setq bol (point))))))))) ;;; ;;; Functions for decoding RFC2047 messages ;;; -(defvar rfc2047-encoded-word-regexp - "=\\?\\([^][\000-\040()<>@,\;:\\\"/?.=]+\\)\\?\\(B\\|Q\\)\\?\\([!->@-~ +]*\\)\\?=") +(eval-and-compile + (defconst rfc2047-encoded-word-regexp + "=\\?\\([^][\000-\040()<>@,\;:\\\"/?.=]+\\)\\?\\(B\\|Q\\)\ +\\?\\([!->@-~ +]*\\)\\?=")) + +;; Fixme: This should decode in place, not cons intermediate strings. +;; Also check whether it needs to worry about delimiting fields like +;; encoding. + +;; In fact it's reported that (invalid) encoding of mailboxes in +;; addr-specs is in use, so delimiting fields might help. Probably +;; not decoding a word which isn't properly delimited is good enough +;; and worthwhile (is it more correct or not?), e.g. something like +;; `=?iso-8859-1?q?foo?=@'. (defun rfc2047-decode-region (start end) "Decode MIME-encoded words in region between START and END." @@ -508,9 +641,10 @@ The buffer may be narrowed." (goto-char (point-min)) ;; Remove whitespace between encoded words. (while (re-search-forward - (concat "\\(" rfc2047-encoded-word-regexp "\\)" - "\\(\n?[ \t]\\)+" - "\\(" rfc2047-encoded-word-regexp "\\)") + (eval-when-compile + (concat "\\(" rfc2047-encoded-word-regexp "\\)" + "\\(\n?[ \t]\\)+" + "\\(" rfc2047-encoded-word-regexp "\\)")) nil t) (delete-region (goto-char (match-end 1)) (match-beginning 6))) ;; Decode the encoded words. @@ -521,8 +655,8 @@ The buffer may be narrowed." (prog1 (match-string 0) (delete-region (match-beginning 0) (match-end 0))))) - ;; Remove newlines between decoded words. Though such things - ;; must not be essentially there. + ;; Remove newlines between decoded words, though such things + ;; essentially must not be there. (save-restriction (narrow-to-region e (point)) (goto-char e) @@ -539,34 +673,37 @@ The buffer may be narrowed." mail-parse-charset (not (eq mail-parse-charset 'us-ascii)) (not (eq mail-parse-charset 'gnus-decoded))) - (mm-decode-coding-region-safely b (point-max) mail-parse-charset)))))) + (mm-decode-coding-region b (point-max) mail-parse-charset)))))) (defun rfc2047-decode-string (string) "Decode the quoted-printable-encoded STRING and return the results." (let ((m (mm-multibyte-p))) (if (string-match "=\\?" string) (with-temp-buffer + ;; Fixme: This logic is wrong, but seems to be required by + ;; Gnus summary buffer generation. The value of `m' depends + ;; on the current buffer, not global multibyteness or that + ;; of the string. Also the string returned should always be + ;; multibyte in a multibyte session, i.e. the buffer should + ;; be multibyte before `buffer-string' is called. (when m (mm-enable-multibyte)) (insert string) (inline (rfc2047-decode-region (point-min) (point-max))) (buffer-string)) + ;; Fixme: As above, `m' here is inappropriate. (if (and m mail-parse-charset (not (eq mail-parse-charset 'us-ascii)) (not (eq mail-parse-charset 'gnus-decoded))) - (let* ((decoded (mm-decode-coding-string string mail-parse-charset)) - (charsets (find-charset-string decoded))) - (if (or (memq 'eight-bit-control charsets) - (memq 'eight-bit-graphic charsets)) - (mm-decode-coding-string string 'undecided) - decoded)) - string)))) + (mm-decode-coding-string string mail-parse-charset) + (mm-string-as-multibyte string))))) (defun rfc2047-parse-and-decode (word) "Decode WORD and return it if it is an encoded word. -Return WORD if not." +Return WORD if it is not not an encoded word or if the charset isn't +decodable." (if (not (string-match rfc2047-encoded-word-regexp word)) word (or @@ -576,7 +713,7 @@ Return WORD if not." (upcase (match-string 2 word)) (match-string 3 word)) (error word)) - word))) + word))) ; un-decodable (defun rfc2047-pad-base64 (string) "Pad STRING to quartets." @@ -609,18 +746,16 @@ If your Emacs implementation can't decode CHARSET, return nil." (when (and (eq cs 'ascii) mail-parse-charset) (setq cs mail-parse-charset)) - (mm-with-unibyte-current-buffer-mule4 - ;; In Emacs Mule 4, decoding UTF-8 should be in unibyte mode. - (mm-decode-coding-string - (cond - ((equal "B" encoding) - (base64-decode-string - (rfc2047-pad-base64 string))) - ((equal "Q" encoding) - (quoted-printable-decode-string - (mm-replace-chars-in-string string ?_ ? ))) - (t (error "Invalid encoding: %s" encoding))) - cs))))) + (mm-decode-coding-string + (cond + ((equal "B" encoding) + (base64-decode-string + (rfc2047-pad-base64 string))) + ((equal "Q" encoding) + (quoted-printable-decode-string + (mm-replace-chars-in-string string ?_ ? ))) + (t (error "Invalid encoding: %s" encoding))) + cs)))) (provide 'rfc2047) diff --git a/lisp/rfc2231.el b/lisp/rfc2231.el index f0866f8..bd88c71 100644 --- a/lisp/rfc2231.el +++ b/lisp/rfc2231.el @@ -30,6 +30,9 @@ (eval-when-compile (require 'cl)) (require 'ietf-drums) (require 'rfc2047) +(autoload 'mm-encode-body "mm-bodies") +(autoload 'mail-header-remove-whitespace "mail-parse") +(autoload 'mail-header-remove-comments "mail-parse") (defun rfc2231-get-value (ct attribute) "Return the value of ATTRIBUTE from CT." @@ -56,6 +59,7 @@ The list will be on the form (mail-header-remove-comments string))) (let ((table (copy-syntax-table ietf-drums-syntax-table))) (modify-syntax-entry ?\' "w" table) + (modify-syntax-entry ?= " " table) ;; The following isn't valid, but one should be liberal ;; in what one receives. (modify-syntax-entry ?\: "w" table) diff --git a/lisp/sha1-el.el b/lisp/sha1-el.el index 6bd25c6..ab5804d 100644 --- a/lisp/sha1-el.el +++ b/lisp/sha1-el.el @@ -1,6 +1,6 @@ ;;; sha1-el.el --- SHA1 Secure Hash Algorithm in Emacs-Lisp. -;; Copyright (C) 1999, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1999, 2001, 2003 Free Software Foundation, Inc. ;; Author: Shuhei KOBAYASHI ;; Keywords: SHA1, FIPS 180-1 @@ -60,21 +60,32 @@ ;;; external SHA1 function. ;;; -(defvar sha1-maximum-internal-length 500 +(defgroup sha1 nil + "Elisp interface for SHA1 hash computation." + :group 'extensions) + +(defcustom sha1-maximum-internal-length 500 "*Maximum length of message to use lisp version of SHA1 function. If message is longer than this, `sha1-program' is used instead. If this variable is set to 0, use extarnal program only. -If this variable is set to nil, use internal function only.") +If this variable is set to nil, use internal function only." + :type 'integer + :group 'sha1) -(defvar sha1-program '("openssl" "sha1") +(defcustom sha1-program '("sha1sum") "*Name of program to compute SHA1. -It must be a string \(program name\) or list of strings \(name and its args\).") - -(defvar sha1-use-external - (exec-installed-p (car sha1-program)) - "*Use external sha1 program. -If this variable is set to nil, use internal function only.") +It must be a string \(program name\) or list of strings \(name and its args\)." + :type '(repeat string) + :group 'sha1) + +(defcustom sha1-use-external (condition-case () + (executable-find (car sha1-program)) + (error)) + "*Use external SHA1 program. +If this variable is set to nil, use internal function only." + :type 'boolean + :group 'sha1) (defun sha1-string-external (string) ;; `with-temp-buffer' is new in v20, so we do not use it. @@ -416,6 +427,7 @@ If this variable is set to nil, use internal function only.") (sha1-string-external string) (sha1-string-internal string))) +;;;###autoload (defun sha1 (object &optional beg end) "Return the SHA1 (Secure Hash Algorithm) of an object. OBJECT is either a string or a buffer. diff --git a/lisp/sieve-manage.el b/lisp/sieve-manage.el index 8897dd1..bda44dc 100644 --- a/lisp/sieve-manage.el +++ b/lisp/sieve-manage.el @@ -74,7 +74,8 @@ (or (fboundp 'md5) (require 'md5)) (eval-and-compile - (autoload 'starttls-open-stream "starttls")) + (autoload 'starttls-open-stream "starttls") + (autoload 'starttls-negotiate "starttls")) ;; User customizable variables: diff --git a/lisp/sieve.el b/lisp/sieve.el index 8297f57..83dd4f3 100644 --- a/lisp/sieve.el +++ b/lisp/sieve.el @@ -131,6 +131,13 @@ require \"fileinto\"; (define-key sieve-manage-mode-map [(down-mouse-2)] 'sieve-edit-script) (define-key sieve-manage-mode-map [(down-mouse-3)] 'sieve-manage-mode-menu)) +(easy-menu-define sieve-manage-mode-menu sieve-manage-mode-map + "Sieve Menu." + '("Manage Sieve" + ["Edit script" sieve-edit-script t] + ["Activate script" sieve-activate t] + ["Deactivate script" sieve-deactivate t])) + (define-derived-mode sieve-manage-mode fundamental-mode "SIEVE" "Mode used for sieve script management." (setq mode-name "SIEVE") @@ -140,13 +147,6 @@ require \"fileinto\"; (put 'sieve-manage-mode 'mode-class 'special) -(easy-menu-define sieve-manage-mode-menu sieve-manage-mode-map - "Sieve Menu." - '("Manage Sieve" - ["Edit script" sieve-edit-script t] - ["Activate script" sieve-activate t] - ["Deactivate script" sieve-deactivate t])) - ;; This is necessary to allow correct handling of \\[cvs-mode-diff-map] ;; in substitute-command-keys. ;(fset 'sieve-manage-mode-map sieve-manage-mode-map) diff --git a/lisp/smiley.el b/lisp/smiley.el index 0411264..896e456 100644 --- a/lisp/smiley.el +++ b/lisp/smiley.el @@ -195,7 +195,7 @@ A list of images is returned." (gnus-add-image 'smiley image) (put-text-property (point) (progn - (gnus-put-image image string) + (gnus-put-image image string 'smiley) (point)) 'smilified t))))) (put-text-property beg (or end (point-max)) 'smilified nil) diff --git a/lisp/smime.el b/lisp/smime.el index 5701ec8..908e696 100644 --- a/lisp/smime.el +++ b/lisp/smime.el @@ -119,7 +119,6 @@ ;;; Code: (require 'dig) -(require 'comint) (eval-when-compile (require 'cl)) (defgroup smime nil @@ -185,6 +184,27 @@ and the files themself should be in PEM format." (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." @@ -194,6 +214,7 @@ If nil, use system defaults." (defvar smime-details-buffer "*OpenSSL output*") +;; Use mm-util? (eval-and-compile (defalias 'smime-make-temp-file (if (fboundp 'make-temp-file) @@ -210,8 +231,8 @@ If nil, use system defaults." (defun smime-ask-passphrase () "Asks the passphrase to unlock the secret key." (let ((passphrase - (comint-read-noecho - "Passphrase for secret key (RET for no passphrase): " t))) + (read-passwd + "Passphrase for secret key (RET for no passphrase): "))) (if (string= passphrase "") nil passphrase))) @@ -348,6 +369,8 @@ Any details (stdout and stderr) are left in the buffer specified by (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 @@ -489,6 +512,7 @@ A string or a list of strings is returned." (caddr curkey) (smime-get-certfiles keyfile otherkeys))))) +;; Use mm-util? (eval-and-compile (defalias 'smime-point-at-eol (if (fboundp 'point-at-eol) diff --git a/lisp/spam-report.el b/lisp/spam-report.el index 46884c4..efd6778 100644 --- a/lisp/spam-report.el +++ b/lisp/spam-report.el @@ -1,5 +1,5 @@ ;;; spam-report.el --- Reporting spam -;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Teodor Zlatanov ;; Keywords: network @@ -31,16 +31,22 @@ (require 'gnus) (require 'gnus-sum) +(eval-and-compile + (autoload 'mm-url-insert "mm-url")) + (defgroup spam-report nil "Spam reporting configuration.") (defcustom spam-report-gmane-regex nil - "String matching Gmane newsgroups if wanted, e.g. \"^nntp+.*:gmane.\" -This is probably handled better with group/topic parameters." - :type 'regexp + "Regexp matching Gmane newsgroups, e.g. \"^nntp\\+.*:gmane\\.\" +If you are using spam.el, consider setting gnus-spam-process-newsgroups +or the gnus-group-spam-exit-processor-report-gmane group/topic parameter +instead." + :type '(radio (const nil) + (regexp :format "%t: %v\n" :size 0 :value "^nntp\+.*:gmane\.")) :group 'spam-report) -(defcustom spam-report-gmane-spam-header +(defcustom spam-report-gmane-spam-header "^X-Report-Spam: http://\\([^/]+\\)\\(.*\\)$" "String matching Gmane spam-reporting header. Two match groups are needed." :type 'regexp @@ -51,18 +57,28 @@ This is probably handled better with group/topic parameters." :type 'boolean :group 'spam-report) -(defun spam-report-gmane (article) +(defcustom spam-report-url-ping-function + 'spam-report-url-ping-plain + "Function to use for url ping spam reporting." + :type '(choice + (const :tag "Connect directly" + spam-report-url-ping-plain) + (const :tag "Use the external program specified in `mm-url-program'" + spam-report-url-ping-mm-url)) + :group 'spam-report) + +(defun spam-report-gmane (&rest articles) "Report an article as spam through Gmane" - (interactive "nEnter the article number: ") - (when (and gnus-newsgroup-name - (or (null spam-report-gmane-regex) - (string-match spam-report-gmane-regex gnus-newsgroup-name))) - (gnus-message 6 "Reporting spam article %d to spam.gmane.org..." article) + (dolist (article articles) + (when (and gnus-newsgroup-name + (or (null spam-report-gmane-regex) + (string-match spam-report-gmane-regex gnus-newsgroup-name))) + (gnus-message 6 "Reporting spam article %d to spam.gmane.org..." article) (if spam-report-gmane-use-article-number - (spam-report-url-ping "spam.gmane.org" - (format "/%s:%d" - (gnus-group-real-name gnus-newsgroup-name) - article)) + (spam-report-url-ping "spam.gmane.org" + (format "/%s:%d" + (gnus-group-real-name gnus-newsgroup-name) + article)) (with-current-buffer nntp-server-buffer (gnus-request-head article gnus-newsgroup-name) (goto-char (point-min)) @@ -70,27 +86,40 @@ This is probably handled better with group/topic parameters." (let* ((host (match-string 1)) (report (match-string 2)) (url (format "http://%s%s" host report))) - (gnus-message 10 "Reporting spam through URL %s..." url) + (gnus-message 7 "Reporting spam through URL %s..." url) (spam-report-url-ping host report)) - (gnus-message 10 "Could not find X-Report-Spam in article %d..." - article)))))) - + (gnus-message 3 "Could not find X-Report-Spam in article %d..." + article))))))) (defun spam-report-url-ping (host report) - "Ping a host through HTTP, addressing a specific GET resource" + "Ping a host through HTTP, addressing a specific GET resource using +the function specified by `spam-report-url-ping-function'." + (funcall spam-report-url-ping-function host report)) + +(defun spam-report-url-ping-plain (host report) + "Ping a host through HTTP, addressing a specific GET resource." (let ((tcp-connection)) (with-temp-buffer (or (setq tcp-connection - (open-network-stream + (open-network-stream "URL ping" (buffer-name) host 80)) (error "Could not open connection to %s" host)) (set-marker (process-mark tcp-connection) (point-min)) - (process-send-string tcp-connection - (format "GET %s HTTP/1.1\nHost: %s\n\n" - report host))))) + (process-send-string + tcp-connection + (format "GET %s HTTP/1.1\nUser-Agent: %s (spam-report.el)\nHost: %s\n\n" + report (gnus-emacs-version) host))))) + +(defun spam-report-url-ping-mm-url (host report) + "Ping a host through HTTP, addressing a specific GET resource. Use +the external program specified in `mm-url-program' to connect to +server." + (with-temp-buffer + (let ((url (concat "http://" host "/" report))) + (mm-url-insert url t)))) (provide 'spam-report) diff --git a/lisp/spam-stat.el b/lisp/spam-stat.el index 96df016..e85e057 100644 --- a/lisp/spam-stat.el +++ b/lisp/spam-stat.el @@ -183,6 +183,9 @@ effect when spam-stat is invoked through spam.el." "Syntax table used when processing mails for statistical analysis. The important part is which characters are word constituents.") +(defvar spam-stat-dirty nil + "Whether the spam-stat database needs saving.") + (defvar spam-stat-buffer nil "Buffer to use for scoring while splitting. This is set by hooking into Gnus.") @@ -238,12 +241,6 @@ This uses `gnus-article-buffer'." (set-buffer gnus-original-article-buffer) (spam-stat-store-current-buffer))) -(when spam-stat-install-hooks - (add-hook 'nnmail-prepare-incoming-message-hook - 'spam-stat-store-current-buffer) - (add-hook 'gnus-select-article-hook - 'spam-stat-store-gnus-article-buffer)) - ;; Data -- not using defstruct in order to save space and time (defvar spam-stat (make-hash-table :test 'equal) @@ -347,7 +344,8 @@ Use `spam-stat-ngood', `spam-stat-nbad', `spam-stat-good', (setq entry (spam-stat-make-entry 0 count))) (spam-stat-set-score entry (spam-stat-compute-score entry)) (puthash word entry spam-stat))) - (spam-stat-buffer-words))) + (spam-stat-buffer-words)) + (setq spam-stat-dirty t)) (defun spam-stat-buffer-is-non-spam () "Consider current buffer to be a new non-spam mail." @@ -360,7 +358,8 @@ Use `spam-stat-ngood', `spam-stat-nbad', `spam-stat-good', (setq entry (spam-stat-make-entry count 0))) (spam-stat-set-score entry (spam-stat-compute-score entry)) (puthash word entry spam-stat))) - (spam-stat-buffer-words))) + (spam-stat-buffer-words)) + (setq spam-stat-dirty t)) (defun spam-stat-buffer-change-to-spam () "Consider current buffer no longer normal mail but spam." @@ -375,7 +374,8 @@ Use `spam-stat-ngood', `spam-stat-nbad', `spam-stat-good', (spam-stat-set-bad entry (+ (spam-stat-bad entry) count)) (spam-stat-set-score entry (spam-stat-compute-score entry)) (puthash word entry spam-stat)))) - (spam-stat-buffer-words))) + (spam-stat-buffer-words)) + (setq spam-stat-dirty t)) (defun spam-stat-buffer-change-to-non-spam () "Consider current buffer no longer spam but normal mail." @@ -390,32 +390,37 @@ Use `spam-stat-ngood', `spam-stat-nbad', `spam-stat-good', (spam-stat-set-bad entry (- (spam-stat-bad entry) count)) (spam-stat-set-score entry (spam-stat-compute-score entry)) (puthash word entry spam-stat)))) - (spam-stat-buffer-words))) + (spam-stat-buffer-words)) + (setq spam-stat-dirty t)) ;; Saving and Loading -(defun spam-stat-save () +(defun spam-stat-save (&optional force) "Save the `spam-stat' hash table as lisp file." (interactive) - (with-temp-buffer - (let ((standard-output (current-buffer)) - (font-lock-maximum-size 0)) - (insert "(setq spam-stat-ngood " - (number-to-string spam-stat-ngood) - " spam-stat-nbad " - (number-to-string spam-stat-nbad) - " spam-stat (spam-stat-to-hash-table '(") - (maphash (lambda (word entry) - (prin1 (list word - (spam-stat-good entry) - (spam-stat-bad entry)))) - spam-stat) - (insert ")))") - (write-file spam-stat-file)))) + (when (or force spam-stat-dirty) + (with-temp-buffer + (let ((standard-output (current-buffer)) + (font-lock-maximum-size 0)) + (insert "(setq spam-stat-ngood " + (number-to-string spam-stat-ngood) + " spam-stat-nbad " + (number-to-string spam-stat-nbad) + " spam-stat (spam-stat-to-hash-table '(") + (maphash (lambda (word entry) + (prin1 (list word + (spam-stat-good entry) + (spam-stat-bad entry)))) + spam-stat) + (insert ")))") + (write-file spam-stat-file))) + (setq spam-stat-dirty nil))) (defun spam-stat-load () "Read the `spam-stat' hash table from disk." - (load-file spam-stat-file)) + ;; TODO: maybe we should warn the user if spam-stat-dirty is t? + (load-file spam-stat-file) + (setq spam-stat-dirty nil)) (defun spam-stat-to-hash-table (entries) "Turn list ENTRIES into a hash table and store as `spam-stat'. @@ -438,7 +443,8 @@ This deletes all the statistics." (interactive) (setq spam-stat (make-hash-table :test 'equal) spam-stat-ngood 0 - spam-stat-nbad 0)) + spam-stat-nbad 0) + (setq spam-stat-dirty t)) ;; Scoring buffers @@ -567,6 +573,25 @@ COUNT defaults to 5" (remhash key spam-stat))) spam-stat)) +(defun spam-stat-install-hooks-function () + "Install the spam-stat function hooks" + (interactive) + (add-hook 'nnmail-prepare-incoming-message-hook + 'spam-stat-store-current-buffer) + (add-hook 'gnus-select-article-hook + 'spam-stat-store-gnus-article-buffer)) + +(when spam-stat-install-hooks + (spam-stat-install-hooks-function)) + +(defun spam-stat-unload-hook () + "Uninstall the spam-stat function hooks" + (interactive) + (remove-hook 'nnmail-prepare-incoming-message-hook + 'spam-stat-store-current-buffer) + (remove-hook 'gnus-select-article-hook + 'spam-stat-store-gnus-article-buffer)) + (provide 'spam-stat) ;;; spam-stat.el ends here diff --git a/lisp/spam.el b/lisp/spam.el index 4f84c11..008f8e9 100644 --- a/lisp/spam.el +++ b/lisp/spam.el @@ -1,5 +1,5 @@ ;;; spam.el --- Identifying spam -;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: network @@ -32,6 +32,9 @@ ;;; Several TODO items are marked as such +;; TODO: spam scores, detection of spam in newsgroups, cross-server splitting, +;; remote processing, training through files + ;;; Code: (require 'path-util) @@ -41,8 +44,9 @@ (require 'gnus-sum) (require 'gnus-uu) ; because of key prefix issues -(require 'gnus) ; for the definitions of group content classification and spam processors -(require 'message) ;for the message-fetch-field functions +;;; for the definitions of group content classification and spam processors +(require 'gnus) +(require 'message) ;for the message-fetch-field functions ;; for nnimap-split-download-body-default (eval-when-compile (require 'nnimap)) @@ -55,6 +59,13 @@ (eval-and-compile (autoload 'spam-report-gmane "spam-report")) +;; autoload gnus-registry +(eval-and-compile + (autoload 'gnus-registry-group-count "gnus-registry") + (autoload 'gnus-registry-add-group "gnus-registry") + (autoload 'gnus-registry-store-extra-entry "gnus-registry") + (autoload 'gnus-registry-fetch-extra "gnus-registry")) + ;; autoload query-dns (eval-and-compile (autoload 'query-dns "dns")) @@ -71,28 +82,69 @@ (defcustom spam-move-spam-nonspam-groups-only t "Whether spam should be moved in non-spam groups only. -When nil, only ham and unclassified groups will have their spam moved -to the spam-process-destination. When t, spam will also be moved from +When t, only ham and unclassified groups will have their spam moved +to the spam-process-destination. When nil, spam will also be moved from spam groups." :type 'boolean :group 'spam) +(defcustom spam-process-ham-in-nonham-groups nil + "Whether ham should be processed in non-ham groups." + :type 'boolean + :group 'spam) + +(defcustom spam-log-to-registry nil + "Whether spam/ham processing should be logged in the registry." + :type 'boolean + :group 'spam) + +(defcustom spam-split-symbolic-return nil + "Whether `spam-split' should work with symbols or group names." + :type 'boolean + :group 'spam) + +(defcustom spam-split-symbolic-return-positive nil + "Whether `spam-split' should ALWAYS work with symbols or group names. +Do not set this if you use `spam-split' in a fancy split + method." + :type 'boolean + :group 'spam) + +(defcustom spam-process-ham-in-spam-groups nil + "Whether ham should be processed in spam groups." + :type 'boolean + :group 'spam) + (defcustom spam-mark-only-unseen-as-spam t - "Whether only unseen articles should be marked as spam in spam -groups. When nil, all unread articles in a spam group are marked as + "Whether only unseen articles should be marked as spam in spam groups. +When nil, all unread articles in a spam group are marked as spam. Set this if you want to leave an article unread in a spam group without losing it to the automatic spam-marking process." :type 'boolean :group 'spam) (defcustom spam-mark-ham-unread-before-move-from-spam-group nil - "Whether ham should be marked unread before it's moved out of a spam -group according to ham-process-destination. This variable is an -official entry in the international Longest Variable Name + "Whether ham should be marked unread before it's moved. +The article is moved out of a spam group according to ham-process-destination. +This variable is an official entry in the international Longest Variable Name Competition." :type 'boolean :group 'spam) +(defcustom spam-disable-spam-split-during-ham-respool nil + "Whether `spam-split' should be ignored while resplitting ham in a process +destination. This is useful to prevent ham from ending up in the same spam +group after the resplit. Don't set this to t if you have spam-split as the +last rule in your split configuration." + :type 'boolean + :group 'spam) + +(defcustom spam-autodetect-recheck-messages nil + "Should spam.el recheck all meessages when autodetecting? +Normally this is nil, so only unseen messages will be checked." + :type 'boolean + :group 'spam) + (defcustom spam-whitelist (expand-file-name "whitelist" spam-directory) "The location of the whitelist. The file format is one regular expression per line. @@ -108,114 +160,166 @@ The regular expression is matched against the address." :group 'spam) (defcustom spam-use-dig t - "Whether query-dig should be used instead of query-dns." + "Whether `query-dig' should be used instead of `query-dns'." :type 'boolean :group 'spam) (defcustom spam-use-blacklist nil - "Whether the blacklist should be used by spam-split." + "Whether the blacklist should be used by `spam-split'." :type 'boolean :group 'spam) +(defcustom spam-blacklist-ignored-regexes nil + "Regular expressions that the blacklist should ignore." + :type '(repeat (regexp :tag "Regular expression to ignore when blacklisting")) + :group 'spam) + (defcustom spam-use-whitelist nil - "Whether the whitelist should be used by spam-split." + "Whether the whitelist should be used by `spam-split'." :type 'boolean :group 'spam) (defcustom spam-use-whitelist-exclusive nil - "Whether whitelist-exclusive should be used by spam-split. + "Whether whitelist-exclusive should be used by `spam-split'. Exclusive whitelisting means that all messages from senders not in the whitelist are considered spam." :type 'boolean :group 'spam) (defcustom spam-use-blackholes nil - "Whether blackholes should be used by spam-split." + "Whether blackholes should be used by `spam-split'." :type 'boolean :group 'spam) (defcustom spam-use-hashcash nil - "Whether hashcash payments should be detected by spam-split." + "Whether hashcash payments should be detected by `spam-split'." :type 'boolean :group 'spam) (defcustom spam-use-regex-headers nil - "Whether a header regular expression match should be used by spam-split. -Also see the variable `spam-spam-regex-headers' and `spam-ham-regex-headers'." + "Whether a header regular expression match should be used by `spam-split'. +Also see the variables `spam-regex-headers-spam' and `spam-regex-headers-ham'." + :type 'boolean + :group 'spam) + +(defcustom spam-use-regex-body nil + "Whether a body regular expression match should be used by `spam-split'. +Also see the variables `spam-regex-body-spam' and `spam-regex-body-ham'." :type 'boolean :group 'spam) (defcustom spam-use-bogofilter-headers nil - "Whether bogofilter headers should be used by spam-split. + "Whether bogofilter headers should be used by `spam-split'. Enable this if you pre-process messages with Bogofilter BEFORE Gnus sees them." :type 'boolean :group 'spam) (defcustom spam-use-bogofilter nil - "Whether bogofilter should be invoked by spam-split. + "Whether bogofilter should be invoked by `spam-split'. Enable this if you want Gnus to invoke Bogofilter on new messages." :type 'boolean :group 'spam) (defcustom spam-use-BBDB nil - "Whether BBDB should be used by spam-split." + "Whether BBDB should be used by `spam-split'." :type 'boolean :group 'spam) (defcustom spam-use-BBDB-exclusive nil - "Whether BBDB-exclusive should be used by spam-split. -Exclusive BBDB means that all messages from senders not in the BBDB are + "Whether BBDB-exclusive should be used by `spam-split'. +Exclusive BBDB means that all messages from senders not in the BBDB are considered spam." :type 'boolean :group 'spam) (defcustom spam-use-ifile nil - "Whether ifile should be used by spam-split." + "Whether ifile should be used by `spam-split'." :type 'boolean :group 'spam) (defcustom spam-use-stat nil - "Whether spam-stat should be used by spam-split." + "Whether `spam-stat' should be used by `spam-split'." :type 'boolean :group 'spam) +(defcustom spam-use-spamoracle nil + "Whether spamoracle should be used by `spam-split'." + :type 'boolean + :group 'spam) + +(defcustom spam-install-hooks (or + spam-use-dig + spam-use-blacklist + spam-use-whitelist + spam-use-whitelist-exclusive + spam-use-blackholes + spam-use-hashcash + spam-use-regex-headers + spam-use-regex-body + spam-use-bogofilter-headers + spam-use-bogofilter + spam-use-BBDB + spam-use-BBDB-exclusive + spam-use-ifile + spam-use-stat + spam-use-spamoracle) + "Whether the spam hooks should be installed. +Default to t if one of the spam-use-* variables is set." + :group 'spam + :type 'boolean) + (defcustom spam-split-group "spam" - "Group name where incoming spam should be put by spam-split." + "Group name where incoming spam should be put by `spam-split'." :type 'string :group 'spam) -(defcustom spam-junk-mailgroups (cons spam-split-group '("mail.junk" "poste.pourriel")) +;;; TODO: deprecate this variable, it's confusing since it's a list of strings, +;;; not regular expressions +(defcustom spam-junk-mailgroups (cons + spam-split-group + '("mail.junk" "poste.pourriel")) "Mailgroups with spam contents. All unmarked article in such group receive the spam mark on group entry." :type '(repeat (string :tag "Group")) :group 'spam) -(defcustom spam-blackhole-servers '("bl.spamcop.net" "relays.ordb.org" +(defcustom spam-blackhole-servers '("bl.spamcop.net" "relays.ordb.org" "dev.null.dk" "relays.visi.com") "List of blackhole servers." :type '(repeat (string :tag "Server")) :group 'spam) (defcustom spam-blackhole-good-server-regex nil - "String matching IP addresses that should not be checked in the blackholes" - :type 'regexp + "String matching IP addresses that should not be checked in the blackholes." + :type '(radio (const nil) + (regexp :format "%t: %v\n" :size 0)) :group 'spam) (defcustom spam-face 'gnus-splash-face - "Face for spam-marked articles" + "Face for spam-marked articles." :type 'face :group 'spam) (defcustom spam-regex-headers-spam '("^X-Spam-Flag: YES") - "Regular expression for positive header spam matches" + "Regular expression for positive header spam matches." :type '(repeat (regexp :tag "Regular expression to match spam header")) :group 'spam) (defcustom spam-regex-headers-ham '("^X-Spam-Flag: NO") - "Regular expression for positive header ham matches" + "Regular expression for positive header ham matches." :type '(repeat (regexp :tag "Regular expression to match ham header")) :group 'spam) +(defcustom spam-regex-body-spam '() + "Regular expression for positive body spam matches." + :type '(repeat (regexp :tag "Regular expression to match spam body")) + :group 'spam) + +(defcustom spam-regex-body-ham '() + "Regular expression for positive body ham matches." + :type '(repeat (regexp :tag "Regular expression to match ham body")) + :group 'spam) + (defgroup spam-ifile nil "Spam ifile configuration." :group 'spam) @@ -233,20 +337,20 @@ All unmarked article in such group receive the spam mark on group entry." :group 'spam-ifile) (defcustom spam-ifile-spam-category "spam" - "Name of the spam ifile category." + "Name of the spam ifile category." :type 'string :group 'spam-ifile) (defcustom spam-ifile-ham-category nil - "Name of the ham ifile category. If nil, the current group name will -be used." + "Name of the ham ifile category. +If nil, the current group name will be used." :type '(choice (string :tag "Use a fixed category") - (const :tag "Use the current group name")) + (const :tag "Use the current group name")) :group 'spam-ifile) (defcustom spam-ifile-all-categories nil "Whether the ifile check will return all categories, or just spam. -Set this to t if you want to use the spam-split invocation of ifile as +Set this to t if you want to use the `spam-split' invocation of ifile as your main source of newsgroup names." :type 'boolean :group 'spam-ifile) @@ -276,6 +380,16 @@ your main source of newsgroup names." :type 'string :group 'spam-bogofilter) +(defcustom spam-bogofilter-spam-strong-switch "-S" + "The switch that Bogofilter uses to unregister ham messages." + :type 'string + :group 'spam-bogofilter) + +(defcustom spam-bogofilter-ham-strong-switch "-N" + "The switch that Bogofilter uses to unregister spam messages." + :type 'string + :group 'spam-bogofilter) + (defcustom spam-bogofilter-bogosity-positive-spam-header "^\\(Yes\\|Spam\\)" "The regex on `spam-bogofilter-header' for positive spam identification." :type 'regexp @@ -283,9 +397,27 @@ your main source of newsgroup names." (defcustom spam-bogofilter-database-directory nil "Directory path of the Bogofilter databases." - :type '(choice (directory :tag "Location of the Bogofilter database directory") + :type '(choice (directory + :tag "Location of the Bogofilter database directory") (const :tag "Use the default")) - :group 'spam-ifile) + :group 'spam-bogofilter) + +(defgroup spam-spamoracle nil + "Spam spamoracle configuration." + :group 'spam) + +(defcustom spam-spamoracle-database nil + "Location of spamoracle database file. When nil, use the default +spamoracle database." + :type '(choice (directory :tag "Location of spamoracle database file.") + (const :tag "Use the default")) + :group 'spam-spamoracle) + +(defcustom spam-spamoracle-binary (executable-find "spamoracle") + "Location of the spamoracle binary." + :type '(choice (directory :tag "Location of the spamoracle binary") + (const :tag "Use the default")) + :group 'spam-spamoracle) ;;; Key bindings for spam control. @@ -296,19 +428,29 @@ your main source of newsgroup names." "Msx" gnus-summary-mark-as-spam "\M-d" gnus-summary-mark-as-spam) -;;; How to highlight a spam summary line. +(defvar spam-old-ham-articles nil + "List of old ham articles, generated when a group is entered.") -;; TODO: How do we redo this every time spam-face is customized? +(defvar spam-old-spam-articles nil + "List of old spam articles, generated when a group is entered.") -(push '((eq mark gnus-spam-mark) . spam-face) - gnus-summary-highlight) +(defvar spam-split-disabled nil + "If non-nil, `spam-split' is disabled, and always returns nil.") + +(defvar spam-split-last-successful-check nil + "`spam-split' will set this to nil or a spam-use-XYZ check if it + finds ham or spam.") ;; convenience functions +(defun spam-xor (a b) + "Logical exclusive `or'." + (and (or a b) (not (and a b)))) + (defun spam-group-ham-mark-p (group mark &optional spam) (when (stringp group) (let* ((marks (spam-group-ham-marks group spam)) - (marks (if (symbolp mark) - marks + (marks (if (symbolp mark) + marks (mapcar 'symbol-value marks)))) (memq mark marks)))) @@ -318,8 +460,8 @@ your main source of newsgroup names." (defun spam-group-ham-marks (group &optional spam) (when (stringp group) (let* ((marks (if spam - (gnus-parameter-spam-marks group) - (gnus-parameter-ham-marks group))) + (gnus-parameter-spam-marks group) + (gnus-parameter-ham-marks group))) (marks (car marks)) (marks (if (listp (car marks)) (car marks) marks))) marks))) @@ -330,22 +472,56 @@ your main source of newsgroup names." (defun spam-group-spam-contents-p (group) (if (stringp group) (or (member group spam-junk-mailgroups) - (memq 'gnus-group-spam-classification-spam + (memq 'gnus-group-spam-classification-spam (gnus-parameter-spam-contents group))) nil)) - + (defun spam-group-ham-contents-p (group) (if (stringp group) - (memq 'gnus-group-spam-classification-ham + (memq 'gnus-group-spam-classification-ham (gnus-parameter-spam-contents group)) nil)) +(defvar spam-list-of-processors + '((gnus-group-spam-exit-processor-report-gmane spam spam-use-gmane) + (gnus-group-spam-exit-processor-bogofilter spam spam-use-bogofilter) + (gnus-group-spam-exit-processor-blacklist spam spam-use-blacklist) + (gnus-group-spam-exit-processor-ifile spam spam-use-ifile) + (gnus-group-spam-exit-processor-stat spam spam-use-stat) + (gnus-group-spam-exit-processor-spamoracle spam spam-use-spamoracle) + (gnus-group-ham-exit-processor-ifile ham spam-use-ifile) + (gnus-group-ham-exit-processor-bogofilter ham spam-use-bogofilter) + (gnus-group-ham-exit-processor-stat ham spam-use-stat) + (gnus-group-ham-exit-processor-whitelist ham spam-use-whitelist) + (gnus-group-ham-exit-processor-BBDB ham spam-use-BBDB) + (gnus-group-ham-exit-processor-copy ham spam-use-ham-copy) + (gnus-group-ham-exit-processor-spamoracle ham spam-use-spamoracle)) + "The spam-list-of-processors list contains pairs associating a +ham/spam exit processor variable with a classification and a +spam-use-* variable.") + (defun spam-group-processor-p (group processor) (if (and (stringp group) (symbolp processor)) - (member processor (car (gnus-parameter-spam-process group))) + (or (member processor (nth 0 (gnus-parameter-spam-process group))) + (spam-group-processor-multiple-p + group + (cdr-safe (assoc processor spam-list-of-processors)))) nil)) +(defun spam-group-processor-multiple-p (group processor-info) + (let* ((classification (nth 0 processor-info)) + (check (nth 1 processor-info)) + (parameters (nth 0 (gnus-parameter-spam-process group))) + found) + (dolist (parameter parameters) + (when (and (null found) + (listp parameter) + (eq classification (nth 0 parameter)) + (eq check (nth 1 parameter))) + (setq found t))) + found)) + (defun spam-group-spam-processor-report-gmane-p (group) (spam-group-processor-p group 'gnus-group-spam-exit-processor-report-gmane)) @@ -361,6 +537,9 @@ your main source of newsgroup names." (defun spam-group-ham-processor-ifile-p (group) (spam-group-processor-p group 'gnus-group-ham-exit-processor-ifile)) +(defun spam-group-spam-processor-spamoracle-p (group) + (spam-group-processor-p group 'gnus-group-spam-exit-processor-spamoracle)) + (defun spam-group-ham-processor-bogofilter-p (group) (spam-group-processor-p group 'gnus-group-ham-exit-processor-bogofilter)) @@ -379,45 +558,65 @@ your main source of newsgroup names." (defun spam-group-ham-processor-copy-p (group) (spam-group-processor-p group 'gnus-group-ham-exit-processor-copy)) +(defun spam-group-ham-processor-spamoracle-p (group) + (spam-group-processor-p group 'gnus-group-ham-exit-processor-spamoracle)) + ;;; Summary entry and exit processing. (defun spam-summary-prepare () + (setq spam-old-ham-articles + (spam-list-articles gnus-newsgroup-articles 'ham)) + (setq spam-old-spam-articles + (spam-list-articles gnus-newsgroup-articles 'spam)) (spam-mark-junk-as-spam-routine)) -(add-hook 'gnus-summary-prepare-hook 'spam-summary-prepare) - ;; The spam processors are invoked for any group, spam or ham or neither (defun spam-summary-prepare-exit () (unless gnus-group-is-exiting-without-update-p (gnus-message 6 "Exiting summary buffer and applying spam rules") - (when (and spam-bogofilter-path - (spam-group-spam-processor-bogofilter-p gnus-newsgroup-name)) - (gnus-message 5 "Registering spam with bogofilter") - (spam-bogofilter-register-spam-routine)) - - (when (and spam-ifile-path - (spam-group-spam-processor-ifile-p gnus-newsgroup-name)) - (gnus-message 5 "Registering spam with ifile") - (spam-ifile-register-spam-routine)) - - (when (spam-group-spam-processor-stat-p gnus-newsgroup-name) - (gnus-message 5 "Registering spam with spam-stat") - (spam-stat-register-spam-routine)) - - (when (spam-group-spam-processor-blacklist-p gnus-newsgroup-name) - (gnus-message 5 "Registering spam with the blacklist") - (spam-blacklist-register-routine)) - - (when (spam-group-spam-processor-report-gmane-p gnus-newsgroup-name) - (gnus-message 5 "Registering spam with the Gmane report") - (spam-report-gmane-register-routine)) - - (if spam-move-spam-nonspam-groups-only + + ;; first of all, unregister any articles that are no longer ham or spam + ;; we have to iterate over the processors, or else we'll be too slow + (dolist (classification '(spam ham)) + (let* ((old-articles (if (eq classification 'spam) + spam-old-spam-articles + spam-old-ham-articles)) + (new-articles (spam-list-articles + gnus-newsgroup-articles + classification)) + (changed-articles (gnus-set-difference old-articles new-articles))) + ;; now that we have the changed articles, we go through the processors + (dolist (processor-param spam-list-of-processors) + (let ((processor (nth 0 processor-param)) + (processor-classification (nth 1 processor-param)) + (check (nth 2 processor-param)) + unregister-list) + (dolist (article changed-articles) + (let ((id (spam-fetch-field-message-id-fast article))) + (when (spam-log-unregistration-needed-p + id 'process classification check) + (push article unregister-list)))) + ;; call spam-register-routine with specific articles to unregister, + ;; when there are articles to unregister and the check is enabled + (when (and unregister-list (symbol-value check)) + (spam-register-routine classification check t unregister-list)))))) + + ;; find all the spam processors applicable to this group + (dolist (processor-param spam-list-of-processors) + (let ((processor (nth 0 processor-param)) + (classification (nth 1 processor-param)) + (check (nth 2 processor-param))) + (when (and (eq 'spam classification) + (spam-group-processor-p gnus-newsgroup-name processor)) + (spam-register-routine classification check)))) + + (if spam-move-spam-nonspam-groups-only (when (not (spam-group-spam-contents-p gnus-newsgroup-name)) (spam-mark-spam-as-expired-and-move-routine (gnus-parameter-spam-process-destination gnus-newsgroup-name))) - (gnus-message 5 "Marking spam as expired and moving it to %s" gnus-newsgroup-name) - (spam-mark-spam-as-expired-and-move-routine + (gnus-message 5 "Marking spam as expired and moving it to %s" + gnus-newsgroup-name) + (spam-mark-spam-as-expired-and-move-routine (gnus-parameter-spam-process-destination gnus-newsgroup-name))) ;; now we redo spam-mark-spam-as-expired-and-move-routine to only @@ -425,110 +624,141 @@ your main source of newsgroup names." (gnus-message 5 "Marking spam as expired without moving it") (spam-mark-spam-as-expired-and-move-routine nil) - (when (spam-group-ham-contents-p gnus-newsgroup-name) - (when (spam-group-ham-processor-whitelist-p gnus-newsgroup-name) - (gnus-message 5 "Registering ham with the whitelist") - (spam-whitelist-register-routine)) - (when (spam-group-ham-processor-ifile-p gnus-newsgroup-name) - (gnus-message 5 "Registering ham with ifile") - (spam-ifile-register-ham-routine)) - (when (spam-group-ham-processor-bogofilter-p gnus-newsgroup-name) - (gnus-message 5 "Registering ham with Bogofilter") - (spam-bogofilter-register-ham-routine)) - (when (spam-group-ham-processor-stat-p gnus-newsgroup-name) - (gnus-message 5 "Registering ham with spam-stat") - (spam-stat-register-ham-routine)) - (when (spam-group-ham-processor-BBDB-p gnus-newsgroup-name) - (gnus-message 5 "Registering ham with the BBDB") - (spam-BBDB-register-routine))) + (when (or (spam-group-ham-contents-p gnus-newsgroup-name) + (and (spam-group-spam-contents-p gnus-newsgroup-name) + spam-process-ham-in-spam-groups) + spam-process-ham-in-nonham-groups) + ;; find all the ham processors applicable to this group + (dolist (processor-param spam-list-of-processors) + (let ((processor (nth 0 processor-param)) + (classification (nth 1 processor-param)) + (check (nth 2 processor-param))) + (when (and (eq 'ham classification) + (spam-group-processor-p gnus-newsgroup-name processor)) + (spam-register-routine classification check))))) (when (spam-group-ham-processor-copy-p gnus-newsgroup-name) (gnus-message 5 "Copying ham") - (spam-ham-move-routine - (gnus-parameter-ham-process-destination gnus-newsgroup-name) t)) + (spam-ham-copy-routine + (gnus-parameter-ham-process-destination gnus-newsgroup-name))) ;; now move all ham articles out of spam groups (when (spam-group-spam-contents-p gnus-newsgroup-name) (gnus-message 5 "Moving ham messages from spam group") (spam-ham-move-routine - (gnus-parameter-ham-process-destination gnus-newsgroup-name))))) + (gnus-parameter-ham-process-destination gnus-newsgroup-name)))) -(add-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit) + (setq spam-old-ham-articles nil) + (setq spam-old-spam-articles nil)) (defun spam-mark-junk-as-spam-routine () ;; check the global list of group names spam-junk-mailgroups and the ;; group parameters (when (spam-group-spam-contents-p gnus-newsgroup-name) (gnus-message 5 "Marking %s articles as spam" - (if spam-mark-only-unseen-as-spam + (if spam-mark-only-unseen-as-spam "unseen" "unread")) - (let ((articles (if spam-mark-only-unseen-as-spam + (let ((articles (if spam-mark-only-unseen-as-spam gnus-newsgroup-unseen gnus-newsgroup-unreads))) (dolist (article articles) (gnus-summary-mark-article article gnus-spam-mark))))) -(defun spam-mark-spam-as-expired-and-move-routine (&optional group) - (gnus-summary-kill-process-mark) - (let ((articles gnus-newsgroup-articles) - article tomove) - (dolist (article articles) - (when (eq (gnus-summary-article-mark article) gnus-spam-mark) - (gnus-summary-mark-article article gnus-expirable-mark) - (push article tomove))) - - ;; now do the actual move - (when (and tomove - (stringp group)) - (dolist (article tomove) - (gnus-summary-set-process-mark article)) - (when tomove (gnus-summary-move-article nil group)))) - (gnus-summary-yank-process-mark)) - -(defun spam-ham-move-routine (&optional group copy) - (gnus-summary-kill-process-mark) - (let ((articles gnus-newsgroup-articles) - article mark tomove) - (when (stringp group) ; this routine will do nothing - ; without a valid group +(defun spam-mark-spam-as-expired-and-move-routine (&rest groups) + (if (and (car-safe groups) (listp (car-safe groups))) + (apply 'spam-mark-spam-as-expired-and-move-routine (car groups)) + (gnus-summary-kill-process-mark) + (let ((articles gnus-newsgroup-articles) + (backend-supports-deletions + (gnus-check-backend-function + 'request-move-article gnus-newsgroup-name)) + article tomove deletep) (dolist (article articles) - (when (spam-group-ham-mark-p gnus-newsgroup-name - (gnus-summary-article-mark article)) + (when (eq (gnus-summary-article-mark article) gnus-spam-mark) + (gnus-summary-mark-article article gnus-expirable-mark) (push article tomove))) - ;; now do the actual move - (when tomove + ;; now do the actual copies + (dolist (group groups) + (when (and tomove + (stringp group)) + (dolist (article tomove) + (gnus-summary-set-process-mark article)) + (when tomove + (if (or (not backend-supports-deletions) + (> (length groups) 1)) + (progn + (gnus-summary-copy-article nil group) + (setq deletep t)) + (gnus-summary-move-article nil group))))) + + ;; now delete the articles, if there was a copy done, and the + ;; backend allows it + (when (and deletep backend-supports-deletions) (dolist (article tomove) + (gnus-summary-set-process-mark article)) + (when tomove + (let ((gnus-novice-user nil)) ; don't ask me if I'm sure + (gnus-summary-delete-article nil)))) + + (gnus-summary-yank-process-mark)))) + +(defun spam-ham-copy-or-move-routine (copy groups) + (gnus-summary-kill-process-mark) + (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) + + (when (member 'respool groups) + (setq respool t) ; boolean for later + (setq groups '("fake"))) ; when respooling, groups are dynamic so fake it + + ;; now do the actual move + (dolist (group groups) + (when (and todo (stringp group)) + (dolist (article todo) (when spam-mark-ham-unread-before-move-from-spam-group - (gnus-summary-mark-article article gnus-unread-mark)) + (gnus-summary-mark-article article gnus-unread-mark)) + (gnus-summary-set-process-mark article)) + + (if respool ; respooling is with a "fake" group + (let ((spam-split-disabled + (or spam-split-disabled + spam-disable-spam-split-during-ham-respool))) + (gnus-summary-respool-article nil respool-method)) + (if (or (not backend-supports-deletions) ; else, we are not respooling + (> (length groups) 1)) + (progn ; if copying, copy and set deletep + (gnus-summary-copy-article nil group) + (setq deletep t)) + (gnus-summary-move-article nil group))))) ; else move articles + + ;; now delete the articles, unless a) copy is t, and there was a copy done + ;; b) a move was done to a single group + ;; c) backend-supports-deletions is nil + (unless copy + (when (and deletep backend-supports-deletions) + (dolist (article todo) (gnus-summary-set-process-mark article)) - (if copy - (gnus-summary-copy-article nil group) - (gnus-summary-move-article nil group))))) + (when todo + (let ((gnus-novice-user nil)) ; don't ask me if I'm sure + (gnus-summary-delete-article nil)))))) + (gnus-summary-yank-process-mark)) - -(defun spam-generic-register-routine (spam-func ham-func) - (let ((articles gnus-newsgroup-articles) - article mark ham-articles spam-articles) - - (while articles - (setq article (pop articles) - mark (gnus-summary-article-mark article)) - (cond ((spam-group-spam-mark-p gnus-newsgroup-name mark) - (push article spam-articles)) - ((memq article gnus-newsgroup-saved)) - ((spam-group-ham-mark-p gnus-newsgroup-name mark) - (push article ham-articles)))) - - (when (and ham-articles ham-func) - (mapc ham-func ham-articles)) ; we use mapc because unlike - ; mapcar it discards the - ; return values - (when (and spam-articles spam-func) - (mapc spam-func spam-articles)))) ; we use mapc because unlike - ; mapcar it discards the - ; return values + +(defun spam-ham-copy-routine (&rest groups) + (if (and (car-safe groups) (listp (car-safe groups))) + (apply 'spam-ham-copy-routine (car groups)) + (spam-ham-copy-or-move-routine t groups))) + +(defun spam-ham-move-routine (&rest groups) + (if (and (car-safe groups) (listp (car-safe groups))) + (apply 'spam-ham-move-routine (car groups)) + (spam-ham-copy-or-move-routine nil groups))) (eval-and-compile (defalias 'spam-point-at-eol (if (fboundp 'point-at-eol) @@ -537,12 +767,12 @@ your main source of newsgroup names." (defun spam-get-article-as-string (article) (let ((article-buffer (spam-get-article-as-buffer article)) - article-string) + article-string) (when article-buffer (save-window-excursion (set-buffer article-buffer) (setq article-string (buffer-string)))) - article-string)) + article-string)) (defun spam-get-article-as-buffer (article) (let ((article-buffer)) @@ -557,8 +787,10 @@ your main source of newsgroup names." ;; (defun spam-get-article-as-filename (article) ;; (let ((article-filename)) ;; (when (numberp article) -;; (nnml-possibly-change-directory (gnus-group-real-name gnus-newsgroup-name)) -;; (setq article-filename (expand-file-name (int-to-string article) nnml-current-directory))) +;; (nnml-possibly-change-directory +;; (gnus-group-real-name gnus-newsgroup-name)) +;; (setq article-filename (expand-file-name +;; (int-to-string article) nnml-current-directory))) ;; (if (file-exists-p article-filename) ;; article-filename ;; nil))) @@ -567,99 +799,404 @@ your main source of newsgroup names." "Fetch the `from' field quickly, using the internal gnus-data-list function" (if (and (numberp article) (assoc article (gnus-data-list nil))) - (mail-header-from (gnus-data-header (assoc article (gnus-data-list nil)))) + (mail-header-from + (gnus-data-header (assoc article (gnus-data-list nil)))) nil)) (defun spam-fetch-field-subject-fast (article) - "Fetch the `subject' field quickly, using the internal gnus-data-list function" + "Fetch the `subject' field quickly, using the internal + gnus-data-list function" (if (and (numberp article) (assoc article (gnus-data-list nil))) - (mail-header-subject (gnus-data-header (assoc article (gnus-data-list nil)))) + (mail-header-subject + (gnus-data-header (assoc article (gnus-data-list nil)))) + nil)) + +(defun spam-fetch-field-message-id-fast (article) + "Fetch the `Message-ID' field quickly, using the internal + gnus-data-list function" + (if (and (numberp article) + (assoc article (gnus-data-list nil))) + (mail-header-message-id + (gnus-data-header (assoc article (gnus-data-list nil)))) nil)) ;;;; Spam determination. (defvar spam-list-of-checks - '((spam-use-blacklist . spam-check-blacklist) - (spam-use-regex-headers . spam-check-regex-headers) - (spam-use-whitelist . spam-check-whitelist) - (spam-use-BBDB . spam-check-BBDB) - (spam-use-ifile . spam-check-ifile) - (spam-use-stat . spam-check-stat) - (spam-use-blackholes . spam-check-blackholes) - (spam-use-hashcash . spam-check-hashcash) - (spam-use-bogofilter-headers . spam-check-bogofilter-headers) - (spam-use-bogofilter . spam-check-bogofilter)) -"The spam-list-of-checks list contains pairs associating a parameter -variable with a spam checking function. If the parameter variable is -true, then the checking function is called, and its value decides what -happens. Each individual check may return nil, t, or a mailgroup -name. The value nil means that the check does not yield a decision, -and so, that further checks are needed. The value t means that the -message is definitely not spam, and that further spam checks should be -inhibited. Otherwise, a mailgroup name is returned where the mail -should go, and further checks are also inhibited. The usual mailgroup -name is the value of `spam-split-group', meaning that the message is + '((spam-use-blacklist . spam-check-blacklist) + (spam-use-regex-headers . spam-check-regex-headers) + (spam-use-regex-body . spam-check-regex-body) + (spam-use-whitelist . spam-check-whitelist) + (spam-use-BBDB . spam-check-BBDB) + (spam-use-ifile . spam-check-ifile) + (spam-use-spamoracle . spam-check-spamoracle) + (spam-use-stat . spam-check-stat) + (spam-use-blackholes . spam-check-blackholes) + (spam-use-hashcash . spam-check-hashcash) + (spam-use-bogofilter-headers . spam-check-bogofilter-headers) + (spam-use-bogofilter . spam-check-bogofilter)) + "The spam-list-of-checks list contains pairs associating a +parameter variable with a spam checking function. If the +parameter variable is true, then the checking function is called, +and its value decides what happens. Each individual check may +return nil, t, or a mailgroup name. The value nil means that the +check does not yield a decision, and so, that further checks are +needed. The value t means that the message is definitely not +spam, and that further spam checks should be inhibited. +Otherwise, a mailgroup name or the symbol 'spam (depending on +spam-split-symbolic-return) is returned where the mail should go, +and further checks are also inhibited. The usual mailgroup name +is the value of `spam-split-group', meaning that the message is definitely a spam.") (defvar spam-list-of-statistical-checks - '(spam-use-ifile spam-use-stat spam-use-bogofilter) -"The spam-list-of-statistical-checks list contains all the mail + '(spam-use-ifile + spam-use-regex-body + spam-use-stat + spam-use-bogofilter + spam-use-spamoracle) + "The spam-list-of-statistical-checks list contains all the mail splitters that need to have the full message body available.") +;;;TODO: modify to invoke self with each check if invoked without specifics (defun spam-split (&rest specific-checks) "Split this message into the `spam' group if it is spam. -This function can be used as an entry in `nnmail-split-fancy', for -example like this: (: spam-split). It can take checks as parameters. +This function can be used as an entry in the variable `nnmail-split-fancy', +for example like this: (: spam-split). It can take checks as +parameters. A string as a parameter will set the +spam-split-group to that string. See the Info node `(gnus)Fancy Mail Splitting' for more details." (interactive) - (save-excursion - (save-restriction - (dolist (check spam-list-of-statistical-checks) - (when (symbol-value check) - (widen) - (gnus-message 8 "spam-split: widening the buffer (%s requires it)" - (symbol-name check)) - (return))) - ;; (progn (widen) (debug (buffer-string))) - (let ((list-of-checks spam-list-of-checks) - decision) - (while (and list-of-checks (not decision)) - (let ((pair (pop list-of-checks))) - (when (and (symbol-value (car pair)) - (or (null specific-checks) - (memq (car pair) specific-checks))) - (gnus-message 5 "spam-split: calling the %s function" (symbol-name (cdr pair))) - (setq decision (funcall (cdr pair)))))) - (if (eq decision t) - nil - decision))))) - + (setq spam-split-last-successful-check nil) + (unless spam-split-disabled + (let ((spam-split-group-choice spam-split-group)) + (dolist (check specific-checks) + (when (stringp check) + (setq spam-split-group-choice check) + (setq specific-checks (delq check specific-checks)))) + + (let ((spam-split-group spam-split-group-choice)) + (save-excursion + (save-restriction + (dolist (check spam-list-of-statistical-checks) + (when (and (symbolp check) (symbol-value check)) + (widen) + (gnus-message 8 "spam-split: widening the buffer (%s requires it)" + (symbol-name check)) + (return))) + ;; (progn (widen) (debug (buffer-string))) + (let ((list-of-checks spam-list-of-checks) + decision) + (while (and list-of-checks (not decision)) + (let ((pair (pop list-of-checks))) + (when (and (symbol-value (car pair)) + (or (null specific-checks) + (memq (car pair) specific-checks))) + (gnus-message 5 "spam-split: calling the %s function" + (symbol-name (cdr pair))) + (setq decision (funcall (cdr pair))) + ;; if we got a decision at all, save the current check + (when decision + (setq spam-split-last-successful-check (car pair))) + + (when (eq decision 'spam) + (if spam-split-symbolic-return + (setq decision spam-split-group) + (gnus-error + 5 + (format "spam-split got %s but %s is nil" + (symbol-name decision) + (symbol-name spam-split-symbolic-return)))))))) + (if (eq decision t) + (if spam-split-symbolic-return-positive 'ham nil) + decision)))))))) + +(defun spam-find-spam () + "This function will detect spam in the current newsgroup using spam-split." + (interactive) + + (let* ((group gnus-newsgroup-name) + (autodetect (gnus-parameter-spam-autodetect group)) + (methods (gnus-parameter-spam-autodetect-methods group)) + (first-method (nth 0 methods))) + (when (and autodetect + (not (equal first-method 'none))) + (mapcar + (lambda (article) + (let ((id (spam-fetch-field-message-id-fast article)) + (subject (spam-fetch-field-subject-fast article)) + (sender (spam-fetch-field-from-fast article))) + (unless (and spam-log-to-registry + (spam-log-registered-p id 'incoming)) + (let* ((spam-split-symbolic-return t) + (spam-split-symbolic-return-positive t) + (split-return + (with-temp-buffer + (gnus-request-article-this-buffer + article + group) + (if (or (null first-method) + (equal first-method 'default)) + (spam-split) + (apply 'spam-split methods))))) + (if (equal split-return 'spam) + (gnus-summary-mark-article article gnus-spam-mark)) + + (when (and split-return spam-log-to-registry) + (when (zerop (gnus-registry-group-count id)) + (gnus-registry-add-group + id group subject sender)) + + (spam-log-processing-to-registry + id + 'incoming + split-return + spam-split-last-successful-check + group)))))) + (if spam-autodetect-recheck-messages + gnus-newsgroup-articles + gnus-newsgroup-unseen))))) + +(defvar spam-registration-functions + ;; first the ham register, second the spam register function + ;; third the ham unregister, fourth the spam unregister function + '((spam-use-blacklist nil + spam-blacklist-register-routine + nil + spam-blacklist-unregister-routine) + (spam-use-whitelist spam-whitelist-register-routine + nil + spam-whitelist-unregister-routine + nil) + (spam-use-BBDB spam-BBDB-register-routine + nil + spam-BBDB-unregister-routine + nil) + (spam-use-ifile spam-ifile-register-ham-routine + spam-ifile-register-spam-routine + spam-ifile-unregister-ham-routine + spam-ifile-unregister-spam-routine) + (spam-use-spamoracle spam-spamoracle-learn-ham + spam-spamoracle-learn-spam + spam-spamoracle-unlearn-ham + spam-spamoracle-unlearn-spam) + (spam-use-stat spam-stat-register-ham-routine + spam-stat-register-spam-routine + spam-stat-unregister-ham-routine + spam-stat-unregister-spam-routine) + ;; note that spam-use-gmane is not a legitimate check + (spam-use-gmane nil + spam-report-gmane-register-routine + ;; does Gmane support unregistration? + nil + nil) + (spam-use-bogofilter spam-bogofilter-register-ham-routine + spam-bogofilter-register-spam-routine + spam-bogofilter-unregister-ham-routine + spam-bogofilter-unregister-spam-routine)) + "The spam-registration-functions list contains pairs +associating a parameter variable with the ham and spam +registration functions, and the ham and spam unregistration +functions") + +(defun spam-classification-valid-p (classification) + (or (eq classification 'spam) + (eq classification 'ham))) + +(defun spam-process-type-valid-p (process-type) + (or (eq process-type 'incoming) + (eq process-type 'process))) + +(defun spam-registration-check-valid-p (check) + (assoc check spam-registration-functions)) + +(defun spam-unregistration-check-valid-p (check) + (assoc check spam-registration-functions)) + +(defun spam-registration-function (classification check) + (let ((flist (cdr-safe (assoc check spam-registration-functions)))) + (if (eq classification 'spam) + (nth 1 flist) + (nth 0 flist)))) + +(defun spam-unregistration-function (classification check) + (let ((flist (cdr-safe (assoc check spam-registration-functions)))) + (if (eq classification 'spam) + (nth 3 flist) + (nth 2 flist)))) + +(defun spam-list-articles (articles classification) + (let ((mark-check (if (eq classification 'spam) + 'spam-group-spam-mark-p + 'spam-group-ham-mark-p)) + list mark-cache-yes mark-cache-no) + (dolist (article articles) + (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 + check + &optional unregister + specific-articles) + (when (and (spam-classification-valid-p classification) + (spam-registration-check-valid-p check)) + (let* ((register-function + (spam-registration-function classification check)) + (unregister-function + (spam-unregistration-function classification check)) + (run-function (if unregister + unregister-function + register-function)) + (log-function (if unregister + 'spam-log-undo-registration + 'spam-log-processing-to-registry)) + article articles) + + (when run-function + ;; make list of articles, using specific-articles if given + (setq articles (or specific-articles + (spam-list-articles + gnus-newsgroup-articles + classification))) + ;; process them + (gnus-message 5 "%s %d %s articles with classification %s, check %s" + (if unregister "Unregistering" "Registering") + (length articles) + (if specific-articles "specific" "") + (symbol-name classification) + (symbol-name check)) + (funcall run-function articles) + ;; now log all the registrations (or undo them, depending on unregister) + (dolist (article articles) + (funcall log-function + (spam-fetch-field-message-id-fast article) + 'process + classification + check + gnus-newsgroup-name)))))) + +;;; log a ham- or spam-processor invocation to the registry +(defun spam-log-processing-to-registry (id type classification check group) + (when spam-log-to-registry + (if (and (stringp id) + (stringp group) + (spam-process-type-valid-p type) + (spam-classification-valid-p classification) + (spam-registration-check-valid-p check)) + (let ((cell-list (cdr-safe (gnus-registry-fetch-extra id type))) + (cell (list classification check group))) + (push cell cell-list) + (gnus-registry-store-extra-entry + id + type + cell-list)) + + (gnus-message 5 (format "%s called with bad ID, type, classification, check, or group" + "spam-log-processing-to-registry"))))) + +;;; check if a ham- or spam-processor registration has been done +(defun spam-log-registered-p (id type) + (when spam-log-to-registry + (if (and (stringp id) + (spam-process-type-valid-p type)) + (cdr-safe (gnus-registry-fetch-extra id type)) + (progn + (gnus-message 5 (format "%s called with bad ID, type, classification, or check" + "spam-log-registered-p")) + nil)))) + +;;; check if a ham- or spam-processor registration needs to be undone +(defun spam-log-unregistration-needed-p (id type classification check) + (when spam-log-to-registry + (if (and (stringp id) + (spam-process-type-valid-p type) + (spam-classification-valid-p classification) + (spam-registration-check-valid-p check)) + (let ((cell-list (cdr-safe (gnus-registry-fetch-extra id type))) + found) + (dolist (cell cell-list) + (unless found + (when (and (eq classification (nth 0 cell)) + (eq check (nth 1 cell))) + (setq found t)))) + found) + (progn + (gnus-message 5 (format "%s called with bad ID, type, classification, or check" + "spam-log-unregistration-needed-p")) + nil)))) + + +;;; undo a ham- or spam-processor registration (the group is not used) +(defun spam-log-undo-registration (id type classification check &optional group) + (when (and spam-log-to-registry + (spam-log-unregistration-needed-p id type classification check)) + (if (and (stringp id) + (spam-process-type-valid-p type) + (spam-classification-valid-p classification) + (spam-registration-check-valid-p check)) + (let ((cell-list (cdr-safe (gnus-registry-fetch-extra id type))) + new-cell-list found) + (dolist (cell cell-list) + (unless (and (eq classification (nth 0 cell)) + (eq check (nth 1 cell))) + (push cell new-cell-list))) + (gnus-registry-store-extra-entry + id + type + new-cell-list)) + (progn + (gnus-message 5 (format "%s called with bad ID, type, check, or group" + "spam-log-undo-registration")) + nil)))) + +;;; set up IMAP widening if it's necessary (defun spam-setup-widening () (dolist (check spam-list-of-statistical-checks) (when (symbol-value check) (setq nnimap-split-download-body-default t)))) -(add-hook 'gnus-get-new-news-hook 'spam-setup-widening) + +;;;; Regex body + +(defun spam-check-regex-body () + (let ((spam-regex-headers-ham spam-regex-body-ham) + (spam-regex-headers-spam spam-regex-body-spam)) + (spam-check-regex-headers t))) ;;;; Regex headers -(defun spam-check-regex-headers () - (let (ret found) +(defun spam-check-regex-headers (&optional body) + (let ((type (if body "body" "header")) + (spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group)) + ret found) (dolist (h-regex spam-regex-headers-ham) (unless found (goto-char (point-min)) (when (re-search-forward h-regex nil t) - (message "Ham regex header search positive.") + (message "Ham regex %s search positive." type) (setq found t)))) (dolist (s-regex spam-regex-headers-spam) (unless found (goto-char (point-min)) (when (re-search-forward s-regex nil t) - (message "Spam regex header search positive." (match-string 1)) + (message "Spam regex %s search positive." type) (setq found t) (setq ret spam-split-group)))) ret)) @@ -667,9 +1204,18 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;;;; Blackholes. +(defun spam-reverse-ip-string (ip) + (when (stringp ip) + (mapconcat 'identity + (nreverse (split-string ip "\\.")) + "."))) + (defun spam-check-blackholes () "Check the Received headers for blackholed relays." - (let ((headers (message-fetch-field "received")) + (let ((headers (nnmail-fetch-field "received")) + (spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group)) ips matches) (when headers (with-temp-buffer @@ -677,29 +1223,31 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (goto-char (point-min)) (gnus-message 5 "Checking headers for relay addresses") (while (re-search-forward - "\\[\\([0-9]+.[0-9]+.[0-9]+.[0-9]+\\)\\]" nil t) + "\\([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\)" nil t) (gnus-message 9 "Blackhole search found host IP %s." (match-string 1)) - (push (mapconcat 'identity - (nreverse (split-string (match-string 1) "\\.")) - ".") + (push (spam-reverse-ip-string (match-string 1)) ips))) (dolist (server spam-blackhole-servers) (dolist (ip ips) (unless (and spam-blackhole-good-server-regex - (string-match spam-blackhole-good-server-regex ip)) - (let ((query-string (concat ip "." server))) - (if spam-use-dig - (let ((query-result (query-dig query-string))) - (when query-result - (gnus-message 5 "(DIG): positive blackhole check '%s'" - query-result) - (push (list ip server query-result) - matches))) - ;; else, if not using dig.el - (when (query-dns query-string) - (gnus-message 5 "positive blackhole check") - (push (list ip server (query-dns query-string 'TXT)) - matches)))))))) + ;; match the good-server-regex against the reversed (again) IP string + (string-match + spam-blackhole-good-server-regex + (spam-reverse-ip-string ip))) + (unless matches + (let ((query-string (concat ip "." server))) + (if spam-use-dig + (let ((query-result (query-dig query-string))) + (when query-result + (gnus-message 5 "(DIG): positive blackhole check '%s'" + query-result) + (push (list ip server query-result) + matches))) + ;; else, if not using dig.el + (when (query-dns query-string) + (gnus-message 5 "positive blackhole check") + (push (list ip server (query-dns query-string 'TXT)) + matches))))))))) (when matches spam-split-group))) @@ -708,16 +1256,16 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (condition-case nil (progn (require 'hashcash) - + (defun spam-check-hashcash () "Check the headers for hashcash payments." - (mail-check-payment))) ;mail-check-payment returns a boolean + (mail-check-payment))) ;mail-check-payment returns a boolean (file-error (progn (defalias 'mail-check-payment 'ignore) (defalias 'spam-check-hashcash 'ignore)))) -;;;; BBDB +;;;; BBDB ;;; original idea for spam-check-BBDB from Alexander Kotelnikov ;;; @@ -728,37 +1276,53 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (progn (require 'bbdb) (require 'bbdb-com) - - (defun spam-enter-ham-BBDB (from) - "Enter an address into the BBDB; implies ham (non-spam) sender" - (when (stringp from) - (let* ((parsed-address (gnus-extract-address-components from)) - (name (or (car parsed-address) "Ham Sender")) - (net-address (car (cdr parsed-address)))) - (gnus-message 5 "Adding address %s to BBDB" from) - (when (and net-address - (not (bbdb-search-simple nil net-address))) - (bbdb-create-internal name nil net-address nil nil - "ham sender added by spam.el"))))) - - (defun spam-BBDB-register-routine () - (spam-generic-register-routine - ;; spam function - nil - ;; ham function - (lambda (article) - (spam-enter-ham-BBDB (spam-fetch-field-from-fast article))))) - - (defun spam-check-BBDB () - "Mail from people in the BBDB is classified as ham or non-spam" - (let ((who (message-fetch-field "from"))) - (when who - (setq who (cadr (gnus-extract-address-components who))) - (if (bbdb-search-simple nil who) - t - (if spam-use-BBDB-exclusive - spam-split-group - nil)))))) + + (defun spam-enter-ham-BBDB (addresses &optional remove) + "Enter an address into the BBDB; implies ham (non-spam) sender" + (dolist (from addresses) + (when (stringp from) + (let* ((parsed-address (gnus-extract-address-components from)) + (name (or (nth 0 parsed-address) "Ham Sender")) + (remove-function (if remove + 'bbdb-delete-record-internal + 'ignore)) + (net-address (nth 1 parsed-address)) + (record (and net-address + (bbdb-search-simple nil net-address)))) + (when net-address + (gnus-message 5 "%s address %s %s BBDB" + (if remove "Deleting" "Adding") + from + (if remove "from" "to")) + (if record + (funcall remove-function record) + (bbdb-create-internal name nil net-address nil nil + "ham sender added by spam.el"))))))) + + (defun spam-BBDB-register-routine (articles &optional unregister) + (let (addresses) + (dolist (article articles) + (when (stringp (spam-fetch-field-from-fast article)) + (push (spam-fetch-field-from-fast article) addresses))) + ;; now do the register/unregister action + (spam-enter-ham-BBDB addresses unregister))) + + (defun spam-BBDB-unregister-routine (articles) + (spam-BBDB-register-routine articles t)) + + (defun spam-check-BBDB () + "Mail from people in the BBDB is classified as ham or non-spam" + (let ((who (nnmail-fetch-field "from")) + (spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group))) + (when who + (setq who (nth 1 (gnus-extract-address-components who))) + (if (bbdb-search-simple nil who) + t + (if spam-use-BBDB-exclusive + spam-split-group + nil)))))) (file-error (progn (defalias 'bbdb-search-simple 'ignore) @@ -766,6 +1330,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (defalias 'spam-BBDB-register-routine 'ignore) (defalias 'spam-enter-ham-BBDB 'ignore) (defalias 'bbdb-create-internal 'ignore) + (defalias 'bbdb-delete-record-internal 'ignore) (defalias 'bbdb-records 'ignore)))) @@ -775,25 +1340,29 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;;; as spam (defun spam-get-ifile-database-parameter () - "Get the command-line parameter for ifile's database from spam-ifile-database-path." + "Get the command-line parameter for ifile's database from + spam-ifile-database-path." (if spam-ifile-database-path (format "--db-file=%s" spam-ifile-database-path) nil)) - + (defun spam-check-ifile () - "Check the ifile backend for the classification of this message" - (let ((article-buffer-name (buffer-name)) + "Check the ifile backend for the classification of this message." + (let ((article-buffer-name (buffer-name)) + (spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group)) category return) (with-temp-buffer (let ((temp-buffer-name (buffer-name)) (db-param (spam-get-ifile-database-parameter))) (save-excursion (set-buffer article-buffer-name) - (if db-param - (call-process-region (point-min) (point-max) spam-ifile-path - nil temp-buffer-name nil "-q" "-c" db-param) - (call-process-region (point-min) (point-max) spam-ifile-path - nil temp-buffer-name nil "-q" "-c"))) + (apply 'call-process-region + (point-min) (point-max) spam-ifile-path + nil temp-buffer-name nil "-c" + (if db-param `(,db-param "-q") `("-q")))) + ;; check the return now (we're back in the temp buffer) (goto-char (point-min)) (if (not (eobp)) (setq category (buffer-substring (point) (spam-point-at-eol)))) @@ -802,38 +1371,38 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (setq return category) ;; else, if spam-ifile-all-categories is not set... (when (string-equal spam-ifile-spam-category category) - (setq return spam-split-group)))))) + (setq return spam-split-group)))))) ; note return is nil otherwise return)) -(defun spam-ifile-register-with-ifile (article-string category) +(defun spam-ifile-register-with-ifile (articles category &optional unregister) "Register an article, given as a string, with a category. Uses `gnus-newsgroup-name' if category is nil (for ham registration)." - (when (stringp article-string) - (let ((category (or category gnus-newsgroup-name)) - (db-param (spam-get-ifile-database-parameter))) - (with-temp-buffer - (insert article-string) - (if db-param - (call-process-region (point-min) (point-max) spam-ifile-path - nil nil nil - "-h" "-i" category db-param) - (call-process-region (point-min) (point-max) spam-ifile-path - nil nil nil - "-h" "-i" category)))))) - -(defun spam-ifile-register-spam-routine () - (spam-generic-register-routine - (lambda (article) - (spam-ifile-register-with-ifile - (spam-get-article-as-string article) spam-ifile-spam-category)) - nil)) - -(defun spam-ifile-register-ham-routine () - (spam-generic-register-routine - nil - (lambda (article) - (spam-ifile-register-with-ifile - (spam-get-article-as-string article) spam-ifile-ham-category)))) + (let ((category (or category gnus-newsgroup-name)) + (add-or-delete-option (if unregister "-d" "-i")) + (db (spam-get-ifile-database-parameter)) + parameters) + (with-temp-buffer + (dolist (article articles) + (let ((article-string (spam-get-article-as-string article))) + (when (stringp article-string) + (insert article-string)))) + (apply 'call-process-region + (point-min) (point-max) spam-ifile-path + nil nil nil + add-or-delete-option category + (if db `(,db "-h") `("-h")))))) + +(defun spam-ifile-register-spam-routine (articles &optional unregister) + (spam-ifile-register-with-ifile articles spam-ifile-spam-category unregister)) + +(defun spam-ifile-unregister-spam-routine (articles) + (spam-ifile-register-spam-routine articles t)) + +(defun spam-ifile-register-ham-routine (articles &optional unregister) + (spam-ifile-register-with-ifile articles spam-ifile-ham-category unregister)) + +(defun spam-ifile-unregister-ham-routine (articles) + (spam-ifile-register-ham-routine articles t)) ;;;; spam-stat @@ -842,51 +1411,61 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (progn (let ((spam-stat-install-hooks nil)) (require 'spam-stat)) - + (defun spam-check-stat () "Check the spam-stat backend for the classification of this message" - (let ((spam-stat-split-fancy-spam-group spam-split-group) ; override + (let ((spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group)) + (spam-stat-split-fancy-spam-group spam-split-group) ; override (spam-stat-buffer (buffer-name)) ; stat the current buffer category return) (spam-stat-split-fancy))) - (defun spam-stat-register-spam-routine () - (spam-generic-register-routine - (lambda (article) - (let ((article-string (spam-get-article-as-string article))) - (with-temp-buffer - (insert article-string) - (spam-stat-buffer-is-spam)))) - nil)) - - (defun spam-stat-register-ham-routine () - (spam-generic-register-routine - nil - (lambda (article) - (let ((article-string (spam-get-article-as-string article))) - (with-temp-buffer - (insert article-string) - (spam-stat-buffer-is-non-spam)))))) + (defun spam-stat-register-spam-routine (articles &optional unregister) + (dolist (article articles) + (let ((article-string (spam-get-article-as-string article))) + (with-temp-buffer + (insert article-string) + (if unregister + (spam-stat-buffer-change-to-non-spam) + (spam-stat-buffer-is-spam)))))) + + (defun spam-stat-unregister-spam-routine (articles) + (spam-stat-register-spam-routine articles t)) + + (defun spam-stat-register-ham-routine (articles &optional unregister) + (dolist (article articles) + (let ((article-string (spam-get-article-as-string article))) + (with-temp-buffer + (insert article-string) + (if unregister + (spam-stat-buffer-change-to-spam) + (spam-stat-buffer-is-non-spam)))))) + + (defun spam-stat-unregister-ham-routine (articles) + (spam-stat-register-ham-routine articles t)) (defun spam-maybe-spam-stat-load () (when spam-use-stat (spam-stat-load))) - - (defun spam-maybe-spam-stat-save () - (when spam-use-stat (spam-stat-save))) - ;; Add hooks for loading and saving the spam stats - (add-hook 'gnus-save-newsrc-hook 'spam-maybe-spam-stat-save) - (add-hook 'gnus-get-top-new-news-hook 'spam-maybe-spam-stat-load) - (add-hook 'gnus-startup-hook 'spam-maybe-spam-stat-load)) + (defun spam-maybe-spam-stat-save () + (when spam-use-stat (spam-stat-save)))) (file-error (progn + (defalias 'spam-stat-load 'ignore) + (defalias 'spam-stat-save 'ignore) + (defalias 'spam-maybe-spam-stat-load 'ignore) + (defalias 'spam-maybe-spam-stat-save 'ignore) (defalias 'spam-stat-register-ham-routine 'ignore) + (defalias 'spam-stat-unregister-ham-routine 'ignore) (defalias 'spam-stat-register-spam-routine 'ignore) + (defalias 'spam-stat-unregister-spam-routine 'ignore) (defalias 'spam-stat-buffer-is-spam 'ignore) + (defalias 'spam-stat-buffer-change-to-spam 'ignore) (defalias 'spam-stat-buffer-is-non-spam 'ignore) + (defalias 'spam-stat-buffer-change-to-non-spam 'ignore) (defalias 'spam-stat-split-fancy 'ignore) - (defalias 'spam-stat-load 'ignore) - (defalias 'spam-stat-save 'ignore) (defalias 'spam-check-stat 'ignore)))) @@ -896,47 +1475,77 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (defvar spam-whitelist-cache nil) (defvar spam-blacklist-cache nil) -(defun spam-enter-whitelist (address) - "Enter ADDRESS into the whitelist." +(defun spam-kill-whole-line () + (beginning-of-line) + (let ((kill-whole-line t)) + (kill-line))) + +;;; address can be a list, too +(defun spam-enter-whitelist (address &optional remove) + "Enter ADDRESS (list or single) into the whitelist. +With a non-nil REMOVE, remove them." (interactive "sAddress: ") - (spam-enter-list address spam-whitelist) + (spam-enter-list address spam-whitelist remove) (setq spam-whitelist-cache nil)) -(defun spam-enter-blacklist (address) - "Enter ADDRESS into the blacklist." +;;; address can be a list, too +(defun spam-enter-blacklist (address &optional remove) + "Enter ADDRESS (list or single) into the blacklist. +With a non-nil REMOVE, remove them." (interactive "sAddress: ") - (spam-enter-list address spam-blacklist) + (spam-enter-list address spam-blacklist remove) (setq spam-blacklist-cache nil)) -(defun spam-enter-list (address file) - "Enter ADDRESS into the given FILE, either the whitelist or the blacklist." - (unless (file-exists-p (file-name-directory file)) - (make-directory (file-name-directory file) t)) - (save-excursion - (set-buffer - (find-file-noselect file)) - (goto-char (point-max)) - (unless (bobp) - (insert "\n")) - (insert address "\n") - (save-buffer))) - -;;; returns t if the sender is in the whitelist, nil or spam-split-group otherwise +(defun spam-enter-list (addresses file &optional remove) + "Enter ADDRESSES into the given FILE. +Either the whitelist or the blacklist files can be used. With +REMOVE not nil, remove the ADDRESSES." + (if (stringp addresses) + (spam-enter-list (list addresses) file remove) + ;; else, we have a list of addresses here + (unless (file-exists-p (file-name-directory file)) + (make-directory (file-name-directory file) t)) + (save-excursion + (set-buffer + (find-file-noselect file)) + (dolist (a addresses) + (when (stringp a) + (goto-char (point-min)) + (if (re-search-forward (regexp-quote a) nil t) + ;; found the address + (when remove + (spam-kill-whole-line)) + ;; else, the address was not found + (unless remove + (goto-char (point-max)) + (unless (bobp) + (insert "\n")) + (insert a "\n"))))) + (save-buffer)))) + +;;; returns t if the sender is in the whitelist, nil or +;;; spam-split-group otherwise (defun spam-check-whitelist () ;; FIXME! Should it detect when file timestamps change? - (unless spam-whitelist-cache - (setq spam-whitelist-cache (spam-parse-list spam-whitelist))) - (if (spam-from-listed-p spam-whitelist-cache) - t - (if spam-use-whitelist-exclusive - spam-split-group - nil))) + (let ((spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group))) + (unless spam-whitelist-cache + (setq spam-whitelist-cache (spam-parse-list spam-whitelist))) + (if (spam-from-listed-p spam-whitelist-cache) + t + (if spam-use-whitelist-exclusive + spam-split-group + nil)))) (defun spam-check-blacklist () ;; FIXME! Should it detect when file timestamps change? - (unless spam-blacklist-cache - (setq spam-blacklist-cache (spam-parse-list spam-blacklist))) - (and (spam-from-listed-p spam-blacklist-cache) spam-split-group)) + (let ((spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group))) + (unless spam-blacklist-cache + (setq spam-blacklist-cache (spam-parse-list spam-blacklist))) + (and (spam-from-listed-p spam-blacklist-cache) spam-split-group))) (defun spam-parse-list (file) (when (file-readable-p file) @@ -946,60 +1555,100 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (while (not (eobp)) (setq address (buffer-substring (point) (spam-point-at-eol))) (forward-line 1) + ;; insert the e-mail address if detected, otherwise the raw data (unless (zerop (length address)) - (setq address (regexp-quote address)) - (while (string-match "\\\\\\*" address) - (setq address (replace-match ".*" t t address))) - (push address contents)))) + (let ((pure-address (nth 1 (gnus-extract-address-components address)))) + (push (or pure-address address) contents))))) (nreverse contents)))) (defun spam-from-listed-p (cache) - (let ((from (message-fetch-field "from")) + (let ((from (nnmail-fetch-field "from")) found) (while cache - (when (string-match (pop cache) from) - (setq found t - cache nil))) + (let ((address (pop cache))) + (unless (zerop (length address)) ; 0 for a nil address too + (setq address (regexp-quote address)) + ;; fix regexp-quote's treatment of user-intended regexes + (while (string-match "\\\\\\*" address) + (setq address (replace-match ".*" t t address)))) + (when (and address (string-match address from)) + (setq found t + cache nil)))) found)) -(defun spam-blacklist-register-routine () - (spam-generic-register-routine - ;; the spam function - (lambda (article) - (let ((from (spam-fetch-field-from-fast article))) - (when (stringp from) - (spam-enter-blacklist from)))) - ;; the ham function - nil)) - -(defun spam-whitelist-register-routine () - (spam-generic-register-routine - ;; the spam function - nil - ;; the ham function - (lambda (article) - (let ((from (spam-fetch-field-from-fast article))) - (when (stringp from) - (spam-enter-whitelist from)))))) +(defun spam-filelist-register-routine (articles blacklist &optional unregister) + (let ((de-symbol (if blacklist 'spam-use-whitelist 'spam-use-blacklist)) + (declassification (if blacklist 'ham 'spam)) + (enter-function + (if blacklist 'spam-enter-blacklist 'spam-enter-whitelist)) + (remove-function + (if blacklist 'spam-enter-whitelist 'spam-enter-blacklist)) + from addresses unregister-list) + (dolist (article articles) + (let ((from (spam-fetch-field-from-fast article)) + (id (spam-fetch-field-message-id-fast article)) + sender-ignored) + (when (stringp from) + (dolist (ignore-regex spam-blacklist-ignored-regexes) + (when (and (not sender-ignored) + (stringp ignore-regex) + (string-match ignore-regex from)) + (setq sender-ignored t))) + ;; remember the messages we need to unregister, unless remove is set + (when (and + (null unregister) + (spam-log-unregistration-needed-p + id 'process declassification de-symbol)) + (push from unregister-list)) + (unless sender-ignored + (push from addresses))))) + + (if unregister + (funcall enter-function addresses t) ; unregister all these addresses + ;; else, register normally and unregister what we need to + (funcall remove-function unregister-list t) + (dolist (article unregister-list) + (spam-log-undo-registration + (spam-fetch-field-message-id-fast article) + 'process + declassification + de-symbol)) + (funcall enter-function addresses nil)))) + +(defun spam-blacklist-unregister-routine (articles) + (spam-blacklist-register-routine articles t)) + +(defun spam-blacklist-register-routine (articles &optional unregister) + (spam-filelist-register-routine articles t unregister)) + +(defun spam-whitelist-unregister-routine (articles) + (spam-whitelist-register-routine articles t)) + +(defun spam-whitelist-register-routine (articles &optional unregister) + (spam-filelist-register-routine articles nil unregister)) ;;;; Spam-report glue -(defun spam-report-gmane-register-routine () - (spam-generic-register-routine - 'spam-report-gmane - nil)) +(defun spam-report-gmane-register-routine (articles) + (when articles + (apply 'spam-report-gmane articles))) ;;;; Bogofilter (defun spam-check-bogofilter-headers (&optional score) - (let ((header (message-fetch-field spam-bogofilter-header))) - (when (and header - (string-match spam-bogofilter-bogosity-positive-spam-header - header)) - (if score - (when (string-match "spamicity=\\([0-9.]+\\)" header) - (match-string 1 header)) - spam-split-group)))) + (let ((header (nnmail-fetch-field spam-bogofilter-header)) + (spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group))) + (when header ; return nil when no header + (if score ; scoring mode + (if (string-match "spamicity=\\([0-9.]+\\)" header) + (match-string 1 header) + "0") + ;; spam detection mode + (when (string-match spam-bogofilter-bogosity-positive-spam-header + header) + spam-split-group))))) ;; return something sensible if the score can't be determined (defun spam-bogofilter-score () @@ -1011,55 +1660,164 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (let ((score (or (spam-check-bogofilter-headers t) (spam-check-bogofilter t)))) (message "Spamicity score %s" score) - (or score "0")))) + (or score "0")) + (gnus-summary-show-article))) (defun spam-check-bogofilter (&optional score) "Check the Bogofilter backend for the classification of this message" - (let ((article-buffer-name (buffer-name)) + (let ((article-buffer-name (buffer-name)) + (db spam-bogofilter-database-directory) return) (with-temp-buffer (let ((temp-buffer-name (buffer-name))) (save-excursion (set-buffer article-buffer-name) - (if spam-bogofilter-database-directory - (call-process-region (point-min) (point-max) - spam-bogofilter-path - nil temp-buffer-name nil "-v" - "-d" spam-bogofilter-database-directory) - (call-process-region (point-min) (point-max) spam-bogofilter-path - nil temp-buffer-name nil "-v"))) + (apply 'call-process-region + (point-min) (point-max) + spam-bogofilter-path + nil temp-buffer-name nil + (if db `("-d" ,db "-v") `("-v")))) (setq return (spam-check-bogofilter-headers score)))) return)) -(defun spam-bogofilter-register-with-bogofilter (article-string spam) +(defun spam-bogofilter-register-with-bogofilter (articles + spam + &optional unregister) "Register an article, given as a string, as spam or non-spam." - (when (stringp article-string) - (let ((switch (if spam spam-bogofilter-spam-switch - spam-bogofilter-ham-switch))) - (with-temp-buffer - (insert article-string) - (if spam-bogofilter-database-directory - (call-process-region (point-min) (point-max) - spam-bogofilter-path - nil nil nil "-v" switch - "-d" spam-bogofilter-database-directory) - (call-process-region (point-min) (point-max) spam-bogofilter-path - nil nil nil "-v" switch)))))) - -(defun spam-bogofilter-register-spam-routine () - (spam-generic-register-routine - (lambda (article) - (spam-bogofilter-register-with-bogofilter - (spam-get-article-as-string article) t)) - nil)) - -(defun spam-bogofilter-register-ham-routine () - (spam-generic-register-routine - nil - (lambda (article) - (spam-bogofilter-register-with-bogofilter - (spam-get-article-as-string article) nil)))) + (dolist (article articles) + (let ((article-string (spam-get-article-as-string article)) + (db spam-bogofilter-database-directory) + (switch (if unregister + (if spam + spam-bogofilter-spam-strong-switch + spam-bogofilter-ham-strong-switch) + (if spam + spam-bogofilter-spam-switch + spam-bogofilter-ham-switch)))) + (when (stringp article-string) + (with-temp-buffer + (insert article-string) + + (apply 'call-process-region + (point-min) (point-max) + spam-bogofilter-path + nil nil nil switch + (if db `("-d" ,db "-v") `("-v")))))))) + +(defun spam-bogofilter-register-spam-routine (articles &optional unregister) + (spam-bogofilter-register-with-bogofilter articles t unregister)) + +(defun spam-bogofilter-unregister-spam-routine (articles) + (spam-bogofilter-register-spam-routine articles t)) + +(defun spam-bogofilter-register-ham-routine (articles &optional unregister) + (spam-bogofilter-register-with-bogofilter articles nil unregister)) + +(defun spam-bogofilter-unregister-ham-routine (articles) + (spam-bogofilter-register-ham-routine articles t)) + + + +;;;; spamoracle +(defun spam-check-spamoracle () + "Run spamoracle on an article to determine whether it's spam." + (let ((article-buffer-name (buffer-name)) + (spam-split-group (if spam-split-symbolic-return + 'spam + spam-split-group))) + (with-temp-buffer + (let ((temp-buffer-name (buffer-name))) + (save-excursion + (set-buffer article-buffer-name) + (let ((status + (apply 'call-process-region + (point-min) (point-max) + spam-spamoracle-binary + nil temp-buffer-name nil + (if spam-spamoracle-database + `("-f" ,spam-spamoracle-database "mark") + '("mark"))))) + (if (eq 0 status) + (progn + (set-buffer temp-buffer-name) + (goto-char (point-min)) + (when (re-search-forward "^X-Spam: yes;" nil t) + spam-split-group)) + (error "Error running spamoracle" status)))))))) + +(defun spam-spamoracle-learn (articles article-is-spam-p &optional unregister) + "Run spamoracle in training mode." + (with-temp-buffer + (let ((temp-buffer-name (buffer-name))) + (save-excursion + (goto-char (point-min)) + (dolist (article articles) + (insert (spam-get-article-as-string article))) + (let* ((arg (if (spam-xor unregister article-is-spam-p) + "-spam" + "-good")) + (status + (apply 'call-process-region + (point-min) (point-max) + spam-spamoracle-binary + nil temp-buffer-name nil + (if spam-spamoracle-database + `("-f" ,spam-spamoracle-database + "add" ,arg) + `("add" ,arg))))) + (when (not (eq 0 status)) + (error "Error running spamoracle" status))))))) + +(defun spam-spamoracle-learn-ham (articles &optional unregister) + (spam-spamoracle-learn articles nil unregister)) + +(defun spam-spamoracle-unlearn-ham (articles &optional unregister) + (spam-spamoracle-learn-ham articles t)) + +(defun spam-spamoracle-learn-spam (articles &optional unregister) + (spam-spamoracle-learn articles t unregister)) + +(defun spam-spamoracle-unlearn-spam (articles &optional unregister) + (spam-spamoracle-learn-spam articles t)) + + +;;;; Hooks + +;;;###autoload +(defun spam-initialize () + "Install the spam.el hooks and do other initialization" + (interactive) + (setq spam-install-hooks t) + ;; TODO: How do we redo this every time spam-face is customized? + (push '((eq mark gnus-spam-mark) . spam-face) + gnus-summary-highlight) + ;; Add hooks for loading and saving the spam stats + (add-hook 'gnus-save-newsrc-hook 'spam-maybe-spam-stat-save) + (add-hook 'gnus-get-top-new-news-hook 'spam-maybe-spam-stat-load) + (add-hook 'gnus-startup-hook 'spam-maybe-spam-stat-load) + (add-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit) + (add-hook 'gnus-summary-prepare-hook 'spam-summary-prepare) + (add-hook 'gnus-get-new-news-hook 'spam-setup-widening) + (add-hook 'gnus-summary-prepare-hook 'spam-find-spam)) + +(defun spam-unload-hook () + "Uninstall the spam.el hooks" + (interactive) + (remove-hook 'gnus-save-newsrc-hook 'spam-maybe-spam-stat-save) + (remove-hook 'gnus-get-top-new-news-hook 'spam-maybe-spam-stat-load) + (remove-hook 'gnus-startup-hook 'spam-maybe-spam-stat-load) + (remove-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit) + (remove-hook 'gnus-summary-prepare-hook 'spam-summary-prepare) + (remove-hook 'gnus-get-new-news-hook 'spam-setup-widening) + (remove-hook 'gnus-summary-prepare-hook 'spam-find-spam)) + +(when spam-install-hooks + (spam-initialize)) (provide 'spam) ;;; spam.el ends here. + +(provide 'spam) + +;;; spam.el ends here diff --git a/lisp/tls.el b/lisp/tls.el index a2cced9..9c5466f 100644 --- a/lisp/tls.el +++ b/lisp/tls.el @@ -68,7 +68,7 @@ after successful negotiation." :group 'tls) (defcustom tls-process-connection-type nil - "*Value for `process-connection-type' to use when starting process." + "*Value for `process-connection-type' to use when starting TLS process." :type 'boolean :group 'tls) diff --git a/lisp/utf7.el b/lisp/utf7.el index eea6afe..45e472a 100644 --- a/lisp/utf7.el +++ b/lisp/utf7.el @@ -1,7 +1,8 @@ -;;; utf7.el --- UTF-7 encoding/decoding for Emacs -;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. +;;; utf7.el --- UTF-7 encoding/decoding for Emacs -*-coding: iso-8859-1;-*- +;; Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. ;; Author: Jon K Hellan +;; Maintainer: bugs@gnus.org ;; Keywords: mail ;; This file is part of GNU Emacs. @@ -22,37 +23,69 @@ ;; Boston, MA 02111-1307, USA. ;;; Commentary: -;;; UTF-7 - A Mail-Safe Transformation Format of Unicode - RFC 2152 -;;; This is a transformation format of Unicode that contains only 7-bit -;;; ASCII octets and is intended to be readable by humans in the limiting -;;; case that the document consists of characters from the US-ASCII -;;; repertoire. -;;; In short, runs of characters outside US-ASCII are encoded as base64 -;;; inside delimiters. -;;; A variation of UTF-7 is specified in IMAP 4rev1 (RFC 2060) as the way -;;; to represent characters outside US-ASCII in mailbox names in IMAP. -;;; This library supports both variants, but the IMAP variation was the -;;; reason I wrote it. -;;; The routines convert UTF-7 -> UTF-16 (16 bit encoding of Unicode) -;;; -> current character set, and vice versa. -;;; However, until Emacs supports Unicode, the only Emacs character set -;;; supported here is ISO-8859.1, which can trivially be converted to/from -;;; Unicode. -;;; When decoding results in a character outside the Emacs character set, -;;; an error is thrown. It is up to the application to recover. + +;; UTF-7 - A Mail-Safe Transformation Format of Unicode - RFC 2152 +;; This is a transformation format of Unicode that contains only 7-bit +;; ASCII octets and is intended to be readable by humans in the limiting +;; case that the document consists of characters from the US-ASCII +;; repertoire. +;; In short, runs of characters outside US-ASCII are encoded as base64 +;; inside delimiters. +;; A variation of UTF-7 is specified in IMAP 4rev1 (RFC 2060) as the way +;; to represent characters outside US-ASCII in mailbox names in IMAP. +;; This library supports both variants, but the IMAP variation was the +;; reason I wrote it. +;; The routines convert UTF-7 -> UTF-16 (16 bit encoding of Unicode) +;; -> current character set, and vice versa. +;; However, until Emacs supports Unicode, the only Emacs character set +;; supported here is ISO-8859.1, which can trivially be converted to/from +;; Unicode. +;; When decoding results in a character outside the Emacs character set, +;; an error is thrown. It is up to the application to recover. + +;; UTF-7 should be done by providing a coding system. Mule-UCS does +;; already, but I don't know if it does the IMAP version and it's not +;; clear whether that should really be a coding system. The UTF-16 +;; part of the conversion can be done with coding systems available +;; with Mule-UCS or some versions of Emacs. Unfortunately these were +;; done wrongly (regarding handling of byte-order marks and how the +;; variants were named), so we don't have a consistent name for the +;; necessary coding system. The code below doesn't seem to DTRT +;; generally. E.g.: +;; +;; (utf7-encode "a+£") +;; => "a+ACsAow-" +;; +;; $ echo "a+£"|iconv -f iso-8859-1 -t utf-7 +;; a+-+AKM +;; +;; -- fx + ;;; Code: (require 'base64) (eval-when-compile (require 'cl)) +(require 'mm-util) -(defvar utf7-direct-encoding-chars " -%'-*,-[]-}" +(defconst utf7-direct-encoding-chars " -%'-*,-[]-}" "Character ranges which do not need escaping in UTF-7.") -(defvar utf7-imap-direct-encoding-chars +(defconst utf7-imap-direct-encoding-chars (concat utf7-direct-encoding-chars "+\\~") "Character ranges which do not need escaping in the IMAP variant of UTF-7.") +(defconst utf7-utf-16-coding-system + (cond ((mm-coding-system-p 'utf-16-be-no-signature) ; Mule-UCS + 'utf-16-be-no-signature) + ((and (mm-coding-system-p 'utf-16-be) ; Emacs 21.4 (?), Emacs 22 + ;; Avoid versions with BOM. + (= 2 (length (encode-coding-string "a" 'utf-16-be)))) + 'utf-16-be) + ((mm-coding-system-p 'utf-16-be-nosig) ; ? + 'utf-16-be-nosig)) + "Coding system which encodes big endian UTF-16 without a BOM signature.") + (defsubst utf7-imap-get-pad-length (len modulus) "Return required length of padding for IMAP modified base64 fragment." (mod (- len) modulus)) @@ -64,10 +97,11 @@ Use IMAP modification if FOR-IMAP is non-nil." (end (point-max))) (narrow-to-region start end) (goto-char start) - (let ((esc-char (if for-imap ?& ?+)) - (direct-encoding-chars - (if for-imap utf7-imap-direct-encoding-chars - utf7-direct-encoding-chars))) + (let* ((esc-char (if for-imap ?& ?+)) + (direct-encoding-chars + (if for-imap utf7-imap-direct-encoding-chars + utf7-direct-encoding-chars)) + (not-direct-encoding-chars (concat "^" direct-encoding-chars))) (while (not (eobp)) (skip-chars-forward direct-encoding-chars) (unless (eobp) @@ -75,7 +109,7 @@ Use IMAP modification if FOR-IMAP is non-nil." (let ((p (point)) (fc (following-char)) (run-length - (skip-chars-forward (concat "^" direct-encoding-chars)))) + (skip-chars-forward not-direct-encoding-chars))) (if (and (= fc esc-char) (= run-length 1)) ; Lone esc-char? (delete-backward-char 1) ; Now there's one too many @@ -88,7 +122,8 @@ Use IMAP modification if FOR-IMAP is non-nil." (save-restriction (narrow-to-region start end) (funcall (utf7-get-u16char-converter 'to-utf-16)) - (base64-encode-region start (point-max)) + (mm-with-unibyte-current-buffer + (base64-encode-region start (point-max))) (goto-char start) (let ((pm (point-max))) (when for-imap @@ -135,15 +170,24 @@ Use IMAP modification if FOR-IMAP is non-nil." (defun utf7-get-u16char-converter (which-way) "Return a function to convert between UTF-16 and current character set." - ;; Add test to check if we are really Latin-1. - ;; Support other character sets once Emacs groks Unicode. - (if (eq which-way 'to-utf-16) - 'utf7-latin1-u16-char-converter - 'utf7-u16-latin1-char-converter)) + (if utf7-utf-16-coding-system + (if (eq which-way 'to-utf-16) + (lambda () + (encode-coding-region (point-min) (point-max) + utf7-utf-16-coding-system)) + (lambda () + (decode-coding-region (point-min) (point-max) + utf7-utf-16-coding-system))) + ;; Add test to check if we are really Latin-1. + (if (eq which-way 'to-utf-16) + 'utf7-latin1-u16-char-converter + 'utf7-u16-latin1-char-converter))) (defun utf7-latin1-u16-char-converter () "Convert latin 1 (ISO-8859.1) characters to 16 bit Unicode. Characters are converted to raw byte pairs in narrowed buffer." + (mm-encode-coding-region (point-min) (point-max) 'iso-8859-1) + (mm-disable-multibyte) (goto-char (point-min)) (while (not (eobp)) (insert 0) @@ -157,11 +201,13 @@ Characters are in raw byte pairs in narrowed buffer." (if (= 0 (following-char)) (delete-char 1) (error "Unable to convert from Unicode")) - (forward-char))) + (forward-char)) + (mm-decode-coding-region (point-min) (point-max) 'iso-8859-1) + (mm-enable-multibyte)) (defun utf7-encode (string &optional for-imap) "Encode UTF-7 STRING. Use IMAP modification if FOR-IMAP is non-nil." - (let ((default-enable-multibyte-characters nil)) + (let ((default-enable-multibyte-characters t)) (with-temp-buffer (insert string) (utf7-encode-internal for-imap) @@ -173,6 +219,7 @@ Characters are in raw byte pairs in narrowed buffer." (with-temp-buffer (insert string) (utf7-decode-internal for-imap) + (mm-enable-multibyte) (buffer-string)))) (provide 'utf7) diff --git a/texi/ChangeLog b/texi/ChangeLog index 08041c4..8c0289a 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,516 @@ +2004-01-04 Reiner Steib + + * gnus.texi (Spam ELisp Package Configuration Examples): Markup fixes. + +2004-01-03 Teodor Zlatanov + + * gnus.texi (Spam ELisp Package Sequence of Events): explain more + about the sequence of events and what happens with read-only + backends + (Spam ELisp Package Global Variables): explain what happens with + read-only backends + (Spam ELisp Package Configuration Examples): added Reiner Steib + and Ted Zlatanov's setups + +2004-01-03 Reiner Steib + + * emacs-mime.texi (Display Customization): Add mm-enable-external. + +2004-01-03 Lars Magne Ingebrigtsen + + * gnus.texi (Category Syntax): + gnus-agent-cat-enable-undownloaded-faces. + +2004-01-03 Reiner Steib + + * message.texi, gnus.texi, gnus-faq.texi: Update copyright. + + * gnus-faq.texi ([5.12]): Fix code example for FQDN in Message-Ids. + + * message.texi (Message Headers): Add message-header-synonyms. + + * gnus.texi (Other modes): New node. + (Oort Gnus): Refer to the above in "Dired integration". + +2004-01-02 Teodor Zlatanov + + * 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 + + * gnus.texi (Foreign Groups): Add `gnus-group-read-ephemeral-group'. + (Oort Gnus): Ditto. + +2004-01-02 Lars Magne Ingebrigtsen + + * message.texi (Key Index): Untabified. + + * gnus.texi (RSS): kindex. + +2003-12-30 Reiner Steib + + * gnus.texi (Summary Score Commands): Add `f' to + `gnus-score-find-trace'. + (Score File Editing): Added `V t'. + +2003-12-31 Steve Youngs + + * gnus.texi (XEmacs): Update list of Gnus XEmacs package + requirements. + +2003-12-30 Reiner Steib + + * gnus.texi (Canceling and Superseding): Mention `Cancel-Lock'. + +2003-12-30 Lars Magne Ingebrigtsen + + * gnus.texi (Maildir): Filled. + (Key Index): Untabified. + +2003-12-29 Lars Magne Ingebrigtsen + + * gnus.texi (Group Parameters): Clarification. + +2003-12-29 Simon Josefsson + + * gnus.texi (Agent Variables): Add. + +2003-12-23 Reiner Steib + + * gnus.texi (Oort Gnus): Mention change of `e' in draft groups. + +2003-12-15 Jesper Harder + + * gnus.texi (Group Parameters): Clarify. + +2003-12-11 Kevin Greiner + + * gnus.texi (Agent Parameters): Added references in Topic and + Group Parameters. Added gnus-agent-cat-disable-undownloaded-faces + to the list of documented agent parameters. + +2003-12-11 Jesper Harder + + * message.texi (Mailing Lists): Fix typo. + +2003-12-04 Katsumi Yamaoka + + * gnus.texi (Fancy Mail Splitting): Close paren of a Lisp function. + (SpamAssassin): Ditto. + +2003-12-04 Teodor Zlatanov + + * gnus.texi (SpamAssassin, Fancy Mail Splitting): add + save-restriction before (widen) in the example. From Kevin Ryde + . + +2003-12-03 Simon Josefsson + + * emacs-mime.texi (Flowed text): Fix. + +2003-12-02 Simon Josefsson + + * gnus.texi (Agent Variables): Fix. + +2003-12-01 Jesper Harder + + * gnus.texi: Add missing mode to some @kindex'es. + +2003-11-30 Jesper Harder + + * gnus.texi (RSS): Add nnrss-use-local. + (Foreign Groups): Add `G R'. + +2003-11-29 Jesper Harder + + * gnusref.tex (subsection*{Notes}): Add `G R'. + +2003-11-25 Jesper Harder + + * gnus.texi (Hiding Headers): Update. + +2003-11-20 Teodor Zlatanov + + * gnus.texi (Debugging IMAP): minor corrections + +2003-11-20 Reiner Steib + + * gnus.texi (Finding the Parent): nnml does supports fetching by + MID. + +2003-11-20 Simon Josefsson + + * gnus.texi (Debugging IMAP): Add. + +2003-11-19 Katsumi Yamaoka + + * gnus.texi (Score Decays): Update the gnus-decay-score function. + +2003-11-17 Jesper Harder + + * gnus.texi (Troubleshooting): Update. + +2003-11-03 Teodor Zlatanov + + * gnus.texi (Filtering Spam Using The Spam ELisp Package): added + some clarifications + +2003-10-30 Teodor Zlatanov + + * gnus.texi (Fancy Mail Splitting): added mention of + nnmail-split-fancy-match-partial-words + +2003-10-30 Jesper Harder + + * gnus.texi (Slashdot, SpamAssassin, Score File Format): Fix + overfull hbox. + (Topic Parameters): @group. + (Slashdot): Fix. + +2003-10-27 Teodor Zlatanov + + * gnus.texi (Filtering Spam Using The Spam ELisp Package): added + example of using a string as a parameter to spam-split in order + to override the default spam-split-group value + +2003-10-27 Jesper Harder + + * gnusref.tex (subsection*{Notes}): do. + + * gnus.texi (Exiting the Summary Buffer): Add keybinding. + +2003-10-23 Reiner Steib + + * emacs-mime.texi: Markup: Use @acronym for MML and MIME. + + * message.texi: Ditto. + + * gnus.texi: Ditto. + +2003-10-23 Simon Josefsson + + * emacs-mime.texi (MML Definition): Add format. + +2003-10-22 Teodor Zlatanov + + * gnus.texi (Filtering Spam Using The Spam ELisp Package): + changed to use the new spam-initialize function + +2003-10-19 Reiner Steib + + * message.texi (Mailing Lists): Add Mail-Followup-To to index. + + * gnus.texi (Group Parameters): Add Mail-Followup-To to index. + (Emacsen): Fixed typo. + (Oort Gnus): Mention message-forward-show-mml change (Sync with + GNUS-NEWS). + +2003-10-12 Adrian Aichner + + * gnus.texi (Mail Source Specifiers): uref fixes. + +2003-10-18 Jesper Harder + + * gnus.texi (Group Mail Splitting) + (Filtering Spam Using The Spam ELisp Package): Markup fixes. + + * message.texi (Security): @url -> @uref. + +2003-10-18 Lars Magne Ingebrigtsen + + * gnus.texi: Define gnusasis and gnusurl. + +2003-10-12 Jesper Harder + + * gnus.texi (Group Mail Splitting): Markup fix. + +2003-10-03 Jesper Harder + + * emacs-mime.texi (Files and Directories): Update. + +2003-10-02 Teodor Zlatanov + + * gnus.texi (Filtering Spam Using The Spam ELisp Package): added + spam-process-ham-in-spam-groups and + spam-process-ham-in-nonham-groups variable descriptions + +2003-10-01 Jesper Harder + + * message.texi (Various Message Variables): Typo. + + * gnus.texi (Oort Gnus): Typo. + (Filtering Spam Using The Spam ELisp Package): Just remember, + kids: There is no 'c' in 'supersede'. + +2003-09-27 Jesper Harder + + * message.texi (Reply): Fix typo. + +2003-09-22 Teodor Zlatanov + + * gnus.texi (Fancy Mail Splitting, SpamAssassin): corrected fancy + split example to use current buffer, mentioned + nnimap-split-download-body + +2003-09-22 Jesper Harder + + * gnus.texi, gnus-faq.texi, message.texi: gnus -> Gnus. + + * message.texi: Fixes. + +2003-09-20 Jesper Harder + + * gnus.texi (Fancy Mail Splitting): Make split-on-body work for + respooling. Suggested by Harald Maier . + (Fancy Mail Splitting): Reformat. + +2003-09-15 Jesper Harder + + * gnus.texi (Posting Styles): Fix typo. @itemize attribute names. + +2003-09-14 Jesper Harder + + * pgg.texi (Selecting an implementation, Caching passphrase) + (Initializing): Markup fix. + +2003-09-12 Jesper Harder + + * gnus.texi (Summary Buffer Lines): Formatting fix. + +2003-09-03 Jesper Harder + + * gnus.texi (Creating a Virtual Server): Use nnml for the example. + nnspool doesn't work on ms-windows due to file name restrictions. + +2003-08-29 Teodor Zlatanov + + * gnus.texi (Gmane Spam Reporting): added explanation of + spam-report-gmane-use-article-number + +2003-08-25 Jesper Harder + + * gnus.texi (Customizing Articles): xface -> x-face. + +2003-08-20 Simon Josefsson + + * gnus.texi (GroupLens): Move text around. + +2003-08-16 Jesper Harder + + * gnus.texi (Searching for Articles): Fix example. + +2003-08-08 Jesper Harder + + * gnus.texi (Kibozed Groups): Fix. + +2003-08-04 Jesper Harder + + * gnus.texi (Group Parameters): Add expiry-target. + (Archived Messages): Layout fix. + +2003-07-22 Jesper Harder + + * gnus.texi (Top): Menu fixes and additions. + +2003-07-19 Jesper Harder + + * emacs-mime.texi (Encoding Customization): Fix. + (MML Definition): Typo. + +2003-07-17 Jesper Harder + + * gnus.texi (Sorting the Summary Buffer): Index. + +2003-07-15 Reiner Steib + + * gnus-faq.texi ([3.8]): Fixed example. + +2003-07-14 Teodor Zlatanov + + * gnus.texi (Filtering Spam Using The Spam ELisp Package): + mentioned the spam-install-hooks mess + +2003-07-11 Simon Josefsson + + * gnus.texi (Splitting in IMAP): Typos, tiny patch from Matthias + Andree . + (Splitting in IMAP): Mention Sieve. + +2003-07-10 Simon Josefsson + + * message.texi (Security): Discuss the PGP 2.x compatibility + problem. + +2003-06-24 Jesper Harder + + * sieve.texi (Sieve Mode): Formatting fix. + + * gnus.texi (Agent Basics, Group Parameters, Quassia Gnus): do. + +2003-06-24 Lars Magne Ingebrigtsen + + * gnus.texi (Summary Mail Commands): Make note of + Mail-Followup-To. + +2003-06-23 Jesper Harder + + * gnus.texi: Formatting fixes. + +2003-06-22 Simon Josefsson + + * message.texi (Security): Mention S/MIME passphrases. + +2003-06-20 Jesper Harder + + * gnus.texi: Add @command. + + * texi2latex.el (latexi-translate-file): Add @command and @:. + + * gnus.texi (Face): Use @uref. + +2003-06-19 Jesper Harder + + * gnus.texi (Sieve Commands, Agent Basics, SpamOracle): @xref + fixes. + +2003-06-18 Didier Verna + + * gnus.texi (Face): New node. + * gnus.texi (Article Display): Reference it. + * gnus.texi (Customizing Articles): Ditto. + * gnus.texi (Image Enhancements): Put the Face node into the menu. + +2003-06-17 Kai Gro,A_(Bjohann + + * gnus.texi (Splitting Mail): Add "splitting" entry and concept + index entries. Small patch from Karl Pfl,Ad(Bsterer + . + +2003-06-15 Reiner Steib + + * gnus.texi (Daemons): Fixed typo. + +2003-06-15 Kai Gro,A_(Bjohann + + * message.texi (Message Headers): Extend + `message-subject-re-regexp' example. From Niklas Morberg + . + +2003-06-11 Teodor Zlatanov + + * gnus.texi (Bogofilter): revise docs to mention threshold is now + user-controllable + +2003-06-10 Jesper Harder + + * emacs-mime.texi: Use two spaces consistently to end sentences. + + * message.texi: do. + + * gnus.texi: do. + +2003-06-09 Teodor Zlatanov + + * gnus.texi (Filtering Spam Using The Spam ELisp Package): new + SpamOracle node + (SpamOracle): document new SpamOracle code + +2003-06-07 Jesper Harder + + * gnus.texi (Article Buttons, Splitting in IMAP) + (Category Syntax, Picons): Preemptive strike by + alt.possesive.its.has.no.apostrophe. + +2003-06-03 Jesper Harder + + * gnus.texi (Fancy Mail Splitting): Explain some entries in + nnmail-split-abbrev-alist. + +2003-05-17 Adrian Aichner + + * emacs-mime.texi (Charset Translation): Ruthless typo fixing. + * gnus.texi (Top): Ditto. + * gnus.texi (Selecting a Group): Ditto. + * gnus.texi (Delayed Articles): Ditto. + * gnus.texi (Hiding Headers): Ditto. + * gnus.texi (Getting Mail): Ditto. + * gnus.texi (Comparing Mail Back Ends): Ditto. + * gnus.texi (IMAP): Ditto. + * gnus.texi (Required Back End Functions): Ditto. + * gnusref.tex (MIMESummary): Ditto. + * message.texi (Message Headers): Ditto. + * message.texi (Mail Variables): Ditto. + * pgg.texi (Prerequisites): Ditto. + * pgg.texi (Architecture): Ditto. + * pgg.texi (Backend methods): Ditto. + * sieve.texi (Managing Sieve): Ditto. + +2003-05-17 Jesper Harder + + * gnusref.tex (subsection*{Notes}): Fix. + +2003-05-13 Lars Magne Ingebrigtsen + + * gnus.texi (Anti-Spam Basics): Removed mention of gnus-junk. + +2003-05-13 Jesper Harder + + * gnus.texi (Agent Variables, Score File Format) + (Troubleshooting, Editing IMAP ACLs, Conformity): a -> an. + + * message.texi (Insertion Variables): do. + +2003-05-13 Simon Josefsson + + * gnus.texi (IMAP, Agent and IMAP, Oort Gnus): s/a/an/. Tiny + patch from Niklas Morberg . + +2003-05-12 Kevin Greiner + + * gnus.texi (Agent Visuals): Add. + +2003-05-09 Simon Josefsson + + * pgg.texi (Default user identity): Add. + +2003-05-08 Jesper Harder + + * gnus.texi (Selecting a Group): Mention nil value + gnus-large-newsgroup. + +2003-05-07 Jesper Harder + + * gnus.texi (MIME Commands): Fix typo. + +2003-05-05 Jesper Harder + + * gnusref.tex: Additions. + + * gnus.texi (Oort Gnus): Fix typo. + +2003-05-03 Kai Gro,A_(Bjohann + + * gnus.texi (Agent Basics): Explain that some servers can be + agentized, whereas others aren't. + 2003-05-01 Reiner Steib * gnus.texi (Oort Gnus): Add prefix limit feature. @@ -17,11 +530,11 @@ * texi2latex.el (latexi-translate-file): Add @syncodeindex. - * gnus.texi: Markup and formatting improvements. + * gnus.texi: Markup and formatting improvements. Use @syncodeindex for merging indexes to get the same font for @defvar and @vindex entries. Be more consistent about the case of index entries. - + 2003-04-30 Reiner Steib @@ -97,7 +610,7 @@ * gnus-faq.texi: Allow inclusion in `gnus.texi' again. 2003-04-21 Reiner Steib - + * gnus-faq.texi: New, the Gnus FAQ from http://my.gnus.org/FAQ. From Frank Schmitt . diff --git a/texi/Makefile.in b/texi/Makefile.in index a45ab99..430c1b9 100644 --- a/texi/Makefile.in +++ b/texi/Makefile.in @@ -173,8 +173,8 @@ gnus.latexi gnus-faq.latexi message.latexi emacs-mime.latexi sieve.latexi: $(src egrep -v "end\{document\}" $< > gnus.tmplatexi cat $(srcdir)/postamble.tex >> gnus.tmplatexi TEXINPUTS=$(srcdir):$$TEXINPUTS $(PDFLATEX) gnus.tmplatexi - thumbpdf gnus.pdf - TEXINPUTS=$(srcdir):$$TEXINPUTS $(PDFLATEX) gnus.tmplatexi + #thumbpdf gnus.pdf + #TEXINPUTS=$(srcdir):$$TEXINPUTS $(PDFLATEX) gnus.tmplatexi mv gnus.pdf $@ latexps: gnus.dvi-x diff --git a/texi/emacs-mime.texi b/texi/emacs-mime.texi index 40b91b1..8c51bde 100644 --- a/texi/emacs-mime.texi +++ b/texi/emacs-mime.texi @@ -93,7 +93,7 @@ read at least RFC2045 and RFC2047. @menu * Decoding and Viewing:: A framework for decoding and viewing. -* Composing:: MML; a language for describing @acronym{MIME} parts. +* Composing:: @acronym{MML}; a language for describing @acronym{MIME} parts. * Interface Functions:: An abstraction over the basic functions. * Basic Functions:: Utility and basic parsing functions. * Standards:: A summary of RFCs and working documents used. @@ -407,6 +407,22 @@ setting this option to non-@code{nil}. The default value is @code{t}. @vindex mm-external-terminal-program The program used to start an external terminal. +@item mm-enable-external +@vindex mm-enable-external +Indicate whether external MIME handlers should be used. + +If @code{t}, all defined external MIME handlers are used. If +@code{nil}, files are saved to disk (@code{mailcap-save-binary-file}). +If it is the symbol @code{ask}, you are prompted before the external +@acronym{MIME} handler is invoked. + +When you launch an attachment through mailcap (@pxref{mailcap}) an +attempt is made to use a safe viewer with the safest options--this isn't +the case if you save it to disk and launch it in a different way +(command line or double-clicking). Anyhow, if you want to be sure not +to launch any external programs, set this variable to @code{nil} or +@code{ask}. + @end table @node Files and Directories @@ -430,6 +446,16 @@ parts. Each function is applied successively to the file name. Ready-made functions include @table @code +@item mm-file-name-delete-control +@findex mm-file-name-delete-control +Delete all control characters. + +@item mm-file-name-delete-gotchas +@findex mm-file-name-delete-gotchas +Delete characters that could have unintended consequences when used +with flawed shell scripts, i.e. @samp{|}, @samp{>} and @samp{<}; and +@samp{-}, @samp{.} as the first character. + @item mm-file-name-delete-whitespace @findex mm-file-name-delete-whitespace Remove all whitespace. @@ -448,7 +474,6 @@ Collapse multiple whitespace characters. Replace whitespace with underscores. Set the variable @code{mm-file-name-replace-whitespace} to any other string if you do not like underscores. - @end table The standard Emacs functions @code{capitalize}, @code{downcase}, @@ -499,9 +524,10 @@ tell it to insert, but it also sets things up so that the text can be @cindex MML @cindex MIME Meta Language -Creating a @acronym{MIME} message is boring and non-trivial. Therefore, a -library called @code{mml} has been defined that parses a language called -MML (@acronym{MIME} Meta Language) and generates @acronym{MIME} messages. +Creating a @acronym{MIME} message is boring and non-trivial. Therefore, +a library called @code{mml} has been defined that parses a language +called @acronym{MML} (@acronym{MIME} Meta Language) and generates +@acronym{MIME} messages. @findex mml-generate-mime The main interface function is @code{mml-generate-mime}. It will @@ -509,12 +535,12 @@ examine the contents of the current (narrowed-to) buffer and return a string containing the @acronym{MIME} message. @menu -* Simple MML Example:: An example MML document. -* MML Definition:: All valid MML elements. -* Advanced MML Example:: Another example MML document. +* Simple MML Example:: An example @acronym{MML} document. +* MML Definition:: All valid @acronym{MML} elements. +* Advanced MML Example:: Another example @acronym{MML} document. * Encoding Customization:: Variables that affect encoding. * Charset Translation:: How charsets are mapped from @sc{mule} to @acronym{MIME}. -* Conversion:: Going from @acronym{MIME} to MML and vice versa. +* Conversion:: Going from @acronym{MIME} to @acronym{MML} and vice versa. * Flowed text:: Soft and hard newlines. @end menu @@ -556,10 +582,10 @@ Content-Type: text/enriched @node MML Definition @section MML Definition -The MML language is very simple. It looks a bit like an SGML +The @acronym{MML} language is very simple. It looks a bit like an SGML application, but it's not. -The main concept of MML is the @dfn{part}. Each part can be of a +The main concept of @acronym{MML} is the @dfn{part}. Each part can be of a different type or use a different charset. The way to delineate a part is with a @samp{<#part ...>} tag. Multipart parts can be introduced with the @samp{<#multipart ...>} tag. Parts are ended by the @@ -574,8 +600,8 @@ Each tag can contain zero or more parameters on the form but that's not necessary unless the value contains white space. So @samp{filename=/home/user/#hello$^yes} is perfectly valid. -The following parameters have meaning in MML; parameters that have no -meaning are ignored. The MML parameter names are the same as the +The following parameters have meaning in @acronym{MML}; parameters that have no +meaning are ignored. The @acronym{MML} parameter names are the same as the @acronym{MIME} parameter names; the things in the parentheses say which header it will be used in. @@ -589,7 +615,7 @@ Use the contents of the file in the body of the part @item charset The contents of the body of the part are to be encoded in the character -set speficied (@code{Content-Type}). @xref{Charset Translation}. +set specified (@code{Content-Type}). @xref{Charset Translation}. @item name Might be used to suggest a file name if the part is to be saved @@ -628,15 +654,25 @@ default key used. The size (in octets) of the part (@code{Content-Disposition}). @item sign -What technology to sign this MML part with (@code{smime}, @code{pgp} +What technology to sign this @acronym{MML} part with (@code{smime}, @code{pgp} or @code{pgpmime}) @item encrypt -What technology to encrypt this MML part with (@code{smime}, +What technology to encrypt this @acronym{MML} part with (@code{smime}, @code{pgp} or @code{pgpmime}) @end table +Parameters for @samp{text/plain}: + +@table @samp +@item format +Formatting parameter for the text, valid values include @samp{fixed} +(the default) and @samp{flowed}. Normally you do not specify this +manually, since it requires the textual body to be formatted in a +special way described in RFC 2646. @xref{Flowed text}. +@end table + Parameters for @samp{application/octet-stream}: @table @samp @@ -794,7 +830,7 @@ default is As an example, if you do not want to have ISO-8859-1 characters quoted-printable encoded, you may add @code{(iso-8859-1 . 8bit)} to this variable. You can override this setting on a per-message basis -by using the @code{encoding} MML tag (@pxref{MML Definition}). +by using the @code{encoding} @acronym{MML} tag (@pxref{MML Definition}). @item mm-coding-system-priorities @vindex mm-coding-system-priorities @@ -803,20 +839,20 @@ is @code{nil}, which means to use the defaults in Emacs. It is a list of coding system symbols (aliases of coding systems does not work, use @kbd{M-x describe-coding-system} to make sure you are not specifying an alias in this variable). For example, if you have configured Emacs -to use prefer UTF-8, but wish that outgoing messages should be sent in +to prefer UTF-8, but wish that outgoing messages should be sent in ISO-8859-1 if possible, you can set this variable to -@code{(iso-latin-1)}. You can override this setting on a per-message -basis by using the @code{charset} MML tag (@pxref{MML Definition}). +@code{(iso-latin-1)}. You can override this setting on a per-message +basis by using the @code{charset} @acronym{MML} tag (@pxref{MML Definition}). @item mm-content-transfer-encoding-defaults @vindex mm-content-transfer-encoding-defaults Mapping from @acronym{MIME} types to encoding to use. This variable is usually used except, e.g., when other requirements force a safer encoding -(digitally signed messages require 7bit encoding). Besides the normal +(digitally signed messages require 7bit encoding). Besides the normal @acronym{MIME} encodings, @code{qp-or-base64} may be used to indicate that for each case the most efficient of quoted-printable and base64 should be used. You can override this setting on a per-message basis by using -the @code{encoding} MML tag (@pxref{MML Definition}). +the @code{encoding} @acronym{MML} tag (@pxref{MML Definition}). @item mm-use-ultra-safe-encoding @vindex mm-use-ultra-safe-encoding @@ -834,8 +870,9 @@ encoding messages that are to be digitally signed). @section Charset Translation @cindex charsets -During translation from MML to @acronym{MIME}, for each @acronym{MIME} part which -has been composed inside Emacs, an appropriate charset has to be chosen. +During translation from @acronym{MML} to @acronym{MIME}, for each +@acronym{MIME} part which has been composed inside Emacs, an appropriate +charset has to be chosen. @vindex mail-parse-charset If you are running a non-@sc{mule} Emacs, this process is simple: If the @@ -875,8 +912,8 @@ messages. You can modify this by altering the @code{mm-coding-system-priorities} variable though (@pxref{Encoding Customization}). -The charset to be used can be overriden by setting the @code{charset} -MML tag (@pxref{MML Definition}) when composing the message. +The charset to be used can be overridden by setting the @code{charset} +@acronym{MML} tag (@pxref{MML Definition}) when composing the message. The encoding of characters (quoted-printable, 8bit etc) is orthogonal to the discussion here, and is controlled by the variables @@ -888,15 +925,15 @@ Customization}). @section Conversion @findex mime-to-mml -A (multipart) @acronym{MIME} message can be converted to MML with the -@code{mime-to-mml} function. It works on the message in the current -buffer, and substitutes MML markup for @acronym{MIME} boundaries. -Non-textual parts do not have their contents in the buffer, but instead -have the contents in separate buffers that are referred to from the MML -tags. +A (multipart) @acronym{MIME} message can be converted to @acronym{MML} +with the @code{mime-to-mml} function. It works on the message in the +current buffer, and substitutes @acronym{MML} markup for @acronym{MIME} +boundaries. Non-textual parts do not have their contents in the buffer, +but instead have the contents in separate buffers that are referred to +from the @acronym{MML} tags. @findex mml-to-mime -An MML message can be converted back to @acronym{MIME} by the +An @acronym{MML} message can be converted back to @acronym{MIME} by the @code{mml-to-mime} function. These functions are in certain senses ``lossy''---you will not get back @@ -921,12 +958,14 @@ variable (@pxref{Hard and Soft Newlines, ,Hard and Soft Newlines, emacs, Emacs Manual}) when encoding a message, and the ``format=flowed'' Content-Type parameter when decoding a message. -On encoding text, lines terminated by soft newline characters are -filled together and wrapped after the column decided by -@code{fill-flowed-encode-column}. This variable controls how the text -will look in a client that does not support flowed text, the default -is to wrap after 66 characters. If hard newline characters are not -present in the buffer, no flow encoding occurs. +On encoding text, regardless of @code{use-hard-newlines}, lines +terminated by soft newline characters are filled together and wrapped +after the column decided by @code{fill-flowed-encode-column}. +Quotation marks (matching @samp{^>* ?}) are respected. The variable +controls how the text will look in a client that does not support +flowed text, the default is to wrap after 66 characters. If hard +newline characters are not present in the buffer, no flow encoding +occurs. On decoding flowed text, lines with soft newline characters are filled together and wrapped after the column decided by diff --git a/texi/gnus-faq-ja.texi b/texi/gnus-faq-ja.texi index c34386d..fe833d1 100644 --- a/texi/gnus-faq-ja.texi +++ b/texi/gnus-faq-ja.texi @@ -71,10 +71,10 @@ Baur $B;a!"(B Per Abrahamsen $B;a$K46!"(B APEL $B$,I,MW$K$J$j$^$9$,!"I,MW$J%P!<%8%g%s(B $B$O(B FLIM / SEMI $B%Q%C%1!<%8Fb$N(B README $B$r;2>H$7$F$/$@$5$$!#(B @@ -120,7 +120,7 @@ anonymous ftp $B$G$Nl=j$+$i" @noindent Then typing your alias (followed by a space or punctuation character) on a To: or Cc: line in the message buffer will - cause gnus to insert the full address for you. See the + cause Gnus to insert the full address for you. See the node "Mail Aliases" in Message (not Gnus) manual for details. @@ -1845,17 +1845,25 @@ Answer: name to put after the "@@". If the name of the machine where Gnus is running isn't suitable (it probably isn't at most private machines) you can tell Gnus what to use - by saying: - - + by saying @example -(defun message-make-message-id() - (concat "<"(message-unique-id)"@@yourmachine.yourdomain.tld>")) +(setq message-user-fqdn "yourmachine.yourdomain.tld") @end example - - @noindent - in ~/.gnus. If you have no idea what to insert for + in ~/.gnus. If you use Gnus 5.9 or ealier, you can use this +instead: +@example +(eval-after-load "message" + '(let (myfqdn "yourmachine.yourdomain.tld");; <-- Edit this! + (if (boundp 'message-user-fqdn) + (setq message-user-fqdn fqdn) + (gnus-message 1 "Redefining `message-make-fqdn'.") + (defun message-make-fqdn () + "Return user's fully qualified domain name." + fqdn)))) +@end example + + If you have no idea what to insert for "yourmachine.yourdomain.tld", you've got several choices. You can either ask your provider if he allows you to use something like diff --git a/texi/gnus-ja.texi b/texi/gnus-ja.texi index 1abd205..6d80aa6 100644 --- a/texi/gnus-ja.texi +++ b/texi/gnus-ja.texi @@ -1,7 +1,7 @@ \input texinfo @setfilename gnus-ja -@settitle T-gnus 6.15 Manual +@settitle T-gnus 6.16 Manual @syncodeindex fn cp @syncodeindex vr cp @syncodeindex pg cp @@ -33,7 +33,7 @@ \makeindex \begin{document} -\newcommand{\gnusversionname}{T-gnus v6.15} +\newcommand{\gnusversionname}{T-gnus v6.16} \newcommand{\gnuschaptername}{} \newcommand{\gnussectionname}{} @@ -53,6 +53,9 @@ \newcommand{\gnustt}[1]{{\gnusselectttfont{}#1}} \newcommand{\gnuscode}[1]{\gnustt{#1}} +\newcommand{\gnusasis}[1]{\gnustt{#1}} +\newcommand{\gnusurl}[1]{\gnustt{#1}} +\newcommand{\gnuscommand}[1]{\gnustt{#1}} \newcommand{\gnusenv}[1]{\gnustt{#1}} \newcommand{\gnussamp}[1]{``{\fontencoding{OT1}\gnusselectttfont{}#1}''} \newcommand{\gnuslisp}[1]{\gnustt{#1}} @@ -153,6 +156,11 @@ } }{\end{list}} +\newenvironment{asislist}% +{\begin{list}{}{ +} +}{\end{list}} + \newenvironment{kbdlist}% {\begin{list}{}{ \labelwidth=0cm @@ -293,7 +301,7 @@ \thispagestyle{empty} Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003 +2002, 2003, 2004 Free Software Foundation, Inc. @@ -382,7 +390,7 @@ license to the document, as described in section 6 of the license. @tex @titlepage -@title T-gnus 6.15 Manual +@title T-gnus 6.16 Manual @author by Lars Magne Ingebrigtsen @author by members of Semi-gnus mailing-list @@ -450,7 +458,7 @@ T-gnus $B$O(B @acronym{SEMI} API $B$K4p$E$/(B @acronym{MIME} $B5!G=$rDs6!$7 $B$5$^$6$^$J8@8l7w$r:9JL$7$^$;$s!#$"$"!"%/%j%s%4%s$NJ}$O(B Unicode Next Generation $B$r$*BT$A$/$@$5$$!#(B -$B$3$N@bL@=q$O(B T-gnus 6.15 $B$KBP1~$7$^$9!#(B +$B$3$N@bL@=q$O(B T-gnus 6.16 $B$KBP1~$7$^$9!#(B @end ifinfo @@ -497,7 +505,7 @@ Emacs $B$,J8>O$rJT=8$9$k?M$KNO$rM?$($k$h$&$K!"(Bgnus $B$O%K%e!<%9$rFI$`?M$KNO Other related manuals -* Message:(message). Composing messages. +* Message:(message). $B%a%C%;!<%8$N:n@.(B * Emacs-MIME:(emacs-mime). Composing messages; @acronym{MIME}-specific parts. * Sieve:(sieve). Managing Sieve scripts in Emacs. * PGG:(pgg). @acronym{PGP/MIME} with Gnus. @@ -618,7 +626,7 @@ Reply, Followup and Post * Summary Mail Commands:: $B%a!<%k$rAw$k(B * Summary Post Commands:: $B%K%e!<%9$rAw$k(B * Summary Message Commands:: $BB>$N%a%C%;!<%84XO"$NL?Na(B -* Canceling and Superseding:: +* Canceling and Superseding:: Marking Articles @@ -682,7 +690,7 @@ Various Summary Stuff * Summary Group Information:: $B>pJs;X8~$NL?Na(B * Searching for Articles:: $BJ#?t5-;vL?Na(B -* Summary Generation Commands:: +* Summary Generation Commands:: * Really Various Summary Commands:: $B$"$N$d$C$+$$$JB>$KE,9g$7$J$$L?Na(B Article Buffer @@ -747,7 +755,7 @@ Getting Mail * Group Mail Splitting:: $B%a!<%kJ,3d$r6nF0$9$k$?$a$K%0%k!<%W%+%9%?%^%$%:$r;H$&(B * Incorporating Old Mail:: $B$"$J$?$,;}$C$F$$$k8E$$%a!<%k$r$I$&$9$k$+(B? * Expiring Mail:: $BM_$7$/$J$$%a!<%k$r$N%U%!%$%k$rFI$`$?$a$K%a!<%k%P%C%/%(%s%I$r;H$&(B * Choosing a Mail Back End:: Gnus $B$O?'!9$J%a!<%kMM<0$rFI$`;v$,$G$-$k(B @@ -770,7 +778,7 @@ Choosing a Mail Back End Browsing the Web -* Archiving Mail:: +* Archiving Mail:: * Web Searches:: $BJ8;zNs$K%^%C%A$9$k5-;v$+$i%0%k!<%W$r:n$k(B * Slashdot:: Slashdot $B$N%3%a%s%H$rFI$`(B * Ultimate:: Ultimate Bulletin Board $B%7%9%F%`(B @@ -786,6 +794,7 @@ Browsing the Web * Editing IMAP ACLs:: $B%a!<%k%\%C%/%9$X$NB>$NMxMQA06u4V$r;H$&(B($B;H$o$J$$(B)$BJ}K!(B +* Debugging IMAP:: $B$b$N$4$H$,F/$+$J$$$H$-$K$9$k$Y$-$3$H(B Other Sources @@ -815,6 +824,7 @@ Gnus Unplugged * Agent Basics:: $B$3$l$i$O$I$&F0$/$N$+(B * Agent Categories:: $B2?$r%@%&%s%m!<%I$9$k$+$r(B gnus $B%(!<%8%'%s%H$K65$($kJ}K!(B * Agent Commands:: $B3F%P%C%U%!!<$G$N?7$7$$L?Na(B +* Agent Visuals:: $B%(!<%8%'%s%H$,35N,%P%C%U%!$KJQ2=$r$b$?$i$9$+$b$7$l$J$$J}K!(B * Agent as Cache:: $B%(!<%8%'%s%H$OBg$-$J%-%c%C%7%e$G$b$"$k(B * Agent Expiry:: $B8E$$5-;v$r>C$9J}K!(B * Agent Regeneration:: $BDL?.@ZCG$dB>$N;v8N$+$i2sI|$9$kJ}K!(B @@ -842,7 +852,7 @@ Scoring * Summary Score Commands:: $B8=:_$N%0%k!<%W$N$?$a$N%9%3%"EPO?$rDI2C$9$k(B * Group Score Commands:: $B0lHLE*$J%9%3%"L?Na(B -* Score Variables:: $B$"$J$?$N%9%3%"$r%+%9%?%^%$%:$9$k(B ($B$^$!!"$J$s$FMQ8l$G$7$g$&(B) +* Score Variables:: $B$"$J$?$N%9%3%"$r%+%9%?%^%$%:$9$k(B ($B$^$!!"$J$s$FMQ8l(B (Scoring) $B$G$7$g$&(B) * Score File Format:: $B%9%3%"%U%!%$%k$K2?$rF~$l$k$+(B * Score File Editing:: $BC5n%U%!%$%k$r%9%3%"%U%!%$%k$KJQ49$9$k(B * GroupLens:: $B$I$l$rFI$`$N$,9%$-$+$NM=8@$rF@$k(B * Advanced Scoring:: $B%9%3%"$NK!B'$r:n$k$?$a$KO@M}I=8=$r;H$&(B @@ -891,6 +901,7 @@ Various * Image Enhancements:: $B:G?7$N(B Emacs/XEmacs $B$O3($rI=<($G$-$k(B * Fuzzy Matching:: $BBg$-$JLJLS$C$F2?(B? * Thwarting Email Spam:: $BM>7W$J>&6HE*EE;R%a!<%k$rHr$1$kJ}K!(B +* Other modes:: $BB>$N%b!<%I$H$NAj8_:nMQ(B * Various Various:: $BK\Ev$K$$$m$$$m$J$b$N(B Formatting Variables @@ -906,9 +917,10 @@ Formatting Variables Image Enhancements -* Picons:: $B$"$J$?$,FI$s$G$$$k$b$N$N3($rI=<($9$kJ}K!(B -* Smileys:: $BI=<($5$l$k$Y$/@8$^$l$?9,$;$=$&$J4i$rI=<($9$kJ}K!(B * X-Face:: $B%U%!%s%-!<$J$A$C$A$c$JGr9u$N3($rI=<($9$k(B +* Face:: $B$h$j%U%!%s%-!<$G$A$C$A$c$J%+%i!<$N3($rI=<($9$k(B +* Smileys:: $BI=<($5$l$k$Y$/@8$^$l$?9,$;$=$&$J4i$rI=<($9$kJ}K!(B +* Picons:: $B$"$J$?$,FI$s$G$$$k$b$N$N3($rI=<($9$kJ}K!(B * XVarious:: $B$=$NB>$N(B XEmacs $B$G(B Gnus $B$JJQ?t(B Thwarting Email Spam @@ -917,8 +929,32 @@ Thwarting Email Spam * Anti-Spam Basics:: $B$?$/$5$s$N(B spam $B$r8:$i$94JC1$JJ}K!(B * SpamAssassin:: Spam $BBP:v%D!<%k$N;H$$J}(B * Hashcash:: CPU $B;~4V$rHq$d$7$F(B spam $BB`<#$9$k(B -* Filtering Spam Using The Spam ELisp Package:: -* Filtering Spam Using Statistics with spam-stat:: +* Filtering Spam Using The Spam ELisp Package:: +* Filtering Spam Using Statistics with spam-stat:: + +Filtering Spam Using 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 + +* Creating a spam-stat dictionary:: +* Splitting mail using spam-stat:: +* Low-level interface to the spam-stat dictionary:: Appendices @@ -1099,7 +1135,7 @@ gnus $B$O(B @code{gnus-secondary-servers} $B%j%9%H(B ($B$b$7B8:_$9$k$J$i$P $BNa$r;H$&$3$H$NJ}$,NI$$$G$7$g$&!#$=$l$O!"A*Br2DG=$J%0%k!<%W$rI=<($7!"$=$N(B $BCf$+$i$I$l$G$b9%$-$J$b$N$r9XFI$9$k$3$H$,$G$-$^$9!#$3$l(B $B$O(B @file{.newsrc} $B$NJ];}$r$:$C$H$d$j$d$9$/$7$^$9!#(B -@xref{Foreign Groups, $B30It%0%k!<%W(B}$B!#(B +@xref{Foreign Groups, $B30It%0%k!<%W(B}. @vindex gnus-secondary-select-methods @c @head @@ -1166,7 +1202,7 @@ Gnus $B$O!"?.Mj$G$-$k%W%m%0%i%`$N0l$D$H$7$F!"%5!<%P!<$H@\B3$G$-$J$$$H$-$O(B $B$r;H$&$3$H$,$G$-$^$9!#5^$$$G$$$k$H$-$K$b$T$C$?$j$G$7$g$&!#$3$NL?Na$OK\Mh(B $B$N%5!<%P!<$K$O@\B3$7$^$;$s!=!=$=$NBe$o$j$K!"%l%Y%k(B 1 $B$H(B 2 $B$K$"$k$9$Y$F$N(B $B%0%k!<%W$r3hF0>uBV$K$7$^$9(B ($B4pK\%0%k!<%W$G$J$$%0%k!<%W$O$=$NFs$D$N%l%Y%k(B -$B$K$7$F$*$/$N$,K>$^$7$$$G$7$g$&(B)$B!#(B@pxref{Group Levels} $B$b;2>H$7$F2<$5$$!#(B +$B$K$7$F$*$/$N$,K>$^$7$$$G$7$g$&(B)$B!#(B@ref{Group Levels} $B$b;2>H$7$F2<$5$$!#(B @node Slave Gnusae @section gnus $B$r%9%l!<%V$K$9$k(B @@ -1593,8 +1629,7 @@ Gnus $B$O5/F0$7$?$H$-$d!"A0$r;}$D%0%k!<%W$rGS=|$9$k$?$a$K;H$o$l$F$-$^$7$?$,!"6=L#$NL5$$%0(B $B%k!<%W$N3,AX$rL5;k$9$k$?$a$K;H$&$3$H$b$G$-$^$9!#$7$+$7!"$3$l$O$*4+$a$G$-(B $B$^$;$s!#K\Ev$N$3$H$r8@$&$H!"A4$/;?@.$G$-$^$;$s!#Be$o$j$K!"$=$N$h$&$JMQES(B -$B$KMQ$$$i$l$kJQ?t$N35N,$rCN$k$?$a$K!"(B@pxref{New Groups} $B$r;2>H$7$F$/$@$5(B -$B$$!#(B +$B$KMQ$$$i$l$kJQ?t$N35N,$rCN$k$?$a$K!"(B@ref{New Groups} $B$r;2>H$7$F$/$@$5$$!#(B @c This variable is @c @code{nil} by default, and will slow down active file handling somewhat @@ -1795,12 +1830,12 @@ Gnus $B$N5/F0$K@.8y$7$?8e$K!"0lHV:G8e$Ke5-$N9T$r@8@.$7$^$9!#(B $B%3%m%s$O!"$3$N9T$NCf$KI,$:L5$/$F$O$$$1$^$;$s!#%+!<%=%k$O!"2?$+$NA`:n$r$7(B -$B$?8e$O>o$K%3%m%s$N$H$3$m$K0\F0$9$k$+$i$G$9!#(B@xref{Positioning Point}$B!#B>(B +$B$?8e$O>o$K%3%m%s$N$H$3$m$K0\F0$9$k$+$i$G$9!#(B@xref{Positioning Point}. $BB>(B $B$K$O2?$bI,MW$G$O$"$j$^$;$s!=!=%0%k!<%WL>$5$($b$G$9!#I=<($5$l$F$$$kJ8;z$O(B $BA4$F$?$@$N2hLL$N>~$j$G$"$j!"(Bgnus $B$,$=$l$rD4$Y$k$3$H$O$"$j$^$;$s!#(BGnus $B$O(B $BI,MW$H$9$kA4$F$NpJs$r!"%F%-%9%HB0@-$r;H$C$F21$($F$$$^$9!#(B @@ -1978,7 +2013,7 @@ Gnus $B$O(B @code{gnus-user-format-function-}@samp{X} $B4X?t$r8F$S=P$7$^$9!#$ (t . my-group-face-5))) @end lisp -@pxref{Faces and Fonts} $B$b;2>H$7$F$/$@$5$$!#(B +@ref{Faces and Fonts} $B$b;2>H$7$F$/$@$5$$!#(B $B$3$N(B form $B$,I>2A$5$l$k$H$-$KF0E*$KB+G{$5$l$F$$$kJQ?t$K$O0J2<$N$b$N$,$"$j(B $B$^$9!#(B @@ -2150,17 +2185,17 @@ Gnus $B$O(B @code{gnus-user-format-function-}@samp{X} $B4X?t$r8F$S=P$7$^$9!#$ @end table @vindex gnus-large-newsgroup -@code{gnus-large-newsgroup} $BJQ?t$O!"2?$rBg$-$J%0%k!<%W$H9M$($k$Y$-$+!"(B -$B$r(B gnus $B$KM?$($^$9!#$3$l$O=i4|@_Dj$G$O(B 200 $B$G$9!#%0%k!<%W$K(B ($BL$FI$H0uIU(B -$B$-$N(B) $B5-;v$,$3$N?t0J>e$"$l$P!"(Bgnus $B$O$=$N%0%k!<%W$KF~$kA0$KMxMQe$"$l$P!"(Bgnus $B$O$=$N%0%k!<%W$KF~$kA0$KMxMQo!"(B@code{gnus-activate-level} $B$+$=$l$h$j>.$5$$%l%Y%k$N%0%k!<% @cindex making groups $B?7$7$$%0%k!<%W$r:n@.$7$^$9(B (@code{gnus-group-make-group})$B!#(BGnus $B$O%W%m%s(B $B%W%H$rI=<($7$F!"L>A0$HJ}K!$H!">l9g$K$h$C$F$O(B @dfn{address} $B$NF~NO$r5a$a(B -$B$F$-$^$9!#$h$j4JC1$K(B @acronym{NNTP} $B%0%k!<%W$r9XFI$9$kJ}K!$O!"(B -@pxref{Browse Foreign Server}$B!#(B +$B$F$-$^$9!#$h$j4JC1$K(B @acronym{NNTP} $B%0%k!<%W$r9XFI$9$kJ}K!$K$D$$$F$O!"(B +@ref{Browse Foreign Server} $B$r;2>H$7$F2<$5$$!#(B + +@item G M +@kindex G M ($B%0%k!<%W(B) +@findex gnus-group-read-ephemeral-group +$B0l;~%K%e!<%9%0%k!<%W$r:n@.$7$^(B +$B$9(B (@code{gnus-group-read-ephemeral-group})$B!#(B Gnus $B$O%W%m%s%W%H$rI=<($7(B +$B$F!"L>A0!"J}K!$*$h$S(B @dfn{address} $B$NF~NO$r5a$a$^$9!#(B @item G n @kindex G n ($B%0%k!<%W(B) @findex gnus-group-make-shimbun-group @cindex making groups +@cindex emacs-w3m @cindex nnshimbun @cindex web newspaper $B?7$7$$(B @code{nnshimbun} $B%0%k!<%W$r:n@.$7$^(B $B$9(B (@code{gnus-group-make-shimbun-group})$B!#(Bgnus $B$O%W%m%s%W%H$rI=<($7$F!"(B $B%5!<%P!<$N%"%I%l%9$r<($9%7%s%\%kL>$H5-;v%0%k!<%WL>$NF~NO$r5a$a$F$-$^$9!#(B -@code{nnshimbun} $B$K4X$9$k>\:Y$O(B @pxref{Web Newspaper} $B$r;2>H$7$F2<$5$$!#(B +$B$3$l$r;H$&$K$O(B @uref{http://emacs-w3m.namazu.org/, emacs-w3m} $B$,I,MW$G$9!#(B +@code{nnshimbun} $B$K4X$9$k>\:Y(B +$B$O(B (@pxref{Nnshimbun, , Nnshimbun, emacs-w3m-ja, Emacs-w3m-ja}) $B$r;2>H$7(B +$B$F2<$5$$!#(B @item G r @kindex G r ($B%0%k!<%W(B) @@ -2612,7 +2658,7 @@ kiboze $B%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$GL>A0$H!"(Bkiboze $B%0%k!<%W$K!V4^$ @code{slack-digest}, @code{clari-briefs}, @code{nsmail}, @code{outlook}, @code{oe-dbx} $B$*$h$S(B @code{mailman} $B$G$9!#@\F,<-$J$7$G$3$N%3%^%s%I$rA0$H!"(Bkiboze $B%0%k!<%W$K!V4^$ @samp{shaving group:alt.sysadmin.recovery} $B$N$h$&$J9gCW$9$kJ8;zNs$rMQ$$(B $B$k$3$H$K$h$C$F!"8!:wBP>]$rFCDj$N%0%k!<%W$K8BDj$9$k$3$H$,2DG=$G$9!#(B +@item G R +@kindex G R ($B%0%k!<%W(B) +@findex gnus-group-make-rss-group +@acronym{RSS} feed $B$K4p$E$/%0%k!<%W$r:n$j$^(B +$B$9(B (@code{gnus-group-make-rss-group})$B!#(BURL $B$NF~NO$rB%$5$l$^$9!#(B +@xref{RSS}. + @item G DEL @kindex G DEL ($B%0%k!<%W(B) @findex gnus-group-delete-group @@ -2662,16 +2715,16 @@ kiboze $B%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$GL>A0$H!"(Bkiboze $B%0%k!<%W$K!V4^$ $B=>$$$^$9!#(B @end table -$B$5$^$6$^$JA*BrJ}K!$K4X$9$k$5$i$J$k>pJs$O(B @xref{Select Methods} $B$r;2>H$7(B -$B$F$/$@$5$$!#(B +$B$5$^$6$^$JA*BrJ}K!$K4X$9$k$5$i$J$k>pJs$O(B @ref{Select Methods} $B$r;2>H$7$F(B +$B2<$5$$!#(B @vindex gnus-activate-foreign-newsgroups $B$b$7(B @code{gnus-activate-foreign-newsgroups} $B$,@5$N?t$G$"$l$P!"(Bgnus $B$O5/(B $BF0;~$K!"$3$N?t$+$=$l$h$j$b>.$5$$%l%Y%k$N30It%0%k!<%W$rA4$F%A%'%C%/$7$^$9!#(B $B$3$l$OFC$K0c$C$?(B @acronym{NNTP} $B%5!<%P$+$i$?$/$5$s$N%0%k!<%W$r9XFI$7$F$$(B -$B$k>l9g$J$I!"$7$P$i$/;~4V$,$+$+$k$+$b$7$l$^$;$s!#(B@pxref{Group Levels} $B$b(B -$B;2>H$7$F2<$5$$!#(B@code{gnus-activate-level} $B$b30It%K%e!<%9%0%k!<%W$N3hF0(B -$B2=$K1F6A$r5Z$\$7$^$9!#(B +$B$k>l9g$J$I!"$7$P$i$/;~4V$,$+$+$k$+$b$7$l$^$;$s!#(B@ref{Group Levels} $B$b;2(B +$B>H$7$F2<$5$$!#(B@code{gnus-activate-level} $B$b30It%K%e!<%9%0%k!<%W$N3h@-2=(B +$B$K1F6A$r5Z$\$7$^$9!#(B @node Group Parameters @section $B%0%k!<%W%Q%i%a!<%?(B @@ -2737,9 +2790,6 @@ kiboze $B%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$GL>A0$H!"(Bkiboze $B%0%k!<%W$K!V4^$ $B<+F0E*$KIU2C$5$l$^$9!#(B @vindex gnus-add-to-list -$B$b$7(B @kbd{a} $B%3%^%s%I$r%a!<%k%0%k!<%W$GA0$H!"(Bkiboze $B%0%k!<%W$K!V4^$ @anchor{subscribed} @item subscribed @cindex subscribed +@cindex Mail-Followup-To +@findex gnus-find-subscribed-addresses $B$b$7$3$N%Q%i%a!<%?$,(B @code{t} $B$K@_Dj$5$l$F$$$k$H!"(Bgnus $B$O$"$J$?$,$3$N%0(B $B%k!<%W$r(B to-address $B$H(B to-list $B%Q%i%a!<%?$N%"%I%l%9$G9XFI$7$F$$$k%a!<%j(B $B%s%0%j%9%H$G$"$k$H2rpJs$r(B gnus $B$KM?$($k$3$H$O!"$"$J$?$,$=(B $B$l$i$N%a!<%j%s%0%j%9%H$KEj9F$9$k$H$-$K@5$7$$(B Mail-Followup-To $B%X%C%@!<$r(B -$B@8@.$9$k$?$a$N(B ($B$[$s$N(B) $BBh0lJb$G$9!#MxMQ$G$-$k(B MFT $BBP1~5!G=$r40A4$K07$&(B -$B$K$O!"$3$3(B @pxref{Mailing Lists, , Mailing Lists, message, The Message -Manual} $B$r8+$F2<$5$$!#(B +$B@8@.$9$k$?$a$N(B ($B$[$s$N(B) $BBh0lJb$G$9!#FsJbL\$O(B @file{.gnus.el} $B$K0J2<$rF~(B +$B$l$k$3$H$G$9!#(B + +@lisp +(setq message-subscribed-address-functions + '(gnus-find-subscribed-addresses)) +@end lisp -@code{gnus-find-subscribed-addresses} $B$b;2>H$7$F2<$5$$!#$3$N4X?t$O$3$N%0(B -$B%k!<%W%Q%i%a!<%?$rD>@\$K;H$$$^$9!#(B +$BMxMQ$G$-$k(B MFT $BBP1~5!G=$r40A4$K07$&$K$O!"$3$3(B (@pxref{Mailing Lists, , +Mailing Lists, message-ja, The Message Manual}) $B$r8+$F2<$5$$!#(B @item visible @cindex visible @@ -2795,15 +2851,17 @@ Manual} $B$r8+$F2<$5$$!#(B $B$7(B @code{(gcc-self . none)} $B$,$"$l$P!"(B@code{Gcc:} $BMs$O@8@.$5$l$:!"(B @code{(gcc-self . "string")} $B$,$"$l$P$3$NJ8;zNs$O$=$N$^$^(B @code{gcc} $BMs(B $B$KA^F~$5$l$^$9!#$3$N%Q%i%a!<%?$O0J2<$G@bL@$9$kA4$F$N(B @code{Gcc} $B$N=i4|5,(B -$BB'$h$j$bM%@h$5$l$^$9(B (@pxref{Archived Messages})$B!#7Y9p(B:: @code{nntp} $B%5!<(B -$B%P!<$J$I$N%0%k!<%W$G(B @code{(gcc-self . t)} $B$r@_Dj$9$k$H%(%i!<$r0z$-5/$3(B -$B$7$^$9!#$J$<$J$i(B @code{nntp} $B%5!<%P!<$O5-;v$rC5n$5$l$k$h$&$K0u$rIU$1$i$l$^$9!#B>$NJ}K!$O!"(B -@pxref{Expiring Mail}$B!#(B +@xref{Expiring Mail}. @code{gnus-auto-expirable-newsgroups} $B$b;2>H$7$F2<$5$$!#(B @@ -2826,6 +2884,11 @@ Manual} $B$r8+$F2<$5$$!#(B $B?t(B ($B@0?t$G$"$kI,MW$O$J$$(B) $B$+$b$7$/$O(B @code{never} $B$+(B @code{immediate} $B$N(B $B%7%s%\%k$r;XDj$G$-$^$9!#(B +@item expiry-target +@cindex expiry-target +$B;~8B>C5n$5$l$k%a%C%;!<%8$N2L$F$k>l=j!#$3$N%Q%l%a!<%?(B +$B$O(B @code{nnmail-expiry-target} $B$r>e=q$-$7$^$9!#(B + @item score-file @cindex score file group parameter @code{(score-file . "file")} $B$N$h$&$JMWAG$O!"(B@file{file} $B$r8=:_$N%0%k!<(B @@ -2949,10 +3012,10 @@ See also @code{gnus-group-ignored-charsets-alist}. $B$K(B @samp{fileinto "group.name";} $B$H$$$&%F%9%H>r7o$rK\BN$K;}$D!"(B Sieve $B$N(B @samp{IF} $B@)8f9=B$BN$,:n$i$l$^$9!#(B -$BNc$($P!"$b$7(B INBOX.list.sieve $B%0%k!<%W$,(B @code{(sieve address "sender" -"sieve-admin@@extundo.com")} $B$H$$$&%0%k!<%W%Q%i%a!<%?$r;}$C$F$$$?$J$i$P!"(B -$B%0%k!<%W%Q%i%a!<%?$r(B Sieve $B%9%/%j%W%H$KJQ49$9(B -$B$k(B (@pxref{Sieve Commands}) $B$H$-$K!"0J2<$N(B Sieve $B%3!<%I$,:n$i$l$^$9(B: +$BNc$($P!"$b$7(B @samp{INBOX.list.sieve} $B%0%k!<%W$,(B @code{(sieve address +"sender" "sieve-admin@@extundo.com")} $B$H$$$&%0%k!<%W%Q%i%a!<%?$r;}$C$F$$(B +$B$?$J$i$P!"%0%k!<%W%Q%i%a!<%?$r(B Sieve $B%9%/%j%W%H$KJQ49$9$k(B (@pxref{Sieve +Commands}) $B$H$-$K!"0J2<$N(B Sieve $B%3!<%I$,:n$i$l$^$9(B: @example if address \"sender\" \"sieve-admin@@extundo.com\" @{ @@ -2960,8 +3023,15 @@ if address \"sender\" \"sieve-admin@@extundo.com\" @{ @} @end example -Sieve $B8@8l$O(B RFC 3028 $B$G=R$Y$i$l$F$$$^$9!#(B@xref{Top, , Top, sieve, Emacs -Sieve}$B!#(B +Sieve $B8@8l$O(B RFC 3028 $B$G=R$Y$i$l$F$$$^(B +$B$9(B (@pxref{Top, Emacs Sieve, Top, sieve, Emacs Sieve})$B!#(B + +@item (agent parameters) +$B%(!<%8%'%s%H$r;H$&$h$&$K$7$F$"$k$H!"8D!9$N%0%k!<%W$G%(!<%8%'%s%H$N?6$kIq(B +$B$$$r@)8f$9$k$I$N%Q%i%a!<%?$b@_Dj$9$k$3$H$,$G$-$^$9!#%(!<%8%'%s%H%Q%i%a!<(B +$B%?$K$D$$$F$O(B @ref{Category Syntax} $B$r;2>H$7$F2<$5$$!#$?$$$F$$$N%f!<%6$O!"(B +$B@_Dj$KMW$9$k6lO+$r:G>.8B$K$9$k$?$a$K!"%(!<%8%'%s%H%+%F%4%j!<$+%0%k!<%W%H(B +$B%T%C%/$N$I$A$i$+$G%(!<%8%'%s%H%Q%i%a!<%?$r@_Dj$9$k$3$H$rA*$V$G$7$g$&!#(B @item (@var{variable} @var{form}) $B%0%k!<%W$KF~$k$H$-$K!"$=$N%0%k!<%W%m!<%+%k$NJQ?t$r@_Dj$9$k%0%k!<%W%Q%i%a!<(B @@ -2985,12 +3055,16 @@ form $B$N(B @code{nil} $B$O$=$3$GI>2A$5$l$^$9!#(B @vindex gnus-list-identifiers $B$3$N5!G=$NMQES$N0l$D$O!"5-;v$NBjL>Ms$+$i%a!<%j%s%0%j%9%H$NI8<1%?%0$r$O$.(B -$B$K(B @samp{DOC-BOOK-APPS:} $B$H$$$&%?%0$r;}$C$F$$$k$J$i$P!"$=$N%0%k!<%W(B -$B$N%0%k!<%W%Q%i%a!<%?$K(B @code{(gnus-list-identifiers "DOCBOOK-APPS:")} $B$r(B -$BF~$l$k$3$H$K$h$C$F!"$=$N%0%k!<%W$N35N,%P%C%U%!$KI=<($5$l$k5-;v$NBjL>$+$i(B -$B%?%0$r$O$.$K(B @samp{DOC-BOOK-APPS:} $B$H$$$&%?%0$r;}$C$F$$$k$J(B +$B$i$P!"$=$N%0%k!<%W$N%0%k!<%W%Q%i%a!<%?$K(B @code{(gnus-list-identifiers +"DOCBOOK-APPS:")} $B$rF~$l$k$3$H$K$h$C$F!"$=$N%0%k!<%W$N35N,%P%C%U%!$KI=<((B +$B$5$l$k5-;v$NBjL>$+$i%?%0$r$O$.pJs$O(B @xref{Sorting Groups} $B$r;2(B -$B>H$7$F$/$@$5$$!#(B +$B$9!#%0%k!<%W$N%=!<%H$K$D$$$F$N$5$i$J$k>pJs$O(B @ref{Sorting Groups} $B$r;2>H(B +$B$7$F2<$5$$!#(B @node Topic Topology @subsection $B%H%T%C%/$N0LAj9=B$(B @@ -3883,7 +3959,10 @@ Gnus $B%H%T%C%/Fb$NA4$F$N%0%k!<%W$O%0%k!<%W%Q%i%a!<%?$r!"$=$N?F(B ($B$H@hAD(B) $B$N%H%T%C(B $B%/%Q%i%a!<%?$+$i7Q>5$7$^$9!#%0%k!<%W%Q%i%a!<%?$H$7$F@5$7$$$b$N$OA4$F!"%H(B -$B%T%C%/%Q%i%a!<%?$H$7$F$b@5$7$$$b$N$G$9(B(@pxref{Group Parameters})$B!#(B +$B%T%C%/%Q%i%a!<%?$H$7$F$b@5$7$$$b$N$G$9(B(@pxref{Group Parameters})$B!#%(!<%8%'(B +$B%s%H$r;H$&$h$&$K$7$F$"$k$H!"$9$Y$F$N%(!<%8%'%s%H%Q%i%a!<%?(B (@ref{Category +Syntax} $B$N(B Agent Parameters $B$r;2>H(B ($BLuCm(B: $BI,MW$J$i(B Index $B$r;H$C$F(B)) $B$OM-(B +$B8z$J%H%T%C%/%Q%i%a!<%?$G$b$"$j$^$9!#(B $B$5$i$K!"0J2<$N%Q%i%a!<%?$O%H%T%C%/%Q%i%a!<%?$H$7$F$N$_M-8z$G$9(B: @@ -3908,6 +3987,7 @@ Gnus $B$k$+$bCN$l$J$$$1$I!"$=$l$O$4<+M3$K(B)$B!#(B @example +@group Gnus Emacs 3: comp.emacs @@ -3920,6 +4000,7 @@ Gnus 8: comp.binaries.fractals 13: comp.sources.unix 452: alt.sex.emacs +@end group @end example @samp{Emacs} $B%H%T%C%/$O%H%T%C%/%Q%i%a!<(B @@ -3964,7 +4045,7 @@ Gnus @kindex ^ ($B%0%k!<%W(B) @findex gnus-group-enter-server-mode $B%5!<%P%P%C%U%!%b!<%I$KF~$k(B (@code{gnus-group-enter-server-mode})$B!#(B -@xref{Server Buffer}$B!#(B +@xref{Server Buffer}. @item a @kindex a ($B%0%k!<%W(B) @@ -3974,7 +4055,7 @@ Gnus $B%W$KEj9F$7$^$9!#$b$7@\F,<-$,(B 1 $B$@$C$?$i!"$I$N%0%k!<%W$KEj9F$9$k$+$r?R$M(B $B$^$9!#$3$N4X?t$NL>A0$+$iO"A[$5$l$k$3$H$H$ON"J"$K!"@\F,<-$G%a!<%k%0%k!<%W(B $B$,;XDj$5$l$?>l9g$O!"%K%e!<%9$NBe$o$j$K%a!<%k$NMM<0$,MQ0U$5$l$^$9!#(B -@xref{Composing Messages}$B!#(B +@xref{Composing Messages}. @item m @kindex m ($B%0%k!<%W(B) @@ -3982,14 +4063,14 @@ Gnus $B%a!<%k$r$I$3$+$KAw$j$^$9(B (@code{gnus-group-mail})$B!#$b$7@\F,<-$,M?$($i$l(B $B$?$i8=:_0LCV$N%0%k!<%W$NEj9FMM<0(B (posting style) $B$r;H$$$^$9!#$b$7@\F,<-(B $B$,(B 1 $B$@$C$?$i!"$I$N%0%k!<%W$NEj9FMM<0$r;H$&$+$r?R$M$^$9!#(B -@xref{Composing Messages}$B!#(B +@xref{Composing Messages}. @item i @kindex i ($B%0%k!<%W(B) @findex gnus-group-news $B%K%e!<%9$N:n@.$r3+;O$7$^$9(B (@code{gnus-group-news})$B!#$b$7@\F,<-$,M?$($i(B $B$l$?$i8=:_0LCV$N%0%k!<%W$KEj9F$7$^$9!#$b$7@\F,<-$,(B 1 $B$@$C$?$i!"$I$N%0%k!<(B -$B%W$KEj9F$9$k$+$r?R$M$^$9!#(B@xref{Composing Messages}$B!#(B +$B%W$KEj9F$9$k$+$r?R$M$^$9!#(B@xref{Composing Messages}. $B$3$N4X?t$O!"$?$H$(%a!<%k%0%k!<%W$G;H$o$l$?$H$7$F$b!"l=j$K0\F0(B $B$7$^$9!#(B($B$b$A$m$s!"$3$NF0:n$rJQ$($k$3$H$,$G$-$J$$$H$7$?$i(B Gnus $B$K$O$"$k(B $B$^$8$-$3$H$G$9!#4X?t(B @code{gnus-goto-colon} $B$r!"$"$J$?$,9%$-$J%+!<%=%k$N(B -$BF0$-$K$J$k$h$&$K!"?7$?$K=q$1$PNI$$$N$G$9!#(B) @xref{Positioning Point}$B!#(B +$BF0$-$K$J$k$h$&$K!"?7$?$K=q$1$PNI$$$N$G$9!#(B) @xref{Positioning Point}. $B=i4|CM$NJ8;zNs$O(B @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n} $B$G$9!#(B @@ -4442,7 +4523,7 @@ Gnus $B$OJQ?t(B @code{gnus-extract-address-components} $B$NCM$r(B @code{From $B5-;v?t!#(B @item S $BI=Bj$NJ8;zNs!#(B@code{gnus-list-identifiers} $B$N@_Dj$K$h$C$F%a!<%j%s%0%j%9(B -$B%H$NI8<1$,:o=|$5$l$^$9!#(B@xref{Article Hiding}$B!#(B +$B%H$NI8<1$,:o=|$5$l$^$9!#(B@xref{Article Hiding}. @item s $B%9%l%C%I(B (thread) $B$N4p5-;v$G$"$k$H$-$+D>A0$N5-;v$,0c$&I=Bj$N$H$-$O$=$NBj(B $BL>$G!"$=$l0J30$O(B @code{gnus-summary-same-subject}$B!#(B @@ -4534,12 +4615,12 @@ Gnus $B$OJQ?t(B @code{gnus-extract-address-components} $B$NCM$r(B @code{From @item < $BFs==0z$/%9%l%C%I%l%Y%k$N6uGr!#(B @item U -$BL$FI!#(B@xref{Read Articles}$B!#(B +$BL$FI!#(B@xref{Read Articles}. @item R $B$3$NJ6$i$o$7$$L>A0;XDj;R$O(B @dfn{secondary mark} $B$K$h$C$FDj5A$5$l$^$9!#$3(B $B$N%^!<%/$O5-;v$,4{$KJVEz:Q$_$N$b$N$+!"%-%c%C%7%e$5$l$?$b$N$+!"$"$k$$$OJ](B -$BB8$5$l$?$b$N$+$rI=$7$^$9!#(B@xref{Other Marks}$B!#(B +$BB8$5$l$?$b$N$+$rI=$7$^$9!#(B@xref{Other Marks}. @item i $B?t;z$H$7$F$N%9%3%"(B (@pxref{Scoring})$B!#(B @@ -4579,8 +4660,8 @@ Gnus $B$OJQ?t(B @code{gnus-extract-address-components} $B$NCM$r(B @code{From @item u $BMxMQ$N35N,;XDj$HF1MM$K35N,$KA^F~(B $B$5$l$^$9!#(B @end table @@ -4820,7 +4901,7 @@ Gnus $B$,H$7$F$/$@$5$$!#(B +$B%k!<%W$K0\$j$^$9!#(B@ref{Group Levels} $B$b;2>H$7$F$/$@$5$$!#(B @item gnus-auto-select-same @vindex gnus-auto-select-same @@ -4874,7 +4955,7 @@ Summary Buffer} $B$r;2>H$7$F2<$5$$!#(B $B$9$G$K5-;v%&%#%s%I%&$r3+$$$F$$$k$H$-$K:FEY(B @kbd{SPACE} $B$r2!$9$H!"$=$N5-(B $B;v$O%9%/%m!<%k$5$l$^$9!#%K%e!<%9%0%k!<%WA4BN$r(B @kbd{SPACE} $B$GJXMx$KDLFI(B -$B$G$-$^$9!#(B@pxref{Paging the Article}$B!#(B +$B$G$-$^$9!#(B@xref{Paging the Article}. @item G n @itemx n @@ -4947,7 +5028,7 @@ Summary Buffer} $B$r;2>H$7$F2<$5$$!#(B @kbd{l} $B$,:G=*Fs$D$N5-;v$N4V$r0\F0$9$k$N$KBP$7$F!"$3$l$O9%$-$J$@$1A0$N5-(B $B;v$rMzNr$+$iA*$S=P$9$3$H$,$G$-$kE@$G$9!#2?$i$+$N$3$l$K4X78$7$?$3$H(B $B$O(B ($B$b$7$3$l$i$NL?Na$r$?$/$5$s;H$&$N$G$"$l$P(B)$B!"(B -@pxref{Article Backlog} $B$r;2>H$7$F$/$@$5$$!#(B +@ref{Article Backlog} $B$r;2>H$7$F$/$@$5$$!#(B @item G j @item j @@ -5087,7 +5168,7 @@ Summary Buffer} $B$r;2>H$7$F2<$5$$!#(B * Summary Mail Commands:: $B%a!<%k$rAw$k(B * Summary Post Commands:: $B%K%e!<%9$rAw$k(B * Summary Message Commands:: $BB>$N%a%C%;!<%84XO"$NL?Na(B -* Canceling and Superseding:: +* Canceling and Superseding:: @end menu @node Summary Mail Commands @@ -5123,7 +5204,8 @@ Summary Buffer} $B$r;2>H$7$F2<$5$$!#(B $B8=:_$N5-;v$r=q$$$??M$KBP$7$F!"9-$$JVEz(B (wide reply) $B$r$7$^(B $B$9(B (@code{gnus-summary-wide-reply})$B!#(B@dfn{$B9-$$JVEz(B} $B$H$O%X%C%@!<(B $B$N(B @code{To}, @code{From}, ($B$b$7$/$O(B @code{Reply-to}) $B$H(B @code{Cc}) $B$N$9(B -$B$Y$F$N?M$KJVEz$r$9$k$3$H$G$9!#(B +$B$Y$F$N?M$KJVEz$r$9$k$3$H$G$9!#(B@code{Mail-Followup-To} $B$,$"$l$P!"Be$o$j$K(B +$B$=$l$,;H$o$l$^$9!#(B @item S W @kindex S W ($B35N,(B) @@ -5155,7 +5237,7 @@ Summary Buffer} $B$r;2>H$7$F2<$5$$!#(B $BL5;k$7$^$9(B (@code{gnus-summary-reply-broken-reply-to})$B!#%a!<%j%s%0%j%9%H(B $B$,$=$N%j%9%H$r;X$9(B @code{Reply-To} $B$r2a$C$F@_Dj$9$k$?$a$K$3$l$,I,MW$J$N(B $B$G$"$l$P!"$"$J$?$O$?$V$sBe$o$j$K(B @code{broken-reply-to} $B%0%k!<%W%Q%i%a!<(B -$B%?$r@_Dj$7$?$$$H;W$$!"$=$l$OF0:n$9$k$G$7$g$&!#(B +$B%?$r@_Dj$9$kI,MW$,$"$j!"$=$l$OF0:n$9$k$G$7$g$&!#(B @item S B R @kindex S B R ($B35N,(B) @@ -5223,13 +5305,12 @@ gnus $B$O$=$N%a!<%k$r7$/$G$7$g$&!#$G$9$+$i!"$b$A$m$s!"K\Ev(B $B$K(B $BAw$7$?$$$H$-$KMQ$$$i$l$^$9!#(B -($B$b$7$"$J$?$,!"(B@code{$B%k!<%H(B} (root) $B$G$"$j!"(B -@code{$B%]%9%H%^%9%?!<(B} (postmaster) $B$G$b$"$j!"(B@code{$B%k!<%H(B} $B$K(B @code{$B%]%9(B -$B%H%^%9%?!<(B} $B$X$N%a!<%k$rl9g$O!"$=$l(B -$B$r(B @code{$B%]%9%H%^%9%?!<(B} $B$K$b:FAw$7$?$$$H;W$&$G$7$g(B -$B$&!#(BOrdnung muss sein!) +$B$3$NL?Na$OAw$7$?$$$H$-$KMQ$$$i$l$^$9!#(B($B$b$7$"$J$?(B +$B$,(B @code{root} $B$G$"$j!"(B@code{postmaster} $B$G$b$"$j!"(B +@code{root} $B$K(B @code{postmaster} $B$X$N%a!<%k$rl9g$O!"$=$l(B +$B$r(B @code{postmaster} $B$K$b:FAw$9$kI,MW$,$"$k$7$g$&!#Ca=x$,$J$1$l$P$J$j$^(B +$B$;$s(B! (Ordnung muss sein!)) $B$3$NL?Na$O%W%m%;%9(B/$B@\F,0z?t$N=,47$K=>$$$^$9(B (@pxref{Process/Prefix})$B!#(B @@ -5382,6 +5463,10 @@ Gnus $B$O!"C$9$H$-$K!X8=:_!Y$NA*BrJ}K!$r;H$$$^$9!#I8=`$NEj9FJ}K!$r;H(B $B$$$?$$$N$G$"$l$P!"J8;z@\F,0z?t(B @samp{a} $B$r;H$C$F$/$@$5(B $B$$(B (@pxref{Symbolic Prefixes})$B!#(B +Gnus $B$O(B @code{Cancel-Lock} $B%X%C%@!<(B (@pxref{Canceling News, Canceling +News, , message, Message Manual}) $B$r;H$C$F!"$"$J$?$@$1$,$"$J$?$N%a%C%;!<(B +$B%8$r%-%c%s%;%k$G$-$k$3$H$rJ]>Z$7$^$9!#(B + $B$b$72?$+4V0c$$$r$7$?$N$K5$IU$$$F!"D{@5$r$7$?$$$N$G$"$l$P!"(B @dfn{$BBeBX(B} (@dfn{superseding}) $B5-;v$rEj9F$7$FK\5-;v$rCV$-49$($k$3$H$,$G(B $B$-$^$9!#(B @@ -5433,8 +5518,8 @@ Gnus $B$O!"C$9$H$-$K!X8=:_!Y$NA*BrJ}K!$r;H$$$^$9!#I8=`$NEj9FJ}K!$r;H(B @code{d} ($BF|(B), @code{w} ($B=5(B), @code{M} ($B7n(B) $B$*$h$S(B @code{Y} ($BG/(B) $B$G$9!#(B @item -$BF|IU!#(B@code{YYYYY-MM-DD} $B$N$h$&$J7A<0$G;XDj$7$^$9!#!#%a%C%;!<%8$NAw?.$O(B -$B$=$NF|$NFCDj$N;~9o(B ($B%G%#%U%)%k%H$O(B 8 $B;~(B) $B$^$GCY$i$;$i$l$^$9!#(B +$BF|IU!#(B@code{YYYY-MM-DD} $B$N$h$&$J7A<0$G;XDj$7$^$9!#!#%a%C%;!<%8$NAw?.$O$=(B +$B$NF|$NFCDj$N;~9o(B ($B%G%#%U%)%k%H$O(B 8 $B;~(B) $B$^$GCY$i$;$i$l$^$9!#(B @code{gnus-delay-default-hour} $B$b;2>H$7$F2<$5$$!#(B @item @@ -5687,7 +5772,7 @@ gnus $B<+BN$O2D;k5-;v$r4|8B@Z$l>C5n$7$^$;$s(B) $B$N$G!"1J1s$K5-;v$rJ]B8$7$F$* @item @vindex gnus-downloaded-mark -gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$r;H$C$F$$$k$H$-!"5-;v(B +gnus $B%(!<%8%'%s%H(B (@pxref{Agent Basics}) $B$r;H$C$F$$$k$H$-!"5-;v(B $B$O(B unplugged ($B%*%U%i%$%s(B) $B$G8+$k$?$a$K%@%&%s%m!<%I$5$l$F$$$k$+$b$7$l$^$;(B $B$s!#(B@samp{%O} $B$N;EMM$r;H$C$F$$$k$H!"$=$l$i$N5-;v$K$O$=$N;EMM(B $B$K(B @samp{+} $B$N0u$,IU$-$^$9!#(B($BJQ?t(B @code{gnus-downloaded-mark} $B$G$I$NJ8;z(B @@ -5695,18 +5780,18 @@ gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$r;H$C$F$$$k$H$-!"5-;v(B @item @vindex gnus-undownloaded-mark -gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$r;H$C$F$$$k$H$-!"$$$/$D$+$N5-;v(B -$B$O%@%&%s%m!<%I$5$l$F$$$J$$$+$b$7$l$^$;$s!#(BUnplugged ($B%*%U%i%$%s(B) $B$N>uBV(B -$B$G$O$=$N$h$&$J5-;v$r8+$k$3$H$,$G$-$^$;$s!#(B@samp{%O} $B$N;EMM$r;H$C$F$$$k$H!"(B -$B$=$l$i$N5-;v$K$O$=$N;EMM$K(B @samp{-} $B$N0u$,IU$-$^$9!#(B($BJQ(B +gnus $B%(!<%8%'%s%H(B (@pxref{Agent Basics}) $B$r;H$C$F$$$k$H$-!"$$$/$D$+$N5-(B +$B;v$O%@%&%s%m!<%I$5$l$F$$$J$$$+$b$7$l$^$;$s!#(BUnplugged ($B%*%U%i%$%s(B) $B$N>u(B +$BBV$G$O$=$N$h$&$J5-;v$r8+$k$3$H$,$G$-$^$;$s!#(B@samp{%O} $B$N;EMM$r;H$C$F$$$k(B +$B$H!"$=$l$i$N5-;v$K$O$=$N;EMM$K(B @samp{-} $B$N0u$,IU$-$^$9!#(B($BJQ(B $B?t(B @code{gnus-undownloaded-mark} $B$G$I$NJ8;z$r;H$&$+$r@)8f$7$^$9!#(B) @item @vindex gnus-downloadable-mark -gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&%s(B -$B%m!<%I$7$^$9$,!"<+F0E*$K%@%&%s%m!<%I$5$l$J$$5-;v$K$b%@%&%s%m!<%I$N$?$a$N(B -$BL@<(E*$J0u$rIU$1$k$3$H$O2DG=$G$9!#$=$N$h$&$JL@<(E*$K0u$,IU$1$i$l$?5-;v$K(B -$B$O!":G=i$N7e$K(B @samp{%} $B$N0u$,IU$-$^$9!#(B($BJQ(B +gnus $B%(!<%8%'%s%H(B (@pxref{Agent Basics}) $B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&(B +$B%s%m!<%I$7$^$9$,!"<+F0E*$K%@%&%s%m!<%I$5$l$J$$5-;v$K$b%@%&%s%m!<%I$N$?$a(B +$B$NL@<(E*$J0u$rIU$1$k$3$H$O2DG=$G$9!#$=$N$h$&$JL@<(E*$K0u$,IU$1$i$l$?5-;v(B +$B$K$O!":G=i$N7e$K(B @samp{%} $B$N0u$,IU$-$^$9!#(B($BJQ(B $B?t(B @code{gnus-downloadable-mark} $B$G$I$NJ8;z$r;H$&$+$r@)8f$7$^$9!#(B) @item @@ -5912,7 +5997,7 @@ gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&%s $B%W%m%;%90u$O35N,%P%C%U%!!<$K(B @code{#} $B$H$7$FI=<($5$l!"B>$N%3%^%s%I$G=hM}(B $B$5$;$k5-;v$K0u$rIU$1$k$?$a$K;H$o$l$^$9!#Nc$($P!";M$D$N5-;v$K$K0u$rIU$1$F(B $B$+$i(B @kbd{*} $B%3%^%s%I$r;H$&$H!"(Bgnus $B$O$=$l$i;M$D$N5-;v$r%-%c%C%7%e$KF~$l(B -$B$^$9!#>\$7$/$O(B @pxref{Process/Prefix} $B$r$I$&$>!#(B +$B$^$9!#>\$7$/$O(B @ref{Process/Prefix} $B$r$I$&$>!#(B @table @kbd @item M P p @@ -6025,7 +6110,7 @@ gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&%s @end table $B$=$7$F!"$I$&$d$C$F5-;v$NK\J8(B (body) $B$NFbMF$r4p$K%W%m%;%90u$rIU$1$k$+$O!"(B -@pxref{Searching for Articles} $B$N(B @kbd{&} $BL?Na$r;2>H$7$F2<$5$$!#(B +@ref{Searching for Articles} $B$N(B @kbd{&} $BL?Na$r;2>H$7$F2<$5$$!#(B @node Limiting @section $B@)8B$r$9$k(B @@ -6115,7 +6200,7 @@ gnus $B%(!<%8%'%s%H(B @pxref{Agent Basics} $B$O$$$/$D$+$N5-;v$r<+F0E*$K%@%&%s @findex gnus-summary-limit-to-display-predicate $B35N,%P%C%U%!$r(B @code{display} $B%0%k!<%W%Q%i%a!<%?$N=R8l$rK~B-$5$;$k$h$&$K(B $B@)8B$7$^$9(B (@code{gnus-summary-limit-to-display-predicate})$B!#$3$N=R8l$K(B -$B4X$9$k>\:Y$O(B @pxref{Group Parameters} $B$r;2>H$7$F2<$5$$!#(B +$B4X$9$k>\:Y$O(B @ref{Group Parameters} $B$r;2>H$7$F2<$5$$!#(B @item / E @itemx M S @@ -6192,8 +6277,8 @@ Gnus $B$O=i4|@_Dj$G5-;v$r%9%l%C%I$K$7$^$9!#(B@dfn{$B%9%l%C%I$K$9$k(B} $B$H$ $B$K!"(B@code{References} $BMs$O$7$P$7$P2u$l$F$$$k$+!";~$K$OC1$K$J$$$H$$$&$3$H(B $B$,$"$j$^$9!#IT;W5D$J%K%e!<%9$NA}?#$,LdBj$rA}$d$7$^$9$N$G!"4n$P$7$$7k2L$r(B $BF@$k$?$a$K$OB>$NH/8+K!$r:NMQ$7$J$1$l$P$J$j$^$;$s!#2a>j$JBP:vK!$OB8:_$7$F(B -$B$$$F!"$=$N62$k$Y$->\:Y$O(B @pxref{Customizing Threading} $B$K>\$7$/=q$$$F$"(B -$B$j$^$9!#(B +$B$$$F!"$=$N62$k$Y$->\:Y$O(B @ref{Customizing Threading} $B$K>\$7$/=q$$$F$"$j(B +$B$^$9!#(B $B$^$:!"35G0$N354Q$G$9(B: @@ -6283,7 +6368,7 @@ Gnus $B$O?F$N$U$j$r$9$k$_$;$+$1$N35N,9T$r$D$/$j$^$9!#$_$;$+$1$N9T$O$I$NK\(B $B:G=i$NK\Ev$N5-;v$rA*Br$r$9$k$@$1$K$J$j$^$9!#$_$;$+$1$N:,K\$NMM<0$r;XDj(B $B$9$k$?$a$K!"(B@code{gnus-summary-dummy-line-format} $B$,;H$o$l$^$9!#$3$l$O$?$C(B $B$?0l$D$@$1$N%U%)!<%^%C%H$N;EMM$rl9g$O!"(B @code{gnus-summary-make-false-root-always} $B$r(B @code{t} $B$K@_Dj$7$F2<$5$$!#(B @@ -6708,7 +6793,8 @@ gnus $B$OA4$F$N5-;v$N40A4$J(B @code{References} $BMs$r8+$F!"F1$8%9%l%C%I$KB0$ @findex gnus-thread-sort-by-number @findex gnus-thread-sort-by-random @vindex gnus-thread-sort-functions -@findex gnus-thread-sort-by-most-recent-thread +@findex gnus-thread-sort-by-most-recent-number +@findex gnus-thread-sort-by-most-recent-date $B$b$7%9%l%C%I$N35N,I=<($r;H$C$F$$$k$N$G$"$l$P!"(B @code{gnus-thread-sort-functions} $B$r@_Dj$9$k$3$H$G%9%l%C%I$rJB$SBX$($k$3(B $B$H$,$G$-$^$9!#$=$l$O!"C1FH$N4X?t!"4X?t$N%j%9%H!"4X?t$H(B @code{($B4X?t$G$J$$(B @@ -7257,8 +7343,8 @@ gnus $B$,J]B8$9$k5-;v$N(B @code{Archive-name} $B9T$rD4$Y$F!"$=$l$r%U%!%$%kL>$ $B$3$l$O%U%!%$%kL>$r>/$7$-$l$$$K$9$k4X?t$NNc$G$9!#(B @samp{nnml:mail.whatever} $B$N$h$&$J%a!<%k%0%k!<%W$,$?$/$5$s$"$k$N$G$"$l$P!"(B -$BJ]B8$9$k$?$a$N%U%!%$%kL>$r:n$kA0$K$3$l$i$N%0%k!<%WL>$N:G=i$r@Z$jMn$H$7$?(B -$B$$$+$b$7$l$^$;$s!#$r:n$kA0$K$3$l$i$N%0%k!<%WL>$N:G=i$r@Z$jMn$H$9I,(B +$BMW$,$"$k$+$b$7$l$^$;$s!#H$7$F2<$5$$!#(B +$B5-;v$r<+F0E*$K%U%)%s$HJQ99$5$;$k$?$a$K$O(B @ref{Customizing Articles} $B$r;2(B +$B>H$7$F2<$5$$!#(B @node Article Hiding @subsection $B5-;v$r1#$9(B @@ -8028,9 +8114,9 @@ Gnus $B$O$I$3$N0zMQJ8$,1#$5$l$F$$$k$+$r<($9$?$a$K%\%?%s$rIU$12C$(!"J8>O$N(B $B$($l$P!"$=$l$i$O>o$K1#$7$^$9!#(B $B0zMQ%+%9%?%^%$%:$N$?$a$NB>$NJQ?t$N>pJs$N$?$a(B -$B$K(B @pxref{Article Highlighting} $B$b;2>H$7$F$/$@$5$$!#(B +$B$K(B @ref{Article Highlighting} $B$b;2>H$7$F$/$@$5$$!#(B -$B<+F0E*$K5-;v$NMWAG$r1#$9$?$a$NJ}K!$O(B @xref{Customizing Articles} $B$r;2>H(B +$B<+F0E*$K5-;v$NMWAG$r1#$9$?$a$NJ}K!$O(B @ref{Customizing Articles} $B$r;2>H(B $B$7$F2<$5$$!#(B @node Article Washing @@ -8047,7 +8133,7 @@ Gnus $B$O$I$3$N0zMQJ8$,1#$5$l$F$$$k$+$r<($9$?$a$K%\%?%s$rIU$12C$(!"J8>O$N(B $B$?$V$s!#(B gnus $B$,5-;v$rI=<($9$k4{Dj$N$d$jJ}$rJQ$($?$$$H$-(B -$B$O(B @xref{Customizing Articles} $B$r;2>H$7$F2<$5$$!#(B +$B$O(B @ref{Customizing Articles} $B$r;2>H$7$F2<$5$$!#(B @table @kbd @item C-u g @@ -8065,7 +8151,7 @@ gnus $B$,5-;v$rI=<($9$k4{Dj$N$d$jJ}$rJQ$($?$$$H$-(B @findex gnus-summary-stop-page-breaking $B%Z!<%8$N6h@Z$j$r8=:_$N5-;v$+$iH$7$F2<$5$$!#(B +$B$O(B @ref{Misc Article} $B$r;2>H$7$F2<$5$$!#(B @item W r @kindex W r ($B35N,(B) @@ -8131,8 +8217,9 @@ Sm*rtq**t*s $B$O$b$C$HB?$/$N0zMQJ8;z$rDs6!$9$k$?$a$K!"%^"#"#"#%="#"#$,>!H(B -$B$7$F2<$5$$!#(B +$B5-;v$N@vBu$r<+F0E*$K$9$k$?$a$NJ}K!$O(B @ref{Customizing Articles} $B$r;2>H$7(B +$B$F2<$5$$!#(B @node Article Header @subsection $B5-;v%X%C%@!<(B @@ -8515,8 +8602,8 @@ Archive Network) $B%"!<%+%$%V$N%G%#%l%/%H%j$G$9!#(B $B%^%&%9$N%+!<%=%k$,%\%?%s$N>e$K$"$k$H$-$K;H$o$l$k%U%'%$%9$G$9!#(B @end table -$B5-;v$r<+F0E*$K%\%?%s2=$9$kJ}K!$O(B @xref{Customizing Articles} $B$r;2>H$7$F(B -$B2<$5$$!#(B +$B5-;v$r<+F0E*$K%\%?%s2=$9$kJ}K!$O(B @ref{Customizing Articles} $B$r;2>H$7$F2<(B +$B$5$$!#(B @node Article Button Levels @subsection Article button levels @@ -8661,8 +8748,8 @@ gnus $B$G%a!<%k$rFI$`$3$H$NM-Mx$JE@$O!"C1=c$J%P%0$rAG@2$i$7$$IT>rM}$KCV$-(B $B$G$9!#;d$,?.MQ$G$-$^$;$s$+(B? *$B$/$9$/$9(B($B>P(B)* @end table -$B<+F0E*$K9%$`=q<0$GF|IU$rI=<($9$kJ}K!$O(B @xref{Customizing Articles} $B$r;2(B -$B>H$7$F2<$5$$!#(B +$B<+F0E*$K9%$`=q<0$GF|IU$rI=<($9$kJ}K!$O(B @ref{Customizing Articles} $B$r;2>H(B +$B$7$F2<$5$$!#(B @node Article Display @subsection Article Display @@ -8676,12 +8763,15 @@ gnus $B$G%a!<%k$rFI$`$3$H$NM-Mx$JE@$O!"C1=c$J%P%0$rAG@2$i$7$$IT>rM}$KCV$-(B @code{X-Face} $B%X%C%@!<$O>.$5$JGr9u2hA|$G!"%a%C%;!<%8%X%C%@!<$+$i6!5k$5$l(B $B$^$9(B (@pxref{X-Face})$B!#(B -$B0lJ}(B Picon $B$O$"$J$?<+?H$N%7%9%F%`$K0MB8$7!"(Bgnus $B$O%X%C%@!<$K%^%C%A$9$k$"(B -$B$J$?$N;}$AJ*$rC5$7$F$_$^$9(B (@pxref{Picons})$B!#(B +@code{Face} $B%X%C%@!<$O>.$5$J%+%i!<2hA|$G!"%a%C%;!<%8%X%C%@!<$+$i6!5k$5$l(B +$B$^$9(B (@pxref{Face})$B!#(B $B%9%^%$%j!<$O!"?M!9$,%a%C%;!<%8$K;6$i$+$7$?$,$k>.$5$J(B @samp{:-)} $B%7%s%\%k(B $B$G$9!#(B +$B0lJ}(B Picon $B$O$"$J$?<+?H$N%7%9%F%`$K0MB8$7!"(Bgnus $B$O%X%C%@!<$K%^%C%A$9$k$"(B +$B$J$?$N;}$AJ*$rC5$7$F$_$^$9(B (@pxref{Picons})$B!#(B + $B$3$l$i$9$Y$F$N5!G=$O%H%0%k$G$9!#$b$7$9$G$K$=$l$i$,B8:_$7$F$$$?$J$i$P!"$=(B $B$l$i$O:o=|$5$l$^$9!#(B @@ -8964,11 +9054,10 @@ gnus $B$G%a!<%k$rFI$`$3$H$NM-Mx$JE@$O!"C1=c$J%P%0$rAG@2$i$7$$IT>rM}$KCV$-(B $B$[$H$s$I$N%a!<%k%P%C%/%(%s%I$O(B @code{Message-ID} $B$G$N$N$b$N$O;~4V$,$+$+$j$9$.$^$9!#(B) @code{nnmh} $B$G$OA4$/IT2DG=(B -$B$G$9!#(B +@code{nnbabyl}, @code{nnmaildir} $B$*$h$S(B @code{nnml} $B$O$I$N%0%k!<%W$+$i$N(B +$B5-;v$b0LCV$rF@$k$3$H$,$G$-$^$9$,!"(B@code{nnfolder} $B$H(B @code{nnimap} $B$O8=(B +$B:_$N%0%k!<%W$KEj9F$7$?5-;v$N0LCV$7$+F@$k;v$,$G$-$^$;$s!#(B($B$=$NB>$N$b$N$O(B +$B;~4V$,$+$+$j$9$.$^$9!#(B) @code{nnmh} $B$G$OA4$/IT2DG=$G$9!#(B @node Alternative Approaches @section $BBeBXpJs;X8~$NL?Na(B * Searching for Articles:: $BJ#?t5-;vL?Na(B -* Summary Generation Commands:: +* Summary Generation Commands:: * Really Various Summary Commands:: $B$"$N$d$C$+$$$JB>$KE,9g$7$J$$L?Na(B @end menu @@ -9472,7 +9561,7 @@ Gnus $B$,F1$8(B @code{Message-ID} $B$r;}$DFs$D$N5-;v$rH/8+$7$?$H$-$O!"2?$+;W$ @item H f @kindex H f ($B35N,(B) @findex gnus-summary-fetch-faq -@vindex gnus-grou-faq-directory +@vindex gnus-group-faq-directory $B8=:_$N%0%k!<%W$N(B @acronym{FAQ} (frequently asked questions ($BIQHK$K$5$l$k(B $B$7$^(B $B$9(B (@code{gnus-summary-reselect-current-group})$B!#$b$7@\F,0z?t$rM?$($i$l(B @@ -9745,9 +9838,9 @@ Parameters}) $B$rJT=8$7$^$9(B (@code{gnus-summary-edit-parameters})$B!#(B $B>eFI$^$J$$$G$9$`$H$$$&;v$rJ]>Z$7$^$9!#$b$A$m$s!"$@$l$+$,$=$l$r$$$/$D$+$N(B $B%0%k!<%W$KJL!9$KEj9F$7$J$$8B$j$O!#F1$85-;v$r$$$/$D$+$N%0%k!<%W$KEj9F$9$k(B $B;v(B ($BAj8_Ej9F$G$J$/$F(B) $B$O(B @dfn{spamming} $B$H8F$P$l!"$"$J$?$O$=$N$h$&$JA~$`(B -$B$Y$-HH:a$r9T$&$b$N$K$KBP$7$F!"K!N'$K$h$C$FIT2w$J5-;v$rAw$k$3$H$,5AL3$E$1(B -$B$i$l$F$$$^$9!#(Bspam $B$rA*JL$9$k$?$a$K!"(BNoCeM $BH$7$F$/$@$5$$!#(B +$BBeBXH$7$F$/$@$5$$!#(B @node Duplicate Suppression @section $B=EJ#$NM^@)(B @@ -9889,13 +9982,13 @@ manual (@pxref{Security, ,Security, message, Message Manual}). @vindex mm-verify-option Option of verifying signed parts. @code{never}, not verify; @code{always}, always verify; @code{known}, only verify known -protocols. Otherwise, ask user. +protocols. Otherwise, ask user. @item mm-decrypt-option @vindex mm-decrypt-option Option of decrypting encrypted parts. @code{never}, no decryption; @code{always}, always decrypt; @code{known}, only decrypt known -protocols. Otherwise, ask user. +protocols. Otherwise, ask user. @item mml1991-use @vindex mml1991-use @@ -10171,7 +10264,7 @@ GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N, $B$K$7$F$*$-!"<~$j$K?M$,$$$J$$;~$r8+7W$i$C$F5-;v%P%C%U%!$K8=$o$l$k%\%?%s$r(B $B2!$7$^$7$g$&!#(B -@c Also see @pxref{MIME Commands}. +@c Also @xref{MIME Commands}. @node Customizing Articles @section $B5-;v$N%+%9%?%^%$%:(B @@ -10213,7 +10306,7 @@ GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N, $B:G=i$NMWAG$,J8;zNs$G$J$$%j%9%H$G$9(B: $B%j%9%H$O:F5"E*$KI>2A$5$l$^$9!#%j%9%H$N:G=i$NMWAG$O=R8l$G$9!#0J2<$N=R8l$,(B -$BG'<1$5$l$^$9(B: @code{or}, @code{and}, @code{not}, @code{typep}. $B$3$l$,Nc(B +$BG'<1$5$l$^$9(B: @code{or}, @code{and}, @code{not}, @code{typep}$B!#$3$l$,Nc(B $B$G$9(B: @lisp @@ -10287,10 +10380,14 @@ GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N, @xref{Smileys}. -@item gnus-treat-display-xface (head) +@item gnus-treat-display-x-face (head) @xref{X-Face}. +@item gnus-treat-display-face (head) + +@xref{Face}. + @item gnus-treat-emphasize (t, head, integer) @item gnus-treat-fill-article (t, integer) @item gnus-treat-fill-long-lines (t, integer) @@ -10524,9 +10621,9 @@ GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N, @kindex C-c C-c ($BEj9F(B) $BEj9F$N$?$a$NL?Na$r$9$k$H!"$"$J$?$O%a%C%;!<%8%P%C%U%!$K0\F0$7$^$9!#(B $B$=$3$G$O!"5-;v$r9%$-$J$h$&$KJT=8$9$k;v$,$G$-$^$9!#(B -$B$=$N8e$G(B @kbd{C-c C-c} $B$r2!$9;v$K$h$C$F!"5-;v$rAw?.$7$^$9!#(B -@xref{Top, , Overview, message, Message Manual}$B!#5-;v$O$"$J$?$N@_Dj$K4p(B -$B$E$$$FAw?.$5$l$^$9(B (@pxref{Posting Server})$B!#(B +$B$=$N8e$G(B @kbd{C-c C-c} $B$r2!$9;v$K$h$C$F!"5-;v$rAw?.$7$^(B +$B$9(B (@pxref{Top, , Overview, message-ja, Message Manual})$B!#5-;v$O$"$J$?$N(B +$B@_Dj$K4p$E$$$FAw?.$5$l$^$9(B (@pxref{Posting Server})$B!#(B @menu * Mail:: $B%a!<%k$HJVEz(B @@ -10539,8 +10636,8 @@ GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N, @c * Signing and encrypting:: How to compose secure messages. @end menu -$BEj9F$9$k$Y$-$G$J$+$C$?5-;v$r:o=|$9$k$?$a$N>pJs$O(B @pxref{Canceling and -Superseding} $B$r;2>H$7$F$/$@$5$$!#(B +$BEj9F$9$k$Y$-$G$J$+$C$?5-;v$r:o=|$9$k$?$a$N>pJs$K$D$$$F(B @ref{Canceling +and Superseding} $B$b;2>H$7$F2<$5$$!#(B @node Mail @section $B%a!<%k(B @@ -10669,18 +10766,19 @@ ISP $B$,(B @acronym{POP}-before-@acronym{SMTP} $B$NG'>Z$rMW5a$7$F$$$k>l9g$KM- @vindex gnus-user-agent @cindex User-Agent -($BLuCm(B: T-gnus $B$G$O8=:_$3$NJQ?t$K$h$k@)8f$O5!G=$7$^$;$s!#(B) $B$3$NJQ?t$O!"$I(B -$B$N>pJs$,(B User-Agent $B%X%C%@!<$KDDNs$5$l$k$+$r@)8f$7$^$9!#$=$l$OpJs$,(B User-Agent $B%X%C%@!<$KDDNs$5$l$k$+$r@)8f$7$^$9!#(B +$B$=$l$OH(B)$B!#(B +@code{emacs-gnus-type} (@code{emacs-gnus}) $B$HF1$8!\%7%9%F%`%?%$%W(B)$B!"(B +@code{gnus-mime-edit} (Gnus $B$H(B MIME Edit $B$J$I$N%P!<%8%g%s(B)$B!"$^$?$O9%$_$N(B +$BJ8;zNs!#$3$l$rJ8;zNs$K$9$k$H$-$O!"@5$7$$%U%)!<%^%C%H$K$J$C$F$$$k$3$H$r3N(B +$B$+$a$F2<$5$$(B (RFC2616 $B;2>H(B)$B!#(B @end table -$B$"$J$?$O<+J,$,Aw$k%a%C%;!<%8$NDV$j$rD4$Y$?$$$H;W$&$+$bCN$l$^$;$s!#$b$7$/(B -$B$O!"$b$7e$N$=$N%5!<%P!<$N%0(B $B$3$NJQ?t$O$KA*BrJ}K!$r4^$a$k$3$H$,$G$-$^$9$,!"$=$&$9$k$H$=$N%a%C(B @@ -10768,17 +10865,16 @@ Gnus $B$O30$X=P$F9T$/A4$F$N%a%C%;!<%8$K!"0l$D$+$=$l0J>e$N$=$N%5!<%P!<$N%0(B $B=P$F9T$/%a%C%;!<%8$O(B @samp{nnfolder+archive:foo} $B$KJ]B8$5$l$^$9$,!"$b$7(B $B$"$J$?$,(B @code{"nnml:foo"} $B$H$$$&CM$r;H$&$H!"(B@samp{nnml:foo} $B$KJ]B8$5$l(B $B$^$9!#(B -@samp{nnml:foo}. -@item -$BJ8;zNs$N%j%9%H(B + +@item $BJ8;zNs$N%j%9%H(B $B%a%C%;!<%8$O$=$l$i$NA4$F$N%0%k!<%W$KJ]B8$5$l$^$9!#(B -@item -$B@55,I=8=!"4X?t!"MM<0$NO"A[%j%9%H(B + +@item $B@55,I=8=!"4X?t!"MM<0$NO"A[%j%9%H(B $B%-!<$,!X9gCW!Y$9$k$H!"7k2L$,;H$o$l$^$9!#(B -@item -@code{nil} + +@item @code{nil} $B%a%C%;!<%8$NJ]B8$O9T$o$l$^$;$s!#$3$l$,%G%#%U%)%k%H$G$9!#(B -@end itemize +@end table $B;n$7$F$_$^$7$g$&(B: @@ -10907,22 +11003,30 @@ Gnus $B$O30$X=P$F9T$/A4$F$N%a%C%;!<%8$K!"0l$D$+$=$l0J>e$N$=$N%5!<%P!<$N%0(B $B$,J8;zNs$G$"$l$P!"(Bgnus $B$O$=$l$r%0%k!<%WL>$K@55,I=8=$H$7$F9gCWA`:n$r9T$$(B $B$^$9!#(B@code{(header $B9gCW(B $B@55,I=8=(B)} $B$H$$$&MM<0$G$"$l$P!"(Bgnus $B$O85$N5-;v(B $B$NCf$+$iL>A0$,9gCW$9$k%X%C%@!<$rC5$7!"$=$l$r@55,I=8=$HHf3S$7$^$9!#9gCW$H(B -$B@55,I=8=$OJ8;zNs$G$9!#(B($B$3$3$G!"85$N5-;v$H$OJV?.$^$?$O%U%)%m!<%"%C%W$7$h(B -$B$&$H$7$F$$$k$b$N$G$9!#JV?.$"$k$$$O%U%)%m!<%"%C%W$r:n@.$7$F$$$J$1$l$P!"9g(B -$BCW$9$k$b$N$O2?$b$"$j$^$;$s!#(B) $B$b$7(B @code{$B9gCW(B} $B$,4X?t$N%7%s%\%k$G$"$l$P!"(B -$B$=$N4X?t$,0z?tL5$7$G8F$P$l$^$9!#$=$l$,JQ?t$N%7%s%\%k$G$"$l$P!"$=$NJQ?t$,(B -$B;2>H$5$l$^$9!#$=$l$,%j%9%H$G$"$l$P!"$=$N%j%9%H$,(B @code{$BI>2A(B} $B$5$l$^$9!#(B -$B$I$N>l9g$G$b!"$3$l$,(B @code{nil}$B$G$J$$CM$r5"$;$P!"MM<0(B -$B$O(B @code{$B9gCW$7$?(B} $B$H8@$$$^$9!#(B +$B@55,I=8=$OJ8;zNs$G$9!#(B($B85$N5-;v$H$OJV?.$^$?$O%U%)%m!<%"%C%W$7$h$&$H$7$F(B +$B$$$k$b$N$G$9!#JV?.$"$k$$$O%U%)%m!<%"%C%W$r:n@.$7$F$$$J$1$l$P!"9gCW$9$k$b(B +$B$N$O2?$b$"$j$^$;$s!#(B) $B$b$7(B @code{$B9gCW(B} $B$,4X?t$N%7%s%\%k$G$"$l$P!"$=$N4X(B +$B?t$,0z?tL5$7$G8F$P$l$^$9!#$=$l$,JQ?t$N%7%s%\%k$G$"$l$P!"$=$NJQ?t$,;2>H$5(B +$B$l$^$9!#$=$l$,%j%9%H$G$"$l$P!"$=$N%j%9%H$,(B @code{$BI>2A(B} $B$5$l$^$9!#$I$N>l(B +$B9g$G$b!"$3$l$,(B @code{nil}$B$G$J$$CM$r5"$;$P!"MM<0$O(B @code{$B9gCW$7$?(B} $B$H8@$$(B +$B$^$9!#(B $B$=$l$>$l$NMM<0$OG$0U$NNL$N(B @dfn{$BB0@-(B} $B$r;}$D;v$,$G$-$^$9!#$=$l$>$l$NB0@-(B -$B$O(B @code{(@var{name} @var{value})} $B$NBP$K$h$j@.$jN)$C$F$$$^$9!#B0@-L>(B -$B$O!"(B@code{signature}, @code{signature-file}, @code{x-face-file}, -@code{address} (@code{user-mail-address} $B$r>e=q$-$9$k(B), @code{name} -(@code{user-full-name} $B$r>e=q$-$9$k(B) $B$^$?$O(B @code{body} $B$N$I$l$+$G$"$k;v(B -$B$,$G$-$^$9!#B0@-L>$OJ8;zNs$^$?$O%7%s%\%k$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"(B -$B$3$l$O%X%C%@!$H$7$F;H$o$l!"$=$NCM$,5-;v$N%X%C%@!<$KA^F~$5$l$^$9!#$b$7(B -$BB0@-L>$,(B @code{nil} $B$@$C$?$i$=$N%X%C%@!$O:o=|$5$l$^$9!#$b$7B0@-L>(B +$B$O(B @code{(@var{name} @var{value})} $B$NBP$K$h$j@.$jN)$C$F$$$^$9!#B0@-L>$O!"(B +$B0J2<$N$I$l$+$G$"$k;v$,$G$-$^$9!#(B + +@itemize @bullet +@item @code{signature} +@item @code{signature-file} +@item @code{x-face-file} +@item @code{address}, @code{user-mail-address} $B$r>e=q$-$7$^$9(B +@item @code{name}, @code{(user-full-name)} $B$r>e=q$-$7$^$9(B +@item @code{body} +@end itemize + +$BB0@-L>$OJ8;zNs$^$?$O%7%s%\%k$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"$3$l$O%X%C%@!<(B +$BL>$H$7$F;H$o$l!"$=$NCM$,5-;v$N%X%C%@!<$KA^F~$5$l$^$9!#$b$7B0@-L>(B +$B$,(B @code{nil} $B$@$C$?$i$=$N%X%C%@!$O:o=|$5$l$^$9!#$b$7B0@-L>(B $B$,(B @code{eval} $B$@$C$?$i$=$NMM<0$,I>2A$5$l!"7k2L$Oe$N%5!<%P!<$r:n@.$9$k(B $B$b$7$"$J$?$,1JB35-;v$r;H$C$F$?$/$5$s$N5-;v$r%-%c%C%7%e$KJ]B8$7$F$$$k$N$G(B -$B$"$l$P!"%-%c%C%7%e$rFI$`$?$a$N;ve$N%5!<%P!<$r:n$j$?$$$H;W$&$+$b$7$l$^(B +$B$"$l$P!"%-%c%C%7%e$rFI$`$?$a$N;ve$N%5!<%P!<$r:n$kI,MW$,$"$k$+$b$7$l$^(B $B$;$s!#(B $B:G=i$K!"?7$7$$%5!<%P!<$rIU$12C$($kI,MW$,$"$j$^$9!#L?Na(B @kbd{a} $B$,$=$l$r(B -$B$7$^$9!#$*$=$i$/%-%c%C%7%e$rFI$`$?$a$K$O(B @code{nnspool} $B$r;H$&$N$,0lHVNI(B -$B$$$G$7$g$&!#(B@code{nnml} $B$d(B @code{nnmh} $B$b;H$&;v$,$G$-$^$9$1$I!#(B +$B$7$^$9!#$*$=$i$/%-%c%C%7%e$rFI$`$?$a$K$O(B @code{nnml} $B$r;H$&$N$,0lHVNI$$(B +$B$G$7$g$&!#(B@code{nnspool} $B$d(B @code{nnmh} $B$b;H$&;v$,$G$-$^$9$1$I!#(B -@kbd{a nnspool RET cache RET} $B$HBG$C$F$/$@$5$$!#(B +@kbd{a nnml RET cache RET} $B$HBG$C$F$/$@$5$$!#(B -$B$9$k$H(B @samp{cache} $B$H8F$P$l$k!$(B @code{nnspool} $B$N;ve$N%5!<%P!<(B -$B$,$G$-$k$O$:$G$9!#e$N%5!<%P!<$,$G$-$k$O(B +$B$:$G$9!#A0$G$O$J$/$F@0?t(B ($B$D$^(B -$B$j(B @samp{snews} $B$d(B @samp{nntps} $B$G$O$J$/$F(B @samp{563}) $B$r;XDj$7$F2<$5$$!#(B -$B30It$N(B @acronym{TLS}/@acronym{SSL} $B%D!<%k$O%]!<%H$NL>A0$G$OF0:n$7$J$$$+(B -$B$i$G$9!#(B +$B$j(B @samp{snews} $B$d(B @samp{nntps} $B$G$O$J$/$F(B @samp{563}) $B$r;XDj$9$kI,MW$,(B +$B$"$j$^$9!#30It$N(B @acronym{TLS}/@acronym{SSL} $B%D!<%k$O%]!<%H$NL>A0$G$OF0(B +$B:n$7$J$$$+$i$G$9!#(B @item nntp-end-of-line @vindex nntp-end-of-line @@ -12178,7 +12281,7 @@ Emacs $B$N%;%C%7%g%sA4BN$r%i%C%W$7$F!"%G%#%U%)%k%H$N%a%=%C%I$r;H$&$H$$$&$N(B * Group Mail Splitting:: $B%a!<%kJ,3d$r6nF0$9$k$?$a$K%0%k!<%W%+%9%?%^%$%:$r;H$&(B * Incorporating Old Mail:: $B$"$J$?$,;}$C$F$$$k8E$$%a!<%k$r$I$&$9$k$+(B? * Expiring Mail:: $BM_$7$/$J$$%a!<%k$r$N%U%!%$%k$rFI$`$?$a$K%a!<%k%P%C%/%(%s%I$r;H$&(B * Choosing a Mail Back End:: Gnus $B$O?'!9$J%a!<%kMM<0$rFI$`;v$,$G$-$k(B @@ -12206,7 +12309,7 @@ gnus $B$O$U$D$&F1$8H$7$F2<$5$$!#(B +$B%a!<%k$N(B expire $B$K$D$$$F$O(B @ref{Expiring Mail} $B$r;2>H$7$F2<$5$$!#(B $B$7$P$i$/%a!<%k$H%K%e!<%9$NN>J}$r;H$C$F$_$l$P!"5-;v$No$K4JC1$G$9!#$"$J$?$N%a!<%k%P%C%/(B $B$NFs$D$N%0%k!<%W$K9g$o$J$$%a!<%k$OA4$F:G8e$N%0%k!<%W$KF~$l$i$l$^$9!#(B $B$3$l$O(B gnus $B$G%a!<%k$rFI$`$?$a$K=$N9`$r=OFI$7$?$$$H;W$&$+$b$7$l$^$;$s$,!#FC(B -$B$K(B @pxref{Choosing a Mail Back End} $B$H(B @pxref{Expiring Mail} $B$r!#(B +$B$NB>$N9`$r=OFI$9$kI,MW$,$"$k$+$b$7$l$^$;$s$,!#FC(B +$B$K(B @ref{Choosing a Mail Back End} $B$H(B @ref{Expiring Mail} $B$r!#(B @node Splitting Mail @subsection $B%a!<%k$NJ,3d(B @cindex splitting mail @cindex mail splitting +@cindex mail filtering (splitting) @vindex nnmail-split-methods $BJQ?t(B @code{nnmail-split-methods} $B$OF~$C$F$/$k%a!<%k$r$I$N$h$&$K%0%k!<%W(B @@ -12686,7 +12790,7 @@ Maildir $B%a!<%k%=!<%9$NNc$r$U$?$D(B: $B>\$7$/$O(B @xref{IMAP} $B$r;2>H$7$F2<$5$$!#(B Kerberos, GSSAPI, @acronym{TLS}/@acronym{SSL} $B$*$h$S(B STARTTLS $B$N$?$a$N30(B -$BIt%W%m%0%i%`$H%i%$%V%i%j$,I,MW$G$"$k$3$H$KN10U$7$F2<$5$$!#(B@xref{IMAP}$B!#(B +$BIt%W%m%0%i%`$H%i%$%V%i%j$,I,MW$G$"$k$3$H$KN10U$7$F2<$5$$!#(B@xref{IMAP}. $B%-!<%o!<%I(B: @@ -12750,9 +12854,9 @@ ssh %s imapd $Bl9g(B $B$O(B "one-line-cookie" $B%Q%C%A$rEv$F$kI,MW$,$"$j$^$9!#(B @@ -12838,9 +12942,9 @@ UNDELETED} $B$O$*$=$i$/$?$$$F$$$N?M$K$O:GNI$NA*Br$G$7$g$&$,!"$H$-$I(B @subsubsection $B4X?t%$%s%?!<%U%'!<%9(B $B>e5-$N$$$/$D$+$N%-!<%o!<%I$O!"$l$N%-!<%o!<%I(B @code{:foo} $B$NCM$H$7$F(B Lisp - $BJQ?t(B @code{foo} $B$,;H$o$l$^$9!#Nc$($P!"0J2<$N%a!<%k%=!<%9$N@_DjNc$K$D$$(B -$B$F9M$($F$_$F2<$5$$!#(B +$B$,$l$N%-!<%o!<%I(B @code{:foo} $B$NCM$H$7(B +$B$F(B Lisp $BJQ?t(B @code{foo} $B$,;H$o$l$^$9!#Nc$($P!"0J2<$N%a!<%k%=!<%9$N@_DjNc(B +$B$K$D$$$F9M$($F$_$F2<$5$$!#(B @lisp (setq mail-sources '((pop :user "jrl" @@ -13067,16 +13171,15 @@ UNDELETED} $B$O$*$=$i$/$?$$$F$$$N?M$K$O:GNI$NA*Br$G$7$g$&$,!"$H$-$I(B @end lisp $B$3$NJQ?t$O(B @dfn{$BJ,3d(B} $B$NMM<0$K$J$C$F$$$^$9!#J,3d$O(B ($B$"$k$$$O(B) $B$=$l$>$l$N(B -$BJ,3d$,B>$NJ,3d$r4^$`:F5"E*9=B$$G$9!#$3$l$O;HMQ2DG=$J8^$D$NJ,3d9=J8$G$9(B: +$BJ,3d$,B>$NJ,3d$r4^$`:F5"E*9=B$$G$9!#$3$l$O;HMQ2DG=$JJ,3d9=J8$G$9(B: -@enumerate +@table @code -@item -@samp{group}: $B$b$7J,3d$,J8;zNs$G$"$k$H!"$=$l$O%0%k!<%WL>$H$7$F$_$J$5$l$^(B -$B$9!#IaDL$N@55,I=8=$N9gCW$,$J$5$l$^$9!#Nc$O2<$NJ}$r8+$F2<$5$$!#(B +@item group +$B$b$7J,3d$,J8;zNs$G$"$k$H!"$=$l$O%0%k!<%WL>$H$7$F$_$J$5$l$^$9!#IaDL$N@55,(B +$BI=8=$N9gCW$,$J$5$l$^$9!#Nc$O2<$NJ}$r8+$F2<$5$$!#(B -@item -@code{(@var{field} @var{value} @code{[-} @var{restrict} @code{[@dots{}]}@code{]} @var{split})}: +@item (@var{field} @var{value} [- @var{restrict} [@dots{}] ] @var{split}) $B$b$7J,3d$,%j%9%H$G!":G=i$NMWAG$,J8;zNs$G$"$j!"%X%C%@!<(B @var{field} ($B@55,(B $BI=8=(B) $B$,(B @var{value} ($B$3$l$b@55,I=8=(B) $B$r4^$s$G$$$k>l9g!"%a%C%;!<%8(B $B$r(B @var{split} $B$G;XDj$5$l$?$H$3$m$KC_@Q$7$^$9!#(B@var{restrict} ($B$^$?B>$N(B @@ -13084,24 +13187,24 @@ UNDELETED} $B$O$*$=$i$/$?$$$F$$$N?M$K$O:GNI$NA*Br$G$7$g$&$,!"$H$-$I(B $B$+$NJ8;zNs$K9gCW$7$?$i!"(B@var{split} $B$OL5;k$5$l$^$9!#(B@var{restrict} $B$NJD(B $BJq$N$I$l$b$,9gCW$7$J$1$l$P(B @var{split} $B$,K@(B) $B$G$"$k$H!"$=$l$>$l$N(B @var{split} $B$r$=$N$&$A$N0l$D$,(B -$B9gCW$9$k$^$Ge$N%0%k!<(B -$B%W$KC_@Q$5$l$?$H$-$K(B ``$B9gCW$7$?(B'' $B$H$7$^$9!#(B +@item (| @var{split} @dots{}) +$BJ,3d$,%j%9%H$G!":G=i$NMWAG$,(B @code{|} ($B?bD>K@(B) $B$G$"$k$H!"$=$l$>$l(B +$B$N(B @var{split} $B$r$=$N$&$A$N0l$D$,9gCW$9$k$^$Ge$N%0%k!<%W$KC_@Q$5$l$?$H$-$K(B ``$B9gCW$7$?(B'' $B$H$7(B +$B$^$9!#(B -@item -@code{(& @var{split}@dots{})}: $BJ,3d$,%j%9%H$G!":G=i$NMWAG$,(B @code{&} $B$G(B -$B$"$k$H!"%j%9%H$NA4$F$N(B @var{split} ($BJ#?t(B) $B$rC5n$7$F$7$^$$$^$9(B)$B!#Hs>o$KCm0U$7$F;H$C$F2<$5$$!#(B +@item junk +$B$b$7J,3d$,%7%s%\%k(B @code{junk} $B$G$"$k$H!"$=$N%a%C%;!<%8$rJ]B8$7$^$;(B +$B$s(B ($B$9$J$o$A!">C5n$7$F$7$^$$$^$9(B)$B!#Hs>o$KCm0U$7$F;H$C$F2<$5$$!#(B -@item -@code{(: @var{function} @var{arg1} @var{arg2} @dots{})}: $B$b$7J,3d$,%j%9(B -$B%H$G!":G=i$NMWAG$,(B @code{:} $B$G$"$k$H!"FsHVL\$NMWAG$,(B @var{args} $B$r0z?t$H(B -$B$7$F4X?t$H$7$F8F$P$l$^$9!#4X?t$O(B @var{split} $B$rJV$9$Y$-$G$9!#(B +@item (: @var{function} @var{arg1} @var{arg2} @dots{}) +$B$b$7J,3d$,%j%9%H$G!":G=i$NMWAG$,(B @code{:} $B$G$"$k$H!"FsHVL\$NMWAG(B +$B$,(B @var{args} $B$r0z?t$H$7$F4X?t$H$7$F8F$P$l$^$9!#4X?t$O(B @var{split} $B$rJV(B +$B$9$Y$-$G$9!#(B @cindex body split $BNc$($P0J2<$N4X?t$O!"5-;v$N%\%G%#$K4p$E$$$?J,3d$K;H$($k$G$7$g$&(B: @@ -13109,25 +13212,29 @@ UNDELETED} $B$O$*$=$i$/$?$$$F$$$N?M$K$O:GNI$NA*Br$G$7$g$&$,!"$H$-$I(B @lisp (defun split-on-body () (save-excursion - (set-buffer " *nnmail incoming*") - (goto-char (point-min)) - (when (re-search-forward "Some.*string" nil t) - "string.group"))) -@end lisp - -@code{:} $B$,;H$o$l$k$H$-!"%P%C%U%!(B @samp{" *nnmail incoming*"} $B$O%a%C%;!<(B -$B%8$NItJ,$K69$a$i$l$^$9!#(B - -@item -@code{(! @var{func} @var{split})}: $BJ,3d$,%j%9%H$G!":G=i$NMWAG(B -$B$,(B @code{!} $B$G$"$k$H(B @var{split} $B$,e5-$NNc$G(B @code{save-excursion} $B$H(B @code{save-restriction} $B$N(B +$B8e$G(B @code{(widen)} $B$,8F$P$l$kI,MW$,$"$kM}M3$G$9!#$5$i$K(B nnimap $B%P%C%/%((B +$B%s%I$N>l9g!"%G%#%U%)%k%H$G$O5-;v$N%\%G%#$,%@%&%s%m!<%I$5$l$J$$$3$H$KCm0U(B +$B$7$F2<$5$$!#$=$l$r$9$k$?$a$K$O(B @code{nnimap-split-download-body} $B$r(B t $B$K(B +$B@_Dj$9$kI,MW$,$"$j$^$9(B (@pxref{Splitting in IMAP})$B!#(B + +@item (! @var{func} @var{split}) +$BJ,3d$,%j%9%H$G!":G=i$NMWAG$,(B @code{!} $B$G$"$k$H(B @var{split} $B$,$K9gCW$7$J$1$l$P$J$j$^(B $B$;$s!#(B@var{value} $B$O4pAC%b!<%I(B (fundamental mode) $B9=J8%F!<%V%k(B (syntax @@ -13137,9 +13244,21 @@ table) $B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+(B @vindex nnmail-split-abbrev-alist @var{field} $B$H(B @var{value} $B$O(B Lisp $B%7%s%\%k(B (symbol) $B$G$"$k;v$b$G$-!"$=(B -$B$N>l9g$O$=$l$i$O(B @code{nnmail-split-abbrev-alist} $B$G;XDj$5$l$F$$$k$h$&$K(B -$BE83+$5$l$^$9!#$3$l$O%;%k$N(B @code{car} $B$,%-!<$r4^$s$G$$$F!"(B@code{cdr} $B$,(B -$B4XO"IU$1$i$l$?CM$r;}$C$F$$$k%3%s%9%;%k(B (cons cell) $B$NO"A[%j%9%H$G$9!#(B +$B$N>l9g$=$l$i$O(B @code{nnmail-split-abbrev-alist} $B$G;XDj$5$l$F$$$k$h$&$KE8(B +$B3+$5$l$^$9!#$3$l$O%;%k$N(B @sc{car} $B$,%-!<$r4^$s$G$$$F!"(B@sc{cdr} $B$,4XO"IU(B +$B$1$i$l$?CM$r;}$C$F$$$k%3%s%9%;%k(B (cons cell) $B$NO"A[%j%9%H$G$9!#0J2<$N9`(B +$BL\$,!"$"$i$+$8$a(B @code{nnmail-split-abbrev-alist} $B$KDj5A$5$l$F$$$^$9(B: + +@table @code +@item from +@samp{From}$B!"(B@samp{Sender} $B$*$h$S(B @samp{Resent-From} $B$N3F%U%#!<%k%I$K9g(B +$BCW$7$^$9!#(B +@item to +@samp{To}$B!"(B@samp{Cc}$B!"(B@samp{Apparently-To}$B!"(B@samp{Resent-To} $B$*$h(B +$B$S(B @samp{Resent-Cc} $B$N3F%U%#!<%k%I$K9gCW$7$^$9!#(B +@item any +@code{from} $B$H(B @code{to} $B$rE}9g$7$?$b$N$G$9!#(B +@end table @vindex nnmail-split-fancy-syntax-table @code{nnmail-split-fancy-syntax-table} $B$,$3$l$i$NA4$F$NJ,3d$,$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+(B $B;H$o$l$^$9!#F1MM$K!"MWAG(B @samp{\\1} $B$+$i(B @samp{\\9} $B$^$G$O%0%k!<%WIU(B $B$1(B 1 $B$+$i(B 9 $B$^$G$G9gCW$7$?J8;zNs$GBeBX$5$l$^$9!#(B +@vindex nnmail-split-fancy-match-partial-words +@code{nnmail-split-fancy-match-partial-words} $B$O!"FC5iJ,3d$GItJ,E*$J8l$,(B +$B9gCW$9$k$+$I$&$+$r@)8f$7$^$9!#(B + +$BDL>o(B @code{nnmail-split-fancy} $B$GM?$($i$l$k@55,I=8=$O!"0E$K8l$N6h@Z$j$r(B +$BI=$9(B @code{\<...\>} $B0u$G0O$^$l$F$$$^$9!#$3$NJQ?t$,??$G$"$k$H!"$=$l$i$O2?(B +$B$K$h$C$F$b0E$K0O$^$l$^$;$s!#(B + +@example +(any "joe" "joemail") +@end example + +$B$3$NNc$G!"DL>o(B @samp{joedavis@@foo.org} $B$+$iMh$?%a%C%;!<%8(B +$B$O(B @samp{joemail} $B$K3JG<$5$l$^$;$s!#$7$+$7!"(B +@code{nnmail-split-fancy-match-partial-words} $B$r(B t $B$K@_Dj$9$k$H9gCW$,5/(B +$B$-$^$9!#MW$9$k$K!"8l$r6h@Z$k>r7o$,:o=|$5$l!"Be$o$j$K9gCW$,$h(B +$B$j(B grep $B$i$7$/$J$k$N$G$9!#(B + @findex nnmail-split-fancy-with-parent $B4X?t(B @code{nnmail-split-fancy-with-parent} $B$O!"%U%)%m!<%"%C%W5-;v$r?F5-(B $B;v$HF1$8%0%k!<%W$K?6$jJ,$1$k$?$a$K;H$$$^$9!#%a!<%k$N?6$jJ,$1$r0l@87|L?@_(B @@ -13211,10 +13348,10 @@ table) $B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+(B $B$"$k%0%k!<%W$r%-%c%C%7%e$K5-O?$7$?$/$J$$>l9g$O!"JQ(B $B?t(B @code{nnmail-cache-ignore-groups} $B$b;2>H$7$F2<$5$$!#Nc$($P!"30$K=P$9(B -$B$9$Y$F$N%a%C%;!<%8$,(B `outgoing' $B%0%k!<%W$G=q$+$l$F$$$k$J$i$P!"(B +$B$9$Y$F$N%a%C%;!<%8$,(B ``outgoing'' $B%0%k!<%W$G=q$+$l$F$$$k$J$i$P!"(B @code{nnmail-cache-ignore-groups} $B$r$=$N%0%k!<%WL>$K%^%C%A$9$k$h$&$K@_Dj(B $B$9$k$N$,NI$$$G$9!#$5$b$J$$$H$"$J$?$N$9$Y$F$N%a%C%;!<%8$KBP$9$kJV;v$,!":G(B -$B8e$O(B `outgoing' $B%0%k!<%W$KF~$C$F$7$^$&$G$7$g$&!#(B +$B8e$O(B ``outgoing'' $B%0%k!<%W$KF~$C$F$7$^$&$G$7$g$&!#(B @node Group Mail Splitting @subsection $B%0%k!<%W%a!<%kJ,3d(B @@ -13225,31 +13362,32 @@ table) $B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+(B $B$?!<$/$5$s$N%a!<%j%s%0%j%9%H$r9XFI$7$F$$$k$1$l$I!"J}$b$7$/$O$I$A$i$+$r@_Dj$7(B +$B$G(B @code{to-list}, @code{to-address} $B$NN>J}$b$7$/$O$I$A$i$+$r@_Dj$7(B $B$F(B @code{nnmail-split-methods} $B$r(B @code{gnus-group-split} $B$K@_Dj$9$k$@$1(B $B$G$9!#J,3d4X?t$OA4$F$N%0%k!<%W$G$3$l$i$N%Q%i%a!<%?$rAv::$7!"$=$l$K=>$C$F(B $BJ,3d$7$^$9!#$9$J$o$A!"%a!<%k%0%k!<%W$N%Q%i%a!<(B -$B%?(B @var{to-list} $B$+(B @var{to-address} $B$G;XDj$5$l$?%"%I%l%9$+$iEj9F$5$l$?(B -$B$b$N$+!"$=$N%"%I%l%9$XEj9F$5$l$?%a%C%;!<%8$,$=$N%0%k!<%W$KJ]B8$5$l$^$9!#(B +$B%?(B @code{to-list} $B$+(B @code{to-address} $B$G;XDj$5$l$?%"%I%l%9$+$iEj9F$5$l(B +$B$?$b$N$+!"$=$N%"%I%l%9$XEj9F$5$l$?%a%C%;!<%8$,$=$N%0%k!<%W$KJ]B8$5$l$^$9!#(B $B$H$-$K$O!"%a!<%j%s%0%j%9%H$K$OJ#?t$N%"%I%l%9$,$"$j!"%a!<%kJ,3d$K$=$l$iA4(B -$B$F$rG'<1$5$;$?$$$H;W$&$H$-$,$"$k$+$b$7$l$^$;$s(B: @var{extra-aliases} $B%0%k!<(B -$B%W%Q%i%a!<%?$rDI2C$N%"%I%l%9$N%j%9%H$K@_Dj$9$k$@$1$G=*$j$G$9!#@55,I=8=$r(B -$B;H$$$?$1$l$P!"(B@var{split-regexp} $B$r@_Dj$7$F$/$@$5$$!#(B +$B$F$rG'<1$5$;$kI,MW$,$"$k$+$b$7$l$^$;$s(B: @code{extra-aliases} $B%0%k!<%W%Q(B +$B%i%a!<%?$rDI2C$N%"%I%l%9$N%j%9%H$K@_Dj$9$k$@$1$G=*$j$G$9!#@55,I=8=$r;H$$(B +$B$?$1$l$P!"(B@code{split-regexp} $B$r@_Dj$7$F$/$@$5$$!#(B $B$3$l$i$NA4$F$N%0%k!<%W$N%Q%i%a!<%?$O!"(B@code{nnmail-split-fancy} $BJ,3d$r:n(B $B@.$9$k$?$a$K;HMQ$5$l!"$=$l$O(B @var{field} $B$,(B @samp{any} $B$G!"(B -@var{value} $B$,(B @var{to-list}, @var{to-address}, @var{extra-aliases} $B$NA4(B -$B$F!"(B@var{split-regexp} $B$NA4$F$N9gCW$K9gCW$9$kC1FH$N@55,I=8=!"(B -@var{split} $B$,%0%k!<%W$NL>A0$K$J$j$^$9!#(B@var{restrict} $B$b;HMQ$G$-$^$9(B: -@var{split-exclude} $B%Q%i%a!<%?$r@55,I=8=$N%j%9%H$K@_Dj$9$k$@$1$G$9!#(B +@var{value} $B$,(B @code{to-list}, @code{to-address}, +@code{extra-aliases} $B$N$9$Y$F!"(B@code{split-regexp} $B$NA4$F$N9gCW$K9gCW$9(B +$B$kC1FH$N@55,I=8=!"(B@var{split} $B$,%0%k!<%W$NL>A0$K$J$j$^$9!#(B@var{restrict} +$B$b;HMQ$G$-$^$9(B: @code{split-exclude} $B%Q%i%a!<%?$r@55,I=8=$N%j%9%H$K@_Dj(B +$B$9$k$@$1$G$9!#(B $B$3$l$i$NA4$F$N%Q%i%a!<%?$r;H$C$F@5$7$$J,3d$,@8@.$5$l$J$$$H$-$d!"2?$+0c$C(B $B$?$b$N$,I,MW$J$H$-$O!"%Q%i%a!<(B -$B%?(B @var{split-spec} $B$r(B @code{nnmail-split-fancy} $BJ,3d$K@_Dj$9$k$3$H$,$G(B +$B%?(B @code{split-spec} $B$r(B @code{nnmail-split-fancy} $BJ,3d$K@_Dj$9$k$3$H$,$G(B $B$-$^$9!#$3$N>l9g$O!"B>$NA0$K=q$$$?A4$F$N%Q%i%a!<%?(B $B$O(B @code{gnus-group-split} $B$KL5;k$5$l$^$9!#FC$K!"(B -@var{split-spec} $B$O(B @code{nil} $B$K@_Dj$9$k$3$H$,$G$-!"$=$N>l9g$O%0%k!<%W(B +@code{split-spec} $B$O(B @code{nil} $B$K@_Dj$9$k$3$H$,$G$-!"$=$N>l9g$O%0%k!<%W(B $B$O(B @code{gnus-group-split} $B$KL5;k$5$l$^$9!#(B @vindex gnus-group-split-default-catch-all-group @@ -13258,7 +13396,7 @@ table) $B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+(B $B$^$9!#%a%C%;!<%8$,$I$NJ,3d$K$b9gCW$7$J$1$l$P!"$I$l$+$N%0%k!<%W(B $B$G(B @var{split-spec} $B$,(B @code{catch-all} $B$K@_Dj$5$l$F$$$J$$>l9g(B $B$O(B @code{gnus-group-split-default-catch-all-group} $B$G;XDj$5$l$F$$$k%0%k!<(B -$B%W$KJ]B8$5$l$^$9!#(B@var{split-spec} $B$,(B @code{catch-all} $B$K@_Dj$5$l$F$$$k(B +$B%W$KJ]B8$5$l$^$9!#(B@code{split-spec} $B$,(B @code{catch-all} $B$K@_Dj$5$l$F$$$k(B $B%0%k!<%W$,$"$k>l9g$O!"$=$N%0%k!<%W$,A4$F$rJa3M$9$k%0%k!<%W$H$7$F;HMQ$5$l(B $B$^$9!#$3$NJQ?t$O$7$P$7$PC1$K%0%k!<%W$r;XDj$9$k$?$a$K;H$o$l$^$9$,!"G$0U$N(B $BJ#;($JFC5iJ,3d$r$b@_Dj$9$k(B ($B7k6I!"%0%k!<%WL>$OFC5iJ,3d$J$N$G$9(B) $B$N$G!"8D(B @@ -13307,12 +13445,12 @@ nnml:mail.others: @var{groups} $B$O=PNO$NJ,3d$r@8@.$9$k$?$a$K%Q%i%a!<%?$,Av::$5$l$k%0%k!<%W(B $BL>$N%j%9%H$+@55,I=8=$G$9!#(B@var{no-crosspost} $B$OAj8_Ej9F$r;HMQ6X;_$K$k$?(B $B$a$K;H$&$3$H$,$G$-$^$9!#$=$N>l9g!"C10l$N(B @code{|} $BJ,3d$,=PNO$5$l$^$9!#(B -@var{catch-all} $B$O(B @var{gnus-group-split-default-catch-all-group} $B$N$h$&(B -$B$K!":G8e$Nl9g!"%0%k!<%W$K(B @var{split-spec} $B$,(B @code{catch-all} $B$K@_Dj$5$l$F$$$k(B -$B$b$N$,$"$k$H!"$3$N%0%k!<%W$,(B @var{catch-all} $B0z?t$r>e=q$-$7$^$9!#(B +$B$$>l9g!"%0%k!<%W$K(B @code{split-spec} $B$,(B @code{catch-all} $B$K@_Dj$5$l$F$$(B +$B$k$b$N$,$"$k$H!"$3$N%0%k!<%W$,(B @var{catch-all} $B0z?t$r>e=q$-$7$^$9!#(B @findex gnus-group-split-setup $BIT1?$J$3$H$K!"A4$F$N%0%k%W$H%Q%i%a!<%?$rAv::$9$k$3$H$OHs>o$KCY$$$G$9!#FC(B @@ -13345,7 +13483,7 @@ nnml:mail.others: @vindex gnus-group-split-updated-hook @code{nnmail-split-fancy} $B$,(B @code{gnus-group-split-update} $B$G@_Dj$5$l$?(B -$B8e$K!"JQ99$7$?$$$H$-$N$?$a$K!"$3$N4X?t(B +$B8e$GJQ99$9$kI,MW$,$"$k$H$-$N$?$a$K!"$3$N4X?t(B $B$O(B @code{gnus-group-split-update-hook} $B$r=*N;$9$kD>A0$K$^$7$/$J$$%a!<%k$r:o=|$5$;$k$?$a$K$O!"5-;v$r(B @dfn{$B4|8B@Z$l>C5n $B$l$i$N(B ``$B5-;v(B'' $B$r>C5n$7$^$;$s!#(B $BC5n2DG=$N0u$rIU$1$J$1$l$P$J$i$J$$$o$1$G$O$"$j$^$;(B -$B$s!#(Bgnus $B$O(B `auto-expire' $B$*$h$S(B `total-expire' $B$H8F$P$l$kFs$D$N5!G=$rDs(B -$B6!$7$F!"$"$J$?$NC5n2DG=$G$"$k(B -$B$H(B gnus $B$,2rC5n2DG=$G$"$k$H2rC5n2DG=$G$"$k$H(B gnus $B$,2rC5n2DG=$G$"$k$H2r(B +$B$l$N%j%9%H$r$=$l<+?H$N%0%k!<(B @@ -13440,9 +13579,9 @@ Auto-expire $B$^$?$O(B total-expire $B$N$I$A$i$,NI$$$G$9$+(B? $B$=$l$OEz$($ to stick around $B$N0ULu(B) $B5-;v$K$D$$$F$O!":#$^$G$I$*$j2D;k(B (tick)$B!"J](B $BN1(B (dormant) $B$^$?$O4{FI(B (read) $B$NCf$+$iA*$V$3$H$,$G$-$k(B - $B$H$$$&$3$H$G$9!#(B $B$7$+$7(B total-expire $B$G$O(B dormant $B$H(B ticked $B$+$i$7$+A*$Y$^$;$s!#(B -total-expire $B$NMxE@$O!"E,1~%9%3%"IU$1(B @pxref{Adaptive Scoring} $B$GNI9%$K(B -$BF/$/$3$H$G$9!#(BAuto-expire $B$ODL>o$N%9%3%"IU$1$G$OF0:n$7$^$9$,!"E,1~%9%3%"(B -$BIU$1$G$O$@$a$G$9!#(B +total-expire $B$NMxE@$O!"E,1~%9%3%"IU$1(B (@pxref{Adaptive Scoring}) $B$GNI9%(B +$B$KF/$/$3$H$G$9!#(BAuto-expire $B$ODL>o$N%9%3%"IU$1$G$OF0:n$7$^$9$,!"E,1~%9%3(B +$B%"IU$1$G$O$@$a$G$9!#(B @vindex gnus-auto-expirable-newsgroups $B@55,I=8=(B @code{gnus-auto-expirable-newsgroups} $B$K9gCW$9$k%0%k!<%W$OA4$F(B @@ -13651,7 +13790,7 @@ Gnus $B$O5-;v$rI=<($9$k$H$-$K$=$l$r@vBu$9$k$?$a$K2aEY$N4X?t$rDs6!$7$F$$$^(B @end lisp $B$3$l$O(B @code{gnus-list-identifiers} $B$GHsGK2uE*$K9T$&$3$H$b$G$-$^$9!#(B -@xref{Article Hiding}$B!#(B +@xref{Article Hiding}. @item nnmail-remove-tabs @findex nnmail-remove-tabs @@ -13902,7 +14041,7 @@ rmail box $B$N$?$a$N%"%/%F%#%V%U%!%$%k$NL>A0!#4{DjCM(B @item nnml-newsgroups-file @vindex nnml-newgroups-file -@code{nnml} $B%0%k!<%W5-=R%U%!%$%k!#(B@xref{Newsgroups File Format}$B!#4{DjCM(B +@code{nnml} $B%0%k!<%W5-=R%U%!%$%k!#(B@xref{Newsgroups File Format}. $B4{DjCM(B $B$O(B @file{~/Mail/newsgroups} $B$G$9!#(B @item nnml-get-new-mail @@ -13972,10 +14111,10 @@ rmail box $B$N$?$a$N%"%/%F%#%V%U%!%$%k$NL>A0!#4{DjCM(B @item nnmh-be-safe @vindex nnmh-be-safe -@code{nil} $B$G$J$1$l$P!"(B@code{nnmh} $B$O%U%)%k%@!<$K$"$k5-;v$,pJs$rD4$Y$^$9$N$G!"$3$l$r(B @code{t} $B$K@_Dj$9$k;v$O?<(B -$B9o$JB.EYDc2<$,5/$3$k$H$$$&;v$G$9!#$b$7(B @code{nnmh} $B5-;v$rFI$`$N(B +@code{nil} $B$G$J$1$l$P!"(B@code{nnmh} $B$O%U%)%k%@!<$K$"$k5-;v$,pJs$rD4$Y$^$9$N$G!"$3$l$r(B @code{t} $B$K@_Dj$9$k(B +$B;v$O?<9o$JB.EYDc2<$,5/$3$k$H$$$&;v$G$9!#$b$7(B @code{nnmh} $B5-;v$rFI$`$N(B $B$K(B gnus $B0J30$N$b$N$r;H$C$F$$$J$$$N$G$"$l$P!"$3$NJQ?t$r(B @code{t} $B$K@_Dj$9(B $B$kI,MW$O$"$j$^$;$s!#4{DjCM$O(B @code{nil} $B$G$9!#(B @end table @@ -13989,37 +14128,38 @@ rmail box $B$N$?$a$N%"%/%F%#%V%U%!%$%k$NL>A0!#4{DjCM(B $B$N(B maildir $B$K(B maildir $B%U%)!<%^%C%H$G%a!<%k$r3JG<$7$^$9!#$3$N%U%)!<%^%C(B $B%H$O(B @uref{http://cr.yp.to/proto/maildir.html} $B$*$h(B $B$S(B @uref{http://www.qmail.org/man/man5/maildir.html} $B$GJ8=q2=$5$l$F$$$^(B -$B$9!#$^$?(B nnmaildir $B$O(B maildir $B$NCf$N(B @file{.nnmaildir/} $B%G%#%l%/%H%j$KFC(B -$BJL$J>pJs$r3JG<$7$^$9!#(B +$B$9!#$^$?(B @code{nnmaildir} $B$O(B maildir $B$NCf$N(B @file{.nnmaildir/} $B%G%#%l%/(B +$B%H%j$KFCJL$J>pJs$r3JG<$7$^$9!#(B Maildir $B%U%)!<%^%C%H$O%m%C%/$rI,MW$H$7$J$$F1;~G[Aw$H9VFI$r2DG=$K$9$k$?$a(B $B$K@_7W$5$l$^$7$?!#B>$N%P%C%/%(%s%I$G$O!"%a!<%k$r2?$i$+$N%9%W!<%k$KEO$7$F(B $B$=$N%9%W!<%k$+$i%0%k!<%W$KJ,3d$9$k$?$a$K(B Gnus $B$r@_Dj$7$J$1$l$P$J$i$J$$$G(B -$B$7$g$&!#$=$l$O:#$^$GDL$j(B nnmaildir $B$G9T$J$&$3$H$,$G$-$^$9$,!"$b$C$H0lHL(B -$BE*$J@_Dj$O(B Gnus $B$N%0%k!<%W$H$7$F8=$o$l$k(B maildir $B$K%a!<%k$rD>@\G[Aw$9$k(B -$B$3$H$G$9!#(B +$B$7$g$&!#$=$l$O:#$^$GDL$j(B @code{nnmaildir} $B$G9T$J$&$3$H$,$G$-$^$9$,!"$b$C(B +$B$H0lHLE*$J@_Dj$O(B Gnus $B$N%0%k!<%W$H$7$F8=$o$l$k(B maildir $B$K%a!<%k$rD>@\G[(B +$BAw$9$k$3$H$G$9!#(B -nnmaildir $B$O40A4$K?.Mj$G$-$k$3$H$rL\;X$7$F$$$^$9(B: @kbd{C-g} $B$O%a%b%j!$l$N(B maildir $B$K3JG<$7(B -$B$^$9!#$=$l$K$h$C$F!"$"$k(B Gnus $B$N4D6-$+$iJL$N>l=j$K(B maildir $BA4BN$r%3%T!<(B -$B$9$k$3$H$,$G$-!"0u$OJ]B8$5$l$^$9!#(B +@code{nnmaildir} $B$O5-;v$N0u$H(B @acronym{NOV} $B%G!<%?$r$=$l$>$l$N(B maildir +$B$K3JG<$7$^$9!#$=$l$K$h$C$F!"$"$k(B Gnus $B$N4D6-$+$iJL$N>l=j$K(B maildir $BA4BN(B +$B$r%3%T!<$9$k$3$H$,$G$-!"0u$OJ]B8$5$l$^$9!#(B $B2>A[%5!<%P!<$N@_Dj(B: @table @code @item directory -$B$=$l$>$l$N(B nnmaildir $B%5!<%P!<(B ($B0l$D$r1[$($k%5!<%P!<$,I,MW$@$H$O$H$F$b;W(B -$B$($^$;$s$,(B) $B$KBP$7$F%G%#%l%/%H%j$r:n$j!"$=$l$r(B maildir $B$^$?$O(B maildir $B$X(B -$B$N%7%s%\%j%C%/%j%s%/$H$7$F$NL\E*$N$?$a$K$9$G$K(B -$B;H$o$l$F$$$k%G%#%l%/%H%j$rA*$s$G$O$$$1$^$;$s(B)$B!#$=$l$>$l$N(B maildir $B$O!"$=(B -$B$N%5!<%P!<$N%K%e!<%9%0%k!<%W$H$7$F(B Gnus $B$K8=$l!"%7%s%\%j%C%/%j%s%/$N%U%!(B -$B%$%kL>$,$=$N%0%k!<%W$NL>A0$K$J$j$^$9!#%G%#%l%/%H%j$K$"$k(B `.' $B$G;O$^$k$I(B -$B$s$J%U%!%$%kL>$bL5;k$5$l$^$9!#%G%#%l%/%H%j$O:G=i$K(B Gnus $B$r5/F0$7$?$H$-$H(B -$B%0%k!<%W%P%C%U%!$G(B @kbd{g} $B$r%?%$%W$7$?$H$-$O$$$D$G$bAv::$5$l!"$I$l$+(B -$B$N(B maildir $B$,:o=|$^$?$ODI2C$5$l$?$H$-$KDLCN$7$^$9!#(B +$B$=$l$>$l$N(B @code{nnmaildir} $B%5!<%P!<(B ($B0l$D$r1[$($k%5!<%P!<$,I,MW$@$H$O$H(B +$B$F$b;W$($^$;$s$,(B) $B$KBP$7$F%G%#%l%/%H%j$r:n$j!"$=$l$r(B maildir $B$^$?(B +$B$O(B maildir $B$X$N%7%s%\%j%C%/%j%s%/$H$7$F$NL\E*(B +$B$N$?$a$K$9$G$K;H$o$l$F$$$k%G%#%l%/%H%j$rA*$s$G$O$$$1$^$;$s(B)$B!#$=$l$>$l(B +$B$N(B maildir $B$O!"$=$N%5!<%P!<$N%K%e!<%9%0%k!<%W$H$7$F(B Gnus $B$K8=$l!"%7%s%\(B +$B%j%C%/%j%s%/$N%U%!%$%kL>$,$=$N%0%k!<%W$NL>A0$K$J$j$^$9!#%G%#%l%/%H%j$K$"(B +$B$k(B @samp{.} $B$G;O$^$k$I$s$J%U%!%$%kL>$bL5;k$5$l$^$9!#%G%#%l%/%H%j$O:G=i(B +$B$K(B Gnus $B$r5/F0$7$?$H$-$H%0%k!<%W%P%C%U%!$G(B @kbd{g} $B$r%?%$%W$7$?$H$-$O$$(B +$B$D$G$bAv::$5$l!"$I$l$+$N(B maildir $B$,:o=|$^$?$ODI2C$5$l$?$H$-(B +$B$K(B @code{nnmaildir} $B$ODLCN$7$^$9!#(B @code{directory} $B%Q%i%a!<%?$NCM$O(B Lisp $B<0$G$J$1$l$P$J$j$^$;$s!#(B @code{eval} $B$G=hM}$5$l$?8e$G!"(B@code{expand-file-name} $B$K$h$C$F$3$N%5!<%P!<(B @@ -14028,7 +14168,7 @@ nnmaildir $B$O5-;v$N0u$H(B @acronym{NOV} $B%G!<%?$r$=$l$>$l$N(B maildir $B$ $BL5MQ(B; $BC1$J$kJ8;zNs$GF0:n$7$^$9(B)$B!#$3$N%Q%i%a!<%?$OG$0U$G$O$J$/!"@_Dj$7$J(B $B$1$l$P$J$j$^$;$s!#(B@code{"~/Mail"} $B$d$=$l$N%5%V%G%#%l%/%H%j$r;H$&$3$H$O?d(B $B>)$G$-$^$;$s!#$$$/$D$+$N(B Gnus $B$NB>$NItJ,$,$=$l$r%G%#%U%)%k%H$G$$$m$s$J$b(B -$B$N$K;H$&$N$G!"(Bnnmaildir $B$G$b$=$l$r;H$&$H:.Mp$9$k$+$b$7$l$^$;$s!#(B +$B$N$K;H$&$N$G!"(B@code{nnmaildir} $B$G$b$=$l$r;H$&$H:.Mp$9$k$+$b$7$l$^$;$s!#(B @code{"~/.nnmaildir"} $B$,0lHLE*$JCM$G$9!#(B @item target-prefix @@ -14037,12 +14177,12 @@ nnmaildir $B$O5-;v$N0u$H(B @acronym{NOV} $B%G!<%?$r$=$l$>$l$N(B maildir $B$ $B$NL>A0$r3MF@$7$^$9!#<0$O%5!<%P!<$,3+DL$7$?$H$-$@$1(B @code{eval} $B$5$l!"$=(B $B$N7k2LF@$i$l$?J8;zNs$,!"%5!<%P!<$,JD$8$i$l$k$^$G;H$o$l$^$9!#(B -nnmaildir $B%5!<%P!<$K%0%k!<%W$r:n$k$H!"$=$NL>A0$NF,(B +@code{nnmaildir} $B%5!<%P!<$K%0%k!<%W$r:n$k$H!"$=$NL>A0$NF,(B $B$K(B @code{target-prefix} $B$,IU2C$5$l$?(B maildir $B$H!"$=$N(B maildir $B$r;X$7<($9(B $B%7%s%\%j%C%/%j%s%/$,AG$N%0%k!<%WL>$NL>A0$G:n@.$5$l$^$9!#$7$?$,$C$F!"(B @code{directory} $B$,(B @code{"~/.nnmaildir"} $B$G!"(B @code{target-prefix} $B$,(B @code{"../maildirs/"} $B$@$C$?>l9g$K(B @code{foo} $B$H(B -$B$$$&%0%k!<%W$r:n$k$H!"(Bnnmaildir $B$O(B maildir $B$H$7(B +$B$$$&%0%k!<%W$r:n$k$H!"(B@code{nnmaildir} $B$O(B maildir $B$H$7(B $B$F(B @file{~/.nnmaildir/../maildirs/foo} $B$r!"(B@file{../maildirs/foo} $B$X$N%7(B $B%s%\%j%C%/%j%s%/$H$7$F(B @file{~/.nnmaildir/foo} $B$r:n@.$7$^$9!#(B @@ -14077,21 +14217,22 @@ nnmaildir $B%5!<%P!<$K%0%k!<%W$r:n$k$H!"$=$NL>A0$NF,(B $B$k(B @code{mail-sources} $B$+$i!"=>Mh$N(B Gnus $B$NJ}K!$G%a!<%k$rJ}$GF1$8(B maildir $B$r;H$C$F(B -$B$O(B @emph{$B$$$1$^$;$s(B}$B!#$=$N7k2L$O1?NI$/M-1W$K$J$k$+$b$7$l$^$;$s$,!"$=$s$J(B -$B0U?^$G$O@_7W$5$l$F$$$^$;$s!#>-Mh$O0c$&7k2L$r$b$?$i$92DG=@-$,$"$j$^$9!#$"(B -$B$J$?$NJ,3d5,B'$,?7$7$$%0%k!<%W$r:n$k$h$&$K$J$C$F$$$k>l9g$O!"(B +@code{mail-sources} $B$H(B @code{nnmaildir} $B%0%k!<%W$NN>J}$GF1$8(B maildir $B$r(B +$B;H$C$F$O(B @emph{$B$$$1$^$;$s(B}$B!#$=$N7k2L$O1?NI$/M-1W$K$J$k$+$b$7$l$^$;$s$,!"(B +$B$=$s$J0U?^$G$O@_7W$5$l$F$$$^$;$s!#>-Mh$O0c$&7k2L$r$b$?$i$92DG=@-$,$"$j$^(B +$B$9!#$"$J$?$NJ,3d5,B'$,?7$7$$%0%k!<%W$r:n$k$h$&$K$J$C$F$$$k>l9g$O!"(B @code{create-directory} $B%5!<%P!<%Q%i%a!<%?$rM?$($k$3$H$rK:$l$J$$$G2<$5$$!#(B @end table @subsubsection $B%0%k!<%W%Q%i%a!<%?(B -nnmaildir $B$O$$$/$D$+$N%0%k!<%W%Q%i%a!<%?$r;H$$$^$9!#$3$l$i$N$9$Y$F$rL5;k(B -$B$7$F$b0BA4$G$9!#%G%#%U%)%k%H$N(B nnmaildir $B$NF0:n$O!"B>$N%a!<%k%P%C%/%(%s(B -$B%I$N%G%#%U%)%k%H(B ($B5-;v$,0l=54V8e$K>C5n$5$l$k!"$J$I(B) $B$HF1$8$G$9!#4|8B@Z$l(B -$B>C5n$N%Q%i%a!<%?$r=|$$$F!"$3$N5!G=$O$9$Y$F(B nnmaildir $B$KFCM-$G$9!#$7$?$,$C(B -$B$F!"JL$N%P%C%/%(%s%I$G$9$G$K9T$C$F$$$kF0:n$rC1$KF'=1$5$;$h$&$H$$$&$N$G$"(B -$B$l$P!"$3$l$rL5;k$9$k$3$H$,$G$-$^$9!#(B +@code{nnmaildir} $B$O$$$/$D$+$N%0%k!<%W%Q%i%a!<%?$r;H$$$^$9!#$3$l$i$N$9$Y(B +$B$F$rL5;k$7$F$b0BA4$G$9!#%G%#%U%)%k%H$N(B @code{nnmaildir} $B$NF0:n$O!"B>$N%a!<(B +$B%k%P%C%/%(%s%I$N%G%#%U%)%k%H(B ($B5-;v$,0l=54V8e$K>C5n$5$l$k!"$J$I(B) $B$HF1$8$G(B +$B$9!#4|8B@Z$l>C5n$N%Q%i%a!<%?$r=|$$$F!"$3$N5!G=$O$9$Y(B +$B$F(B @code{nnmaildir} $B$KFCM-$G$9!#$7$?$,$C$F!"JL$N%P%C%/%(%s%I$G$9$G$K9T$C(B +$B$F$$$kF0:n$rC1$KF'=1$5$;$h$&$H$$$&$N$G$"$l$P!"$3$l$rL5;k$9$k$3$H$,$G$-$^(B +$B$9!#(B $B$3$l$i$N%Q%i%a!<%?$N$&$A$N$I$l$G$b!"$=$NCM$,%Y%/%H%k$G$"$k>l9g$O!"%*%j%8(B $B%J%k$NCM$KBe$o$C$F!"Bh0l$NMWAG$,(B Lisp $B<0$H$7$FI>2A$5$l$?7k2L$,;H$o$l$^$9!#(B @@ -14109,30 +14250,30 @@ nnmaildir $B$O$$$/$D$+$N%0%k!<%W%Q%i%a!<%?$r;H$$$^$9!#$3$l$i$N$9$Y$F$rL5;k(B $B$5$l$F$$$J$$$H!"$$$D$b$N(B @code{nnmail-expiry-wait}(@code{-function}) $BJQ(B $B?t(B (@code{expiry-wait}(@code{-function}) $B%0%k!<%W%Q%i%a!<%?$G>e=q$-$5$l(B $B$k(B) $B$r:G8e$N$h$j$I$3$m$K$7$^$9!#(B3$BF|$NCM$,M_$7$$$J$i$P!"(B@code{[(* 3 24 60 -60)]} $B$N$h$&$J$b$N$r;H$C$F2<$5$$!#(Bnnmaildir $B$O<0$rI>2A$7$F!"$=$N7k2L$r;H(B -$B$$$^$9!#5-;v$No$3$l(B -$B$O5-;v$,G[Aw$5$l$?;~9o$HF1$8$G$9$,!"5-;v$NJT=8$O$=$l$rC5n0J30$N(B) $B5-;v$N0\F0$b$^$?!"5-;v$r2A$7$F!"$=$N(B +$B7k2L$r;H$$$^$9!#5-;v$No$3$l$O5-;v$,G[Aw$5$l$?;~9o$HF1$8$G$9$,!"5-;v$NJT=8$O$=$l$rC5n0J30$N(B) $B5-;v$N0\F0$b$^$?!"5-;v$r(B) $B$G!"$+$D$=$N%Q%i%a!<%?$,F1$8L>A0$N%0%k!<%W$KB0(B $B$5$J$$>l9g!"4|8B@Z$l>C5n$,9T$J$o$l$k:]$K!"5-;v$O>C5n$5$l$kA0$K;XDj$5$l$?(B -$B%0%k!<%W$K0\F0$5$;$i$l$^$9!#(B@emph{$B$3$l$,(B nnmaildir $B%0%k!<%W$K@_Dj$5$l$k(B -$B$H!"0\F0@h$N%0%k!<%W$K$*$$$F!"5-;v$,85$N%0%k!<%W$K$"$C$?$H$-$H$A$g$&$IF1(B -$B$8$@$18E$/$J$j$^$9!#(B} $B$7$?$,$C$F!"0\F0@h$N%0%k!<%W$K$*$1(B +$B%0%k!<%W$K0\F0$5$;$i$l$^$9!#(B@emph{$B$3$l$,(B @code{nnmaildir} $B%0%k!<%W$K@_Dj(B +$B$5$l$k$H!"0\F0@h$N%0%k!<%W$K$*$$$F!"5-;v$,85$N%0%k!<%W$K$"$C$?$H$-$H$A$g(B +$B$&$IF1$8$@$18E$/$J$j$^$9!#(B} $B$7$?$,$C$F!"0\F0@h$N%0%k!<%W$K$*$1(B $B$k(B @code{expire-age} $B$K$OCm0U$7$F2<$5$$!#$3$l$,%Q%i%a!<%?$,B0$9$k$N$HF1(B $B$8%0%k!<%W$NL>A0$K@_Dj$5$l$k$H!"5-;v$O$^$C$?$/4|8B@Z$l>C5n$5$l$^$;$s!#%Y(B $B%/%H%k<0$r;H$&$H!":G=i$NMWAG$,0l2s!"$=$l$>$l$N5-;v$K$D$$$FI>2A$5$l$^$9!#(B $B$7$?$,$C$F!"5-;v$r$I$3$KCV$/$+$r7h$a$k$?$a$K!"$=$N<0(B $B$O(B @code{nnmaildir-article-file-name} $B$J$I$K>H2q$9$k$3$H$,$G$-$^$9!#(B @emph{$B$3$N%Q%i%a!<%?$,@_Dj$5$l$F$$$J$$$H!"(B -nnmaildir $B$O(B @code{expiry-target} $B%0%k!<%W%Q%i%a!<%?(B +@code{nnmaildir} $B$O(B @code{expiry-target} $B%0%k!<%W%Q%i%a!<%?(B $B$d(B @code{nnmail-expiry-target} $BJQ?t$r8\$_$^$;$s!#(B} @item read-only -$B$3$l$,(B @code{t} $B$K@_Dj$5$l$F$$$k$H!"(Bnnmaildir $B$O$=$N5-;v$r$3$N%0%k!<%W$G(B -$BFI$_=P$7@lMQ$H$7$F07$$$^$9!#$3$N0UL#$O!"5-;v$O(B @file{new/} $B$+(B +$B$3$l$,(B @code{t} $B$K@_Dj$5$l$F$$$k$H!"(B@code{nnmaildir} $B$O$=$N5-;v$r$3$N%0(B +$B%k!<%W$GFI$_=P$7@lMQ$H$7$F07$$$^$9!#$3$N0UL#$O!"5-;v$O(B @file{new/} $B$+(B $B$i(B @file{cur/} $B$K2~L>$5$l$J$$!"5-;v$O(B @file{cur/} $B$G$O$J(B $B$/(B @file{new/} $B$G$N$_8+$D$+$k!"5-;v$O>C5n$5$l$J$$!"5-;v$OJT=8$G$-$J$$!"(B $B$H$$$&$3$H$G$9!#(B@file{new/} $B$OB>$N(B maildir $B$N(B @file{new/} $B%G%#%l%/%H%j!"(B @@ -14150,44 +14291,44 @@ nnmaildir $B$O(B @code{expiry-target} $B%0%k!<%W%Q%i%a!<%?(B $BDj$5$l$F$$$k4X?t$G$9!#(B @item distrust-Lines: -$BHs(B-@code{nil} $B$G$"$k$H!"(Bnnmaildir $B$O(B @code{Lines:} $B%X%C%@!<%U%#!<%k%I$r(B -$B;H$&Be$o$j$K$$$D$b5-;v$N9T?t$r?t$($^$9!#(B@code{nil} $B$@$C$?>l9g$O!"$"$l$P(B -$B$=$N%X%C%@!<%U%#!<%k%I$,;H$o$l$^$9!#(B +$BHs(B-@code{nil} $B$G$"$k$H!"(B@code{nnmaildir} $B$O(B @code{Lines:} $B%X%C%@!<%U%#!<(B +$B%k%I$r;H$&Be$o$j$K$$$D$b5-;v$N9T?t$r?t$($^$9!#(B@code{nil} $B$@$C$?>l9g$O!"(B +$B$"$l$P$=$N%X%C%@!<%U%#!<%k%I$,;H$o$l$^$9!#(B @item always-marks @code{['(read expire)]} $B$N$h$&$J0u%7%s%\%k$N%j%9%H$G$9!#(BGnus $B$,5-;v$N0u(B -$B$r(B nnmaildir $B$K?R$M$k$H$-$O$$$D$G$b!"%U%!%$%k%7%9%F%`$K3JG<$5$l$F$$$k0u(B -$B$,2?$G$"$k$+$H$OL54X78$K!"(Bnnmaildir $B$O$9$Y$F$N5-;v$,$3$l$i$N0u$r;}$C$F$$(B -$B$k$HEz$($^$9!#$3$l$O9=A[$r;n$9$?$a$N5!G=$G!"$*$=$i$/7k6I$O:o=|$5$l$k$G$7$g(B -$B$&!#$=$l$O(B Gnus $BK\BN$G9T$o$l$k$+!"$"$k$$$OM-1W$G$J$1$l$PJ|4~$5$l$k$Y$-$G(B -$B$9!#(B +$B$r(B @code{nnmaildir} $B$K?R$M$k$H$-$O$$$D$G$b!"%U%!%$%k%7%9%F%`$K3JG<$5$l$F(B +$B$$$k0u$,2?$G$"$k$+$H$OL54X78$K!"(B@code{nnmaildir} $B$O$9$Y$F$N5-;v$,$3$l$i(B +$B$N0u$r;}$C$F$$$k$HEz$($^$9!#$3$l$O9=A[$r;n$9$?$a$N5!G=$G!"$*$=$i$/7k6I$O(B +$B:o=|$5$l$k$G$7$g$&!#$=$l$O(B Gnus $BK\BN$G9T$o$l$k$+!"$"$k$$$OM-1W$G$J$1$l$P(B +$BJ|4~$5$l$k$Y$-$G$9!#(B @item never-marks @code{['(tick expire)]} $B$N$h$&$J0u%7%s%\%k$N%j%9%H$G$9!#(BGnus $B$,5-;v$N0u(B -$B$r(B nnmaildir $B$K?R$M$k$H$-$O$$$D$G$b!"%U%!%$%k%7%9%F%`$K3JG<$5$l$F$$$k0u(B -$B$,2?$G$"$k$+$H$OL54X78$K!"(Bnnmaildir $B$O$3$l$i$N0u$r;}$C$F$$$k5-;v$OL5$$$H(B -$BEz$($^$9!#(B@code{never-marks} $B$O(B @code{always-marks} $B$r>e=q$-$7$^$9!#$3$l(B -$B$O9=A[$r;n$9$?$a$N5!G=$G!"$*$=$i$/7k6I$O:o=|$5$l$k$G$7$g$&!#$=$l$O(B Gnus -$BK\BN$G9T$o$l$k$+!"$"$k$$$OM-1W$G$J$1$l$PJ|4~$5$l$k$Y$-$G$9!#(B +$B$r(B @code{nnmaildir} $B$K?R$M$k$H$-$O$$$D$G$b!"%U%!%$%k%7%9%F%`$K3JG<$5$l$F(B +$B$$$k0u$,2?$G$"$k$+$H$OL54X78$K!"(B@code{nnmaildir} $B$O$3$l$i$N0u$r;}$C$F$$(B +$B$k5-;v$OL5$$$HEz$($^$9!#(B@code{never-marks} $B$O(B @code{always-marks} $B$r>e=q(B +$B$-$7$^$9!#$3$l$O9=A[$r;n$9$?$a$N5!G=$G!"$*$=$i$/7k6I$O:o=|$5$l$k$G$7$g$&!#(B +$B$=$l$O(B Gnus $BK\BN$G9T$o$l$k$+!"$"$k$$$OM-1W$G$J$1$l$PJ|4~$5$l$k$Y$-$G$9!#(B @item nov-cache-size @acronym{NOV} $B%a%b%j!<%-%c%C%7%e$N%5%$%:$r;XDj$9$k@0?t$G$9!#%9%T!<%I%"%C(B -$B%W$N$?$a$K!"(Bnnmaildir $B$O$=$l$>$l$N%0%k!<%W$N8BDj$5$l$??t$N5-;v$KBP$7$F!"(B -$B%a%b%j!<>e$K(B @acronym{NOV} $B%G!<%?$rJ];}$7$^$9!#(B($B$3$l$O$?$V$sM-MQ$G$O$J$/!"(B -$B>-Mh$O$*$=$i$/:o=|$5$l$k$G$7$g$&(B)$B!#$3$N%Q%i%a!<%?$NCM$O!"%5!<%P!<$,3+DL(B -$B$7$?8e$G:G=i$K%0%k!<%W$,8+$i$l$?$H$-!"$9$J$o$A0lHL$K$O:G=i$K(B Gnus $B$r5/F0(B -$B$7$?$H$-!"$@$1CmL\$5$l$^$9!#%5!<%P!<$,JD$8$i$l$F:F$S3+DL$5$l$k$^$G$O!"(B -@acronym{NOV} $B%-%c%C%7%e$N%5%$%:$OJQ99$5$l$^$;$s!#%G%#%U%)%k%H$O35N,%P%C(B -$B%U%!$KI=<($5$l$k5-;v$N?t$N8+@Q$j(B (@code{tick} $B0u$,$"$C$F(B @code{read} $B$,(B -$BL5$$5-;v$N?t$K>/!9$NM>J,$r2C$($?$b$N(B) $B$G$9!#(B +$B%W$N$?$a$K!"(B@code{nnmaildir} $B$O$=$l$>$l$N%0%k!<%W$N8BDj$5$l$??t$N5-;v$K(B +$BBP$7$F!"%a%b%j!<>e$K(B @acronym{NOV} $B%G!<%?$rJ];}$7$^$9!#(B($B$3$l$O$?$V$sM-MQ(B +$B$G$O$J$/!">-Mh$O$*$=$i$/:o=|$5$l$k$G$7$g$&(B)$B!#$3$N%Q%i%a!<%?$NCM$O!"%5!<(B +$B%P!<$,3+DL$7$?8e$G:G=i$K%0%k!<%W$,8+$i$l$?$H$-!"$9$J$o$A0lHL$K$O:G=i(B +$B$K(B Gnus $B$r5/F0$7$?$H$-!"$@$1CmL\$5$l$^$9!#%5!<%P!<$,JD$8$i$l$F:F$S3+DL$5(B +$B$l$k$^$G$O!"(B@acronym{NOV} $B%-%c%C%7%e$N%5%$%:$OJQ99$5$l$^$;$s!#%G%#%U%)%k(B +$B%H$O35N,%P%C%U%!$KI=<($5$l$k5-;v$N?t$N8+@Q$j(B (@code{tick} $B0u$,$"$C(B +$B$F(B @code{read} $B$,L5$$5-;v$N?t$K>/!9$NM>J,$r2C$($?$b$N(B) $B$G$9!#(B @end table @subsubsection $B5-;v$N<1JL(B $B5-;v$O$=$l$>$l$N(B maildir $B$N(B @file{cur/} $B%G%#%l%/%H%j$K3JG<$5$l$^$9!#3F!9(B $B$N5-;v$K$O(B @code{uniq:info} $B$N$h$&$JL>A0$,IU$1$i$l$^$9!#$3$3(B -$B$G(B @code{uniq} $B$O%3%m%s$r4^$_$^$;$s!#(Bnnmaildir $B$O(B @code{:info} $B$NItJ,$r(B -$BJ];}$7$^$9$,L5;k$7$^$9!#(B($BB>$N(B maildir $B%j!<%@!<$O0lHL$K0u$r3JG<$9$k$?$a$K(B -$B$3$NItJ,$r;H$$$^$9!#(B) @code{uniq} $B$NItJ,$O5-;v$r%f%K!<%/$K<1JL$7!"(B +$B$G(B @code{uniq} $B$O%3%m%s$r4^$_$^$;$s!#(B@code{nnmaildir} $B$O(B @code{:info} $B$N(B +$BItJ,$rJ];}$7$^$9$,L5;k$7$^$9!#(B($BB>$N(B maildir $B%j!<%@!<$O0lHL$K0u$r3JG<$9$k(B +$B$?$a$K$3$NItJ,$r;H$$$^$9!#(B) @code{uniq} $B$NItJ,$O5-;v$r%f%K!<%/$K<1JL$7!"(B maildir $B$N(B @file{.nnmaildir/} $B%5%V%G%#%l%/%H%j$N?'!9$J>l=j$K5-;v$K4XO"$7(B $B$?>pJs$r3JG<$9$k$?$a$K;H$o$l$^$9!#35N,%P%C%U%!$G5-;v$rMW5a$7$?8e$G!"5-;v(B $B$N40A4$J%Q%9L>$,(B @code{nnmaildir-article-file-name} $BJQ?t$+$iF@$i$l$^$9!#(B @@ -14199,28 +14340,28 @@ maildir $B$N(B @file{.nnmaildir/} $B%5%V%G%#%l%/%H%j$N?'!9$J>l=j$K5-;v$K4XO"$ $BMW$O$"$^$j$"$j$^$;$s!#5-;v$N(B @acronym{NOV} $B%G!<%?$O5-;v(B $B$+(B @code{nnmail-extra-headers} $B$,JQ2=$7$?$H$-$K<+F0E*$K99?7$5$l$^(B $B$9!#(B) $BBP1~$9$k(B @acronym{NOV} $B%U%!%$%k$r$?$@>C$9$3$H$K$h$C$FC10l$N5-;v(B -$B$N(B @acronym{NOV} $B%G!<%?$N@8@.$r(B nnmaildir $B$K6/@)$9$k$3$H$O$G$-$^$9!#$7$+(B -$B$7(B @emph{$B$4MQ?4(B}$B!#$3$l$O(B nnmaildir $B$,$3$N5-;v$K?7$7$$5-;vHV9f$r3d$j?6$i(B -$B$;!"(B@code{seen} $B0u!"%(!<%8%'%s%H!"$*$h$S%-%c%C%7%e$K$H$C$FLLE]$J$3$H$K$J(B -$B$j$^$9!#(B +$B$N(B @acronym{NOV} $B%G!<%?$N@8@.$r(B @code{nnmaildir} $B$K6/@)$9$k$3$H$O$G$-$^(B +$B$9!#$7$+$7(B @emph{$B$4MQ?4(B}$B!#$3$l$O(B @code{nnmaildir} $B$,$3$N5-;v$K?7$7$$5-;v(B +$BHV9f$r3d$j?6$i$;!"(B@code{seen} $B0u!"%(!<%8%'%s%H!"$*$h$S%-%c%C%7%e$K$H$C$F(B +$BLLE]$J$3$H$K$J$j$^$9!#(B @subsubsection $B5-;v$N0u(B @file{.nnmaildir/marks/flag/uniq} $B%U%!%$%k$,$"$k>l9g$K!"(B@code{uniq} $B$K$h$C(B $B$F<1JL$5$l$k5-;v$O!"(B@code{flag} $B0u$r;}$D$b$N$H9M$($i$l$^$9!#(B -Gnus $B$,(B nnmaildir $B$K%0%k!<%W$N0u$r?R$M$k$H!"(Bnnmaildir $B$O$=$N$h$&$J%U%!%$(B -$B%k$rC5$7$F!"8+$D$1$?0u$N%;%C%H$rJs9p$7$^$9!#(BGnus $B$,(B nnmaildir $B$K0u$N%;%C(B -$B%H$N3JG<$rMW5a$9$k$H!"(Bnnmaildir $B$OI,MW$JBP1~$9$k%U%!%$%k$r@8@.$7!"$^$?$O(B -$B>C5n$7$^$9!#(B($B$l$N0u$N$?$a$K?7$7$$%U%!%$%k$r:n$k$N$G$O$J$/!"(B -i$B%N!<%I(B $B$r@aLs$9$k$?$a$KC1$K(B @file{.nnmaildir/markfile} $B$X$N%O!<%I%j%s%/(B -$B$rD%$j$^$9!#(B) +Gnus $B$,(B @code{nnmaildir} $B$K%0%k!<%W$N0u$r?R$M$k$H!"(B@code{nnmaildir} $B$O$=(B +$B$N$h$&$J%U%!%$%k$rC5$7$F!"8+$D$1$?0u$N%;%C%H$rJs9p$7$^$9!#(B +Gnus $B$,(B @code{nnmaildir} $B$K0u$N%;%C%H$N3JG<$rMW5a$9$k$H!"(B +@code{nnmaildir} $B$OI,MW$JBP1~$9$k%U%!%$%k$r@8@.$7!"$^$?$O>C5n$7$^$9!#(B($B$l$N0u$N$?$a$K?7$7$$%U%!%$%k$r:n$k$N$G$O$J$/!"(Bi$B%N!<%I(B $B$r@aLs(B +$B$9$k$?$a$KC1$K(B @file{.nnmaildir/markfile} $B$X$N%O!<%I%j%s%/$rD%$j$^$9!#(B) @file{.nnmaildir/marks/} $B$K?7$7$$%G%#%l%/%H%j$r:n$k$3$H$K$h$C$F!"?7$7$$(B $B0u$rAOB$$9$k$3$H$,$G$-$^$9!#0u$rJ];}$7$D$D(B maildir $B$r(B tar $B$G$^$H$a$F%5!<(B $B%P!<$+$i$=$l$r:o=|$7!"8e$G(B tar $B$r$[$I$/$3$H$,$G$-$^$9!#0u%U%!%$%k$r:n@.(B $B$^$?$O>C5n$9$k$3$H$K$h$C$F!"$"$J$?<+?H$,0u$rDI2C$^$?$O:o=|$9$k$3$H$,$G$-(B -$B$^$9!#(BGnus $B$,F0:n$7$F$$$F(B nnmaildir $B%5!<%P!<$,3+DL$7$F$$$k$H$-$K$3$l$r9T(B -$B$J$&>l9g$O!":G=i$K$9$Y$F$N(B nnmaildir $B%0%k!<%W$N35N,%P%C%U%!$+$iB`=P$7$F(B -$B%0%k!<%W%P%C%U%!$G(B @kbd{s} $B$r%?%$%W$7!"$=$N8e%0%k!<%W%P%C%U%!(B +$B$^$9!#(BGnus $B$,F0:n$7$F$$$F(B @code{nnmaildir} $B%5!<%P!<$,3+DL$7$F$$$k$H$-$K(B +$B$3$l$r9T$J$&>l9g$O!":G=i$K$9$Y$F$N(B @code{nnmaildir} $B%0%k!<%W$N35N,%P%C%U%!(B +$B$+$iB`=P$7$F%0%k!<%W%P%C%U%!$G(B @kbd{s} $B$r%?%$%W$7!"$=$N8e%0%k!<%W%P%C%U%!(B $B$G(B @kbd{g} $B$+(B @kbd{M-g} $B$r%?%$%W$9$k$N$,:GNI$G$9!#$=$&$7$J$$$H(B Gnus $B$OJQ(B $B99$rB*$($F$/$l$:$K!"$=$l$i$r85$KLa$7$F$7$^$&$+$b$7$l$^$;$s!#(B @@ -14262,7 +14403,7 @@ i$B%N!<%I(B $B$r@aLs$9$k$?$a$KC1$K(B @file{.nnmaildir/markfile} $B$X$N%O!<% @item nnfolder-newgroups-file @vindex nnfolder-newsgroups-file -$B%0%k!<%W5-=R%U%!%$%k$NL>A0!#(B@xref{Newsgroups File Format}$B!#4{DjCM(B +$B%0%k!<%W5-=R%U%!%$%k$NL>A0!#(B@xref{Newsgroups File Format}. $B4{DjCM(B $B$O(B @file{~/Mail/newsgroups"} $B$G$9!#(B @item nnfolder-get-new-mail @@ -14513,7 +14654,7 @@ Gnus $B$O$3$l$i$N%=!<%9$X$N3&LL$rDs6!$9$k%P%C%/%(%s%I72$r>/$7Hw$($D$D$"$j(B $B$^$9!#(B @menu -* Archiving Mail:: +* Archiving Mail:: * Web Searches:: $BJ8;zNs$K%^%C%A$9$k5-;v$+$i%0%k!<%W$r:n$k(B * Slashdot:: Slashdot $B$N%3%a%s%H$rFI$`(B * Ultimate:: Ultimate Bulletin Board $B%7%9%F%`(B @@ -14556,8 +14697,8 @@ Gnus $B$O$3$l$i$N%=!<%9$X$N3&LL$rDs6!$9$k%P%C%/%(%s%I72$r>/$7Hw$($D$D$"$j(B $B$G$-$^$9!#%G!<%?$rI|5"$5$;$k$K$O%G%#%l%/%H%jLZ(B (tree) $B$r85$KLa$9$3$H$G9T(B $B$J$$!"$=$N%G%#%l%/%H%j$r;X$7<($9$h$&$K(B gnus $B$N%5!<%P!<$NDj5A$KDI2C$7$^$9!#(B @ref{Article Backlog}, @ref{Asynchronous Fetching} $B$*$h$S$=$NB>$O!"%G!<(B -$B%?$r>e=q$-$7$Fe=q$-$7$F/$7(B @acronym{HTML} $B$KJQ49$5$l$^$9!#FC$K!"(B@samp{> } $B$G0zMQ(B -$B$5$l$?%F%-%9%H$O$=$NBe$o$j$K(B @code{blockquote} $B$G0zMQ$5$l!"=pL>$K$O$=$l(B -$B$>$l$N9T$N:G8e$K(B @code{br} $B$,DI2C$5$l$^$9!#$=$l0J30$O!"%a%C%;!<%8%P%C%U%!(B +$B$5$l$?%F%-%9%H$O$=$NBe$o$j$K(B @samp{blockquote} $B$G0zMQ$5$l!"=pL>$K$O$=$l(B +$B$>$l$N9T$N:G8e$K(B @samp{br} $B$,DI2C$5$l$^$9!#$=$l0J30$O!"%a%C%;!<%8%P%C%U%!(B $B$KD>@\(B @acronym{HTML} $B$r=q$/$3$H$,$G$-$^$9!#(BSlashdot $B$O$$$/$D(B $B$+(B @acronym{HTML} $B$rA*JL$9$k$3$H$K5$$r$D$1$F$/$@$5$$!#(B @@ -14711,18 +14852,16 @@ gnus $B$r=*N;$7$?$$$+$b$7$l$^$;$s!#(B @item nnslashdot-active-url @vindex nnslashdot-active-url -$B%K%e!<%95-;v$H%3%a%s%H$r\$7$$$3$H$O0J2<$N%Z!<%8$GCN$k$3$H$,$G$-$^$9!#(B - -@example - @uref{http://emacs-w3m.namazu.org/} - @uref{http://w3m.sourceforge.net/} -@end example - -@findex gnus-group-make-shimbun-group -@kindex G n ($B%0%k!<%W(B) -@code{nnshimbun} $B$r;O$a$k$?$a$N0lHV4JC1$JJ}K!$O%0%k!<%W%P%C%U%!$NE,Ev$J(B -$B>l=j$G(B @kbd{G n asahi RET national RET} $B$J$I$H%?%$%W$9$k$3$H$G$9!#(B -@samp{asahi} $B$O@\B3$7$?$$%5!<%P!<$N%"%I%l%9$r<($9%7%s%\%k$K!"(B -@samp{national} $B$O1\Mw$7$?$$5-;v%0%k!<%W$K$=$l$>$lCV$-49$($F$/$@$5$$!#N>(B -$BJ}$H$bL>A0$NJd40$,$G$-$^$9!#(B -@c $B$^$?$O(B @kbd{B nnshimbun RET asahi RET} $B$G%P%C%/%(%s%I$r%V%i%&%:$9$k$3$H(B -@c $B$K$h$C$F$b5-;v$rFI$`$3$H$,$G$-$^$9!#(B -$B2C$($F!"(B@acronym{HTML} $B$N%I%-%e%a%s%H$r%$%s%i%$%sI=<($5$;$?$$>l9g$O!"(B -@file{~/.gnus.el} $B%U%!%$%k$K0J2<$N@_Dj$r$7$F2<$5$$!#(B - -@lisp -(require 'mime-w3m) -@end lisp - -Web Newspaper $B$K4X$9$k0J2<$N(B @code{nnshimbun} $BJQ?t$rJQ$($k$3$H$,2DG=$G$9(B: - -@table @code -@item nnshimbun-directory -@vindex nnshimbun-directory -@code{nnshimbun} $B$,%U%!%$%k$rJ]B8$9$k%G%#%l%/%H%j!<$G$9!#=i4|CM(B -$B$O(B @samp{~/News/shimbun} $B$G$9!#(B -@end table - -@cindex group parameters -@code{nnshimbun} $B$O(B Gnus $B$,Ds6!$9$kHFMQ$N%0%k!<%W%Q%i%a!<(B -$B%?(B @footnote{$B%0%k!<%W%Q%i%a!<%?$r@_Dj$9$k$?$a$N:G$bl=j$K%+!<%=%k$,$"$k>uBV(B -$B$G(B @kbd{G c} $B$r%?%$%W$9$k$3$H$G$9(B (@xref{Group Parameters})$B!#(B} $B$K2C$($F!"(B -@code{nnshimbun} $B@lMQ$N%0%k!<%W%Q%i%a!<%?$rMxMQ$9$k$3$H$,$G$-$^$9!#$=$l(B -$B$i$O(B @code{nnshimbun-group-parameters} $B$H$$$&C10l$N%0%k!<%W%Q%i%a!<%?$K(B -$B$^$H$a$i$l$F$$$^$9$,!"$=$l$,3F%0%k!<%WKh$K;}$D$3$H$,$G$-$kCM$O%W%m%Q%F%#(B -$B%j%9%H$G!"Nc$($P/$J$/$J$j$^$9!#%0%k!<%W%Q%i%a!<(B -$B%?(B @code{prefetch-articles} $B$,@_Dj$5$l$F$$$J$$$+!"$=$NCM$,(B @code{nil} $B$K(B -$B$J$C$F$$$k%0%k!<%W$G$O!"%0%k!<%W%Q%i%a!<%?(B @code{prefetch-articles} $B$NBe(B -$B$o$j$K%G%#%U%)%k%HCM$H$7$FJQ?t(B @code{nnshimbun-pre-fetch-article} $B$NCM$,(B -$B;H$o$l$^$9!#$3$NJQ?t(B @code{nnshimbun-pre-fetch-article} $B$N=i4|CM(B -$B$O(B @code{off} $B$G$9!#(B - -@item encapsulate-images -@vindex nnshimbun-encapsulate-images -$B$3$N%0%k!<%W%Q%i%a!<%?$,(B @code{off} $B$^$?$O(B @code{nil} $B0J30$NCM$K%;%C%H$5(B -$B$l$F$$$k%0%k!<%W$G$O!"(B@code{nnshimbun} $B$O85$N5-;v$KKd$a9~$^$l$F$$$k2hA|(B -$B%G!<%?$r(B @samp{multipart/related} $B$N7A<0$G5-;v$K$O$a9~$_$^$9!#%0%k!<%W%Q(B -$B%i%a!<%?(B @code{encapsulate-images} $B$,@_Dj$5$l$F$$$J$$$+!"$=$NCM$,(B -@code{nil} $B$K$J$C$F$$$k%0%k!<%W$G$O!"%0%k!<%W%Q%i%a!<(B -$B%?(B @code{encapsulate-images} $B$NBe$o$j$K%G%#%U%)%k%HCM$H$7$FJQ(B -$B?t(B @code{nnshimbun-encapsulate-images} $B$NCM$,;H$o$l$^$9!#$3$NJQ(B -$B?t(B @code{nnshimbun-encapsulate-images} $B$N%G%#%U%)%k%HCM$O!"(B -@code{shimbun} $B%i%$%V%i%j$NJQ?t(B @code{shimbun-encapsulate-images} $B$NCM$G(B -$B$9(B ($B$?$V$s$=$N=i4|CM$O(B @code{t} $B$G$9(B)$B!#(B - -@item index-range -@vindex nnshimbun-index-range -$B%0%k!<%W%Q%i%a!<%?(B @code{index-range} $B$G!"%&%'%V%5!<%P!<$+$ie$KB8:_$9$kL\l9g$,(B -$B$"$j$^$9!#Nc$($P!"%a!<%j%s%0%j%9%H$N5-;v$rDs6!$7$F$$$k%5!<%P!<$N>l9g$O!"(B -$B$=$N5-;v$,Ej9F$5$l$?F|IU$K$h$C$FJ,N`$5$l$?L\l9g$O(B @code{last} $B$r(B -$B;H$C$F2<$5$$!#$3$&$9$k$H:G?7$NL\H$7$F?7Ce5-;v$N8!::$r9T$&$h$&(B -$B$K$J$j$^$9!#(B - -$B%0%k!<%W%Q%i%a!<%?(B @code{index-range} $B$,@_Dj$5$l$F$$$J$$$+!"CM(B -$B$,(B @code{nil} $B$K$J$C$F$$$k%0%k!<%W$G$O!"JQ(B -$B?t(B @code{nnshimbun-index-range} $B$NCM$,%G%#%U%)%k%H$H$7$F;H$o$l$^$9!#(B -$B$J$*!"(B@code{nnshimbun-index-range} $B$N%G%#%U%)%k%HCM$O(B @code{nil} $B$G$9!#(B - -@item nnshimbun-group-parameters-alist -@vindex nnshimbun-group-parameters-alist -@code{nnshimbun-group-parameters-alist} $B$O%+%9%?%^%$%:2DG=$J%f!<%6%*%W%7%g(B -$B%s$G!"3FMWAG$K%0%k!<%WL>$N@55,I=8=$H(B @code{nnshimbun} $B@lMQ$N%0%k!<%W%Q%i(B -$B%a!<%?$HF1$8%W%m%Q%F%#%j%9%H$r;}$D$3$H$,$G$-$kO"A[%j%9%H$G$9!#O"A[%j%9%H(B -$B$N3FMWAG$O$l%0%k!<%W%Q%i%a!<%?$r@_Dj$9$kBe$o$j$K;H$&$3$H$,(B -$B$G$-$^$9!#$b$7@55,I=8=$K%^%C%A$9$k%0%k!<%W$G%0%k!<%W%Q%i%a!<%?$N@_Dj$,9T(B -$B$J$o$l$F$$$?>l9g$O!"$=$N@_DjCM$NJ}$,M%@h$5$l$^$9!#(B -@end table - -@cindex article expiry -@cindex auto-expire -@cindex expiry-wait -@vindex nnmail-expiry-wait-function -@vindex nnmail-expiry-wait -$B$H$3$m$G(B @code{nnshimbun} $B%P%C%/%(%s%I$G$O!"5-;v$N4|8B@Z$l>C5n$r9T$J$&$3(B -$B$H$,$G$-$^$9(B @footnote{@code{nnshimbun} $B%0%k!<%W$G<+F04|8B@Z$l>C5n$r9T$J(B -$B$&J}K!$K$O$N@55,I=8=$r(B @code{gnus-auto-expirable-newsgroups} $B$KDI2C$7$F!">C5n$9(B -$B$k$^$G$NF|?t$r3F%0%k!<%WKh$K(B @code{nnmail-expiry-wait-function} $B$G;XDj$9(B -$B$k$3$H!#$b$&0l$D$O(B @code{nnshimbun} $B$N3F%0%k!<%WKh$K%0%k!<%W%Q%i%a!<(B -$B%?(B @code{auto-expire} $B$r(B @code{t} $B$K$7$F!"F1$8$/%0%k!<%W%Q%i%a!<(B -$B%?(B @code{expiry-wait} $B$G>C5n$9$k$^$G$NF|?t$r;XDj$9$k$d$jJ}$G$9!#>\$7$$$3(B -$B$H$O(B @xref{Expiring Mail} $B$r;2>H$7$F2<$5$$!#$J$*K\JT$G$b?($l$F$$$^$9$,!"(B -$B8D!9$KF|?t$r@_Dj$7$J$$>l9g$O%G%#%U%)%k%H$NCM$,E,MQ$5$l$^$9!#(B}$B!#$"$"!"$b(B -$B$A$m$s$"$J$?$,;0F|A0$N?7J95-;v$r>C5n$9$k$h$&$K@_Dj$7$?$+$i$H$$$C$F!"?7J9(B -$BC$($F$7$^$&$o$1$G$O$"$j$^$;$s!#>C$($k$N(B -$B$O$"$J$?8D?M$,;}$C$F$$$k(B @code{nnshimbun} $BMQ$N(B @acronym{NOV} $B%U%!%$(B -$B%k(B @footnote{@code{nnshimbun} $BMQ$N(B @acronym{NOV} $B%U%!%$%k$H(B -$B$O(B ``~/News/shimbun/asahi/national/.overview'' $B$N$h$&$J$b$N$G$9!#(B} $B$N3:(B -$BEv$9$kItJ,$G!"$=$l$K$h$C$F$=$N5-;v$OFsEY$H35N,%P%C%U%!$K8=$l$J$/$J$j$^$9!#(B - -@code{nnshimbun} $B%P%C%/%(%s%I$G$O5-;v$N4|8B@Z$l>C5n$r9T$J$o$J$$(B -$B$H(B @acronym{NOV} $B%U%!%$%k$,:]8BL5$/B@$jB3$1!"?7J9l9g$K$O!"2a5n$NA45-;v$rJ](B -$BM-$7$F$$$k>l9g$,>/$J$/$J$$$G$7$g$&!#@N$"$J$?$,6=$8$?0lO"$N5-;v$rFI$_JV$7(B -$B$F2{$+$7$`$?$a$K!"$=$&$$$&%0%k!<%W$G$O4|8B@Z$l>C5n$O$5$;$?$/$J$$$H;W$&$+(B -$B$b$7$l$^$;$s!#(B - -$B$N%a!<%k%P%C%/%(%s%I$HF1MM$NJ}(B -$BK!$G%0%k!<%WKh$K<+F04|8B@Z$l>C5n2DG=$K$7$?$j!";D$7$F$*$/4|4V$r@_Dj$9$k$3(B -$B$H$,$G$-$k$N$G$9!#(B - -$B$?$@(B @code{nnshimbun} $B%P%C%/%(%s%I$N4|8B@Z$l>C5n$K$O!"B>$N%a!<%k%P%C%/%((B -$B%s%I$H>/$7$@$10c$&E@$,$"$j$^$9!#Bh0l$K!";D$7$F$*$/4|4V$N%G%#%U%)%k%HCM$K(B -@code{shimbun} $B%i%$%V%i%j$,Ds6!$9$kCM$,4X78$7!"0J2<$NM%@hEY$G4|4V$,7hDj(B -$B$5$l$k$3$H$G$9!#(B +$B%&%'%V$K4p$E$$$?%P%C%/%(%s%I$G$"$k(B @samp{nnshimbun} $B$O!"(B2003$BG/(B6$B7n(B18$BF|$r(B +$B0J$F(B emacs-w3m $B%Q%C%1!<%8$K0\@R$5$l$^$7$?!#:#$^$G$N$h$&$K(B T-gnus $B$G%&%'(B +$B%V$N?7J9$r1\Mw$7$?$$$N$G$"$l$P!":G?7HG$N(B emacs-w3m $B$r%$%s%9%H!<%k$9$kI,(B +$BMW$,$"$j$^$9!#$=$N:]!"(B@emph{$BI,$:(B} T-gnus $BM3Mh(B +$B$N(B @file{nnshimbun.el} $B$H(B @file{nnshimbun.elc} $B%U%!%$%k$r>C$7$F2<$5$$!#(B +Emacs-w3m $B$O30It%3%^%s%I(B w3m $B$X$N(B Emacs $B$N%$%s%?!<%U%'!<%9$G$9!#>\:Y>pJs(B +$B$K$D$$$F$O0J2<$N%Z!<%8$rK,$M$F$_$F2<$5$$!#(B @example -$B%0%k!<%W%Q%i%a!<%?$N(B @code{expiry-wait} -@code{nnmail-expiry-wait-function} $B$rI>2A$7$?CM(B -@code{shimbun} $B%i%$%V%i%j$,Ds6!$9$k%0%k!<%WKh$N%G%#%U%)%k%HCM(B -@code{nnmail-expiry-wait} $B$NCM(B +@c Don't use @uref{} here, or old texinfmt will neglect @example. :-( +http://emacs-w3m.namazu.org/ +http://w3m.sourceforge.net/ @end example -$BBhFs$K!"(B@code{nnmail-expiry-wait-function} $B$,4X?t$@$C$?>l9g$K!"$=$N0z?t(B -$B$KM?$($i$l$kJ8;zNs$K(B ``nnshimbin+asahi:national'' $B$N$h$&$K%P%C%/%(%s%I$H(B -$B%5!<%P!<$NL>A0$,4^$^$l$k$3$H$G$9!#B>$N%a!<%k%P%C%/%(%s%I$N>l9g$K$O%0%k!<(B -$B%WL>$@$1$,M?$($i$l$k$N$K!"$G$9!#0l$DNc$r5s$2$^$7$g$&!#(B - -@lisp -(setq nnmail-expiry-wait-function - (lambda (group) - (cond ((string-equal group "wl") 7) - ((string-equal group "nnshimbun+airs:wl") 'never)))) -@end lisp - -$B$3$l$O!"Nc$($P(B @code{nnml} $B$d(B @code{nnmh} $B$GC5n$9$k$,!"(B@code{nnshimbun} $B$GFI$`F1(B -$B$8%a!<%j%s%0%j%9%H$N%"!<%+%$%V$O$9$Y$FFI$a$k>uBV$K$7$F$*$/!"$H$$$&$3$H$G(B -$B$9!#$I$&$G$9!"$J$+$J$+8-$$$G$7$g(B? - -$BBh;0$K!"$3$l$O$"$J$?$,IT?3$K;W$C$?$H$-$K;W$$=P$7$F$/$l$k$3$H$r4|BT$7$F=q(B -$B$$$F$*$-$^$9$,!"%0%k!<%W$N$9$Y$F$N5-;v$,4|8B@Z$l>C5n$NBP>]$K$J$C$F$7$^$C(B -$B$?$H$-$K!"(B@code{nnshimbun} $B$O:G8e$N0lDL$@$1$O>C$5$:$K;D$7$F$*$-$^$9!#$3(B -$B$l$O$"$J$?$NL$N}?4$rK~B-$5$;$k$?$a$G$O$J$/!"%5!<%P!<$+$i8E$$5-;v$r:F$S$N:v$J$N$G$9!#(B - -@code{nnshimbun} $B$N4|8B@Z$l>C5n$K4X78$9$k%0%k!<%W%Q%i%a!<%?$HJQ?t$O0J2<(B -$B$NDL$j$G$9!#(B - -@table @code -@item expiry-wait -@cindex expiry-wait -$B$I$&$+:.Mp$J$5$i$J$$$h$&$K!#(Bgnus $B$,Ds6!$7$F$$$kHFMQ$N%0%k!<%W%Q%i%a!<(B -$B%?(B @code{expiry-wait} $B$HF1$8L>A0$G0UL#$bF1$8$b$N$,(B @code{nnshimbun} $B@lMQ(B -$B$N%0%k!<%W%Q%i%a!<%?$K$bMQ0U$5$l$F$$$^$9!#$"$J$?$O$I$A$i$r;H$C$F$b9=$$$^(B -$B$;$s!#$b$7(B @code{nnshimbun} $B@lMQ$N%0%k!<%W%Q%i%a!<%?$NJ}$r(B @code{nil} $B0J(B -$B30$NCM$K@_Dj$9$k$H!"HFMQ$N%0%k!<%W%Q%i%a!<%?$NCM$h$j$bM%@h$7$F;H$o$l$^$9!#(B -$B$3$l$O!"%0%k!<%W%P%C%U%!$G(B @kbd{G c} $B$r%?%$%W$7$?$H$-$K8=$l$kJT=82hLL$K(B -$B$*$$$F!"(B@code{nnshimbun} $B$K4X78$9$k$b$N$r0l2U=j$K=8$a$k$?$a$H!"%f!<%6%*(B -$B%W%7%g%s(B @code{nnshimbun-group-parameters-alist} $B$G0l3g$7$F4IM}$G$-$k$h(B -$B$&$K$9$k$3$H$rL\E*$KMQ0U$7$?$b$N$G$9(B @footnote{$B$J(B -$B$<(B @code{auto-expire} $B$J$I$b(B @code{nnshimbun} $B@lMQ$N%0%k!<%W%Q%i%a!<%?$K(B -$B4^$a$F$*$$$F$/$l$J$$$N(B? $B$H$$$&Ld$$$KBP$9$kEz$($rMQ0U$7$F$$$^$9!#(B -@code{expiry-wait} $B$r;2>H$9$k$N$,(B @code{nnshimbun} $B%P%C%/%(%s%I$J$N$KBP(B -$B$7$F!"(B@code{auto-expire} $B$J$I$r;2>H$9$k$N$O(B Gnus $B$NK\BN$J$N$G$9$,!"K\BN(B -$B$N5!G=$rFCDj$N%P%C%/%(%s%I$NLLE]$r8+$k$h$&$K3HD%$9$k$N$O!"(BGnus $B$N@_7W;W(B -$BA[$KH?$7$F$$$k$+$i$G$9!#(B}$B!#@_Dj$G$-$kCM$OHFMQ$N%0%k!<%W%Q%i%a!<%?$HF1MM(B -$B$K!";~8B>C5n$NF|?t!"(B@code{never} $B$^$?$O(B @code{immediate} $B$G$9!#(B - -@item nnshimbun-keep-unparsable-dated-articles -@vindex nnshimbun-keep-unparsable-dated-articles -$B$3$NJQ?t$NCM$,(B @code{nil} $B$G$J$$>l9g$O!":n@.$5$l$?$jAw?.$5$l$?;~9o$,$h$/(B -$B$o$+$i$J$$5-;v$r4|8B@Z$l>C5n$7$^$;$s!#$J$K$7$m4|8B$,$o$+$i$J$$$s$G$9$+$i!#(B -$B=i4|CM$O(B @code{t} $B$G$9$,!"(B@code{nil} $B$K$9$k$H4|8B@Z$l>C5n$N=hM}$,9T$J$o(B -$B$l$k$H$-$K!"4|8B$,$o$+$i$J$$5-;v$G$bM-L5$r8@$o$:>C$7$F$7$^$$$^$9!#$^$"!"(B -$BG/$NJk$l$NBgA]=|$N$H$-$K$G$b;H$C$F2<$5$$!#(B -@end table +@c This comment line is needed to prevent texinfmt bug. :-( +$B$"$J$?$N%7%9%F%`$K$9$G$K(B emacs-w3m $B$,%$%s%9%H!<%k$5$l$F$$$k$N$J$i$P!"(B +(@pxref{Nnshimbun, , Nnshimbun, emacs-w3m-ja, Emacs-w3m-ja}) $B$r;2>H$7$F(B +$B2<$5$$!#(B @node RSS @subsection RSS @cindex nnrss @cindex RSS -$B$$$/$D$+$N%5%$%H$O(B RDF site summary (RSS) $B$r;}$C$F$$$^(B -$B$9(B @uref{http://purl.org/rss/1.0/spec}$B!#$3$l$O$H$F$b5,B'E*$+$DNIo$K?7$7$/$7$F$*$/$?$a$N>pJs$rF@$k$3$H(B -$B$,$G$-$^$9!#(B +$B$$$/$D$+$N%5%$%H$O(B RDF site summary (@acronym{RSS}) $B$r;}$C$F$$$^$9!#(B +@acronym{RSS} $B$O!"%K%e!<%9$K4XO"$9$k%5%$%H(B (BBC $B$d(B CNN $B$N$h$&$J(B) $B$No$K?7$7$/$7$F$*$/$?$a$N>pJs$rF@$k$3$H$,$G$-$^$9!#(B -$B4JC1$K(B @code{nnrss} $B$r;H$$;O$a$k$K$O!"%0%k!<%W%P%C%U%!(B -$B$G(B @kbd{B nnrss RET RET} $B$H%?%$%W$7$F!"%0%k!<%W$r9VFI$7$F2<$5$$!#(B +@kindex G R ($B35N,(B) +Feed $B$r9VFI$9$k$K$O!"35N,%P%C%U%!$+$i(B @kbd{G R} $B$r;H$C$F2<$5$$(B---feed $B$N(B +$B=j:_$NF~NO$r5a$a$i$l$k$G$7$g$&!#(B + +$B4JC1$K(B @code{nnrss} $B$r$O$8$a$kJ}K!$O!"%0%k!<%W%P%C%U%!$G(B @kbd{B nnrss +RET y} $B$N$h$&$J$3$H$r>'$(!"$=$7$F%0%k!<%W$r9VFI$9$k$3$H$G$9!#(B $B0J2<$N(B @code{nnrss} $BJQ?t$,JQ992DG=$G$9(B: @@ -15057,6 +14991,14 @@ Web Newspaper $B$K4X$9$k0J2<$N(B @code{nnshimbun} $BJQ?t$rJQ$($k$3$H$,2DG=$G$ @vindex nnrss-directory @code{nnrss} $B$,%U%!%$%k$r=q$-9~$`%G%#%l%/%H%j!<$G!"%G%#%U%)%k%H(B $B$O(B @file{~/News/rss/} $B$G$9!#(B + +@item nnrss-use-local +@vindex nnrss-use-local +@findex nnrss-generate-download-script +@code{nnrss-use-local} $B$r(B @code{t} $B$K@_Dj$9$k$H!"(B +@code{nnrss} $B$O(B @code{nnrss-directory} $B$K$"$k%m!<%+%k%U%!%$%k$+$i(B feed +$B$rFI$_$^$9!#(B@code{nnrss-generate-download-script}$B%3%^%s%I$r;H$&$3$H$K$h$C(B +$B$F!"(B@command{wget} $B$r;H$C$?%@%&%s%m!<%I!&%9%/%j%W%H$r:n$k$3$H$,$G$-$^$9!#(B @end table $B35N,%P%C%U%!$K@bL@$rI=<($5$;$?$$$J$i$P!"0J2<$N%3!<%I$,Lr$KN)$D$G$7$g$&!#(B @@ -15148,7 +15090,7 @@ Gnus $B$O%&%'%V%Z!<%8$rH$7$F2<$5$$!#(B +@ref{Mail Sources} $B$r;2>H$7$F2<$5$$!#(B @acronym{IMAP} $B$r%a!<%k$rCyB"$9$k%W%m%H%3%k$H$7$F;H$$$?$$$H$-$O!"(B @code{gnus-secondary-select-methods} $B$K(B nnimap $B$rEPO?$7$F2<$5$$!#$3$l$K(B @@ -15276,7 +15218,7 @@ Gnus $B$O%&%'%V%Z!<%8$r(B/$B%Q%9%o!<%I(B $B$G$9!#30(B -$BIt%i%$%V%i%j(B @code{digest-md5.el} $B$,I,MW$G$9!#(B +$BIt%i%$%V%i%j(B @file{digest-md5.el} $B$,I,MW$G$9!#(B @item @dfn{cram-md5:} CRAM-MD5 $B$G0E9f2=$5$l$?(B $BMxMQ(B/$B%Q%9%o!<%I(B $B$G$9!#(B @item @dfn{login:} LOGIN $B7PM3$G$N@8$N(B $BMxMQ(B/$B%Q%9%o!<%I(B $B$G$9!#(B @item -@dfn{anonymous:} $BEE;R%a!<%k%"%I%l%9$r%Q%9%o!<%I$H$7!"(B`anonymous' $B$H$7$F(B -$B%m%0%$%s$7$^$9!#(B +@dfn{anonymous:} $BEE;R%a!<%k%"%I%l%9$r%Q%9%o!<%I$H$7$FM?$(!"(B +``anonymous'' $B$H$7$F%m%0%$%s$7$^$9!#(B @end itemize @item nnimap-expunge-on-close @@ -15373,7 +15315,7 @@ Gnus $B$O%&%'%V%Z!<%8$rC5n$7$^$;$s!#8=:_$O!">C5n$N0u$,IU$$$?5-;v$r(B nnimap $B$GI=<($9(B $B$kJ}K!$O$"$j$^$;$s$,!"B>$N(B @acronym{IMAP} $B%/%i%$%"%s%H$O$G$O$G$-$k$+$b$7(B $B$l$^$;$s!#C5n$5$l$?5-;v$r:o=|$9$k$+$I$&$+(B $B$r?R$M$^$9!#(B @@ -15438,6 +15380,7 @@ nnimap $B$K5-;v$NFbItE*$JF|IU$NBe$o$j$K(B Date: $B$r;H$&$h$&$K$5$;$^$9!#$5$i$ * Editing IMAP ACLs:: $B%a!<%k%\%C%/%9$X$NB>$NMxMQA06u4V$r;H$&(B($B;H$o$J$$(B)$BJ}K!(B +* Debugging IMAP:: $B$b$N$4$H$,F/$+$J$$$H$-$K$9$k$Y$-$3$H(B @end menu @node Splitting in IMAP @@ -15452,6 +15395,10 @@ nnimap $B$K5-;v$NFbItE*$JF|IU$NBe$o$j$K(B Date: $B$r;H$&$h$&$K$5$;$^$9!#$5$i$ $B$=$7$Fl@j(B +$BM-N($rA}$7$F!"$$$/$D$b$N(B IMAP $B%5!<%P!<$K$h$C$F%5%]!<%H$5$l$k$h$&$K$J$j$^(B +$B$7$?!#9,$$$K(B gnus $B$b$=$l$r%5%]!<%H$7$^$9!#(B@xref{Sieve Commands}.) + $B4XO"$9$kJQ?t$O;0$D$G$9(B: @table @code @@ -15507,7 +15454,7 @@ Nnmail $B$KBP1~$9$k$b$N$O$"$j$^$;$s!#(B $B$r(B INBOX.junk $B$KF~$l!"$=$NB>A4$F$N$b$N$r(B INBOX.private $B$KF~$l$^$9!#(B $B:G=i$NJ8;zNs$O!"(Breplace-match $B$G9gCW$7$?%F%-%9%H$+$iI{I=8=$rA^F~$9$k$H$-(B -$B$K;HMQ$5$l$k$N$HF1$8$h$&$J!"(B`\\1' $B7A<0$r4^$`$3$H$,$G$-$^$9!#Nc$($P(B: +$B$K;HMQ$5$l$k$N$HF1$8$h$&$J!"(B@samp{\\1} $B7A<0$r4^$`$3$H$,$G$-$^$9!#Nc$($P(B: @lisp ("INBOX.lists.\\1" "^Sender: owner-\\([a-z-]+\\)@@") @@ -15577,7 +15524,7 @@ Nnmail $B$GBP1~$9$k$b$N(B: @code{nnmail-split-methods}. $B$b$7$"$J$?$,FC5iJ,3d$r;H$$$?$$$J$i$P!"(B@code{nnimap-split-rule} $B$NCM(B $B$r(B @code{nnmail-split-fancy} $B$K@_Dj$9$k$3$H$,$G$-$^$9!#(B -@xref{Fancy Mail Splitting}$B!#(B +@xref{Fancy Mail Splitting}. $B$7$+$7(B nnmail $B$H(B nnimap $B$H$G0[$J$kFC5iJ,3dJ}<0$r;}$D$h$&$K$9$k$K$O!"(B @code{nnimap-split-rule} $B$NCM$r(B @code{nnimap-split-fancy} $B$K@_Dj$7$F!"(B @@ -15642,7 +15589,7 @@ Nnmail $B$GBP1~$9$k$b$N(B: @code{nnmail-split-fancy}. @cindex editing imap acls @cindex Access Control Lists @cindex Editing @acronym{IMAP} ACLs -@kindex G l +@kindex G l ($B%0%k!<%W(B) @findex gnus-group-nnimap-edit-acl ACL $B$O(B Access Control List ($B;HMQ@)8B0lMw(B) $B$NN,$G$9!#(B@acronym{IMAP} $B$G(B @@ -15674,11 +15621,11 @@ ACL $B$O(B Access Control List ($B;HMQ@)8B0lMw(B) $B$NN,$G$9!#(B@acronym{I @cindex expunge @cindex manual expunging -@kindex G x +@kindex G x ($B%0%k!<%W(B) @findex gnus-group-nnimap-expunge @code{nnimap-expunge-on-close} $B$K(B @code{never} $B$r@_Dj$7$F$$$l$P!"%a!<%k(B -$B%\%C%/%9$NA4$F$N>C5n$5$l$?5-;v$rC5n$5$l$?5-;v$rC5n$5$l$?5-;v$rI=<($9$kJ}K!$O$"$j$^$;$s!#$?$@>C5n$G$-$k$@$1(B @@ -15727,6 +15674,37 @@ ACL $B$O(B Access Control List ($B;HMQ@)8B0lMw(B) $B$NN,$G$9!#(B@acronym{I $B=q$r8+$F2<$5$$!#$=$l$i$O6/NO$J9)6q$J$N$G!"$I$s$J8z2L$,$"$k$+$,3N$+$J>l9g(B $B$@$1;H$C$F2<$5$$!#(B +@node Debugging IMAP +@subsection IMAP $B$N%G%P%C%0(B +@cindex IMAP debugging +@cindex protocol dump (IMAP) + +@acronym{IMAP} $B$O(B @acronym{NNTP} $B$d(B @acronym{POP3} $B$h$j$b$C$HJ#;($J%W%m(B +$B%H%3%k$G$9!#e$N%P%0$,L5$$$H$O8@$$@Z$l$J$$$N$G!";d$?$A$O!"$9$0$K$=$l(B +$B$i$rD>$9$?$a$K:GA1$r?T$/$7$^$9!#$"$J$?$,4qL/$J?6$kIq$$$K=P2q$C$?$H$7$?$i!"(B +$B%5!<%P!<$+(B gnus $B$N$I$A$i$+$K%P%0$,$"$k2DG=@-$,$"$j$^$9!#(B + +$B$"$J$?$,0lHLE*$J%M%C%H%o!<%/!&%W%m%H%3%k$K@:DL$7$F$$$k$J$i$P!"(BGnus $B$H%5!<(B +$B%P!<$N4V$G$d$j$H$j$5$l$k%W%m%H%3%k!&%@%s%W$rFI$`$3$H$K$h$C$F!"$*$=$i$/$$(B +$B$/$D$+$N)Ne$7$^$9!#(B + +@vindex imap-log +$B%W%m%H%3%k!&%@%s%W$O!"$=$l$rM-8z$K$7$F$$$k$H$?$/$5$s$N%G!<%?$r@8@.$9$k$N(B +$B$G!"%G%#%U%)%k%H$G$OL58z$K$J$C$F$$$^$9!#M-8z$K$9$k$K$O!"0J2<$N$h$&(B +$B$K(B @code{imap-log} $B$r@_Dj$7$F2<$5$$(B: + +@lisp +(setq imap-log t) +@end lisp + +$B$3$l$O(B @code{imap.el} $B%Q%C%1!<%8$K!"%5!<%P!<$H$N$d$j$H$j$r2?$G$b5-O?$5$;(B +$B$^$9!#$=$N5-O?$O(B @samp{*imap-log*} $B$H$$$&%P%C%U%!$K3JG<$5$l$^$9!#$H$-$H(B +$B$7$F(B @code{BAD} $B$H$$$&;%$,IU$1$i$l$k!"%(%i!<%a%C%;!<%8$rC5$7$F2<$5$$!#$G(B +$B$b!"%P%0$rDs=P$9$k$H$-$O!"$9$Y$F$N%G!<%?$r4^$a$k$h$&$K$7$F2<$5$$!#(B + @node Other Sources @section $B$=$NB>$N%0%k!<%W8;(B @@ -16528,10 +16506,11 @@ nnvirtual $B%0%k!<%W(B (@dfn{nnvirtual group}) $B$O$N%0%k!<%W$N=89g0J>e @cindex kibozing @dfn{Kiboze} $B$9$k!"$H$O!"(B``$B%K%e!<%9%9%W!<%kA4It(B ($B$"$k$$$O$=$N0lIt(B) $B$+(B -$B$i(B grep $B$9$k$3$H(B'' $B$H%*%C%/%9%U%)!<%IBg<-E5$K$h$C$FDj5A$5$l$F$$$^$9!#(B -@code{nnkiboze} $B$O$3$l$r$"$J$?$N$?$a$K9T$C$F$/$l$k%P%C%/%(%s%I$G$9!#4r$7(B -$B$$$M(B! $B$3$l$G$I$s$J(B @acronym{NNTP} $B%5!<%P!<$G$b!"Lr$KN)$?$J$$MW5a$G;_$^$C(B -$B$F$7$^$&$^$G9s;H$9$k$3$H$,$G$-$k$M!#$"$"!"$J$s$F9,$;$J$s$@(B! +$B$i(B grep $B$9$k$3$H(B'' $B$H(B @acronym{OED} ($B%*%C%/%9%U%)!<%IBg<-E5(B) $B$K$h$C$FDj(B +$B5A$5$l$F$$$^$9!#(B@code{nnkiboze} $B$O$3$l$r$"$J$?$N$?$a$K9T$C$F$/$l$k%P%C%/(B +$B%(%s%I$G$9!#4r$7$$$M(B! $B$3$l$G$I$s$J(B @acronym{NNTP} $B%5!<%P!<$G$b!"Lr$KN)$?(B +$B$J$$MW5a$G;_$^$C$F$7$^$&$^$G9s;H$9$k$3$H$,$G$-$k$M!#$"$"!"$J$s$F9,$;$J$s(B +$B$@(B! @kindex G k ($B%0%k!<%W(B) kiboze $B%0%k!<%W$r:n@.$9$k$K$O!"%0%k!<%W%P%C%U%!$G(B @kbd{G k} $BL?Na$r;H$$$^(B @@ -16564,9 +16543,9 @@ Gnus $B$O$=$N(B @code{nnkiboze} $B%0%k!<%W$N0lIt$H$J$k$Y$-5-;v$,$"$k$+$I$&$+$ $B$bNI$$$7!"30It%0%k!<%W$G$b9=$$$^$;$s!#L5@)8B$G$9!#(B @vindex nnkiboze-directory -@code{nnkiboze} $B%0%k!<%W$N@8@.$K$h$C$F!"Fs$D$N%U%!%$%k(B - @code{nnkiboze-directory} $BFb$K:n@.$5$l$^$9!#$3$N=i4|@_DjCM(B -$B$O(B @file{~/News/} $B$G$9!#0lJ}$N%U%!%$%k$O$=$N%0%k!<%W$NA45-;v(B +@code{nnkiboze} $B%0%k!<%W$N@8@.$K$h$C$F!"Fs$D$N%U%!%$(B +$B%k(B @code{nnkiboze-directory} $BFb$K:n@.$5$l$^$9!#$3$N=i4|@_DjCM(B +$B$O(B @file{~/News/kiboze/} $B$G$9!#0lJ}$N%U%!%$%k$O$=$N%0%k!<%W$NA45-;v(B $B$N(B @acronym{NOV} $B%X%C%@!<9T$r4^$s$G$$$F!"$b$&0lJ}$O9=@.5-;v$r8+$D$1$k$?(B $B$a$K$I$N%0%k!<%W$,8!:w$5$l$?$+$N>pJs$r3JG<$9$k!"(B@file{.newsrc} $B$NJd=u%U%!(B $B%$%k$G$9!#(B @@ -16615,7 +16594,7 @@ Namazu $B$r;H$C$F!"%a!<%k$N;3$+$i$"$J$?$N9%$-$J%-!<%o!<%I$r4^$`5-;v$r8+(B @end example $B$3$&$9$k$H!"(Bgnus $B$H(B namazu $B$NAPJ}$N%-!<%o!<%I$rF1;~$K4^$`%a!<%k$rA4$F(B -$BC5$7=P$7!"$=$l$i$N%a!<%k$+$i$J$k2>A[%0%k!<%W$r:n@.$7$^$9(B(@xref{Virtual +$BC5$7=P$7!"$=$l$i$N%a!<%k$+$i$J$k2>A[%0%k!<%W$r:n@.$7$^$9(B (@pxref{Virtual Groups})$B!#(B @kbd{C-c C-n}$B$K$h$C$F8F$S=P$5$l$kL?Na(B @code{gnus-namazu-search} $B$O!"(B @@ -16698,6 +16677,7 @@ Gnus $B$r(B ``$B%*%U%i%$%s(B'' $B$N%K%e!<%9%j!<%@!<$H$7$F;EN)$F$k$N$O6K$a$F * Agent Basics:: $B$3$l$i$O$I$&F0$/$N$+(B * Agent Categories:: $B2?$r%@%&%s%m!<%I$9$k$+$r(B gnus $B%(!<%8%'%s%H$K65$($kJ}K!(B * Agent Commands:: $B3F%P%C%U%!!<$G$N?7$7$$L?Na(B +* Agent Visuals:: $B%(!<%8%'%s%H$,35N,%P%C%U%!$KJQ2=$r$b$?$i$9$+$b$7$l$J$$J}K!(B * Agent as Cache:: $B%(!<%8%'%s%H$OBg$-$J%-%c%C%7%e$G$b$"$k(B * Agent Expiry:: $B8E$$5-;v$r>C$9J}K!(B * Agent Regeneration:: $BDL?.@ZCG$dB>$N;v8N$+$i2sI|$9$kJ}K!(B @@ -16715,17 +16695,41 @@ Gnus $B$r(B ``$B%*%U%i%$%s(B'' $B$N%K%e!<%9%j!<%@!<$H$7$F;EN)$F$k$N$O6K$a$F $B$^$:!"$$$/$D$+$NMQ8l$rJRIU$1$F$*$-$^$7$g$&!#(B -$B$"$J$?$,%M%C%H%o!<%/$H$NDL?.$,@Z$l$F$$$k$H$-(B($B$G%(!<%8%'%s%H$,$=$l$rCN$i(B -$B$5$l$F$$$k$H$-(B)$B$O!"(Bgnus $B%(!<%8%'%s%H$O@Z$jN%$5$l$F$$$k(B (@dfn{unplugged})$B!"(B -$B$H8@$$$^$9!#%M%C%H%o!<%/$NDL?.$,I|3h$7(B ($B$=$7$F(B gnus $B$,$=$l$rCN$l$P(B)$B!"%(!<(B -$B%8%'%s%H$O:9$79~$^$l$F$$$k(B (@dfn{plugged})$B!"$H8@$$$^$9!#(B +$B%M%C%H%o!<%/$H$NDL?.$,@Z$l$F$$$k$H$-(B ($B$=$7$F%(!<%8%'%s%H$,$=$l$rCN$i$5$l(B +$B$F$$$k$H$-(B)$B!"(Bgnus $B%(!<%8%'%s%H$O@Z$jN%$5$l$F$$$k(B (@dfn{unplugged}) $B$H8@(B +$B$$$^$9!#%M%C%H%o!<%/$NDL?.$,I|3h$7(B ($B$=$7$F(B gnus $B$,$=$l$rCN$l$P(B)$B!"%(!<%8%'(B +$B%s%H$O:9$79~$^$l$F$$$k(B (@dfn{plugged}) $B$H8@$$$^$9!#(B $B%m!<%+%k(B (@dfn{local}) $B%^%7%s$H$O!"$"$J$?$,?($C$F$$$k%^%7%s$G!"%M%C%H%o!<(B $B%/$K7QB3E*$K@\B3$5$l$F$$$k$b$N$G$O$"$j$^$;$s!#(B -$B%@%&%s%m!<%I(B (@dfn{download}) $B$H$O%M%C%H%o!<%/$+$i2?$+$r$"$J$?$N%m!<%+%k(B -$B%^%7%s$K$N%K%e!<%9%j!<%@!<$OM-L5$r8@$o$:$"$J$?$K%I%8$rF'$^$;$k$+$b$7$l$^(B +$B$;$s$,!"(Bgnus $B$G$O$"$J$?$KA*Br8"$,$"$j$^$9(B! + +Gnus $B$OuBV$K$b$"$j$^$;$s!#(B +$B$b$C$H@53N$K8@$($P!"%5!<%P!<$4$H$K$=$l$>$l$N>uBV$r;}$A$^$9!#$3$l$O!"$$$/(B +$B$D$+$N%5!<%P!<$,@\B3$G$-$J$$$H$-$K!"B>$N%5!<%P!<$O@\B3$G$-$k$3$H$r0UL#$7(B +$B$^$9!#$5$i$K!"(B Agent $B$K$h$C$F$$$/$D$+$N%5!<%P!<$r$9$Y$FL5;k$9$k$3$H$,$G(B +$B$-$^$9(B ($B$=$N0UL#$O!"$=$l$i$,$$$D$b(B plugged $B$K$J$C$F$$$k$N$H;w$F$$$k$H$$(B +$B$&$3$H$G$9(B)$B!#(B + +Agent $B$r@Z$jN%$7$F$b!"$J$<(B gnus $B$,%M%C%H$K@\B3$7$F$$$k$N$+$,$$$V$+$7$/;W(B +$B$o$l$?$H$-!"9T$&$Y$-uBV$O(B @dfn{offline} $B$G$9!#%5!<%P!<$O$H$-$I$-E~C#2DG=$G$O$J$/(B +$B$J$j$^$9!#(BGnus $B$,$3$N$3$H$rCN$k$H!"$=$N%5!<%P!<$r(B offline $B$N>uBV$K@Z$j49(B +$B$($F$bNI$$$+$I$&$+$r?R$M$^$9!#$O$$!"$HEz$($?$J$i$P!"(B(offline $B$KLa$7$FNI(B +$B$$$+$H(B gnus $B$,?R$M$?>l9g0J30$O(B) $B%5!<%P!<$OB?>/(B unplugged $B$@$C$?$H$-$N$h(B +$B$&$K?6$kIq$$$^$9!#(B $B%(!<%8%'%s%H$r;H$C$?E57?E*$J(B gnus $B$NBPOCA`:n$r8+$F$_$^$7$g$&!#(B @@ -16743,14 +16747,14 @@ Gnus $B$r(B @code{gnus-unplugged} $B$G5/F0$7$^$9!#$3$l$O(B gnus $B%(!<%8%'% $B$79~$`$?$a$K(B @kbd{J j} $B$rC!$-!"$=$7$FIaDL$O?7Ce%a!<%k$r8!::$9$k$?$a(B $B$K(B @kbd{g} $B$r;H$$$^$9!#(Bgnus $B%(!<%8%'%s%H$,@Z$jN%$5$l$F$$(B $B$k(B (@dfn{unplugged}) $B$H$-$N?7Ce%a!<%k$N8!::$K$D$$$F(B -$B$O(B @pxref{Mail Source Specifiers} $B$r;2>H$7$F2<$5$$!#(B +$B$O(B @ref{Mail Source Specifiers} $B$r;2>H$7$F2<$5$$!#(B @item $B$=$7$F!"$=$N>l$G$9$0$K?7$7$$%K%e!<%9$rFI$`$3$H$b$G$-$^$9$7!"%K%e!<%9$r%m!<(B $B%+%k%^%7%s$K%@%&%s%m!<%I$9$k$3$H$b$G$-$^$9!#8eH$7$F$/$@$5$$!#(B) +$B$K$O(B @ref{Agent Categories} $B$r;2>H$7$F$/$@$5$$!#(B) @item $B5-;v$ruBV$K$5$;!"(B @@ -16770,18 +16774,18 @@ PPP $B4X78(B($B$J$I(B)$B$rJD$8$^$9!#$=$&$7$F%K%e!<%9$r%*%U%i%$%s$GFI$`$3$H$ $B$I$N%5!<%P!<$r%(!<%8%'%s%H$GLLE]$r8+$k$+$r7h$a$^$9!#$b$7%a!<%k%P%C%/%(%s(B $B%I$,$"$l$P!"$=$l$r%(!<%8%'%s%H$KLLE]$r8+$5$;$k$N$O$*$=$i$/L50UL#$G$7$g$&!#(B $B%5!<%P!<%P%C%U%!!<$K0\F0$7(B ($B%0%k!<%W%P%C%U%!!<$G(B @kbd{^})$B!"%(!<%8%'%s%H(B -$B$K07$C$FM_$7$$%5!<%P!<(B($BJ#?t2D(B)$B$G(B @kbd{J a} $B$r2!$9$+!"$^$?$O%(!<%8%'%s%H(B -$B$K07$C$FM_$7$/$J$$$N$K<+F0E*$KDI2C$5$l$?%5!<%P!<$G(B @kbd{J r} $B$r2!$7$^$9!#(B -$B%G%#%U%)%k%H$G(B +$B$K07$C$FM_$7$$%5!<%P!<(B($BJ#?t2D(B)$B$G(B @kbd{J a} $B$r2!$9(B (@pxref{Server Agent +Commands}) $B$+!"$^$?$O%(!<%8%'%s%H$K07$C$FM_$7$/$J$$$N$K<+F0E*$KDI2C$5$l(B +$B$?%5!<%P!<$G(B @kbd{J r} $B$r2!$7$^$9!#%G%#%U%)%k%H$G(B $B$O(B @code{gnus-select-method} $B$H(B @code{gnus-secondary-select-methods} $B$K(B -$B$"$k$9$Y$F$N(B @code{nntp} $B$H(B @code{nnimap} $B%0%k!<%W$,%(!<%8%'%s%H2=$5$l$^(B +$B$"$k$9$Y$F$N(B @code{nntp} $B$H(B @code{nnimap} $B%5!<%P!<$,%(!<%8%'%s%H2=$5$l$^(B $B$9!#(B @item $B%@%&%s%m!<%IJ}?K$r7hDj$7$^$9!#$"$J$?$NJ}?K$rJ}$O!"B??t$N%0%k!<%W$KE,MQ$9$kJ}?K$N@_(B @@ -16838,12 +16842,13 @@ PPP $B4X78(B($B$J$I(B)$B$rJD$8$^$9!#$=$&$7$F%K%e!<%9$r%*%U%i%$%s$GFI$`$3$H$ $BJQ?t$r>e=q$-$9$kB?$/$NG$0U$J%Q%i%a!<%?$+$i@.$j$^$9!#%(!<%8%'%s%H%Q%i%a!<(B $B%?$N40A4$J%j%9%H$r0J2<$K<($7$^$9!#(B +@cindex Agent Parameters @table @code @item gnus-agent-cat-name -The name of the category. +$BJ,N`$NL>A0!#(B @item gnus-agent-cat-groups -The list of groups that are in this category. +$B$3$NJ,N`$K$"$k%0%k!<%W$N%j%9%H!#(B @item gnus-agent-cat-predicate ($BDL>o(B) $B$I$N5-;v$r%@%&%s%m!<%I$9$k$N$,E,Ev$+$H$$$&Bg$^$+$JNX3T$rM?$($k=R(B @@ -16875,6 +16880,18 @@ The list of groups that are in this category. @item gnus-agent-cat-length-when-long @code{gnus-agent-long-article} $B$r>e=q$-$9$k@0?t!#(B + +@c @item gnus-agent-cat-disable-undownloaded-faces +@c $B%@%&%s%m!<%I$5$l$F$$$J$$5-;v$r(B gnus-summary-*-undownloaded-face $B$r;H$C$F(B +@c $B35N,%P%C%U%!$KI=<($9$Y$-(B @emph{$B$G$O$J$$(B} $B$3$H$r<($9%7%s%\%k!#CM(B +@c $B$,(B @code{nil} $B$@$H!"B>$N%7%s%\%k$,$=$l$i$rM^@)$7$F$$$F$b!"%@%&%s%m!<%I$5(B +@c $B$l$F$$$J$$5-;vMQ$N%U%'!<%9$r;H$($k$h$&$K$J$j$^$9!#(B + +@item gnus-agent-cat-enable-undownloaded-faces +$B%@%&%s%m!<%I$5$l$F$$$J$$5-;v$r(B gnus-summary-*-undownloaded-face $B$r;H$C$F(B +$B35N,%P%C%U%!$KI=<($9$Y$-$G$"$k$3$H$r<($9%7%s%\%k!#CM$,(B @code{nil} $B$@$H!"(B +$BB>$N%7%s%\%k$,$=$l$i$rM-8z$K$7$F$$$F$b!"%@%&%s%m!<%I$5$l$F$$$J$$5-;vMQ$N(B +$B%U%'!<%9$r;H$o$J$$$h$&$K$J$j$^$9!#(B @end table $B$$$C$?$sJ,N`$,:n$i$l$?$i!"J,N`$NL>A0$rJQ$($k$3$H$O$G$-$^$;$s!#(B @@ -17294,7 +17311,7 @@ parameters at one time (@code{gnus-category-customize-category}). @kindex J S ($B%(!<%8%'%s%H(B $B%0%k!<%W(B) @findex gnus-group-send-queue $B=gHVBT$A(B (queue) $B%0%k!<%W$K$"$kAw?.2DG=$J%a%C%;!<%8$rA4$FAw?.$9(B -$B$k(B (@code{gnus-group-send-queue})$B!#(B@xref{Drafts}$B!#(B +$B$k(B (@code{gnus-group-send-queue})$B!#(B@xref{Drafts}. @item J a @kindex J a ($B%(!<%8%'%s%H(B $B%0%k!<%W(B) @@ -17380,6 +17397,69 @@ parameters at one time (@code{gnus-category-customize-category}). $B$k(B (@code{gnus-agent-remove-server})$B!#(B @end table +@node Agent Visuals +@subsection $B%(!<%8%'%s%H$N;k3P8z2L(B + +$B%*%U%i%$%s(B (unplugged) $B$N$H$-$K35N,$r3+$$$?>l9g$K!"(Bgnus $B$,8=:_%(!<%8%'%s(B +$B%H$K3JG<$5$l$F$$$k%X%C%@!<$h$j$bB?$/$N5-;v$,$"$k$3$H$r!"$=$N%0%k!<%W(B +$B$N(B active ($BLuCm(B: $B2?HV$+$i2?HV$^$G$N5-;v$,$"$k$+$r<($94IM}>pJs(B) $B$NHO0O$+(B +$B$iCN$C$F$$$k>l9g!"I=Bj$,(B @samp{[Undownloaded article #####]} $B$N$h$&$K$J$C(B +$B$F$$$k$$$/$D$+$N5-;v$r8+$k$+$b$7$l$^$;$s!#$=$l$i$O8+Ev$?$i$J$$%X%C%@!<$N(B +$B$?$a$N7jKd$a(B (placeholders) $B$G$9!#0u(B (mark) $B$r@_Dj$9$k$3$H$O$H$b$+$/!"$=(B +$B$l$i$N7jKd$a$N0l$D$G$G$-$k$3$H$OB?$/$O$"$j$^$;$s!#:G=*E*$K(B gnus $B$,%0%k!<(B +$B%W$N%X%C%@!<$rH(B)$B!#(B + +$B$9$Y$F$N?M$K$H$C$FL@Gr$+$b$7$l$^$;$s$,!"%*%U%i%$%s$N$H$-$KMxMQ$G$-$k$N$O!"(B +$B0JA0$K:9$79~$^$l$F$$$?4V(B (plugged) $B$K%(!<%8%'%s%H$KuBV$rI=<($7$^$9!#(B + +$BBh0l$N;k3P8z2L$O(B @samp{%O} $B;EMM$G$9!#$3$N;X<(;R$r4^$a$k$?$a(B +$B$K(B @code{gnus-summary-line-format} $B$r%+%9%?%^%$%:$9$k$H!"5-;v$N%@%&%s%m!<(B +$B%I$N>uBV$r<($9C10l$NJ8;z$,2C$o$k$G$7$g$&!#%(!<%8%'%s%H$+%-%c%C%7%e$N$I$A(B +$B$i$+$Kr7o8!::$H%U%'!<%9L>$N%j%9%H(B (@code{gnus-summary-highlight} $B;2(B +$B>H(B) $B$G@)8f$5$l$k$3$H$G$9!#$=$l$>$l$N>r7o$O!"$=$l$,%j%9%H$NCf$K8=$l$k=g$K(B +$B8!::$5$l$k$N$G!"8e$N>r7o$h$j$bA0$N>r7o$,M%@h$5$l$^$9!#$3$l$,0UL#$9$k$9$Y(B +$B$F$O!"%@%&%s%m!<%I$5$l$F$$$J$$5-;v$K2D;k5-;v(B (ticked) $B$N0u$rIU$1$F$b!"$=(B +$B$N5-;v$O2D;k5-;v$N%U%'!<%9$G$O$J$/$F!"%@%&%s%m!<%I$5$l$F$$$J$$5-;v$N%U%'!<(B +$B%9$GI=<($7B3$1$i$l$k$H$$$&$3$H$G$9!#(B + +($B5-;v$rFI$`$?$S$KF1$85-;v$r%@%&%s%m!<%I$7$J$$$h$&$K$9$k$?$a!"$^$?$O@\B3(B +$B;~4V$r:G>.$K$9$k$?$a$K(B) $B%(!<%8%'%s%H$r%-%c%C%7%e$H$7$F;H$&>l9g$O!"%@%&%s(B +$B%m!<%I$5$l$F$$$J$$5-;v$N%U%'!<%9$O$*$=$i$/NI$$9M$($N$h$&$K;W$($k$G$7$g$&!#(B +$B%@%&%s%m!<%I$5$l$?5-;v$KBP$7$F$9$Y$F$N;E;v(B ($B0u$rIU$1$k!"FI$`!":o=|$9(B +$B$k(B) $B$r9T$J$($P!"$$$D$bDL>o$N%U%'!<%9$,8=$l$k$+$i$G$9!#(B + +$B$H$-$?$^%(!<%8%'%s%H$r;H$&%f!<%6$K$H$C$F$O!"%@%&%s%m!<%I$5$l$F$$$J$$5-;v(B +$B$N%U%'!<%9$O!"$I$&$7$h$&$b$J$/$R$I$$9M$($G$"$k$h$&$K;W$($k$+$b$7$l$^$;$s!#(B +$BO@E@$O!"H`$i$NBgDq$N5-;v$O%(!<%8%'%s%H$Ko$N%U%'!<%9$,!"%@%&%s%m!<%I$5$l$F$$$J$$5-;v$N%U%'!<%9$N1"$K2b$s$G$7$^$&(B +$B$3$H$G$9!#$3$l$,$"$J$?$N6-6x$J$i$P!"$"$J$?$K$OFs$D$NA*Br;h$,$"$j$^$9!#Bh(B +$B0l$K!"(B@code{gnus-summary-*-undownloaded-face} $B$N%U%'!<%972$K4X$o$k;0$D$N(B +$B%3%s%9%;%k$r>C5n$9$k$?$a$K(B @code{gnus-summary-highlight} $B$r%+%9%?%^%$%:(B +$B$9$k$3$H$K$h$C$F!"%@%&%s%m!<%I$5$l$F$$$J$$5-;v$N%U%'!<%9$r40A4$KM^@)$9$k(B +$B$3$H$,$G$-$^$9!#BhFs$K!"$b$C$H@vN}$5$l$?%"%W%m!<%A$,9%$_$J$i$P!"(B +@code{agent-disable-undownloaded-faces} $B%0%k!<%W%Q%i%a!<%?$r(B t $B$K@_Dj$7(B +$B$F$bNI$$$G$7$g$&!#$3$N%Q%i%a!<%?$OB>$N$9$Y$F$N%(!<%8%'%s%H%Q%i%a!<%?$HF1(B +$BMM$K!"%(!<%8%'%s%HJ,N`(B (@pxref{Agent Categories})$B!"%0%k!<%W%H%T%C(B +$B%/(B (@pxref{Topic Parameters})$B!"$"$k$$$O8D!9$N%0%k!<%W(B (@pxref{Group +Parameters}) $B$KBP$7$F@_Dj$9$k$3$H$,$G$-$^$9!#(B + @node Agent as Cache @subsection $B%-%c%C%7%e$H$7$F$N%(!<%8%'%s%H(B @@ -17394,10 +17474,9 @@ gnus $B$,(B @dfn{plugged} $B$G$"$k$H$-$K!"$9$G$K%(!<%8%'%s%H$K3JG<$5$l$F$$$k% $B$"$J$?$,$=$&K>$`$N$G$"$l$P!"(B@dfn{plugged} $B$J4|4V$O>o$K%X%C%@!<$H5-;v$r%@(B $B%&%s%m!<%I$9$k$h$&$K!"%(!<%8%'%s%H(B (@code{gnus-agent-cache} $B;2(B -$B>H(B @pxref{Agent Variables}) $B$r@_Dj$9$k$3$H$,$G$-$^$9!#(Bgnus $B$O$[$H$s$I3N(B -$B$+$K$b$C$HCY$/$J$j$^$9$,!"%5!<%P!<$H$NF14|$OJ]$?$l$^$9!#(B -nntp $B$+(B nnimap $B%P%C%/%(%s%I$r;H$C$F$$$k>l9g$O!"$?$V$s$3$N:G8e$NE@$O0UL#(B -$B$r$J$5$J$$$G$7$g$&!#(B +$B>H(B @ref{Agent Variables}) $B$r@_Dj$9$k$3$H$,$G$-$^$9!#(Bgnus $B$O$[$H$s$I3N$+(B +$B$K$b$C$HCY$/$J$j$^$9$,!"%5!<%P!<$H$NF14|$OJ]$?$l$^$9!#(Bnntp $B$+(B nnimap $B%P%C(B +$B%/%(%s%I$r;H$C$F$$$k>l9g$O!"$?$V$s$3$N:G8e$NE@$O0UL#$r$J$5$J$$$G$7$g$&!#(B @node Agent Expiry @subsection $B%(!<%8%'%s%H4|8B@Z$l>C5n(B @@ -17590,9 +17669,13 @@ plugged $B$N$H$-$K!"%m!<%+%k$K;}$C$F$$$k(B @acronym{NOV} $B$H5-;v$r;H$&$+$I$& @item gnus-agent-consider-all-articles @vindex gnus-agent-consider-all-articles -@code{gnus-agent-consider-all-articles} $B$,(B $BHs(B-@code{nil} $B$@$C$?$i!"%(!<(B -$B%8%'%s%H$O$9$Y$F$N8+Ev$?$i$J$$%X%C%@!<$rl9g!"$=$l$,%G%#%U%)(B +$B%k%H$G$9$,!"%(!<%8%'%s%H$OL$FI$N5-;v$r%@%&%s%m!<%I$9$k$+$I$&$+$@$1$r=R8l(B +$B$K7hDj$5$;$^$9!#$3$l$rM-8z$K$9$k$K$O!"8e$G%(!<%8%'%s%H$,4|8B@Z$l>C5n$9$k(B +$B5-;v$r2?EY$b7+$jJV$7%@%&%s%m!<%I$7$J$$$h$&$K!"%(!<%8%'%s%H$N4|8B@Z$l>C5n(B +$B$N@_Dj(B (@pxref{Category Variables}) $B$r8+D>$9I,MW$b$"$k$+$b$7$l$^$;$s!#(B @item gnus-agent-max-fetch-size @vindex gnus-agent-max-fetch-size @@ -17817,7 +17900,7 @@ Gnus Agent $B$O$h$/$"$kB>$N%*%U%i%$%s%K%e!<%9%j!<%@!<$N$h$&$K$OF0:n$7$^$;(B $BA4$F$N5-;v$O%9%3%"$N=i4|CM$r;}$C$F$*(B $B$j(B (@code{gnus-summary-default-score})$B!"$3$l$O%G%#%U%)%k%H$G(B 0 $B$G$9!#$3(B $B$N%9%3%"$OBPOCE*$d!"%9%3%"%U%!%$%k(B (score file) $B$NJ}K!$K$h$j!">e$2$i$l$?(B -$B$j2<$2$i$l$?$j$7$^$9!#(B@code{gnus-summary-bark-below} $B$h$j$bDc$$%9%3%"$N(B +$B$j2<$2$i$l$?$j$7$^$9!#(B@code{gnus-summary-mark-below} $B$h$j$bDc$$%9%3%"$N(B $B5-;v$K$O4{FI$N0u$,IU$-$^$9!#(B Gnus $B$O35N,%P%C%U%!$r:n@.$9$kA0$K!"8=:_$N%0%k!<%W$KE,MQ$5$l$k$I$s(B @@ -17834,7 +17917,7 @@ Gnus $B$O35N,%P%C%U%!$r:n@.$9$kA0$K!"8=:_$N%0%k!<%W$KE,MQ$5$l$k$I$s(B @menu * Summary Score Commands:: $B8=:_$N%0%k!<%W$N$?$a$N%9%3%"EPO?$rDI2C$9$k(B * Group Score Commands:: $B0lHLE*$J%9%3%"L?Na(B -* Score Variables:: $B$"$J$?$N%9%3%"$r%+%9%?%^%$%:$9$k(B ($B$^$!!"$J$s$FMQ8l$G$7$g$&(B) +* Score Variables:: $B$"$J$?$N%9%3%"$r%+%9%?%^%$%:$9$k(B ($B$^$!!"$J$s$FMQ8l(B (Scoring) $B$G$7$g$&(B) * Score File Format:: $B%9%3%"%U%!%$%k$K2?$rF~$l$k$+(B * Score File Editing:: $BC5n%U%!%$%k$r%9%3%"%U%!%$%k$KJQ49$9$k(B * GroupLens:: $B$I$l$rFI$`$N$,9%$-$+$NM=8@$rF@$k(B * Advanced Scoring:: $B%9%3%"$NK!B'$r:n$k$?$a$KO@M}I=8=$r;H$&(B @@ -17884,10 +17967,10 @@ Gnus $B$O35N,%P%C%U%!$r:n@.$9$kA0$K!"8=:_$N%0%k!<%W$KE,MQ$5$l$k$I$s(B @kindex V t ($B35N,(B) @findex gnus-score-find-trace $B8=:_$N5-;v$K;H$o$l$F$$$kA4$F$N%9%3%"K!B'(B (score rule) $B$rI=<($7$^(B -$B$9(B (@code{gnus-score-find-trace})$B!#(B@code{*Score Trace*} $B%P%C%U%!$G(B -$B$O(B @kbd{q} $B$G=*N;$9$k$3$H$,$G$-$^$9!#(B@kbd{e} $B$GBP1~$9$k%9%3%"%U%!%$%k$r(B -$BJT=8$7$^$9!#%]%$%s%H$,9gCW$7$?AG;R$NCf$NJ8;zNs>e$K$"$k$H$-!"(B@kbd{e} $B$O%9(B -$B%3%"%U%!%$%k$NCf$N$3$NJ8;zNs$N>l=j$X0\F0$7$h$&$H$7$^$9!#(B +$B$9(B (@code{gnus-score-find-trace})$B!#(B@code{*Score Trace*} $B%P%C%U%!(B +$B$G!"(B@kbd{e} $B$r%?%$%W$7$F8=:_9T$N%9%3%"K!B'$KBP1~$9$k%9%3%"%U%!%$%k$rJT=8(B +$B$9$k$3$H$,$G$-!"(B@kbd{f} $B$G$O%9%3%"%U%!%$%k$N%U%)!<%^%C(B +$B%H(B (@code{gnus-score-pretty-print}) $B$HJT=8$r9T$J$&$3$H$,$G$-$^$9!#(B @item V w @kindex V w ($B35N,(B) @@ -18250,6 +18333,7 @@ Gnus $B$O0lHLE*$J%9%3%"%U%!%$%k$rFCDj$N%9%3%"%U%!%$%k8~$1$N$b$N$h$jA0$KE,(B $BNc$($P!"%5!<%P!<$rFCDj$7$J$$A4BN%9%3%"%U%!%$%k$r;H$C$F!"?F%0%k!<%W$K=`$8(B $B$?%9%3%"IU$1$r9T$J$&$J$i$P!"2A(B} (eval) $B$5$l$^$;$s!#$7$+$7!"(BLisp $B%j!<%@!<$,$3$NMM<0$rFI$_(B @@ -18384,12 +18468,13 @@ gnus $B$K5-;vA4BN$rl9g%9(B $B%3%"EPO?$N(B 5 $BHVL\$NMWAG$,%9%3%"$rIU$1$k%X%C%@!<$NL>A0$K$J$j$^$9!#(B -@acronym{NNTP} $B%5!<%P!<$,(B overview $B$K(B NNTP-Posting-Host $B$r5-O?$7$F$$$k$J(B -$B$i$P!"(B@file{all.SCORE} $B%U%!%$%k$N0J2<$NEPO?$O!"C10l$N%[%9%H$+$i(B spam $B$N(B -$B967b$,$"$k>l9g$KM-8z$G$9!#(B +@acronym{NNTP} $B%5!<%P!<$,(B overview $B$K(B @samp{NNTP-Posting-Host} $B$r5-O?$7(B +$B$F$$$k$J$i$P!"(B@file{all.SCORE} $B%U%!%$%k$N0J2<$NEPO?$O!"C10l$N%[%9%H$+(B +$B$i(B spam $B$N967b$,$"$k>l9g$KM-8z$G$9!#(B @lisp -("111.222.333.444" -1000 nil s "NNTP-Posting-Host") +("111.222.333.444" -1000 nil s + "NNTP-Posting-Host") @end lisp @item Lines, Chars @@ -18446,7 +18531,7 @@ Date ($BF|IU(B) $B%X%C%@!<$K$O;0$D$N$J$s$H$J$/$P$+$2$F$$$k9gCW$N7?$,$"$j$^$9 $B9F$5$l$?5-;v$K9gCW$9$k;v$KCm0U$7$F$/$@$5$$!#I8=`;~$O0l2H$K$H$C$FHs>o$KM-(B $B1W$J3Z$7$_$G$7$g$&(B?) -@item Head, Body All +@item Head, Body, All $B$3$l$i$N;0$D$N9gCW$N%-!<$O(B @code{From} $B%X%C%@!<(B ($B$J$I(B) $B$HF1$89gCW$N7?$r(B $B;H$$$^$9!#(B @@ -18598,8 +18683,8 @@ ignore)} $B$rE,1~%9%3%"$r$7$?$/$J$$%0%k!<%W$KA^F~$9$k$G$7$g$&!#>/$7$N%0%k!<(B @vindex gnus-score-mode-hook @code{gnus-score-menu-hook} $B$,%9%3%"%b!<%I%P%C%U%!$G\$7$/@bL@$5(B -$B$l$F$$$^$9$,!"$3$3$G$O(B @code{nnml} $B$G(B @samp{To} $B$H(B @samp{Cc} $B%X%C%@!<$K(B -$B%9%3%"$rIU$1$kJ}K!$ND4M}$NNc$r5s$2$^$7$g$&!#(B +$B$N(B @ref{To From Newsgroups} $B$N9`$G$O$3$N5!9=$,$I$&F/$/$+$,>\$7$/@bL@$5$l(B +$B$F$$$^$9$,!"$3$3$G$O(B @code{nnml} $B$G(B @samp{To} $B$H(B @samp{Cc} $B%X%C%@!<$K%9(B +$B%3%"$rIU$1$kJ}K!$ND4M}$NNc$r5s$2$^$7$g$&!#(B $B0J2<$r(B @file{~/.gnus.el} $B%U%!%$%k$KCV$$$F2<$5$$!#(B @@ -19178,7 +19263,7 @@ Gnus $B$O$^$@!"$"$N$&$6$C$?$$8E$$>C5n%U%!%$%k$r%5%]!<%H$7$F$$$^$9!#C(B @cindex converting kill files $B$"$J$?$,8E$$>C5n%U%!%$%k$r$I$C$5$j;}$C$F$$$k$N$G$"$l$P!"$=$l$i$r%9%3%"%U%!(B -$B%$%k$KJQ49$7$?$/$J$k$G$7$g$&!#$b$7$=$l$i$,(B ``$BIaDL$N(B''$B$d$D$G$"$l$P!"(B +$B%$%k$KJQ49$7$?$/$J$k$G$7$g$&!#$b$7$=$l$i$,(B ``$BIaDL$N(B'' $B$d$D$G$"$l$P!"(B @file{gnus-kill-to-score.el} $B%Q%C%1!<%8$r;H$&$3$H$,$G$-$^$9!#$=$&$G$J$1(B $B$l$P!"C5n%U%!%$%k$r%5%]!<%H$7$F$$$^$9!#C(B @section GroupLens @cindex GroupLens +@sc{$BCm0U(B:} $B;DG0$J$3$H$K(B GroupLens $B5!9=$OJD:?$5$l$F$$$k$h$&$J$N$G!"$3$N9`(B +$B$O$N?M$H6&$K8+$D$1$k$N$r=u(B $B$1$k$?$a$N6&F1A*JL5!9=$G$9!#(B @@ -19208,9 +19296,6 @@ Gnus $B$O$^$@!"$"$N$&$6$C$?$$8E$$>C5n%U%!%$%k$r%5%]!<%H$7$F$$$^$9!#C(B $B$l$P!"M=8@$N7A$G!"$=$l$i$N?M$,5-;v$r$I$&;W$&$+$r$"$J$?$K9p$2$^$9!#$"$J$?(B $B$O$3$NM=8@$r5-;v$rFI$_$?$$$+$I$&$+$r7hDj$9$k$N$KLrN)$F$k;v$,$G$-$^$9!#(B -@sc{$BCm0U(B:} $B;DG0$J$3$H$K(B GroupLens $B5!9=$OJD:?$5$l$F$$$k$h$&$J$N$G!"$3$N9`(B -$B$O (abs n) (lsh -1 -2))) + (string-to-number + (car (split-string (number-to-string n) "\\."))) + (floor n)))) @end lisp @vindex gnus-score-decay-scale @@ -19618,6 +19708,7 @@ Gnus $B$O0lF|$K0l2s%9%3%"$rIeGT$5$;$h$&$H$7$^$9!#Nc$($P!"$b$7(B gnus $B$r;MF| * Image Enhancements:: $B:G?7$N(B Emacs/XEmacs $B$O3($rI=<($G$-$k(B * Fuzzy Matching:: $BBg$-$JLJLS$C$F2?(B? * Thwarting Email Spam:: $BM>7W$J>&6HE*EE;R%a!<%k$rHr$1$kJ}K!(B +* Other modes:: $BB>$N%b!<%I$H$NAj8_:nMQ(B * Various Various:: $BK\Ev$K$$$m$$$m$J$b$N(B @end menu @@ -19728,7 +19819,7 @@ Gnus $B$r=*N;$9$kA0$K3NG'$rMW5a$7$^$9!#$3$NJQ?t$O=i4|@_Dj$G(B @code{t} $B$G$9 $B0z?t$rLrN)$F$F$$$k$o$1$G$O$"$j$^$;$s!#(B $B$b$7$I$N$h$&$K(B gnus $B$,$3$l$re5i;2>H$r$?$/$5$s;H$C(B $B$F$$$k$J$i!"(BT-gnus $B$,$H$F$bCY$/$J$k$N$,$o$+$k$G$7$g$&!#$3$l$O$"$J$?$,9T(B $B$N308+$KK~B-$7$?$H$-$K(B @kbd{M-x gnus-compile} $B$r.$5$JDI2C$N%U%l!<%`$,(B picon $B$rI=<($9$k$?$a$K:n$i$l$k(B $B$H$$$&;v$K$J$j$^$9!#$4Mw$NDL$j!"IaDL$N(B @code{1.0} $B:G>e0L;XDj$NBe$o$j$K!"(B $B$=$l$>$l$NDI2C$NJ,3d$,%U%l!<%`%Q%i%a!<%?O"A[%j%9%H$rBg$-$5;XDj$H$7$F;}$?(B -$B$J$1$l$P$J$j$^$;$s!#(B@xref{Frame Parameters, , Frame Parameters, elisp, -The GNU Emacs Lisp Reference Manual}. XEmacs $B$G$O!"%U%l!<%`%W%m%Q%F%#%j(B +$B$J$1$l$P$J$j$^$;$s(B (@pxref{Frame Parameters, , Frame Parameters, elisp, +The GNU Emacs Lisp Reference Manual})$B!#(BXEmacs $B$G$O!"%U%l!<%`%W%m%Q%F%#%j(B $B%9%H$b;H$($^$9(B---$BNc$($P!"(B@code{(height 5 width 15 left -1 top 1)} $B$O$=$N(B $B$h$&$J%Q%i%a!<%?%j%9%H$G$9!#(B @code{gnus-buffer-configuration} $B$K;HMQ2DG=$JA4$F$N%-!<$N0lMw$O$=$N=i4|(B @@ -20519,9 +20610,9 @@ gnus $B$O3:Ev$9$k$G$"$m$&>pJs$G%b!<%I9T$r99?7$7$^$9!#$3$NJQ?t(B Gnus$B!"$=$l$O(B($B8@$$EA$($K$h$l$P(B)$B$+$D$F=q$+$l$?$$$+$J$k%W%m%0%i%`$h$j$bBg$-(B $B$/!"$"$J$?$,$d$C$FM_$7$$$H;W$&$5$^$6$^$J4qL/$J$3$H$r!"$"$J$?$N$$$J$$$H$3(B $B$m$G9T$C$F$/$l$k$b$N$G$9!#Nc$($P!"$"$J$?$O;~$?$^?7Ce%a!<%k$r%A%'%C%/$7$F(B -$B$b$i$$$?$/$J$k$+$bCN$l$^$;$s!#$"$k$$$O(B Emacs $B$r$7$P$i$/J|$C$F$*$$$?$H$-(B -$BA4$F$N%5!<%P$N@\B3$r@ZCG$7$F$b$i$$$?$/$J$k$+$b$7$l$^$;$s!#B>$K$b2?$+$=$&(B -$B$$$C$?$3$H$G$9!#(B +$B$b$i$$$?$$$+$bCN$l$^$;$s!#$"$k$$$O(B Emacs $B$r$7$P$i$/J|$C$F$*$$$?$H$-A4$F(B +$B$N%5!<%P$N@\B3$r@ZCG$7$F$b$i$$$?$/$J$k$+$b$7$l$^$;$s!#B>$K$b2?$+$=$&$$$C(B +$B$?$3$H$G$9!#(B Gnus $B$O$5$^$6$^$J@)8f;R(B @dfn{handlers} $B$rDj5A$9$k$3$H$K$h$C$F$=$N$h$&$J(B $B$3$H$r2DG=$K$7$^$9!#3F@)8f;R$O;0$D$NMWAG$+$i@.$j$^$9!#(B @@ -20836,90 +20927,138 @@ XEmacs $B$=$l$K(B Emacs 21@footnote{MS $B%&%#%s%I%&%:$N(B Emacs 21 $B$O$^$@ gnus $B$O$3$l$rMxMQ$9$k$3$H$K$7$^$9!#(B @menu -* Picons:: $B$"$J$?$,FI$s$G$$$k$b$N$N3($rI=<($9$kJ}K!(B +* X-Face:: $B%U%!%s%-!<$G$A$C$A$c$JGr9u$N3($rI=<($9$k(B +* Face:: $B$h$j%U%!%s%-!<$G$A$C$A$c$J%+%i!<$N3($rI=<($9$k(B * Smileys:: $BI=<($5$l$k$Y$/@8$^$l$?9,$;$=$&$J4i$rI=<($9$kJ}K!(B -* X-Face:: $B%U%!%s%-!<$J$A$C$A$c$JGr9u$N3($rI=<($9$k(B +* Picons:: $B$"$J$?$,FI$s$G$$$k$b$N$N3($rI=<($9$kJ}K!(B * XVarious:: $B$=$NB>$N(B XEmacs $B$G(B Gnus $B$JJQ?t(B @end menu -@node Picons -@subsection Picons - -@iftex -@iflatex -\include{picons} -@end iflatex -@end iftex - -$B$=$l$G!D!"$"$J$?$O$3$N%K%e!<%9%j!<%@!<$r$5$i$K$b$C$HCY$/$7$?$$$C$F$o$1$@(B -$B$M(B! $B$3$l$O$=$&$9$k$N$K$T$C$?$j$JJ}K!$G$9!#$5$i$K$3$l$O!"$"$J$?$,%K%e!<%9(B -$B$rFI$s$G$$$k$s$@$H$$$&$3$H$r!"$"$J$?$N8*1[$7$K8+$D$a$F$$$k?M$K0u>]$E$1$k(B -$B$?$a$NAG@2$i$7$$J}K!$G$b$"$j$^$9!#(B +@node X-Face +@subsection X-Face +@cindex x-face -Picon $B$H$O$J$s$G$7$g$&(B? Picons $B%&%'%V%5%$%H$+$iD>@\0zMQ$7$^$7$g$&!#(B +@code{X-Face} $B%X%C%@!<$O!"%a%C%;!<%8$NCxe$NMxMQ.$5$J2hA|$G!"%G!<%?%Y!<(B -$B%9$r;}$?$;$F!"$"$kEE;R%a!<%k%"%I%l%9$,$"$C$?$i!"$=$l$KE,@Z$J2hA|$r8+$D$1(B -$B$i$l$k$h$&$K$7$F$*$/$b$N$G$9!#MxMQ%W%m%0%i%`$K$D$$$F$O!"(B +`compface' $B$d(B GNU/Linux $B%7%9%F%`$K$*$1$k(B `faces-xface' $B$N$h$&$J%Q%C%1!<(B +$B%8$rC5$7$F2<$5$$!#(B} $B$r%U%)!<%/$7$F8+$h$&$H$7$^$9!#(B -Picon $B$NI=<($,$G$-$k$h$&$K$9$k$?$a$K$O!"(Bpicon $B%G!<%?%Y!<%9$,$"$k%G%#%l%/(B -$B%H%j$,!"$?$@C1$K(B @code{gnus-picon-databases} $B$K@_Dj$5$l$F$$$k$h$&$K$7$F(B -$B2<$5$$!#(B +XEmacs $B$+@E;_2h$r%5%]!<%H$7$F$$$k(B Emacs 21+ $B$G$N%G%#%U%)%k%H$NF0:n(B +$B$O(B @code{From} $BMs$NA0$K4i$rI=<($9$k$3$H$G$9!#(B(XEmacs $B$,(B X-Face $B5!G=IU$-(B +$B$G%3%s%Q%$%k$5$l$F$$$k$HNI$$$G$7$g$&!=!=$=$l$OI=<($r>/$7Aa$/$7$^$9!#$b$7(B +$B:,K\E*(B X-Face $B5!G=$,$J$$$N$G$"$l$P!"(Bgnus $B$O(B @code{pbmplus} $B$d$=$NCg4V$N(B +$B30It%W%m%0%i%`$r;H$C$F(B @code{X-Face} $BMs$rJQ49$7$h$&$H;n$_$^$9(B @footnote{ +GNU/Linux $B%7%9%F%`$G$O(B @code{netpbm}$B!"(B@code{libgr-progs} $B$^$?(B +$B$O(B @code{compface} $B$N$h$&$JL>A0$N%Q%C%1!<%8$rC5$7$F2<$5$$!#(B}$B!#(B) -$B$b$N$4$H$N=j:_$r4IM}$9$k$?$a$K!"0J2<$NJQ?t$r@_$1$F$$$^$9!#(B +($BCm(B: $BJQ?t(B/$B4X?tL>$K$O(B @code{xface} $B$G$O$J$/(B @code{x-face} $B$,;H$o$l$^$9!#(B) -@table @code -@item gnus-picons-database -@vindex gnus-picons-database -Picon $B%G!<%?%Y!<%9$N>l=j$G$9!#$3$l$O(B @file{news}, @file{domains}, -@file{users} ($B$J$I$J$I(B) $B$N%5%V%G%#%l%/%H%j!<$,4^$^$l$F$$$k%G%#%l%/%H%j!<(B -$B$N%j%9%H$G$9!#(B@code{("/usr/lib/picon" "/usr/local/faces")} $B$,%G%#%U%)%k(B -$B%H$G$9!#(B +gnus $B$O!"30$K=P$9%a%C%;!<%8$K(B X-Face $B%X%C%@!<$r4JC1$KA^F~$9$k$?$a$N!"JX(B +$BMx$J4X?t$HJQ?t$r>/$7$P$+$jDs6!$7$^$9!#(B -@item gnus-picon-news-directories -@vindex gnus-picon-news-directories -@code{gnus-picons-database} $B$+$i%K%e!<%9%0%k!<%WMQ$N%U%'!<%9$rC5$9$?$a$N(B -$B%5%V%G%#%l%/%H%j!<$N%j%9%H$G$9!#%G%#%U%)%k%H$O(B @code{("news")} $B$G$9!#(B +@findex gnus-random-x-face +@vindex gnus-convert-pbm-to-x-face-command +@vindex gnus-x-face-directory +@code{gnus-random-x-face} $B$O(B @code{gnus-x-face-directory} $B$K$"$k$9$Y$F(B +$B$N(B @samp{pbm} $B$r$/$^$J$/C5$7$F%i%s%@%`$K0l$D$rA*$S$N%U%'!<%9$rC5$9$?$a$N%5%V%G%#(B -$B%l%/%H%j!<$N%j%9%H$G$9!#%G%#%U%)%k%H$O(B @code{("domains")} $B$G$9!#$3$N%j%9(B -$B%H$K(B @samp{"unknown"} $B$rDI2C$7$F$*$-$?$/$J$k?M$b$$$k$G$7$g$&!#(B +@findex gnus-x-face-from-file +@vindex gnus-convert-image-to-x-face-command +@code{gnus-x-face-from-file} $B$O%Q%i%a!<%?$H$7$F(B GIF $B%U%!%$%k$r$H$7$F;n$7$F$_$k3HD%;R$N=gHV%j%9%H$G$9!#%G%#%U%)%k%H$O!"(B -@code{("xpm" "gif" "xbm")} $B$+$i(B Emacs $B$KAH$_9~$^$l$F$$$J$$$b$N$r=|30$7$?(B -$B$b$N$G$9!#(B -@end table +$B0lHVL\$O0lHLE*$K;H$&$G$"$m$&4X?t$G$9!#0J2<$N$h$&$J$b$N(B +$B$r(B @file{~/.gnus.el} $B%U%!%$%k$K=q$$$F2<$5$$(B: + +@lisp +(setq message-required-news-headers + (nconc message-required-news-headers + (list '(X-Face . gnus-random-x-face)))) +@end lisp + +$B:G8e$N4X?t$r;H$&$N$O!"$3$N$h$&$K$J$k$G$7$g$&(B: + +@lisp +(setq message-required-news-headers + (nconc message-required-news-headers + (list '(X-Face . (lambda () + (gnus-x-face-from-file + "~/My-face.gif")))))) +@end lisp + +@node Face +@subsection Face +@cindex face + +@c #### FIXME: faces and x-faces'implementations should really be harmonized. + +@code{Face} $B%X%C%@!<$O!"K\]D'$7$F$$$k$3$H$,4|BT$5$l$k!"(B +48$B!_(B48 $B2hAG$N%+%i!<2hA|$rIA$-$^$9!#(B + +@cindex face +@findex gnus-article-display-face +@code{Face} $B%X%C%@!<$NFbMF$O!"(Bbase64 $B$G%(%s%3!<%I$5$l$?(B PNG $B$N2hA|$G$J$1(B +$B$l$P$J$j$^$;$s!#@53N$J;EMM$K$D$$$F!"(B +@uref{http://quimby.gnus.org/circus/face/} $B$r;2>H$7$F2<$5$$!#(B + +$BAw?.$9$k%a%C%;!<%8$K4JC1$K(B Face $B%X%C%@!<$rA^F~$G$-$k$h$&$K$9$k$?$a$K!"(B +Gnus $B$O(B 2$B!A(B3 $B$N4X?t$HJQ?t$rDs6!$7$^$9!#(B + +@findex gnus-convert-png-to-face +@code{gnus-convert-png-to-face} $B$O(B 726-byte $B0J2<$N(B 48$B!_(B48 $B$N(B PNG $B$N2hA|(B +$B$rFI$_9~$s$G!"$=$l$r(B Face $B$KJQ49$7$^$9!#(B + +@findex gnus-face-from-file +@vindex gnus-convert-image-to-face-command +@code{gnus-face-from-file} $B$O(B JPEG $B$N%U%!%$%kL>$r%Q%i%a!<%?$H$7$F$H$7$F;n$7$F$_$k3HD%;R$N=gHV%j%9%H$G$9!#%G%#%U%)%k%H$O!"(B $B%9%^%$%j!<$N%U%!%$%kL>$H$7$F;n$7$F$_$k3HD%;R$N%j%9%H$G$9!#(B @end table -@node X-Face -@subsection X-Face -@cindex x-face - -@code{X-Face} $B%X%C%@!<$O!"%a%C%;!<%8$NCx]$E$1$k(B +$B$?$a$NAG@2$i$7$$J}K!$G$b$"$j$^$9!#(B -$B$3$l$r@)8f$9$k$N$OJQ?t(B @code{gnus-article-x-face-command} $B$G$9!#$3$NJQ?t(B -$B$,J8;zNs$J$i$P!"$3$NJ8;zNs$,%5%V%7%'%k$G@\0zMQ$7$^$7$g$&!#(B -Emacs 20 $B$G$N%G%#%U%)%k%H$NF0:n$O(B @code{display} $B%W%m%0%i(B -$B%`(B @footnote{@code{display} $B$O(B ImageMagick $B%Q%C%1!<%8$K4^$^$l$F$$$^$9!#(B -@code{uncompface} $B$H(B @code{icontopbm} $B$NN>%W%m%0%i%`$K$D$$$F$O!"(B -`compface' $B$d(B GNU/Linux $B%7%9%F%`$K$*$1$k(B `faces-xface' $B$N$h$&$J%Q%C%1!<(B -$B%8$rC5$7$F2<$5$$!#(B} $B$r%U%)!<%/$7$F8+$h$&$H$7$^$9!#(B +@iftex +@iflatex +\margindex{} +@end iflatex +@end iftex -XEmacs $B$+@E;_2h$r%5%]!<%H$7$F$$$k(B Emacs 21+ $B$G$N%G%#%U%)%k%H$NF0:n(B -$B$O(B @code{From} $BMs$NA0$K4i$rI=<($9$k$3$H$G$9!#(B(XEmacs $B$,(B X-Face $B5!G=IU$-(B -$B$G%3%s%Q%$%k$5$l$F$$$k$HNI$$$G$7$g$&!=!=$=$l$OI=<($r>/$7Aa$/$7$^$9!#$b$7(B -$B:,K\E*(B X-Face $B5!G=$,$J$$$N$G$"$l$P!"(Bgnus $B$O(B @code{pbmplus} $B$d$=$NCg4V$N(B -$B30It%W%m%0%i%`$r;H$C$F(B @code{X-Face} $BMs$rJQ49$7$h$&$H;n$_$^$9(B @footnote{ -GNU/Linux $B%7%9%F%`$G$O(B @code{netpbm}$B!"(B@code{libgr-progs} $B$^$?(B -$B$O(B @code{compface} $B$N$h$&$JL>A0$N%Q%C%1!<%8$rC5$7$F2<$5$$!#(B}$B!#(B) +@quotation +@dfn{Picon} $B$H$O!"(B``$B8D?M%"%$%3%s(B (personal icons)'' $B$NN,$G$9!#$3$l$O!"%M%C(B +$B%H>e$NMxMQ.$5$J2hA|$G!"%G!<%?%Y!<(B +$B%9$r;}$?$;$F!"$"$kEE;R%a!<%k%"%I%l%9$,$"$C$?$i!"$=$l$KE,@Z$J2hA|$r8+$D$1(B +$B$i$l$k$h$&$K$7$F$*$/$b$N$G$9!#MxMQ$K$O(B @code{xface} $B$G$O$J$/(B @code{x-face} $B$,;H$o$l$^$9!#(B) +@vindex gnus-picon-databases +Picon $B%G!<%?%Y!<%9$NF~/$7$P$+$jDs6!$7$^$9!#(B +$B$b$7(B Debian GNU/Linux $B$r;H$C$F$$$k$N$J$i!"(B@samp{apt-get install +picons.*} $B$H8@$($P(B gnus $B$,8+$D$1$k$3$H$,$G$-$k(B picon $B$,%$%s%9%H!<%k$5$l(B +$B$^$9!#(B -@findex gnus-random-x-face -@vindex gnus-convert-pbm-to-x-face-command -@vindex gnus-x-face-directory -@code{gnus-random-x-face} $B$O(B @code{gnus-x-face-directory} $B$K$"$k$9$Y$F(B -$B$N(B @samp{pbm} $B$r$/$^$J$/C5$7$F%i%s%@%`$K0l$D$rA*$Sl=j$G$9!#$3$l$O(B @file{news}, @file{domains}, +@file{users} ($B$J$I$J$I(B) $B$N%5%V%G%#%l%/%H%j!<$,4^$^$l$F$$$k%G%#%l%/%H%j!<(B +$B$N%j%9%H$G$9!#(B@code{("/usr/lib/picon" "/usr/local/faces")} $B$,%G%#%U%)%k(B +$B%H$G$9!#(B -$B0lHVL\$O0lHLE*$K;H$&$G$"$m$&4X?t$G$9!#0J2<$N$h$&$J$b$N(B -$B$r(B @file{~/.gnus.el} $B%U%!%$%k$K=q$$$F2<$5$$(B: +@item gnus-picon-news-directories +@vindex gnus-picon-news-directories +@code{gnus-picon-database} $B$+$i%K%e!<%9%0%k!<%WMQ$N%U%'!<%9$rC5$9$?$a$N(B +$B%5%V%G%#%l%/%H%j!<$N%j%9%H$G$9!#%G%#%U%)%k%H$O(B @code{("news")} $B$G$9!#(B -@lisp -(setq message-required-news-headers - (nconc message-required-news-headers - (list '(X-Face . gnus-random-x-face)))) -@end lisp +@item gnus-picon-user-directories +@vindex gnus-picon-user-directories +@code{gnus-picon-database} $B$+$i%f!<%6$N%U%'!<%9$rC5$9$?$a$N%5%V%G%#%l%/(B +$B%H%j!<$N%j%9%H$G$9!#(B@code{("local" "users" "usenix" "misc")} $B$,%G%#%U%)(B +$B%k%H$G$9!#(B -$B:G8e$N4X?t$r;H$&$N$O!"$3$N$h$&$K$J$k$G$7$g$&(B: +@item gnus-picon-domain-directories +@vindex gnus-picon-domain-directories +@code{gnus-picon-database} $B$+$i%I%a%$%sL>$N%U%'!<%9$rC5$9$?$a$N%5%V%G%#(B +$B%l%/%H%j!<$N%j%9%H$G$9!#%G%#%U%)%k%H$O(B @code{("domains")} $B$G$9!#$3$N%j%9(B +$B%H$K(B @samp{"unknown"} $B$rDI2C$7$F$*$-$?$/$J$k?M$b$$$k$G$7$g$&!#(B -@lisp -(setq message-required-news-headers - (nconc message-required-news-headers - (list '(X-Face . (lambda () - (gnus-x-face-from-file - "~/My-face.gif")))))) -@end lisp +@item gnus-picon-file-types +@vindex gnus-picon-file-types +Picon $B$N%U%!%$%kL>$H$7$F;n$7$F$_$k3HD%;R$N=gHV%j%9%H$G$9!#%G%#%U%)%k%H$O!"(B +@code{("xpm" "gif" "xbm")} $B$+$i(B Emacs $B$KAH$_9~$^$l$F$$$J$$$b$N$r=|30$7$?(B +$B$b$N$G$9!#(B +@end table @node XVarious @subsection $B$5$^$6$^$J(B XEmacs $BJQ?t(B @@ -21157,8 +21287,8 @@ Gnus $B$O!"%9%3%"IU$1!"%9%l%C%I$N7A@.!"%9%l%C%IHf3S$J$I$r9T$&$H$-$K!"(B * Anti-Spam Basics:: $B$?$/$5$s$N(B spam $B$r8:$i$94JC1$JJ}K!(B * SpamAssassin:: Spam $BBP:v%D!<%k$N;H$$J}(B * Hashcash:: CPU $B;~4V$rHq$d$7$F(B spam $BB`<#$9$k(B -* Filtering Spam Using The Spam ELisp Package:: -* Filtering Spam Using Statistics with spam-stat:: +* Filtering Spam Using The Spam ELisp Package:: +* Filtering Spam Using Statistics with spam-stat:: @end menu @node The problem of spam @@ -21178,8 +21308,8 @@ Commercial E-mail -- $BK>$^$l$J$$>&MQEE;R%a!<%k(B -- $B$NF,J8(B $B3d9g$N?M!9$,(B UCE $B$K1~Ez$9$k$@$1$G9-9p@\$N_I2a$OM-1W$K$J$jF@$^$9!#(B +Spam $B$N=|5n(B (filtering) $B$X$N:G$bC1=c$J@\$N(B +$B_I2a$OM-1W$K$J$jF@$^$9!#(B $B$b$&0l$D$NEE;R%a!<%k_I2a$X$Nl9g!"H`$O$=$l$i$N(B @code{N} $B8D$N%7%9%F%`$N$&$A$N0l$D(B -$B$rD4$Y$^$9!#(B +$BF~$7$F$$$^$9!#K\l9g!"H`$O$=$l$i$N(B @var{N} $B8D$N%7%9%F%`$N$&$A$N0l$D$rD4$Y$^(B +$B$9!#(B $BJ,;67?(B spam $B=hM}$OF1;~$KB?$/$N%a%C%;!<%8$rAw$k(B spammers $B$HHs>o$K$h$/@o$C(B $B$F$/$l$^$9$,!"$=$l$O%f!<%6!<$,$+$J$jJ#;($J%A%'%C%/$r@_Dj$9$k$3$H$r5a$a$^(B $B$9!#>&MQ$H!"%U%j!<$JJ,;67?(B spam $B=hM}%7%9%F%`$,$"$j$^$9!#J,;67?(B spam $B=hM}(B $B$O!"$=$l<+BN$N4m81$b$O$i$s$G$$$^$9!#Nc$($P!"@5Ev$JAw?.o$=$NJ,@O$O!"$*$=$i$/C18l$NBP$+;0$D(B @@ -21227,7 +21363,18 @@ Spam $B_I2a$X$NE}7WE*$Jl9g$K$H$F$b$h$/F/$/$N$G$9$,!";~$H$7$F@5Ev$JEE;R%a!<%k(B $B$r(B spam $B$H$7$FJ,N`$7$F$7$^$&$3$H$,$"$j$^$9!#J,@O$K$O;~4V$,$+$+$j$^$9!#$9(B $B$Y$F$N%a%C%;!<%8$rJ,@O$7$J$1$l$P$J$j$^$;$s!#$=$7$F%f!<%6!<$O(B spam $B$rJ,@O(B -$B$9$k$?$a$N%G!<%?%Y!<%9$rMQ0U$7$J$1$l$P$J$j$^$;$s!#(B +$B$9$k$?$a$N%G!<%?%Y!<%9$rMQ0U$7$J$1$l$P$J$j$^$;$s!#%5!<%P!<$G$NE}7WJ,@O$O(B +$B?M5$$rF@$F$$$^$9!#$3$l$K$O!"%f!<%6!<$OC1$K%a!<%k$rFI$a$PNI$$$H$$$&D9=j$H!"(B +$B$7$+$7%5!<%P!<$K$=$l$,2a$C$F%a!<%k$rJ,N`$7$?$3$H$rEA$($k$N$,:$Fq$@$H$$$&(B +$BC;=j$,$"$j$^$9!#(B + +$BM>?M$N8@$rBT$?$:$H$b!"(Bspam $B$H$N@o$$$O3Z$G$O$"$j$^$;$s!#%^%^$+$i$NEE;R%a!<(B +$B%k$H%P%$%"%0%i9-9p$r6hJL$9$kKbK!$N%9%$%C%A$O$"$j$^$;$s!#?M!9$O(B +$BHs(B-spam $B$H(B spam $B$r6hJL$9$k$N$KF$$$F$$$k$H$$$&$N$K!#$=$l$O!"(B +spammers $B$,7|L?$K$=$l$i$r%^%^$@$H;W$o$;$h$&$H$7$F$$$k$N$,K\$_$^$9!#(B @node Anti-Spam Basics @subsection Spam $BB`<#$N4pAC(B @@ -21256,14 +21403,12 @@ Spam $B$KBP=h$9$k0l$D$NJ}K!$O!"(Bgnus $B$KA4$F$N(B spam $B$r(B @samp{spam} $B$9(B (@pxref{Fancy Mail Splitting})$B!#(B @lisp -( - ... +(... (to "larsi@@trym.ifi.uio.no" - (| ("subject" "re:.*" "misc") - ("references" ".*@@.*" "misc") - "spam")) - ... -) + (| ("subject" "re:.*" "misc") + ("references" ".*@@.*" "misc") + "spam")) + ...) @end lisp $B$3$N0UL#$O!"$3$N%"%I%l%9$KFO$$$?A4$F$N%a!<%k$r$^$:5?$$$^$9$,!"(B @@ -21292,18 +21437,13 @@ Spam $B$KBP=h$9$k0l$D$NJ}K!$O!"(Bgnus $B$KA4$F$N(B spam $B$r(B @samp{spam} $B$k$H;W$C$F$$$k$J$i!"$=$l$>$l$N2!$7IU$1@kEA%a!<%k$N4X78Ev6I$K6l>p$rAw$jIU(B $B$1$k$3$H$5$($b$G$-$^$9(B --- $B2K$J$H$-$K$G$b$M!#(B -$B$^$?!"$"$J$?$,BU$1p$r$$$&J}$,NI$$$H;W$&$+(B -$B$b$7$l$^$;$s!#$3$l(B -$B$O(B @* @uref{http://stud2.tuwien.ac.at/~e9426626/gnus-junk.html} $B$+(B -$B$i!VL5NA$G!WMxMQ$G$-$^$9!#$[$H$s$I$N(B spam $B%a!<%k$O<+F0E*$KAw$i$l$F$$$k$N(B -$B$G!"$A$g$C$H$@$11'Ch$N%P%i%s%9$,$H$l$k$+$b$7$l$^$;$s!#(B - $B$3$l$G;d$N$H$3$m$G$OF0$$$F$$$^$9!#$3$l$G$_$s$J$O4JC1$JJ}K!$G;d$KO"Mm$ruBV$G$9!#;d$N0U8+$H$7$F$O!"(B@code{From} $B%X%C%@!<(B $B$r56B$$7$FB8:_$7$J$$%I%a%$%s$KAw$i$;$k$N$O%-%?%J%$$G$9!#(B +$B$3$N$N$[$H$s$I$NF;6q$K$b4JC1$KE,9g$9$k$O(B $B$:$G$9!#(B +$B$3$N9`$O(B @code{spam.el} $B%Q%C%1!<%8$H$O4X78L5$$$3$H$KCm0U$7$F2<$5$$!#$=$l(B +$B$Ol9g$N9M$(J}$r<($7$^(B @@ -21327,12 +21471,14 @@ Spam $B$rHr$1$k$?$a$NA09`$N%R%s%H$,==J,$@$C$?F|!9$O2a$.5n$j$^$7$?!#:#$G$O(B '((file :prescript "formail -bs spamassassin < /var/mail/%u") (pop :user "jrl" :server "pophost" - :postscript "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t"))) + :postscript + "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t"))) @end lisp -$B$$$C$?$s%a!<%k$rl9g!"%G%#%U%)%k%H$G$O5-;v$N%\%G%#$,%@%&%s%m!<(B +$B%I$5$l$J$$$3$H$KCm0U$7$F2<$5$$!#$=$l$r$9$k$?$a$K$O!"(B +@code{nnimap-split-download-body} $B$r(B t $B$K@_Dj$9$kI,MW$,$"$j$^(B +$B$9(B (@pxref{Splitting in IMAP})$B!#(B + $B0J>e$,$3$l$K4X$9$k$3$H$G$9!#$$$/$D$+$N(B spam $B$O$I$&$7$F$bAGDL$j$7$F$7$^$&(B $B$N$G!"(Bspam $B$rFI$`$O$a$K$J$C$?$H$-$K8F$V$?$a$N5$$NMx$$$?4X?t$,M_$7$$$G$7$g(B $B$&!#$3$l$,$=$N5$$NMx$$$?4X?t$G$9(B: @@ -21395,11 +21542,11 @@ Spam $B$H@o$&$?$a$N?7$7$$5;K!$O!"%a%C%;!<%8$rAw?.$9$k:]$K$$$/$P$/$+$NIiC4(B $B$3$H$O!">.$5$J%Q!<%;%s%F!<%8$N(B spam $B$,$$$D$bAGDL$j$7$F$7$^$&$3$H$r0UL#$7(B $B$^$9!#$=$l$O$^$?!"$I$3$+$G$@$l$+$,$=$l$i$NF;6q$r99?7$9$k$?$a$K!"$?$/$5$s(B $B$N(B spam $B$rFI$^$J$1$l$P$J$i$J$$$3$H$r$b0UL#$7$^$9!#(BHashcash $B$O$=$l$r2sHr(B -$B$7$^$9$,!"Be$o$j$K$"$J$?$,DL?.$9$k$9$Y$F$N?M$?$A$,!"$=$N;EAH$_$r;H$C$F$$(B -$B$k$3$H$,I,MW$G$9!#$"$J$?$Or(B (dogmatic) $B$NFs$D$N$N$P(B -$B$i$P$i$J$b$N$h$j6/NO$J$N$G$9!#(B +$B$7$^$9$,!"Be$o$j$K$"$J$?$,EE;R%a!<%k$GO"Mm$9$k$9$Y$F$N?M$?$A$K!"$J$k$Y$/(B +$B$=$N;EAH$_$r;H$C$F$b$i$&I,MW$,$"$j$^$9!#$"$J$?$Or(B (dogmatic) $B$NFs$D$N$N$P$i$P$i$J$b$N$h$j6/NO$J$N$G$9!#(B @cindex X-Hashcash $B!V$$$/$P$/$+$NIiC4!W$H$O(B CPU $B;~4V$r>CHq$9$k$3$H$G!"6qBNE*$K$O0lDj?t$N%S%C(B @@ -21418,7 +21565,7 @@ Spam $B$H@o$&$?$a$N?7$7$$5;K!$O!"%a%C%;!<%8$rAw?.$9$k:]$K$$$/$P$/$+$NIiC4(B (add-hook 'message-send-hook 'mail-add-payment) @end lisp -@code{hashcash.el} $B%i%$%V%i%j(B +@file{hashcash.el} $B%i%$%V%i%j(B $B$O(B @uref{http://users.actrix.gen.nz/mycroft/hashcash.el} $B$+3+H/HG(B $B$N(B gnus $B$N(B contrib $B%G%#%l%/%H%j$K$"$j$^$9!#(B @@ -21455,14 +21602,33 @@ Spam $B$H@o$&$?$a$N?7$7$$5;K!$O!"%a%C%;!<%8$rAw?.$9$k:]$K$$$/$P$/$+$NIiC4(B @cindex spam filtering @cindex spam -@code{spam.el} $B$N??$NL\E*$O(B spam $B8!=P$H_I2a$N$?$a$N41@)%;%s%?!<(B -$B$r(B gnus $B$NCf$K;}$D$3$H$G$9!#$=$N$?$a$K(B @code{spam.el} $B$OFs$D$N$3$H$r9T$J(B -$B$$$^$9(B: $BF~$C$F$/$k%a!<%k$r_I2a$7!"(Bspam $B$^$?$O(B ham $B$H$7$FCN$i$l$k%a!<%k$r(B -$BJ,@O$9$k$3$H$G$9!#(B@emph{Ham} $B$O(B @code{spam.el} $B$N$$$?$k=j$G(B spam $B$G$O$J(B -$B$$%a%C%;!<%8$r<($9$?$a$K;H$&L>A0$G$9!#(B +@file{spam.el} $B$N??$NL\E*$O(B spam $B8!=P$H_I2a$N$?$a$N41@)%;%s%?!<(B +$B$r(B gnus $B$NCf$K;}$D$3$H$G$9!#$=$N$?$a$K(B @file{spam.el} $B$OFs$D$N$3$H$r9T$J(B +$B$$$^$9(B: $B?7$7$$%a!<%k$r_I2a$7!"(Bspam $B$^$?$O(B ham $B$H$7$FCN$i$l$k%a!<%k$rJ,@O(B +$B$9$k$3$H$G$9!#(B@dfn{Ham} $B$O(B @file{spam.el} $B$N$$$?$k=j$G(B spam $B$G$O$J$$%a%C(B +$B%;!<%8$r<($9$?$a$K;H$&L>A0$G$9!#(B + +$BBh0l$K!"(B@code{spam.el} $B$r<+F0FI$_9~$_(B (autoload) $B$7$F(B @code{spam.el} $B$N(B +$B3F%U%C%/$r%$%s%9%H!<%k$9$k$?$a$K!"4X(B +$B?t(B @code{spam-initialize} $B$r(B @strong{$B\:Y$O8e=R(B (@pxref{Spam ELisp +Package Sequence of Events})$B!#(B -$B$G$O(B @code{spam.el} $B$r(B load $B$9$k$H2?$,5/$-$k$G$7$g$&$+(B? $BBh0l$K!"0J2<$N(B -$B%-!<%\!<%IL?Na$,;H$($k$h$&$K$J$j$^$9(B: +$B0J2<$N%-!<%\!<%IL?Na$,;H$($k$h$&$K$J$j$^$9(B: @table @kbd @item M-d @@ -21489,14 +21655,239 @@ Spam $B5-;v$r8+$?$H$-$O$$$D$G$b!"%0%k!<%W$rH4$1$kA0$KI,$:(B @kbd{M-d} $B$G$=$ $B$3$N%3%^%s%I$,$A$c$s$HF/$/$?$a$K$O(B Bogofilter $B$r%$%s%9%H!<%k$7$J$1$l$P$J(B $B$j$^$;$s!#(B -@xref{Bogofilter}$B!#(B +@xref{Bogofilter}. @end table -$B$^$?!"(B@code{spam.el} $B$r(B load $B$9$k$H!"$=$NJQ?t72$r%+%9%?%^%$%:$9$k$3$H$,(B -$B$G$-$k$h$&$K$J$j$^$9!#(B@samp{spam} $BJQ?t%0%k!<%W$K$D$$(B +$B$^$?!"(B@file{spam.el} $B$rFI$_9~$`$H!"$=$NJQ?t72$r%+%9%?%^%$%:$9$k$3$H$,$G(B +$B$-$k$h$&$K$J$j$^$9!#(B@samp{spam} $BJQ?t%0%k!<%W$K$D$$(B $B$F(B @code{customize-group} $B$r;n$7$F$_$F2<$5$$!#(B +@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 + +$BI,$:$3$N9`$rFI$s$G2<$5$$!#(B@code{spam.el} $B$NF0:n$rM}2r$9$k$?$a$K!#FI$_Ht(B +$B$P$7!"B.FI!"$NItJ,$N4V$KFs$D$N@\E@(B +$B$,$"$j$^$9(B: spam $B$N$?$a$N?7Ce%a!<%k$N8!::!"$*$h$S%0%k!<%W$rH4$1$k>l9g$G(B +$B$9!#(B + +$B?7Ce%a!<%k$NH$7$F2<$5$$!#(B + +@code{nntp} $B$N$h$&$J%P%C%/%(%s%I$K$O$d$C$FMh$k%a!<%k$N%9%W!<%k$,L5$$$N$G!"(B +$BBe$o$j$N5!9=$r;H$o$J$1$l$P$J$j$^$;$s!#$3$l$O!"%5!<%P!<$,$d$C$FMh$?%a!<%k(B +$B$NJ,3d$rC4Ev$7$F$$$F!"(BGnus $B$,$5$i$KJ,3d$r9T$J$o$J$$%P%C%/%(%s%I$G$b5/$-(B +$B$k$+$b$7$l$^$;$s!#%0%k!<%W%Q%i%a!<(B +$B%?(B @code{spam-autodetect} $B$H(B @code{spam-autodetect-methods} ($BIaDL(B @kbd{G +c} and @kbd{G p} $B$GA`:n2D(B)$B!"$=$7$FBP1~$9$kJQ(B +$B?t(B @code{gnus-spam-autodetect-methods} $B$*$h(B +$B$S(B @code{gnus-spam-autodetect-methods} (@kbd{M-x customize-variable} $B$G(B +$BA`:n2D(B) $B$G$9!#(B + +@code{spam-autodetect} $B$,;H$o$l$k>l9g!"$=$l$O%0%k!<%W$KF~$k=hM}$K0z$C$+(B +$B$1$i$l$^$9!#$7$?$,$C$F!"$^$@FI$^$l$?$3$H$,L5$$!"$^$?$OL$FI$N5-;v$,$"$k%0(B +$B%k!<%W$KF~$k$3$H$O!"$d$C$FMh$?%a!<%k$N8!::$NBe$o$j$K$J$j$^$9!#$^$@FI$^$l(B +$B$?$3$H$,L5$$5-;v!"$^$?$O$9$Y$F$NL$FI$N5-;v$,=hM}$5$l$k$+$I$&$+$O!"(B +@code{spam-autodetect-recheck-messages} $B$K$h$C$F7h$^$j$^$9!#(Bt $B$K@_Dj$5$l(B +$B$k$H!"L$FI$N%a%C%;!<%8$,:F8!::$5$l$^$9!#(B + +@code{spam-autodetect} $B$O!"%f!<%6$K(B spam $B_I2a$NB?>/$N4IM}$rB(9oG'$a$^$9!#(B +$B%f!<%6$O3F%0%k!<%W$N(B spam $B$No$N(B spam $B$H$7$F(B +$B=hM}$5$l$^$9!#H`$,(B @code{spam-split} $B$G9T$J$C$F$bNI$$$h$&$K!"%f!<%6$O8!(B +$B::$N(B @emph{sequence} $B$r$h$j>/$J$/4IM}$7$^$9!#(B + +$B?7$?$KJ,3d$5$l$?%a!<%k$,%0%k!<%W$KF~$C$?!"$^$?$O%a%C%;!<%8$,(B ham $B$^$?(B +$B$O(B spam $B$H$7$F<+F08!CN$5$l$?>l9g!"8e$K(B spam $B=hM}$r9T$J$o$;$k$?$a$K!"$=$l(B +$B$i$N%0%k!<%W$r(B ($BI,MW$J$iF~$C$?8e$G(B) $BH4$1=P$J$/$F$O$J$j$^$;$s!#%0%k!<%W$,(B +$B$=$N(B @code{spam-content} $B%Q%i%a!<%?(B (@pxref{Spam ELisp Package Global +Variables}) $B$K4p$E$$$F(B ham $B$^$?$O(B spam $B%0%k!<%W$H9M$($i$l$k$+!"L$J,N`$+(B +$B$I$&$+$O=EMW$G$9!#(BSpam $B%0%k!<%W$O!"$=$3$KF~$k$H!"$^$@FI$^$l$?$3$H$,L5$$!"(B +$B$^$?$OL$FI$N5-;v$K(B spam $B$N0u$,IU$1$i$l$k(B ($BJQ(B +$B?t(B @code{spam-mark-only-unseen-as-spam} $B$K0MB8(B) $B$H$$$&DI2C$NFC@-$r;}$A$^(B +$B$9!#$3$N$h$&$K!"J,3d$5$l$F(B spam $B%0%k!<%W$KF~$l$i$l$?5-;v$K$O!"$"$J$?$,$=(B +$B$N%0%k!<%W$KF~$C$?$H$-$K<+F0E*$K(B spam $B$N0u$,IU$1$i$l$^$9!#(B + +$B$7$?$,$C$F!"%0%k!<%W$rH4$1$k$H(B @code{spam-processors} $B$,(B ($B2?$G$"$l@_Dj$5(B +$B$l$F$$$l$P(B) $BE,MQ$5$l!"=hM}$5$l$?%a!<%k$O5-;v$NJ,N`$K4p$E$$(B +$B$F(B @code{ham-process-destination} $B$+(B @code{spam-process-destination} $B$K(B +$B0\F0$5$;$i$l$^$9!#(B@code{ham-process-destination} $B$^$?(B +$B$O(B @code{spam-process-destination} $B$N$I$A$i$+$,(B ($BLuCp(B: $B0\F0@h$H$7$F(B) $BE,(B +$B@Z$G!"$=$l$i$,(B nil $B$@$C$?>l9g!"$=$N5-;v$O8=:_$N%0%k!<%W$K;D$5$l$^$9!#(B + +$B$I$l$+$N%0%k!<%W$G(B spam $B$,8+$D$+$C$?$i(B ($BHs(B-spam $B%0%k!<%W$K8B$C(B +$B$F(B @code{spam-move-spam-nonspam-groups-only} $B$GJQ992D(B)$B!"%0%k!<%W$rH4$1$k(B +$B$H$-$K3h$-$F$$$k(B @code{spam-processors} (@pxref{Spam ELisp Package +Global Variables}) $B$G=hM}$5$l$^$9!#$5$i$K!"8e$G%H%l!<%K%s%0$^$?$O:o=|$9(B +$B$k$?$a$K!"(Bspam $B$O(B @code{spam-process-destination} (@pxref{Spam ELisp +Package Global Variables}) $B$K0\F0$5$;$i$l$^$9!#(BSpam $B$,:F;0=hM}$5$l$k$3$H(B +$B$rK>$^$J$$$J$i$P!"(B@file{gnus-registry.el} $B%Q%C%1!<%8$rFI$_9~$_!"(B +@code{spam-log-to-registry} $BJQ?t$rM-8z$K$7$J$1$l$P$J$j$^$;$s!#$3$N$h$&(B +$B$K(B spam $B$O$I$3$G$b8!CN$5$l=hM}$5$l$^$9!#$=$l$O$[$H$s$I$N?M!9$,K>$`$b$N$G(B +$B$9!#(B@code{spam-process-destination} $B$,(B nil $B$@$C$?>l9g!"(Bspam $B$K$O4|8B@Z$l(B +$B>C5n$N0u$,IU$1$i$l$^$9!#IaDL$=$l$O@5$7$$9T$J$$$G$9!#(B + +Spam $B$,0\F0$G$-$J$$>l9g(B ($BNc$($P(B NNTP $B$N$h$&$JFI$_9~$_@lMQ%P%C%/%(%s%I$N(B +$B$?$a$K(B)$B!"$=$l$O%3%T!<$5$l$^$9!#(B + +Ham $B%0%k!<%W$G(B @code{ham-marks} $B%Q%i%a!<%?$G7hDj$5$l$k(B ham $B%a!<%k$,8+$D(B +$B$+$C$?$i!"%0%k!<%W$rH4$1$k$H$-$K3h$-$F$$$k(B ham @code{spam-processor} $B$G(B +$B=hM}$5$l$^$9!#$5$i$K!"JQ?t(B @code{spam-process-ham-in-spam-groups} $B$*$h(B +$B$S(B @code{spam-process-ham-in-nonham-groups} $B$K$h$C$F!"$I$3$G8+$D$+$C(B +$B$?(B ham $B$G$b=hM}$G$-$k$h$&$KF0:n$rJQ99$9$k$3$H$,$G$-$^$9!#(BHam $B$,:F;0=hM}(B +$B$5$l$k$3$H$rK>$^$J$$$J$i$P!"(B@file{gnus-registry.el} $B%Q%C%1!<%8$rFI$_9~$_!"(B +@code{spam-log-to-registry} $BJQ?t$rM-8z$K$7$J$1$l$P$J$j$^$;$s!#$3$N$h$&(B +$B$K(B ham $B$OI,MW$J>l9g$@$18!CN$5$l=hM}$5$l$^$9!#$=$l$O$[$H$s$I$N?M!9$,K>$`(B +$B$b$N$G$9!#$3$l$K4X$9$k>\:Y$O(B @xref{Spam ELisp Package Configuration +Examples}. + +Ham $B$,0\F0$G$-$J$$>l9g(B ($BNc$($P(B NNTP $B$N$h$&$JFI$_9~$_@lMQ%P%C%/%(%s%I$N$?(B +$B$a$K(B)$B!"$=$l$O%3%T!<$5$l$^$9!#(B + +$B$3$l$i$9$Y$F$,$o$1$,$o$+$i$J$/$F$b!"?4G[$OL5MQ$G$9(B ($BLuCm(B: $B$G$bLuJ8$,@53N(B +$B$G$O$J$$$+$b$7$l$J$$$N$G!"JQ$@$H;W$C$?$i86J8$r;2>H$N$3$H(B :-p)$B!#$9$0$K$=(B +$B$l$O?@7P%$%s%?!<%U%'!<%9>e$K(B Lisp $B<0$r%?%$%W$9$k$h$&$K<+A3$J$3$H$K$J$j$^(B +$B$9(B... $B$(!+$4$a$s!"$=$l$K$O$^$@(B 50$BG/Aa$$$G$9$M!#$?$@;d$?$A$r?.Mj$7$F2<$5(B +$B$$!#$=$l$OA0$N%0%k!<%W$KAw$j$^$9!#%G%#(B +$B%U%)%k%H$G$O$=$N%0%k!<%WL>$O(B @samp{spam} $B$G$9$,!"(B +@code{spam-split-group} $B$r%+%9%?%^%$%:$9$k$3$H$,2DG=$G$9!#(B +@code{spam-split-group} $B$NFbMF$,(B @emph{$B@dBP(B} $B%0%k!<%WL>$G$"$k$3$H!"Nc$((B +$B$P(B @samp{your-server} $B$H$$$&(B @code{nnimap} $B%5!<%P!<$N>l9g$O!"(B +@samp{spam} $BJQ?t$,:G=*E*$K(B @samp{nnimap+your-server:spam} $B$K$J$k$3$H$r3N(B +$B$+$a$F2<$5$$!#=>$C$F(B @samp{nnimap+server:spam} $B$H$$$&CM$O4V0c$$$G!"$=$l(B +$B$O$KBP$7(B +$B$F42MF$+$I$&$+$K0MB8$9$k$G$7$g$&!#(B + +$B$^$?!"(B@code{spam-split} $B$K%Q%i%a!<%?!"Nc$((B +$B$P(B @samp{spam-use-regex-headers} $B$^$?$O(B @samp{"maybe-spam"} $B$rM?$($k$3$H(B +$B$b$G$-$^$9!#$J$<$3$l$,M-MQ$J$N$G$7$g$&$+(B? + +$B$3$l$i$N(B (@code{spam-use-regex-headers} $B$H(B @code{spam-use-blackholes} $B$N(B +$B@_Dj$K$h$k(B) $BJ,3d$N5,B'$r8+$F2<$5$$(B: + +@example + nnimap-split-fancy '(| + (any "ding" "ding") + (: spam-split) + ;; default mailbox + "mail") +@end example + +$B$5$F!"LdBj$O(B ding $B08$F$N%a%C%;!<%8$r$9$Y$F(B ding $B%U%)%k%@!<$KF~$l$h$&$H$7(B +$B$F$$$k$3$H$G$9!#$G$b$=$l$O(B ding $B%a!<%j%s%0%j%9%H08$F$KAw$i$l$?(B spam ($BNc(B +$B$($P(B SpamAssassin $B$H(B @code{spam-use-regex-headers} $B$K$h$C$F8!=P$5$l(B +$B$k(B spam) $B$r5v$7$F$7$^$&$G$7$g$&!#0lJ}!"$$$/$D$+$N(B ding $B08$F$N%a%C%;!<%8(B +$B$O%V%i%C%/%[!<%k%j%9%H$K:\$C$F$$$k%a!<%k%5!<%P!<$+$i$d$C$FMh$k$N$G!"(B +ding $B$N5,B'$h$jA0$K(B @code{spam-split} $B$rH/F0$9$k$3$H$,$G$-$^$;$s!#(B + +SpamAssassin $B%X%C%@!<$K(B ding $B$N5,B'$rCV$-49$($5$;$k$3$H$O$G$-$^$9$,!"B>(B +$B$N$9$Y$F$N(B @code{spam-split} $B$N5,B'(B ($BBhFs$N@55,I=8=%X%C%@!<8!::$r4^(B +$B$`(B) $B$O(B ding $B$N5,B'$N8e$K$J$C$F$7$^$&$G$7$g$&!#(B + +@example + nnimap-split-fancy '(| +;;; spam-use-regex-headers $B$G8!=P$5$l$?$9$Y$F$N(B spam $B$O(B "regex-spam" $B$X!#(B + (: spam-split "regex-spam" 'spam-use-regex-headers) + (any "ding" "ding") +;;; spam-split $B$G8!=P$5$l$?B>$N$9$Y$F$N(B spam $B$O(B spam-split-group $B$X!#(B + (: spam-split) + ;; default mailbox + "mail") +@end example + +$B4pK\E*$K!"$3$l$OFC$K$"$J$?$NI,MW$K0MB8$7$?FCDj$N(B @code{spam-split} $B8!(B +$B::$r5/F0$5$;!"$=$l$i$N8!::$N7k2L$OFCDj$N(B spam $B%0%k!<%W$r;X$7<($7$^$9!#$9(B +$B$Y$F$N%a!<%k$r$9$Y$F$N(B spam $B%F%9%H$KEj$2$kI,MW$O$"$j$^$;$s!#$3$l$,NI$$JL(B +$B$NM}M3$O!"5,B'$r;}$C$F$$$k%a!<%j%s%0%j%9%H$X$N%a%C%;!<%8$KBP$7$F!";q8;=8(B +$BLsE*$J%V%i%C%/%[!<%k!&%A%'%C%/$rr7o(B +$BIU$-$NFI$_9~$_$,9T$o$l$k$+$i$G$9!#(B + +@emph{@acronym{IMAP} $BMxMQl9g$O!"%V!<(B +$B%kJQ?t(B @code{nnimap-split-download-body} $B$,@_Dj$5$l$kI,MW$,$"$j$^$9!#%G%#(B +$B%U%)%k%H$G$O!"(Bnnimap $B%P%C%/%(%s%I$O%a%C%;!<%8%X%C%@!<$@$1$rpJs(B +$B$rF@$k(B) $B$r;H$&$J$i$P!"$3$NJQ?t$r@_Dj$7$J$1$l$P$J$j$^$;$s!#$=$l(B +$B$O(B @acronym{IMAP} $B$NF0:n$rCY$/$7$F$7$^$$!"%f!<%6$rBeI=$9$k$N$K$U$5$o$7$$(B +$B7hDj$G$O$J$$$N$G!"%G%#%U%)%k%H$G$O@_Dj$5$l$F$$$^$;$s!#(B + +@xref{Splitting in IMAP}. + +@emph{TODO: spam.el $B$O$9$Y$F$NE}7W%G!<%?%Y!<%9$r%H%l!<%K%s%0$9$k$?$a$N0l(B +$BDjITJQ$NJ}K!$rDs6!$9$kI,MW$,$"$j$^$9!#$$$/$D$+$O$=$N5!G=$r<+A0$G;}$C$F$$(B +$B$^$9$,!"$=$&$G$J$$$b$N$b$"$j$^$9!#(B} + +@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 Ham $B%W%m%;%C%5!<$H(B spam $B%W%m%;%C%5!<$N35G0$OHs>o$K=EMW$G$9!#$"$k%0%k!<%W(B $B$N(B ham $B%W%m%;%C%5!<$H(B spam $B%W%m%;%C%5!<$O!"(B@code{spam-process} $B%0%k!<%W(B @@ -21507,6 +21898,10 @@ ham $B%W%m%;%C%5!<$OHs(B spam (@emph{ham}) $B$G$"$k$3$H$,$o$+$C$F$$$k%a!<%k$r $B$N(B spam $B$,8!=P$5$l$k$h$&$K!"(Bspam $B$G$"$k$3$H$,$o$+$C$F$$$k%a!<%k$r\$7$/$O8D!9$N(B spam $B%W%m%;%C(B +$B%5!<$N9`$r;2>H$7$F2<$5$$!#(B + @vindex gnus-spam-newsgroup-contents gnus $B$O$"$J$?$,e$N(B spam $B%0(B $B%k!<%W$K(B spam $B5-;v$r=8$a$F!"JQ?t(B @code{spam-junk-mailgroups} $B$rE,@Z$K@_(B @@ -21553,12 +21948,17 @@ Spam $B%0%k!<%W$G$O!"%G%#%U%)%k%H$G$9$Y$F$N%a%C%;!<%8$,(B spam $B$G$"$k$H2rC5n(B (deleted)$B!"4{FI(B (read)$B!"(B $B:o=|(B (killed)$B!"(Bkill $B%U%!%$%k$K$"$k$b$N(B (kill-filed) $B$*$h$SDc$$%9%3(B -$B%"(B (low-score) $B0u$N%j%9%H$G$9!#(B +$B%"(B (low-score$B!"4{FI$@$1$l$I$b(B spam $B$G$O$J$$$H9M$($k(B) $B0u$N%j%9%H$G$9!#(B +Ham $B0u$N%j%9%H$K2D;k(B (tick) $B0u$r4^$a$k$3$H$,LrN)$D$3$H$b$"$j$^$9!#L$FI0u(B +$B$r(B ham $B0u$K$9$k$3$H$O!"DL>o$=$l$,J,N`$,B-$j$F$$$J$$$3$H$rI=$9$N$G!"4+$a(B +$B$i$l$^$;$s!#$7$+$7!"$"$J$?$,$=$l$r9T$J$&$3$H$O$G$-$k$7!";d$?$A$KITK~$O$"(B +$B$j$^$;$s!#(B @end defvar @defvar spam-marks $B$3$N%0%k!<%W$^$?$O%H%T%C%/%Q%i%a!<%?$r(B spam $B$G$"$k$H2r!l=j$K0\(B $B$5$l$^$9!#$=$l$i$O%0%k!<%WL>$K9gCW$9$k@55,I=8=$N%j%9%H$G(B $B$9(B (@code{customize-variable gnus-ham-process-destinations} $B$K$h$C$F$3$N(B -$BJQ?t$r%+%9%?%^%$%:$9$k$N$,:G$b4JC1$G$9(B)$B!#:G=*E*$J>l=j$O%0%k!<%WL>$G$9!#(B +$BJQ?t$r%+%9%?%^%$%:$9$k$N$,:G$b4JC1$G$9(B)$B!#JQ?t$r$l$N(B +$B%K%e!<%9%0%k!<%W$N;EMM@_Dj$O(B @code{(REGEXP PROCESSOR)} $B$N7A<0$NCM$r;}$A(B +$B$^$9!#:G=*E*$J>l=j$O(B ($BC1?t$^$?$OJ#?t$N(B) $B%0%k!<%WL>$G$9!#(B @code{ham-process-destination} $B%Q%i%a!<%?$,@_Dj$5$l$F$$$J$$$H!"(Bham $B5-;v(B $B$O$=$3$KN1$aCV$+$l$^$9!#(B @code{spam-mark-ham-unread-before-move-from-spam-group} $B%Q%i%a!<%?$,@_Dj(B $B$5$l$F$$$k$H!"(Bham $B5-;v$O0\F0$5$;$i$l$kA0$KL$FI$N0u$,IU$1$i$l$^$9!#(B +Ham $B$,0\F0$G$-$J$$>l9g(B ($BNc$($P(B NNTP $B$N$h$&$JFI$_9~$_@lMQ%P%C%/%(%s%I$N$?(B +$B$a$K(B)$B!"$=$l$O%3%T!<$5$l$^$9!#(B + +$B%0%k!<%W$^$?$O@55,I=8=$4$H$KJ#?t$N0\F0@h$r;XDj$G$-$k$3$H$KCmL\$7$F2<$5$$(B! +$B$3$l$K$h$C$F(B ham $B5-;v$r@55,$N%a!<%k%0%k!<%W$H(B @emph{ham $B%H%l!<%K%s%0(B} $B%0(B +$B%k!<%W$KAw$k$3$H$,$G$-$^$9!#(B + @emph{Ham} $B%0%k!<%W$rH4$1$k$H$-$K!"(Bham $B0u$,IU$$$F$$$k$9$Y$F$N5-;v(B $B$O(B ham $B%W%m%;%C%5!<$KAw$i$l!"$=$l$i$r(B spam $B$G$O$J$$I8K\$H$7$F3X=,$7$^$9!#(B +@vindex spam-process-ham-in-spam-groups +$BJQ?t(B @code{spam-process-ham-in-spam-groups} $B$O%G%#%U%)%k%H$G(B +$B$O(B @code{nil} $B$G$9!#(BSpam $B%0%k!<%W$G8+$D$+$C$?(B ham $B$,%W%m%;%C%5!<$KAw$i$l(B +$B$k$h$&$K$7$?$$>l9g$O(B @code{t} $B$K$7$F2<$5$$!#DL>o$3$l$O9T$J$o$l$^$;$s!#$"(B +$B$J$?$,<+J,$G(B ham $B5-;v$r(B ham $B%0%k!<%W$KAw$C$F!"$=$3$G=hM}$9$k$3$H$,4|BT$5(B +$B$l$F$$$^$9!#(B + +@vindex spam-process-ham-in-nonham-groups +$BJQ?t(B @code{spam-process-ham-in-nonham-groups} $B$O%G%#%U%)%k%H$G(B +$B$O(B @code{nil} $B$G$9!#(BHam $B$G$O$J$$(B (spam $B$^$?$OL$J,N`$N(B) $B%0%k!<%W$G8+$D$+$C(B +$B$?(B ham $B$,%W%m%;%C%5!<$KAw$i$l$k$h$&$K$7$?$$>l9g$O(B @code{t} $B$K$7$F2<$5$$!#(B +$BDL>o$3$l$O9T$J$o$l$^$;$s!#$"$J$?$,<+J,$G(B ham $B5-;v$r(B ham $B%0%k!<%W$KAw$C$F!"(B +$B$=$3$G=hM}$9$k$3$H$,4|BT$5$l$F$$$^$9!#(B + @vindex gnus-spam-process-destinations @emph{Ham} $B$^$?$O(B @emph{$BL$J,N`(B} $B%0%k!<%W$rH4$1$k$H$-$K!"$9$Y$F(B $B$N(B @strong{spam} $B5-;v$O!"(B@code{spam-process-destination} $B%0%k!<%W%Q%i%a!<(B $B%?$+(B @code{gnus-spam-process-destinations} $BJQ?t$N$I$A$i$+$K9gCW$9$k>l=j(B $B$K0\$5$l$^$9!#$=$l$i$O%0%k!<%WL>$K9gCW$9$k@55,I=8=$N%j%9%H$G(B $B$9(B (@code{customize-variable gnus-spam-process-destinations} $B$K$h$C$F$3(B -$B$NJQ?t$r%+%9%?%^%$%:$9$k$N$,:G$b4JC1$G$9(B)$B!#:G=*E*$J>l=j$O%0%k!<%WL>$G$9!#(B +$B$NJQ?t$r%+%9%?%^%$%:$9$k$N$,:G$b4JC1$G$9(B)$B!#JQ?t$r$l(B +$B$N%K%e!<%9%0%k!<%W$N;EMM@_Dj$O(B @code{(REGEXP GROUP)} $B$N7A<0$NCM$r;}$A$^(B +$B$9!#:G=*E*$J>l=j$O(B ($BC1?t$^$?$OJ#?t$N(B) $B%0%k!<%WL>$G$9!#(B @code{spam-process-destination} $B%Q%i%a!<%?$,@_Dj$5$l$F$$$J$$$H!"(Bspam $B5-(B -$B;v$OC1$K4|8B@Z$l>C5n$5$l$^$9!#(B +$B;v$OC1$K4|8B@Z$l>C5n$5$l$^$9!#%0%k!<%WL>$O40A47A$G$"$k$3$H!"$9$J$o$A%0%k!<(B +$B%W%P%C%U%!$G%0%k!<%WL>$NA0$K(B @samp{nntp:servername} $B$N$h$&$J$b$N$,8+$($k(B +$B>l9g$O!"$3$3$G$b$=$l$r;H$&I,MW$,$"$j$^$9!#(B + +Spam $B$,0\F0$G$-$J$$>l9g(B ($BNc$($P(B NNTP $B$N$h$&$JFI$_9~$_@lMQ%P%C%/%(%s%I$N(B +$B$?$a$K(B)$B!"$=$l$O%3%T!<$5$l$^$9!#(B + +$B%0%k!<%W$^$?$O@55,I=8=$4$H$KJ#?t$N0\F0@h$r;XDj$G$-$k$3$H$KCmL\$7$F2<$5$$(B! +$B$3$l$K$h$C$F(B spam $B5-;v$r@55,$N%a!<%k%0%k!<%W(B +$B$H(B @emph{spam $B%H%l!<%K%s%0(B} $B%0%k!<%W$KAw$k$3$H$,$G$-$^$9!#(B + +@vindex spam-log-to-registry +Ham $B$H(B spam $B$K4X$9$kLdBj$O!"(BGnus $B$,%G%#%U%)%k%H$G$O$3$N=hM}$rDI@W$7$F$/(B +$B$l$J$$$3$H$G$9!#=hM}$5$l$?5-;v$rDI@W$7!"$+$DJ#?t2s$K$o$?$C$F=hM}$9$k$3$H(B +$B$r2sHr$9$k$?$a$K(B @code{spam.el} $B$,(B @code{gnus-registry.el} $B$r;H$&$h$&$K!"(B +@code{spam-log-to-registry} $BJQ?t$rM-8z$K$7$F$/$@$5$$!#EPO??t$r@)8B$9$k$H!"(B +$B@)8B$,L5$$>l9g$N$h$&$KF0:n$7$J$$$3$H$r3P$($F$*$$$F2<$5$$!#(B + +@vindex spam-mark-only-unseen-as-spam +Spam $B%0%k!<%W$K$"$k!"$^$@FI$^$l$?$3$H$,L5$$5-;v$@$1$K(B spam $B$N0u$rIU$1$?(B +$B$$>l9g$O!"$3$NJQ?t$r%;%C%H$7$F2<$5$$!#%G%#%U%)%k%H$G$O%;%C%H$5$l$F$$$^$9!#(B +$B$3$l$r(B nil $B$K$9$k$H!"L$FI$N5-;v$K$b(B spam $B0u$,IU$1$i$l$^$9!#(B + +@vindex spam-mark-ham-unread-before-move-from-spam-group +Ham $B$,(B spam $B%0%k!<%W$+$i0\F0$5$l$kA0$K0u$r>C$7$?$$>l9g$O!"$3$NJQ?t$r%;%C(B +$B%H$7$F2<$5$$!#$3$l$O(B ham $B$K0u$rIU$1$k$?$a$K2D;k(B (tick) $B0u$N$h$&$J$b$N$r(B +$B;H$&>l9g$K!"$H$F$bLr$KN)$A$^$9!#5-;v$O$"$?$+$b$=$l$,%a!<%k%5!<%P$r=P$?$P(B +$B$+$j$N$h$&$K!"L50u$G(B ham $B=hM}>l$KCV$+$l$k$G$7$g$&!#(B + +@vindex spam-autodetect-recheck-messages +$B$3$NJQ?t$O(B @code{spam.el} $B$,(B spam $B$N<+F08!CN$r9T$J$&>l9g$K!"$^$@FI$^$l$?(B +$B$3$H$,L5$$5-;v$@$1!"$^$?$O$9$Y$F$NL$FI5-;v$N(B spam $B8!::$r9T$J$&$+$I$&$+$r(B +$B;X<($7$^$9!#$3$l$O$=$N$^$^$K$7$F$*$/$3$H$r4+$a$^$9!#(B + +@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 -$BF~$C$F$/$k%a!<%k$r_I2a$9$kL\E*$G(B @code{spam.el} $B$r;H$&$K$O!"FC5iJ,3d%j%9(B -$B%H(B @code{nnmail-split-fancy} $B$^$?$O(B @code{nnimap-split-fancy} $B$K0J2<$rDI(B -$B2C$7$J$1$l$P$J$j$^$;$s(B: +@subsubheading Ted's setup +From Ted Zlatanov . @example -(: spam-split) -@end example -$BFC5iJ,3d$O!"%a!<%k$NA0$N%0%k!<%W$KAw$j$^$9!#%G%#(B -$B%U%)%k%H$G$O$=$N%0%k!<%WL>$O(B @samp{spam} $B$G$9$,!"(B -@code{spam-split-group} $B$r%+%9%?%^%$%:$9$k$3$H$,2DG=$G$9!#(B +;; my parameters, set with `G p' -@c TRANSLATEME -You can also give @code{spam-split} a parameter, -e.g. @samp{'spam-use-regex-headers}. Why is this useful? +;; all nnml groups, and all nnimap groups except +;; "nnimap+mail.lifelogs.com:train" and +;; "nnimap+mail.lifelogs.com:spam": any spam goes to nnimap training, +;; because it must have been detected manually -Take these split rules (with @code{spam-use-regex-headers} and -@code{spam-use-blackholes} set): +((spam-process-destination . "nnimap+mail.lifelogs.com:train")) -@example - nnimap-split-fancy '(| - (any "ding" "ding") - (: spam-split) - ;; default mailbox - "mail") -@end example +;; all NNTP groups +;; autodetect spam with the blacklist and ham with the BBDB +((spam-autodetect-methods spam-use-blacklist spam-use-BBDB) +;; send all spam to the training group + (spam-process-destination . "nnimap+mail.lifelogs.com:train")) -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. +;; only some NNTP groups, where I want to autodetect spam +((spam-autodetect . t)) -You can let SpamAssassin headers supercede ding rules, but all other -@code{spam-split} rules (including a second invocation of the -regex-headers check) will be after the ding rule: +;; my nnimap "nnimap+mail.lifelogs.com:spam" group + +;; this is a spam group +((spam-contents gnus-group-spam-classification-spam) + + ;; any spam (which happens when I enter for all unseen messages, + ;; because of the gnus-spam-newsgroup-contents setting above), goes to + ;; "nnimap+mail.lifelogs.com:train" unless I mark it as ham + + (spam-process-destination "nnimap+mail.lifelogs.com:train") + + ;; any ham goes to my "nnimap+mail.lifelogs.com:mail" folder, but + ;; also to my "nnimap+mail.lifelogs.com:trainham" folder for training + + (ham-process-destination "nnimap+mail.lifelogs.com:mail" + "nnimap+mail.lifelogs.com:trainham") + ;; in this group, only '!' marks are ham + (ham-marks + (gnus-ticked-mark)) + ;; remembers senders in the blacklist on the way out - this is + ;; definitely not needed, it just makes me feel better + (spam-process (gnus-group-spam-exit-processor-blacklist))) + +;; Later, on the IMAP server I use the "train" group for training +;; SpamAssassin to recognize spam, and the "trainham" group for +;; recognizing ham - but Gnus has nothing to do with it. -@example - nnimap-split-fancy '(| - (: spam-split 'spam-use-regex-headers) - (any "ding" "ding") - (: spam-split) - ;; default mailbox - "mail") @end example -Basically, this lets you invoke specific @code{spam-split} checks -depending on your particular needs. 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. +@subsubheading Using @file{spam.el} on an IMAP server with a statistical filter on the server -You still have to have specific checks such as -@code{spam-use-regex-headers} set to t, even if you specifically -invoke @code{spam-split} with the check. The reason is that when -loading @code{spam.el}, some conditional loading is done depending on -what @code{spam-use-xyz} variables you have set. +From Reiner Steib . -@emph{@acronym{IMAP} $BMxMQl9g$O!"%V!<(B -$B%kJQ?t(B @code{nnimap-split-download-body} $B$,@_Dj$5$l$kI,MW$,$"$j$^$9!#%G%#(B -$B%U%)%k%H$G$O!"(Bnnimap $B%P%C%/%(%s%I$O%a%C%;!<%8%X%C%@!<$@$1$rpJs(B -$B$rF@$k(B) $B$r;H$&$J$i$P!"$3$NJQ?t$r@_Dj$7$J$1$l$P$J$j$^$;$s!#$=$l(B -$B$O(B @acronym{IMAP} $B$NF0:n$rCY$/$7$F$7$^$$!"%f!<%6$rBeI=$9$k$N$K$U$5$o$7$$(B -$B7hDj$G$O$J$$$N$G!"%G%#%U%)%k%H$G$O@_Dj$5$l$F$$$^$;$s!#(B +With the following entries in @code{gnus-parameters}, @code{spam.el} +does most of the job for me: -@xref{Splitting in IMAP}. +@lisp + ("nnimap:spam\\.detected" + (gnus-article-sort-functions '(gnus-article-sort-by-chars)) + (ham-process-destination "nnimap:INBOX" "nnimap:training.ham") + (spam-contents gnus-group-spam-classification-spam)) + ("nnimap:\\(INBOX\\|other-folders\\)" + (spam-process-destination . "nnimap:training.spam") + (spam-contents gnus-group-spam-classification-ham)) +@end lisp -@emph{TODO: $B8=>u(B spam.el $B$O5-;v$r%P%C%/%(%s%I$KEjF~$9$k$3$H$@$1$r%5%]!<(B -$B%H$7$^$9!#5-;v$,$b$O$d(B spam $B$^$?$O(B ham $B$G$O$J$$$H(B spam.el $B$KEA$($kJ}K!$O(B -$B$"$j$^$;$s!#(B} +@itemize -@emph{TODO: spam.el $B$O$9$Y$F$NE}7W%G!<%?%Y!<%9$r71N}$9$k$?$a$N0lDjITJQ$N(B -$BJ}K!$rDs6!$9$kI,MW$,$"$j$^$9!#$$$/$D$+$O$=$N5!G=$r<+A0$G;}$C$F$$$^$9$,!"(B -$B$=$&$G$J$$$b$N$b$"$j$^$9!#(B} +@item @b{The Spam folder:} -$B0J2<$O(B @code{spam-split} $B$NF0:n$r@)8f$9$k$?$a$K;H$&$3$H$,$G$-$k3F. + +With following entry in @code{gnus-parameters}, @kbd{S x} +(@code{gnus-summary-mark-as-spam}) marks articles in @code{gmane.*} +groups as spam and reports the to Gmane at group exit: + +@lisp + ("^gmane\\." + (spam-process (gnus-group-spam-exit-processor-report-gmane))) +@end lisp + +Additionally, I use `(setq spam-report-gmane-use-article-number nil)' +because I don't read the groups directly from news.gmane.org, but +through my local news server (leafnode). I.e. the article numbers are +not the same as on news.gmane.org, thus @code{spam-report.el} has to check +the @code{X-Report-Spam} header to find the correct number. @node Blacklists and Whitelists @subsubsection $B%V%i%C%/%j%9%H$H%[%o%$%H%j%9%H(B @@ -21742,6 +22265,12 @@ what @code{spam-use-xyz} variables you have set. $B$,%0%k!<%W$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($i$l$k$H!"(Bspam $B0u$,IU$$(B $B$?5-;v$NAw?.)$7$^$9!#$9$Y$FF1Ey$KF0(B +$B:n$9$k$3$H$OJ]>Z$5$l$^$9!#(B + @end defvar @defvar gnus-group-ham-exit-processor-whitelist @@ -21754,6 +22283,12 @@ what @code{spam-use-xyz} variables you have set. $B$N(B ham $B%W%m%;%C%5!<$O(B @emph{spam} $B$+(B @emph{$BL$J,N`(B} $B%0%k!<%W$K$O8z2L$r5Z(B $B$\$5$J$$$3$H$KCm0U$7$F2<$5$$!#(B +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-ham-exit-processor-whitelist} $B$NBe$o$j$K!"(B +@code{'(ham spam-use-whitelist)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$KF0(B +$B:n$9$k$3$H$OJ]>Z$5$l$^$9!#(B + @end defvar $B%V%i%C%/%j%9%H$O!"$"$J$?$,(B spam $B$NAw?.)$7$^$9!#$9$Y$FF1Ey$KF0:n$9$k(B +$B$3$H$OJ]>Z$5$l$^$9!#(B + @end defvar -@c TRANSLATEME @node Gmane Spam Reporting -@subsubsection Gmane Spam Reporting +@subsubsection Gmane Spam $BJs9p(B @cindex spam reporting @cindex Gmane, spam reporting @cindex Gmane, spam reporting @@ -21823,30 +22363,47 @@ what @code{spam-use-xyz} variables you have set. @defvar gnus-group-spam-exit-processor-report-gmane -Add this symbol to a group's @code{spam-process} parameter by -customizing the group parameters or the -@code{gnus-spam-process-newsgroups} variable. When this symbol is -added to a group's @code{spam-process} parameter, the spam-marked -articles groups will be reported to the Gmane administrators. +$B%0%k!<%W%Q%i%a!<%?$+JQ?t(B @code{gnus-spam-process-newsgroups} $B$r%+%9%?%^(B +$B%$%:$7$F!"$3$N%7%s%\%k$r%0%k!<%W$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$((B +$B$F2<$5$$!#$3$l$,2C$($i$l$k$H!"(Bspam $B0u$,IU$$$?5-;v$N%0%k!<%W$,(B HTTP $B7PM3(B +$B$G(B Gmane $B$N4IM})$7$^$9!#$9$Y$FF1Ey$KF0:n$9(B +$B$k$3$H$OJ]>Z$5$l$^$9!#(B + +@end defvar + +@defvar spam-report-gmane-use-article-number + +$B$3$NJQ?t$O%G%#%U%)%k%H$G(B @code{t} $B$G$9!#$"$J$?<+?H$,%K%e!<%9%5!<%P!<$r1?(B +$B1D$7$F$$$k!"$9$J$o$A%m!<%+%k$J5-;vHV9f$,(B Gmane $B$N5-;vHV9f$H9g$o$J$$>l9g(B +$B$O!"(B@code{nil} $B$K@_Dj$7$F2<$5$$!#(B +@code{spam-report-gmane-use-article-number} $B$,(B @code{nil} $B$G$"$k$H!"(B +@file{spam-report.el} $B$O(B Gmane $B$,Ds6!$9$k(B @code{X-Report-Spam} $B%X%C%@!<(B +$B$r;H$$$^$9!#(B @end defvar @node Anti-spam Hashcash Payments -@subsubsection Anti-spam Hashcash Payments +@subsubsection $BHs(B-spam Hashcash $B0u(B @cindex spam filtering @cindex hashcash, spam filtering @cindex spam @defvar spam-use-hashcash -Similar to @code{spam-use-whitelist} (@pxref{Blacklists and -Whitelists}), but uses hashcash tokens for whitelisting messages -instead of the sender address. You must have the @code{hashcash.el} -package loaded for @code{spam-use-hashcash} to work properly. -Messages without a hashcash payment token will be sent to the next -spam-split rule. This is an explicit filter, meaning that unless a -hashcash token is found, the messages are not assumed to be spam or -ham. +@code{spam-use-whitelist} (@pxref{Blacklists and Whitelists}) $B$K;w$F$$$^(B +$B$9$,!"Aw?.u$G$O(B @code{spam-use-dig} $B$r(B @code{nil} $B$K@_Dj$9$k$3$H$O!"$$(B $B$/?M$+$N%f!<%6!<$,;H$($J$$$+$b$7$l$J$$$N$G!"$=$l$,2DG=$J@-G=2~A1$G$"$k$K(B $B$b$+$+$o$i$:?d>)$5$l$^$;$s!#$7$+$7!"$=$l$,F0$/$+$I$&$+$r3N$+$a$k$3$H$O$G(B @@ -21890,7 +22447,7 @@ ham. @defvar spam-use-dig -@code{dns.el} $B%Q%C%1!<%8$NBe$o$j$K(B @code{dig.el} $B%Q%C%1!<%8$r;H$$$^$9!#(B +@file{dns.el} $B%Q%C%1!<%8$NBe$o$j$K(B @file{dig.el} $B%Q%C%1!<%8$r;H$$$^$9!#(B $B%G%#%U%)%k%H$N@_Dj$G$"$k(B @code{t} $B$,?d>)$5$l$^$9!#(B @end defvar @@ -21950,8 +22507,9 @@ Spam $B5-;v$@$1$N(B @samp{$} $B0u$r4XO"IU$1$k:G>.$N@$OC$K$h$C$F!"(BBogofilte $B$N5-;v$N(B @emph{spamicity} ($BLuCm(B: spam $BEY(B?) $B%9%3%"(B (0.0$B!A(B1.0) $B$rI=<($7$^(B $B$9!#(B -Bogofilter $B$O!"%3%s%Q%$%k;~$K@_Dj$5$l$kFbIt$NogCM$K4p$E$$$F!"%a%C%;!<%8(B -$B$,(B spam $B$+$I$&$+$r7hDj$7$^$9!#ogCM$O%+%9%?%^%$%:$G$-$^$;$s!#(B +Bogofilter $B$O!"$"$k0lDj$NogCM$K4p$E$$$F!"%a%C%;!<%8$,(B spam $B$+$I$&$+$r8+(B +$B6K$a$^$9!#ogCM$O%+%9%?%^%$%:$G$-$^$9!#(BBogofilter $B$N%I%-%e%a%s%H$rD4$Y$F(B +$B2<$5$$!#(B Path $B$K(B @code{bogofilter} $B$Nl9g!"(BBogofilter $B$N=hM}$O(B $BC$5$l$^$9!#(B @@ -21980,6 +22538,12 @@ Path $B$K(B @code{bogofilter} $B$Nl9g!"(BBogofilter $B$N $B$O(B @code{gnus-spam-process-newsgroups} $BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k(B $B$,%0%k!<%W$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($i$l$k$H!"(Bspam $B0u$,IU$$(B $B$?5-;v$,(B bogofilter $B$N(B spam $B%G!<%?%Y!<%9$K2C$($i$^$9!#(B + +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-spam-exit-processor-bogofilter} $B$NBe$o$j$K!"(B +@code{'(spam spam-use-bogofilter)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$K(B +$BF0:n$9$k$3$H$OJ]>Z$5$l$^$9!#(B @end defvar @defvar gnus-group-ham-exit-processor-bogofilter @@ -21990,6 +22554,12 @@ Path $B$K(B @code{bogofilter} $B$Nl9g!"(BBogofilter $B$N $B$?(B @emph{ham} $B%0%k!<%W$N5-;v$,Hs(B-spam $B5-;vMQ$N(B Bogofilter $B%G!<%?%Y!<%9$K(B $BDI2C$5$l$^$9!#$3$N(B ham $B%W%m%;%C%5!<$O(B @emph{spam} $B$+(B @emph{$BL$J,N`(B} $B%0%k!<(B $B%W$K$O8z2L$r5Z$\$5$J$$$3$H$KCm0U$7$F2<$5$$!#(B + +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-ham-exit-processor-bogofilter} $B$NBe$o$j$K!"(B +@code{'(ham spam-use-bogofilter)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$KF0(B +$B:n$9$k$3$H$OJ]>Z$5$l$^$9!#(B @end defvar @defvar spam-bogofilter-database-directory @@ -22000,10 +22570,10 @@ Path $B$K(B @code{bogofilter} $B$Nl9g!"(BBogofilter $B$N @end defvar -Bogofilter $B$N%a!<%kJ,N`4o$O!"0U?^$HL\E*$NE@$G(B ifile $B$K;w$F$$$^$9!#(B -Spam $B$H(B ham $B$N%W%m%;%C%5!<$,Ds6!$5$l!"2C$($F(B spam-$BJ,3d(B (spam-split) $B$K(B -$B$b(B Bogofilter $B$,;H$o$l$k$Y$-$G$"$k$3$H!"$^$?$O$9$G$K5-;v$K;H$o$l$?$3$H$r(B -$B<($9(B @code{spam-use-bogofilter} $B$*$h(B +Bogofilter $B$N%a!<%kJ,N`4o$O!"0U?^$HL\E*$NE@$G(B @command{ifile} $B$K;w$F$$$^(B +$B$9!#(BSpam $B$H(B ham $B$N%W%m%;%C%5!<$,Ds6!$5$l!"2C$($F(B spam-$BJ,(B +$B3d(B (spam-split) $B$K$b(B Bogofilter $B$,;H$o$l$k$Y$-$G$"$k$3$H!"$^$?$O$9$G$K5-(B +$B;v$K;H$o$l$?$3$H$r<($9(B @code{spam-use-bogofilter} $B$*$h(B $B$S(B @code{spam-use-bogofilter-headers} $BJQ?t$,Ds6!$5$l$^$9!#$3$N5!G=$r8!::(B $B$9$k$?$a$K(B Bogofilter $B$N%P!<%8%g%s(B 0.9.2.1 $B$,;H$o$l$^$7$?!#(B @@ -22015,8 +22585,9 @@ Spam $B$H(B ham $B$N%W%m%;%C%5!<$,Ds6!$5$l!"2C$($F(B spam-$BJ,3d(B (spam-s @defvar spam-use-ifile -Bogofilter $B$K;w$?E}7WJ,@O4o$G$"$k(B ifile $B$r(B @code{spam-split} $B$K;H$$$?$$(B -$B>l9g$O!"$3$NJQ?t$rM-8z$K$7$F2<$5$$!#(B +Bogofilter $B$K;w$?E}7WJ,@O4o$G$"(B +$B$k(B @command{ifile} $B$r(B @code{spam-split} $B$K;H$$$?$$>l9g$O!"$3$NJQ?t$rM-8z(B +$B$K$7$F2<$5$$!#(B @end defvar @@ -22024,8 +22595,8 @@ Bogofilter $B$K;w$?E}7WJ,@O4o$G$"$k(B ifile $B$r(B @code{spam-split} $B$K;H @code{spam-use-ifile} $B$K!"C1$J$k(B spam/$BHs(B-spam $B$G$O$J$/$F(B ifile $B$N$9$Y$F(B $B$N%+%F%4%j!<$rM?$($F$b$i$$$?$$$J$i$P!"$3$NJQ?t$rM-8z$K$7$F2<$5$$!#$3$l$r(B -$B;H$&>l9g$O!"$=$NJ88%$K=q$+$l$F$$$k$h$&$K(B ifile $B$r71N}$7$F$*$+$J$1$l$P$J(B -$B$j$^$;$s!#(B +$B;H$&>l9g$O!"$=$NJ88%$K=q$+$l$F$$$k$h$&$K(B ifile $B$r%H%l!<%K%s%0$7$F$*$+$J(B +$B$1$l$P$J$j$^$;$s!#(B @end defvar @@ -22070,6 +22641,12 @@ Emacs Lisp $B$K$h$kE}7WJ,@O4o$G$"$k(B spam-stat.el $B$r(B @code{spam-split} $B$O(B @code{gnus-spam-process-newsgroups} $BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k(B $B$,%0%k!<%W$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($i$l$k$H!"(Bspam $B0u$,IU$$(B $B$?5-;v$,(B spam $B5-;vMQ$N(B spam-stat $B%G!<%?%Y!<%9$KDI2C$5$l$^$9!#(B + +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-spam-exit-processor-stat} $B$NBe$o$j$K!"(B +@code{'(spam spam-use-stat)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$KF0:n$9(B +$B$k$3$H$OJ]>Z$5$l$^$9!#(B @end defvar @defvar gnus-group-ham-exit-processor-stat @@ -22080,16 +22657,139 @@ Emacs Lisp $B$K$h$kE}7WJ,@O4o$G$"$k(B spam-stat.el $B$r(B @code{spam-split} $B$?(B @emph{ham} $B%0%k!<%W$N5-;v$,Hs(B-spam $B5-;vMQ$N(B spam-stat $B%G!<%?%Y!<%9$K(B $BDI2C$5$l$^$9!#$3$N(B ham $B%W%m%;%C%5!<$O(B @emph{spam} $B$+(B @emph{$BL$J,N`(B} $B%0%k!<(B $B%W$K$O8z2L$r5Z$\$5$J$$$3$H$KCm0U$7$F2<$5$$!#(B + +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-ham-exit-processor-stat} $B$NBe$o$j$K!"(B +@code{'(ham spam-use-stat)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$KF0:n$9$k(B +$B$3$H$OJ]>Z$5$l$^$9!#(B @end defvar -$B$3$l$O(B spam.el $B$,(B spam-stat.el $B$HF/$-9g$&$3$H$r2DG=$K$7$^$9!#(B -spam-stat.el $B$O(B (Lisp $B$@$1$N(B) spam $BFbIt%G!<%?%Y!<%9$rDs6!$7$^$9$,!"$=$l(B -$B$O(B ifile $B$d(B Bogofilter $B$H0c$C$F30It%W%m%0%i%`$rI,MW$H$7$^$;$s!#(B +$B$3$l$O(B @file{spam.el} $B$,(B @file{spam-stat.el} $B$HF/$-9g$&$3$H$r2DG=$K$7$^(B +$B$9!#(B@file{spam-stat.el} $B$O(B (Lisp $B$@$1$N(B) spam $BFbIt%G!<%?%Y!<%9$rDs6!$7$^(B +$B$9$,!"$=$l$O(B ifile $B$d(B Bogofilter $B$H0c$C$F30It%W%m%0%i%`$rI,MW$H$7$^$;$s!#(B Spam $B$H(B ham $B$N%W%m%;%C%5!<$H(B @code{spam-split} $B$N$?$a(B $B$N(B @code{spam-use-stat} $BJQ?t$,Ds6!$5$l$^$9!#(B -@node Extending the spam elisp package -@subsubsection Spam elisp $B%Q%C%1!<%8$N3HD%(B +@node SpamOracle +@subsubsection Gnus $B$G(B SpamOracle $B$r;H$&$K$O(B +@cindex spam filtering +@cindex SpamOracle +@cindex spam + +$B5$7Z$K(B spam $B$r_I2a$9$k0l$D$N$d$jJ}$O(B SpamOracle $B$r;H$&$3$H$G$9!#E}7WE*$K(B +$B%a!<%k$r_I2a$9$k$?$a$NF;6q$G$"$k(B SpamOracle $B$O!"(BXavier Leroy $B$K$h$C$F=q(B +$B$+$l$^$7$?!#$3$l$OJL$K%$%s%9%H!<%k$9$kI,MW$,$"$j$^$9!#(B + +Gnus $B$G(B SpamOracle $B$r;H$&$K$O!"$$$/$D$+$N$d$jJ}$,$"$j$^$9!#$9$Y$F$N>l9g(B +$B$K!"%a!<%k$O(B @emph{mark} $B%b!<%I$GF0:n$7$F$$$k(B SpamOracle $B$K%Q%$%W$5$l$^(B +$B$9!#$9$k$H(B SpamOracle $B$O!"$=$N%a!<%k$r(B spam $B$@$H8+$J$7$?$+$I$&$+$r<((B +$B$9(B @samp{X-Spam} $B%X%C%@!<$r5-F~$7$^$9!#(B + +$Bl9g$O(B @samp{Junk} $B$K0\F0$5$;$i$l$^$9!#(BHam $B$J%a%C%;!<%8(B +$B$O(B @samp{INBOX} $B$K;D$j$^$9(B: + +@example +(setq spam-use-spamoracle t + spam-split-group "Junk" + nnimap-split-inbox '("INBOX") + nnimap-split-rule 'nnimap-split-fancy + nnimap-split-fancy '(| (: spam-split) "INBOX")) +@end example + +@defvar spam-use-spamoracle +Gnus $B$K(B SpamOracle $B$r;H$C$F(B spam $B$N_I2a$r$5$;$?$$>l9g$K(B @code{t} $B$K$7$F(B +$B2<$5$$!#(B +@end defvar + +@defvar spam-spamoracle-binary +Gnus $B$O%f!<%6$N(B PATH $B$G8+$D$+$C$?(B @file{spamoracle} $B$H$$$&(B SpamOracle $B$N(B +$B%P%$%J%j$r;H$$$^$9!#$3$l$K$O%+%9%?%^%$%:2DG=$JJQ(B +$B?t(B @code{spam-spamoracle-binary} $B$r;H$$$^$9!#(B +@end defvar + +@defvar spam-spamoracle-database +SpamOracle $B$O$=$N2r@O7k2L$r%G!<%?%Y!<%9$H$7$F3JG<$9$k$?$a$K!"%G%#%U%)%k(B +$B%H$G(B @file{~/.spamoracle.db} $B%U%!%$%k$r;H$$$^$9!#$3$l$OJQ(B +$B?t(B @code{spam-spamoracle-database} $B$G@)8f$5$l!"%G%#%U%)%k%H(B +$B$O(B @code{nil} $B$G$9!#$=$l$O!"%G%#%U%)%k%H$N(B SpamOracle $B%G!<%?%Y!<%9$,;H$o(B +$B$l$k$3$H$r0UL#$7$^$9!#%G!<%?%Y!<%9$,$I$3$+FCJL$J>l=j$K$"$k>l9g$O!"(B +@code{spam-spamoracle-database} $B$r$=$N%Q%9$K@_Dj$7$F2<$5$$!#(B +@end defvar + +SpamOracle $B$O%a%C%;!<%8$,(B spam $B$+(B ham $B$+$r8+6K$a$k$?$a$KE}7WE*$J/$J$$NI$$7k2L$rF@$k$?$a$K!"(BSpamOracle $B$O%H%l!<(B +$B%K%s%0$rI,MW$H$7$^$9!#(BSpamOracle $B$O(B spam $B%a!<%k$NFCD'$r3X$S$^$9!#(B +@emph{add} $B%b!<%I(B ($B%H%l!<%K%s%0!&%b!<%I(B) $B$r;H$C$F!"NI$$%a!<(B +$B%k(B (ham) $B$H(B spam $B$r(B SpamOracle $B$KM?$($J$1$l$P$J$j$^$;$s!#$3$l$O!"35N,%P%C(B +$B%U%!$G(B @kbd{|} $B$r2!$9$3$H$K$h$C$F%a!<%k$r(B SpamOracle $B$N%W%m%;%9$K%Q%$%W(B +$B$9$k$+!"$^$?$O(B @file{spam.el} $B$N(B spam $B$*$h$S(B ham $B%W%m%;%C%5!<$r;H$&$3$H(B +$B$K$h$C$F9T$J$&$3$H$,$G$-$^$9!"(B@xref{Filtering Spam Using The Spam ELisp +Package}. + +@defvar gnus-group-spam-exit-processor-spamoracle +$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W(B +$B$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($k$+!"$^$?(B +$B$O(B @code{gnus-spam-process-newsgroups} $BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k(B +$B$,%0%k!<%W$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($i$l$k$H!"(Bspam $B0u$,IU$$(B +$B$?5-;v$,(B spam $B$N%5%s%W%k$H$7$F(B SpamOracle $B$KAw$i$l$^$9!#(B + +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-spam-exit-processor-spamoracle} $B$NBe$o$j$K!"(B +@code{'(spam spam-use-spamoracle)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$K(B +$BF0:n$9$k$3$H$OJ]>Z$5$l$^$9!#(B +@end defvar + +@defvar gnus-group-ham-exit-processor-spamoracle +$B$3$N%7%s%\%k$r!"%0%k!<%W%Q%i%a!<%?$N%+%9%?%^%$%:$K$h$C$F%0%k!<%W(B +$B$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($k$+!"$^$?(B +$B$O(B @code{gnus-spam-process-newsgroups} $BJQ?t$K2C$($F2<$5$$!#$3$N%7%s%\%k(B +$B$,%0%k!<%W$N(B @code{spam-process} $B%Q%i%a!<%?$K2C$($i$l$k$H!"(B@emph{ham} $B%0(B +$B%k!<%W$K$"$k(B ham $B0u$,IU$$$?5-;v$,(B ham $B$N5-;v$N%5%s%W%k$H$7(B +$B$F(B SpamOracle $B$KAw$i$l$^$9!#$3$N(B ham $B%W%m%;%C%5!<(B +$B$O(B @emph{spam} $B$+(B @emph{$BL$J,N`(B} $B%0%k!<%W$K$O8z2L$r5Z$\$5$J$$$3$H$KCm0U$7(B +$B$F2<$5$$!#(B + +@emph{$B7Y9p(B} + +$BGQ$l$?(B @code{gnus-group-ham-exit-processor-spamoracle} $B$NBe$o$j$K!"(B +@code{'(ham spam-use-spamoracle)} $B$r;H$&$3$H$r?d>)$7$^$9!#$9$Y$FF1Ey$KF0(B +$B:n$9$k$3$H$OJ]>Z$5$l$^$9!#(B +@end defvar + +@emph{$BNc(B:} $B$3$l$i$O(B ham $B%0%k!<%W$H$7$FJ,N`$5$l$?!"$D$^$j(B ham $B$N5-;v$7$+(B +$B$J$$%0%k!<%W$N%0%k!<%W%Q%i%a!<%?$G$9!#(B + +@example + ((spam-contents gnus-group-spam-classification-ham) + (spam-process ((ham spam-use-spamoracle) + (spam spam-use-spamoracle)))) +@end example + +$B$3$N%0%k!<%W$G$O(B @code{spam-use-spamoracle} $B$,(B ham $B$H(B spam $BN>J}$N=hM}$r(B +$B9T$J$$$^$9!#$3$N%0%k!<%W$K(B spam $B5-;v$,$"$C$F(B (SpamOracle $B$,==J,$J%5%s%W(B +$B%k$r?)$Y$5$;$F$b$i$C$F$$$J$1$l$P!"$=$&$J$j$^$9$M(B)$B!"$+$D%f!<%6$,$$$/$D$+(B +$B$N5-;v$K(B spam $B$N0u$rIU$1$?$J$i$P!"$=$l$i$N5-;v$O(B SpamOracle $B$K$h$C$F=hM}(B +$B$5$l$^$9!#$=$N%W%m%;%C%5!<$O!"?7$7$$(B spam $B$N%5%s%W%k$H$7$F(B SpamOracle $B$K(B +$B5-;v$rAw$j$^$9!#(B + +@node Extending the Spam ELisp package +@subsubsection Spam ELisp $B%Q%C%1!<%8$N3HD%(B @cindex spam filtering @cindex spam elisp package, extending @cindex extending the spam elisp package @@ -22108,17 +22808,40 @@ Spam $B$H(B ham $B$N%W%m%;%C%5!<$H(B @code{spam-split} $B$N$?$a(B @end lisp @code{spam-list-of-checks} $B$K(B + +@example + (spam-use-blackbox . spam-check-blackbox) +@end example + +$B$rDI2C!#(B@code{spam-list-of-processors} $B$K(B + @example - (spam-use-blackbox . spam-check-blackbox) + (gnus-group-ham-exit-processor-blackbox ham spam-use-blackbox) + (gnus-group-spam-exit-processor-blackbox spam spam-use-blackbox) @end example + +$B$rDI2C!#(B@code{spam-registration-functions} $B$K(B + +@example + (spam-use-blackbox spam-blackbox-register-routine + nil + spam-blackbox-unregister-routine + nil) +@end example + $B$rDI2C!#(B +$B$NEPO?(B/$B:o=|%k!<%A%s$r=q$$$F2<$5$$!#(B + @item $B4X?t(B @code{spam-check-blackbox} $B4X?t$r=q$$$F2<$5$$!#$=$l(B -$B$O(B @samp{nil} $B$+(B @code{spam-split-group} $B$rJV$5$J$1$l$P$J$j$^$;$s!#$"$J(B -$B$?$K$G$-$k$3$H$NNc$O!"4{B8$N(B @code{spam-check-*} $B4X?t$r;2>H$7$F$/$@$5$$!#(B +$B$OB>$N=,47$KJo$C$F(B @samp{nil} $B$+(B @code{spam-split-group} $B$rJV$5$J$1$l$P(B +$B$J$j$^$;$s!#$"$J$?$K$G$-$k$3$H$NNc$O!"4{B8$N(B @code{spam-check-*} $B4X?t$r(B +$B;2>H$7$F$/$@$5$$!#$^$?!"$"$J$?$,$=$&$G$J$$M}M3$r40A4$KM}2r$7$F$$$J$$$J$i(B +$B$P!"%F%s%W%l!<%H$Ksv$jIU$$$F2<$5$$!#(B $B%V%i%C%/%\%C%/%9$,!"$=$l$,F0:n$9$k$?$a$K%a%C%;!<%8A4BN$rI,MW$H$9$kE}7WE*(B $B%a!<%kJ,@O4o$G$"$k$N$J$i$P!"(B @@ -22137,48 +22860,42 @@ Spam $B$^$?$O(B ham $B$N%W%m%;%C%5!<$rMQ0U$9$kI,MW$O$"$j$^$;$s!#(B Blackbox $B$,(B spam $B$^$?$O(B ham $B$N=hM}$r%5%]!<%H$9$k>l9g$@$1!"$=$l$i$rMQ0U$7(B $B$F2<$5$$!#(B +$B$5$i$K(B ham $B$H(B spam $B$N%W%m%;%C%5!<$OC10l$NJQ?t$G$O$J$/$5$l$D$D$"$j!"Be$o(B +$B$j$K(B @code{'(spam spam-use-blackbox)} $B$^$?(B +$B$O(B @code{'(ham spam-use-blackbox)} $B$N7A<0$,?d>)$5$l$^$9!#:#$N$H$3(B +$B$m(B spam/ham $B%W%m%;%C%5!l9g!"<-=q$r:n$k$H$-$K==J,$KCm0U$7$J$1$l$P$J$j(B @@ -22347,7 +23064,7 @@ Spam $BMQ$N%0%k!<%W$G$9!#%G%#%U%)%k%H$O(B @samp{mail.spam} $B$G$9!#(B (setq nnmail-split-fancy `(| (: spam-stat-split-fancy) ("Subject" "\\bspam-stat\\b" "mail.emacs") - "mail.misc")) + "mail.misc")) @end lisp $B$3$l$rEAE}E*$J_I2a$HAH$_9g$o$;$k$3$H$b$G$-$^$9!#$3$3$G$O2f!9$O$9$Y$F(B @@ -22359,9 +23076,9 @@ Spam $BMQ$N%0%k!<%W$G$9!#%G%#%U%)%k%H$O(B @samp{mail.spam} $B$G$9!#(B @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 @node Low-level interface to the spam-stat dictionary @@ -22453,6 +23170,37 @@ Reduce table size: (spam-stat-reduce-size) Save table: (spam-stat-save) @end example +@node Other modes +@section $BB>$N%b!<%I$H$NAj8_:nMQ(B + +@subsection Dired +@cindex dired + +@code{gnus-dired-minor-mode} $B$O(B dired $B%P%C%U%!$G;H$($k$$$/$D$+$NJXMx$J5!(B +$BG=$rDs6!$7$^$9!#$3$l$O$C$F%U%!%$%k$r3+$-$^(B +$B$9(B (@code{gnus-dired-find-file-mailcap})$B!#@\F,<-$rIU$1$k$H!"%U%!%$%k$r?7(B +$B$7$$%P%C%U%!$G3+$-$^$9!#(B + +@item C-c C-m C-p +@findex gnus-dired-print +mailcap $B9`L\$K=>$C$F%U%!%$%k$r0u:~$7$^$9(B (@code{gnus-dired-print})$B!#0u:~(B +$B%3%^%s%I$,L5$$>l9g$O(B PostScript $B2hA|$K0u:~$7$^$9!#(B +@end table + @node Various Various @section $B$$$m$$$m$N$$$m$$$m(B @cindex mode lines @@ -22636,10 +23384,10 @@ but at the common table.@* XEmacs $B$O%Q%C%1!<%8$N=/=8$H$7$FG[I[$5$l$F$$$^$9!#(Bgnus $B$N(B XEmacs $B%Q%C%1!<(B $B%8$,I,MW$H$9$k$b$N$O2?$G$"$l!"$"$J$?$O%$%s%9%H!<%k$9$Y$-$G$9!#:#$N$H$3$m(B -$BI,MW$J$N$O(B @samp{gnus}, @samp{w3}, @samp{mh-e}, @samp{mailcrypt}, -@samp{rmail}, @samp{eterm}, @samp{mail-lib}, @samp{xemacs-base}, -@samp{sh-script} $B$*$h$S(B @samp{fsf-compat} $B$G$9!#%b!<%k%9I|9f$N$?$a$K(B -$B$O(B @samp{misc-games} $B%Q%C%1!<%8$,I,MW$G$9!#(B +$BI,MW$J$N$O(B @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} $B$*$h$S(B @samp{sasl} $B$G$9!#(B @node History @section $BNr;K(B @@ -22877,7 +23625,7 @@ Message Mode $B$O!#(B @@ -23175,8 +23923,8 @@ Richard Hoskins, Brad Howes, Miguel de Icaza, Fran,Ag(Bois Felix Ingrand, -$B;T@n(B $BC#:H(B, -$B@P@n(B $B0lO:(B, +$B;T@n(B $BC#(B +$B:H(B, $B@P@n(B $B0lO:(B, Lee Iverson, $B4d<<(B $B85E5(B, Rajappa Iyer, @@ -23221,8 +23969,8 @@ Fred Oberhauser, C. R. Oldham, Alexandre Oliva, Ken Olstad, -$BBg@>(B $B2m@2(B, -$B>.Ln(B $B=(5.(B, +$BBg@>(B $B2m(B +$B@2(B, $B>.Ln(B $B=(5.(B, Ettore Perazzoli, William Perry, Stephen Peters, @@ -23835,7 +24583,7 @@ Gnus 5.6 $B$N?7$7$$5!G=(B: @item Gnus $B$r%*%U%i%$%s%K%e!<%9%j!<%@!<$H$7$F;H$&?75!G=$,2C$($i$l$^$7$?!#2a>j(B $B$J$[$I$N?7$7$$L?Na$H%b!<%I$,DI2C$5$l$^$7$?!#40A4$JOC$KIU$$$F(B -$B$O(B @pxref{Gnus Unplugged} $B$r8+$F2<$5$$!#(B +$B$O(B @ref{Gnus Unplugged} $B$r8+$F2<$5$$!#(B @item @code{nndraft} $B%P%C%/%(%s%I$,La$C$F$-$^$7$?$,!"0MA3$H$O0c$&$h$&$KF0:n$9(B @@ -23867,12 +24615,12 @@ Gnus $B$r%*%U%i%$%s%K%e!<%9%j!<%@!<$H$7$F;H$&?75!G=$,2C$($i$l$^$7$?!#2a>j(B $B%$%i%$%H$r6X;_$9$k$h$&$K$J$j$^$7$?!#(B @item -@code{gnus-boring-article-headers} $B$K?7$7$$MWAG$,$"$j$^$9(B--- -@code{long-to}$B!#(B +@code{gnus-boring-article-headers} $B$K?7$7$$MWAG$,$"$j$^(B +$B$9(B---@code{long-to}$B!#(B @item -@kbd{M-i} $B%7%s%\%k@\F,0z?tL?Na$,$"$j$^$9!#>\:Y$O(B ``Symbolic -Prefixes'' $B$NItJ,$r8+$F2<$5$$!#(B +@kbd{M-i} $B%7%s%\%k@\F,0z?tL?Na$,$"$j$^$9!#>\:Y(B +$B$O(B @ref{Symbolic Prefixes} $B$r8+$F2<$5$$!#(B @item $B35N,%P%C%U%!$N(B @kbd{L} $B$H(B @kbd{I} $B$O(B @file{all.SCORE} $B%U%!%$%k$K%9%3%"K!(B @@ -24023,556 +24771,597 @@ Gnus posting styles $B$,:F$S2~Au$5$l$^$7$?!#8=:_$OHyL/$K0c$&5,B'$GF0:n$7$^(B Gnus $B$O(B @code{nnimap} $B$K$h$C$F(B @acronym{IMAP} $B%a!<%k$rFI$`$3$H$,$G$-$^$9!#(B @end itemize -@c TRANSLATEME @node Oort Gnus @subsubsection Oort Gnus @cindex Oort Gnus -New features in Gnus 5.10: +Gnus 5.10 $B$N?7$7$$5!G=(B: + +$BLuCm(B: Gnus $B$OFH<+$K(B @acronym{MIME} $B$N5!G=$r;}$C$F$$$k$N$KBP$7$F!"(B +T-gnus $B$O(B @acronym{SEMI} $B$d(B @acronym{FLIM} $B$KMj$C$F$$$^$9!#$7$?$,$C$F!"(B +$B0J2<$G@bL@$5$l$F$$$k$$$/$D$+$N5!G=$O(B T-gnus $B$G$O;H$($J$$$3$H$KCm0U$7$F2<(B +$B$5$$!#(B @itemize @bullet @item -The revised Gnus @acronym{FAQ} is included in the manual, -@xref{Frequently Asked Questions}. +@code{gnus-group-read-ephemeral-group} $B$r(B @kbd{G M} $B%-!<$GBPOCE*$K8F$V$3(B +$B$H$,$G$-$^$9!#(B @item -Upgrading from previous (stable) version if you have used Oort. +$B%I%i%U%H!&%0%k!<%W$G(B @kbd{e} $B%-!<$,(B @code{gnus-draft-edit-message} $B%3%^(B +$B%s%I$K3d$jEv$F$i$l$^$7$?!#(B@code{gnus-summary-edit-article} $B%3%^%s%I$K$O!"(B +$BBe$o$j$K(B @kbd{B w} $B%-!<$r;H$C$F2<$5$$!#(B -If you have tried Oort (the unstable Gnus branch leading to this -release) but went back to a stable version, be careful when upgrading to -this version. In particular, you will probably want to remove all -@file{.marks} (nnml) and @file{.mrk} (nnfolder) files, so that flags are -read from your @file{.newsrc.eld} instead of from the -@file{.marks}/@file{.mrk} file where this release store flags. See a -later entry for more information about marks. Note that downgrading -isn't save in general. +@item +$B2~Dj$5$l$?(B Gnus @acronym{FAQ} $B$,%^%K%e%"%k$K4^$^$l$F$$$^$9!#(B +@xref{Frequently Asked Questions}. ($BLuCm(B: T-gnus $B$N$?$a(B +$B$N(B @acronym{FAQ} $B$O1J$i$/2~Dj$5$l$F$$$^$;$s!#(B) @item -Article Buttons +Oort $B$r;H$C$?$3$H$,$"$k>l9g$N!"0JA0$N(B ($B0BDj$J(B) $BHG$+$i$N%0%l!<%I%"%C%W!#(B -More buttons for URLs, mail addresses, Message-IDs, Info links, man -pages and Emacs or Gnus related references. @xref{Article Buttons}. The -variables @code{gnus-button-@var{*}-level} can be used to control the -appearance of all article buttons. @xref{Article Button Levels}. +Oort ($B$3$N%j%j!<%9$K@hN)$D0BDj$G$O$J$$(B Gnus $B$N;^(B) $B$r;H$C$F$_$?$b$N$N!"0B(B +$BDjHG$KLa$7$F$7$^$C$?$J$i$P!"$3$NHG$K%0%l!<%I%"%C%W$9$k$H$-$KCm0U$7$F2<$5(B +$B$$!#FC$K!"$*$=$i$/$9$Y$F(B +$B$N(B @file{.marks} (nnml) $B$H(B @file{.mrk} (nnfolder) $B%U%!%$%k$r>C5n$9$kI,MW(B +$B$,$"$k$G$7$g$&!#$3$NHG(B ($B$N(B Gnus) $B$,%U%i%0$r3JG<$9(B +$B$k(B @file{.marks}/@file{.mrk} $B%U%!%$%k$G$O$J$/$F(B @file{.newsrc.eld} $B$+$i(B +$B%U%i%0$,FI$^$l$k$h$&$K$J$C$F$$$?$+$i$G$9!#8e=R$N9`L\$G!"0u(B (marks) $B$K4X(B +$B$9$k$h$jB?$/$N>pJs$rFI$s$G2<$5$$!#%0%l!<%I$r2<$2$F$b0lHL$K$O=u$1$K$J$i$J(B +$B$$$3$H$KCm0U$7$F2<$5$$!#(B @item -Dired integration +$B5-;v$N%\%?%s(B -@code{gnus-dired-minor-mode} installs key bindings in dired buffers to send -a file as an attachment (@kbd{C-c C-a}), open a file using the approriate -mailcap entry (@kbd{C-c C-l}), and print a file using the mailcap entry -(@kbd{C-c P}). It is enabled with -@lisp -(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) -@end lisp +URL$B!"%a!<%k%"%I%l%9!"(BMessage-ID$B!"(BInfo $B$X$N%j%s%/!"(Bman $B%Z!<%8$H(B Emacs $B$^(B +$B$?$O(B Gnus $B$K4XO"$7$?;29MJ88%$N$?$a$N!"$h$jB?$/$N%\%?%s!#(B@xref{Article +Buttons}. $B$9$Y$F$N5-;v$N%\%?%s$N8+1I$($r@)8f$9$k$?$a(B +$B$K(B @code{gnus-button-@var{*}-level} $BJQ?t$r;H$&$3$H$,$G$-$^$9!#(B +@xref{Article Button Levels}. @item -Gnus can display RSS newsfeeds as a newsgroup. @xref{RSS}. +Dired $B$NE}9g(B + +@code{gnus-dired-minor-mode} (@ref{Other modes} $B;2>H(B) $B$O!"(Bdired $B$N%P%C%U%!(B +$B$G%-!<@_Dj(B -- $BE:IU%U%!%$%k$NAw?.!"(Bmailcap $B$NE,@Z$J9`L\$r;H$C$F%U%!%$%k$r(B +$B3+$/!"$=$l$K(B mailcap $B$N9`L\$r;H$C$F%U%!%$%k$r0u:~$9$k(B -- $B$r9T$J$$$^$9!#(B @item -Single-part yenc encoded attachments can be decoded. +Gnus $B$O(B RSS $B$N%K%e!<%9G[Aw$r!"%K%e!<%9%0%k!<%W$H$7$FI=<($7$^$9!#(B +@xref{RSS}. + +@item +$BC10l$N(B yenc $B$G%(%s%3!<%I$5$l$?E:IU%Q!<%H$,%G%3!<%I$G$-$^$9!#(B @item Picons -The picons code has been reimplemented to work in GNU Emacs---some of -the previous options have been removed or renamed. +Picon $B$N%3!<%I$,!"(BGNU Emacs $B$GF0:n$5$;$k$?$a$K:F$5$l$F$$$^$9!#(B -Picons are small ``personal icons'' representing users, domain and -newsgroups, which can be displayed in the Article buffer. -@xref{Picons}. +Picon $B$O!"%f!<%6!O$H%3%s%H%m!<%k%a%C%;!<%8$NO$r%X%C%@!<(B (X-PGP-Sig) $B$r!"(B@kbd{W p} $B$GG'>Z$9$k$3$H$,$G$-$^$9!#(B @item -The Summary Buffer uses an arrow in the fringe to indicate the current -article. Use @code{(setq gnus-summary-display-arrow nil)} to disable it. +$B35N,%P%C%U%!$O(B fringe $B$NCf$NLp0u$G8=:_$N5-;v$r<($7$^$9!#$3$l$rL58z$K$9$k(B +$B$K$O(B @code{(setq gnus-summary-display-arrow nil)} $B$r;H$C$F2<$5$$!#(B @item -Warn about email replies to news +$B%K%e!<%9$K%a!<%k$GJV?.$7$h$&$H$7$?$i7Y9p(B -Do you often find yourself replying to news by email by mistake? Then -the new option @code{gnus-confirm-mail-reply-to-news} is just the thing for -you. +$B4V0c$C$F%K%e!<%9$K%a!<%k$GJV?.$7$h$&$H$7$F$7$^$&$3$H$,!"$7$g$C$A$e$&$"$j(B +$B$^$;$s$+(B? $B$=$s$J$"$J$?$K?7%*%W%7%g(B +$B%s(B @code{gnus-confirm-mail-reply-to-news}$B!#(B @item -If the new option @code{gnus-summary-display-while-building} is -non-@code{nil}, the summary buffer is shown and updated as it's being -built. +$B?7$7$$%*%W%7%g%s(B @code{gnus-summary-display-while-building} $B$r(B +$BHs(B-@code{nil} $B$K$9$k$H!"35N,%P%C%U%!$,:n$i$l$F$$$/MM;R$,I=<($5$l$^$9!#(B @item -The new @code{recent} mark @samp{.} indicates newly arrived messages (as -opposed to old but unread messages). +$B?7$7$$(B @code{recent} $B0u(B @samp{.} $B$G!"?75,$KFO$$$?%a%C%;!<%8$r(B ($BL$FI$@$1(B +$B$l$I$b8E$$5-;v$H$O6hJL$7$F(B) $BI=<($7$^$9!#(B @item -The new option @code{gnus-gcc-mark-as-read} automatically marks -Gcc articles as read. +$B?7$7$$%*%W%7%g%s(B @code{gnus-gcc-mark-as-read} $B$O!"(BGcc $B$N5-;v$K<+F0E*$K4{(B +$BFI$N0u$rIU$1$^$9!#(B @item -The nndoc back end now supports mailman digests and exim bounces. +nndoc $B%P%C%/%(%s%I$O!"(Bmailman $B$N$^$H$aAw$j$H(B exim $B$,CF$$$?%a%C%;!<%8$r%5(B +$B%]!<%H$9$k$h$&$K$J$j$^$7$?!#(B @item -Gnus supports RFC 2369 mailing list headers, and adds a number of -related commands in mailing list groups. @xref{Mailing List}. +Gnus $B$O(B RFC 2369 $B$N%a!<%j%s%0%j%9%H$N%X%C%@!<$r%5%]!<%H$7$^$9!#$^$?!"%a!<(B +$B%j%s%0%j%9%H$N%0%k!<%WMQ$K?t!9$N%3%^%s%I$rMQ0U$7$^$7$?!#(B@xref{Mailing +List}. @item -The Date header can be displayed in a format that can be read aloud -in English. @xref{Article Date}. +$BF|IU%X%C%@!<$r!"1Q8l$GH/2;$G$-$k7A<0$GI=<($9$k$3$H$,$G$-$^$9!#(B +@xref{Article Date}. @item -The envelope sender address can be customized when using Sendmail. -@xref{Mail Variables, Mail Variables,, message, Message Manual}. +Sendmail $B$r;H$&$H$-$N%(%s%Y%m!<%WAw?.$5$l$^$7$?!#(BXEmacs $B$H(B GNU Emacs $B$r<+F0G'(B +$B<1$7!"(B@file{gnus-load.el} $B$r@8@.$7!"%3%s%Q%$%kCf$H(B info $B%U%!%$%k$N@8@.Cf(B +$B$K%(%i!<$,5/$-$?$i9=C[=hM}$N:G8e$KJs9p$7$^$9!#(B@code{makeinfo} $B$,MxMQ2DG=(B +$B$G$"$l$P$=$l$r;H$$!"$5$b$J$1$l$P(B @file{infohack.el} $B$KMj$j$^$9!#:#(B +$B$d(B @file{make.bat} $B$O(B Gnus $B$rF0:n$5$;$k$?$a$KI,MW$J$9$Y$F$N%U%!%$%k$r%$(B +$B%s%9%H!<%k$9$k$O$:$G!"BgBN$K$*$$$F(B Unix $B%7%9%F%`$K$*$1(B +$B$k(B @code{configure; make; make install} $B%5%$%/%k$N40A4$JCV$-49$($K$J$j$^(B +$B$7$?!#(B -The new @file{make.bat} makes @file{make-x.bat} superfluous, so it has -been removed. +$B?7$7$$(B @file{make.bat} $B$O(B @file{make-x.bat} $B$rITMW$K$7$?$N$G!"$=$l$O:o=|(B +$B$5$l$^$7$?!#(B @item -Support for non-@acronym{ASCII} domain names +$BHs(B-@acronym{ASCII} $B%I%a%$%sL>$N%5%]!<%H(B -Message supports non-@acronym{ASCII} domain names in From:, To: and -Cc: and will query you whether to perform encoding when you try to -send a message. The variable @code{message-use-idna} controls this. -Gnus will also decode non-@acronym{ASCII} domain names in From:, To: -and Cc: when you view a message. The variable @code{gnus-use-idna} -controls this. +Message $B$O(B From:, To: $B$*$h$S(B Cc: $B$K$"$kHs(B-@acronym{ASCII} $B%I%a%$%sL>$r%5(B +$B%]!<%H$7!"%a%C%;!<%8$NAw?.$r;n$_$k$H$-$K%(%s%3!<%I$9$k$+$I$&$+$r?R$M$^$9!#(B +@code{message-use-idna} $BJQ?t$G$3$l$r@)8f$7$^$9!#(BGnus $B$b$^$?!"%a%C%;!<%8(B +$B$r8+$k$H$-$K(B From:, To: $B$*$h$S(B Cc: $B$K$"$kHs(B-@acronym{ASCII} $B%I%a%$%sL>$r(B +$B%G%3!<%I$7$^$9!#$3$l$r@)8f$9$k$N$O(B @code{gnus-use-idna} $BJQ?t$G$9!#(B @item -Better handling of Microsoft citation styles +$B%^%$%/%m%=%U%H0zMQMM<0$N$h$jNI$$/$7$@$1$"$k?75,$JFbMF$KB3$$$F(B +$B$$$k$?$/$5$s$N5-;v$rFI$`>l9g$K!"$3$l$OFC$KLr$KN)$A$^$9!#(B @item -The format spec @code{%C} for positioning point has changed to @code{%*}. +$B%]%$%s%H$N0LCV7h$a$N$?$a$N%U%)!<%^%C%H$N;EMM(B (format spec) $B$G$"(B +$B$k(B @code{%C} $B$O!"(B@code{%*} $B$KJQ99$5$l$^$7$?!#(B @item -The new variable @code{gnus-parameters} can be used to set group parameters. +$B?7$7$$JQ?t(B @code{gnus-parameters} $B$,!"%0%k!<%W%Q%i%a!<%?$r@_Dj$9$k$?$a$K(B +$B;H$&$3$H$,$G$-$^$9!#(B -Earlier this was done only via @kbd{G p} (or @kbd{G c}), which stored -the parameters in @file{~/.newsrc.eld}, but via this variable you can -enjoy the powers of customize, and simplified backups since you set the -variable in @file{~/.emacs} instead of @file{~/.newsrc.eld}. The -variable maps regular expressions matching group names to group -parameters, a'la: +$B$3$l$O=i4|$K$O!"%Q%i%a!<%?$r(B @file{~/.newsrc.eld} $B$K3JG<$9$k(B @kbd{G p} +($B$^$?$O(B @kbd{G c}) $B$G$7$+9T$J$&$3$H$,$G$-$^$;$s$G$7$?$,!"$3$NJQ?t$K$h$C(B +$B$F%+%9%?%^%$%:$N0RNO$r4.G=$9$k$3$H$,$G$-$^$9!#$^$?!"$=$NJQ?t(B +$B$O(B @file{~/.newsrc.eld} $B$G$O$J$/$F(B @file{~/.emacs} $B$G@_Dj$9$k$N$G!"%P%C(B +$B%/%"%C%W$,4JC1$K$J$j$^$9!#$=$NJQ?t$O!"%0%k!<%WL>$K9gCW$9$k@55,I=8=$r!"0J(B +$B2<$N$h$&$JN.57$G%0%k!<%W%Q%i%a!<%?$K3d$jEv$F$^$9(B: @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 -Smileys (@samp{:-)}, @samp{;-)} etc) are now iconized for Emacs too. +$B%9%^%$%j!<(B (@samp{:-)}, @samp{;-)} $B$J$I(B) $B$,(B Emacs $B$G$b%"%$%3%s2=$5$l$k$h(B +$B$&$K$J$j$^$7$?!#(B -Put @code{(setq gnus-treat-display-smileys nil)} in @file{~/.emacs} to -disable it. +$B$3$l$rF/$+$J$$$h$&$K$9$k$K$O!"(B@code{(setq gnus-treat-display-smileys +nil)} $B$r(B @file{~/.emacs} $B$KCV$$$F2<$5$$!#(B @item -Gnus no longer generate the Sender: header automatically. +Gnus $B$O:#$G$O(B Sender: $B%X%C%@!<$r<+F0$G$O@8@.$7$^$;$s!#(B -Earlier it was generated iff the user configurable email address was -different from the Gnus guessed default user address. As the guessing -algorithm is rarely correct these days, and (more controversally) the -only use of the Sender: header was to check if you are entitled to -cancel/supersede news (which is now solved by Cancel Locks instead, -see another entry), generation of the header has been disabled by -default. See the variables @code{message-required-headers}, -@code{message-required-news-headers}, and -@code{message-required-mail-headers}. +$B=i4|$N$3$m!"$=$l$O%f!<%6!<$,@_Dj$G$-$k(B email $B%"%I%l%9$,!"(BGnus $B$,A[Dj$7$?(B +$B%f!<%6!<$N%G%#%U%)%k%H$N%"%I%l%9$H0c$C$F$$$?>l9g$K@8@.$5$l$^$7$?!#:#F|$G(B +$B$O$=$NA[Dj%"%k%4%j%:%`$,@5$7$$$3$H$O$^$l$G!"(BSender: $B%X%C%@!<$NM#0l$N(B ($B5D(B +$BO@$NE*$K$J$k(B) $BMQES$O!"%K%e!<%9$r(B cancel/supersede $B$9$k;q3J$,$"$k$+$I$&$+(B +$B$r8!::$9$k$3$H(B ($B$3$l$OBe$o$j$K!"B>$N9`$G=R$Y$i$l$k(B Cancel Locks $B$K$h$C$F(B +$B2r7h$5$l$?(B) $B$J$N$G!"$=$N%X%C%@!<$N@8@.$O%G%#%U%)%k%H$GM^@)$5$l$F$$$^$9!#(B +$BJQ?t(B @code{message-required-headers}$B!"(B +@code{message-required-news-headers} $B$*$h(B +$B$S(B @code{message-required-mail-headers} $B$r;2>H$7$F2<$5$$!#(B @item -Features from third party @file{message-utils.el} added to @file{message.el}. +$B%5!<%I%Q!<%F%#!<$K$h$k(B @file{message-utils.el} $B$N5!G=(B +$B$,(B @file{message.el} $B$K2C$($i$l$^$7$?!#(B -Message now asks if you wish to remove @samp{(was: )} from -subject lines (see @code{message-subject-trailing-was-query}). @kbd{C-c -M-m} and @kbd{C-c M-f} inserts markers indicating included text. -@kbd{C-c C-f a} adds a X-No-Archive: header. @kbd{C-c C-f x} inserts -appropriate headers and a note in the body for cross-postings and -followups (see the variables @code{message-cross-post-@var{*}}). +Message $B$OI=Bj(B (subject) $B$N9T$+$i(B @samp{(was: )} $B$r:o=|$9$k(B +$B$+$I$&$+$r?R$M$k$h$&$K$J$j$^$7(B +$B$?(B (@code{message-subject-trailing-was-query} $B;2>H(B)$B!#(B +@kbd{C-c M-m} $B$H(B @kbd{C-c M-f} $B$OA^F~$5$l$?%F%-%9%H$r<($90u$rA^F~$7$^$9!#(B +@kbd{C-c C-f a} $B$O(B X-No-Archive: $B%X%C%@!<$rIU$12C$($^$9!#(B@kbd{C-c C-f +x} $B$O!"E,@Z$J%X%C%@!<$H!"%/%m%9%]%9%H$H%U%)%m!<@h$K$D$$$F$NCm0U=q$-$rK\(B +$BJ8$KA^F~$7$^$9(B (@code{message-cross-post-@var{*}} $BJQ?t72$r8+$F2<$5$$(B)$B!#(B @item -References and X-Draft-Headers are no longer generated when you start -composing messages and @code{message-generate-headers-first} is -@code{nil}. +$B:#$d(B @code{message-generate-headers-first} $B$,(B @code{nil} $B$@$C$?$i!"%a%C(B +$B%;!<%8$N:n@.$r;O$a$k$H$-$K(B References $B$H(B X-Draft-Headers $B$O@8@.$5$l$^$;(B +$B$s!#(B @item -Improved anti-spam features. +$B2~NI$5$l$?(B spam $BBP935!G=!#(B -Gnus is now able to take out spam from your mail and news streams -using a wide variety of programs and filter rules. Among the supported -methods are RBL blocklists, bogofilter and white/blacklists. Hooks -for easy use of external packages such as SpamAssassin and Hashcash -are also new. @xref{Thwarting Email Spam}. +Gnus $B$OHs>o$KJQ2=$KIY$s$@%W%m%0%i%`$H_I2a$N5,B'$r;H$C$F!"%a!<%k$d%K%e!<(B +$B%9$NK[N.$+$i(B spam $B$rH4$-(B +$B8e$K8F$P$l$k(B) $B$+$i(B @code{nnimap-fixup-unread-after-getting-new-news} $B$r(B +$B8F$V$3$H$K$h$C$F@.$7?k$2$i$l$^$9!#$3$l$i$NJQ?t$r%G%#%U%)%k%H$+$iJQ$($F$$(B +$B$k>l9g$O!":F$S(B @code{nnimap-fixup-unread-after-getting-new-news} $B$rDI2C(B +$B$9$kI,MW$,$"$k$+$b$7$l$^$;$s!#8+@Q$j$KK~B-$7$F$$$F!"?7$7$$%a!<%k$r.8BEY$N(B) $B;~4V$r@aLs$7$?$$$N$G$"$l$P!"$=$N4X?t$r30$7(B +$B$F2<$5$$!#(B @item -Group Carbon Copy (GCC) quoting +$B%0%k!<%W%+!<%\%s%3%T!<(B (GCC) $B$r0zMQId$G0O$`(B -To support groups that contains SPC and other weird characters, groups -are quoted before they are placed in the Gcc: header. This means -variables such as @code{gnus-message-archive-group} should no longer -contain quote characters to make groups containing SPC work. Also, if -you are using the string @samp{nnml:foo, nnml:bar} (indicating Gcc -into two groups) you must change it to return the list -@code{("nnml:foo" "nnml:bar")}, otherwise the Gcc: line will be quoted -incorrectly. Note that returning the string @samp{nnml:foo, nnml:bar} -was incorrect earlier, it just didn't generate any problems since it -was inserted directly. +$B6uGr$dB>$NJQ$JJ8;z$r4^$`%0%k!<%W$r07$($k$h$&$K$9$k$?$a$K!"%0%k!<%W(B +$B$O(B Gcc: header $B$KCV$+$l$kA0$K0zMQId$G0O$^$l$^$9!#$3$l$O!"6uGr$r4^$`%0%k!<(B +$B%W$,;H$($k$h$&$K$9$k$?$a$K!"$b$O$d(B @code{gnus-message-archive-group} $B$N(B +$B$h$&$JJQ?t$K0zMQJ8;z$r4^$a$k$Y$-$G$O$J$$$3$H$r0UL#$7$^$9!#$5$i$K!"J8;z(B +$BNs(B @samp{nnml:foo, nnml:bar} ($BFs$D$N%0%k!<%W$K(B Gcc $B$r3JG<$9$k$3$H$r<((B +$B$9(B) $B$r;H$C$F$$$k$J$i$P!"%j%9%H(B @code{("nnml:foo" "nnml:bar")} $B$rJV$9$h$&(B +$B$KJQ99$7$J$1$l$P$J$j$^$;$s!#$5$b$J$$$H!"(BGcc: $B9T$O4V0c$C$?0O$^$lJ}$r$5$l(B +$B$F$7$^$&$G$7$g$&!#=i4|$N$3$m$KJ8;zNs(B @samp{nnml:foo, nnml:bar} $B$rJV$9$h(B +$B$&$K$7$?$3$H$,4V0c$$$@$C$?$3$H$KCeL\$7$F2<$5$$!#$=$l$OD>@\A^F~$5$l$?$N$G!"(B +$B$^$C$?$/LdBj$r@8$8$^$;$s$G$7$?!#(B @item -@file{~/News/overview/} not used. +@file{~/News/overview/} $B$OITMW!#(B -As a result of the following change, the @file{~/News/overview/} -directory is not used any more. You can safely delete the entire -hierarchy. +$B0J2<$NJQ99$N7k2L!":#8e$O(B @file{~/News/overview/} $B%G%#%l%/%H%j$OMW$j$^$;(B +$B$s!#$9$Y$F$N3,AX$r0BA4$K:o=|$9$k$3$H$,$G$-$^$9!#(B @item @code{gnus-agent} -The Gnus Agent has seen a major updated and is now enabled by default, -and all nntp and nnimap servers from @code{gnus-select-method} and -@code{gnus-secondary-select-method} are agentized by default. Earlier -only the server in @code{gnus-select-method} was agentized by the -default, and the agent was disabled by default. When the agent is -enabled, headers are now also retrieved from the Agent cache instead -of the back ends when possible. Earlier this only happened in the -unplugged state. You can enroll or remove servers with @kbd{J a} and -@kbd{J r} in the server buffer. Gnus will not download articles into -the Agent cache, unless you instruct it to do so, though, by using -@kbd{J u} or @kbd{J s} from the Group buffer. You revert to the old -behaviour of having the Agent disabled with @code{(setq gnus-agent -nil)}. Note that putting @code{(gnus-agentize)} in @file{~/.gnus.el} -is not needed any more. +Gnus $B%(!<%8%'%s%H$OBg5,LO$J99?7$r7P$F!":#$d%G%#%U%)%k%H$G3h@-2=$5$l$^$9!#(B +$B$=$7(B +$B$F(B @code{gnus-select-method} $B$H(B @code{gnus-secondary-select-method} $B$G;X(B +$BDj$5$l$k$9$Y$F$N(B nntp $B$H(B nnimap $B$N%5!<%P!<$,!"%G%#%U%)%k%H$G%(!<%8%'%s%H(B +$B2=$5$l$^$9!#=i4|$K$*$$$F$O(B @code{gnus-select-method} $B$N%5!<%P!<$@$1$,%G%#(B +$B%U%)%k%H$G%(!<%8%'%s%H2=$5$l!"%(!<%8%'%s%H$O%G%#%U%)%k%H$GIT3h@-2=$5$l$F(B +$B$$$^$7$?!#%(!<%8%'%s%H$,3h@-2=$5$l$k$H!"2DG=$J$i$P%P%C%/%(%s%I$KBe$o$C$F(B +$B%(!<%8%'%s%H$N%-%c%C%7%e$+$i%X%C%@!<$,uBV$G$N$_9T$J$o$l$F$$$^$7$?!#%5!<%P!<%P%C%U%!(B +$B$G(B @kbd{J a} $B$H(B @kbd{J r} $B$r;H$&$3$H$K$h$C$F!"%5!<%P!<$NEPO?$H:o=|$r9T$J(B +$B$&$3$H$,$G$-$^$9!#%0%k!<%W%P%C%U%!$+$i(B @kbd{J u} $B$+(B @kbd{J s} $B$r;H$C$FL?(B +$BNa$7$J$$8B$j!"(BGnus $B$O5-;v$r%(!<%8%'%s%H$N%-%c%C%7%e$K%@%&%s%m!<%I$7$^$;(B +$B$s!#(B@code{(setq gnus-agent nil)} $B$G$b$C$F!"%(!<%8%'%s%H$,IT3h@-2=$5$l$F(B +$B$$$?@N$N?6$kIq$$$KLa$9$3$H$,$G$-$^$9!#:#8e(B +$B$O(B @file{~/.gnus.el} $B$K(B @code{(gnus-agentize)} $B$rCV$$$F$*$/I,MW$,L5$$$3(B +$B$H$KCm0U$7$F2<$5$$!#(B @item @code{gnus-summary-line-format} -The default value changed to @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) -%s\n}. Moreover @code{gnus-extra-headers}, -@code{nnmail-extra-headers} and @code{gnus-ignored-from-addresses} -changed their default so that the users name will be replaced by the -recipient's name or the group name posting to for @acronym{NNTP} -groups. +$B%G%#%U%)%k%HCM$,(B @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n} $B$KJQ$o$j$^$7(B +$B$?!#$5$i$K!"A0$+(B @acronym{NNTP} $B%0%k!<%W$KEj9F$7$?%0%k!<%WL>$G(B +$B%f!<%6L>$rCV$-49$($k$?$a$K!"(B@code{gnus-extra-headers}$B!"(B +@code{nnmail-extra-headers} $B$*$h$S(B @code{gnus-ignored-from-addresses} $B$N(B +$B%G%U%)%k%HCM$,JQ$o$j$^$7$?!#(B @item @file{deuglify.el} (@code{gnus-article-outlook-deuglify-article}) -A new file from Raymond Scholz @email{rscholz@@zonix.de} for deuglifying -broken Outlook (Express) articles. +$B$$$+$l$?(B Outlook (Express) $B$N5-;v$r=9$/$J$/$9$k$?$a$N!"(BRaymond Scholz +@email{rscholz@@zonix.de} $B$K$h$C$F?7@_$5$l$?%U%!%$%k$G$9!#(B @item @code{(require 'gnus-load)} -If you use a stand-alone Gnus distribution, you'd better add -@code{(require 'gnus-load)} into your @file{~/.emacs} after adding the Gnus -lisp directory into load-path. +$BC1FH$GG[I[$5$l$F$$$k(B Gnus $B$r;H$&>l9g$K$O!"(B +@code{load-path} $B$K(B Gnus $B$N(B lisp $B%G%#%l%/%H%j$rDI2C$7$F$+$i!"(B +@file{~/.emacs} $B$K(B @code{(require 'gnus-load)} $B$r2C$($k$N$,NI$$$G$9!#(B -File @file{gnus-load.el} contains autoload commands, functions and variables, -some of which may not be included in distributions of Emacsen. +$B%U%!%$%k(B @file{gnus-load.el} $B$O!"$=$N$&$A$N$$$/$D$+$O(B Emacsen $B$NG[I[$KF~$C(B +$B$F$$$J$$$+$b$7$l$J$$<+F0FI$_9~$_(B (autoload) $B%3%^%s%I!"4X?t$*$h$SJQ?t$r4^(B +$B$s$G$$$^$9!#(B @item @code{gnus-slave-unplugged} -A new command which starts Gnus offline in slave mode. +$B%*%U%i%$%s$N(B Gnus $B$r%9%l!<%V%b!<%I$G5/F0$9$k?7$7$$%3%^%s%I$G$9!#(B @item @code{message-insinuate-rmail} -Adding @code{(message-insinuate-rmail)} and @code{(setq -mail-user-agent 'gnus-user-agent)} in @file{.emacs} convinces Rmail to -compose, reply and forward messages in message-mode, where you can -enjoy the power of @acronym{MML}. +@code{(message-insinuate-rmail)} $B$H(B @code{(setq mail-user-agent +'gnus-user-agent)} $B$r(B @file{.emacs} $B$K2C$($k$3$H$G!"(B +@code{message-mode} $B$G%a%C%;!<%8$N:n@.!"JV?.$*$h$SE>Aw$r9T$J$&$h$&(B +$B$K(B Rmail $B$r@bF@$9$k$3$H$,$G$-$^$9!#$=$3$G$O(B @acronym{MML} $B$N0RNO$r4.G=$G(B +$B$-$^$9!#(B @item @code{message-minibuffer-local-map} -The line below enables BBDB in resending a message: +$B2<$N9T$G!"%a%C%;!<%8$r:FAw$9$k$H$-$K(B BBDB $B$,;H$($^$9(B: @lisp (define-key message-minibuffer-local-map [(tab)] 'bbdb-complete-name) @end lisp @item -Externalizing and deleting of attachments. +$BE:IU%U%!%$%k(B (attachments) $B$N@Z$jN%$7(B (externalizing) $B$H>C5n!#(B -If @code{gnus-gcc-externalize-attachments} or -@code{message-fcc-externalize-attachments} is non-@code{nil}, attach -local files as external parts. +@code{gnus-gcc-externalize-attachments} $B$^$?(B +$B$O(B @code{message-fcc-externalize-attachments} $B$,Hs(B-@code{nil} $B$K$J$C$F$$(B +$B$k$H!"%m!<%+%k%U%!%$%k$r30It%Q!<%H$H$7$FE:IU$7$^$9!#(B -The command @code{gnus-mime-save-part-and-strip} (bound to @kbd{C-o} -on @acronym{MIME} buttons) saves a part and replaces the part with an -external one. @code{gnus-mime-delete-part} (bound to @kbd{d} on -@acronym{MIME} buttons) removes a part. It works only on back ends -that support editing. +@code{gnus-mime-save-part-and-strip} $B%3%^%s%I(B (@acronym{MIME} $B%\%?%s>e(B +$B$G(B @kbd{C-o} $B$K3d$jEv$F$i$l$F$$$k(B) $B$O!"%Q!<%H$r%;!<%V$7$F$+$i30It$N$=$l(B +$B$HCV$-49$($^$9!#(B@code{gnus-mime-delete-part} (@acronym{MIME} $B%\%?%s>e(B +$B$G(B @kbd{d} $B$K3d$jEv$F$i$l$F$$$k(B) $B$O!"%Q!<%H$r:o=|$7$^$9!#$3$l$OJT=8$r%5(B +$B%]!<%H$7$F$$$k%P%C%/%(%s%I$G$@$1F0:n$7$^$9!#(B @item @code{gnus-default-charset} -The default value is determined from the -@code{current-language-environment} variable, instead of -@code{iso-8859-1}. Also the @samp{.*} item in -@code{gnus-group-charset-alist} is removed. +$B%G%U%)%k%HCM$O(B @code{iso-8859-1} $B$KBe$o$C(B +$B$F(B @code{current-language-environment} $BJQ?t$K$h$C$F7hDj$5$l$kCM$K$J$j$^(B +$B$9!#$^$?!"(B@code{gnus-group-charset-alist} $B$K$"$C$?(B @samp{.*} $B$N9`L\$O:o(B +$B=|$5$l$^$7$?!#(B @item @code{gnus-posting-styles} -Add a new format of match like +$B$3$N$h$&$J9gCW$NMM<0$,2C$o$j$^$7$?!#(B @lisp ((header "to" "larsi.*org") (Organization "Somewhere, Inc.")) @end lisp -The old format like the lines below is obsolete, but still accepted. +$B2<5-$N$h$&$J8E$$MM<0$O;~BeCY$l$K$J$j$^$7$?$,!"$^$@l9g$K!"$b$7$+$9$k$H(B +$B$=$l$iFs$D$N%X%C%@!<$r2C$($kI,MW$,$"$j$^$9!#(B @item -Gnus reads the @acronym{NOV} and articles in the Agent if plugged. +Gnus $B$O:9$79~$^$l$F$$$k(B (@dfn{plugged}) $B$H$-$K!"%(!<%8%'%s%H$+(B +$B$i(B @acronym{NOV} $B$H5-;v$rFI$_9~$_$^$9!#(B -If one reads an article while plugged, and the article already exists -in the Agent, it won't get downloaded once more. @code{(setq -gnus-agent-cache nil)} reverts to the old behavior. +$B:9$79~$^$l$F$$$k$H$-$K5-;v$rFI$`>l9g$K!"$=$N5-;v$,$9$G$K%(!<%8%'%s%H$K$"(B +$B$k$J$i$P!"$b$&0lEY%@%&%s%m!<%I$9$k$3$H$O$"$j$^$;$s!#(B@code{(setq +gnus-agent-cache nil)} $B$O5l<0$NF0:n$KLa$7$^$9!#(B @item -Gnus supports the ``format=flowed'' (RFC 2646) parameter. On -composing messages, it is enabled by @code{use-hard-newlines}. -Decoding format=flowed was present but not documented in earlier -versions. +Gnus $B$O(B ``format=flowed'' (RFC 2646) $B%Q%i%a!<%?$r%5%]!<%H$7$^$9!#%a%C%;!<(B +$B%8$r:n@.$9$k$H$-$K!"$=$l$O(B @code{use-hard-newlines} $B$G3h@-2=$5$l$^$9!#(B +format=flowed $B$N%G%3!<%I$O0JA0$+$i$G$-$^$7$?$,!"=i4|$NHG$G$O@bL@$NJ8=q$,(B +$B$"$j$^$;$s$G$7$?!#(B @item -Gnus supports the generation of RFC 2298 Disposition Notification requests. +Gnus $B$O(B RFC 2298 $B$N3+Iu3NG'MW5a$N@8@.$r%5%]!<%H$7$^$9!#(B -This is invoked with the @kbd{C-c M-n} key binding from message mode. +$B$3$l$O%a%C%;!<%8%b!<%I$N(B @kbd{C-c M-n} $B%-!<$G5/F0$5$l$^$9!#(B @item -Gnus supports Maildir groups. +Gnus $B$O(B Maildir $B%0%k!<%W$r%5%]!<%H$7$^$9!#(B -Gnus includes a new back end @file{nnmaildir.el}. @xref{Maildir}. +Gnus $B$O?7%P%C%/%(%s%I$G$"$k(B @file{nnmaildir.el} $B$r4^$s$G$$$^$9!#(B +@xref{Maildir}. @item -Printing capabilities are enhanced. +$B0u:~$N@-G=$,8~>e$7$^$7$?!#(B -Gnus supports Muttprint natively with @kbd{O P} from the Summary and -Article buffers. Also, each individual @acronym{MIME} part can be -printed using @kbd{p} on the @acronym{MIME} button. +Gnus $B$O$=$l<+?H$,!"35N,$H5-;v%P%C%U%!$K$*$1$k(B @kbd{O P} $B$G(B Muttprint $B$r(B +$B%5%]!<%H$7$^$9!#$5$i$K(B @acronym{MIME} $B%\%?%s>e$G(B @kbd{p} $B$r;H$&$3$H$K$h$C(B +$B$F!"8D!9$N(B @acronym{MIME} $B%Q!<%H$N$=$l$>$l$r0u:~$9$k$3$H$,$G$-$^$9!#(B @item -Message supports the Importance: (RFC 2156) header. +Message $B$O(B Importance: $B%X%C%@!<(B (RFC 2156) $B$r%5%]!<%H$9$k$h$&$K$J$j$^$7(B +$B$?!#(B -In the message buffer, @kbd{C-c C-f C-i} or @kbd{C-c C-u} cycles through -the valid values. +$B%a%C%;!<%8%P%C%U%!$G(B @kbd{C-c C-f C-i} $B$+(B @kbd{C-c C-u} $B$r;H$&$H!"2DG=$J(B +$BCM$,=[4D$7$^$9!#(B @item -Gnus supports Cancel Locks in News. +Gnus $B$O%K%e!<%9$N(B Cancel Locks $B$r%5%]!<%H$7$^$9!#(B -This means a header @samp{Cancel-Lock} is inserted in news posting. It is -used to determine if you wrote a article or not (for cancelling and -superseding). Gnus generates a random password string the first time -you post a message, and saves it in your @file{~/.emacs} using the Custom -system. While the variable is called @code{canlock-password}, it is not -security sensitive data. Publishing your canlock string on the web -will not allow anyone to be able to anything she could not already do. -The behaviour can be changed by customizing @code{message-insert-canlock}. +$BEj9F$9$k%K%e!<%95-;v$K(B @samp{Cancel-Lock} $B%X%C%@!<$,A^F~$5$l$k$3$H$G$9!#(B +$B$3$l$O!"5-;v$r$"$J$?$,=q$$$?$N$+$I$&$+$r3N$+$a$k$?$a$K;H$$$^$9(B ($B%-%c%s%;(B +$B%k$HCV$-49$($N$H$-(B)$B!#:G=i$K5-;v$rEj9F$9$k$H$-$K!"(BGnus $B$O%i%s%@%`$J%Q%9%o!<(B +$B%IJ8;zNs$r@8@.$7!"%+%9%?%`$N5!9=$r;H$C$F(B @file{~/.emacs} $B$K%;!<%V$7$^$9!#(B +$B$=$NJQ?t$O(B @code{canlock-password} $B$H8F$P$l$^$9$,!"5!L)$r5$$K$9$k%G!<%?(B +$B$G$O$"$j$^$;$s!#%&%'%V>e$G(B canlock $B$r8x3+$7$F$b!"0JA0$+$iH`=w$,$G$-$J$+$C(B +$B$?2?$+$r!"C/$+$,$G$-$k$h$&$K$9$k$b$N$G$O$"$j$^$;$s!#(B +@code{message-insert-canlock} $B$r%+%9%?%^%$%:$9$k$3$H$K$h$C$F!"?6$kIq$$$r(B +$BJQ99$9$k$,$G$-$^$9!#(B @item -Gnus supports server-side mail filtering using Sieve. +Gnus $B$O(B Sieve $B$r;H$C$?%5!<%P!H$7$F2<$5$$!#(B @item -Extended format specs. +$B3HD%$5$l$?%U%)!<%^%C%H$N;EMM(B (format specs)$B!#(B -Format spec @samp{%&user-date;} is added into -@code{gnus-summary-line-format-alist}. Also, user defined extended -format specs are supported. The extended format specs look like -@samp{%u&foo;}, which invokes function -@code{gnus-user-format-function-@var{foo}}. Because @samp{&} is used as the -escape character, old user defined format @samp{%u&} is no longer supported. +$B%U%)!<%^%C%H$N;E(B +$BMM(B @samp{%&user-date;} $B$,(B @code{gnus-summary-line-format-alist} $B$KDI2C$5(B +$B$l$^$7$?!#$=$l$K!"%f!<%6Dj5A$K$h$k3HD%$5$l$?%U%)!<%^%C%H$N;EMM$b%5%]!<%H(B +$B$5$l$F$$$^$9!#3HD%$5$l$?%U%)!<%^%C%H$N;EMM$O(B @samp{%u&foo;} $B$N$h$&$J$b$N(B +$B$G!"4X?t(B @code{gnus-user-format-function-@var{foo}} $B$r5/F0$7$^$9!#(B +@samp{&} $B$,%(%9%1!<%WJ8;z$K;H$o$l$F$$$k$N$G!"8E$$%f!<%6Dj5A%U%)!<%^%C%H(B +$B$G$"$k(B @samp{%u&} $B$O:#$d%5%]!<%H$5$l$F$$$^$;$s!#(B @item -@kbd{/ *} (@code{gnus-summary-limit-include-cached}) is rewritten. +@kbd{/ *} (@code{gnus-summary-limit-include-cached}) $B$,=q$-D>$5$l$^$7$?!#(B -It was aliased to @kbd{Y c} -(@code{gnus-summary-insert-cached-articles}). The new function filters -out other articles. +$B$3$l$O(B @kbd{Y c} (@code{gnus-summary-insert-cached-articles}) $B$NJLL>$G$7(B +$B$?(B ($BLuCm(B: $B0JA0$O(B)$B!#?7$7$$4X?t$OB>$N5-;v$r_I2a$7$F=|5n$7$^$9!#(B -@item Some limiting commands accept a @kbd{C-u} prefix to negate the match. +@item +$B$$$/$D$+$N%3%^%s%I$O(B @kbd{C-u} $B@\F,<-$G9gCW$NH]Dj$r07$&$3$H$,$G$-$^$9!#(B -If @kbd{C-u} is used on subject, author or extra headers, i.e., @kbd{/ -s'}, @kbd{/ a}, and @kbd{/ x} -(@code{gnus-summary-limit-to-@{subject,author,extra@}}) respectively, the -result will be to display all articles that do not match the expression. +@kbd{C-u} $B$r(B subject$B!"(Bauthor $B$^$?$O(B extra $B%X%C%@!<$r$3$N=g$K;H$&(B -- $B$9$J(B +$B$o$A(B @kbd{/ s}$B!"(B@kbd{/ a} $B$*$h(B +$B$S(B @kbd{/ x} (@code{gnus-summary-limit-to-@{subject,author,extra@}}) +-- $B$H!"7k2L$H$7$F$=$NI=8=$K9gCW$7$J$$$9$Y$F$N5-;v$,I=<($5$l$^$9!#(B @item -Group names are treated as UTF-8 by default. +$B%0%k!<%WL>$O!"%G%#%U%)%k%H$G(B UTF-8 $B$G$"$k$b$N$H$7$FH$7$F2<$5$$!#(B @item -The nnml and nnfolder backends store marks for each groups. +nnml $B$H(B nnfolder $B%P%C%/%(%s%I$O!"%0%k!<%WKh$K0u(B (marks) $B$r3JG<$9$k$h$&$K(B +$B$J$j$^$7$?!#(B -This makes it possible to take backup of nnml/nnfolder servers/groups -separately of @file{~/.newsrc.eld}, while preserving marks. It also -makes it possible to share articles and marks between users (without -sharing the @file{~/.newsrc.eld} file) within e.g. a department. It -works by storing the marks stored in @file{~/.newsrc.eld} in a per-group -file @file{.marks} (for nnml) and @file{@var{groupname}.mrk} (for -nnfolder, named @var{groupname}). If the nnml/nnfolder is moved to -another machine, Gnus will automatically use the @file{.marks} or -@file{.mrk} file instead of the information in @file{~/.newsrc.eld}. -The new server variables @code{nnml-marks-is-evil} and -@code{nnfolder-marks-is-evil} can be used to disable this feature. +$B$3$l$O(B nnml/nnfolder $B%5!<%P!<(B/$B%0%k!<%W(B $B$r(B @file{~/.newsrc.eld} $B$H@Z$jN%(B +$B$7$F!"$7$+$70u$Ol$J$I$NAH?%Fb$G!"(B(@file{~/.newsrc.eld} $B%U%!%$%k$r6&M-$9$k(B +$B$3$HL5$7$K(B) $B%f!<%64V$G5-;v$H0u$r6&M-$9$k$3$H$r$b2DG=$K$7$^$9!#$3$l$O!"(B +@file{~/.newsrc.eld} $B$K3JG<$5$l$k0u$r!"%0%k!<%WKh$N(B @file{.marks} $B%U%!%$(B +$B%k(B (nnml $BMQ(B) $B$H(B @file{@var{groupname}.mrk} $B%U%!%$%k(B (@var{groupname} $B$N(B +$BL>A0$r;}$D(B nnfolder $BMQ(B) $B$K3JG<$9$k$3$H$K$h$C$FF0:n$7$^$9!#(B +nnml/nnfolder $B$rB>$N%^%7%s$K0z$C1[$7$F$b!"(B +Gnus $B$O(B @file{~/.newsrc.eld} $B$K$"$k>pJs$NBe$o$j$K!"<+F0E*(B +$B$K(B @file{.marks} $B$+(B @file{.mrk} $B%U%!%$%k$r;H$$$^$9!#?7$7$$%5!<%P!A0(B ``Misc'' $B$O(B ``Gnus'' $B$K2~L>$5(B +$B$l$^$7$?!#(B @item -The menu bar item (in Message mode) named ``@acronym{MML}'' has been -renamed to ``Attachments''. Note that this menu also contains security -related stuff, like signing and encryption (@pxref{Security, Security,, -message, Message Manual}). +Message mode $B$G(B ``@acronym{MML}'' $B$HL>IU$1$i$l$?%a%K%e!<9`L\$O!"(B +``Attachments'' $B$K2~L>$5$l$^$7$?!#$3$N%a%K%e!<$O!"=pL>$H0E9f(B +$B2=(B (@pxref{Security, Security,, message-ja, Message Manual}) $B$N$h$&$J!"(B +$BJ]0B$K4XO"$7$?$b$N$b4^$s$G$$$k$3$H$KCeL\$7$F2<$5$$!#(B @item -@code{gnus-group-charset-alist} and -@code{gnus-group-ignored-charsets-alist}. +@code{gnus-group-charset-alist} $B$H(B @code{gnus-group-ignored-charsets-alist}$B!#(B -The regexps in these variables are compared with full group names -instead of real group names in 5.8. Users who customize these -variables should change those regexps accordingly. For example: +$B$3$l$i$NJQ?t$K@_Dj$5$l$?@55,I=8=$O!"40A4$J(B (full) $B%0%k!<%WL>$HHf3S$5$l$^(B +$B$9!#(BGnus 5.8 $B$G$O$,Hf3S$NBP>]$G$7$?!#$7$?$,$C$F!"(B +$B$3$l$i$NJQ?t$r%+%9%?%^%$%:$7$F$$$k%f!<%6$O!"@55,I=8=$rJQ99$7$J$1$l$P$J$j(B +$B$^$;$s!#Nc$G$9(B: @lisp ("^han\\>" euc-kr) -> ("\\(^\\|:\\)han\\>" euc-kr) @end lisp @item -Gnus supports @acronym{PGP} (RFC 1991/2440), @acronym{PGP/MIME} (RFC -2015/3156) and @acronym{S/MIME} (RFC 2630-2633). +Gnus $B$O(B @acronym{PGP} (RFC 1991/2440)$B!"(B@acronym{PGP/MIME} (RFC +2015/3156) $B$*$h$S(B @acronym{S/MIME} (RFC 2630-2633) $B$r%5%]!<%H$7$^$9!#(B -It needs an external @acronym{S/MIME} and OpenPGP implementation, but no -additional Lisp libraries. This add several menu items to the -Attachments menu, and @kbd{C-c RET} key bindings, when composing -messages. This also obsoletes @code{gnus-article-hide-pgp-hook}. +$B$3$l$K$O(B @acronym{S/MIME} $B$H(B OpenPGP $B$,WFM(B +$B$,2sHr$5$l$^$7$?!#$3$N%3%^%s%I$b$^$?!"%a%C%;!<%8%b!<%I$G$OLr$KN)$D$N$G$9!#(B + +@item +@code{message-forward-show-mml} $B$N%G%#%U%)%k%H$,(B @code{best} $B$KJQ$o$j$^(B +$B$7$?!#(B + +$BCM(B @code{best} $B$N?6$kIq$$$O!"$=$l$,$U$5$o$7$$>l9g$O(B @acronym{MML} $B$rI=<((B +$B$9$k(B ($B$9$J$o$A(B @acronym{MIME} $B$KJQ49$9$k(B) $B$3$H$G$9!#JQ49$,%G%#%8%?%k=pL>(B +$B$rL58z$K$7$F$7$^$&$N$G!"=pL>$5$l$?!"$^$?$O0E9f2=$5$l$?%a%C%;!<%8$rE>Aw$9(B +$B$k$H$-$O(B @acronym{MML} $B$O;H$o$l$^$;$s!#(B @end itemize @iftex @@ -24688,27 +25477,27 @@ gnus $B$O%a!<%k$H%K%e!<%9$,$[$H$s$IF1$8$@$H$_$J$7$^$9!#K\Ev$K!#0c$$$Oo$K35N,%P%C%U%!$rCf?4:F@_Dj$r$9$k$3$H$r6X;_$9$k$?$a$K$3$l(B @subsection $B>/$7$N%G%#%9%/MFNL(B @cindex disk space -$B5/F0%U%!%$%k$OHf3SE*Bg$-$/$J$j$^$9$N$G!"6u$-MFNL$,>/$J$/$J$C$F$-$F$$$k$H(B -$B$-$O$=$NBg$-$5$r>/$7>.$5$/$7$?$$$H;W$&$G$7$g$&!#(B +$B5/F0%U%!%$%k$OHf3SE*Bg$-$/$J$k$N$G!"6u$-MFNL$,>/$J$/$J$C$F$-$F$$$k$H$-$O(B +$B$=$NBg$-$5$r>/$7>.$5$/$9$kI,MW$,$"$k$G$7$g$&!#(B @table @code @item gnus-save-newsrc-file @@ -24972,11 +25768,11 @@ Gnus $B$,>o$K35N,%P%C%U%!$rCf?4:F@_Dj$r$9$k$3$H$r6X;_$9$k$?$a$K$3$l(B $B$b$7CY$$5!3#$r;}$C$F$$$k$+!"$b$7$/$OC1$KK\Ev$KG&BQNO$,$J$$;~$O!"(Bgnus $B$N(B $B/$7$"$j$^$9!#(B -$B5/F0$rB.$/$9$k$?$a(B -$B$K(B @code{gnus-check-new-newsgroups} $B$H(B @code{gnus-check-bogus-newsgroups} $B$r(B @code{nil} $B$K(B -$B@_Dj$7$F2<$5$$!#35N,%P%C%U%!$KF~$k;v$HH4$1$k;v$rB.$/$9$k$?$a$K!"(B -@code{gnus-show-threads} $B$H(B @code{gnus-use-cross-reference} $B$H(B @code{gnus-nov-is-evil} $B$r(B @code{nil} $B$K(B -$B@_Dj$7$F2<$5$$!#(B +$B5/F0$rB.$/$9$k$?$a$K(B @code{gnus-check-new-newsgroups} $B$*$h(B +$B$S(B @code{gnus-check-bogus-newsgroups} $B$r(B @code{nil} $B$K@_Dj$7$F2<$5$$!#35(B +$BN,%P%C%U%!$KF~$k;v$HH4$1$k;v$rB.$/$9$k$?$a(B +$B$K(B @code{gnus-show-threads} $B$H(B @code{gnus-use-cross-reference}$B!"$=$l(B +$B$K(B @code{gnus-nov-is-evil} $B$r(B @code{nil} $B$K@_Dj$7$F2<$5$$!#(B @page @node Troubleshooting @@ -25000,11 +25796,10 @@ Gnus $B$OH"$+$i=P$7$F$9$0$K(B @emph{$BHs>o$K(B} $B$h$/F0:n$7$^$9(B---$B2? @item @kbd{M-x gnus-version} $B$r;n$7$F2<$5$$!#$b$7!"(B -@samp{T-gnus 6.15.* (based on Oort Gnus v0.*; for SEMI 1.1*, FLIM +@samp{T-gnus 6.16.* (based on Gnus v5.10.*; for SEMI 1.1*, FLIM 1.1*)} $B$N$h$&$J$b$N$,=P$F$-$?$J$i!"@5$7$$%U%!%$%k$,FI$_9~$^$l$F$$$^$9!#(B -$B$b$7!"(B@samp{NNTP 3.x} $B$d(B @samp{nntp flee} $B$N$h$&$J$b$N$,=P$F$-$?$H$-$O!"(B -$B$=$3$K$"$k$$$/$D$+$N8E$$(B @file{.el} $B%U%!%$%k$,FI$_9~$^$l$F$$$^$9!#$=$l$i(B -$B$r>C$7$F2<$5$$!#(B +$B$=$&$J$i$J$$>l9g$O!"8E$$(B @file{.el} $B%U%!%$%k$,;6$i$+$C$F$$$^$9!#$=$l$i$r(B +$B>C$7$F2<$5$$!#(B @item @acronym{FAQ} $B$H(B how-to $B$rFI$`$?$a$K%X%k%W%0%k!<%W(B ($B%0%k!<%W%P%C%U%!(B @@ -25032,9 +25827,10 @@ Gnus $B$OB?$/$NB?$/$N:F5"9=B$$GF0:n$7!"2?$i$+$N6KC<$J(B ($B$=$7$FHs>o$K$^$l( $B%0$r:F8=$5$;$kJ}K!$r@53N$K=q$$$F$/$l$?$H$-$N$_!"$=$l$r=$@5$9$k;v$,$G$-$^(B $B$9!#(B -$B%P%0Js9p$G$O!">\:Y$9$.$k$3$H$O7h$7$F$"$j$^$;$s!#%P%0Js9p$r$9$k$H$-$O!"$=(B -$B$l$,;H$&$?$S$K(B 10Kb $B%a!<%k$r:n$j!"$b$7$"$J$?$N4D6-$r0JA0;d$K(B 500 $B2sAw$C(B -$B$F$-$?$H$7$F$b!"L?Na(B @kbd{M-x gnus-bug} $B$r;H$C$F2<$5$$!#(B +$B%P%0Js9p$G$O!">\:Y$9$.$k$3$H$O7h$7$F$"$j$^$;$s!#%P%0Js9p$r$9$k$H$-$O!"$$(B +$B$D$b(B @kbd{M-x gnus-bug} $BL?Na$r;H$C$F2<$5$$!#$=$l$r;H$&$?$S$K(B 10Kb $B$N%a!<(B +$B%k$,$G$-$F$7$^$C$F$b!"$=$7$F$"$J$?$N4D6-$r0JA0;d$K(B 500 $B2sAw$C$?$H$7$F$b(B +$B$G$9!#(B $B;d$O!"5-21$H$$$&pJs$rMW5a Gnus $B$O%0%k!<%WL>$H5-;vHV9f$K$h$C$F$=$l$>$l$N%a%C%;!<%8$rFCDj$7$^$9!#$=(B $B$l$i5-;vHV9f$K4X$9$k$A$g$C$H$7$?@bL@$r$9$k$3$H$OM-1W$+$b$7$l$^$;$s!#$^$:(B $BBh0l$K!"$=$N?t;z$O@5$N@0?t$G$9!#BhFs$K!"(BGnus $B$r:.Mp$5$;$k$3$H$J$/8E$$5-(B -$B;vHV9f$r8e$G:F;HMQ$9$k$3$H$OIaDL$O$G$-$^$;$s!#$=$l$O!"$b$7$"$k%0%k!<%W$,(B -$B$+$D$F(B 42 $BHV$N5-;v$r;}$C$F$$$?$H$7$?$i!"$=$NHV9f$GB>$N5-;v$r;}$D$3$H$O$G(B -$B$-$J$$$+!"$^$?$O(B Gnus $B$,:.Mp$7$F$7$^$&$+$b$7$l$J$$$H$$$&$3$H$G$9!#(B +$B;vHV9f$r8e$G(B ``$B:F;HMQ(B'' $B$9$k$3$H$OIaDL$O$G$-$^$;$s!#$=$l$O!"$b$7$"$k%0%k!<(B +$B%W$,$+$D$F(B 42 $BHV$N5-;v$r;}$C$F$$$?$H$7$?$i!"$=$NHV9f$GB>$N5-;v$r;}$D$3$H(B +$B$O$G$-$J$$$+!"$^$?$O(B Gnus $B$,:.Mp$7$F$7$^$&$+$b$7$l$J$$$H$$$&$3$H$G$9!#(B @footnote{See the function @code{nnchoke-request-update-info}, @ref{Optional Back End Functions}$B!#(B} $BBh;0$K!"5-;vHV9f$O$=$N%0%k!<%W$G$N(B $BE~Ce=g$K$J$C$F$$$J$1$l$P$J$i$J$$$3$H$G$9!#$H$O8@$(%a%C%;!<%8$NF|IU$bE~Ce(B $B=g$G$"$kI,MW$O$"$j$^$;$s$,!#(B $B$9$G$KA0$N@a$G!"5-;vHV9f$O0l2s;H$o$l$?$@$1$GLrL\$r=*$o$i$J$1$l$P$J$i$J(B -$B$$(B `$B87$7$$(B' $B@)8B$K$D$$$F@bL@$7$^$7$?!#$7$+$7!"5-;vHV9f$NJB$S$KH4$1$,$"$k(B -$B$H(B Gnus $B$O$H$F$b:.Mp$7$F$7$^$&$N$G!"(B@emph{$BDL$7(B} $BHV9f$rIU$1$k$3$H$,M-MQ$J(B -$B$N$+$b$7$l$^$;$s!#$?$@$7(B `$B:F;HMQIT2D(B' $B$N@)8B$,$"$k$N$G!"$$$D$G$bHV9f$NH4(B -$B$1$r2sHr$G$-$k$H$O8B$j$^$;$s!#$^$?!"2DG=$J8B$j5-;vHV9f$r(B 1 $B$+$i;O$a$k$3(B -$B$H$O!"HV9f$r;H$$@Z$C$F$7$^$&$3$H$rHr$1$k$?$a$KLrN)$A$^$9!#(B +$B$$(B ``$B87$7$$(B'' $B@)8B$K$D$$$F@bL@$7$^$7$?!#$7$+$7!"5-;vHV9f$NJB$S$KH4$1$,$"(B +$B$k$H(B Gnus $B$O$H$F$b:.Mp$7$F$7$^$&$N$G!"(B@emph{$BDL$7(B} $BHV9f$rIU$1$k$3$H$,M-MQ(B +$B$J$N$+$b$7$l$^$;$s!#$?$@$7(B ``$B:F;HMQIT2D(B'' $B$N@)8B$,$"$k$N$G!"$$$D$G$bHV9f(B +$B$NH4$1$r2sHr$G$-$k$H$O8B$j$^$;$s!#$^$?!"2DG=$J8B$j5-;vHV9f$r(B 1 $B$+$i;O$a(B +$B$k$3$H$O!"HV9f$r;H$$@Z$C$F$7$^$&$3$H$rHr$1$k$?$a$KLrN)$A$^$9!#(B $B47Nc$H$7$F!"%P%C%/%(%s%I$O(B @code{nn$B$J$s$?$i(B} $B$HL>IU$1$i$l$^$9$,!"(B gnus $B$K$O(B @file{nnheader.el}$B!"(B@file{nnmail.el} $B$*$h$S(B @file{nnoo.el} $B$N(B @@ -25399,7 +26195,7 @@ field = @end example $B$3$l$i$NMs$K$I$N$h$&$J$b$N$,4^$^$l$k$+$r$h$j>\$7$/8+$?$1$l$P!"(B -@pxref{Headers} $B$r;2>H$7$F$/$@$5$$!#(B +@ref{Headers} $B$r;2>H$7$F$/$@$5$$!#(B @item (nnchoke-open-server SERVER &optional DEFINITIONS) @@ -25679,14 +26475,14 @@ description-buffer = *description-line $B?t(B @code{message-make-date} $B$+$iJV$5$l$?$b$N(B) $B$G$9!#%G!<%?$O(B active $B%P%C(B $B%U%!$N7A<0$G$J$1$l$P$J$j$^$;$s!#(B -$B$3$N4X?t$,B?$9$.$k%0%k!<%W$rJV$7$F$b%*!<%1%$$G$9!#$$$/$D$+$N%P%C%/%(%s%I(B -$B$O?7$7$$%0%k!<%W$r8+$D$1$k$h$j$b!"3Z$r$7$FA4$F$N%0%k!<%W$N%j%9%H$rJV$9$+(B -$B$b$7$l$^$;$s!#$7$+$7%P%C%/%(%s%I$,JV$9B?$/$N%0%k!<%W$KBP$7$F$3$l(B ($BLuCm(B: -$B?7$7$$%0%k!<%W$H$7$F07$&$3$H(B) $B$r$7$F$O$$$1$^$;$s!#IaDL!"%f!<%6!<<+?H$,:n$C(B -$B$?%0%k!<%W$J$i$PB?$9$.$k$3$H$O$J$$$G$7$g$&!#$G$9$+$i(B @code{nnml} $B$H$=$l(B -$B$KN`$9$k$b$N$O$?$V$s?4G[$"$j$^$;$s!#$7$+$7(B @code{nntp} $B$N$h$&$J%P%C%/%((B -$B%s%I$G$O%0%k!<%W$O%5!<%P!<$K$h$C$F:n$i$l$F$$$^$9$+$i!"B?$/$N%0%k!<%W$,JV$C(B -$B$F$/$k$3$H$,$"$j$($^$9!#(B +$B$3$N4X?t$,(B ``$BB?$9$.$k(B'' $B%0%k!<%W$rJV$7$F$b%*!<%1%$$G$9!#$$$/$D$+$N%P%C%/(B +$B%(%s%I$O?7$7$$%0%k!<%W$r8+$D$1$k$h$j$b!"3Z$r$7$FA4$F$N%0%k!<%W$N%j%9%H$r(B +$BJV$9$+$b$7$l$^$;$s!#$7$+$7%P%C%/%(%s%I$,JV$9B?$/$N%0%k!<%W$KBP$7$F$3(B +$B$l(B ($BLuCm(B: $B?7$7$$%0%k!<%W$H$7$F07$&$3$H(B) $B$r$7$F$O$$$1$^$;$s!#IaDL!"%f!<%6!<(B +$B<+?H$,:n$C$?%0%k!<%W$J$i$PB?$9$.$k$3$H$O$J$$$G$7$g$&!#$G$9$+(B +$B$i(B @code{nnml} $B$H$=$l$KN`$9$k$b$N$O$?$V$s?4G[$"$j$^$;$s!#$7$+(B +$B$7(B @code{nntp} $B$N$h$&$J%P%C%/%(%s%I$G$O%0%k!<%W$O%5!<%P!<$K$h$C$F:n$i$l(B +$B$F$$$^$9$+$i!"B?$/$N%0%k!<%W$,JV$C$F$/$k$3$H$,$"$j$($^$9!#(B @item (nnchoke-request-create-group GROUP &optional SERVER) @@ -25797,8 +26593,8 @@ description-buffer = *description-line @code{nnml} $B$O(B @code{nnspool} $B$K$H$F$b;w$F$$$^$9$,!"%5!<%P!<>e$N5-;v$rJT(B $B=8$9$k$3$H$,$G$-$^$9!#(B@code{nnmh} $B$O(B @code{nnml} $B$K$H$F$b;w$F$$$^$9$,!"(B $B$3$l$O%"%/%F%#%V%U%!%$%k$r;H$o$:!"35MW%G!<%?%Y!<%9$bJ];}$7$^$;$s!#(B -@code{nndir} $B$O(B @code{nnml} $B$K$H$F$b;w$F$$$^$9$,!"$3$l$K$O(B ``$B%0%k!<%W(B'' -$B$N35G0$O$J$/!"5-;v$N=$@5$O$G$-$^$;$s!#(B +@code{nndir} $B$O(B @code{nnml} $B$K$H$F$b;w$F$$$^$9$,!"$3$l$K(B +$B$O(B ``$B%0%k!<%W(B'' $B$N35G0$O$J$/!"5-;v$N=$@5$O$G$-$^$;$s!#(B $B?7$7$$%P%C%/%(%s%I$r=q$/$H$-$KB>$N%P%C%/%(%s%I$+$i4X?t$r(B ``$B7Q>5(B'' $B$9$k$3(B $B$H$,2DG=$G$"$C$F$[$7$$!"$H;W$&$N$OM}$KE,$C$F$$$^$9!#$=$7$F$^$5$K!"$"$J$?(B diff --git a/texi/gnus.texi b/texi/gnus.texi index 8b027a8..66ced09 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -1,7 +1,7 @@ \input texinfo @setfilename gnus -@settitle T-gnus 6.15 Manual +@settitle T-gnus 6.16 Manual @syncodeindex fn cp @syncodeindex vr cp @syncodeindex pg cp @@ -33,7 +33,7 @@ \makeindex \begin{document} -\newcommand{\gnusversionname}{T-gnus v6.15} +\newcommand{\gnusversionname}{T-gnus v6.16} \newcommand{\gnuschaptername}{} \newcommand{\gnussectionname}{} @@ -53,6 +53,9 @@ \newcommand{\gnustt}[1]{{\gnusselectttfont{}#1}} \newcommand{\gnuscode}[1]{\gnustt{#1}} +\newcommand{\gnusasis}[1]{\gnustt{#1}} +\newcommand{\gnusurl}[1]{\gnustt{#1}} +\newcommand{\gnuscommand}[1]{\gnustt{#1}} \newcommand{\gnusenv}[1]{\gnustt{#1}} \newcommand{\gnussamp}[1]{``{\fontencoding{OT1}\gnusselectttfont{}#1}''} \newcommand{\gnuslisp}[1]{\gnustt{#1}} @@ -153,6 +156,11 @@ } }{\end{list}} +\newenvironment{asislist}% +{\begin{list}{}{ +} +}{\end{list}} + \newenvironment{kbdlist}% {\begin{list}{}{ \labelwidth=0cm @@ -293,7 +301,7 @@ \thispagestyle{empty} Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003 +2002, 2003, 2004 Free Software Foundation, Inc. @@ -346,7 +354,7 @@ license to the document, as described in section 6 of the license. @tex @titlepage -@title T-gnus 6.15 Manual +@title T-gnus 6.16 Manual @author by Lars Magne Ingebrigtsen @page @@ -396,7 +404,7 @@ internationalization/localization and multiscript features based on MULE API. So T-gnus does not discriminate various language communities. Oh, if you are a Klingon, please wait Unicode Next Generation. -This manual corresponds to T-gnus 6.15. +This manual corresponds to T-gnus 6.16. @end ifinfo @@ -565,16 +573,13 @@ Reply, Followup and Post * Summary Mail Commands:: Sending mail. * Summary Post Commands:: Sending news. * Summary Message Commands:: Other Message-related commands. -* Canceling and Superseding:: +* Canceling and Superseding:: Marking Articles * Unread Articles:: Marks for unread articles. * Read Articles:: Marks for read articles. * Other Marks:: Marks that do not affect readedness. -* Setting Marks:: -* Generic Marking Commands:: -* Setting Process Marks:: Marking Articles @@ -632,7 +637,7 @@ Various Summary Stuff * Summary Group Information:: Information oriented commands. * Searching for Articles:: Multiple article commands. -* Summary Generation Commands:: +* Summary Generation Commands:: * Really Various Summary Commands:: Those pesky non-conformant commands. Article Buffer @@ -697,7 +702,7 @@ Getting Mail * Group Mail Splitting:: Use group customize to drive mail splitting. * Incorporating Old Mail:: What about the old mail you have? * Expiring Mail:: Getting rid of unwanted mail. -* Washing Mail:: Removing gruft from the mail you get. +* Washing Mail:: Removing cruft from the mail you get. * Duplicates:: Dealing with duplicated mail. * Not Reading Mail:: Using mail back ends for reading other files. * Choosing a Mail Back End:: Gnus can read a variety of mail formats. @@ -720,7 +725,7 @@ Choosing a Mail Back End Browsing the Web -* Archiving Mail:: +* Archiving Mail:: * Web Searches:: Creating groups from articles that match a string. * Slashdot:: Reading the Slashdot comments. * Ultimate:: The Ultimate Bulletin Board systems. @@ -735,6 +740,7 @@ Browsing the Web * Editing IMAP ACLs:: Limiting/enabling other users access to a mailbox. * Expunging mailboxes:: Equivalent of a ``compress mailbox'' button. * A note on namespaces:: How to (not) use @acronym{IMAP} namespace in Gnus. +* Debugging IMAP:: What to do when things don't work. Other Sources @@ -764,6 +770,7 @@ Gnus Unplugged * Agent Basics:: How it all is supposed to work. * Agent Categories:: How to tell the Gnus Agent what to download. * Agent Commands:: New commands for all the buffers. +* Agent Visuals:: Ways that the agent may effect your summary buffer. * Agent as Cache:: The Agent is a big cache too. * Agent Expiry:: How to make old articles go away. * Agent Regeneration:: How to recover from lost connections and other accidents. @@ -839,6 +846,7 @@ Various * Image Enhancements:: Modern versions of Emacs/XEmacs can display images. * Fuzzy Matching:: What's the big fuzz? * Thwarting Email Spam:: A how-to on avoiding unsolicited commercial email. +* Other modes:: Interaction with other modes. * Various Various:: Things that are really various. Formatting Variables @@ -854,9 +862,10 @@ Formatting Variables Image Enhancements -* Picons:: How to display pictures of what you're reading. -* Smileys:: Show all those happy faces the way they were meant to be shown. * X-Face:: Display a funky, teensy black-and-white image. +* Face:: Display a funkier, teensier colored image. +* Smileys:: Show all those happy faces the way they were meant to be shown. +* Picons:: How to display pictures of what you're reading. * XVarious:: Other XEmacsy Gnusey variables. Thwarting Email Spam @@ -865,8 +874,32 @@ Thwarting Email Spam * Anti-Spam Basics:: Simple steps to reduce the amount of spam. * SpamAssassin:: How to use external anti-spam tools. * Hashcash:: Reduce spam by burning CPU time. -* Filtering Spam Using The Spam ELisp Package:: -* Filtering Spam Using Statistics with spam-stat:: +* Filtering Spam Using The Spam ELisp Package:: +* Filtering Spam Using Statistics with spam-stat:: + +Filtering Spam Using 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 + +* Creating a spam-stat dictionary:: +* Splitting mail using spam-stat:: +* Low-level interface to the spam-stat dictionary:: Appendices @@ -878,7 +911,7 @@ Appendices * 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 @@ -959,7 +992,7 @@ If you want to start gnus in a different frame, you can use the command If things do not go smoothly at startup, you have to twiddle some variables in your @file{~/.gnus.el} file. This file is similar to -@file{~/.emacs}, but is read when gnus starts. +@file{~/.emacs}, but is read when Gnus starts. If you puzzle at any terms used in this manual, please refer to the terminology section (@pxref{Terminology}). @@ -1335,11 +1368,11 @@ subscribed, and if it matches the latter, it will be ignored. @vindex gnus-auto-subscribed-groups Yet another variable that meddles here is @code{gnus-auto-subscribed-groups}. It works exactly like -@code{gnus-options-subscribe}, and is therefore really superfluous, but I -thought it would be nice to have two of these. This variable is more -meant for setting some ground rules, while the other variable is used -more for user fiddling. By default this variable makes all new groups -that come from mail back ends (@code{nnml}, @code{nnbabyl}, +@code{gnus-options-subscribe}, and is therefore really superfluous, +but I thought it would be nice to have two of these. This variable is +more meant for setting some ground rules, while the other variable is +used more for user fiddling. By default this variable makes all new +groups that come from mail back ends (@code{nnml}, @code{nnbabyl}, @code{nnfolder}, @code{nnmbox}, @code{nnmh}, and @code{nnmaildir}) subscribed. If you don't like that, just set this variable to @code{nil}. @@ -1761,7 +1794,7 @@ a @code{printf} specifications, for those of you who use (feh!) C. There should always be a colon on the line; the cursor always moves to the colon after performing an operation. @xref{Positioning -Point}. Nothing else is required---not even the group name. All +Point}. Nothing else is required---not even the group name. All displayed text is just window dressing, and is never examined by Gnus. Gnus stores all real information it needs using text properties. @@ -1830,7 +1863,7 @@ comment element in the group parameters. Newsgroup description. You need to read the group descriptions before these will appear, and to do that, you either have to set @code{gnus-read-active-file} or use the group buffer @kbd{M-d} -command. +command. @item o @samp{m} if moderated. @@ -1927,7 +1960,7 @@ background is dark: (defface my-group-face-1 '((t (:foreground "Red" :bold t))) "First group face") (defface my-group-face-2 - '((t (:foreground "DarkSeaGreen4" :bold t))) + '((t (:foreground "DarkSeaGreen4" :bold t))) "Second group face") (defface my-group-face-3 '((t (:foreground "Green4" :bold t))) "Third group face") @@ -2126,17 +2159,19 @@ manner will have no permanent effects. @end table @vindex gnus-large-newsgroup -The @code{gnus-large-newsgroup} variable says what gnus should consider -to be a big group. This is 200 by default. If the group has more +The @code{gnus-large-newsgroup} variable says what Gnus should +consider to be a big group. If it is @code{nil}, no groups are +considered big. The default value is 200. If the group has more (unread and/or ticked) articles than this, gnus will query the user -before entering the group. The user can then specify how many articles -should be fetched from the server. If the user specifies a negative -number (@code{-n}), the @code{n} oldest articles will be fetched. If it -is positive, the @code{n} articles that have arrived most recently will -be fetched. +before entering the group. The user can then specify how many +articles should be fetched from the server. If the user specifies a +negative number (@var{-n}), the @var{n} oldest articles will be +fetched. If it is positive, the @var{n} articles that have arrived +most recently will be fetched. @vindex gnus-large-ephemeral-newsgroup -Same as @code{gnus-large-newsgroup}, but only used for ephemeral +@code{gnus-large-ephemeral-newsgroup} is the same as +@code{gnus-large-newsgroup}, but is only used for ephemeral newsgroups. @vindex gnus-select-group-hook @@ -2510,7 +2545,13 @@ consulted. @cindex making groups Make a new group (@code{gnus-group-make-group}). Gnus will prompt you for a name, a method and possibly an @dfn{address}. For an easier way -to subscribe to @acronym{NNTP} groups, @pxref{Browse Foreign Server}. +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) @@ -2628,6 +2669,13 @@ If you use the @code{google} search engine, you can limit the search to a particular group by using a match string like @samp{shaving group:alt.sysadmin.recovery}. +@item G R +@kindex G R (Group) +@findex gnus-group-make-rss-group +Make a group based on an @acronym{RSS} feed +(@code{gnus-group-make-rss-group}). You will be prompted for an URL. +@xref{RSS}. + @item G DEL @kindex G DEL (Group) @findex gnus-group-delete-group @@ -2636,7 +2684,7 @@ This function will delete the current group actually delete all the articles in the group, and forcibly remove the group itself from the face of the Earth. Use a prefix only if you are absolutely sure of what you are doing. This command can't be used on -read-only groups (like @code{nntp} group), though. +read-only groups (like @code{nntp} groups), though. @item G V @kindex G V (Group) @@ -2727,10 +2775,6 @@ then a @code{to-list} group parameter will be added automatically upon sending the message if @code{gnus-add-to-list} is set to @code{t}. @vindex gnus-add-to-list -If you do an @kbd{a} command in a mail group and you don't have a -@code{to-list} group parameter, one will be added automatically upon -sending the message. - @findex gnus-mailing-list-mode @cindex mail list groups If this variable is set, @code{gnus-mailing-list-mode} is turned on when @@ -2741,16 +2785,22 @@ See also @code{gnus-parameter-to-list-alist}. @anchor{subscribed} @item subscribed @cindex subscribed +@cindex Mail-Followup-To +@findex gnus-find-subscribed-addresses If this parameter is set to @code{t}, Gnus will consider the to-address and to-list parameters for this group as addresses of mailing lists you are subscribed to. Giving Gnus this information is (only) a first step in getting it to generate correct Mail-Followup-To -headers for your posts to these lists. Look here @pxref{Mailing -Lists, , Mailing Lists, message, The Message Manual} for a complete -treatment of available MFT support. +headers for your posts to these lists. The second step is to put the +following in your @file{.gnus.el} + +@lisp +(setq message-subscribed-address-functions + '(gnus-find-subscribed-addresses)) +@end lisp -See also @code{gnus-find-subscribed-addresses}, the function that -directly uses this group parameter. +@xref{Mailing Lists, ,Mailing Lists, message, The Message Manual}, for +a complete treatment of available MFT support. @item visible @cindex visible @@ -2787,9 +2837,11 @@ composed messages will be @code{Gcc}'d to the current group. If generated, if @code{(gcc-self . "string")} is present, this string will be inserted literally as a @code{gcc} header. This parameter takes precedence over any default @code{Gcc} rules as described later -(@pxref{Archived Messages}). CAVEAT:: It yields an error putting -@code{(gcc-self . t)} in groups of a @code{nntp} server or so, because -a @code{nntp} server doesn't accept articles. +(@pxref{Archived Messages}). + +@strong{Caveat}: Adding @code{(gcc-self . t)} to the parameter list of +@code{nntp} groups (or the like) isn't valid. An @code{nntp} server +doesn't accept articles. @item auto-expire @cindex auto-expire @@ -2819,6 +2871,11 @@ If the group parameter has an element that looks like can either be a number of days (not necessarily an integer) or the symbols @code{never} or @code{immediate}. +@item expiry-target +@cindex expiry-target +Where expired messages end up. This parameter overrides +@code{nnmail-expiry-target}. + @item score-file @cindex score file group parameter Elements that look like @code{(score-file . "file")} will make @@ -2933,7 +2990,7 @@ instead of @code{gnus-post-method}. @item banner @cindex banner An item like @code{(banner . @var{regexp})} causes any part of an article -that matches the regular expression @var{regexp} to be stripped. Instead of +that matches the regular expression @var{regexp} to be stripped. Instead of @var{regexp}, you can also use the symbol @code{signature} which strips the last signature or any of the elements of the alist @code{gnus-article-banner-alist}. @@ -2945,7 +3002,7 @@ that should be placed in this group. From this group parameter, a Sieve @samp{IF} control structure is generated, having the test as the condition and @samp{fileinto "group.name";} as the body. -For example, if the INBOX.list.sieve group has the @code{(sieve +For example, if the @samp{INBOX.list.sieve} group has the @code{(sieve address "sender" "sieve-admin@@extundo.com")} group parameter, when translating the group parameter into a Sieve script (@pxref{Sieve Commands}) the following Sieve code is generated: @@ -2956,8 +3013,15 @@ if address \"sender\" \"sieve-admin@@extundo.com\" @{ @} @end example -The Sieve language is described in RFC 3028. @xref{Top, , Top, sieve, -Emacs Sieve}. +The Sieve language is described in RFC 3028. @xref{Top, Emacs Sieve, +Top, sieve, Emacs Sieve}. + +@item (agent parameters) +If the agent has been enabled, you can set any of the its parameters +to control the behavior of the agent in individual groups. See Agent +Parameters in @ref{Category Syntax}. Most users will choose to set +agent parameters in either an agent category or group topic to +minimize the configuration effort. @item (@var{variable} @var{form}) You can use the group parameters to set variables local to the group you @@ -2975,16 +3039,19 @@ question to @code{gnus-newsgroup-variables}. @xref{Various Summary Stuff}. So if you want to set @code{message-from-style} via the group parameters, then you may need the following statement elsewhere in your @file{~/.gnus} file: + @lisp (add-to-list 'gnus-newsgroup-variables 'message-from-style) @end lisp @vindex gnus-list-identifiers A use for this feature is to remove a mailing list identifier tag in -the subject fields of articles. E.g. if the news group +the subject fields of articles. E.g. if the news group + @example nntp+news.gnus.org:gmane.text.docbook.apps @end example + has the tag @samp{DOC-BOOK-APPS:} in the subject of all articles, this tag can be removed from the article subjects in the summary buffer for the group by putting @code{(gnus-list-identifiers "DOCBOOK-APPS:")} @@ -3604,9 +3671,9 @@ Yank the previously killed group or topic before all groups. So, to move a topic to the beginning of the list of topics, just hit -@kbd{C-k} on it. This is like the `cut' part of cut and paste. Then, -move the cursor to the beginning of the buffer (just below the `Gnus' -topic) and hit @kbd{C-y}. This is like the `paste' part of cut and +@kbd{C-k} on it. This is like the ``cut'' part of cut and paste. Then, +move the cursor to the beginning of the buffer (just below the ``Gnus'' +topic) and hit @kbd{C-y}. This is like the ``paste'' part of cut and paste. Like I said -- E-Z. You can use @kbd{C-k} and @kbd{C-y} on groups as well as on topics. So @@ -3719,7 +3786,7 @@ sub-topics unless given a prefix. @findex gnus-topic-expire-articles Run all expirable articles in the current group or topic through the expiry process (if any) -(@code{gnus-topic-expire-articles}). (@pxref{Expiring Mail}). +(@code{gnus-topic-expire-articles}). (@pxref{Expiring Mail}). @item T r @kindex T r (Topic) @@ -3853,7 +3920,7 @@ Sort the current topic alphabetically by server name (@code{gnus-topic-sort-groups-by-server}). @item T S s -@kindex T S s +@kindex T S s (Topic) @findex gnus-topic-sort-groups Sort the current topic according to the function(s) given by the @code{gnus-group-sort-function} variable @@ -3916,9 +3983,11 @@ allowed---@code{visible} and @code{invisible}. @subsection Topic Parameters @cindex topic parameters -All groups in a topic will inherit group parameters from the parent (and -ancestor) topic parameters. All valid group parameters are valid topic -parameters (@pxref{Group Parameters}). +All groups in a topic will inherit group parameters from the parent +(and ancestor) topic parameters. All valid group parameters are valid +topic parameters (@pxref{Group Parameters}). When the agent is +enabled, all agent parameters (See Agent Parameters in @ref{Category +Syntax}) are also valid topic parameters. In addition, the following parameters are only valid as topic parameters: @@ -3943,6 +4012,7 @@ know. Normal inheritance rules. (@dfn{Rules} is here a noun, not a verb, although you may feel free to disagree with me here.) @example +@group Gnus Emacs 3: comp.emacs @@ -3955,6 +4025,7 @@ Gnus 8: comp.binaries.fractals 13: comp.sources.unix 452: alt.sex.emacs +@end group @end example The @samp{Emacs} topic has the topic parameter @code{(score-file @@ -4059,7 +4130,7 @@ whether they are empty or not. @item gnus-group-name-charset-method-alist @vindex gnus-group-name-charset-method-alist -An alist of method and the charset for group names. It is used to show +An alist of method and the charset for group names. It is used to show non-@acronym{ASCII} group names. For example: @@ -4179,7 +4250,7 @@ messages for the group, which in some cases includes the charter. @vindex gnus-group-fetch-control-use-browse-url @cindex control message Fetch the control messages for the group from the archive at -@code{ftp.isc.org} (@code{gnus-group-fetch-control}). Query for a +@code{ftp.isc.org} (@code{gnus-group-fetch-control}). Query for a group if given a prefix argument. If @code{gnus-group-fetch-control-use-browse-url} is non-@code{nil}, @@ -4341,7 +4412,7 @@ placed in all groups that have matching rules, otherwise the article is only placed in the group with the first matching rule. For example, the group parameter @samp{(sieve address "sender" "owner-ding@@hpc.uh.edu")} will generate the following piece of Sieve -code if @code{gnus-sieve-crosspost} is @code{nil}. (When +code if @code{gnus-sieve-crosspost} is @code{nil}. (When @code{gnus-sieve-crosspost} is non-@code{nil}, it looks the same except that the line containing the call to @code{stop} is removed.) @@ -4352,7 +4423,7 @@ if address "sender" "owner-ding@@hpc.uh.edu" @{ @} @end example -@xref{Top, ,Top, sieve, Emacs Sieve}. +@xref{Top, Emacs Sieve, Top, sieve, Emacs Sieve}. @table @kbd @@ -4518,7 +4589,7 @@ the @code{a} spec. @item L Number of lines in the article. @item c -Number of characters in the article. This specifier is not supported +Number of characters in the article. This specifier is not supported in some methods (like nnfolder). @item k Pretty-printed version of the number of characters in the article; @@ -4566,7 +4637,7 @@ Used for drawing a vertical line. The default is @samp{| }. @item gnus-sum-thread-tree-indent @vindex gnus-sum-thread-tree-indent -Used for indenting. The default is @samp{ }. +Used for indenting. The default is @samp{ }. @item gnus-sum-thread-tree-leaf-with-other @vindex gnus-sum-thread-tree-leaf-with-other @@ -4592,7 +4663,7 @@ One space for each thread level. @item < Twenty minus thread level spaces. @item U -Unread. @xref{Read Articles}. +Unread. @xref{Read Articles}. @item R This misleadingly named specifier is the @dfn{secondary mark}. This @@ -4637,7 +4708,7 @@ Age sensitive date format. Various date format is defined in @item u User defined specifier. The next character in the format string should be a letter. Gnus will call the function -@code{gnus-user-format-function-}@samp{X}, where @samp{X} is the letter +@code{gnus-user-format-function-@var{x}}, where @var{x} is the letter following @samp{%u}. The function will be passed the current header as argument. The function should return a string, which will be inserted into the summary just like information from any other summary specifier. @@ -4956,7 +5027,7 @@ unread article (@code{gnus-summary-next-page}). If you have an article window open already and you press @kbd{SPACE} again, the article will be scrolled. This lets you conveniently -@kbd{SPACE} through an entire newsgroup. @pxref{Paging the Article}. +@kbd{SPACE} through an entire newsgroup. @xref{Paging the Article}. @item G n @itemx n @@ -5062,7 +5133,7 @@ the server and display it in the article buffer. @item gnus-select-article-hook @vindex gnus-select-article-hook This hook is called whenever an article is selected. By default it -exposes any threads hidden under the selected article. If you would +exposes any threads hidden under the selected article. If you would like each article to be saved in the Agent as you read it, putting @code{gnus-agent-fetch-selected-article} on this hook will do so. @@ -5184,7 +5255,7 @@ Select the article buffer (@code{gnus-summary-select-article-buffer}). * Summary Mail Commands:: Sending mail. * Summary Post Commands:: Sending news. * Summary Message Commands:: Other Message-related commands. -* Canceling and Superseding:: +* Canceling and Superseding:: @end menu @@ -5223,7 +5294,8 @@ command uses the process/prefix convention. Mail a wide reply to the author of the current article (@code{gnus-summary-wide-reply}). A @dfn{wide reply} is a reply that goes out to all people listed in the @code{To}, @code{From} (or -@code{Reply-to}) and @code{Cc} headers. +@code{Reply-to}) and @code{Cc} headers. If @code{Mail-Followup-To} is +present, that's used instead. @item S W @kindex S W (Summary) @@ -5395,7 +5467,7 @@ Post a followup to the current article (@code{gnus-summary-followup}). @c @icon{gnus-summary-followup-with-original} @findex gnus-summary-followup-with-original Post a followup to the current article and include the original message -(@code{gnus-summary-followup-with-original}). This command uses the +(@code{gnus-summary-followup-with-original}). This command uses the process/prefix convention. @item S n @@ -5482,6 +5554,10 @@ Gnus will use the ``current'' select method when canceling. If you 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. @@ -5538,7 +5614,7 @@ A time span. Consists of an integer and a letter. For example, (months) and @code{Y} (years). @item -A specific date. Looks like @code{YYYYY-MM-DD}. The message will be +A specific date. Looks like @code{YYYY-MM-DD}. The message will be delayed until that day, at a specific time (eight o'clock by default). See also @code{gnus-delay-default-hour}. @@ -5796,7 +5872,7 @@ religiously) are marked with an @samp{S} in the second column Articles that according to the server haven't been shown to the user before are marked with a @samp{N} in the second column (@code{gnus-recent-mark}). Note that not all servers support this -mark, in which case it simply never appears. Compare with +mark, in which case it simply never appears. Compare with @code{gnus-unseen-mark}. @item @@ -5807,7 +5883,7 @@ Compare with @code{gnus-recent-mark}. @item @vindex gnus-downloaded-mark -When using the Gnus agent @pxref{Agent Basics}, articles may be +When using the Gnus agent (@pxref{Agent Basics}), articles may be downloaded for unplugged (offline) viewing. If you are using the @samp{%O} spec, these articles get the @samp{+} mark in that spec. (The variable @code{gnus-downloaded-mark} controls which character to @@ -5815,7 +5891,7 @@ use.) @item @vindex gnus-undownloaded-mark -When using the Gnus agent @pxref{Agent Basics}, some articles might +When using the Gnus agent (@pxref{Agent Basics}), some articles might not have been downloaded. Such articles cannot be viewed while you are unplugged (offline). If you are using the @samp{%O} spec, these articles get the @samp{-} mark in that spec. (The variable @@ -5823,7 +5899,7 @@ articles get the @samp{-} mark in that spec. (The variable @item @vindex gnus-downloadable-mark -The Gnus agent @pxref{Agent Basics} downloads some articles +The Gnus agent (@pxref{Agent Basics}) downloads some articles automatically, but it is also possible to explicitly mark articles for download, even if they would not be downloaded automatically. Such explicitly-marked articles get the @samp{%} mark in the first column. @@ -6106,7 +6182,7 @@ expression (@code{gnus-uu-unmark-by-regexp}). Mark articles in region (@code{gnus-uu-mark-region}). @item M P g -@kindex M P g +@kindex M P g (Summary) @findex gnus-uu-unmark-region Unmark articles in region (@code{gnus-uu-unmark-region}). @@ -6170,7 +6246,7 @@ Push the current process mark set onto the stack @end table -Also see the @kbd{&} command in @pxref{Searching for Articles} for how to +Also see the @kbd{&} command in @ref{Searching for Articles}, for how to set process marks based on article body contents. @@ -6194,14 +6270,14 @@ additional articles. @kindex / / (Summary) @findex gnus-summary-limit-to-subject Limit the summary buffer to articles that match some subject -(@code{gnus-summary-limit-to-subject}). If given a prefix, exclude +(@code{gnus-summary-limit-to-subject}). If given a prefix, exclude matching articles. @item / a @kindex / a (Summary) @findex gnus-summary-limit-to-author Limit the summary buffer to articles that match some author -(@code{gnus-summary-limit-to-author}). If given a prefix, exclude +(@code{gnus-summary-limit-to-author}). If given a prefix, exclude matching articles. @item / x @@ -6209,7 +6285,7 @@ matching articles. @findex gnus-summary-limit-to-extra Limit the summary buffer to articles that match one of the ``extra'' headers (@pxref{To From Newsgroups}) -(@code{gnus-summary-limit-to-extra}). If given a prefix, exclude +(@code{gnus-summary-limit-to-extra}). If given a prefix, exclude matching articles. @item / u @@ -6266,8 +6342,8 @@ score (@code{gnus-summary-limit-to-score}). @findex gnus-summary-limit-to-display-predicate Limit the summary buffer to articles that satisfy the @code{display} group parameter predicate -(@code{gnus-summary-limit-to-display-predicate}). See @pxref{Group -Parameters} for more on this predicate. +(@code{gnus-summary-limit-to-display-predicate}). @xref{Group +Parameters}, for more on this predicate. @item / E @itemx M S @@ -6315,19 +6391,19 @@ Exclude all dormant articles that have no children from the limit@* @kindex / C (Summary) @findex gnus-summary-limit-mark-excluded-as-read Mark all excluded unread articles as read -(@code{gnus-summary-limit-mark-excluded-as-read}). If given a prefix, +(@code{gnus-summary-limit-mark-excluded-as-read}). If given a prefix, also mark excluded ticked and dormant articles as read. @item / N @kindex / N (Summary) @findex gnus-summary-insert-new-articles -Insert all new articles in the summary buffer. It scans for new emails +Insert all new articles in the summary buffer. It scans for new emails if @var{back-end}@code{-get-new-mail} is non-@code{nil}. @item / o @kindex / o (Summary) @findex gnus-summary-insert-old-articles -Insert all old articles in the summary buffer. If given a numbered +Insert all old articles in the summary buffer. If given a numbered prefix, fetch this number of articles. @end table @@ -6348,7 +6424,7 @@ trees, but unfortunately, the @code{References} header is often broken or simply missing. Weird news propagation exacerbates the problem, so one has to employ other heuristics to get pleasing results. A plethora of approaches exists, as detailed in horrible detail in -@pxref{Customizing Threading}. +@ref{Customizing Threading}. First, a quick overview of the concepts: @@ -6594,16 +6670,16 @@ something like: @item gnus-fetch-old-headers @vindex gnus-fetch-old-headers If non-@code{nil}, gnus will attempt to build old threads by fetching -more old headers---headers to articles marked as read. If you -would like to display as few summary lines as possible, but still -connect as many loose threads as possible, you should set this variable -to @code{some} or a number. If you set it to a number, no more than -that number of extra old headers will be fetched. In either case, -fetching old headers only works if the back end you are using carries -overview files---this would normally be @code{nntp}, @code{nnspool}, +more old headers---headers to articles marked as read. If you would +like to display as few summary lines as possible, but still connect as +many loose threads as possible, you should set this variable to +@code{some} or a number. If you set it to a number, no more than that +number of extra old headers will be fetched. In either case, fetching +old headers only works if the back end you are using carries overview +files---this would normally be @code{nntp}, @code{nnspool}, @code{nnml}, and @code{nnmaildir}. Also remember that if the root of -the thread has been expired by the server, there's not much Gnus can do -about that. +the thread has been expired by the server, there's not much Gnus can +do about that. This variable can also be set to @code{invisible}. This won't have any visible effects, but is useful if you use the @kbd{A T} command a lot @@ -6900,7 +6976,8 @@ Matching}). @findex gnus-thread-sort-by-number @findex gnus-thread-sort-by-random @vindex gnus-thread-sort-functions -@findex gnus-thread-sort-by-most-recent-thread +@findex gnus-thread-sort-by-most-recent-number +@findex gnus-thread-sort-by-most-recent-date If you are using a threaded summary display, you can sort the threads by setting @code{gnus-thread-sort-functions}, which can be either a single function, a list of functions, or a list containing functions and @@ -7159,7 +7236,7 @@ file. @findex gnus-cache-move-cache @code{gnus-cache-move-cache} will move your whole -@code{gnus-cache-directory} to some other location. You get asked to +@code{gnus-cache-directory} to some other location. You get asked to where, isn't that cool? @node Persistent Articles @@ -7323,9 +7400,9 @@ complete headers in the piped output. @kindex O P (Summary) @findex gnus-summary-muttprint @vindex gnus-summary-muttprint-program -Save the current article into muttprint. That is, print it using the +Save the current article into muttprint. That is, print it using the external program @uref{http://muttprint.sourceforge.net/, -Muttprint}. The program name and options to use is controlled by the +Muttprint}. The program name and options to use is controlled by the variable @code{gnus-summary-muttprint-program}. (@code{gnus-summary-muttprint}). @@ -8165,7 +8242,7 @@ Signature}. Strip list identifiers specified in @code{gnus-list-identifiers}. These are strings some mailing list servers add to the beginning of all @code{Subject} headers---for example, @samp{[zebra 4711]}. Any leading -@samp{Re: } is skipped before stripping. @code{gnus-list-identifiers} +@samp{Re: } is skipped before stripping. @code{gnus-list-identifiers} may not contain @code{\\(..\\)}. @table @code @@ -8223,7 +8300,7 @@ banner something like @samp{Do You Yoo-hoo!?} in all articles he sends, you can use the following element to remove them: @lisp -("@@yoo-hoo\\.co\\.jp\\'" . +("@@yoo-hoo\\.co\\.jp\\'" . "\n_+\nDo You Yoo-hoo!\\?\n.*\n.*\n") @end lisp @@ -8260,7 +8337,7 @@ Number of lines of hidden text. @item gnus-cited-lines-visible @vindex gnus-cited-lines-visible The number of lines at the beginning of the cited text to leave -shown. This can also be a cons cell with the number of lines at the top +shown. This can also be a cons cell with the number of lines at the top and bottom of the text, respectively, to remain visible. @end table @@ -8642,7 +8719,7 @@ Fold all the message headers (@code{gnus-article-treat-fold-headers}). @item W E w -@kindex W E w +@kindex W E w (Summary) @findex gnus-article-remove-leading-whitespace Remove excessive whitespace from all headers (@code{gnus-article-remove-leading-whitespace}). @@ -8760,17 +8837,17 @@ message ID or a mail address. If it is one of the symbols @code{mid} or @code{mail}, Gnus will always assume that the string is a message ID or a mail address, respectively. If this variable is set to the symbol @code{ask}, always query the user what do do. If it is a function, this -function will be called with the string as it's only argument. The +function will be called with the string as its only argument. The function must return @code{mid}, @code{mail}, @code{invalid} or @code{ask}. The default value is the function @code{gnus-button-mid-or-mail-heuristic}. @item gnus-button-mid-or-mail-heuristic @findex gnus-button-mid-or-mail-heuristic -Function that guesses whether it's argument is a message ID or a mail -address. Returns @code{mid} it's a message IDs, @code{mail} if it's a -mail address, @code{ask} if unsure and @code{invalid} if the string is -invalid. +Function that guesses whether its argument is a message ID or a mail +address. Returns @code{mid} if it's a message IDs, @code{mail} if +it's a mail address, @code{ask} if unsure and @code{invalid} if the +string is invalid. @item gnus-button-mid-or-mail-heuristic-alist @vindex gnus-button-mid-or-mail-heuristic-alist @@ -8973,12 +9050,15 @@ buffer in Emacs versions that support them. @code{X-Face} headers are small black-and-white images supplied by the message headers (@pxref{X-Face}). -Picons, on the other hand, reside on your own system, and Gnus will -try to match the headers to what you have (@pxref{Picons}). +@code{Face} headers are small colored images supplied by the message +headers (@pxref{Face}). Smileys are those little @samp{:-)} symbols that people like to litter their messages with (@pxref{Smileys}). +Picons, on the other hand, reside on your own system, and Gnus will +try to match the headers to what you have (@pxref{Picons}). + All these functions are toggles---if the elements already exist, they'll be removed. @@ -9215,7 +9295,7 @@ To have all Vcards be ignored, you'd say something like this: @item gnus-article-loose-mime @vindex gnus-article-loose-mime -If non-@code{nil}, Gnus won't required the @samp{MIME-Version} header +If non-@code{nil}, Gnus won't require the @samp{MIME-Version} header before interpreting the message as a @acronym{MIME} message. This helps when reading messages from certain broken mail user agents. The default is @code{nil}. @@ -9579,11 +9659,11 @@ then ask Google if that fails: Most of the mail back ends support fetching by @code{Message-ID}, but do not do a particularly excellent job at it. That is, @code{nnmbox}, -@code{nnbabyl}, and @code{nnmaildir} are able to locate articles from -any groups, while @code{nnml}, @code{nnfolder}, and @code{nnimap} are -only able to locate articles that have been posted to the current group. -(Anything else would be too time consuming.) @code{nnmh} does not -support this at all. +@code{nnbabyl}, @code{nnmaildir}, @code{nnml}, are able to locate +articles from any groups, while @code{nnfolder}, and @code{nnimap} are +only able to locate articles that have been posted to the current +group. (Anything else would be too time consuming.) @code{nnmh} does +not support this at all. @node Alternative Approaches @@ -9765,10 +9845,10 @@ Variables related to the display are: @item gnus-tree-brackets @vindex gnus-tree-brackets This is used for differentiating between ``real'' articles and -``sparse'' articles. The format is +``sparse'' articles. The format is @example -((@var{real-open} . @var{real-close}) - (@var{sparse-open} . @var{sparse-close}) +((@var{real-open} . @var{real-close}) + (@var{sparse-open} . @var{sparse-close}) (@var{dummy-open} . @var{dummy-close})) @end example and the default is @code{((?[ . ?]) (?( . ?)) (?@{ . ?@}) (?< . ?>))}. @@ -10018,7 +10098,7 @@ suggestions you find reasonable. (Note that @menu * Summary Group Information:: Information oriented commands. * Searching for Articles:: Multiple article commands. -* Summary Generation Commands:: +* Summary Generation Commands:: * Really Various Summary Commands:: Those pesky non-conformant commands. @end menu @@ -10092,7 +10172,7 @@ variables and their default values (when the default values are not @code{nil}), that should be made global while the summary buffer is active. These variables can be used to set variables in the group parameters while still allowing them to affect operations done in -other buffers. For example: +other buffers. For example: @lisp (setq gnus-newsgroup-variables @@ -10167,7 +10247,7 @@ on this field, and a command to be executed if the match is made string, the match is done on the entire article. If given a prefix, search backward instead. -For instance, @kbd{& RET some.*string #} will put the process mark on +For instance, @kbd{& RET some.*string RET #} will put the process mark on all articles that have heads or bodies that match @samp{some.*string}. @item M-& @@ -10272,8 +10352,10 @@ group and return you to the group buffer. @table @kbd @item Z Z +@itemx Z Q @itemx q @kindex Z Z (Summary) +@kindex Z Q (Summary) @kindex q (Summary) @findex gnus-summary-exit @vindex gnus-summary-exit-hook @@ -10318,7 +10400,9 @@ Mark all articles as read and go to the next group (@code{gnus-summary-catchup-and-goto-next-group}). @item Z R +@itemx C-x C-s @kindex Z R (Summary) +@kindex C-x C-s (Summary) @findex gnus-summary-reselect-current-group Exit this group, and then enter it again (@code{gnus-summary-reselect-current-group}). If given a prefix, select @@ -10544,13 +10628,13 @@ manual (@pxref{Security, ,Security, message, Message Manual}). @vindex mm-verify-option Option of verifying signed parts. @code{never}, not verify; @code{always}, always verify; @code{known}, only verify known -protocols. Otherwise, ask user. +protocols. Otherwise, ask user. @item mm-decrypt-option @vindex mm-decrypt-option Option of decrypting encrypted parts. @code{never}, no decryption; @code{always}, always decrypt; @code{known}, only decrypt known -protocols. Otherwise, ask user. +protocols. Otherwise, ask user. @item mml1991-use @vindex mml1991-use @@ -10736,7 +10820,7 @@ variable, will be displayed in random order after all the headers listed in this You can hide further boring headers by setting @code{gnus-treat-hide-boring-headers} to @code{head}. What this function does depends on the @code{gnus-boring-article-headers} variable. It's a -list, but this list doesn't actually contain header names. Instead is +list, but this list doesn't actually contain header names. Instead it lists various @dfn{boring conditions} that Gnus can check and remove from sight. @@ -10748,21 +10832,21 @@ Remove all empty headers. Remove the @code{Followup-To} header if it is identical to the @code{Newsgroups} header. @item reply-to -Remove the @code{Reply-To} header if it lists the same address as the -@code{From} header, or if the @code{broken-reply-to} group parameter is -set. +Remove the @code{Reply-To} header if it lists the same addresses as +the @code{From} header, or if the @code{broken-reply-to} group +parameter is set. @item newsgroups Remove the @code{Newsgroups} header if it only contains the current group name. @item to-address Remove the @code{To} header if it only contains the address identical to -the current groups's @code{to-address} parameter. +the current group's @code{to-address} parameter. @item to-list Remove the @code{To} header if it only contains the address identical to -the current groups's @code{to-list} parameter. +the current group's @code{to-list} parameter. @item cc-list Remove the @code{CC} header if it only contains the address identical to -the current groups's @code{to-list} parameter. +the current group's @code{to-list} parameter. @item date Remove the @code{Date} header if the article is less than three days old. @@ -10829,7 +10913,7 @@ To avoid such kind of situation, gnus stops to use non-@code{nil} every-time, then you can push button in the article buffer when there are nobody else. -Also see @pxref{MIME Commands}. +Also @pxref{MIME Commands}. @node Customizing Articles @@ -10953,10 +11037,14 @@ is controlled by @code{gnus-body-boundary-delimiter}. @xref{Smileys}. -@item gnus-treat-display-xface (head) +@item gnus-treat-display-x-face (head) @xref{X-Face}. +@item gnus-treat-display-face (head) + +@xref{Face}. + @item gnus-treat-emphasize (t, head, integer) @item gnus-treat-fill-article (t, integer) @item gnus-treat-fill-long-lines (t, integer) @@ -11217,7 +11305,7 @@ on your setup (@pxref{Posting Server}). * Signing and encrypting:: How to compose secure messages. @end menu -Also see @pxref{Canceling and Superseding} for information on how to +Also @pxref{Canceling and Superseding} for information on how to remove articles you shouldn't have posted. @@ -11253,7 +11341,7 @@ press R anyway, this variable might be for you. If non-@code{nil}, Gnus also requests confirmation according to @code{gnus-confirm-mail-reply-to-news} when replying to mail. This is useful for treating mailing lists like newsgroups. - + @end table @@ -11433,9 +11521,8 @@ determined by the @code{gnus-message-archive-group} variable. This variable can be used to do the following: -@itemize @bullet -@item -a string +@table @asis +@item a string Messages will be saved in that group. Note that you can include a select method in the group name, then the @@ -11447,16 +11534,16 @@ has the default value shown above. Then setting messages are stored in @samp{nnfolder+archive:foo}, but if you use the value @code{"nnml:foo"}, then outgoing messages will be stored in @samp{nnml:foo}. -@item -a list of strings + +@item a list of strings Messages will be saved in all those groups. -@item -an alist of regexps, functions and forms + +@item an alist of regexps, functions and forms When a key ``matches'', the result is used. -@item -@code{nil} + +@item @code{nil} No message archiving will take place. This is the default. -@end itemize +@end table Let's illustrate: @@ -11589,7 +11676,7 @@ string, then Gnus will try to regexp match it against the group name. If it is the form @code{(header @var{match} @var{regexp})}, then Gnus will look in the original article for a header whose name is @var{match} and compare that @var{regexp}. @var{match} and -@var{regexp} are strings. (There original article is the one you are +@var{regexp} are strings. (The original article is the one you are replying or following up to. If you are not composing a reply or a followup, then there is nothing to match against.) If the @code{match} is a function symbol, that function will be called with @@ -11600,15 +11687,22 @@ said to @dfn{match}. Each style may contain an arbitrary amount of @dfn{attributes}. Each attribute consists of a @code{(@var{name} @var{value})} pair. The -attribute name can be one of @code{signature}, @code{signature-file}, -@code{x-face-file}, @code{address} (overriding -@code{user-mail-address}), @code{name} (overriding -@code{(user-full-name)}) or @code{body}. The attribute name can also -be a string or a symbol. In that case, this will be used as a header -name, and the value will be inserted in the headers of the article; if -the value is @code{nil}, the header name will be removed. If the -attribute name is @code{eval}, the form is evaluated, and the result -is thrown away. +attribute name can be one of: + +@itemize @bullet +@item @code{signature} +@item @code{signature-file} +@item @code{x-face-file} +@item @code{address}, overriding @code{user-mail-address} +@item @code{name}, overriding @code{(user-full-name)} +@item @code{body} +@end itemize + +The attribute name can also be a string or a symbol. In that case, +this will be used as a header name, and the value will be inserted in +the headers of the article; if the value is @code{nil}, the header +name will be removed. If the attribute name is @code{eval}, the form +is evaluated, and the result is thrown away. The attribute value can be a string (used verbatim), a function with zero arguments (the return value will be used), a variable (its value @@ -11815,52 +11909,52 @@ are in reply to encrypted messages. Gnus offers @code{gnus-message-replysignencrypted} (on by default) will sign automatically encrypted messages. -Instructing MML to perform security operations on a @acronym{MIME} part is -done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c -C-m c} key map for encryption, as follows. +Instructing @acronym{MML} to perform security operations on a +@acronym{MIME} part is done using the @kbd{C-c C-m s} key map for +signing and the @kbd{C-c C-m c} key map for encryption, as follows. @table @kbd @item C-c C-m s s -@kindex C-c C-m s s +@kindex C-c C-m s s (Message) @findex mml-secure-message-sign-smime Digitally sign current message using @acronym{S/MIME}. @item C-c C-m s o -@kindex C-c C-m s o +@kindex C-c C-m s o (Message) @findex mml-secure-message-sign-pgp Digitally sign current message using @acronym{PGP}. @item C-c C-m s p -@kindex C-c C-m s p +@kindex C-c C-m s p (Message) @findex mml-secure-message-sign-pgp Digitally sign current message using @acronym{PGP/MIME}. @item C-c C-m c s -@kindex C-c C-m c s +@kindex C-c C-m c s (Message) @findex mml-secure-message-encrypt-smime Digitally encrypt current message using @acronym{S/MIME}. @item C-c C-m c o -@kindex C-c C-m c o +@kindex C-c C-m c o (Message) @findex mml-secure-message-encrypt-pgp Digitally encrypt current message using @acronym{PGP}. @item C-c C-m c p -@kindex C-c C-m c p +@kindex C-c C-m c p (Message) @findex mml-secure-message-encrypt-pgpmime Digitally encrypt current message using @acronym{PGP/MIME}. @item C-c C-m C-n -@kindex C-c C-m C-n +@kindex C-c C-m C-n (Message) @findex mml-unsecure-message -Remove security related MML tags from message. +Remove security related @acronym{MML} tags from message. @end table @@ -12157,27 +12251,26 @@ If you're saving lots of articles in the cache by using persistent articles, you may want to create a virtual server to read the cache. First you need to add a new server. The @kbd{a} command does that. It -would probably be best to use @code{nnspool} to read the cache. You -could also use @code{nnml} or @code{nnmh}, though. +would probably be best to use @code{nnml} to read the cache. You +could also use @code{nnspool} or @code{nnmh}, though. -Type @kbd{a nnspool RET cache RET}. +Type @kbd{a nnml RET cache RET}. -You should now have a brand new @code{nnspool} virtual server called +You should now have a brand new @code{nnml} virtual server called @samp{cache}. You now need to edit it to have the right definitions. Type @kbd{e} to edit the server. You'll be entered into a buffer that will contain the following: @lisp -(nnspool "cache") +(nnml "cache") @end lisp Change that to: @lisp -(nnspool "cache" - (nnspool-spool-directory "~/News/cache/") - (nnspool-nov-directory "~/News/cache/") - (nnspool-active-file "~/News/cache/active")) +(nnml "cache" + (nnml-directory "~/News/cache/") + (nnml-active-file "~/News/cache/active")) @end lisp Type @kbd{C-c C-c} to return to the server buffer. If you now press @@ -12737,7 +12830,7 @@ Password to use when logging in on the intermediate host. @vindex nntp-via-envuser If non-@code{nil}, the intermediate @code{telnet} session (client and server both) will support the @code{ENVIRON} option and not prompt for -login name. This works for Solaris @code{telnet}, for instance. +login name. This works for Solaris @code{telnet}, for instance. @item nntp-via-shell-prompt @vindex nntp-via-shell-prompt @@ -12769,7 +12862,7 @@ Address of the intermediate host to connect to. @subsubsection Common Variables The following variables affect the behavior of all, or several of the -pre-made connection functions. When not specified, all functions are +pre-made connection functions. When not specified, all functions are affected. @table @code @@ -12907,7 +13000,7 @@ course. * Group Mail Splitting:: Use group customize to drive mail splitting. * Incorporating Old Mail:: What about the old mail you have? * Expiring Mail:: Getting rid of unwanted mail. -* Washing Mail:: Removing gruft from the mail you get. +* Washing Mail:: Removing cruft from the mail you get. * Duplicates:: Dealing with duplicated mail. * Not Reading Mail:: Using mail back ends for reading other files. * Choosing a Mail Back End:: Gnus can read a variety of mail formats. @@ -12937,7 +13030,7 @@ deleted? How awful! But, no, it means that old messages are @dfn{expired} according to some scheme or other. For news messages, the expire process is controlled by the news administrator; for mail, the expire process is controlled by -you. The expire process for mail is covered in depth in @pxref{Expiring +you. The expire process for mail is covered in depth in @ref{Expiring Mail}. What many Gnus users find, after using it a while for both news and @@ -13022,6 +13115,7 @@ Especially @pxref{Choosing a Mail Back End} and @pxref{Expiring Mail}. @subsection Splitting Mail @cindex splitting mail @cindex mail splitting +@cindex mail filtering (splitting) @vindex nnmail-split-methods The @code{nnmail-split-methods} variable says how the incoming mail is @@ -13109,7 +13203,7 @@ useful if you want to match articles based on the raw header data. @vindex nnmail-resplit-incoming By default, splitting is performed on all incoming messages. If you specify a @code{directory} entry for the variable @code{mail-sources} -@pxref{Mail Source Specifiers}, however, then splitting does +(@pxref{Mail Source Specifiers}), however, then splitting does @emph{not} happen by default. You can set the variable @code{nnmail-resplit-incoming} to a non-@code{nil} value to make splitting happen even in this case. (This variable has no effect on @@ -13524,11 +13618,11 @@ An example @acronym{IMAP} mail source: @end lisp @item webmail -Get mail from a webmail server, such as @uref{www.hotmail.com}, -@uref{webmail.netscape.com}, @uref{www.netaddress.com}, -@uref{mail.yahoo.com}. +Get mail from a webmail server, such as @uref{http://www.hotmail.com/}, +@uref{http://webmail.netscape.com/}, @uref{http://www.netaddress.com/}, +@uref{http://mail.yahoo.com/}. -NOTE: Webmail largely depends cookies. A "one-line-cookie" patch is +NOTE: Webmail largely depends on cookies. A "one-line-cookie" patch is required for url "4.0pre.46". WARNING: Mails may be lost. NO WARRANTY. @@ -13827,46 +13921,42 @@ Let's look at an example value of this variable first: "misc.misc") @end lisp -This variable has the format of a @dfn{split}. A split is a (possibly) -recursive structure where each split may contain other splits. Here are -the five possible split syntaxes: - -@enumerate - -@item -@samp{group}: If the split is a string, that will be taken as a group -name. Normal regexp match expansion will be done. See below for -examples. - -@item -@code{(@var{field} @var{value} @code{[-} @var{restrict} -@code{[@dots{}]}@code{]} @var{split})}: If the split is a list, the -first element of which is a string, then store the message as -specified by @var{split}, if header @var{field} (a regexp) contains -@var{value} (also a regexp). If @var{restrict} (yet another regexp) -matches some string after @var{field} and before the end of the -matched @var{value}, the @var{split} is ignored. If none of the -@var{restrict} clauses match, @var{split} is processed. - -@item -@code{(| @var{split}@dots{})}: If the split is a list, and the first -element is @code{|} (vertical bar), then process each @var{split} until -one of them matches. A @var{split} is said to match if it will cause -the mail message to be stored in one or more groups. - -@item -@code{(& @var{split}@dots{})}: If the split is a list, and the first -element is @code{&}, then process all @var{split}s in the list. +This variable has the format of a @dfn{split}. A split is a +(possibly) recursive structure where each split may contain other +splits. Here are the possible split syntaxes: -@item -@code{junk}: If the split is the symbol @code{junk}, then don't save -(i.e., delete) this message. Use with extreme caution. +@table @code -@item -@code{(: @var{function} @var{arg1} @var{arg2} @dots{})}: If the split is -a list, and the first element is @code{:}, then the second element will -be called as a function with @var{args} given as arguments. The -function should return a @var{split}. +@item group +If the split is a string, that will be taken as a group name. Normal +regexp match expansion will be done. See below for examples. + +@item (@var{field} @var{value} [- @var{restrict} [@dots{}] ] @var{split}) +If the split is a list, the first element of which is a string, then +store the message as specified by @var{split}, if header @var{field} +(a regexp) contains @var{value} (also a regexp). If @var{restrict} +(yet another regexp) matches some string after @var{field} and before +the end of the matched @var{value}, the @var{split} is ignored. If +none of the @var{restrict} clauses match, @var{split} is processed. + +@item (| @var{split} @dots{}) +If the split is a list, and the first element is @code{|} (vertical +bar), then process each @var{split} until one of them matches. A +@var{split} is said to match if it will cause the mail message to be +stored in one or more groups. + +@item (& @var{split} @dots{}) +If the split is a list, and the first element is @code{&}, then +process all @var{split}s in the list. + +@item junk +If the split is the symbol @code{junk}, then don't save (i.e., delete) +this message. Use with extreme caution. + +@item (: @var{function} @var{arg1} @var{arg2} @dots{}) +If the split is a list, and the first element is @samp{:}, then the +second element will be called as a function with @var{args} given as +arguments. The function should return a @var{split}. @cindex body split For instance, the following function could be used to split based on the @@ -13875,25 +13965,31 @@ body of the messages: @lisp (defun split-on-body () (save-excursion - (set-buffer " *nnmail incoming*") - (goto-char (point-min)) - (when (re-search-forward "Some.*string" nil t) - "string.group"))) -@end lisp - -The @samp{" *nnmail incoming*"} is narrowed to the message in question -when the @code{:} function is run. - -@item -@code{(! @var{func} @var{split})}: If the split is a list, and the -first element is @code{!}, then @var{split} will be processed, and -@var{func} will be called as a function with the result of @var{split} -as argument. @var{func} should return a split. + (save-restriction + (widen) + (goto-char (point-min)) + (when (re-search-forward "Some.*string" nil t) + "string.group")))) +@end lisp + +The buffer is narrowed to the message in question when @var{function} +is run. That's why @code{(widen)} needs to be called after +@code{save-excursion} and @code{save-restriction} in the example +above. Also note that with the nnimap backend, message bodies will +not be downloaded by default. You need to set +@code{nnimap-split-download-body} to t to do that (@pxref{Splitting in +IMAP}). + +@item (! @var{func} @var{split}) +If the split is a list, and the first element is @code{!}, then +@var{split} will be processed, and @var{func} will be called as a +function with the result of @var{split} as argument. @var{func} +should return a split. -@item -@code{nil}: If the split is @code{nil}, it is ignored. +@item nil +If the split is @code{nil}, it is ignored. -@end enumerate +@end table In these splits, @var{field} must match a complete field name. @var{value} must match a complete word according to the fundamental mode @@ -13902,11 +13998,22 @@ field names or words. In other words, all @var{value}'s are wrapped in @samp{\<} and @samp{\>} pairs. @vindex nnmail-split-abbrev-alist -@var{field} and @var{value} can also be Lisp symbols, in that case they -are expanded as specified by the variable -@code{nnmail-split-abbrev-alist}. This is an alist of cons cells, where -the @code{car} of a cell contains the key, and the @code{cdr} contains the associated -value. +@var{field} and @var{value} can also be Lisp symbols, in that case +they are expanded as specified by the variable +@code{nnmail-split-abbrev-alist}. This is an alist of cons cells, +where the @sc{car} of a cell contains the key, and the @sc{cdr} +contains the associated value. Predefined entries in +@code{nnmail-split-abbrev-alist} include: + +@table @code +@item from +Matches the @samp{From}, @samp{Sender} and @samp{Resent-From} fields. +@item to +Matches the @samp{To}, @samp{Cc}, @samp{Apparently-To}, +@samp{Resent-To} and @samp{Resent-Cc} fields. +@item any +Is the union of the @code{from} and @code{to} entries. +@end table @vindex nnmail-split-fancy-syntax-table @code{nnmail-split-fancy-syntax-table} is the syntax table in effect @@ -13928,6 +14035,25 @@ matched string will be substituted. Similarly, the elements @samp{\\1} up to @samp{\\9} will be substituted with the text matched by the groupings 1 through 9. +@vindex nnmail-split-fancy-match-partial-words +@code{nnmail-split-fancy-match-partial-words} controls whether partial +words are matched during fancy splitting. + +Normally, regular expressions given in @code{nnmail-split-fancy} are +implicitly surrounded by @code{\<...\>} markers, which are word +delimiters. If this variable is true, they are not implicitly +surrounded by anything. + +@example +(any "joe" "joemail") +@end example + +In this example, messages sent from @samp{joedavis@@foo.org} will +normally not be filed in @samp{joemail}. With +@code{nnmail-split-fancy-match-partial-words} set to t, however, the +match will happen. In effect, the requirement of a word boundary is +removed and instead the match becomes more like a grep. + @findex nnmail-split-fancy-with-parent @code{nnmail-split-fancy-with-parent} is a function which allows you to split followups into the same groups their parents are in. Sometimes @@ -13973,10 +14099,10 @@ messages goes into the new group. Also see the variable @code{nnmail-cache-ignore-groups} if you don't want certain groups to be recorded in the cache. For example, if all -outgoing messages are written to an `outgoing' group, you could set +outgoing messages are written to an ``outgoing'' group, you could set @code{nnmail-cache-ignore-groups} to match that group name. Otherwise, answers to all your messages would end up in the -`outgoing' group. +``outgoing'' group. @node Group Mail Splitting @@ -13987,31 +14113,31 @@ Otherwise, answers to all your messages would end up in the @findex gnus-group-split If you subscribe to dozens of mailing lists but you don't want to maintain mail splitting rules manually, group mail splitting is for you. -You just have to set @var{to-list} and/or @var{to-address} in group +You just have to set @code{to-list} and/or @code{to-address} in group parameters or group customization and set @code{nnmail-split-methods} to @code{gnus-group-split}. This splitting function will scan all groups for those parameters and split mail accordingly, i.e., messages posted -from or to the addresses specified in the parameters @var{to-list} or -@var{to-address} of a mail group will be stored in that group. +from or to the addresses specified in the parameters @code{to-list} or +@code{to-address} of a mail group will be stored in that group. Sometimes, mailing lists have multiple addresses, and you may want mail -splitting to recognize them all: just set the @var{extra-aliases} group +splitting to recognize them all: just set the @code{extra-aliases} group parameter to the list of additional addresses and it's done. If you'd -rather use a regular expression, set @var{split-regexp}. +rather use a regular expression, set @code{split-regexp}. All these parameters in a group will be used to create an @code{nnmail-split-fancy} split, in which the @var{field} is @samp{any}, the @var{value} is a single regular expression that matches -@var{to-list}, @var{to-address}, all of @var{extra-aliases} and all -matches of @var{split-regexp}, and the @var{split} is the name of the +@code{to-list}, @code{to-address}, all of @code{extra-aliases} and all +matches of @code{split-regexp}, and the @var{split} is the name of the group. @var{restrict}s are also supported: just set the -@var{split-exclude} parameter to a list of regular expressions. +@code{split-exclude} parameter to a list of regular expressions. If you can't get the right split to be generated using all these parameters, or you just need something fancier, you can set the -parameter @var{split-spec} to an @code{nnmail-split-fancy} split. In +parameter @code{split-spec} to an @code{nnmail-split-fancy} split. In this case, all other aforementioned parameters will be ignored by -@code{gnus-group-split}. In particular, @var{split-spec} may be set to +@code{gnus-group-split}. In particular, @code{split-spec} may be set to @code{nil}, in which case the group will be ignored by @code{gnus-group-split}. @@ -14020,7 +14146,7 @@ this case, all other aforementioned parameters will be ignored by by defining a single @code{&} fancy split containing one split for each group. If a message doesn't match any split, it will be stored in the group named in @code{gnus-group-split-default-catch-all-group}, unless -some group has @var{split-spec} set to @code{catch-all}, in which case +some group has @code{split-spec} set to @code{catch-all}, in which case that group is used as the catch-all group. Even though this variable is often used just to name a group, it may also be set to an arbitrarily complex fancy split (after all, a group name is a fancy split), and this @@ -14069,10 +14195,10 @@ splits like this: parameters will be scanned to generate the output split. @var{no-crosspost} can be used to disable cross-posting; in this case, a single @code{|} split will be output. @var{catch-all} is the fall back -fancy split, used like @var{gnus-group-split-default-catch-all-group}. -If @var{catch-all} is @code{nil}, or if @var{split-regexp} matches the +fancy split, used like @code{gnus-group-split-default-catch-all-group}. +If @var{catch-all} is @code{nil}, or if @code{split-regexp} matches the empty string in any selected group, no catch-all split will be issued. -Otherwise, if some group has @var{split-spec} set to @code{catch-all}, +Otherwise, if some group has @code{split-spec} set to @code{catch-all}, this group will override the value of the @var{catch-all} argument. @findex gnus-group-split-setup @@ -14186,9 +14312,9 @@ repeating one more time, with some spurious capitalizations: IF you do NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES. You do not have to mark articles as expirable by hand. Gnus provides -two features, called `auto-expire' and `total-expire', that can help you -with this. In a nutshell, `auto-expire' means that Gnus hits @kbd{E} -for you when you select an article. And `total-expire' means that Gnus +two features, called ``auto-expire'' and ``total-expire'', that can help you +with this. In a nutshell, ``auto-expire'' means that Gnus hits @kbd{E} +for you when you select an article. And ``total-expire'' means that Gnus considers all articles as expirable that are read. So, in addition to the articles marked @samp{E}, also the articles marked @samp{r}, @samp{R}, @samp{O}, @samp{K}, @samp{Y} and so on are considered @@ -14206,8 +14332,8 @@ advantage of auto-expire is that you get more marks to work with: for the articles that are supposed to stick around, you can still choose between tick and dormant and read marks. But with total-expire, you only have dormant and ticked to choose from. The advantage of -total-expire is that it works well with adaptive scoring @pxref{Adaptive -Scoring}. Auto-expire works with normal scoring but not with adaptive +total-expire is that it works well with adaptive scoring (@pxref{Adaptive +Scoring}). Auto-expire works with normal scoring but not with adaptive scoring. @vindex gnus-auto-expirable-newsgroups @@ -14322,9 +14448,9 @@ expire mail to groups according to the variable With this setup, any mail that has @code{IMPORTANT} in its Subject header and was sent in the year @code{YYYY} and month @code{MMM}, will -get expired to the group @code{nnfolder:IMPORTANT.YYYY.MMM}. If its +get expired to the group @code{nnfolder:IMPORTANT.YYYY.MMM}. If its From or To header contains the string @code{boss}, it will get expired -to @code{nnfolder:Work}. All other mail will get expired to +to @code{nnfolder:Work}. All other mail will get expired to @code{nnfolder:Archive-YYYY}. @vindex nnmail-keep-last-article @@ -14728,8 +14854,8 @@ files. @end table @findex nnml-generate-nov-databases -If your @code{nnml} groups and @acronym{NOV} files get totally out of whack, -you can do a complete update by typing @kbd{M-x +If your @code{nnml} groups and @acronym{NOV} files get totally out of +whack, you can do a complete update by typing @kbd{M-x nnml-generate-nov-databases}. This command will trawl through the entire @code{nnml} hierarchy, looking at each and every article, so it might take a while to complete. A better interface to this @@ -14743,9 +14869,10 @@ Commands}). @cindex mh-e mail spool @code{nnmh} is just like @code{nnml}, except that is doesn't generate -@acronym{NOV} databases and it doesn't keep an active file or marks file. -This makes @code{nnmh} a @emph{much} slower back end than @code{nnml}, -but it also makes it easier to write procmail scripts for. +@acronym{NOV} databases and it doesn't keep an active file or marks +file. This makes @code{nnmh} a @emph{much} slower back end than +@code{nnml}, but it also makes it easier to write procmail scripts +for. Virtual server settings: @@ -14764,11 +14891,11 @@ If non-@code{nil}, @code{nnmh} will read incoming mail. The default is @item nnmh-be-safe @vindex nnmh-be-safe If non-@code{nil}, @code{nnmh} will go to ridiculous lengths to make -sure that the articles in the folder are actually what Gnus thinks they -are. It will check date stamps and stat everything in sight, so +sure that the articles in the folder are actually what Gnus thinks +they are. It will check date stamps and stat everything in sight, so setting this to @code{t} will mean a serious slow-down. If you never -use anything but Gnus to read the @code{nnmh} articles, you do not have -to set this variable to @code{t}. The default is @code{nil}. +use anything but Gnus to read the @code{nnmh} articles, you do not +have to set this variable to @code{t}. The default is @code{nil}. @end table @@ -14780,40 +14907,40 @@ to set this variable to @code{t}. The default is @code{nil}. @code{nnmaildir} stores mail in the maildir format, with each maildir corresponding to a group in Gnus. This format is documented here: @uref{http://cr.yp.to/proto/maildir.html} and here: -@uref{http://www.qmail.org/man/man5/maildir.html}. nnmaildir also -stores extra information in the @file{.nnmaildir/} directory within a -maildir. +@uref{http://www.qmail.org/man/man5/maildir.html}. @code{nnmaildir} +also stores extra information in the @file{.nnmaildir/} directory +within a maildir. Maildir format was designed to allow concurrent deliveries and reading, without needing locks. With other back ends, you would have your mail delivered to a spool of some kind, and then you would configure Gnus to split mail from that spool into your groups. You -can still do that with nnmaildir, but the more common configuration is -to have your mail delivered directly to the maildirs that appear as -group in Gnus. +can still do that with @code{nnmaildir}, but the more common +configuration is to have your mail delivered directly to the maildirs +that appear as group in Gnus. -nnmaildir is designed to be perfectly reliable: @kbd{C-g} will never -corrupt its data in memory, and @code{SIGKILL} will never corrupt its -data in the filesystem. +@code{nnmaildir} is designed to be perfectly reliable: @kbd{C-g} will +never corrupt its data in memory, and @code{SIGKILL} will never +corrupt its data in the filesystem. -nnmaildir stores article marks and @acronym{NOV} data in each maildir. So you -can copy a whole maildir from one Gnus setup to another, and you will -keep your marks. +@code{nnmaildir} stores article marks and @acronym{NOV} data in each +maildir. So you can copy a whole maildir from one Gnus setup to +another, and you will keep your marks. Virtual server settings: @table @code @item directory -For each of your nnmaildir servers (it's very unlikely that you'd need -more than one), you need to create a directory and populate it with -maildirs or symlinks to maildirs (and nothing else; do not choose a -directory already used for other purposes). Each maildir will be -represented in Gnus as a newsgroup on that server; the filename of the -symlink will be the name of the group. Any filenames in the directory -starting with `.' are ignored. The directory is scanned when you -first start Gnus, and each time you type @kbd{g} in the group buffer; -if any maildirs have been removed or added, nnmaildir notices at these -times. +For each of your @code{nnmaildir} servers (it's very unlikely that +you'd need more than one), you need to create a directory and populate +it with maildirs or symlinks to maildirs (and nothing else; do not +choose a directory already used for other purposes). Each maildir +will be represented in Gnus as a newsgroup on that server; the +filename of the symlink will be the name of the group. Any filenames +in the directory starting with @samp{.} are ignored. The directory is +scanned when you first start Gnus, and each time you type @kbd{g} in +the group buffer; if any maildirs have been removed or added, +@code{nnmaildir} notices at these times. The value of the @code{directory} parameter should be a Lisp form which is processed by @code{eval} and @code{expand-file-name} to get @@ -14824,7 +14951,8 @@ don't worry---a simple string will work.) This parameter is not optional; you must specify it. I don't recommend using @code{"~/Mail"} or a subdirectory of it; several other parts of Gnus use that directory by default for various things, and may get confused -if nnmaildir uses it too. @code{"~/.nnmaildir"} is a typical value. +if @code{nnmaildir} uses it too. @code{"~/.nnmaildir"} is a typical +value. @item target-prefix This should be a Lisp form which is processed by @code{eval} and @@ -14832,12 +14960,12 @@ This should be a Lisp form which is processed by @code{eval} and server is opened; the resulting string is used until the server is closed. -When you create a group on an nnmaildir server, the maildir is created -with @code{target-prefix} prepended to its name, and a symlink +When you create a group on an @code{nnmaildir} server, the maildir is +created with @code{target-prefix} prepended to its name, and a symlink pointing to that maildir is created, named with the plain group name. So if @code{directory} is @code{"~/.nnmaildir"} and @code{target-prefix} is @code{"../maildirs/"}, then when you create -the group @code{foo}, nnmaildir will create +the group @code{foo}, @code{nnmaildir} will create @file{~/.nnmaildir/../maildirs/foo} as a maildir, and will create @file{~/.nnmaildir/foo} as a symlink pointing to @file{../maildirs/foo}. @@ -14874,20 +15002,21 @@ the conventional Gnus way, from @code{mail-sources} according to value is @code{nil}. Do @emph{not} use the same maildir both in @code{mail-sources} and as -an nnmaildir group. The results might happen to be useful, but that -would be by chance, not by design, and the results might be different -in the future. If your split rules create new groups, remember to -supply a @code{create-directory} server parameter. +an @code{nnmaildir} group. The results might happen to be useful, but +that would be by chance, not by design, and the results might be +different in the future. If your split rules create new groups, +remember to supply a @code{create-directory} server parameter. @end table @subsubsection Group parameters -nnmaildir uses several group parameters. It's safe to ignore all -this; the default behavior for nnmaildir is the same as the default -behavior for other mail back ends: articles are deleted after one week, -etc. Except for the expiry parameters, all this functionality is -unique to nnmaildir, so you can ignore it if you're just trying to -duplicate the behavior you already have with another back end. +@code{nnmaildir} uses several group parameters. It's safe to ignore +all this; the default behavior for @code{nnmaildir} is the same as the +default behavior for other mail back ends: articles are deleted after +one week, etc. Except for the expiry parameters, all this +functionality is unique to @code{nnmaildir}, so you can ignore it if +you're just trying to duplicate the behavior you already have with +another back end. If the value of any of these parameters is a vector, the first element is evaluated as a Lisp form and the result is used, rather than the @@ -14901,15 +15030,15 @@ quote and wrap the value in a vector when appropriate.) @table @code @item expire-age -An integer specifying the minimum age, in seconds, of an article before -it will be expired, or the symbol @code{never} to specify that +An integer specifying the minimum age, in seconds, of an article +before it will be expired, or the symbol @code{never} to specify that articles should never be expired. If this parameter is not set, -nnmaildir falls back to the usual +@code{nnmaildir} falls back to the usual @code{nnmail-expiry-wait}(@code{-function}) variables (overrideable by the @code{expiry-wait}(@code{-function}) group parameters. If you wanted a value of 3 days, you could use something like @code{[(* 3 24 -60 60)]}; nnmaildir will evaluate the form and use the result. An -article's age is measured starting from the article file's +60 60)]}; @code{nnmaildir} will evaluate the form and use the result. +An article's age is measured starting from the article file's modification time. Normally, this is the same as the article's delivery time, but editing an article makes it younger. Moving an article (other than via expiry) may also make an article younger. @@ -14921,30 +15050,30 @@ If this is set to a string such as a full Gnus group name, like @end example and if it is not the name of the same group that the parameter belongs to, then articles will be moved to the specified group during expiry -before being deleted. @emph{If this is set to an nnmaildir group, the -article will be just as old in the destination group as it was in the -source group.} So be careful with @code{expire-age} in the +before being deleted. @emph{If this is set to an @code{nnmaildir} +group, the article will be just as old in the destination group as it +was in the source group.} So be careful with @code{expire-age} in the destination group. If this is set to the name of the same group that the parameter belongs to, then the article is not expired at all. If you use the vector form, the first element is evaluated once for each article. So that form can refer to @code{nnmaildir-article-file-name}, etc., to decide where to put the -article. @emph{If this parameter is not set, nnmaildir does not fall -back to the @code{expiry-target} group parameter or the +article. @emph{If this parameter is not set, @code{nnmaildir} does +not fall back to the @code{expiry-target} group parameter or the @code{nnmail-expiry-target} variable.} @item read-only -If this is set to @code{t}, nnmaildir will treat the articles in this -maildir as read-only. This means: articles are not renamed from -@file{new/} into @file{cur/}; articles are only found in @file{new/}, -not @file{cur/}; articles are never deleted; articles cannot be -edited. @file{new/} is expected to be a symlink to the @file{new/} -directory of another maildir---e.g., a system-wide mailbox containing -a mailing list of common interest. Everything in the maildir outside -@file{new/} is @emph{not} treated as read-only, so for a shared -mailbox, you do still need to set up your own maildir (or have write -permission to the shared mailbox); your maildir just won't contain -extra copies of the articles. +If this is set to @code{t}, @code{nnmaildir} will treat the articles +in this maildir as read-only. This means: articles are not renamed +from @file{new/} into @file{cur/}; articles are only found in +@file{new/}, not @file{cur/}; articles are never deleted; articles +cannot be edited. @file{new/} is expected to be a symlink to the +@file{new/} directory of another maildir---e.g., a system-wide mailbox +containing a mailing list of common interest. Everything in the +maildir outside @file{new/} is @emph{not} treated as read-only, so for +a shared mailbox, you do still need to set up your own maildir (or +have write permission to the shared mailbox); your maildir just won't +contain extra copies of the articles. @item directory-files A function with the same interface as @code{directory-files}. It is @@ -14953,45 +15082,45 @@ group to find articles. The default is the function specified by the server's @code{directory-files} parameter. @item distrust-Lines: -If non-@code{nil}, nnmaildir will always count the lines of an +If non-@code{nil}, @code{nnmaildir} will always count the lines of an article, rather than use the @code{Lines:} header field. If @code{nil}, the header field will be used if present. @item always-marks -A list of mark symbols, such as -@code{['(read expire)]}. Whenever Gnus asks nnmaildir for -article marks, nnmaildir will say that all articles have these -marks, regardless of whether the marks stored in the filesystem -say so. This is a proof-of-concept feature that will probably be -removed eventually; it ought to be done in Gnus proper, or -abandoned if it's not worthwhile. +A list of mark symbols, such as @code{['(read expire)]}. Whenever +Gnus asks @code{nnmaildir} for article marks, @code{nnmaildir} will +say that all articles have these marks, regardless of whether the +marks stored in the filesystem say so. This is a proof-of-concept +feature that will probably be removed eventually; it ought to be done +in Gnus proper, or abandoned if it's not worthwhile. @item never-marks A list of mark symbols, such as @code{['(tick expire)]}. Whenever -Gnus asks nnmaildir for article marks, nnmaildir will say that no -articles have these marks, regardless of whether the marks stored in -the filesystem say so. @code{never-marks} overrides +Gnus asks @code{nnmaildir} for article marks, @code{nnmaildir} will +say that no articles have these marks, regardless of whether the marks +stored in the filesystem say so. @code{never-marks} overrides @code{always-marks}. This is a proof-of-concept feature that will probably be removed eventually; it ought to be done in Gnus proper, or abandoned if it's not worthwhile. @item nov-cache-size -An integer specifying the size of the @acronym{NOV} memory cache. To speed -things up, nnmaildir keeps @acronym{NOV} data in memory for a limited number of -articles in each group. (This is probably not worthwhile, and will -probably be removed in the future.) This parameter's value is noticed -only the first time a group is seen after the server is opened---i.e., -when you first start Gnus, typically. The @acronym{NOV} cache is never resized -until the server is closed and reopened. The default is an estimate -of the number of articles that would be displayed in the summary -buffer: a count of articles that are either marked with @code{tick} or -not marked with @code{read}, plus a little extra. +An integer specifying the size of the @acronym{NOV} memory cache. To +speed things up, @code{nnmaildir} keeps @acronym{NOV} data in memory +for a limited number of articles in each group. (This is probably not +worthwhile, and will probably be removed in the future.) This +parameter's value is noticed only the first time a group is seen after +the server is opened---i.e., when you first start Gnus, typically. +The @acronym{NOV} cache is never resized until the server is closed +and reopened. The default is an estimate of the number of articles +that would be displayed in the summary buffer: a count of articles +that are either marked with @code{tick} or not marked with +@code{read}, plus a little extra. @end table @subsubsection Article identification Articles are stored in the @file{cur/} subdirectory of each maildir. Each article file is named like @code{uniq:info}, where @code{uniq} -contains no colons. nnmaildir ignores, but preserves, the +contains no colons. @code{nnmaildir} ignores, but preserves, the @code{:info} part. (Other maildir readers typically use this part of the filename to store marks.) The @code{uniq} part uniquely identifies the article, and is used in various places in the @@ -15001,36 +15130,37 @@ available in the variable @code{nnmaildir-article-file-name} after you request the article in the summary buffer. @subsubsection NOV data -An article identified by @code{uniq} has its @acronym{NOV} data (used to -generate lines in the summary buffer) stored in +An article identified by @code{uniq} has its @acronym{NOV} data (used +to generate lines in the summary buffer) stored in @code{.nnmaildir/nov/uniq}. There is no @code{nnmaildir-generate-nov-databases} function. (There isn't much -need for it---an article's @acronym{NOV} data is updated automatically when the -article or @code{nnmail-extra-headers} has changed.) You can force -nnmaildir to regenerate the @acronym{NOV} data for a single article simply by -deleting the corresponding @acronym{NOV} file, but @emph{beware}: this will also -cause nnmaildir to assign a new article number for this article, which -may cause trouble with @code{seen} marks, the Agent, and the cache. +need for it---an article's @acronym{NOV} data is updated automatically +when the article or @code{nnmail-extra-headers} has changed.) You can +force @code{nnmaildir} to regenerate the @acronym{NOV} data for a +single article simply by deleting the corresponding @acronym{NOV} +file, but @emph{beware}: this will also cause @code{nnmaildir} to +assign a new article number for this article, which may cause trouble +with @code{seen} marks, the Agent, and the cache. @subsubsection Article marks An article identified by @code{uniq} is considered to have the mark @code{flag} when the file @file{.nnmaildir/marks/flag/uniq} exists. -When Gnus asks nnmaildir for a group's marks, nnmaildir looks for such -files and reports the set of marks it finds. When Gnus asks nnmaildir -to store a new set of marks, nnmaildir creates and deletes the -corresponding files as needed. (Actually, rather than create a new -file for each mark, it just creates hard links to -@file{.nnmaildir/markfile}, to save inodes.) +When Gnus asks @code{nnmaildir} for a group's marks, @code{nnmaildir} +looks for such files and reports the set of marks it finds. When Gnus +asks @code{nnmaildir} to store a new set of marks, @code{nnmaildir} +creates and deletes the corresponding files as needed. (Actually, +rather than create a new file for each mark, it just creates hard +links to @file{.nnmaildir/markfile}, to save inodes.) You can invent new marks by creating a new directory in @file{.nnmaildir/marks/}. You can tar up a maildir and remove it from your server, untar it later, and keep your marks. You can add and remove marks yourself by creating and deleting mark files. If you do -this while Gnus is running and your nnmaildir server is open, it's -best to exit all summary buffers for nnmaildir groups and type @kbd{s} -in the group buffer first, and to type @kbd{g} or @kbd{M-g} in the -group buffer afterwards. Otherwise, Gnus might not pick up the -changes, and might undo them. +this while Gnus is running and your @code{nnmaildir} server is open, +it's best to exit all summary buffers for @code{nnmaildir} groups and +type @kbd{s} in the group buffer first, and to type @kbd{g} or +@kbd{M-g} in the group buffer afterwards. Otherwise, Gnus might not +pick up the changes, and might undo them. @node Mail Folders @@ -15039,10 +15169,10 @@ changes, and might undo them. @cindex mbox folders @cindex mail folders -@code{nnfolder} is a back end for storing each mail group in a separate -file. Each file is in the standard Un*x mbox format. @code{nnfolder} -will add extra headers to keep track of article numbers and arrival -dates. +@code{nnfolder} is a back end for storing each mail group in a +separate file. Each file is in the standard Un*x mbox format. +@code{nnfolder} will add extra headers to keep track of article +numbers and arrival dates. @cindex self contained nnfolder servers @cindex marks @@ -15052,19 +15182,19 @@ similar, and later be able to restore them into Gnus (by adding the proper @code{nnfolder} server) and have all your marks be preserved. Marks for a group is usually stored in a file named as the mbox file with @code{.mrk} concatenated to it (but see -@code{nnfolder-marks-file-suffix}) within the @code{nnfolder} directory. -Individual @code{nnfolder} groups are also possible to backup, use -@kbd{G m} to restore the group (after restoring the backup into the -@code{nnfolder} directory). +@code{nnfolder-marks-file-suffix}) within the @code{nnfolder} +directory. Individual @code{nnfolder} groups are also possible to +backup, use @kbd{G m} to restore the group (after restoring the backup +into the @code{nnfolder} directory). Virtual server settings: @table @code @item nnfolder-directory @vindex nnfolder-directory -All the @code{nnfolder} mail boxes will be stored under this directory. -The default is the value of @code{message-directory} (whose default is -@file{~/Mail}) +All the @code{nnfolder} mail boxes will be stored under this +directory. The default is the value of @code{message-directory} +(whose default is @file{~/Mail}) @item nnfolder-active-file @vindex nnfolder-active-file @@ -15077,16 +15207,16 @@ Format}. The default is @file{~/Mail/newsgroups} @item nnfolder-get-new-mail @vindex nnfolder-get-new-mail -If non-@code{nil}, @code{nnfolder} will read incoming mail. The default -is @code{t} +If non-@code{nil}, @code{nnfolder} will read incoming mail. The +default is @code{t} @item nnfolder-save-buffer-hook @vindex nnfolder-save-buffer-hook @cindex backup files Hook run before saving the folders. Note that Emacs does the normal -backup renaming of files even with the @code{nnfolder} buffers. If you -wish to switch this off, you could say something like the following in -your @file{.emacs} file: +backup renaming of files even with the @code{nnfolder} buffers. If +you wish to switch this off, you could say something like the +following in your @file{.emacs} file: @lisp (defun turn-off-backup () @@ -15270,13 +15400,13 @@ filename is unrelated to the article number in Gnus. @code{nnmaildir} also stores the equivalent of @code{nnml}'s overview files in one file per article, so it uses about twice as many inodes as @code{nnml}. (Use @code{df -i} to see how plentiful your inode supply is.) If this slows -you down or takes up very much space, consider switching to +you down or takes up very much space, consider switching to @uref{http://www.namesys.com/, ReiserFS} or another non-block-structured file system. Since maildirs don't require locking for delivery, the maildirs you use as groups can also be the maildirs your mail is directly delivered to. -This means you can skip Gnus's mail splitting if your mail is already +This means you can skip Gnus' mail splitting if your mail is already organized into different mailboxes during delivery. A @code{directory} entry in @code{mail-sources} would have a similar effect, but would require one set of mailboxes for spooling deliveries (in mbox format, @@ -15339,7 +15469,7 @@ Gnus has been getting a bit of a collection of back ends for providing interfaces to these sources. @menu -* Archiving Mail:: +* Archiving Mail:: * Web Searches:: Creating groups from articles that match a string. * Slashdot:: Reading the Slashdot comments. * Ultimate:: The Ultimate Bulletin Board systems. @@ -15380,7 +15510,7 @@ To archive an entire @code{nnml}, @code{nnfolder}, or @code{nnmaildir} server, take a recursive copy of the server directory. There is no need to shut down Gnus, so archiving may be invoked by @code{cron} or similar. You restore the data by restoring the directory tree, and -adding a server definition pointing to that directory in Gnus. The +adding a server definition pointing to that directory in Gnus. The @ref{Article Backlog}, @ref{Asynchronous Fetching} and other things might interfere with overwriting data, so you may want to shut down Gnus before you restore the data. @@ -15390,7 +15520,7 @@ It is also possible to archive individual @code{nnml}, For @code{nnml} or @code{nnmaildir}, you copy all files in the group's directory. For @code{nnfolder} you need to copy both the base folder file itself (@file{FOO}, say), and the marks file (@file{FOO.mrk} in -this example). Restoring the group is done with @kbd{G m} from the Group +this example). Restoring the group is done with @kbd{G m} from the Group buffer. The last step makes Gnus notice the new directory. @code{nnmaildir} notices the new directory automatically, so @kbd{G m} is unnecessary in that case. @@ -15444,7 +15574,7 @@ Virtual server variables: @item nnweb-type @vindex nnweb-type What search engine type is being used. The currently supported types -are @code{google}, @code{dejanews}, and @code{gmane}. Note that +are @code{google}, @code{dejanews}, and @code{gmane}. Note that @code{dejanews} is an alias to @code{google}. @item nnweb-search @@ -15514,7 +15644,7 @@ command is the most handy tool (@pxref{Foreign Groups}). When following up to @code{nnslashdot} comments (or posting new comments), some light @acronym{HTML}izations will be performed. In particular, text quoted with @samp{> } will be quoted with -@code{blockquote} instead, and signatures will have @code{br} added to +@samp{blockquote} instead, and signatures will have @samp{br} added to the end of each line. Other than that, you can just write @acronym{HTML} directly into the message buffer. Note that Slashdot filters out some @acronym{HTML} forms. @@ -15545,20 +15675,18 @@ Where @code{nnslashdot} will store its files. The default is @item nnslashdot-active-url @vindex nnslashdot-active-url -The @sc{url} format string that will be used to fetch the information on -news articles and comments. The default is@* +The @acronym{URL} format string that will be used to fetch the +information on news articles and comments. The default is@* @samp{http://slashdot.org/search.pl?section=&min=%d}. @item nnslashdot-comments-url @vindex nnslashdot-comments-url -The @sc{url} format string that will be used to fetch comments. The -default is -@samp{http://slashdot.org/comments.pl?sid=%s&threshold=%d&commentsort=%d&mode=flat&startat=%d}. +The @acronym{URL} format string that will be used to fetch comments. @item nnslashdot-article-url @vindex nnslashdot-article-url -The @sc{url} format string that will be used to fetch the news article. The -default is +The @acronym{URL} format string that will be used to fetch the news +article. The default is @samp{http://slashdot.org/article.pl?sid=%s&mode=nocomment}. @item nnslashdot-threshold @@ -15586,7 +15714,7 @@ information Gnus needs to keep groups updated. The easiest way to get started with @code{nnultimate} is to say something like the following in the group buffer: @kbd{B nnultimate RET -http://www.tcj.com/messboard/ubbcgi/ RET}. (Substitute the @sc{url} +http://www.tcj.com/messboard/ubbcgi/ RET}. (Substitute the @acronym{URL} (not including @samp{Ultimate.cgi} or the like at the end) for a forum you're interested in; there's quite a list of them on the Ultimate web site.) Then subscribe to the groups you're interested in from the @@ -15644,14 +15772,22 @@ The password for your account on the web server. @cindex nnrss @cindex RSS -Some sites have RDF site summary (RSS) -@uref{http://purl.org/rss/1.0/spec}. It has a quite regular and nice -interface, and it's possible to get the information Gnus needs to keep -groups updated. +Some web sites have an RDF Site Summary (@acronym{RSS}). +@acronym{RSS} is a format for summarizing headlines from news related +sites (such as BBC or CNN). But basically anything list-like can be +presented as an @acronym{RSS} feed: weblogs, changelogs or recent +changes to a wiki (e.g. @url{http://cliki.net/recent-changes.rdf}). + +@acronym{RSS} has a quite regular and nice interface, and it's +possible to get the information Gnus needs to keep groups updated. -The easiest way to get started with @code{nnrss} is to say something -like the following in the group buffer: @kbd{B nnrss RET RET}, then -subscribe groups. +@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. + +An easy way to get started with @code{nnrss} is to say something like +the following in the group buffer: @kbd{B nnrss RET y}, then +subscribe to groups. The following @code{nnrss} variables can be altered: @@ -15661,6 +15797,13 @@ The following @code{nnrss} variables can be altered: The directory where @code{nnrss} stores its files. The default is @file{~/News/rss/}. +@item nnrss-use-local +@vindex nnrss-use-local +@findex nnrss-generate-download-script +If you set @code{nnrss-use-local} to @code{t}, @code{nnrss} will read +the feeds from local files in @code{nnrss-directory}. You can use +the command @code{nnrss-generate-download-script} to generate a +download script using @command{wget}. @end table The following code may be helpful, if you want to show the description in @@ -15758,9 +15901,10 @@ entry in @code{gnus-secondary-select-methods}. With this, Gnus will manipulate mails stored on the @acronym{IMAP} server. This is the kind of usage explained in this section. -A server configuration in @file{~/.gnus.el} with a few @acronym{IMAP} servers -might look something like the following. (Note that for @acronym{TLS}/@acronym{SSL}, you -need external programs and libraries, see below.) +A server configuration in @file{~/.gnus.el} with a few @acronym{IMAP} +servers might look something like the following. (Note that for +@acronym{TLS}/@acronym{SSL}, you need external programs and libraries, +see below.) @lisp (setq gnus-secondary-select-methods @@ -15838,8 +15982,9 @@ Example server specification: @vindex nnimap-stream The type of stream used to connect to your server. By default, nnimap will detect and automatically use all of the below, with the exception -of @acronym{TLS}/@acronym{SSL}. (@acronym{IMAP} over @acronym{TLS}/@acronym{SSL} is being replaced by STARTTLS, which -can be automatically detected, but it's not widely deployed yet.) +of @acronym{TLS}/@acronym{SSL}. (@acronym{IMAP} over +@acronym{TLS}/@acronym{SSL} is being replaced by STARTTLS, which can +be automatically detected, but it's not widely deployed yet.) Example server specification: @@ -15852,10 +15997,10 @@ Please note that the value of @code{nnimap-stream} is a symbol! @itemize @bullet @item -@dfn{gssapi:} Connect with GSSAPI (usually Kerberos 5). Requires the +@dfn{gssapi:} Connect with GSSAPI (usually Kerberos 5). Requires the @samp{gsasl} or @samp{imtest} program. @item -@dfn{kerberos4:} Connect with Kerberos 4. Requires the @samp{imtest} program. +@dfn{kerberos4:} Connect with Kerberos 4. Requires the @samp{imtest} program. @item @dfn{starttls:} Connect via the STARTTLS extension (similar to @acronym{TLS}/@acronym{SSL}). Requires the external library @samp{starttls.el} and program @@ -15898,11 +16043,11 @@ tried. @vindex imap-ssl-program For @acronym{SSL} connections, the OpenSSL program is available from -@uref{http://www.openssl.org/}. OpenSSL was formerly known as SSLeay, +@uref{http://www.openssl.org/}. OpenSSL was formerly known as SSLeay, and nnimap support it too---although the most recent versions of SSLeay, 0.9.x, are known to have serious bugs making it -useless. Earlier versions, especially 0.8.x, of SSLeay are known to -work. The variable @code{imap-ssl-program} contain parameters to pass +useless. Earlier versions, especially 0.8.x, of SSLeay are known to +work. The variable @code{imap-ssl-program} contain parameters to pass to OpenSSL/SSLeay. @vindex imap-shell-program @@ -15927,30 +16072,30 @@ Please note that the value of @code{nnimap-authenticator} is a symbol! @itemize @bullet @item -@dfn{gssapi:} GSSAPI (usually kerberos 5) authentication. Requires +@dfn{gssapi:} GSSAPI (usually kerberos 5) authentication. Requires external program @code{gsasl} or @code{imtest}. @item -@dfn{kerberos4:} Kerberos 4 authentication. Requires external program +@dfn{kerberos4:} Kerberos 4 authentication. Requires external program @code{imtest}. @item -@dfn{digest-md5:} Encrypted username/password via DIGEST-MD5. Requires +@dfn{digest-md5:} Encrypted username/password via DIGEST-MD5. Requires external library @code{digest-md5.el}. @item @dfn{cram-md5:} Encrypted username/password via CRAM-MD5. @item @dfn{login:} Plain-text username/password via LOGIN. @item -@dfn{anonymous:} Login as `anonymous', supplying your email address as password. +@dfn{anonymous:} Login as ``anonymous'', supplying your email address as password. @end itemize @item nnimap-expunge-on-close @cindex expunging @vindex nnimap-expunge-on-close -Unlike Parmenides the @acronym{IMAP} designers has decided that things that -doesn't exist actually does exist. More specifically, @acronym{IMAP} has +Unlike Parmenides the @acronym{IMAP} designers have decided things that +don't exist actually do exist. More specifically, @acronym{IMAP} has this concept of marking articles @code{Deleted} which doesn't actually delete them, and this (marking them @code{Deleted}, that is) is what -nnimap does when you delete a article in Gnus (with @kbd{B DEL} or +nnimap does when you delete an article in Gnus (with @kbd{B DEL} or similar). Since the articles aren't really removed when we mark them with the @@ -15983,10 +16128,10 @@ articles or not. @vindex nnimap-importantize-dormant If non-@code{nil} (the default), marks dormant articles as ticked (as -well), for other @acronym{IMAP} clients. Within Gnus, dormant articles will +well), for other @acronym{IMAP} clients. Within Gnus, dormant articles will naturally still (only) be marked as dormant. This is to make dormant articles stand out, just like ticked articles, in other @acronym{IMAP} -clients. (In other words, Gnus has two ``Tick'' marks and @acronym{IMAP} +clients. (In other words, Gnus has two ``Tick'' marks and @acronym{IMAP} has only one.) Probably the only reason for frobing this would be if you're trying @@ -16013,7 +16158,7 @@ UID set and the second @code{%s} is replaced by a date. Probably the only useful value to change this to is @code{"UID %s NOT SENTSINCE %s"}, which makes nnimap use the Date: in -messages instead of the internal article date. See section 6.4.4 of +messages instead of the internal article date. See section 6.4.4 of RFC 2060 for more information on valid strings. @item nnimap-authinfo-file @@ -16039,6 +16184,7 @@ Courier 1.7.1 did. * Editing IMAP ACLs:: Limiting/enabling other users access to a mailbox. * Expunging mailboxes:: Equivalent of a ``compress mailbox'' button. * A note on namespaces:: How to (not) use @acronym{IMAP} namespace in Gnus. +* Debugging IMAP:: What to do when things don't work. @end menu @@ -16047,14 +16193,18 @@ Courier 1.7.1 did. @subsection Splitting in IMAP @cindex splitting imap mail -Splitting is something Gnus users has loved and used for years, and now +Splitting is something Gnus users have loved and used for years, and now the rest of the world is catching up. Yeah, dream on, not many -@acronym{IMAP} server has server side splitting and those that have splitting -seem to use some non-standard protocol. This means that @acronym{IMAP} -support for Gnus has to do it's own splitting. +@acronym{IMAP} servers have server side splitting and those that have +splitting seem to use some non-standard protocol. This means that +@acronym{IMAP} support for Gnus has to do its own splitting. And it does. +(Incidentally, people seem to have been dreaming on, and Sieve has +gaining a market share and is supported by several IMAP servers. +Fortunately, Gnus support it too, @xref{Sieve Commands}.) + Here are the variables of interest: @table @code @@ -16110,7 +16260,7 @@ This will put all articles from the nnimap mailing list into mailbox INBOX.nnimap, all articles containing MAKE MONEY in the Subject: line into INBOX.junk and everything else in INBOX.private. -The first string may contain `\\1' forms, like the ones used by +The first string may contain @samp{\\1} forms, like the ones used by replace-match to insert sub-expressions from the matched text. For instance: @@ -16174,7 +16324,7 @@ split, it is a string and the default is @samp{UNSEEN UNDELETED}. This might be useful if you use another @acronym{IMAP} client to read mail in your inbox but would like Gnus to split all articles in the inbox -regardless of readedness. Then you might change this to +regardless of readedness. Then you might change this to @samp{UNDELETED}. @item nnimap-split-fancy @@ -16184,7 +16334,7 @@ regardless of readedness. Then you might change this to It's possible to set @code{nnimap-split-rule} to @code{nnmail-split-fancy} if you want to use fancy -splitting. @xref{Fancy Mail Splitting}. +splitting. @xref{Fancy Mail Splitting}. However, to be able to have different fancy split rules for nnmail and nnimap back ends you can set @code{nnimap-split-rule} to @@ -16254,7 +16404,7 @@ article is copied instead of appended (that is, uploaded again). @cindex editing imap acls @cindex Access Control Lists @cindex Editing @acronym{IMAP} ACLs -@kindex G l +@kindex G l (Group) @findex gnus-group-nnimap-edit-acl ACL stands for Access Control List. ACLs are used in @acronym{IMAP} for @@ -16262,8 +16412,8 @@ limiting (or enabling) other users access to your mail boxes. Not all @acronym{IMAP} servers support this, this function will give an error if it doesn't. -To edit a ACL for a mailbox, type @kbd{G l} -(@code{gnus-group-edit-nnimap-acl}) and you'll be presented with a ACL +To edit an ACL for a mailbox, type @kbd{G l} +(@code{gnus-group-edit-nnimap-acl}) and you'll be presented with an ACL editing window with detailed instructions. Some possible uses: @@ -16286,7 +16436,7 @@ INBOX.mailbox). @cindex expunge @cindex manual expunging -@kindex G x +@kindex G x (Group) @findex gnus-group-nnimap-expunge If you're using the @code{never} setting of @code{nnimap-expunge-on-close}, @@ -16338,6 +16488,40 @@ See the UoW IMAPD documentation for the @code{#driver.*/} prefix for more information on how to use the prefixes. They are a power tool and should be used only if you are sure what the effects are. +@node Debugging IMAP +@subsection Debugging IMAP +@cindex IMAP debugging +@cindex protocol dump (IMAP) + +@acronym{IMAP} is a complex protocol, more so than @acronym{NNTP} or +@acronym{POP3}. Implementation bugs are not unlikely, and we do our +best to fix them right away. If you encounter odd behaviour, chances +are that either the server or Gnus is buggy. + +If you are familiar with network protocols in general, you will +probably be able to extract some clues from the protocol dump of the +exchanges between Gnus and the server. Even if you are not familiar +with network protocols, when you include the protocol dump in +@acronym{IMAP}-related bug reports you are helping us with data +critical to solving the problem. Therefore, we strongly encourage you +to include the protocol dump when reporting IMAP bugs in Gnus. + + +@vindex imap-log +Because the protocol dump, when enabled, generates lots of data, it is +disabled by default. You can enable it by setting @code{imap-log} as +follows: + +@lisp +(setq imap-log t) +@end lisp + +This instructs the @code{imap.el} package to log any exchanges with +the server. The log is stored in the buffer @samp{*imap-log*}. Look +for error messages, which sometimes are tagged with the keyword +@code{BAD} - but when submitting a bug, make sure to include all the +data. + @node Other Sources @section Other Sources @@ -17088,7 +17272,7 @@ All marks in the virtual group will stick to the articles in the component groups. So if you tick an article in a virtual group, the article will also be ticked in the component group from whence it came. (And vice versa---marks from the component groups will also be -shown in the virtual group.). To create an empty virtual group, run +shown in the virtual group.). To create an empty virtual group, run @kbd{G V} (@code{gnus-group-make-empty-virtual}) in the group buffer and edit the method regexp with @kbd{M-e} (@code{gnus-group-edit-group-method}) @@ -17159,10 +17343,10 @@ inherited. @cindex nnkiboze @cindex kibozing -@dfn{Kibozing} is defined by @acronym{oed} as ``grepping through (parts of) -the news feed''. @code{nnkiboze} is a back end that will do this for -you. Oh joy! Now you can grind any @acronym{NNTP} server down to a halt -with useless requests! Oh happiness! +@dfn{Kibozing} is defined by the @acronym{OED} as ``grepping through +(parts of) the news feed''. @code{nnkiboze} is a back end that will +do this for you. Oh joy! Now you can grind any @acronym{NNTP} server +down to a halt with useless requests! Oh happiness! @kindex G k (Group) To create a kibozed group, use the @kbd{G k} command in the group @@ -17196,10 +17380,11 @@ and they can be foreign. No restrictions. @vindex nnkiboze-directory The generation of an @code{nnkiboze} group means writing two files in -@code{nnkiboze-directory}, which is @file{~/News/} by default. One -contains the @acronym{NOV} header lines for all the articles in the group, -and the other is an additional @file{.newsrc} file to store information -on what groups have been searched through to find component articles. +@code{nnkiboze-directory}, which is @file{~/News/kiboze/} by default. +One contains the @acronym{NOV} header lines for all the articles in +the group, and the other is an additional @file{.newsrc} file to store +information on what groups have been searched through to find +component articles. Articles marked as read in the @code{nnkiboze} group will have their @acronym{NOV} lines removed from the @acronym{NOV} file. @@ -17239,6 +17424,7 @@ Of course, to use it as such, you have to learn a few new commands. * Agent Basics:: How it all is supposed to work. * Agent Categories:: How to tell the Gnus Agent what to download. * Agent Commands:: New commands for all the buffers. +* Agent Visuals:: Ways that the agent may effect your summary buffer. * Agent as Cache:: The Agent is a big cache too. * Agent Expiry:: How to make old articles go away. * Agent Regeneration:: How to recover from lost connections and other accidents. @@ -17267,6 +17453,29 @@ connected to the net continuously. @dfn{Downloading} means fetching things from the net to your local machine. @dfn{Uploading} is doing the opposite. +You know that Gnus gives you all the opportunity you'd ever want for +shooting yourself in the foot. Some people call it flexibility. Gnus +is also customizable to a great extent, which means that the user has a +say on how Gnus behaves. Other newsreaders might unconditionally shoot +you in your foot, but with Gnus, you have a choice! + +Gnus is never really in plugged or unplugged state. Rather, it applies +that state to each server individually. This means that some servers +can be plugged while others can be unplugged. Additionally, some +servers can be ignored by the Agent altogether (which means that +they're kinda like plugged always). + +So when you unplug the Agent and then wonder why is Gnus opening a +connection to the Net, the next step to do is to look whether all +servers are agentized. If there is an unagentized server, you found +the culprit. + +Another thing is the @dfn{offline} state. Sometimes, servers aren't +reachable. When Gnus notices this, it asks you whether you want the +server to be switched to offline state. If you say yes, then the +server will behave somewhat as if it was unplugged, except that Gnus +will ask you whether you want to switch it back online again. + Let's take a typical Gnus session using the Agent. @itemize @bullet @@ -17281,15 +17490,15 @@ already fetched while in this mode. You then decide to see whether any new news has arrived. You connect your machine to the net (using PPP or whatever), and then hit @kbd{J j} to make Gnus become @dfn{plugged} and use @kbd{g} to check for new mail -as usual. To check for new mail in unplugged mode, see (@pxref{Mail +as usual. To check for new mail in unplugged mode (@pxref{Mail Source Specifiers}). @item -You can then read the new news immediately, or you can download the news -onto your local machine. If you want to do the latter, you press @kbd{g} -to check if there are any new news and then @kbd{J -s} to fetch all the eligible articles in all the groups. (To let Gnus -know which articles you want to download, @pxref{Agent Categories}.) +You can then read the new news immediately, or you can download the +news onto your local machine. If you want to do the latter, you press +@kbd{g} to check if there are any new news and then @kbd{J s} to fetch +all the eligible articles in all the groups. (To let Gnus know which +articles you want to download, @pxref{Agent Categories}). @item After fetching the articles, you press @kbd{J j} to make Gnus become @@ -17312,14 +17521,14 @@ Agent. Go to the server buffer (@kbd{^} in the group buffer) and press @kbd{J a} on the server (or servers) that you wish to have covered by the Agent (@pxref{Server Agent Commands}), or @kbd{J r} on automatically added servers you do not wish to have covered by the Agent. By default, -all @code{nntp} and @code{nnimap} groups in @code{gnus-select-method} and +all @code{nntp} and @code{nnimap} servers in @code{gnus-select-method} and @code{gnus-secondary-select-methods} are agentized. @item Decide on download policy. It's fairly simple once you decide whether you are going to use agent categories, topic parameters, and/or group parameters to implement your policy. If you're new to gnus, it -is probably best to start with a category @xref{Agent Categories}. +is probably best to start with a category, @xref{Agent Categories}. Both topic parameters (@pxref{Topic Parameters}) and agent categories (@pxref{Agent Categories}) provide for setting a policy that applies @@ -17362,7 +17571,7 @@ Since you can set agent parameters in several different places we have a rule to decide which source to believe. This rule specifies that the parameter sources are checked in the following order: group parameters, topic parameters, agent category, and finally customizable -variables. So you can mix all of these sources to produce a wide range +variables. So you can mix all of these sources to produce a wide range of behavior, just don't blame me if you don't remember where you put your settings. @@ -17381,6 +17590,7 @@ category, and a number of optional parameters that override the customizable variables. The complete list of agent parameters are listed below. +@cindex Agent Parameters @table @code @item gnus-agent-cat-name The name of the category. @@ -17419,6 +17629,18 @@ an integer that overrides the value of @item gnus-agent-cat-length-when-long an integer that overrides the value of @code{gnus-agent-long-article}. + +@c @item gnus-agent-cat-disable-undownloaded-faces +@c a symbol indicating whether the summary buffer should @emph{not} display +@c undownloaded articles using the gnus-summary-*-undownloaded-face +@c faces. The symbol nil will enable the use of undownloaded faces while +@c all other symbols disable them. + +@item gnus-agent-cat-enable-undownloaded-faces +a symbol indicating whether the summary buffer should display +undownloaded articles using the gnus-summary-*-undownloaded-face +faces. The symbol nil will disable the use of undownloaded faces while +all other symbols enable them. @end table The name of a category can not be changed once the category has been @@ -17559,7 +17781,7 @@ just don't give a damn. The above predicates apply to @emph{all} the groups which belong to the category. However, if you wish to have a specific predicate for an individual group within a category, or you're just too lazy to set up a -new category, you can enter a group's individual predicate in it's group +new category, you can enter a group's individual predicate in its group parameters like so: @lisp @@ -17600,7 +17822,7 @@ three forms: @item Score rule -This has the same syntax as a normal gnus score file except only a +This has the same syntax as a normal Gnus score file except only a subset of scoring keywords are available as mentioned above. example: @@ -17908,7 +18130,7 @@ Remove the downloading mark from the article @findex gnus-agent-toggle-mark Toggle whether to download the article (@code{gnus-agent-toggle-mark}). The download mark is @samp{%} by -default. +default. @item J c @kindex J c (Agent Summary) @@ -17918,7 +18140,7 @@ Mark all articles as read (@code{gnus-agent-catchup}) that are neither cached, d @item J S @kindex J S (Agent Summary) @findex gnus-agent-fetch-group -Download all eligible (See @pxref{Agent Categories}) articles in this group. +Download all eligible (@pxref{Agent Categories}) articles in this group. (@code{gnus-agent-fetch-group}). @item J s @@ -17955,6 +18177,68 @@ Agent (@code{gnus-agent-remove-server}). @end table +@node Agent Visuals +@subsection Agent Visuals + +If you open a summary while unplugged and, Gnus knows from the group's +active range that there are more articles than the headers currently +stored in the Agent, you may see some articles whose subject looks +something like @samp{[Undownloaded article #####]}. These are +placeholders for the missing headers. Aside from setting a mark, +there is not much that can be done with one of these placeholders. +When Gnus finally gets a chance to fetch the group's headers, the +placeholders will automatically be replaced by the actual headers. +You can configure the summary buffer's maneuvering to skip over the +placeholders if you care (See @code{gnus-auto-goto-ignores}). + +While it may be obvious to all, the only headers and articles +available while unplugged are those headers and articles that were +fetched into the Agent while previously plugged. To put it another +way, "If you forget to fetch something while plugged, you might have a +less than satisfying unplugged session". For this reason, the Agent +adds two visual effects to your summary buffer. These effects display +the download status of each article so that you always know which +articles will be available when unplugged. + +The first visual effect is the @samp{%O} spec. If you customize +@code{gnus-summary-line-format} to include this specifier, you will add +a single character field that indicates an article's download status. +Articles that have been fetched into either the Agent or the Cache, +will display @code{gnus-downloaded-mark} (defaults to @samp{+}). All +other articles will display @code{gnus-undownloaded-mark} (defaults to +@samp{-}). If you open a group that has not been agentized, a space +(@samp{ }) will be displayed. + +The second visual effect are the undownloaded faces. The faces, there +are three indicating the article's score (low, normal, high), seem to +result in a love/hate response from many Gnus users. The problem is +that the face selection is controlled by a list of condition tests and +face names (See @code{gnus-summary-highlight}). Each condition is +tested in the order in which it appears in the list so early +conditions have precedence over later conditions. All of this means +that, if you tick an undownloaded article, the article will continue +to be displayed in the undownloaded face rather than the ticked face. + +If you use the Agent as a cache (to avoid downloading the same article +each time you visit it or to minimize your connection time), the +undownloaded face will probably seem like a good idea. The reason +being that you do all of our work (marking, reading, deleting) with +downloaded articles so the normal faces always appear. + +For occasional Agent users, the undownloaded faces may appear to be an +absolutely horrible idea. The issue being that, since most of their +articles have not been fetched into the Agent, most of the normal +faces will be obscured by the undownloaded faces. If this is your +situation, you have two choices available. First, you can completely +disable the undownload faces by customizing +@code{gnus-summary-highlight} to delete the three cons-cells that +refer to the @code{gnus-summary-*-undownloaded-face} faces. Second, if +you prefer to take a more fine-grained approach, you may set the +@code{agent-disable-undownloaded-faces} group parameter to t. This +parameter, like all other agent parameters, may be set on an Agent +Category (@pxref{Agent Categories}), a Group Topic (@pxref{Topic +Parameters}), or an individual group (@pxref{Group Parameters}). + @node Agent as Cache @subsection Agent as Cache @@ -17986,7 +18270,7 @@ sense if you are using a nntp or nnimap back end. @cindex Gnus agent expiry @cindex expiry -The Agent back end, @code{nnagent}, doesn't handle expiry. Well, at +The Agent back end, @code{nnagent}, doesn't handle expiry. Well, at least it doesn't handle it like other back ends. Instead, there are special @code{gnus-agent-expire} and @code{gnus-agent-expire-group} commands that will expire all read articles that are older than @@ -17996,7 +18280,7 @@ efficient, and it's not a particularly good idea to interrupt them (with @kbd{C-g} or anything else) once you've started one of them. Note that other functions, e.g. @code{gnus-request-expire-articles}, -might run @code{gnus-agent-expire} for you to keep the agent +might run @code{gnus-agent-expire} for you to keep the agent synchronized with the group. The agent parameter @code{agent-enable-expiration} may be used to @@ -18095,7 +18379,7 @@ Creating/deleting nnimap groups when unplugged. Technical note: the synchronization algorithm does not work by ``pushing'' all local flags to the server, but rather incrementally update the server view of flags by changing only those flags that were changed by -the user. Thus, if you set one flag on a article, quit the group and +the user. Thus, if you set one flag on an article, quit the group and re-select the group and remove the flag; the flag will be set and removed from the server when you ``synchronize''. The queued flag operations can be found in the per-server @code{flags} file in the Agent @@ -18169,8 +18453,13 @@ read. The default is t. @item gnus-agent-consider-all-articles @vindex gnus-agent-consider-all-articles If @code{gnus-agent-consider-all-articles} is non-@code{nil}, the -agent will fetch all missing headers. When @code{nil}, the agent will -fetch only new headers. The default is @code{nil}. +agent will let the agent predicate decide whether articles need to be +downloaded or not, for all articles. When @code{nil}, the default, +the agent will only let the predicate decide whether unread articles +are downloaded or not. If you enable this, you may also want to look +into the agent expiry settings (@pxref{Category Variables}), so that +the agent doesn't download articles which the agent will later expire, +over and over again. @item gnus-agent-max-fetch-size @vindex gnus-agent-max-fetch-size @@ -18188,7 +18477,7 @@ see any cycling. @item gnus-server-unopen-status @vindex gnus-server-unopen-status -Perhaps not a Agent variable, but closely related to the Agent, this +Perhaps not an Agent variable, but closely related to the Agent, this variable says what will happen if Gnus cannot open a server. If the Agent is enabled, the default, @code{nil}, makes Gnus ask the user whether to deny the server or whether to unplug the agent. If the @@ -18198,7 +18487,7 @@ is only valid if the Agent is used. @item gnus-auto-goto-ignores @vindex gnus-auto-goto-ignores -Another variable that isn't a Agent variable, yet so closely related +Another variable that isn't an Agent variable, yet so closely related that most will look for it here, this variable tells the summary buffer how to maneuver around undownloaded (only headers stored in the agent) and unfetched (neither article nor headers stored) articles. @@ -18209,6 +18498,18 @@ have not been fetched), @code{always-undownloaded} (maneuvering always ignores articles that have not been fetched), @code{unfetched} (maneuvering ignores articles whose headers have not been fetched). +@item gnus-agent-auto-agentize-methods +@vindex gnus-agent-auto-agentize-methods +If you have never used the Agent before (or more technically, if +@file{~/News/agent/lib/servers} does not exist), Gnus will +automatically agentize a few servers for you. This variable control +which backends should be auto-agentized. It is typically only useful +to agentize remote backends. The auto-agentizing has the same effect +as running @kbd{J a} on the servers (@pxref{Server Agent Commands}). +If the file exist, you must manage the servers manually by adding or +removing them, this variable is only applicable the first time you +start Gnus. The default is @samp{(nntp nnimap)}. + @end table @@ -18289,7 +18590,7 @@ may ask: @code{gnus-agent-fetch-selected-article} to @code{gnus-select-article-hook}. -@item If I read an article while plugged, and the article already exists in +@item If I read an article while plugged, and the article already exists in the Agent, will it get downloaded once more? @strong{No}, unless @code{gnus-agent-cache} is @code{nil}. @@ -18384,9 +18685,9 @@ Display the score of the current article @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) @@ -18832,8 +19133,8 @@ Anyway, if you'd like to dig into it yourself, here's an example: (eval (ding))) @end lisp -This example demonstrates most score file elements. For a different -approach, see @pxref{Advanced Scoring}. +This example demonstrates most score file elements. @xref{Advanced +Scoring}, for a different approach. Even though this looks much like Lisp code, nothing here is actually @code{eval}ed. The Lisp reader is used to read this form, though, so it @@ -18858,7 +19159,7 @@ final ``header'' you can score on is @code{Followup}. These score entries will result in new score entries being added for all follow-ups to articles that matches these score entries. -Following this key is a arbitrary number of score entries, where each +Following this key is an arbitrary number of score entries, where each score entry has one to four elements. @enumerate @@ -18905,11 +19206,13 @@ Just as for the standard string overview headers, if you are using gnus-extra-headers, you can score on these headers' values. In this case, there is a 5th element in the score entry, being the name of the header to be scored. The following entry is useful in your -@file{all.SCORE} file in case of spam attacks from a single origin host, -if your @acronym{NNTP} server tracks NNTP-Posting-Host in overviews: +@file{all.SCORE} file in case of spam attacks from a single origin +host, if your @acronym{NNTP} server tracks @samp{NNTP-Posting-Host} in +overviews: @lisp -("111.222.333.444" -1000 nil s "NNTP-Posting-Host") +("111.222.333.444" -1000 nil s + "NNTP-Posting-Host") @end lisp @item Lines, Chars @@ -19124,8 +19427,8 @@ Type @kbd{M-x gnus-score-mode} to use this mode. @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 @@ -19446,10 +19749,10 @@ that Gnus has to request every single article from the back end to find matches. This takes a long time in big groups. Now, there's not much you can do about this for news groups, but for -mail groups, you have greater control. In the @pxref{To From -Newsgroups} section of the manual, it's explained in greater detail what -this mechanism does, but here's a cookbook example for @code{nnml} on -how to allow scoring on the @samp{To} and @samp{Cc} headers. +mail groups, you have greater control. In @ref{To From Newsgroups}, +it's explained in greater detail what this mechanism does, but here's +a cookbook example for @code{nnml} on how to allow scoring on the +@samp{To} and @samp{Cc} headers. Put the following in your @file{~/.gnus.el} file. @@ -19733,6 +20036,9 @@ before. @section GroupLens @cindex GroupLens +@sc{Note:} Unfortunately the GroupLens system seems to have shut down, +so this section is mostly of historical interest. + @uref{http://www.cs.umn.edu/Research/GroupLens/, GroupLens} is a collaborative filtering system that helps you work together with other people to find the quality news articles out of the huge volume of @@ -19748,9 +20054,6 @@ of a prediction, what they thought of the article. You can use this prediction to help you decide whether or not you want to read the article. -@sc{Note:} Unfortunately the GroupLens system seems to have shut down, -so this section is mostly of historical interest. - @menu * Using GroupLens:: How to make Gnus use GroupLens. * Rating Articles:: Letting GroupLens know how you rate articles. @@ -19854,7 +20157,7 @@ from GroupLens in one of three ways controlled by the variable @vindex gnus-grouplens-override-scoring There are three ways to display predictions in grouplens. You may choose to have the GroupLens scores contribute to, or override the -regular gnus scoring mechanism. override is the default; however, some +regular Gnus scoring mechanism. override is the default; however, some people prefer to see the Gnus scores plus the grouplens scores. To get the separate scoring behavior you need to set @code{gnus-grouplens-override-scoring} to @code{'separate}. To have the @@ -20123,16 +20426,21 @@ definition of that function: @lisp (defun gnus-decay-score (score) - "Decay SCORE. -This is done according to `gnus-score-decay-constant' + "Decay SCORE according to `gnus-score-decay-constant' and `gnus-score-decay-scale'." - (floor - (- score - (* (if (< score 0) 1 -1) - (min (abs score) - (max gnus-score-decay-constant - (* (abs score) - gnus-score-decay-scale))))))) + (let ((n (- score + (* (if (< score 0) -1 1) + (min (abs score) + (max gnus-score-decay-constant + (* (abs score) + gnus-score-decay-scale))))))) + (if (and (featurep 'xemacs) + ;; XEmacs' floor can handle only the floating point + ;; number below the half of the maximum integer. + (> (abs n) (lsh -1 -2))) + (string-to-number + (car (split-string (number-to-string n) "\\."))) + (floor n)))) @end lisp @vindex gnus-score-decay-scale @@ -20194,6 +20502,7 @@ four days, Gnus will decay the scores four times, for instance. * Image Enhancements:: Modern versions of Emacs/XEmacs can display images. * Fuzzy Matching:: What's the big fuzz? * Thwarting Email Spam:: A how-to on avoiding unsolicited commercial email. +* Other modes:: Interaction with other modes. * Various Various:: Things that are really various. @end menu @@ -21169,7 +21478,7 @@ Emacs is idle: (gnus-demon-scan-pgp 60 t) @end lisp -This @var{time} parameter and than @var{idle} parameter work together +This @var{time} parameter and that @var{idle} parameter work together in a strange, but wonderful fashion. Basically, if @var{idle} is @code{nil}, then the function will be called every @var{time} minutes. @@ -21261,7 +21570,7 @@ by default. @item gnus-nocem-groups @vindex gnus-nocem-groups Gnus will look for NoCeM messages in the groups in this list. The -default is +default is @lisp ("news.lists.filters" "news.admin.net-abuse.bulletins" "alt.nocem.misc" "news.admin.net-abuse.announce") @@ -21480,139 +21789,14 @@ support images yet.}, is able to display pictures and stuff, so Gnus has taken advantage of that. @menu -* Picons:: How to display pictures of what you're reading. -* Smileys:: Show all those happy faces the way they were meant to be shown. * X-Face:: Display a funky, teensy black-and-white image. +* Face:: Display a funkier, teensier colored image. +* Smileys:: Show all those happy faces the way they were meant to be shown. +* Picons:: How to display pictures of what you're reading. * XVarious:: Other XEmacsy Gnusey variables. @end menu -@node Picons -@subsection Picons - -@iftex -@iflatex -\include{picons} -@end iflatex -@end iftex - -So@dots{} You want to slow down your news reader even more! This is a -good way to do so. Its also a great way to impress people staring -over your shoulder as you read news. - -What are Picons? To quote directly from the Picons Web site: - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@quotation -@dfn{Picons} is short for ``personal icons''. They're small, -constrained images used to represent users and domains on the net, -organized into databases so that the appropriate image for a given -e-mail address can be found. Besides users and domains, there are picon -databases for Usenet newsgroups and weather forecasts. The picons are -in either monochrome @code{XBM} format or color @code{XPM} and -@code{GIF} formats. -@end quotation - -@vindex gnus-picon-databases -For instructions on obtaining and installing the picons databases, -point your Web browser at -@uref{http://www.cs.indiana.edu/picons/ftp/index.html}. - -If you are using Debian GNU/Linux, saying @samp{apt-get install -picons.*} will install the picons where Gnus can find them. - -To enable displaying picons, simply make sure that -@code{gnus-picon-databases} points to the directory containing the -Picons databases. - -The following variables offer control over where things are located. - -@table @code - -@item gnus-picon-databases -@vindex gnus-picon-databases -The location of the picons database. This is a list of directories -containing the @file{news}, @file{domains}, @file{users} (and so on) -subdirectories. Defaults to @code{("/usr/lib/picon" -"/usr/local/faces")}. - -@item gnus-picon-news-directories -@vindex gnus-picon-news-directories -List of subdirectories to search in @code{gnus-picon-databases} for -newsgroups faces. @code{("news")} is the default. - -@item gnus-picon-user-directories -@vindex gnus-picon-user-directories -List of subdirectories to search in @code{gnus-picon-databases} for user -faces. @code{("users" "usenix" "local" "misc")} is the default. - -@item gnus-picon-domain-directories -@vindex gnus-picon-domain-directories -List of subdirectories to search in @code{gnus-picon-databases} for -domain name faces. Defaults to @code{("domains")}. Some people may -want to add @samp{"unknown"} to this list. - -@item gnus-picon-file-types -@vindex gnus-picon-file-types -Ordered list of suffixes on picon file names to try. Defaults to -@code{("xpm" "gif" "xbm")} minus those not built-in your Emacs. - -@end table - -@node Smileys -@subsection Smileys -@cindex smileys - -@iftex -@iflatex -\gnusfig{-3cm}{0.5cm}{\epsfig{figure=ps/BigFace,height=20cm}} -\input{smiley} -@end iflatex -@end iftex - -@dfn{Smiley} is a package separate from Gnus, but since Gnus is -currently the only package that uses Smiley, it is documented here. - -In short---to use Smiley in Gnus, put the following in your -@file{~/.gnus.el} file: - -@lisp -(setq gnus-treat-display-smileys t) -@end lisp - -Smiley maps text smiley faces---@samp{:-)}, @samp{8-)}, @samp{:-(} and -the like---to pictures and displays those instead of the text smiley -faces. The conversion is controlled by a list of regexps that matches -text and maps that to file names. - -@vindex smiley-regexp-alist -The alist used is specified by the @code{smiley-regexp-alist} -variable. The first item in each element is the regexp to be matched; -the second element is the regexp match group that is to be replaced by -the picture; and the third element is the name of the file to be -displayed. - -The following variables customize where Smiley will look for these -files: - -@table @code - -@item smiley-data-directory -@vindex smiley-data-directory -Where Smiley will look for smiley faces files. - -@item gnus-smiley-file-types -@vindex gnus-smiley-file-types -List of suffixes on smiley file names to try. - -@end table - - @node X-Face @subsection X-Face @cindex x-face @@ -21624,7 +21808,6 @@ readers. @cindex x-face @findex gnus-article-display-x-face -@findex gnus-article-x-face-command @vindex gnus-article-x-face-command @vindex gnus-article-x-face-too-ugly @iftex @@ -21708,8 +21891,175 @@ Using the last function would be something like this: @end lisp -@node XVarious -@subsection Various XEmacs Variables +@node Face +@subsection Face +@cindex face + +@c #### FIXME: faces and x-faces'implementations should really be harmonized. + +@code{Face} headers are essentially a funkier version of @code{X-Face} +ones. They describe a 48x48 pixel colored image that's supposed to +represent the author of the message. + +@cindex face +@findex gnus-article-display-face +The contents of a @code{Face} header must be a base64 encoded PNG image. +See @uref{http://quimby.gnus.org/circus/face/} for the precise +specifications. + +Gnus provides a few convenience functions and variables to allow +easier insertion of Face headers in outgoing messages. + +@findex gnus-convert-png-to-face +@code{gnus-convert-png-to-face} takes a 48x48 PNG image, no longer than +726 bytes long, and converts it to a face. + +@findex gnus-face-from-file +@vindex gnus-convert-image-to-face-command +@code{gnus-face-from-file} takes a JPEG file as the parameter, and then +converts the file to Face format by using the +@code{gnus-convert-image-to-face-command} shell command. + +Here's how you would typically use this function. Put something like the +following in your @file{~/.gnus.el} file: + +@lisp +(setq message-required-news-headers + (nconc message-required-news-headers + (list '(Face . (lambda () + (gnus-face-from-file "~/face.jpg")))))) +@end lisp + + +@node Smileys +@subsection Smileys +@cindex smileys + +@iftex +@iflatex +\gnusfig{-3cm}{0.5cm}{\epsfig{figure=ps/BigFace,height=20cm}} +\input{smiley} +@end iflatex +@end iftex + +@dfn{Smiley} is a package separate from Gnus, but since Gnus is +currently the only package that uses Smiley, it is documented here. + +In short---to use Smiley in Gnus, put the following in your +@file{~/.gnus.el} file: + +@lisp +(setq gnus-treat-display-smileys t) +@end lisp + +Smiley maps text smiley faces---@samp{:-)}, @samp{8-)}, @samp{:-(} and +the like---to pictures and displays those instead of the text smiley +faces. The conversion is controlled by a list of regexps that matches +text and maps that to file names. + +@vindex smiley-regexp-alist +The alist used is specified by the @code{smiley-regexp-alist} +variable. The first item in each element is the regexp to be matched; +the second element is the regexp match group that is to be replaced by +the picture; and the third element is the name of the file to be +displayed. + +The following variables customize where Smiley will look for these +files: + +@table @code + +@item smiley-data-directory +@vindex smiley-data-directory +Where Smiley will look for smiley faces files. + +@item gnus-smiley-file-types +@vindex gnus-smiley-file-types +List of suffixes on smiley file names to try. + +@end table + + +@node Picons +@subsection Picons + +@iftex +@iflatex +\include{picons} +@end iflatex +@end iftex + +So@dots{} You want to slow down your news reader even more! This is a +good way to do so. It's also a great way to impress people staring +over your shoulder as you read news. + +What are Picons? To quote directly from the Picons Web site: + +@iftex +@iflatex +\margindex{} +@end iflatex +@end iftex + +@quotation +@dfn{Picons} is short for ``personal icons''. They're small, +constrained images used to represent users and domains on the net, +organized into databases so that the appropriate image for a given +e-mail address can be found. Besides users and domains, there are picon +databases for Usenet newsgroups and weather forecasts. The picons are +in either monochrome @code{XBM} format or color @code{XPM} and +@code{GIF} formats. +@end quotation + +@vindex gnus-picon-databases +For instructions on obtaining and installing the picons databases, +point your Web browser at +@uref{http://www.cs.indiana.edu/picons/ftp/index.html}. + +If you are using Debian GNU/Linux, saying @samp{apt-get install +picons.*} will install the picons where Gnus can find them. + +To enable displaying picons, simply make sure that +@code{gnus-picon-databases} points to the directory containing the +Picons databases. + +The following variables offer control over where things are located. + +@table @code + +@item gnus-picon-databases +@vindex gnus-picon-databases +The location of the picons database. This is a list of directories +containing the @file{news}, @file{domains}, @file{users} (and so on) +subdirectories. Defaults to @code{("/usr/lib/picon" +"/usr/local/faces")}. + +@item gnus-picon-news-directories +@vindex gnus-picon-news-directories +List of subdirectories to search in @code{gnus-picon-databases} for +newsgroups faces. @code{("news")} is the default. + +@item gnus-picon-user-directories +@vindex gnus-picon-user-directories +List of subdirectories to search in @code{gnus-picon-databases} for user +faces. @code{("users" "usenix" "local" "misc")} is the default. + +@item gnus-picon-domain-directories +@vindex gnus-picon-domain-directories +List of subdirectories to search in @code{gnus-picon-databases} for +domain name faces. Defaults to @code{("domains")}. Some people may +want to add @samp{"unknown"} to this list. + +@item gnus-picon-file-types +@vindex gnus-picon-file-types +Ordered list of suffixes on picon file names to try. Defaults to +@code{("xpm" "gif" "xbm")} minus those not built-in your Emacs. + +@end table + + +@node XVarious +@subsection Various XEmacs Variables @table @code @item gnus-xmas-glyph-directory @@ -21817,8 +22167,8 @@ This is annoying. Here's what you can do about it. * Anti-Spam Basics:: Simple steps to reduce the amount of spam. * SpamAssassin:: How to use external anti-spam tools. * Hashcash:: Reduce spam by burning CPU time. -* Filtering Spam Using The Spam ELisp Package:: -* Filtering Spam Using Statistics with spam-stat:: +* Filtering Spam Using The Spam ELisp Package:: +* Filtering Spam Using Statistics with spam-stat:: @end menu @node The problem of spam @@ -21832,13 +22182,14 @@ This is annoying. Here's what you can do about it. 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 @@ -21851,34 +22202,39 @@ through the TMDA system. Another problem with TMDA is that it 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, -@code{N} systems around the world agree that a machine @samp{X} in -China, Ghana, or California is sending out spam e-mail, and these -@code{N} systems enter @samp{X} or the spam e-mail from @samp{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 @code{N} systems. +@var{N} systems around the world agree that a machine @var{X} in +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 @@ -21887,7 +22243,19 @@ words or 3-word combinations thrown into the mix. Statistical 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 @@ -21915,14 +22283,12 @@ Then put the following split rule in @code{nnmail-split-fancy} (@pxref{Fancy Mail Splitting}): @lisp -( - ... +(... (to "larsi@@trym.ifi.uio.no" - (| ("subject" "re:.*" "misc") - ("references" ".*@@.*" "misc") - "spam")) - ... -) + (| ("subject" "re:.*" "misc") + ("references" ".*@@.*" "misc") + "spam")) + ...) @end lisp This says that all mail to this address is suspect, but if it has a @@ -21950,17 +22316,12 @@ check for legitimate mail, though. If you feel like being a good net citizen, you can even send off complaints to the proper authorities on each unsolicited commercial email---at your leisure. -If you are also a lazy net citizen, you will probably prefer complaining -automatically with the @file{gnus-junk.el} package, available FOR FREE -at @* @uref{http://stud2.tuwien.ac.at/~e9426626/gnus-junk.html}. -Since most e-mail spam is sent automatically, this may reconcile the -cosmic balance somewhat. - This works for me. It allows people an easy way to contact me (they can just press @kbd{r} in the usual way), and I'm not bothered at all with 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 @@ -21969,29 +22330,35 @@ to non-existent domains is yucky, in my opinion. @cindex Vipul's Razor @cindex DCC -The days where the hints in the previous section was sufficient in -avoiding spam is coming to an end. There are many tools out there +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 fortunately most of these tools seem to have similar interfaces. Even 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 -Specifiers}) follows. +Specifiers}) follow. @lisp (setq mail-sources '((file :prescript "formail -bs spamassassin < /var/mail/%u") (pop :user "jrl" :server "pophost" - :postscript "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t"))) + :postscript + "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t"))) @end lisp -Once you managed to process your incoming spool somehow, thus making -the mail contain e.g. a header indicating it is spam, you are ready to +Once you manage to process your incoming spool somehow, thus making +the mail contain e.g.@: a header indicating it is spam, you are ready to filter it out. Using normal split methods (@pxref{Splitting Mail}): @lisp @@ -22017,16 +22384,18 @@ call the external tools during splitting. Example fancy split method: ...)) (defun kevin-spamassassin () (save-excursion - (let ((buf (or (get-buffer " *nnmail incoming*") - (get-buffer " *nnml move*")))) - (if (not buf) - (progn (message "Oops, cannot find message buffer") nil) - (set-buffer buf) - (if (eq 1 (call-process-region (point-min) (point-max) - "spamc" nil nil nil "-c")) - "spam"))))) + (save-restriction + (widen) + (if (eq 1 (call-process-region (point-min) (point-max) + "spamc" nil nil nil "-c")) + "spam")))) @end lisp +Note that with the nnimap backend, message bodies will not be +downloaded by default. You need to set +@code{nnimap-split-download-body} to t to do that (@pxref{Splitting in +IMAP}). + That is about it. As some spam is likely to get through anyway, you might want to have a nifty function to call when you happen to read spam. And here is the nifty function: @@ -22046,7 +22415,7 @@ spam. And here is the nifty function: A novel technique to fight spam is to require senders to do something costly for each message they send. This has the obvious drawback that -you cannot rely on that everyone in the world uses this technique, +you cannot rely on everyone in the world using this technique, since it is not part of the Internet standards, but it may be useful in smaller communities. @@ -22055,7 +22424,7 @@ work only because the tools are constantly maintained and updated as 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 @@ -22065,7 +22434,7 @@ one of them separately. The ``something costly'' is to burn CPU time, more specifically to compute a hash collision up to a certain number of bits. The resulting hashcash cookie is inserted in a @samp{X-Hashcash:} -header. For more details, and for the external application +header. For more details, and for the external application @code{hashcash} you need to install to use this feature, see @uref{http://www.cypherspace.org/~adam/hashcash/}. Even more information can be found at @uref{http://www.camram.org/}. @@ -22078,8 +22447,8 @@ like: (add-hook 'message-send-hook 'mail-add-payment) @end lisp -The @code{hashcash.el} library can be found in the Gnus development -contrib directory. or at +The @file{hashcash.el} library can be found in the Gnus development +contrib directory or at @uref{http://users.actrix.gen.nz/mycroft/hashcash.el}. You will need to set up some additional variables as well: @@ -22118,14 +22487,32 @@ a useful contribution, however. @cindex spam filtering @cindex spam -The idea behind @code{spam.el} is to have a control center for spam detection -and filtering in Gnus. To that end, @code{spam.el} does two things: it -filters incoming mail, and it analyzes mail known to be spam or ham. -@emph{Ham} is the name used throughout @code{spam.el} to indicate +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 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. -So, what happens when you load @code{spam.el}? First of all, you get -the following keyboard commands: +First of all, you @strong{must} run the function +@code{spam-initialize} to autoload @code{spam.el} and to install the +@code{spam.el} hooks. There is one exception: if you use the +@code{spam-use-stat} (@pxref{spam-stat spam filtering}) setting, you +should turn it on before @code{spam-initialize}: + +@example +(setq spam-use-stat t) ;; if needed +(spam-initialize) +@end example + +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 @@ -22156,10 +22543,237 @@ You must have Bogofilter installed for that command to work properly. @end table -Also, when you load @code{spam.el}, you will be able to customize its +Also, when you load @file{spam.el}, you will be able to customize its 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 the +@code{spam-process-destination} is nil, the spam is marked as +expired, which is usually the right thing to do. + +If spam can not be moved - because of a read-only backend such as NNTP, +for example, it will be copied. + +If a ham mail is found in a ham group, as determined 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 ham can not be moved - because of a read-only backend such as NNTP, +for example, it will be copied. + +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 @@ -22170,6 +22784,10 @@ that later similar mail will also be considered non-spam. Spam 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 @@ -22194,13 +22812,13 @@ group. If you have seen a message, had it marked as spam, then unmarked it, it won't be marked as spam when you enter the group thereafter. You can disable that behavior, so all unread messages will get the @samp{$} mark, if you set the -@code{spam-mark-only-unseen-as-spam} parameter to nil. You should -remove the @samp{$} mark when you are in the group summary buffer for -every message that is not spam after all. To remove the @samp{$} -mark, you can use @kbd{M-u} to ``unread'' the article, or @kbd{d} for -declaring it read the non-spam way. When you leave a group, all -spam-marked (@samp{$}) articles are sent to a spam processor which -will study them as spam samples. +@code{spam-mark-only-unseen-as-spam} parameter to @code{nil}. You +should remove the @samp{$} mark when you are in the group summary +buffer for every message that is not spam after all. To remove the +@samp{$} mark, you can use @kbd{M-u} to ``unread'' the article, or +@kbd{d} for declaring it read the non-spam way. When you leave a +group, all spam-marked (@samp{$}) articles are sent to a spam +processor which will study them as spam samples. Messages may also be deleted in various other ways, and unless @code{ham-marks} group parameter gets overridden below, marks @samp{R} @@ -22214,13 +22832,19 @@ should then adjust the @code{ham-marks} group parameter. @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 @@ -22240,15 +22864,38 @@ determined by either the @code{ham-process-destination} group parameter or a match in the @code{gnus-ham-process-destinations} variable, which is a list of regular expressions matched with group names (it's easiest to customize this variable with -@code{customize-variable gnus-ham-process-destinations}). The ultimate -location is a group name. If the @code{ham-process-destination} -parameter is not set, ham articles are left in place. If the +@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 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. + +If ham can not be moved - because of a read-only backend such as NNTP, +for example, it will be copied. + +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. +@vindex spam-process-ham-in-spam-groups +By default the variable @code{spam-process-ham-in-spam-groups} is +@code{nil}. Set it to @code{t} if you want ham found in spam groups +to be processed. Normally this is not done, you are expected instead +to send your ham to a ham group and process it there. + +@vindex spam-process-ham-in-nonham-groups +By default the variable @code{spam-process-ham-in-nonham-groups} is +@code{nil}. Set it to @code{t} if you want ham found in non-ham (spam +or unclassified) groups to be processed. Normally this is not done, +you are expected instead to send your ham to a ham group and process +it there. + @vindex gnus-spam-process-destinations When you leave a @emph{ham} or @emph{unclassified} group, all @strong{spam} articles are moved to a location determined by either @@ -22256,111 +22903,213 @@ the @code{spam-process-destination} group parameter or a match in the @code{gnus-spam-process-destinations} variable, which is a list of regular expressions matched with group names (it's easiest to customize this variable with @code{customize-variable -gnus-spam-process-destinations}). The ultimate location is a group -name. If the @code{spam-process-destination} parameter is not set, -the spam articles are only expired. +gnus-spam-process-destinations}). Each newsgroup specification has +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. 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. + +If spam can not be moved - because of a read-only backend such as NNTP, +for example, it will be copied. + +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. + +@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 -To use the @code{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}: +@subsubheading Ted's setup +From Ted Zlatanov . @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. +;; for gnus-registry-split-fancy-with-parent and spam autodetection +;; see gnus-registry.el for more information +(gnus-registry-initialize) +(spam-initialize) + +;; I like control-S for marking spam +(define-key gnus-summary-mode-map "\C-s" 'gnus-summary-mark-as-spam) + +(setq + spam-log-to-registry t ;; for spam autodetection + spam-use-BBDB t + spam-use-regex-headers t ; catch X-Spam-Flag (SpamAssassin) + ;; all groups with "spam" in the name contain spam + gnus-spam-newsgroup-contents '(("spam" gnus-group-spam-classification-spam)) + ;; see documentation for these + spam-move-spam-nonspam-groups-only nil + spam-mark-only-unseen-as-spam t + spam-mark-ham-unread-before-move-from-spam-group t + nnimap-split-rule 'nnimap-split-fancy + ;; understand what this does before you copy it to your own setup! + nnimap-split-fancy '(| + ;; trace references to parents and put in their group + (: gnus-registry-split-fancy-with-parent) + ;; this will catch server-side SpamAssassin tags + (: spam-split 'spam-use-regex-headers) + (any "ding" "ding") + ;; note that spam by default will go to "spam" + (: spam-split) + ;; default mailbox + "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}. +;; my parameters, set with `G p' -You can also give @code{spam-split} a parameter, -e.g. @samp{'spam-use-regex-headers}. Why is this useful? +;; all nnml groups, and all nnimap groups except +;; "nnimap+mail.lifelogs.com:train" and +;; "nnimap+mail.lifelogs.com:spam": any spam goes to nnimap training, +;; because it must have been detected manually -Take these split rules (with @code{spam-use-regex-headers} and -@code{spam-use-blackholes} set): +((spam-process-destination . "nnimap+mail.lifelogs.com:train")) -@example - nnimap-split-fancy '(| - (any "ding" "ding") - (: spam-split) - ;; default mailbox - "mail") -@end example +;; all NNTP groups +;; autodetect spam with the blacklist and ham with the BBDB +((spam-autodetect-methods spam-use-blacklist spam-use-BBDB) +;; send all spam to the training group + (spam-process-destination . "nnimap+mail.lifelogs.com:train")) -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. +;; only some NNTP groups, where I want to autodetect spam +((spam-autodetect . t)) -You can let SpamAssassin headers supercede ding rules, but all other -@code{spam-split} rules (including a second invocation of the -regex-headers check) will be after the ding rule: +;; my nnimap "nnimap+mail.lifelogs.com:spam" group + +;; this is a spam group +((spam-contents gnus-group-spam-classification-spam) + + ;; any spam (which happens when I enter for all unseen messages, + ;; because of the gnus-spam-newsgroup-contents setting above), goes to + ;; "nnimap+mail.lifelogs.com:train" unless I mark it as ham + + (spam-process-destination "nnimap+mail.lifelogs.com:train") + + ;; any ham goes to my "nnimap+mail.lifelogs.com:mail" folder, but + ;; also to my "nnimap+mail.lifelogs.com:trainham" folder for training + + (ham-process-destination "nnimap+mail.lifelogs.com:mail" + "nnimap+mail.lifelogs.com:trainham") + ;; in this group, only '!' marks are ham + (ham-marks + (gnus-ticked-mark)) + ;; remembers senders in the blacklist on the way out - this is + ;; definitely not needed, it just makes me feel better + (spam-process (gnus-group-spam-exit-processor-blacklist))) + +;; Later, on the IMAP server I use the "train" group for training +;; SpamAssassin to recognize spam, and the "trainham" group for +;; recognizing ham - but Gnus has nothing to do with it. -@example - nnimap-split-fancy '(| - (: spam-split 'spam-use-regex-headers) - (any "ding" "ding") - (: spam-split) - ;; default mailbox - "mail") @end example -Basically, this lets you invoke specific @code{spam-split} checks -depending on your particular needs. 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. +@subsubheading Using @file{spam.el} on an IMAP server with a statistical filter on the server -You still have to have specific checks such as -@code{spam-use-regex-headers} set to t, even if you specifically -invoke @code{spam-split} with the check. The reason is that when -loading @code{spam.el}, some conditional loading is done depending on -what @code{spam-use-xyz} variables you have set. +From Reiner Steib . -@emph{Note for IMAP users} +My provider has set up bogofilter (in combination with @acronym{DCC}) on +the mail server (@acronym{IMAP}). Recognized spam goes to +@samp{spam.detected}, the rest goes through the normal filter rules, +i.e. to @samp{some.folder} or to @samp{INBOX}. Training on false +positives or negatives is done by copying or moving the article to +@samp{training.ham} or @samp{training.spam} respectively. A cron job on +the server feeds those to bogofilter with the suitable ham or spam +options and deletes them from the @samp{training.ham} and +@samp{training.spam} folders. -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. +With the following entries in @code{gnus-parameters}, @code{spam.el} +does most of the job for me: -@xref{Splitting in IMAP}. +@lisp + ("nnimap:spam\\.detected" + (gnus-article-sort-functions '(gnus-article-sort-by-chars)) + (ham-process-destination "nnimap:INBOX" "nnimap:training.ham") + (spam-contents gnus-group-spam-classification-spam)) + ("nnimap:\\(INBOX\\|other-folders\\)" + (spam-process-destination . "nnimap:training.spam") + (spam-contents gnus-group-spam-classification-ham)) +@end lisp -@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.} +@itemize -@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.} +@item @b{The Spam folder:} -The following are the methods you can use to control the behavior of -@code{spam-split} and their corresponding spam and ham processors: +In the folder @samp{spam.detected}, I have to check for false positives +(i.e. legitimate mails, that were wrongly judged as spam by +bogofilter or DCC). -@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:: -* Extending the spam elisp package:: -@end menu +Because of the @code{gnus-group-spam-classification-spam} entry, all +messages are marked as spam (with @code{$}). When I find a false +positive, I mark the message with some other ham mark (@code{ham-marks}, +@ref{Spam ELisp Package Global Variables}). On group exit, those +messages are copied to both groups, @samp{INBOX} (were I want to have +the article) and @samp{training.ham} (for training bogofilter) and +deleted from the @samp{spam.detected} folder. + +The @code{gnus-article-sort-by-chars} entry simplifies detection of +false positives for me. I receive lots of worms (sweN, @dots{}), that all +have a similar size. Grouping them by size (i.e. chars) makes finding +other false positives easier. (Of course worms aren't @i{spam} +(@acronym{UCE}, @acronym{UBE}) strictly speaking. Anyhow, bogofilter is +an excellent tool for filtering those unwanted mails for me.) + +@item @b{Ham folders:} + +In my ham folders, I just hit @kbd{S x} +(@code{gnus-summary-mark-as-spam}) whenever I see an unrecognized spam +mail (false negative). On group exit, those messages are moved to +@samp{training.ham}. +@end itemize + +@subsubheading Reporting spam articles in Gmane groups with @code{spam-report.el} + +From Reiner Steib . + +With following entry in @code{gnus-parameters}, @kbd{S x} +(@code{gnus-summary-mark-as-spam}) marks articles in @code{gmane.*} +groups as spam and reports the to Gmane at group exit: + +@lisp + ("^gmane\\." + (spam-process (gnus-group-spam-exit-processor-report-gmane))) +@end lisp + +Additionally, I use `(setq spam-report-gmane-use-article-number nil)' +because I don't read the groups directly from news.gmane.org, but +through my local news server (leafnode). I.e. the article numbers are +not the same as on news.gmane.org, thus @code{spam-report.el} has to check +the @code{X-Report-Spam} header to find the correct number. @node Blacklists and Whitelists @subsubsection Blacklists and Whitelists @@ -22405,6 +23154,13 @@ customizing the group parameters or the 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 @@ -22417,6 +23173,13 @@ ham-marked articles in @emph{ham} groups will be added to the 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 @@ -22476,6 +23239,13 @@ ham-marked articles in @emph{ham} groups will be added to the 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 @@ -22491,7 +23261,28 @@ Add this symbol to a group's @code{spam-process} parameter by customizing the group parameters or the @code{gnus-spam-process-newsgroups} variable. When this symbol is added to a group's @code{spam-process} parameter, the spam-marked -articles groups will be reported to the Gmane administrators. +articles groups will be reported to the Gmane administrators via a +HTTP request. + +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 + +This variable is @code{t} by default. Set it to @code{nil} if you are +running your own news server, for instance, and the local article +numbers don't correspond to the Gmane article numbers. When +@code{spam-report-gmane-use-article-number} is @code{nil}, +@code{spam-report.el} will use the @code{X-Report-Spam} header that +Gmane provides. @end defvar @@ -22530,7 +23321,7 @@ list is fairly comprehensive, but make sure to let us know if it contains outdated servers. The blackhole check uses the @code{dig.el} package, but you can tell -@code{spam.el} to use @code{dns.el} instead for better performance if +@file{spam.el} to use @code{dns.el} instead for better performance if you set @code{spam-use-dig} to @code{nil}. It is not recommended at this time to set @code{spam-use-dig} to @code{nil} despite the possible performance improvements, because some users may be unable to @@ -22613,9 +23404,9 @@ category, spam or not. The command @kbd{S t} in summary mode, either for debugging or for curiosity, shows the @emph{spamicity} score of the current article (between 0.0 and 1.0). -Bogofilter determines if a message is spam based on an internal -threshold, set at compilation time. That threshold can't be -customized. +Bogofilter determines if a message is spam based on a specific +threshold. That threshold can be customized, consult the Bogofilter +documentation. If the @code{bogofilter} executable is not in your path, Bogofilter processing will be turned off. @@ -22643,6 +23434,13 @@ customizing the group parameters or the @code{gnus-spam-process-newsgroups} variable. When this symbol is added to a group's @code{spam-process} parameter, spam-marked articles will be added to the Bogofilter spam database. + +@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 @@ -22653,6 +23451,13 @@ added to a group's @code{spam-process} parameter, the ham-marked articles in @emph{ham} groups will be added to the Bogofilter database of non-spam messages. Note that this ham processor has no effect in @emph{spam} or @emph{unclassified} groups. + +@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 @@ -22663,7 +23468,7 @@ database directory. @end defvar -The Bogofilter mail classifier is similar to ifile in intent and +The Bogofilter mail classifier is similar to @command{ifile} in intent and purpose. A ham and a spam processor are provided, plus the @code{spam-use-bogofilter} and @code{spam-use-bogofilter-headers} variables to indicate to spam-split that Bogofilter should either be @@ -22678,7 +23483,7 @@ Bogofilter was used to test this functionality. @defvar spam-use-ifile -Enable this variable if you want @code{spam-split} to use ifile, a +Enable this variable if you want @code{spam-split} to use @command{ifile}, a statistical analyzer similar to Bogofilter. @end defvar @@ -22733,6 +23538,13 @@ customizing the group parameters or the @code{gnus-spam-process-newsgroups} variable. When this symbol is added to a group's @code{spam-process} parameter, the 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 @@ -22743,16 +23555,141 @@ added to a group's @code{spam-process} parameter, the ham-marked 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}. +@file{spam-stat.el} provides an internal (Lisp-only) spam database, +which unlike ifile or Bogofilter does not require external programs. +A spam and a ham processor, and the @code{spam-use-stat} variable for +@code{spam-split} are provided. + +@node SpamOracle +@subsubsection Using SpamOracle with Gnus +@cindex spam filtering +@cindex SpamOracle +@cindex spam + +An easy way to filter out spam is to use SpamOracle. SpamOracle is an +statistical mail filtering tool written by Xavier Leroy and needs to be +installed separately. + +There are several ways to use SpamOracle with Gnus. In all cases, your +mail is piped through SpamOracle in its @emph{mark} mode. SpamOracle will +then enter an @samp{X-Spam} header indicating whether it regards the +mail as a spam mail or not. + +One possibility is to run SpamOracle as a @code{:prescript} from the +@xref{Mail Source Specifiers}, (@pxref{SpamAssassin}). This method has +the advantage that the user can see the @emph{X-Spam} headers. + +The easiest method is to make @file{spam.el} (@pxref{Filtering Spam +Using The Spam ELisp Package}) call SpamOracle. + +@vindex spam-use-spamoracle +To enable SpamOracle usage by @file{spam.el}, set the variable +@code{spam-use-spamoracle} to @code{t} and configure the +@code{nnmail-split-fancy} or @code{nnimap-split-fancy} as described in +the section @xref{Filtering Spam Using The Spam ELisp Package}. In +this example the @samp{INBOX} of an nnimap server is filtered using +SpamOracle. Mails recognized as spam mails will be moved to +@code{spam-split-group}, @samp{Junk} in this case. Ham messages stay +in @samp{INBOX}: + +@example +(setq spam-use-spamoracle t + spam-split-group "Junk" + nnimap-split-inbox '("INBOX") + nnimap-split-rule 'nnimap-split-fancy + nnimap-split-fancy '(| (: spam-split) "INBOX")) +@end example + +@defvar spam-use-spamoracle +Set to @code{t} if you want Gnus to enable spam filtering using +SpamOracle. +@end defvar + +@defvar spam-spamoracle-binary +Gnus uses the SpamOracle binary called @file{spamoracle} found in the +user's PATH. Using the variable @code{spam-spamoracle-binary}, this +can be customized. +@end defvar + +@defvar spam-spamoracle-database +By default, SpamOracle uses the file @file{~/.spamoracle.db} as a database to +store its analyses. This is controlled by the variable +@code{spam-spamoracle-database} which defaults to @code{nil}. That means +the default SpamOracle database will be used. In case you want your +database to live somewhere special, set +@code{spam-spamoracle-database} to this path. +@end defvar + +SpamOracle employs a statistical algorithm to determine whether a +message is spam or ham. In order to get good results, meaning few +false hits or misses, SpamOracle needs training. SpamOracle learns the +characteristics of your spam mails. Using the @emph{add} mode +(training mode) one has to feed good (ham) and spam mails to +SpamOracle. This can be done by pressing @kbd{|} in the Summary buffer +and pipe the mail to a SpamOracle process or using @file{spam.el}'s +spam- and ham-processors, which is much more convenient. For a +detailed description of spam- and ham-processors, @xref{Filtering Spam +Using The Spam ELisp Package}. + +@defvar gnus-group-spam-exit-processor-spamoracle +Add this symbol to a group's @code{spam-process} parameter by +customizing the group parameter or the +@code{gnus-spam-process-newsgroups} variable. When this symbol is added +to a group's @code{spam-process} parameter, spam-marked articles will be +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 -This enables spam.el to cooperate with spam-stat.el. spam-stat.el -provides an internal (Lisp-only) spam database, which unlike ifile or -Bogofilter does not require external programs. A spam and a ham -processor, and the @code{spam-use-stat} variable for @code{spam-split} -are provided. +@defvar gnus-group-ham-exit-processor-spamoracle +Add this symbol to a group's @code{spam-process} parameter by +customizing the group parameter or the +@code{gnus-spam-process-newsgroups} variable. When this symbol is added +to a grup's @code{spam-process} parameter, the ham-marked articles in +@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 -@node Extending the spam elisp package -@subsubsection Extending the spam elisp package +@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 ((ham spam-use-spamoracle) + (spam spam-use-spamoracle)))) +@end example +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 @cindex spam filtering @cindex spam elisp package, extending @cindex extending the spam elisp package @@ -22772,16 +23709,37 @@ code 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 @@ -22794,53 +23752,45 @@ For processing spam and ham messages, provide the following: @enumerate @item -code +code 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 @@ -22880,9 +23830,9 @@ collections, and save it. And last but not least, you need to use this dictionary in your fancy mail splitting rules. @menu -* Creating a spam-stat dictionary:: -* Splitting mail using spam-stat:: -* Low-level interface to the spam-stat dictionary:: +* Creating a spam-stat dictionary:: +* Splitting mail using spam-stat:: +* Low-level interface to the spam-stat dictionary:: @end menu @node Creating a spam-stat dictionary @@ -22983,7 +23933,7 @@ spam or it should go into @samp{mail.misc}. If it is spam, then @lisp (setq nnmail-split-fancy `(| (: spam-stat-split-fancy) - "mail.misc")) + "mail.misc")) @end lisp @defvar spam-stat-split-fancy-spam-group @@ -22997,8 +23947,8 @@ expression are considered potential spam. @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 @@ -23011,7 +23961,7 @@ mails, when creating the dictionary! (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 @@ -23024,9 +23974,9 @@ dictionary! @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 @@ -23118,6 +24068,36 @@ Reduce table size: (spam-stat-reduce-size) Save table: (spam-stat-save) @end smallexample +@node Other modes +@section Interaction with other modes + +@subsection Dired +@cindex dired + +@code{gnus-dired-minor-mode} provided some useful functions for dired +buffers. It is enabled with +@lisp +(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) +@end lisp + +@table @kbd +@item C-c C-m C-a +@findex gnus-dired-attach +Send dired's marked files as an attachment (@code{gnus-dired-attach}). +You will be prompted for a message buffer. + +@item C-c C-m C-l +@findex gnus-dired-find-file-mailcap +Visit a file according to the appropriate mailcap entry +(@code{gnus-dired-find-file-mailcap}). With prefix, open file in a new +buffer. + +@item C-c C-m C-p +@findex gnus-dired-print +Print file according to the mailcap entry (@code{gnus-dired-print}). If +there is no print command, print in a PostScript image. +@end table + @node Various Various @section Various Various @cindex mode lines @@ -23281,10 +24261,10 @@ but at the common table.@* 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 @@ -23530,7 +24510,7 @@ Message Mode is able to request notifications from the receiver. @cindex RFC 1991 @cindex RFC 2440 RFC 1991 is the original @acronym{PGP} message specification, -published as a Information RFC. RFC 2440 was the follow-up, now +published as an informational RFC. RFC 2440 was the follow-up, now called Open PGP, and put on the Standards Track. Both document a non-@acronym{MIME} aware @acronym{PGP} format. Gnus supports both encoding (signing and encryption) and decoding (verification and @@ -23547,8 +24527,8 @@ RFC 2633 describes the @acronym{S/MIME} format. @item IMAP - RFC 1730/2060, RFC 2195, RFC 2086, RFC 2359, RFC 2595, RFC 1731 RFC 1730 is @acronym{IMAP} version 4, updated somewhat by RFC 2060 (@acronym{IMAP} 4 revision 1). RFC 2195 describes CRAM-MD5 -authentication for @acronym{IMAP}. RFC 2086 describes access control -lists (ACLs) for @acronym{IMAP}. RFC 2359 describes a @acronym{IMAP} +authentication for @acronym{IMAP}. RFC 2086 describes access control +lists (ACLs) for @acronym{IMAP}. RFC 2359 describes a @acronym{IMAP} protocol enhancement. RFC 2595 describes the proper @acronym{TLS} integration (STARTTLS) with @acronym{IMAP}. RFC 1731 describes the GSSAPI/Kerberos4 mechanisms for @acronym{IMAP}. @@ -23567,7 +24547,7 @@ know. @cindex Mule @cindex Emacs -Gnus should work on : +Gnus should work on: @itemize @bullet @@ -23669,7 +24649,7 @@ Luis Fernandes---design and graphics. Joe Reiss---creator of the smiley faces. @item -Justin Sheehy--the @acronym{FAQ} maintainer. +Justin Sheehy---the @acronym{FAQ} maintainer. @item Erik Naggum---help, ideas, support, code and stuff. @@ -24496,11 +25476,11 @@ New features in Gnus 5.6: @item New functionality for using Gnus as an offline newsreader has been -added. A plethora of new commands and modes have been added. See -@pxref{Gnus Unplugged} for the full story. +added. A plethora of new commands and modes have been added. +@xref{Gnus Unplugged}, for the full story. @item - The @code{nndraft} back end has returned, but works differently than +The @code{nndraft} back end has returned, but works differently than before. All Message buffers are now also articles in the @code{nndraft} group, which is created automatically. @@ -24509,110 +25489,110 @@ group, which is created automatically. values. @item - @code{gnus-summary-goto-article} now accept Message-ID's. +@code{gnus-summary-goto-article} now accept Message-ID's. @item - A new Message command for deleting text in the body of a message +A new Message command for deleting text in the body of a message outside the region: @kbd{C-c C-v}. @item - You can now post to component group in @code{nnvirtual} groups with +You can now post to component group in @code{nnvirtual} groups with @kbd{C-u C-c C-c}. @item @code{nntp-rlogin-program}---new variable to ease customization. @item - @code{C-u C-c C-c} in @code{gnus-article-edit-mode} will now inhibit +@code{C-u C-c C-c} in @code{gnus-article-edit-mode} will now inhibit re-highlighting of the article buffer. @item - New element in @code{gnus-boring-article-headers}---@code{long-to}. +New element in @code{gnus-boring-article-headers}---@code{long-to}. @item - @kbd{M-i} symbolic prefix command. See the section ``Symbolic -Prefixes'' in the Gnus manual for details. +@kbd{M-i} symbolic prefix command. @xref{Symbolic Prefixes}, for +details. @item - @kbd{L} and @kbd{I} in the summary buffer now take the symbolic prefix +@kbd{L} and @kbd{I} in the summary buffer now take the symbolic prefix @kbd{a} to add the score rule to the @file{all.SCORE} file. @item - @code{gnus-simplify-subject-functions} variable to allow greater +@code{gnus-simplify-subject-functions} variable to allow greater control over simplification. @item - @kbd{A T}---new command for fetching the current thread. +@kbd{A T}---new command for fetching the current thread. @item - @kbd{/ T}---new command for including the current thread in the +@kbd{/ T}---new command for including the current thread in the limit. @item - @kbd{M-RET} is a new Message command for breaking cited text. +@kbd{M-RET} is a new Message command for breaking cited text. @item - @samp{\\1}-expressions are now valid in @code{nnmail-split-methods}. +@samp{\\1}-expressions are now valid in @code{nnmail-split-methods}. @item - The @code{custom-face-lookup} function has been removed. +The @code{custom-face-lookup} function has been removed. If you used this function in your initialization files, you must rewrite them to use @code{face-spec-set} instead. @item - Canceling now uses the current select method. Symbolic prefix +Canceling now uses the current select method. Symbolic prefix @kbd{a} forces normal posting method. @item - New command to translate M******** sm*rtq**t*s into proper +New command to translate M******** sm*rtq**t*s into proper text---@kbd{W d}. @item - For easier debugging of @code{nntp}, you can set +For easier debugging of @code{nntp}, you can set @code{nntp-record-commands} to a non-@code{nil} value. @item - @code{nntp} now uses @file{~/.authinfo}, a @file{.netrc}-like file, for +@code{nntp} now uses @file{~/.authinfo}, a @file{.netrc}-like file, for controlling where and how to send @sc{authinfo} to @acronym{NNTP} servers. @item - A command for editing group parameters from the summary buffer +A command for editing group parameters from the summary buffer has been added. @item - A history of where mails have been split is available. +A history of where mails have been split is available. @item - A new article date command has been added---@code{article-date-iso8601}. +A new article date command has been added---@code{article-date-iso8601}. @item - Subjects can be simplified when threading by setting +Subjects can be simplified when threading by setting @code{gnus-score-thread-simplify}. @item - A new function for citing in Message has been +A new function for citing in Message has been added---@code{message-cite-original-without-signature}. @item - @code{article-strip-all-blank-lines}---new article command. +@code{article-strip-all-blank-lines}---new article command. @item - A new Message command to kill to the end of the article has +A new Message command to kill to the end of the article has been added. @item - A minimum adaptive score can be specified by using the +A minimum adaptive score can be specified by using the @code{gnus-adaptive-word-minimum} variable. @item - The ``lapsed date'' article header can be kept continually +The ``lapsed date'' article header can be kept continually updated by the @code{gnus-start-date-timer} command. @item - Web listserv archives can be read with the @code{nnlistserv} back end. +Web listserv archives can be read with the @code{nnlistserv} back end. @item - Old dejanews archives can now be read by @code{nnweb}. +Old dejanews archives can now be read by @code{nnweb}. @end itemize @@ -24689,6 +25669,14 @@ New features in Gnus 5.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. + +@item The revised Gnus @acronym{FAQ} is included in the manual, @xref{Frequently Asked Questions}. @@ -24715,13 +25703,10 @@ appearance of all article buttons. @xref{Article Button Levels}. @item Dired integration -@code{gnus-dired-minor-mode} installs key bindings in dired buffers to send -a file as an attachment (@kbd{C-c C-a}), open a file using the approriate -mailcap entry (@kbd{C-c C-l}), and print a file using the mailcap entry -(@kbd{C-c P}). It is enabled with -@lisp -(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) -@end lisp +@code{gnus-dired-minor-mode} (see @ref{Other modes}) installs key +bindings in dired buffers to send a file as an attachment, open a file +using the appropriate mailcap entry, and print a file using the mailcap +entry. @item Gnus can display RSS newsfeeds as a newsgroup. @xref{RSS}. @@ -24761,14 +25746,14 @@ If @code{auto-compression-mode} is enabled, attachments are automatically decompressed when activated. @item -If the new option @code{nnml-use-compressed-files} is non-@code{nil}, +If the new option @code{nnml-use-compressed-files} is non-@code{nil}, the nnml back end allows compressed message files. @item Signed article headers (X-PGP-Sig) can be verified with @kbd{W p}. @item -The Summary Buffer uses an arrow in the fringe to indicate the current +The Summary Buffer uses an arrow in the fringe to indicate the current article. Use @code{(setq gnus-summary-display-arrow nil)} to disable it. @item @@ -24788,14 +25773,14 @@ The new @code{recent} mark @samp{.} indicates newly arrived messages (as opposed to old but unread messages). @item -The new option @code{gnus-gcc-mark-as-read} automatically marks +The new option @code{gnus-gcc-mark-as-read} automatically marks Gcc articles as read. @item The nndoc back end now supports mailman digests and exim bounces. @item -Gnus supports RFC 2369 mailing list headers, and adds a number of +Gnus supports RFC 2369 mailing list headers, and adds a number of related commands in mailing list groups. @xref{Mailing List}. @item @@ -24831,7 +25816,7 @@ the second parameter. automatic recognition of XEmacs and GNU Emacs, generates @file{gnus-load.el}, checks if errors occur while compilation and generation of info files and reports them at the end of the build -process. It now uses @code{makeinfo} if it is available and falls +process. It now uses @code{makeinfo} if it is available and falls back to @file{infohack.el} otherwise. @file{make.bat} should now install all files which are necessary to run Gnus and be generally a complete replacement for the @code{configure; make; make install} @@ -24886,10 +25871,10 @@ parameters, a'la: @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 @@ -24903,7 +25888,7 @@ Gnus no longer generate the Sender: header automatically. Earlier it was generated iff the user configurable email address was different from the Gnus guessed default user address. As the guessing -algorithm is rarely correct these days, and (more controversally) the +algorithm is rarely correct these days, and (more controversially) the only use of the Sender: header was to check if you are entitled to cancel/supersede news (which is now solved by Cancel Locks instead, see another entry), generation of the header has been disabled by @@ -24930,7 +25915,7 @@ composing messages and @code{message-generate-headers-first} is Improved anti-spam features. Gnus is now able to take out spam from your mail and news streams -using a wide variety of programs and filter rules. Among the supported +using a wide variety of programs and filter rules. Among the supported methods are RBL blocklists, bogofilter and white/blacklists. Hooks for easy use of external packages such as SpamAssassin and Hashcash are also new. @xref{Thwarting Email Spam}. @@ -24939,6 +25924,9 @@ are also new. @xref{Thwarting Email Spam}. Easy inclusion of X-Faces headers. @item +Face headers handling. + +@item In the summary buffer, the new command @kbd{/ N} inserts new messages and @kbd{/ o} inserts old messages. @@ -24984,11 +25972,11 @@ hierarchy. The Gnus Agent has seen a major updated and is now enabled by default, and all nntp and nnimap servers from @code{gnus-select-method} and -@code{gnus-secondary-select-method} are agentized by default. Earlier +@code{gnus-secondary-select-method} are agentized by default. Earlier only the server in @code{gnus-select-method} was agentized by the default, and the agent was disabled by default. When the agent is enabled, headers are now also retrieved from the Agent cache instead -of the back ends when possible. Earlier this only happened in the +of the back ends when possible. Earlier this only happened in the unplugged state. You can enroll or remove servers with @kbd{J a} and @kbd{J r} in the server buffer. Gnus will not download articles into the Agent cache, unless you instruct it to do so, though, by using @@ -25055,7 +26043,7 @@ local files as external parts. The command @code{gnus-mime-save-part-and-strip} (bound to @kbd{C-o} on @acronym{MIME} buttons) saves a part and replaces the part with an external one. @code{gnus-mime-delete-part} (bound to @kbd{d} on -@acronym{MIME} buttons) removes a part. It works only on back ends +@acronym{MIME} buttons) removes a part. It works only on back ends that support editing. @item @@ -25077,14 +26065,14 @@ Add a new format of match like 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 @code{message-ignored-news-headers} and @code{message-ignored-mail-headers} @samp{X-Draft-From} and @samp{X-Gnus-Agent-Meta-Information} have been -added into these two variables. If you customized those, perhaps you +added into these two variables. If you customized those, perhaps you need add those two headers too. @item @@ -25127,7 +26115,7 @@ the valid values. Gnus supports Cancel Locks in News. This means a header @samp{Cancel-Lock} is inserted in news posting. It is -used to determine if you wrote a article or not (for cancelling and +used to determine if you wrote an article or not (for canceling and superseding). Gnus generates a random password string the first time you post a message, and saves it in your @file{~/.emacs} using the Custom system. While the variable is called @code{canlock-password}, it is not @@ -25158,13 +26146,13 @@ escape character, old user defined format @samp{%u&} is no longer supported. @kbd{/ *} (@code{gnus-summary-limit-include-cached}) is rewritten. It was aliased to @kbd{Y c} -(@code{gnus-summary-insert-cached-articles}). The new function filters +(@code{gnus-summary-insert-cached-articles}). The new function filters out other articles. @item Some limiting commands accept a @kbd{C-u} prefix to negate the match. If @kbd{C-u} is used on subject, author or extra headers, i.e., @kbd{/ -s'}, @kbd{/ a}, and @kbd{/ x} +s}, @kbd{/ a}, and @kbd{/ x} (@code{gnus-summary-limit-to-@{subject,author,extra@}}) respectively, the result will be to display all articles that do not match the expression. @@ -25176,7 +26164,7 @@ This is supposedly what USEFOR wanted to migrate to. See @code{gnus-group-name-charset-method-alist} for customization. @item -The nnml and nnfolder backends store marks for each groups. +The nnml and nnfolder back ends store marks for each groups. This makes it possible to take backup of nnml/nnfolder servers/groups separately of @file{~/.newsrc.eld}, while preserving marks. It also @@ -25206,7 +26194,7 @@ message, Message Manual}). The regexps in these variables are compared with full group names instead of real group names in 5.8. Users who customize these -variables should change those regexps accordingly. For example: +variables should change those regexps accordingly. For example: @lisp ("^han\\>" euc-kr) -> ("\\(^\\|:\\)han\\>" euc-kr) @end lisp @@ -25229,6 +26217,14 @@ C-m}. This change was made to avoid conflict with the standard binding of @code{back-to-indentation}, which is also useful in message mode. + +@item +The default for @code{message-forward-show-mml} changed to symbol @code{best}. + +The behaviour for the @code{best} value is to show @acronym{MML} (i.e., +convert to @acronym{MIME}) when appropriate. @acronym{MML} will not be +used when forwarding signed or encrypted messages, as the conversion +invalidate the digital signature. @end itemize @iftex @@ -25352,10 +26348,10 @@ Gnus considers mail and news to be mostly the same, really. The only difference is how to access the actual articles. News articles are commonly fetched via the protocol @acronym{NNTP}, whereas mail messages could be read from a file on the local disk. The internal -architecture of Gnus thus comprises a `front end' and a number of -`back ends'. Internally, when you enter a group (by hitting +architecture of Gnus thus comprises a ``front end'' and a number of +``back ends''. Internally, when you enter a group (by hitting @key{RET}, say), you thereby invoke a function in the front end in -Gnus. The front end then `talks' to a back end and says things like +Gnus. The front end then ``talks'' to a back end and says things like ``Give me the list of articles in the foo group'' or ``Show me article number 4711''. @@ -25363,16 +26359,16 @@ So a back end mainly defines either a protocol (the @code{nntp} back end accesses news via @acronym{NNTP}, the @code{nnimap} back end accesses mail via @acronym{IMAP}) or a file format and directory layout (the @code{nnspool} back end accesses news via the common -`spool directory' format, the @code{nnml} back end access mail via a +``spool directory'' format, the @code{nnml} back end access mail via a file format and directory layout that's quite similar). Gnus does not handle the underlying media, so to speak---this is all done by the back ends. A back end is a collection of functions to access the articles. -However, sometimes the term `back end' is also used where `server' -would have been more appropriate. And then there is the term `select -method' which can mean either. The Gnus terminology can be quite +However, sometimes the term ``back end'' is also used where ``server'' +would have been more appropriate. And then there is the term ``select +method'' which can mean either. The Gnus terminology can be quite confusing. @item native @@ -25527,6 +26523,13 @@ An article that responds to a different article---its parent. A collection of messages in one file. The most common digest format is specified by RFC 1153. +@item splitting +@cindex splitting, terminolgy +@cindex mail sorting +@cindex mail filtering (splitting) +The action of sorting your emails according to certain rules. Sometimes +incorrectly called mail filtering. + @end table @@ -25682,9 +26685,8 @@ Gnus will work. @item Try doing an @kbd{M-x gnus-version}. If you get something that looks -like @samp{T-gnus 6.15.* (based on Oort Gnus v0.*; for SEMI 1.1*, FLIM -1.1*)} you have the right files loaded. If, on the other hand, you get -something like @samp{NNTP 3.x} or @samp{nntp flee}, you have some old +like @samp{T-gnus 6.16.* (based on Gnus v5.10.*; for SEMI 1.1*, FLIM +1.1*)} you have the right files loaded. Otherwise you have some old @file{.el} files lying around. Delete these. @item @@ -25752,11 +26754,11 @@ evaluate expressions using @kbd{M-:} or inspect variables using @cindex elp @cindex profile @cindex slow -Sometimes, a problem do not directly generate a elisp error but +Sometimes, a problem do not directly generate an elisp error but manifests itself by causing Gnus to be very slow. In these cases, you can use @kbd{M-x toggle-debug-on-quit} and press @kbd{C-g} when things are slow, and then try to analyze the backtrace (repeating the procedure -helps isolating the real problem areas). +helps isolating the real problem areas). A fancier approach is to use the elisp profiler, ELP. The profiler is (or should be) fully documented elsewhere, but to get you started @@ -25985,7 +26987,7 @@ more. Gnus identifies each message by way of group name and article number. A few remarks about these article numbers might be useful. First of all, the numbers are positive integers. Secondly, it is normally not -possible for later articles to `re-use' older article numbers without +possible for later articles to ``re-use'' older article numbers without confusing Gnus. That is, if a group has ever contained a message numbered 42, then no other message may get that number, or Gnus will get mightily confused.@footnote{See the function @@ -25993,15 +26995,15 @@ mightily confused.@footnote{See the function Third, article numbers must be assigned in order of arrival in the group; this is not necessarily the same as the date of the message. -The previous paragraph already mentions all the `hard' restrictions that +The previous paragraph already mentions all the ``hard'' restrictions that article numbers must fulfill. But it seems that it might be useful to assign @emph{consecutive} article numbers, for Gnus gets quite confused if there are holes in the article numbering sequence. However, due to -the `no-reuse' restriction, holes cannot be avoided altogether. It's +the ``no-reuse'' restriction, holes cannot be avoided altogether. It's also useful for the article numbers to start at 1 to avoid running out of numbers as long as possible. -Note that by convention, backends are named @code{nnsomething}, but +Note that by convention, back ends are named @code{nnsomething}, but Gnus also comes with some @code{nnnotbackends}, such as @file{nnheader.el}, @file{nnmail.el} and @file{nnoo.el}. @@ -26129,7 +27131,7 @@ There should be no data returned. If @var{server} is the current virtual server, and the connection to the physical server is alive, then this function should return a -non-@code{nil} vlue. This function should under no circumstances +non-@code{nil} value. This function should under no circumstances attempt to reconnect to a server we have lost connection to. There should be no data returned. @@ -26393,7 +27395,7 @@ created after @samp{date}, which is in normal human-readable date format the function @code{message-make-date} by default). The data should be in the active buffer format. -It is okay for this function to return `too many' groups; some back ends +It is okay for this function to return ``too many'' groups; some back ends might find it cheaper to return the full list of groups, rather than just the new groups. But don't do this for back ends with many groups. Normally, if the user creates the groups herself, there won't be too @@ -26443,7 +27445,7 @@ optimizations. The function should return a cons where the @code{car} is the group name and the @code{cdr} is the article number that the article was entered as. -The group should exist before the backend is asked to accept the +The group should exist before the back end is asked to accept the article for that group. There should be no data returned. @@ -26789,7 +27791,7 @@ this: @subsection Score File Syntax Score files are meant to be easily parseable, but yet extremely -mallable. It was decided that something that had the same read syntax +mallable. It was decided that something that had the same read syntax as an Emacs Lisp list would fit that spec. Here's a typical score file: diff --git a/texi/gnusref.tex b/texi/gnusref.tex index 208c8e4..0ddecd6 100644 --- a/texi/gnusref.tex +++ b/texi/gnusref.tex @@ -1,7 +1,7 @@ %% include file for the Gnus refcard and booklet \def\progver{5.10}\def\refver{5.10-1} % program and refcard versions -\def\date{Jan, 2003} +\def\date{Oct, 2003} \def\author{Gnus Bugfixing Girls + Boys $<$bugs@gnus.org$>$} %% @@ -146,6 +146,7 @@ ? & (?, M ?) Dormant (only followups are interesting).\\ E & (E, M e, M x) {\bf Expirable}. Only has effect in mail groups.\\ G & (C, B DEL) Canceled article (or deleted in mailgroups).\\ + \$ & (M-d, M s x, S x). Marked as spam.\\ \hline\hline \multicolumn{2}{|p{\markdblcolwidth}|} {The marks below mean that the article @@ -171,6 +172,7 @@ \# & (\#, M \#, M P p) Processable (will be affected by the next operation). [2]\\ A & {\bf Answered} (followed-up or replied). [2]\\ + F & Forwarded. [2]\\ $\ast$ & Cached. [2]\\ S & Saved. [2]\\ N & Recently arrived. [2]\\ @@ -297,6 +299,7 @@ G V & Make a new empty {\bf virtual} group. (nnvirtual)\\ G w & Create ephemeral group based on web-search. [Prefix: make solid group instead]\\ + G R & Make an {\bf RSS} group.\\ G DEL & {\bf Delete} group [Prefix: delete all articles as well].\\ G x & Expunge all deleted articles in an nnimap mailbox.\\ G l & Edit ACL (Access Control {\bf List}) for an nnimap mailbox.\\ @@ -424,7 +427,7 @@ Y c & Insert all cached articles into the summary-buffer.\\ % M-C-e & {\bf Edit} the group-parameters.\\ - M-C-g & Customize the group-parameters.\\ + M-C-a & Customize the group-parameters.\\ % % article handling % @@ -468,7 +471,7 @@ K $\mid$ & Pipe the MIME part to an external command.\\ K b & Make all the MIME parts have buttons in front of them.\\ K m & Try to repair {\bf multipart-headers}.\\ - K C & View the MIME part using a differenct {\bf charset}.\\ + K C & View the MIME part using a different {\bf charset}.\\ X m & Save all parts matching a MIME type to a directory. [p/p]\\ M-t & Toggle the buttonized display of the article buffer.\\ W M w & Decode RFC2047-encoded words in the article headers.\\ @@ -688,7 +691,8 @@ RET & (BUTTON-2) Toggle display of the MIME object.\\ v & Prompt for a method and then view object using this method.\\ o & Prompt for a filename and save the MIME object.\\ - C-o & Prompt for a filename to save the MIME object to and remove it.\\ + C-o & Prompt for a filename to save the MIME object to and remove it.\\ + d & {\bf Delete} the MIME object.\\ c & {\bf Copy} the MIME object to a new buffer and display this buffer.\\ i & Display the MIME object in this buffer.\\ C & Copy the MIME object to a new buffer and display this buffer using {\bf Charset} \\ @@ -940,7 +944,7 @@ \end{keys} The four letters stand for:\\* \quad \B{A}ction: I)ncrease, L)ower;\\* - \quad \B{p}art: a)utor (from), s)ubject, x)refs (cross-posting), d)ate, l)ines, + \quad \B{p}art: a)uthor (from), s)ubject, x)refs (cross-posting), d)ate, l)ines, message-i)d, t)references (parent), f)ollowup, b)ody, h)ead (all headers);\\* \quad \B{m}atch type:\\* \qquad string: s)ubstring, e)xact, r)egexp, f)uzzy,\\* @@ -1005,7 +1009,7 @@ Z P & Exit and go to the {\bf previous} group.\\ % Z G & (M-g) Check for new articles in this group ({\bf get}).\\ - Z R & Exit this group, and then enter it again ({\bf reenter}). + Z R & (C-x C-s) Exit this group, and then enter it again ({\bf reenter}). [Prefix: select all articles, read and unread.]\\ Z s & Update and save the dribble buffer. [Prefix: save .newsrc* as well]\\ \end{keys} @@ -1059,7 +1063,7 @@ C-c C-f C-d & Move to \textbf{Distribution:}.\\ C-c C-f C-m & Move to \textbf{Mail-Followup-To:}.\\ C-c C-f C-o & Move to \textbf{From:}.\\ - C-c C-f C-a & Insert a resonable \textbf{Mail-Followup-To:} for + C-c C-f C-a & Insert a reasonable \textbf{Mail-Followup-To:} for an unsubscribed list. [Prefix: include addresses in \textbf{Cc:}]\\ C-c C-f TAB & (C-c C-u) Move to \textbf{Importance:}.\\ C-c M-n & Insert \textbf{Disposition-Notification-To:} @@ -1081,7 +1085,7 @@ C-c C-m m & Insert \textbf{multi}-part.\\ C-c C-m q & \textbf{Quote} region.\\ C-c C-m c s & Encrypt message using \textbf{S/MIME}.\\ - C-c C-m c o & Encrypt message usging PGP.\\ + C-c C-m c o & Encrypt message using PGP.\\ C-c C-m c p & Encrypt message using \textbf{PGP/MIME}.\\ C-c C-m s s & Sign message using \textbf{S/MIME}.\\ C-c C-m s o & Sign message using PGP.\\ diff --git a/texi/infohack.el b/texi/infohack.el index 3c173ba..89bad3f 100644 --- a/texi/infohack.el +++ b/texi/infohack.el @@ -25,10 +25,11 @@ ;;; Code: -(let ((default-directory (expand-file-name "../lisp/")) - (features (cons 'w3-forms (copy-sequence features)))) +(let ((default-directory (expand-file-name "../lisp/"))) ;; Adjust `load-path' for APEL. - (load-file "dgnushack.el")) + (load-file "dgnushack.el") + ;; Replace "./" with "../lisp/" in `load-path'. + (setq load-path (mapcar 'expand-file-name load-path))) (load-file (expand-file-name "ptexinfmt.el" "./")) (defun infohack-remove-unsupported () @@ -90,6 +91,8 @@ Both characters must have the same length of multi-byte form." (setq command-line-args-left nil)) +(require 'bytecomp) + (defun infohack-texi-format (file &optional addsuffix) (let ((auto-save-default nil) (find-file-run-dired nil) @@ -104,22 +107,6 @@ Both characters must have the same length of multi-byte form." (if (boundp 'MULE) (setq output-coding-system file-coding-system) (setq coding-system-for-write buffer-file-coding-system)) - ;; Remove ignored areas first. - (while (re-search-forward "^@ignore[\t\r ]*$" nil t) - (delete-region (match-beginning 0) - (if (re-search-forward - "^@end[\t ]+ignore[\t\r ]*$" nil t) - (1+ (match-end 0)) - (point-max)))) - (infohack-remove-unsupported) - (goto-char (point-min)) - ;; Add suffix if it is needed. - (when (and addsuffix - (re-search-forward "^@setfilename[\t ]+\\([^\t\n ]+\\)" - nil t) - (not (string-match "\\.info$" (match-string 1)))) - (insert ".info") - (goto-char (point-min))) ;; process @include before updating node ;; This might produce some problem if we use @lowersection or ;; such. @@ -152,11 +139,47 @@ Both characters must have the same length of multi-byte form." (delete-region (point) (save-excursion (forward-line 1) (point)))))))))) + ;; Remove ignored areas. + (goto-char (point-min)) + (while (re-search-forward "^@ignore[\t\r ]*$" nil t) + (delete-region (match-beginning 0) + (if (re-search-forward + "^@end[\t ]+ignore[\t\r ]*$" nil t) + (1+ (match-end 0)) + (point-max)))) + ;; Remove unsupported commands. + (infohack-remove-unsupported) + ;; Add suffix if it is needed. + (goto-char (point-min)) + (when (and addsuffix + (re-search-forward "^@setfilename[\t ]+\\([^\t\n ]+\\)" + nil t) + (not (string-match "\\.info$" (match-string 1)))) + (insert ".info")) (texinfo-mode) (texinfo-every-node-update) (set-buffer-modified-p nil) (message "texinfo formatting %s..." file) - (texinfo-format-buffer nil) + (if (featurep 'mule) + ;; Encode messages to terminal. + (let ((si:message (symbol-function 'message))) + (fset 'message + (byte-compile + (if (boundp 'MULE) + `(lambda (fmt &rest args) + (funcall ,si:message "%s" + (code-convert-string + (apply 'format fmt args) + '*internal* '*junet*))) + `(lambda (fmt &rest args) + (funcall ,si:message "%s" + (encode-coding-string + (apply 'format fmt args) + 'iso-2022-7bit)))))) + (unwind-protect + (texinfo-format-buffer nil) + (fset 'message si:message))) + (texinfo-format-buffer nil)) (if (buffer-modified-p) (progn (message "Saving modified %s" (buffer-file-name)) (save-buffer)))) diff --git a/texi/message-ja.texi b/texi/message-ja.texi index 20142f2..ee6233d 100644 --- a/texi/message-ja.texi +++ b/texi/message-ja.texi @@ -1,7 +1,7 @@ -A\input texinfo +\input texinfo @setfilename message-ja -@settitle T-gnus 6.15 Message Manual +@settitle T-gnus 6.16 Message Manual @synindex fn cp @synindex vr cp @synindex pg cp @@ -22,7 +22,7 @@ This file documents Message, the Emacs message composition mode. $B$3$N%U%!%$%k$O(B Emacs $B$N%a%C%;!<%8:n@.%b!<%I$G$"$k(B Message $B$K4X$9$k@bL@J8(B $B=q$G$9!#(B -Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document @@ -63,7 +63,7 @@ license to the document, as described in section 6 of the license. @tex @titlepage -@title T-gnus 6.15 Message Manual +@title T-gnus 6.16 Message Manual @author by Lars Magne Ingebrigtsen @translated by members of Semi-gnus mailing-list @@ -126,7 +126,7 @@ Gnus $B$NA4$F$N%a%C%;!<%8$N:n@.(B ($B%a!<%k$H%K%e!<%9$NN>J}(B) $B$O%a%C%;!< * Key Index:: $B%a%C%;!<%8%b!<%I%-!<$N0lMw(B @end menu -$B$3$N%^%K%e%"%k$O(B T-gnus 6.15 Message $B$KBP1~$7$^$9!#(BMessage $B$O$3$N%^%K%e(B +$B$3$N%^%K%e%"%k$O(B T-gnus 6.16 Message $B$KBP1~$7$^$9!#(BMessage $B$O$3$N%^%K%e(B $B%"%k$HF1$8HGHV9f$N(B Gnus $B$NG[I[$H6&$KG[I[$5$l$^$9!#(B @node Interface @@ -205,9 +205,10 @@ Message $B$O2?=h$KJVEz$,9T$/$+$rIaDL$NJ}K!(B (@pxref{Responses}) $B$G7hDj$7$^ $B$&!#(B $B$3$N4X?t$O%j%9%H$rJV$9;v$b$G$-$^$9!#$=$N$h$&$J>l9g$O!"$=$l$>$l$NMWAG(B -$B$O(B cons $B%;%k$G$"$k$Y$-$G!"$=$l$N(B car $B$O%X%C%@!<$NL>A0(B ($BNc(B @code{Cc}) $B$G!"(B -cdr $B$,%X%C%@!<$NCM(B ($BNc(B @samp{larsi@@ifi.uio.no}) $B$G$"$k$Y$-$G$9!#A4$F$N(B -$B$3$l$i$N%X%C%@!<$O=P$F9T$/%a!<%k$N%X%C%@!<$KA^F~$5$l$^$9!#(B +$B$O(B cons $B%;%k$G$"$k$Y$-$G!"$=$l$N(B @sc{car} $B$O%X%C%@!<$NL>(B +$BA0(B ($BNc(B @code{Cc}) $B$G!"(B@sc{cdr} $B$,%X%C%@!<$N(B +$BCM(B ($BNc(B @samp{larsi@@ifi.uio.no}) $B$G$"$k$Y$-$G$9!#$9$Y$F$N$3$l$i$N%X%C%@!<(B +$B$O=P$F9T$/%a!<%k$N%X%C%@!<$KA^F~$5$l$^$9!#(B @node Wide Reply @section $B9-$/JVEz(B @@ -338,7 +339,7 @@ constructed. The default value is @code{nil}. If this variable is @code{t} (the default), forwarded messages are included as inline @acronym{MIME} RFC822 parts. If it's @code{nil}, forwarded messages will just be copied inline to the new message, like previous, -non @acronym{MIME}-savvy versions of gnus would do. +non @acronym{MIME}-savvy versions of Gnus would do. @end ignore @item message-forward-before-signature @@ -375,6 +376,7 @@ non @acronym{MIME}-savvy versions of gnus would do. @node Mailing Lists @section $B%a!<%j%s%0%j%9%H(B +@cindex Mail-Followup-To $B%a!<%j%s%0%j%9%H$KEj9F$9$k$H$-!"Ej9F$9$k?M$,$=$N5-;v$KBP$9$k%U%)%m!<%"%C(B $B%W5-;v$N08@h$r;XDj$7$?$$$3$H$,$"$j$^$9!#(BMail-Followup-To (MFT) $B$O$^$5$K(B $B$3$l$r2DG=$K$9$k$?$a$K:n$i$l$^$7$?!#$3$l$,Lr$KN)$D>l9g$NNc$rFs$D(B: @@ -514,9 +516,9 @@ Gnus Manual}) $B%0%k!<%W%Q%i%a!<%?$,Hs(B-@code{nil} $B$K@_Dj$5$l$F$$$k%0%k!<% $B$I$&$9$k$+?R$M$^$9!#(B @end table -MFT $B$rB:=E$9$k$3$H$ONI$$%M%A%1%C%H(B (nettiquette) $B$G$"$k$H9M$($i$l$F$$$^(B -$B$9!#$=$l$O!"$I$3$K%U%)%m!<%"%C%W$9$kI,MW$,$"$k$+$r!"%a%C%;!<%8$rEj9F$7$?(B -$B?M$O$"$J$?$h$j$h$/CN$C$F$$$k!"$H;W$o$l$k$+$i$G$9!#(B +MFT $B$rB:=E$9$k$3$H$ONI$$%M%A%1%C%H(B (netiquette) $B$G$"$k$H9M$($i$l$F$$$^$9!#(B +$B$=$l$O!"$I$3$K%U%)%m!<%"%C%W$9$kI,MW$,$"$k$+$r!"%a%C%;!<%8$rEj9F$7$??M$O(B +$B$"$J$?$h$j$h$/CN$C$F$$$k!"$H;W$o$l$k$+$i$G$9!#(B @node Commands @chapter $BL?Na(B @@ -845,7 +847,7 @@ The most typical thing users want to use the multipart things in be done with the @kbd{C-c C-a} command, which will prompt for a file name and a @acronym{MIME} type. -You can also create arbitrarily complex multiparts using the MML +You can also create arbitrarily complex multiparts using the @acronym{MML} language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME Manual}). @@ -894,12 +896,13 @@ Libidn} $B$r%$%s%9%H!<%k$7$F$*$/I,MW$,$"$j$^$9!#(B @cindex encrypt @cindex secure -Using the MML language, Message is able to create digitally signed and -digitally encrypted messages. Message (or rather MML) currently -support @acronym{PGP} (RFC 1991), @acronym{PGP/MIME} (RFC 2015/3156) and @acronym{S/MIME}. -Instructing MML to perform security operations on a @acronym{MIME} part is -done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c -C-m c} key map for encryption, as follows. +Using the @acronym{MML} language, Message is able to create digitally +signed and digitally encrypted messages. Message (or rather +@acronym{MML}) currently support @acronym{PGP} (RFC 1991), +@acronym{PGP/MIME} (RFC 2015/3156) and @acronym{S/MIME}. Instructing +@acronym{MML} to perform security operations on a @acronym{MIME} part is +done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c C-m +c} key map for encryption, as follows. @table @kbd @@ -942,43 +945,22 @@ Digitally encrypt current message using @acronym{PGP/MIME}. @item C-c C-m C-n @kindex C-c C-m C-n @findex mml-unsecure-message -Remove security related MML tags from message. +Remove security related @acronym{MML} tags from message. @end table These commands do not immediately sign or encrypt the message, they -merely insert the proper MML secure tag to instruct the MML engine to -perform that operation when the message is actually sent. They may -perform other operations too, such as locating and retrieving a -@acronym{S/MIME} certificate of the person you wish to send encrypted mail -to. When the mml parsing engine converts your MML into a properly -encoded @acronym{MIME} message, the secure tag will be replaced with either -a part or a multipart tag. If your message contains other mml parts, -a multipart tag will be used; if no other parts are present in your -message a single part tag will be used. This way, message mode will -do the Right Thing (TM) with signed/encrypted multipart messages. - -@vindex mml-signencrypt-style-alist -By default, when encrypting a message, Gnus will use the ``signencrypt'' -mode. If you would like to disable this for a particular message, -give the @code{mml-secure-message-encrypt-*} command a prefix argument. (for -example, @kbd{C-u C-c C-m c p}). Additionally, by default Gnus will -separately sign, then encrypt a message which has the mode -signencrypt. If you would like to change this behavior you can -customize the @code{mml-signencrypt-style-alist} variable. For -example: - - -@lisp -(setq mml-signencrypt-style-alist '(("smime" combined) - ("pgp" combined) - ("pgpmime" combined))) -@end lisp - -Will cause Gnus to sign and encrypt in one pass, thus generating a -single signed and encrypted part. Note that combined sign and encrypt -does not work with all supported OpenPGP implementations (in -particular, @acronym{PGP} version 2 do not support this). +merely insert the proper @acronym{MML} secure tag to instruct the +@acronym{MML} engine to perform that operation when the message is +actually sent. They may perform other operations too, such as locating +and retrieving a @acronym{S/MIME} certificate of the person you wish to +send encrypted mail to. When the mml parsing engine converts your +@acronym{MML} into a properly encoded @acronym{MIME} message, the secure +tag will be replaced with either a part or a multipart tag. If your +message contains other mml parts, a multipart tag will be used; if no +other parts are present in your message a single part tag will be used. +This way, message mode will do the Right Thing (TM) with +signed/encrypted multipart messages. Since signing and especially encryption often is used when sensitive information is sent, you may want to have some way to ensure that your @@ -993,6 +975,12 @@ party the other night, actually will be sent encrypted. RFC822 headers. They only operate on the @acronym{MIME} object. Keep this in mind before sending mail with a sensitive Subject line. +By default, when encrypting a message, Gnus will use the +``signencrypt'' mode, which means the message is both signed and +encrypted. If you would like to disable this for a particular +message, give the @code{mml-secure-message-encrypt-*} command a prefix +argument, e.g., @kbd{C-u C-c C-m c p}. + Actually using the security commands above is not very difficult. At least not compared with making sure all involved programs talk with each other properly. Thus, we now describe what external libraries or @@ -1004,24 +992,25 @@ programs are required to make things work, and some small general hints. modern cryptography, @acronym{S/MIME}, various PKCS standards, OpenSSL and so on. -The @acronym{S/MIME} support in Message (and MML) require OpenSSL. OpenSSL -perform the actual @acronym{S/MIME} sign/encrypt operations. OpenSSL can -be found at @uref{http://www.openssl.org/}. OpenSSL 0.9.6 and later -should work. Version 0.9.5a cannot extract mail addresses from -certificates, and it insert a spurious CR character into @acronym{MIME} -separators so you may wish to avoid it if you would like to avoid -being regarded as someone who send strange mail. (Although by sending -@acronym{S/MIME} messages you've probably already lost that contest.) +The @acronym{S/MIME} support in Message (and @acronym{MML}) require +OpenSSL. OpenSSL performs the actual @acronym{S/MIME} sign/encrypt +operations. OpenSSL can be found at @uref{http://www.openssl.org/}. +OpenSSL 0.9.6 and later should work. Version 0.9.5a cannot extract mail +addresses from certificates, and it insert a spurious CR character into +@acronym{MIME} separators so you may wish to avoid it if you would like +to avoid being regarded as someone who send strange mail. (Although by +sending @acronym{S/MIME} messages you've probably already lost that +contest.) To be able to send encrypted mail, a personal certificate is not -required. Message (MML) need a certificate for the person to whom you +required. Message (@acronym{MML}) need a certificate for the person to whom you wish to communicate with though. You're asked for this when you type @kbd{C-c C-m c s}. Currently there are two ways to retrieve this certificate, from a local file or from DNS. If you chose a local file, it need to contain a X.509 certificate in @acronym{PEM} format. If you chose DNS, you're asked for the domain name where the certificate is stored, the default is a good guess. To my belief, -Message (MML) is the first mail agent in the world to support +Message (@acronym{MML}) is the first mail agent in the world to support retrieving @acronym{S/MIME} certificates from DNS, so you're not likely to find very many certificates out there. At least there should be one, stored at the domain @code{simon.josefsson.org}. LDAP @@ -1031,8 +1020,8 @@ command line to retrieve a certificate into a file and use it.) As for signing messages, OpenSSL can't perform signing operations without some kind of configuration. Especially, you need to tell it -where your private key and your certificate is stored. MML uses an -Emacs interface to OpenSSL, aptly named @code{smime.el}, and it +where your private key and your certificate is stored. @acronym{MML} +uses an Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain a @code{custom} group used for this configuration. So, try @kbd{M-x customize-group RET smime RET} and look around. @@ -1051,15 +1040,21 @@ $ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem The @file{key+cert.pem} file should be pointed to from the @code{smime-keys} variable. You should now be able to send signed mail. -@emph{Note!} Your private key is stored unencrypted in the file, so take -care in handling it. +@emph{Note!} Your private key is now stored unencrypted in the file, +so take care in handling it. Storing encrypted keys on the disk are +supported, and Gnus will ask you for a passphrase before invoking +OpenSSL. Read the OpenSSL documentation for how to achieve this. If +you use unencrypted keys (e.g., if they are on a secure storage, or if +you are on a secure single user machine) simply press @code{RET} at +the passphrase prompt. @subsection Using PGP/MIME @acronym{PGP/MIME} requires an external OpenPGP implementation, such -as @uref{http://www.gnupg.org/, GNU Privacy Guard}. One Emacs -interface to OpenPGP implementations, PGG (@pxref{Top, ,PGG, pgg, PGG -Manual}), is included, but Mailcrypt and Florian Weimer's +as @uref{http://www.gnupg.org/, GNU Privacy Guard}. Pre-OpenPGP +implementations such as PGP 2.x and PGP 5.x are also supported. One +Emacs interface to the PGP implementations, PGG (@pxref{Top, ,PGG, +pgg, PGG Manual}), is included, but Mailcrypt and Florian Weimer's @code{gpg.el} are also supported. @vindex gpg-temp-directory @@ -1067,8 +1062,36 @@ Note, if you are using the @code{gpg.el} you must make sure that the directory specified by @code{gpg-temp-directory} have permissions 0700. -Creating your own OpenPGP key is described in detail in the -documentation of your OpenPGP implementation, so we refer to it. +Creating your own key is described in detail in the documentation of +your PGP implementation, so we refer to it. + +If you have imported your old PGP 2.x key into GnuPG, and want to send +signed and encrypted messages to your fellow PGP 2.x users, you'll +discover that the receiver cannot understand what you send. One +solution is to use PGP 2.x instead (i.e., if you use @code{pgg}, set +@code{pgg-default-scheme} to @code{pgp}). If you do want to use +GnuPG, you can use a compatibility script called @code{gpg-2comp} +available from +@uref{http://muppet.faveve.uni-stuttgart.de/~gero/gpg-2comp/}. You +could also convince your fellow PGP 2.x users to convert to GnuPG. +@vindex mml-signencrypt-style-alist +As a final workaround, you can make the sign and encryption work in +two steps; separately sign, then encrypt a message. If you would like +to change this behavior you can customize the +@code{mml-signencrypt-style-alist} variable. For example: + +@lisp +(setq mml-signencrypt-style-alist '(("smime" separate) + ("pgp" separate) + ("pgpauto" separate) + ("pgpmime" separate))) +@end lisp + +This causes to sign and encrypt in two passes, thus generating a +message that can be understood by PGP version 2. + +(Refer to @uref{http://www.gnupg.org/gph/en/pgp2x.html} for more +information about the problem.) @end ignore @node Various Commands @@ -1233,7 +1256,7 @@ Emacs $B$G%9%Z%k%A%'%C%/$9$k$?$a$KIa5Z$7$F$$$kFs$D$NJ}K!!"(B @lisp (setq ispell-message-dictionary-alist '(("^Newsgroups:.*\\bde\\." . "deutsch8") - (".*" . "default"))) + (".*" . "default"))) @end lisp @code{ispell} $B$O%$%s%9%H!<%k$5$l$?(B @samp{ispell} $B%3%^%s%I$K0MB8$7$F$$$^(B @@ -1362,7 +1385,23 @@ Message $B$,(B gnus $B>e$GAv$C$F$$$k>l9g!"%a%C%;!<%8%P%C%U%!$O%I%i%U%H%0%k!<% @lisp (setq message-subject-re-regexp - "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)") + (concat + "^[ \t]*" + "\\(" + "\\(" + "[Aa][Nn][Tt][Ww]\\.?\\|" ; antw + "[Aa][Ww]\\|" ; aw + "[Ff][Ww][Dd]?\\|" ; fwd + "[Oo][Dd][Pp]\\|" ; odp + "[Rr][Ee]\\|" ; re + "[Rr][\311\351][Ff]\\.?\\|" ; ref + "[Ss][Vv]" ; sv + "\\)" + "\\(\\[[0-9]*\\]\\)" + "*:[ \t]*" + "\\)" + "*[ \t]*" + )) @end lisp @item message-subject-trailing-was-query @@ -1402,6 +1441,14 @@ Message $B$,(B gnus $B>e$GAv$C$F$$$k>l9g!"%a%C%;!<%8%P%C%U%!$O%I%i%U%H%0%k!<% (setq message-hidden-headers '(not "From" "Subject" "To" "Cc" "Newsgroups")) @end lisp + +@item message-header-synonyms +@vindex message-header-synonyms +$B%X%C%@!l9g!"(B +@code{message-carefully-insert-headers} $B$O(B @code{To} $B%X%C%@!<$rA^F~$7$^(B +$B$;$s!#(B @end table @node Mail Headers @@ -1483,7 +1530,7 @@ qmail-inject $B%W%m%0%i%`$KEO$90z?t$G$9!#$3$l$OJ8;zNs$N%j%9%H$G!"$=$l$>$l(B @item message-mailer-swallows-blank-line @vindex message-mailer-swallows-blank-line $B%7%9%F%`$N%a%$%i!<$,%X%C%@!<$HK\J8$r0l=o$K$7$F$7$^$&>l9g$O!"(B -$BHs(B-@code{nil} $B$K@_Dj$7$F2<$5$$!#(B(Sunos 4 $B$G(B sendmail $B$,%j%b!<%H%b!<%I$G(B +$BHs(B-@code{nil} $B$K@_Dj$7$F2<$5$$!#(B(SunOS 4 $B$G(B sendmail $B$,%j%b!<%H%b!<%I$G(B $BF0:n$9$k>l9g$,3:Ev$7$^$9!#(B) $BCM$O!">c32$,$l(B @findex yow @cindex Mime-Version -$B2C$($F(B cons $B$r%j%9%H$KF~$l$k;v$,$G$-$^$9!#(Bcons $B$N(B car $B$O%7%s%\%k$G$"$k$Y(B -$B$-$G$9!#$3$N%7%s%\%kL>$O%X%C%@!$G!"(Bcdr $B$O$3$N%X%C%@!<$NCM$H$7$F$=$N$^(B -$B$^F~$l$i$l$k$3$H$K$J$kJ8;zNs$+!"8F$P$l$k4X?t$N$I$A$i$+$G$"$k;v$,$G$-$^$9!#(B -$BNc$($P!"$b$7(B @code{Mime-Version: 1.0} $B$rA^F~$7$?$$$J$i!"(B +$B2C$($F(B cons $B$r%j%9%H$KF~$l$k;v$,$G$-$^$9!#$3$N(B cons $B$N(B @sc{car} $B$O%7%s%\(B +$B%k$G$"$k$Y$-$G$9!#$3$N%7%s%\%kL>$O%X%C%@!$G!"(B@sc{cdr} $B$O$3$N%X%C%@!<(B +$B$NCM$H$7$F$=$N$^$^F~$l$i$l$k$3$H$K$J$kJ8;zNs$+!"8F$P$l$k4X?t$N$I$A$i$+$G(B +$B$"$k;v$,$G$-$^$9!#Nc$($P!"$b$7(B @code{Mime-Version: 1.0} $B$rA^F~$7$?$$$J$i!"(B @code{(Mime-Version . "1.0")} $B$r%j%9%H$KF~$l$k$Y$-$G$7$g$&!#$b$7$*$b$7$m(B $B$$0zMQ$rA^F~$7$?$$$J$i!"(B@code{(X-Yow . yow)} $B$N$h$&$J$b$N$r%j%9%H$KF~$l(B $B$k;v$,$G$-$k$G$7$g$&!#4X?t(B @code{yow} $B$O$=$N8e$G0z?tL5$7$G8F$P$l$^$9!#(B -$B$b$7%j%9%H$,(B cons $B$N(B car $B$,(B @code{optional} $B$G$"$k(B cons $B$r4^$s$G$$$k$J$i!"(B -$B$3$N(B cons $B$N(B cdr $B$O(B @code{nil} $B$G$J$$$H$-$@$1A^F~$5$l$^$9!#(B +$B$b$7%j%9%H$,(B cons $B$N(B @sc{car} $B$,(B @code{optional} $B$G$"$k(B cons $B$r4^$s$G$$(B +$B$k$J$i!"$3$N(B cons $B$N(B @sc{cdr} $B$O(B @code{nil} $B$G$J$$$H$-$@$1A^F~$5$l$^$9!#(B $B$3$N%j%9%H$+$i$"$k9`L\$r>C$7$?$$$J$i$P!"0J2<$N(B Lisp $B$N@Z$lC<$,Lr$KN)$D$G(B $B$7$g$&!#B>$NMWAG$r:o=|$7$?$$$H$-$O$=$l$K9g$o$;$F2<$5$$!#(B @@ -1726,7 +1773,8 @@ Hallvard B Furuseth writes: $BG=$,$"$j$^$9!#$b$7$"$J$?$,EY$r1[$7$F0zMQ9T$rJQ99$7$F$7$^$&$H!"$=$l$rFI$`(B $B?M$?$A$bH`$i$N(B gnus $B$rBP1~$5$;$J$1$l$P$J$i$J$/$J$k$G$7$g$&!#JQ(B $B?t(B @code{gnus-cite-attribution-suffix} $B$r;2>H$7$F2<$5$$!#>\:Y(B -$B$O(B @xref{Article Highlighting, , $B5-;v$N%O%$%i%$%H(B, gnus-ja}, $B$K$"$j$^$9!#(B +$B$O(B @xref{Article Highlighting, , $B5-;v$N%O%$%i%$%H(B, gnus-ja, The Gnus +Manual}, $B$K$"$j$^$9!#(B @item message-yank-prefix @vindex message-yank-prefix @@ -1957,7 +2005,7 @@ Emacs $B$O%a%C%;!<%8:n@.$r$$$m$$$m$K2u$7$F$7$^$&$3$H$,$G$-$kB?$/$N%F%-%9%H(B $B<0$r;}$C$F$$$^$9(B @lisp -(TYPE PREDICATE FUNCTION) +(@var{type} @var{predicate} @var{function}) @end lisp @table @var @@ -2119,7 +2167,7 @@ Message $B$O$3$l$i$N%j%9%H$H:nMQ$9$k4X?t$rDs6!$7$F$$$^$9(B: $B%I%&@_Dj$rI|3h$5$;$^$9!#(B @dfn{$BF0:n(B} $B$O2A(B} $B$5$l$k<0$G$9!#(B +@sc{cdr} $B$,0z?t$N%j%9%H$G$"$k%j%9%H$+!"(B@code{$BI>2A(B} $B$5$l$k<0$G$9!#(B @node Compatibility @chapter $B8_49@-(B diff --git a/texi/message.texi b/texi/message.texi index 49ddb31..9842735 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @setfilename message -@settitle T-gnus 6.15 Message Manual +@settitle T-gnus 6.16 Message Manual @synindex fn cp @synindex vr cp @synindex pg cp @@ -18,7 +18,7 @@ This file documents Message, the Emacs message composition mode. -Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document @@ -42,13 +42,13 @@ license to the document, as described in section 6 of the license. @tex @titlepage -@title T-gnus 6.15 Message Manual +@title T-gnus 6.16 Message Manual @author by Lars Magne Ingebrigtsen @page @vskip 0pt plus 1filll -Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002 +Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document @@ -88,7 +88,7 @@ Message mode buffers. * Key Index:: List of Message mode keys. @end menu -This manual corresponds to T-gnus 6.15 Message. Message is distributed +This manual corresponds to T-gnus 6.16 Message. Message is distributed with the Gnus distribution bearing the same version number as this manual. @@ -173,9 +173,9 @@ just return @code{nil}, and the normal methods for determining the To header will be used. This function can also return a list. In that case, each list element -should be a cons, where the car should be the name of an header -(eg. @code{Cc}) and the cdr should be the header value -(eg. @samp{larsi@@ifi.uio.no}). All these headers will be inserted into +should be a cons, where the @sc{car} should be the name of a header +(e.g. @code{Cc}) and the @sc{cdr} should be the header value +(e.g. @samp{larsi@@ifi.uio.no}). All these headers will be inserted into the head of the outgoing mail. @@ -312,7 +312,7 @@ constructed. The default value is @code{nil}. If this variable is @code{t} (the default), forwarded messages are included as inline @acronym{MIME} RFC822 parts. If it's @code{nil}, forwarded messages will just be copied inline to the new message, like previous, -non @acronym{MIME}-savvy versions of gnus would do. +non @acronym{MIME}-savvy versions of Gnus would do. @item message-forward-before-signature @vindex message-forward-before-signature @@ -353,6 +353,7 @@ will be removed before popping up the buffer. The default is @node Mailing Lists @section Mailing Lists +@cindex Mail-Followup-To Sometimes while posting to mailing lists, the poster needs to direct followups to the post to specific places. The Mail-Followup-To (MFT) was created to enable just this. Two example scenarios where this is @@ -399,7 +400,7 @@ way. The following variables would come in handy. @vindex message-subscribed-addresses @item message-subscribed-addresses This should be a list of addresses the user is subscribed to. Its -default value is @code{nil}. Example: +default value is @code{nil}. Example: @lisp (setq message-subscribed-addresses '("ding@@gnus.org" "bing@@noose.org")) @@ -425,8 +426,8 @@ There is a pre-defined function in Gnus that is a good candidate for this variable. @code{gnus-find-subscribed-addresses} is a function that returns a list of addresses corresponding to the groups that have the @code{subscribed} (@pxref{Group Parameters, ,Group Parameters, -gnus, The Gnus Manual}) group parameter set to a non-nil value. This -is how you would do it. +gnus, The Gnus Manual}) group parameter set to a non-@code{nil} value. +This is how you would do it. @lisp (setq message-subscribed-address-functions @@ -460,7 +461,7 @@ other headers and set to the value of all addresses in To: and Cc: @findex message-generate-unsubscribed-mail-followup-to @kindex C-c C-f C-m @findex message-goto-mail-followup-to -Hm. ``So'', you ask, ``what if I send an email to a list I am not +Hm. ``So'', you ask, ``what if I send an email to a list I am not subscribed to? I want my MFT to say that I want an extra copy.'' (This is supposed to be interpreted by others the same way as if there were no MFT, but you can use an explicit MFT to override someone else's @@ -491,7 +492,7 @@ Gnus will prompt you for an action. @end table -It is considered good nettiquette to honor MFT, as it is assumed the +It is considered good netiquette to honor MFT, as it is assumed the fellow who posted a message knows where the followups need to go better than you do. @@ -625,9 +626,9 @@ own address. This function inserts such a header automatically. It fetches the contents of the @samp{To:} header in the current mail buffer, and appends the current @code{user-mail-address}. -If the optional argument @code{include-cc} is non-nil, the addresses in -the @samp{Cc:} header are also put into the @samp{Mail-Followup-To:} -header. +If the optional argument @code{include-cc} is non-@code{nil}, the +addresses in the @samp{Cc:} header are also put into the +@samp{Mail-Followup-To:} header. @end table @@ -666,7 +667,7 @@ address from @code{To:} and @code{Cc:} headers. @kindex C-c M-n @findex message-insert-disposition-notification-to Insert a request for a disposition -notification. (@code{message-insert-disposition-notification-to}). +notification. (@code{message-insert-disposition-notification-to}). This means that if the recipient support RFC 2298 she might send you a notification that she received the message. @@ -716,7 +717,7 @@ Replace contents of @samp{To} header with contents of @samp{Cc} or @kindex C-c C-f w @findex message-insert-wide-reply Insert @samp{To} and @samp{Cc} headers as if you were doing a wide -reply. +reply. @item C-c C-f a @kindex C-c C-f a @@ -831,7 +832,7 @@ The most typical thing users want to use the multipart things in be done with the @kbd{C-c C-a} command, which will prompt for a file name and a @acronym{MIME} type. -You can also create arbitrarily complex multiparts using the MML +You can also create arbitrarily complex multiparts using the @acronym{MML} language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME Manual}). @@ -877,12 +878,13 @@ Libidn} installed in order to use this functionality. @cindex encrypt @cindex secure -Using the MML language, Message is able to create digitally signed and -digitally encrypted messages. Message (or rather MML) currently -support @acronym{PGP} (RFC 1991), @acronym{PGP/MIME} (RFC 2015/3156) and @acronym{S/MIME}. -Instructing MML to perform security operations on a @acronym{MIME} part is -done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c -C-m c} key map for encryption, as follows. +Using the @acronym{MML} language, Message is able to create digitally +signed and digitally encrypted messages. Message (or rather +@acronym{MML}) currently support @acronym{PGP} (RFC 1991), +@acronym{PGP/MIME} (RFC 2015/3156) and @acronym{S/MIME}. Instructing +@acronym{MML} to perform security operations on a @acronym{MIME} part is +done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c C-m +c} key map for encryption, as follows. @table @kbd @@ -925,43 +927,22 @@ Digitally encrypt current message using @acronym{PGP/MIME}. @item C-c C-m C-n @kindex C-c C-m C-n @findex mml-unsecure-message -Remove security related MML tags from message. +Remove security related @acronym{MML} tags from message. @end table These commands do not immediately sign or encrypt the message, they -merely insert the proper MML secure tag to instruct the MML engine to -perform that operation when the message is actually sent. They may -perform other operations too, such as locating and retrieving a -@acronym{S/MIME} certificate of the person you wish to send encrypted mail -to. When the mml parsing engine converts your MML into a properly -encoded @acronym{MIME} message, the secure tag will be replaced with either -a part or a multipart tag. If your message contains other mml parts, -a multipart tag will be used; if no other parts are present in your -message a single part tag will be used. This way, message mode will -do the Right Thing (TM) with signed/encrypted multipart messages. - -@vindex mml-signencrypt-style-alist -By default, when encrypting a message, Gnus will use the ``signencrypt'' -mode. If you would like to disable this for a particular message, -give the @code{mml-secure-message-encrypt-*} command a prefix argument. (for -example, @kbd{C-u C-c C-m c p}). Additionally, by default Gnus will -separately sign, then encrypt a message which has the mode -signencrypt. If you would like to change this behavior you can -customize the @code{mml-signencrypt-style-alist} variable. For -example: - - -@lisp -(setq mml-signencrypt-style-alist '(("smime" combined) - ("pgp" combined) - ("pgpmime" combined))) -@end lisp - -Will cause Gnus to sign and encrypt in one pass, thus generating a -single signed and encrypted part. Note that combined sign and encrypt -does not work with all supported OpenPGP implementations (in -particular, @acronym{PGP} version 2 do not support this). +merely insert the proper @acronym{MML} secure tag to instruct the +@acronym{MML} engine to perform that operation when the message is +actually sent. They may perform other operations too, such as locating +and retrieving a @acronym{S/MIME} certificate of the person you wish to +send encrypted mail to. When the mml parsing engine converts your +@acronym{MML} into a properly encoded @acronym{MIME} message, the secure +tag will be replaced with either a part or a multipart tag. If your +message contains other mml parts, a multipart tag will be used; if no +other parts are present in your message a single part tag will be used. +This way, message mode will do the Right Thing (TM) with +signed/encrypted multipart messages. Since signing and especially encryption often is used when sensitive information is sent, you may want to have some way to ensure that your @@ -976,6 +957,12 @@ party the other night, actually will be sent encrypted. RFC822 headers. They only operate on the @acronym{MIME} object. Keep this in mind before sending mail with a sensitive Subject line. +By default, when encrypting a message, Gnus will use the +``signencrypt'' mode, which means the message is both signed and +encrypted. If you would like to disable this for a particular +message, give the @code{mml-secure-message-encrypt-*} command a prefix +argument, e.g., @kbd{C-u C-c C-m c p}. + Actually using the security commands above is not very difficult. At least not compared with making sure all involved programs talk with each other properly. Thus, we now describe what external libraries or @@ -987,24 +974,25 @@ programs are required to make things work, and some small general hints. modern cryptography, @acronym{S/MIME}, various PKCS standards, OpenSSL and so on. -The @acronym{S/MIME} support in Message (and MML) require OpenSSL. OpenSSL -perform the actual @acronym{S/MIME} sign/encrypt operations. OpenSSL can -be found at @uref{http://www.openssl.org/}. OpenSSL 0.9.6 and later -should work. Version 0.9.5a cannot extract mail addresses from -certificates, and it insert a spurious CR character into @acronym{MIME} -separators so you may wish to avoid it if you would like to avoid -being regarded as someone who send strange mail. (Although by sending -@acronym{S/MIME} messages you've probably already lost that contest.) +The @acronym{S/MIME} support in Message (and @acronym{MML}) require +OpenSSL. OpenSSL performs the actual @acronym{S/MIME} sign/encrypt +operations. OpenSSL can be found at @uref{http://www.openssl.org/}. +OpenSSL 0.9.6 and later should work. Version 0.9.5a cannot extract mail +addresses from certificates, and it insert a spurious CR character into +@acronym{MIME} separators so you may wish to avoid it if you would like +to avoid being regarded as someone who send strange mail. (Although by +sending @acronym{S/MIME} messages you've probably already lost that +contest.) To be able to send encrypted mail, a personal certificate is not -required. Message (MML) need a certificate for the person to whom you +required. Message (@acronym{MML}) need a certificate for the person to whom you wish to communicate with though. You're asked for this when you type @kbd{C-c C-m c s}. Currently there are two ways to retrieve this certificate, from a local file or from DNS. If you chose a local file, it need to contain a X.509 certificate in @acronym{PEM} format. If you chose DNS, you're asked for the domain name where the certificate is stored, the default is a good guess. To my belief, -Message (MML) is the first mail agent in the world to support +Message (@acronym{MML}) is the first mail agent in the world to support retrieving @acronym{S/MIME} certificates from DNS, so you're not likely to find very many certificates out there. At least there should be one, stored at the domain @code{simon.josefsson.org}. LDAP @@ -1014,8 +1002,8 @@ command line to retrieve a certificate into a file and use it.) As for signing messages, OpenSSL can't perform signing operations without some kind of configuration. Especially, you need to tell it -where your private key and your certificate is stored. MML uses an -Emacs interface to OpenSSL, aptly named @code{smime.el}, and it +where your private key and your certificate is stored. @acronym{MML} +uses an Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain a @code{custom} group used for this configuration. So, try @kbd{M-x customize-group RET smime RET} and look around. @@ -1034,15 +1022,21 @@ $ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem The @file{key+cert.pem} file should be pointed to from the @code{smime-keys} variable. You should now be able to send signed mail. -@emph{Note!} Your private key is stored unencrypted in the file, so take -care in handling it. +@emph{Note!} Your private key is now stored unencrypted in the file, +so take care in handling it. Storing encrypted keys on the disk are +supported, and Gnus will ask you for a passphrase before invoking +OpenSSL. Read the OpenSSL documentation for how to achieve this. If +you use unencrypted keys (e.g., if they are on a secure storage, or if +you are on a secure single user machine) simply press @code{RET} at +the passphrase prompt. @subsection Using PGP/MIME @acronym{PGP/MIME} requires an external OpenPGP implementation, such -as @uref{http://www.gnupg.org/, GNU Privacy Guard}. One Emacs -interface to OpenPGP implementations, PGG (@pxref{Top, ,PGG, pgg, PGG -Manual}), is included, but Mailcrypt and Florian Weimer's +as @uref{http://www.gnupg.org/, GNU Privacy Guard}. Pre-OpenPGP +implementations such as PGP 2.x and PGP 5.x are also supported. One +Emacs interface to the PGP implementations, PGG (@pxref{Top, ,PGG, +pgg, PGG Manual}), is included, but Mailcrypt and Florian Weimer's @code{gpg.el} are also supported. @vindex gpg-temp-directory @@ -1050,8 +1044,36 @@ Note, if you are using the @code{gpg.el} you must make sure that the directory specified by @code{gpg-temp-directory} have permissions 0700. -Creating your own OpenPGP key is described in detail in the -documentation of your OpenPGP implementation, so we refer to it. +Creating your own key is described in detail in the documentation of +your PGP implementation, so we refer to it. + +If you have imported your old PGP 2.x key into GnuPG, and want to send +signed and encrypted messages to your fellow PGP 2.x users, you'll +discover that the receiver cannot understand what you send. One +solution is to use PGP 2.x instead (i.e., if you use @code{pgg}, set +@code{pgg-default-scheme} to @code{pgp}). If you do want to use +GnuPG, you can use a compatibility script called @code{gpg-2comp} +available from +@uref{http://muppet.faveve.uni-stuttgart.de/~gero/gpg-2comp/}. You +could also convince your fellow PGP 2.x users to convert to GnuPG. +@vindex mml-signencrypt-style-alist +As a final workaround, you can make the sign and encryption work in +two steps; separately sign, then encrypt a message. If you would like +to change this behavior you can customize the +@code{mml-signencrypt-style-alist} variable. For example: + +@lisp +(setq mml-signencrypt-style-alist '(("smime" separate) + ("pgp" separate) + ("pgpauto" separate) + ("pgpmime" separate))) +@end lisp + +This causes to sign and encrypt in two passes, thus generating a +message that can be understood by PGP version 2. + +(Refer to @uref{http://www.gnupg.org/gph/en/pgp2x.html} for more +information about the problem.) @node Various Commands @section Various Commands @@ -1072,7 +1094,7 @@ many places to rotate the text. The default is 13. @vindex message-elide-ellipsis Elide the text between point and mark (@code{message-elide-region}). The text is killed and replaced with the contents of the variable -@code{message-elide-ellipsis}. The default value is to use an ellipsis +@code{message-elide-ellipsis}. The default value is to use an ellipsis (@samp{[...]}). @item C-c C-z @@ -1220,7 +1242,7 @@ controlled by the @code{ispell-message-dictionary-alist} variable: @lisp (setq ispell-message-dictionary-alist '(("^Newsgroups:.*\\bde\\." . "deutsch8") - (".*" . "default"))) + (".*" . "default"))) @end lisp @code{ispell} depends on having the external @samp{ispell} command @@ -1344,7 +1366,7 @@ Responses to messages have subjects that start with @samp{Re: }. This is @emph{not} an abbreviation of the English word ``response'', but is Latin, and means ``in response to''. Some illiterate nincompoops have failed to grasp this fact, and have ``internationalized'' their software -to use abonimations like @samp{Aw: } (``antwort'') or @samp{Sv: } +to use abominations like @samp{Aw: } (``antwort'') or @samp{Sv: } (``svar'') instead, which is meaningless and evil. However, you may have to deal with users that use these evil tools, in which case you may set this variable to a regexp that matches these prefixes. Myself, I @@ -1355,7 +1377,23 @@ responding to a message: @lisp (setq message-subject-re-regexp - "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)") + (concat + "^[ \t]*" + "\\(" + "\\(" + "[Aa][Nn][Tt][Ww]\\.?\\|" ; antw + "[Aa][Ww]\\|" ; aw + "[Ff][Ww][Dd]?\\|" ; fwd + "[Oo][Dd][Pp]\\|" ; odp + "[Rr][Ee]\\|" ; re + "[Rr][\311\351][Ff]\\.?\\|" ; ref + "[Ss][Vv]" ; sv + "\\)" + "\\(\\[[0-9]*\\]\\)" + "*:[ \t]*" + "\\)" + "*[ \t]*" + )) @end lisp @item message-subject-trailing-was-query @@ -1393,6 +1431,13 @@ hidden when composing a message. '(not "From" "Subject" "To" "Cc" "Newsgroups")) @end lisp +@item message-header-synonyms +@vindex message-header-synonyms +A list of lists of header synonyms. E.g., if this list contains a +member list with elements @code{Cc} and @code{To}, then +@code{message-carefully-insert-headers} will not insert a @code{To} +header when the message is already @code{Cc}ed to the recipient. + @end table @@ -1431,8 +1476,8 @@ buffers that are initialized as mail. @findex message-smtpmail-send-it @findex smtpmail-send-it @findex feedmail-send-it -Function used to send the current buffer as mail. The default is -@code{message-send-mail-with-sendmail}. Other valid values include +Function used to send the current buffer as mail. The default is +@code{message-send-mail-with-sendmail}. Other valid values include @code{message-send-mail-with-mh}, @code{message-send-mail-with-qmail}, @code{message-smtpmail-send-it}, @code{smtpmail-send-it} and @code{feedmail-send-it}. @@ -1476,7 +1521,7 @@ the address to use in the @acronym{SMTP} envelope. If it is @item message-mailer-swallows-blank-line @vindex message-mailer-swallows-blank-line Set this to non-@code{nil} if the system's mailer runs the header and -body together. (This problem exists on Sunos 4 when sendmail is run +body together. (This problem exists on SunOS 4 when sendmail is run in remote mode.) The value should be an expression to test whether the problem will actually occur. @@ -1585,9 +1630,9 @@ unlikely that you should need to fiddle with this variable at all. @findex yow @cindex Mime-Version -In addition, you can enter conses into this list. The car of this cons +In addition, you can enter conses into this list. The @sc{car} of this cons should be a symbol. This symbol's name is the name of the header, and -the cdr can either be a string to be entered verbatim as the value of +the @sc{cdr} can either be a string to be entered verbatim as the value of this header, or it can be a function to be called. This function should return a string to be inserted. For instance, if you want to insert @code{Mime-Version: 1.0}, you should enter @code{(Mime-Version . "1.0")} @@ -1595,8 +1640,8 @@ into the list. If you want to insert a funny quote, you could enter something like @code{(X-Yow . yow)} into the list. The function @code{yow} will then be called without any arguments. -If the list contains a cons where the car of the cons is -@code{optional}, the cdr of this cons will only be inserted if it is +If the list contains a cons where the @sc{car} of the cons is +@code{optional}, the @sc{cdr} of this cons will only be inserted if it is non-@code{nil}. If you want to delete an entry from this list, the following Lisp @@ -1739,7 +1784,7 @@ Note that Gnus provides a feature where clicking on `writes:' hides the cited text. If you change the citation line too much, readers of your messages will have to adjust their Gnus, too. See the variable @code{gnus-cite-attribution-suffix}. @xref{Article Highlighting, , -Article Highlighting, gnus}, for details. +Article Highlighting, gnus, The Gnus Manual}, for details. @item message-yank-prefix @vindex message-yank-prefix @@ -1749,7 +1794,7 @@ When you are replying to or following up an article, you normally want to quote the person you are answering. Inserting quoted text is done by @dfn{yanking}, and each line you yank will have @code{message-yank-prefix} prepended to it (except for quoted and -empty lines which uses @code{message-yank-cited-prefix}). The default +empty lines which uses @code{message-yank-cited-prefix}). The default is @samp{> }. @item message-yank-cited-prefix @@ -1757,7 +1802,7 @@ is @samp{> }. @cindex yanking @cindex cited @cindex quoting -When yanking text from a article which contains no text or already +When yanking text from an article which contains no text or already cited text, each line will be prefixed with the contents of this variable. The default is @samp{>}. See also @code{message-yank-prefix}. @@ -1947,7 +1992,7 @@ Hook run after sending messages. @item message-cancel-hook @vindex message-cancel-hook -Hook run when cancelling news articles. +Hook run when canceling news articles. @item message-mode-syntax-table @vindex message-mode-syntax-table @@ -1968,7 +2013,7 @@ message composition doesn't break too bad. Alist of ways to send outgoing messages. Each element has the form @lisp -(TYPE PREDICATE FUNCTION) +(@var{type} @var{predicate} @var{function}) @end lisp @table @var @@ -2137,7 +2182,7 @@ This restores the Gnus window configuration when the message buffer is killed, postponed or exited. An @dfn{action} can be either: a normal function, or a list where the -@code{car} is a function and the @code{cdr} is the list of arguments, or +@sc{car} is a function and the @sc{cdr} is the list of arguments, or a form to be @code{eval}ed. diff --git a/texi/ptexinfmt.el b/texi/ptexinfmt.el index 919dbae..66a507f 100644 --- a/texi/ptexinfmt.el +++ b/texi/ptexinfmt.el @@ -7,6 +7,7 @@ ;; Author: TAKAHASHI Kaoru ;; Yoshiki Hayashi +;; Katsumi Yamaoka ;; Maintainer: TAKAHASHI Kaoru ;; Created: 7 Jul 2000 ;; Keywords: maint, tex, docs, emulation, compatibility @@ -33,29 +34,81 @@ ;; Support texinfmt.el 2.32 or later. +;; Modified by Yamaoka not to use APEL functions. + ;;; Code: + +(require 'backquote) (require 'texinfmt) -(require 'poe) -(require 'broken) ;;; Broken (defvar ptexinfmt-disable-broken-notice-flag t - "If non-nil disable notice, when call `broken-facility'. -This is NO-NOTICE argument in `broken-facility'.") + "If non-nil disable notice, when call `ptexinfmt-broken-facility'. +This is last argument in `ptexinfmt-broken-facility'.") + +(put 'ptexinfmt-broken-facility 'lisp-indent-function 'defun) +(defmacro ptexinfmt-broken-facility (facility docstring assertion + &optional dummy) + "Declare a symbol FACILITY is broken if ASSERTION is nil. +DOCSTRING will be printed if ASSERTION is nil and +`ptexinfmt-disable-broken-notice-flag' is nil." + (` (let ((facility '(, facility)) + (docstring (, docstring)) + (assertion (eval '(, assertion)))) + (put facility 'broken (not assertion)) + (if assertion + nil + (put facility 'broken-docstring docstring) + (if ptexinfmt-disable-broken-notice-flag + nil + (message "BROKEN FACILITY DETECTED: %s" docstring)))))) + +(put 'ptexinfmt-defun-if-broken 'lisp-indent-function 'defun) +(defmacro ptexinfmt-defun-if-broken (&rest args) + "Redefine a function just like `defun' if it is considered broken." + (let ((name (list 'quote (car args)))) + (setq args (cdr args)) + (` (prog1 + (, name) + (if (get (, name) 'broken) + (defalias (, name) + (function (lambda (,@ args))))))))) + +(put 'ptexinfmt-defun-if-void 'lisp-indent-function 'defun) +(defmacro ptexinfmt-defun-if-void (&rest args) + "Define a function just like `defun' unless it is already defined." + (let ((name (list 'quote (car args)))) + (setq args (cdr args)) + (` (prog1 + (, name) + (if (fboundp (, name)) + nil + (defalias (, name) + (function (lambda (,@ args))))))))) + +(put 'ptexinfmt-defvar-if-void 'lisp-indent-function 'defun) +(defmacro ptexinfmt-defvar-if-void (&rest args) + "Define a variable just like `defvar' unless it is already defined." + (let ((name (car args))) + (setq args (cdr args)) + (` (prog1 + (defvar (, name)) + (if (boundp '(, name)) + nil + (defvar (, name) (,@ args))))))) ;; sort -fd -(broken-facility texinfo-format-printindex +(ptexinfmt-broken-facility texinfo-format-printindex "Can't sort on Mule for Windows." (if (and (memq system-type '(windows-nt ms-dos)) ;;; I don't know version threshold. ;;; (string< texinfmt-version "2.37 of 24 May 1997") (boundp 'MULE) (not (featurep 'meadow))) ; Mule for Windows nil - t) - ptexinfmt-disable-broken-notice-flag) + t)) ;; @var -(broken-facility texinfo-format-var +(ptexinfmt-broken-facility texinfo-format-var "Don't perse @var argument." (condition-case nil (with-temp-buffer @@ -64,11 +117,10 @@ This is NO-NOTICE argument in `broken-facility'.") (insert "@var{@asis{foo}}\n") (texinfo-format-expand-region (point-min) (point-max)) t)) - (error nil)) - ptexinfmt-disable-broken-notice-flag) + (error nil))) ;; @xref -(broken-facility texinfo-format-xref +(ptexinfmt-broken-facility texinfo-format-xref "Can't format @xref, 1st argument is empty." (condition-case nil (with-temp-buffer @@ -77,24 +129,22 @@ This is NO-NOTICE argument in `broken-facility'.") (insert "@xref{, xref, , file}\n") (texinfo-format-expand-region (point-min) (point-max)) t)) - (error nil)) - ptexinfmt-disable-broken-notice-flag) + (error nil))) ;; @uref -(broken-facility texinfo-format-uref +(ptexinfmt-broken-facility texinfo-format-uref "Parse twice @uref argument." (condition-case nil (with-temp-buffer (let (texinfo-enclosure-list texinfo-alias-list) (texinfo-mode) - (insert "@uref{mailto:foo@@bar.com}\n") + (insert "@uref{mailto:foo@@noncommand.example.com}\n") (texinfo-format-expand-region (point-min) (point-max)) t)) - (error nil)) - ptexinfmt-disable-broken-notice-flag) + (error nil))) ;; @multitable -(broken-facility texinfo-multitable-widths +(ptexinfmt-broken-facility texinfo-multitable-widths "`texinfo-multitable-widths' unsupport wide-char." (if (fboundp 'texinfo-multitable-widths) (with-temp-buffer @@ -106,13 +156,11 @@ This is NO-NOTICE argument in `broken-facility'.") nil t))) ;; function definition is void - t) - ptexinfmt-disable-broken-notice-flag) + t)) -(broken-facility texinfo-multitable-item +(ptexinfmt-broken-facility texinfo-multitable-item "`texinfo-multitable-item' unsupport wide-char." - (if-broken texinfo-multitable-widths nil t) - ptexinfmt-disable-broken-notice-flag) + (not (get 'texinfo-multitable-widths 'broken))) ;;; Hardcopy and HTML (discard) @@ -152,12 +200,17 @@ This is NO-NOTICE argument in `broken-facility'.") (put 'page 'texinfo-format 'texinfo-discard-line) (put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) +;; @tie{} (makeinfo 4.3 or later) +(put 'tie 'texinfo-format 'texinfo-format-tie) +(ptexinfmt-defun-if-void texinfo-format-tie () + (texinfo-parse-arg-discard) + (insert " ")) ;;; Directory File ;; @direcategory (put 'dircategory 'texinfo-format 'texinfo-format-dircategory) -(defun-maybe texinfo-format-dircategory () +(ptexinfmt-defun-if-void texinfo-format-dircategory () (let ((str (texinfo-parse-arg-discard))) (delete-region (point) (progn @@ -167,13 +220,13 @@ This is NO-NOTICE argument in `broken-facility'.") ;; @direntry (put 'direntry 'texinfo-format 'texinfo-format-direntry) -(defun-maybe texinfo-format-direntry () +(ptexinfmt-defun-if-void texinfo-format-direntry () (texinfo-push-stack 'direntry nil) (texinfo-discard-line) (insert "START-INFO-DIR-ENTRY\n")) (put 'direntry 'texinfo-end 'texinfo-end-direntry) -(defun-maybe texinfo-end-direntry () +(ptexinfmt-defun-if-void texinfo-end-direntry () (texinfo-discard-command) (insert "END-INFO-DIR-ENTRY\n\n") (texinfo-pop-stack 'direntry)) @@ -213,14 +266,14 @@ This is NO-NOTICE argument in `broken-facility'.") ;; @ifnotinfo ... @end ifnotinfo (makeinfo 3.11 or later) (put 'ifnotinfo 'texinfo-format 'texinfo-format-ifnotinfo) -(defun-maybe texinfo-format-ifnotinfo () +(ptexinfmt-defun-if-void texinfo-format-ifnotinfo () (delete-region texinfo-command-start (progn (re-search-forward "@end ifnotinfo[ \t]*\n") (point)))) ;; @html ... @end html (makeinfo 3.11 or later) (put 'html 'texinfo-format 'texinfo-format-html) -(defun-maybe texinfo-format-html () +(ptexinfmt-defun-if-void texinfo-format-html () (delete-region texinfo-command-start (progn (re-search-forward "@end html[ \t]*\n") (point)))) @@ -234,7 +287,7 @@ This is NO-NOTICE argument in `broken-facility'.") ;; @ifplaintext ... @end ifplaintext (makeinfo 4.2 or later) (put 'ifplaintext 'texinfo-format 'texinfo-format-ifplaintext) -(defun-maybe texinfo-format-ifplaintext () +(ptexinfmt-defun-if-void texinfo-format-ifplaintext () (delete-region texinfo-command-start (progn (re-search-forward "@end ifplaintext[ \t]*\n") (point)))) @@ -250,26 +303,24 @@ This is NO-NOTICE argument in `broken-facility'.") ;; @acronym (put 'acronym 'texinfo-format 'texinfo-format-var) -(when-broken texinfo-format-var - (fmakunbound 'texinfo-format-var)) -(defun-maybe texinfo-format-var () +(ptexinfmt-defun-if-broken texinfo-format-var () (let ((arg (texinfo-parse-expanded-arg))) (texinfo-discard-command) (insert (upcase arg)))) ;; @key (put 'key 'texinfo-format 'texinfo-format-key) -(defun-maybe texinfo-format-key () +(ptexinfmt-defun-if-void texinfo-format-key () (insert (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @email{EMAIL-ADDRESS[, DISPLAYED-TEXT]} (put 'email 'texinfo-format 'texinfo-format-email) -(defun-maybe texinfo-format-email () +(ptexinfmt-defun-if-void texinfo-format-email () "Format EMAIL-ADDRESS and optional DISPLAYED-TXT. Insert < ... > around EMAIL-ADDRESS." (let ((args (texinfo-format-parse-args))) - (texinfo-discard-command) + (texinfo-discard-command) ;; if displayed-text (if (nth 1 args) (insert (nth 1 args) " <" (nth 0 args) ">") @@ -277,7 +328,7 @@ Insert < ... > around EMAIL-ADDRESS." ;; @option (put 'option 'texinfo-format 'texinfo-format-option) -(defun texinfo-format-option () +(ptexinfmt-defun-if-void texinfo-format-option () "Insert ` ... ' around arg unless inside a table; in that case, no quotes." ;; `looking-at-backward' not available in v. 18.57, 20.2 ;; searched-for character is a control-H @@ -288,168 +339,193 @@ Insert < ... > around EMAIL-ADDRESS." (insert (texinfo-parse-arg-discard))) (goto-char texinfo-command-start)) +;; @verb{TEXT} (makeinfo 4.1 or later) +(put 'verb 'texinfo-format 'texinfo-format-verb) +(ptexinfmt-defun-if-void texinfo-format-verb () + "Format text between non-quoted unique delimiter characters verbatim. +Enclose the verbatim text, including the delimiters, in braces. Print +text exactly as written (but not the delimiters) in a fixed-width. + +For example, @verb\{|@|\} results in @ and +@verb\{+@'e?`!`+} results in @'e?`!`." + + (let ((delimiter (buffer-substring-no-properties + (1+ texinfo-command-end) (+ 2 texinfo-command-end)))) + (unless (looking-at "{") + (error "Not found: @verb start brace")) + (delete-region texinfo-command-start (+ 2 texinfo-command-end)) + (search-forward delimiter)) + (delete-backward-char 1) + (unless (looking-at "}") + (error "Not found: @verb end brace")) + (delete-char 1)) ;;; Accents and Special characters ;; @pounds{} ==> # Pounds Sterling (put 'pounds 'texinfo-format 'texinfo-format-pounds) -(defun-maybe texinfo-format-pounds () +(ptexinfmt-defun-if-void texinfo-format-pounds () (texinfo-parse-arg-discard) (insert "#")) ;; @OE{} ==> OE French-OE-ligature (put 'OE 'texinfo-format 'texinfo-format-French-OE-ligature) -(defun-maybe texinfo-format-French-OE-ligature () +(ptexinfmt-defun-if-void texinfo-format-French-OE-ligature () (insert "OE" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @oe{} ==> oe (put 'oe 'texinfo-format 'texinfo-format-French-oe-ligature) -(defun-maybe texinfo-format-French-oe-ligature () ; lower case +(ptexinfmt-defun-if-void texinfo-format-French-oe-ligature () ; lower case (insert "oe" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @AA{} ==> AA Scandinavian-A-with-circle (put 'AA 'texinfo-format 'texinfo-format-Scandinavian-A-with-circle) -(defun-maybe texinfo-format-Scandinavian-A-with-circle () +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-A-with-circle () (insert "AA" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @aa{} ==> aa (put 'aa 'texinfo-format 'texinfo-format-Scandinavian-a-with-circle) -(defun-maybe texinfo-format-Scandinavian-a-with-circle () ; lower case +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-a-with-circle () ; lower case (insert "aa" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @AE{} ==> AE Latin-Scandinavian-AE (put 'AE 'texinfo-format 'texinfo-format-Latin-Scandinavian-AE) -(defun-maybe texinfo-format-Latin-Scandinavian-AE () +(ptexinfmt-defun-if-void texinfo-format-Latin-Scandinavian-AE () (insert "AE" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @ae{} ==> ae (put 'ae 'texinfo-format 'texinfo-format-Latin-Scandinavian-ae) -(defun-maybe texinfo-format-Latin-Scandinavian-ae () ; lower case +(ptexinfmt-defun-if-void texinfo-format-Latin-Scandinavian-ae () ; lower case (insert "ae" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @ss{} ==> ss German-sharp-S (put 'ss 'texinfo-format 'texinfo-format-German-sharp-S) -(defun-maybe texinfo-format-German-sharp-S () +(ptexinfmt-defun-if-void texinfo-format-German-sharp-S () (insert "ss" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @questiondown{} ==> ? upside-down-question-mark (put 'questiondown 'texinfo-format 'texinfo-format-upside-down-question-mark) -(defun-maybe texinfo-format-upside-down-question-mark () +(ptexinfmt-defun-if-void texinfo-format-upside-down-question-mark () (insert "?" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @exclamdown{} ==> ! upside-down-exclamation-mark (put 'exclamdown 'texinfo-format 'texinfo-format-upside-down-exclamation-mark) -(defun-maybe texinfo-format-upside-down-exclamation-mark () +(ptexinfmt-defun-if-void texinfo-format-upside-down-exclamation-mark () (insert "!" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @L{} ==> L/ Polish suppressed-L (Lslash) (put 'L 'texinfo-format 'texinfo-format-Polish-suppressed-L) -(defun-maybe texinfo-format-Polish-suppressed-L () +(ptexinfmt-defun-if-void texinfo-format-Polish-suppressed-L () (insert (texinfo-parse-arg-discard) "/L") (goto-char texinfo-command-start)) ;; @l{} ==> l/ Polish suppressed-L (Lslash) (lower case) (put 'l 'texinfo-format 'texinfo-format-Polish-suppressed-l-lower-case) -(defun-maybe texinfo-format-Polish-suppressed-l-lower-case () +(ptexinfmt-defun-if-void texinfo-format-Polish-suppressed-l-lower-case () (insert (texinfo-parse-arg-discard) "/l") (goto-char texinfo-command-start)) ;; @O{} ==> O/ Scandinavian O-with-slash (put 'O 'texinfo-format 'texinfo-format-Scandinavian-O-with-slash) -(defun-maybe texinfo-format-Scandinavian-O-with-slash () +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-O-with-slash () (insert (texinfo-parse-arg-discard) "O/") (goto-char texinfo-command-start)) ;; @o{} ==> o/ Scandinavian O-with-slash (lower case) (put 'o 'texinfo-format 'texinfo-format-Scandinavian-o-with-slash-lower-case) -(defun-maybe texinfo-format-Scandinavian-o-with-slash-lower-case () +(ptexinfmt-defun-if-void texinfo-format-Scandinavian-o-with-slash-lower-case () (insert (texinfo-parse-arg-discard) "o/") (goto-char texinfo-command-start)) ;; @,{c} ==> c, cedilla accent (put ', 'texinfo-format 'texinfo-format-cedilla-accent) -(defun-maybe texinfo-format-cedilla-accent () +(ptexinfmt-defun-if-void texinfo-format-cedilla-accent () (insert (texinfo-parse-arg-discard) ",") (goto-char texinfo-command-start)) ;; @dotaccent{o} ==> .o overdot-accent (put 'dotaccent 'texinfo-format 'texinfo-format-overdot-accent) -(defun-maybe texinfo-format-overdot-accent () +(ptexinfmt-defun-if-void texinfo-format-overdot-accent () (insert "." (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @ubaraccent{o} ==> _o underbar-accent (put 'ubaraccent 'texinfo-format 'texinfo-format-underbar-accent) -(defun-maybe texinfo-format-underbar-accent () +(ptexinfmt-defun-if-void texinfo-format-underbar-accent () (insert "_" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @udotaccent{o} ==> o-. underdot-accent (put 'udotaccent 'texinfo-format 'texinfo-format-underdot-accent) -(defun-maybe texinfo-format-underdot-accent () +(ptexinfmt-defun-if-void texinfo-format-underdot-accent () (insert (texinfo-parse-arg-discard) "-.") (goto-char texinfo-command-start)) ;; @H{o} ==> ""o long Hungarian umlaut (put 'H 'texinfo-format 'texinfo-format-long-Hungarian-umlaut) -(defun-maybe texinfo-format-long-Hungarian-umlaut () +(ptexinfmt-defun-if-void texinfo-format-long-Hungarian-umlaut () (insert "\"\"" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @ringaccent{o} ==> *o ring accent (put 'ringaccent 'texinfo-format 'texinfo-format-ring-accent) -(defun-maybe texinfo-format-ring-accent () +(ptexinfmt-defun-if-void texinfo-format-ring-accent () (insert "*" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @tieaccent{oo} ==> [oo tie after accent (put 'tieaccent 'texinfo-format 'texinfo-format-tie-after-accent) -(defun-maybe texinfo-format-tie-after-accent () +(ptexinfmt-defun-if-void texinfo-format-tie-after-accent () (insert "[" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @u{o} ==> (o breve accent (put 'u 'texinfo-format 'texinfo-format-breve-accent) -(defun-maybe texinfo-format-breve-accent () +(ptexinfmt-defun-if-void texinfo-format-breve-accent () (insert "(" (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @v{o} ==> i dotless i and dotless j (put 'dotless 'texinfo-format 'texinfo-format-dotless) -(defun-maybe texinfo-format-dotless () +(ptexinfmt-defun-if-void texinfo-format-dotless () (insert (texinfo-parse-arg-discard)) (goto-char texinfo-command-start)) ;; @. (put '\. 'texinfo-format 'texinfo-format-\.) -(defun-maybe texinfo-format-\. () +(ptexinfmt-defun-if-void texinfo-format-\. () (texinfo-discard-command) (insert ".")) ;; @: (put '\: 'texinfo-format 'texinfo-format-\:) -(defun-maybe texinfo-format-\: () +(ptexinfmt-defun-if-void texinfo-format-\: () (texinfo-discard-command)) ;; @- (put '\- 'texinfo-format 'texinfo-format-soft-hyphen) -(defun-maybe texinfo-format-soft-hyphen () +(ptexinfmt-defun-if-void texinfo-format-soft-hyphen () + (texinfo-discard-command)) + +;; @/ +(put '\/ 'texinfo-format 'texinfo-format-\/) +(ptexinfmt-defun-if-void texinfo-format-\/ () (texinfo-discard-command)) @@ -457,9 +533,7 @@ Insert < ... > around EMAIL-ADDRESS." ;; @ref, @xref (put 'ref 'texinfo-format 'texinfo-format-xref) -(when-broken texinfo-format-xref - (fmakunbound 'texinfo-format-xref)) -(defun-maybe texinfo-format-xref () +(ptexinfmt-defun-if-broken texinfo-format-xref () (let ((args (texinfo-format-parse-args))) (texinfo-discard-command) (insert "*Note ") @@ -472,11 +546,9 @@ Insert < ... > around EMAIL-ADDRESS." (unless (null (nth 0 args)) (insert (nth 0 args))))))) -;; @uref +;; @uref{URL [,TEXT] [,REPLACEMENT]} (put 'uref 'texinfo-format 'texinfo-format-uref) -(when-broken texinfo-format-uref - (fmakunbound 'texinfo-format-uref)) -(defun-maybe texinfo-format-uref () +(ptexinfmt-defun-if-broken texinfo-format-uref () "Format URL and optional URL-TITLE. Insert ` ... ' around URL if no URL-TITLE argument; otherwise, insert URL-TITLE followed by URL in parentheses." @@ -489,7 +561,7 @@ otherwise, insert URL-TITLE followed by URL in parentheses." ;; @inforef (put 'inforef 'texinfo-format 'texinfo-format-inforef) -(defun-maybe texinfo-format-inforef () +(ptexinfmt-defun-if-void texinfo-format-inforef () (let ((args (texinfo-format-parse-args))) (texinfo-discard-command) (if (nth 1 args) @@ -510,7 +582,7 @@ otherwise, insert URL-TITLE followed by URL in parentheses." ;;; New command definition ;; @alias NEW=EXISTING (put 'alias 'texinfo-format 'texinfo-alias) -(defun-maybe texinfo-alias () +(ptexinfmt-defun-if-void texinfo-alias () (let ((start (1- (point))) args) (skip-chars-forward " ") @@ -526,10 +598,21 @@ otherwise, insert URL-TITLE followed by URL in parentheses." (texinfo-discard-command)))) +;;; Indent +;; @exampleindent INDENT (makeinfo 4.0 or later) + +;; @paragraphindent INDENT (makeinfo 4.0 or later) +;; INDENT: asis, 0, n + +;; @firstparagraphindent WORD (makeinfo 4.6 or later) +;; WORD: none, insert + + + ;;; Special -;; @image{FILENAME, [WIDTH], [HEIGHT]} +;; @image{FILENAME [, WIDTH] [, HEIGHT]} (put 'image 'texinfo-format 'texinfo-format-image) -(defun-maybe texinfo-format-image () +(ptexinfmt-defun-if-void texinfo-format-image () ;; I don't know makeinfo parse FILENAME. (let ((args (texinfo-format-parse-args)) filename) @@ -545,24 +628,22 @@ otherwise, insert URL-TITLE followed by URL in parentheses." ;; @hyphenation command discards an argument within braces (put 'hyphenation 'texinfo-format 'texinfo-discard-command-and-arg) -(defun-maybe texinfo-discard-command-and-arg () +(ptexinfmt-defun-if-void texinfo-discard-command-and-arg () "Discard both @-command and its argument in braces." (goto-char texinfo-command-end) (forward-list 1) (setq texinfo-command-end (point)) (delete-region texinfo-command-start texinfo-command-end)) - -;; @exampleindent - - ;;; @multitable ... @end multitable -(defvar-maybe texinfo-extra-inter-column-width 0 +(ptexinfmt-defvar-if-void texinfo-extra-inter-column-width 0 "*Number of extra spaces between entries (columns) in @multitable.") -(defvar-maybe texinfo-multitable-buffer-name "*multitable-temporary-buffer*") -(defvar-maybe texinfo-multitable-rectangle-name "texinfo-multitable-temp-") +(ptexinfmt-defvar-if-void texinfo-multitable-buffer-name + "*multitable-temporary-buffer*") +(ptexinfmt-defvar-if-void texinfo-multitable-rectangle-name + "texinfo-multitable-temp-") ;; These commands are defined in texinfo.tex for printed output. (put 'multitableparskip 'texinfo-format 'texinfo-discard-line-with-args) @@ -572,7 +653,7 @@ otherwise, insert URL-TITLE followed by URL in parentheses." (put 'multitable 'texinfo-format 'texinfo-multitable) -(defun-maybe texinfo-multitable () +(ptexinfmt-defun-if-void texinfo-multitable () "Produce multi-column tables." ;; This function pushes information onto the `texinfo-stack'. @@ -589,15 +670,12 @@ otherwise, insert URL-TITLE followed by URL in parentheses." (texinfo-discard-line-with-args)) (put 'multitable 'texinfo-end 'texinfo-end-multitable) -(defun-maybe texinfo-end-multitable () +(ptexinfmt-defun-if-void texinfo-end-multitable () "Discard the @end multitable line and pop the stack of multitable." (texinfo-discard-command) (texinfo-pop-stack 'multitable)) -(when-broken texinfo-multitable-widths - (fmakunbound 'texinfo-multitable-widths)) - -(defun-maybe texinfo-multitable-widths () +(ptexinfmt-defun-if-broken texinfo-multitable-widths () "Return list of widths of each column in a multi-column table." (let (texinfo-multitable-width-list) ;; Fractions format: @@ -632,16 +710,19 @@ otherwise, insert URL-TITLE followed by URL in parentheses." ;; forward-sexp works with braces in Texinfo mode (progn (forward-sexp 1) (1- (point))))) (setq texinfo-multitable-width-list - (cons (- (progn (goto-char end-of-template) (current-column)) - (progn (goto-char start-of-template) (current-column))) + (cons (- (progn + (goto-char end-of-template) + (current-column)) + (progn + (goto-char start-of-template) + (current-column))) texinfo-multitable-width-list)) ;; Remove carriage return from within a template, if any. ;; This helps those those who want to use more than ;; one line's worth of words in @multitable line. (narrow-to-region start-of-template end-of-template) (goto-char (point-min)) - (while (search-forward " -" nil t) + (while (search-forward "\n" nil t) (delete-char -1)) (goto-char (point-max)) (widen) @@ -649,8 +730,8 @@ otherwise, insert URL-TITLE followed by URL in parentheses." ;; ;; Case 3: Trouble (t - (error - "You probably need to specify column widths for @multitable correctly"))) + (error "\ +You probably need to specify column widths for @multitable correctly"))) ;; Check whether columns fit on page. (let ((desired-columns (+ @@ -661,14 +742,13 @@ otherwise, insert URL-TITLE followed by URL in parentheses." ;; sum of spaces for each entry (apply '+ texinfo-multitable-width-list)))) (if (> desired-columns fill-column) - (error - (format - "Multi-column table width, %d chars, is greater than page width, %d chars." - desired-columns fill-column)))) + (error (format "\ +Multi-column table width, %d chars, is greater than page width, %d chars." + desired-columns fill-column)))) texinfo-multitable-width-list)) ;; @item A1 @tab A2 @tab A3 -(defun-maybe texinfo-multitable-extract-row () +(ptexinfmt-defun-if-void texinfo-multitable-extract-row () "Return multitable row, as a string. End of row is beginning of next @item or beginning of @end. Cells within rows are separated by @tab." @@ -685,11 +765,8 @@ Cells within rows are separated by @tab." (delete-region texinfo-command-start end) row)) -(when-broken texinfo-multitable-item - (fmakunbound 'texinfo-multitable-item)) - (put 'multitable 'texinfo-item 'texinfo-multitable-item) -(defun-maybe texinfo-multitable-item () +(ptexinfmt-defun-if-void texinfo-multitable-item () "Format a row within a multicolumn table. Cells in row are separated by @tab. Widths of cells are specified by the arguments in the @multitable line. @@ -711,7 +788,7 @@ This command is executed when texinfmt sees @item inside @multitable." (insert unformated-row) (goto-char (point-min)) ;; 1. Check for correct number of @tab in line. - (let ((tab-number 1)) ; one @tab between two columns + (let ((tab-number 1)) ;; one @tab between two columns (while (search-forward "@tab" nil t) (setq tab-number (1+ tab-number))) (if (/= tab-number (length table-widths)) @@ -744,21 +821,23 @@ This command is executed when texinfmt sees @item inside @multitable." (delete-region (point) (save-excursion (end-of-line) (point))) ;; Temorarily set texinfo-stack to nil so texinfo-format-scan ;; does not see an unterminated @multitable. - (let (texinfo-stack) ; nil + (let (texinfo-stack) ;; nil (texinfo-format-scan)) - (let (fill-prefix) ; no fill prefix + (let (fill-prefix) ;; no fill prefix (fill-region (point-min) (point-max))) (setq table-entry-height (max table-entry-height (count-lines (point-min) (point-max)))) ;; 3. Move point to end of bottom line, and pad that line to fill column. (goto-char (point-min)) (forward-line (1- table-entry-height)) - (let* ((beg (point)) ; beginning of line + (let* ((beg (point)) ;; beginning of line ;; add one more space for inter-column spacing (needed-whitespace (1+ (- fill-column - (progn (end-of-line) (current-column)))))) ; end of existing line + (progn + (end-of-line) + (current-column)))))) ;; end of existing line (insert (make-string (if (> needed-whitespace 0) needed-whitespace 1) ? ))) @@ -795,10 +874,7 @@ This command is executed when texinfmt sees @item inside @multitable." (setq fill-column existing-fill-column))) -(when-broken texinfo-format-printindex - (fmakunbound 'texinfo-format-printindex)) - -(defun-maybe texinfo-format-printindex () +(ptexinfmt-defun-if-broken texinfo-format-printindex () (let ((indexelts (symbol-value (cdr (assoc (texinfo-parse-arg-discard) texinfo-indexvar-alist)))) diff --git a/texi/refcard.tex b/texi/refcard.tex index 92ed19d..8028687 100644 --- a/texi/refcard.tex +++ b/texi/refcard.tex @@ -113,17 +113,18 @@ \SortSummary \subsection*{Score (Value) Commands} \Scoring - \subsection*{Extract Series (Uudecode etc)} - \ExtractSeries \subsection*{Output Articles} \OutputArticles + \subsection*{Extract Series (Uudecode etc)} + \ExtractSeries \subsection*{MIME operations from the Summary-Buffer} \MIMESummary % \subsection*{Post, Followup, Reply, Forward, Cancel} \PostReplyetc - \subsection*{Message-Composition} - \MsgCompositionGeneral + \newpage + \subsection*{Message Composition} + \MsgCompositionGeneral \subsubsection*{Jumping in message-buffer} \MsgCompositionMovementArticle \subsubsection*{Attachments/MML} diff --git a/texi/sieve.texi b/texi/sieve.texi index e4403b9..6bfcf2f 100644 --- a/texi/sieve.texi +++ b/texi/sieve.texi @@ -135,7 +135,7 @@ indentation. Sieve mode has its own abbrev table (@code{sieve-mode-syntax-table}). In addition to the editing utility functions, Sieve mode also contains -bindings to manage Sieve scripts remotely. @pxref{Managing Sieve}. +bindings to manage Sieve scripts remotely. @xref{Managing Sieve}. @table @kbd @@ -162,7 +162,7 @@ on a remote server. It can be invoked with @kbd{M-x sieve-manage RET}, which queries the user for a server and if necessary, user credentials to use. -When a server has been succesfully contacted, the Manage Sieve buffer +When a server has been successfully contacted, the Manage Sieve buffer looks something like: @example diff --git a/texi/texi2latex.el b/texi/texi2latex.el index 237e8ad..a5e5a26 100644 --- a/texi/texi2latex.el +++ b/texi/texi2latex.el @@ -143,6 +143,8 @@ (insert "\\\\")) ((equal command "sp") (replace-match "" t t)) + ((equal command ":") + (replace-match "" t t)) ((member command '("deffn" "defvar" "defun")) (replace-match "" t t)) ((equal command "node") @@ -275,7 +277,8 @@ (latexi-exchange-command (concat "gnus" command) arg)) ((member command '("sc" "file" "dfn" "emph" "kbd" "key" "uref" "code" "samp" "var" "strong" "i" - "result" "email" "env" "r")) + "result" "email" "env" "r" "command" "asis" + "url")) (goto-char (match-beginning 0)) (delete-char 1) (insert "\\gnus"))