.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
** 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
** 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
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.
** 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
`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.
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.
** 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.
** (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.
** 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
** 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.
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.
** 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.
`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
("^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.
----------------------------------------------------------------------
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
-This package contains a alpha version of Gnus. The lisp directory
+This package contains a beta version of Gnus. The lisp directory
contains the source lisp files, and the texi directory contains a
draft of the Gnus info pages.
+2003-05-14 Lars Magne Ingebrigtsen <lars@ingebrigtsen.no>
+
+ * gnus.el: Gnus v5.10.2 is released.
+
+2003-05-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * 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 <jik@kamens.brookline.ma.us>
+
+ * gnus-sum.el (gnus-summary-exit): Added `leave-hidden'. (Tiny
+ patch.)
+
+2003-05-13 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * 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 <yamaoka@jpl.org>
+
+ * dgnushack.el (assq-delete-all): New compiler macro for Emacs 20.
+
+2003-05-12 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * lpath.el: Fbind find-coding-system.
+
+ * dgnushack.el (dgnushack-make-load): Remove redundant format call
+ in message. Suggested by Yoichi NAKAYAMA <yoichi@geiin.org>.
+ * pop3.el (pop3-movemail): Ditto.
+
+2003-05-12 Colin Marquardt <c.marquardt@alcatel.de> (tiny change)
+
+ * gnus.el (gnus-agent): Docstring fix.
+
+2003-05-12 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * 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 <kgreiner@xpediantsolutions.com>
+
+ * 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 <fx@gnu.org>
+
+ * 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 <jas@extundo.com>
+
+ * pgg.el (pgg-temp-buffer-show-function): Reuse existing visible
+ output window if one is available. Tiny patch from Ville Skytt\e,Ad\e(B
+ <scop@xemacs.org>.
+
+2003-05-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-agent.el (gnus-agent-expire-unagentized-dirs): Added
+ space.
+
+2003-05-11 Jesper Harder <harder@ifa.au.dk>
+
+ * 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 <harder@ifa.au.dk>
+
+ * gnus-cite.el (gnus-article-hide-citation-maybe): Make toggling
+ work. Update mode-line.
+
+2003-05-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus.el (gnus-logo-color-alist): Added no colours.
+
+2003-05-09 Dave Love <fx@gnu.org>
+
+ * 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 <tzz@lifelogs.com>
+
+ * 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 <jdc@chow.mat.jhu.edu>
+ (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 <harder@ifa.au.dk>
+
+ * gnus-picon.el (gnus-picon-transform-address): Parse the encoded
+ address.
+
+2003-05-08 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * 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 <niklas.morberg@axis.com>
+
+2003-05-08 Kai Gro\e,A_\e(Bjohann <kai.grossjohann@gmx.net>
+
+ * gnus-sum.el (gnus-summary-next-page): Mention
+ `gnus-article-skip-boring' in docstring.
+
+2003-05-08 Jesper Harder <harder@ifa.au.dk>
+
+ * 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 <zsh@cs.rochester.edu>
+
+ * 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 <fx@gnu.org>
+
+ * 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 <harder@ifa.au.dk>
+
+ * message.el (message-kill-to-signature): Fix.
+
+2003-05-06 Jesper Harder <harder@ifa.au.dk>
+
+ * 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 <fx@gnu.org>
+
+ * mm-util.el (mm-default-multibyte-p): New.
+ (mm-coding-system-p): Maybe use find-coding-systems.
+
+2003-05-04 Dave Love <fx@gnu.org>
+
+ * 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 <harder@ifa.au.dk>
+
+ * 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 <deskpot@despammed.com> (tiny change)
+
+ * gnus-util.el (gnus-multiple-choice): Add ", ?".
+
+2003-05-03 Dave Love <fx@gnu.org>
+
+ * 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 <fx@gnu.org>
+
+ * 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 <larsi@gnus.org>
+
+ * nnrss.el (nnrss-find-rss-via-syndic8): Indent.
+
+2003-05-01 Mark A. Hershberger <mah@everybody.org>
+
+ * nnrss.el (nnrss-find-rss-via-syndic8): Don't error out.
+
+2003-05-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus.el (gnus-version-number): Bump.
+
+2003-05-01 Teodor Zlatanov <tzz@lifelogs.com>
+
+ * spam-report.el (spam-report-gmane-regex): docstring fix. From
+ Jon Ericson <Jon.Ericson@jpl.nasa.gov> (tiny change)
+
+ * gnus.el (gnus-install-group-spam-parameters): docstring fix.
+ From Jon Ericson <Jon.Ericson@jpl.nasa.gov> (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 <lars@ingebrigtsen.no>
* gnus.el: Gnus v5.10.1 is released.
;; Define compiler macros for the functions provided by cl in old Emacsen.
(unless (featurep 'xemacs)
+ (define-compiler-macro assq-delete-all (&whole form key alist)
+ (if (>= emacs-major-version 21)
+ form
+ `(let* ((key ,key)
+ (alist ,alist)
+ (tail alist))
+ (while tail
+ (if (and (consp (car tail)) (eq (car (car tail)) key))
+ (setq alist (delq (car tail) alist)))
+ (setq tail (cdr tail)))
+ alist)))
+
(define-compiler-macro butlast (&whole form x &optional n)
(if (>= emacs-major-version 21)
form
(batch-update-autoloads)))
(defun dgnushack-make-load ()
- (message (format "Generating %s..." dgnushack-gnus-load-file))
+ (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)
(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))
+ (message "Compiling %s..." dgnushack-gnus-load-file)
(byte-compile-file dgnushack-gnus-load-file))
;;; dgnushack.el ends here
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-days-until-old agent-days-until-old)
+ gnus-agent-cat-enable-expiration agent-enable-expiration)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-enable-expiration agent-enable-expiration)
+ gnus-agent-cat-groups agent-groups)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-groups agent-groups)
+ gnus-agent-cat-high-score agent-high-score)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-high-score agent-high-score)
+ gnus-agent-cat-length-when-long agent-length-when-long)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-length-when-long agent-length-when-long)
+ gnus-agent-cat-length-when-short agent-length-when-short)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-length-when-short agent-length-when-short)
+ gnus-agent-cat-low-score agent-low-score)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-low-score agent-low-score)
+ gnus-agent-cat-predicate agent-predicate)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-predicate agent-predicate)
+ gnus-agent-cat-score-file agent-score-file)
(gnus-agent-cat-defaccessor
- gnus-agent-cat-score-file agent-score-file)
+ gnus-agent-cat-disable-undownloaded-faces agent-disable-undownloaded-faces)
(eval-when-compile
(defsetf gnus-agent-cat-groups (category) (groups)
(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
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
(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."
(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
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)
"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"))))
(require 'gnus)
(require 'gnus-range)
+(require 'gnus-art)
(require 'message) ; for message-cite-prefix-regexp
;;; Customization:
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."
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)
(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)
)
(defun gnus-trim-whitespace (s)
(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))
(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."
;; 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 ")
(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"))
(autoload 'smiley-region "smiley")
+;; Fixme: shouldn't require message
+(autoload 'message-text-with-property "message")
(defun gnus-kill-all-overlays ()
"Delete all overlays in the current buffer."
(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
(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))))
(gnus-add-wash-type 'xface))))))
(defun gnus-grab-cam-x-face ()
(require 'message)
(require 'gnus-range)
-(eval-when-compile
- (defun gnus-agent-expire (a b c)))
+(autoload 'gnus-agent-expire "gnus-agent")
(defcustom gnus-open-server-hook nil
"Hook called just before opening connection to the news server."
;;; 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 <hardaker@ece.ucdavis.edu>
(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.
+ (mail-encode-encoded-word-string
+ (or (mail-fetch-field header) ""))))
spec file point cache)
(dolist (address addresses)
(setq address (car address))
(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 'boolean)
+
+(defcustom gnus-registry-cache-file "~/.gnus.registry.eld"
+ "File where the Gnus registry will be stored."
:group 'gnus-registry
- :type 'regexp)
+ :type 'file)
;; Function(s) missing in Emacs 20
(when (memq nil (mapcar 'fboundp '(puthash)))
;; 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-translate-from-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
+ ;; Save .newsrc.eld.
+ (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 <jdc@chow.mat.jhu.edu>
+;; Save the gnus-registry file with extra line breaks.
+(defun gnus-registry-cache-whitespace (filename)
+ (gnus-message 4 "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 ()
+ (setq gnus-registry-alist (hashtable-to-alist gnus-registry-hashtb))
+ (gnus-registry-cache-save))
+
+(defun gnus-registry-read ()
+ (gnus-registry-cache-read)
(setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist)))
(defun alist-to-hashtable (alist)
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))
+ (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)
(when refstr
(setq references (nreverse (gnus-split-references refstr)))
(mapcar (lambda (x)
(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)
(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 ((trail (gethash id gnus-registry-hashtb)))
+ (dolist (crumb trail)
+ (unless (stringp crumb)
+ (return (gnus-registry-fetch-extra-entry crumb entry))))))
+
+(defun gnus-registry-fetch-extra-entry (alist &optional entry)
+ "Get the extra data of a message, or a specific entry in it."
+ (if entry
+ (assq entry alist)
+ 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)))
+ (puthash id (cons extra (delete old-extra trail))
+ gnus-registry-hashtb))))
+
+(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 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))
(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
+ (unless (gnus-registry-group-count id)
+ (remhash id gnus-registry-hashtb))
+ (gnus-registry-store-extra-entry id 'mtime (current-time)))))
-(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."
+(defun gnus-registry-add-group (id group &rest extra)
+ "Add a group for a message, based on the message ID."
;; make sure there are no duplicate entries
(when group
- (when id
+ (when (and id
+ (not (string-match "totally-fudged-out-message-id" id)))
(let ((group (gnus-group-short-name group)))
(gnus-registry-delete-group id group)
(let ((trail (gethash id gnus-registry-hashtb)))
(puthash id (if trail
(cons group trail)
(list group))
- gnus-registry-hashtb))))))
+ gnus-registry-hashtb)
+ (when extra (gnus-registry-store-extra id extra))
+ (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)
-
-(add-hook 'gnus-save-newsrc-hook 'gnus-registry-translate-to-alist)
-(add-hook 'gnus-read-newsrc-el-hook 'gnus-registry-translate-from-alist)
+ (setq gnus-registry-alist nil)
+ (setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist)))
-(add-hook 'gnus-summary-prepare-hook 'gnus-registry-register-message-ids)
+(defun gnus-registry-install-hooks ()
+ "Install the registry hooks."
+ (interactive)
+ (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)
+
+ (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))
+
+(when gnus-registry-install
+ (gnus-registry-install-hooks))
;; TODO: a lot of things
(gnus-dribble-delete-file)
(gnus-group-set-mode-line)))))
-(defun gnus-gnus-to-quick-newsrc-format ()
+(defun gnus-gnus-to-quick-newsrc-format (&optional minimal name specific-variable)
"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)
(stringp gnus-save-killed-list))
(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))))
+ (variables
+ (if specific-variable
+ (list specific-variable)
+ (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)
(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
(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.")
gnus-cache-removable-articles gnus-newsgroup-cached
gnus-newsgroup-data gnus-newsgroup-data-reverse
gnus-newsgroup-limit gnus-newsgroup-limits
- gnus-newsgroup-charset gnus-newsgroup-display)
+ gnus-newsgroup-charset gnus-newsgroup-display
+ gnus-summary-use-undownloaded-faces)
"Variables that are buffer-local to the summary buffers.")
(defvar gnus-newsgroup-variables nil
(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
+ (not (gnus-agent-find-parameter
+ group
+ 'agent-disable-undownloaded-faces))))
(setq gnus-newsgroup-name group
gnus-newsgroup-unselected nil
(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))
(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)))
(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)))
(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)
(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)
(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)))
(gnus-handle-ephemeral-exit quit-config))
;; Clear the current group name.
(unless quit-config
(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)))
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)
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
(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)
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
(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))
;; We check that there are unread articles.
(when (or all (gnus-summary-find-next))
(gnus-summary-catchup all t beg nil t)))))
-
(gnus-summary-position-point))
+
(defun gnus-summary-catchup-all (&optional quietly)
"Mark all articles in this newsgroup as read.
This command is dangerous. Normally, you want \\[gnus-summary-catchup]
(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
;; 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:
(require 'custom)
;; 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"
(let ((now (decode-time (current-time))))
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."
;;; Functions for saving to babyl/mail files.
-(defvar rmail-default-rmail-file)
+(eval-when-compile
+ (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)
(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)
(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))
`(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
(require 'mm-util)
(require 'nnheader)
-;; Make sure it was the right mm-util.
-(unless (fboundp 'mm-guess-mime-charset)
- (error "Wrong `mm-util' found in `load-path'. Make sure the Gnus one is found first."))
-
(defgroup gnus nil
"The coffee-brewing, all singing, all dancing, kitchen sink newsreader."
:group 'news
:link '(custom-manual "(gnus)Exiting Gnus")
:group 'gnus)
-(defconst gnus-version-number "5.10.1"
+(defconst gnus-version-number "5.10.2"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Gnus v%s" gnus-version-number)
(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)
(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.")
`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 <tzz@lifelogs.com>
(defcustom gnus-install-group-spam-parameters t
"*Disable the group parameters for spam detection.
"*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"
:group 'gnus-agent
:type 'boolean)
-(defcustom gnus-default-charset (mm-guess-mime-charset)
+(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
(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)."
+Putting (gnus-agentize) in ~/.gnus is obsoleted by (setq gnus-agent t)."
:version "21.3"
:group 'gnus-agent
:type 'boolean)
'(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-format-specs)
"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.")
(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)
(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
+ display-graphic-p display-time-event-handler find-coding-system
+ 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
rmail-msg-is-pruned rmail-msg-restore-non-pruned-header
: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."
(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."
(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))))
:group 'message-sending
:type 'string)
-(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)
:group 'message-various
:type 'regexp)
+;; Fixme: Why are all these things autoloaded?
+
;;; marking inserted text
;;;###autoload
(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)
'ask)
"Whether to encode non-ASCII in domain names into ASCII according to IDNA."
:group 'message-headers
(beg 1)
(first t)
quoted elems paren)
- (save-excursion
- (message-set-work-buffer)
+ (with-temp-buffer
+ (mm-enable-multibyte)
(insert header)
(goto-char (point-min))
(while (not (eobp))
(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)
- (mm-enable-multibyte)))
-
(defun message-functionp (form)
"Return non-nil if FORM is funcallable."
(or (and (symbolp form) (fboundp form))
(let ((point (point)))
(message-goto-signature)
(unless (eobp)
- (forward-line -2))
+ (end-of-line -1))
(kill-region point (point))
(unless (bolp)
(insert "\n"))))
(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))
(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)))))))))
(if (message-functionp message-user-organization)
(funcall message-user-organization)
message-user-organization))))
- (save-excursion
- (message-set-work-buffer)
+ (with-temp-buffer
+ (mm-enable-multibyte)
(cond ((stringp organization)
(insert organization))
((and (eq t organization)
(user-full-name))))
(when (string= fullname "&")
(setq fullname (user-login-name)))
- (save-excursion
- (message-set-work-buffer)
+ (with-temp-buffer
+ (mm-enable-multibyte)
(cond
((or (null style)
(equal fullname ""))
(when message-default-mail-headers
(insert message-default-mail-headers)
(or (bolp) (insert ?\n)))
+ (save-restriction
+ (message-narrow-to-headers)
+ (if message-alternative-emails
+ (message-use-alternative-email-as-from)))
(when message-generate-headers-first
(message-generate-headers
(message-headers-to-generate
(message-insert-signature)
(save-restriction
(message-narrow-to-headers)
- (if 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)
(concat "["
(let ((prefix
(or (message-fetch-field "newsgroups")
- (cdr
- (mail-header-parse-address
- (mail-decode-encoded-word-string
- (message-fetch-field "from"))))
+ (let ((from (message-fetch-field "from")))
+ (and from
+ (cdr (mail-header-parse-address from))))
"(nowhere)")))
(if message-forward-decoded-p
prefix
(not message-forward-decoded-p))
(insert
(with-temp-buffer
- (mm-disable-multibyte-mule4)
+ (mm-disable-multibyte)
(insert
(with-current-buffer forward-buffer
- (mm-with-unibyte-current-buffer-mule4 (buffer-string))))
- (mm-enable-multibyte-mule4)
+ (mm-with-unibyte-current-buffer (buffer-string))))
+ (mm-enable-multibyte)
(mime-to-mml)
(goto-char (point-min))
(when (looking-at "From ")
(cdr local)))))
locals)))
-;;; Miscellaneous functions
-
-(defsubst message-replace-chars-in-string (string from to)
- (mm-subst-char-in-string from to string))
-
;;;
;;; MIME functions
;;;
(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))
(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))
(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)))
(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."
(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."
(require 'mail-parse)
(require '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)
(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
(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
(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
(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)))))
(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)
(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)
(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))))
((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
(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
`(
;; 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)))
;; Windows-1252 is actually a superset of Latin-1. See also
;; `gnus-article-dumbquotes-map'.
(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 ()
"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
(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
(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)
;; `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
(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)
(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)
(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."
(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)
(require 'smime)
(require 'mm-decode)
+(autoload 'message-narrow-to-headers "message")
(defun mml-smime-sign (cont)
(when (null smime-keys)
(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)
(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
(eval-when-compile (require 'cl))
(require 'mm-decode)
(require 'mm-util)
+(require 'mml)
(defvar mml2015-use (or
(progn
(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
(funcall mml-boundary-function (incf mml-multipart-number)))
(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
`((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))
(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+"))
(require 'mail-utils)
(require 'mm-util)
+(require 'gnus-util)
(eval-and-compile
(autoload 'gnus-sorted-intersection "gnus-range")
(autoload 'gnus-intersection "gnus-range")
(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"))
+ (message "XML-RPC is not available... not checking Syndic8.")
+ (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
(defun nntp-open-network-stream (buffer)
(open-network-stream "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 (start-process "nntpd" buffer
,@body)))
(defun pgg-temp-buffer-show-function (buffer)
- (let ((window (split-window-vertically)))
+ (let ((window (or (get-buffer-window buffer 'visible)
+ (split-window-vertically))))
(set-window-buffer window buffer)
(shrink-window-if-larger-than-buffer window)))
(setq message-count (car (pop3-stat process)))
(unwind-protect
(while (<= n message-count)
- (message (format "Retrieving message %d of %d from %s..."
- n message-count pop3-mailhost))
+ (message "Retrieving message %d of %d from %s..."
+ n message-count pop3-mailhost)
(pop3-retr process n crashbuf)
(save-excursion
(set-buffer crashbuf)
(save-excursion
(set-buffer (process-buffer process))
(while (not (re-search-forward "^\\.\r\n" nil t))
+ ;; Fixme: Shouldn't depend on nnheader.
(nnheader-accept-process-output process)
;; bill@att.com ... to save wear and tear on the heap
;; uncommented because the condensed version below is a problem for
-;;; 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 <larsi@gnus.org>
;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
(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!*+/=_")
+ address-mime)
(t . mime))
"*Header/encoding method alist.
The list is traversed sequentially. The keys can either 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)
(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."
(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
(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)
+ (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 <abraham@dina.kvl.dk> 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)))))))
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.
+ (progn
+ (goto-char (point-min))
+ ;; Does it need encoding?
+ (skip-chars-forward "\000-\177" e)
+ (unless (eobp)
+ (rfc2047-encode b e)))
+ ;; `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-special-chars')."
(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))
- (encoding (or (cdr (assq 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-special-chars')."
+ (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 (if (assq mime-charset
+ rfc2047-charset-encoding-alist)
+ (cdr (assq mime-charset
rfc2047-charset-encoding-alist))
- 'B))
+ 'B))
(start (concat
"=?" (downcase (symbol-name mime-charset)) "?"
(downcase (symbol-name encoding)) "?"))
(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))
+ (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))))))
(defun rfc2047-fold-field ()
- "Fold the current line."
+ "Fold the current header field."
(save-excursion
(save-restriction
(rfc2047-narrow-to-field)
(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))
(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.
(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.
(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)
(let ((alist rfc2047-q-encoding-alist)
(bol (save-restriction
(widen)
- (gnus-point-at-bol))))
+ (rfc2047-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)))
+ (quoted-printable-encode-region b e nil (cdar alist))
(subst-char-in-region (point-min) (point-max) ? ?_)
(setq alist nil))
(pop alist))
(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.
(defun rfc2047-decode-region (start end)
"Decode MIME-encoded words in region between START and END."
(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.
(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)
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
(upcase (match-string 2 word))
(match-string 3 word))
(error word))
- word)))
+ word))) ; un-decodable
(defun rfc2047-pad-base64 (string)
"Pad STRING to quartets."
(when (and (eq cs 'ascii)
mail-parse-charset)
(setq cs mail-parse-charset))
- (mm-with-unibyte-current-buffer-mule4
+ ;; Fixme: What's this for? The following comment makes no sense. -- fx
+ (mm-with-unibyte-current-buffer
;; In Emacs Mule 4, decoding UTF-8 should be in unibyte mode.
(mm-decode-coding-string
(cond
(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."
(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)
(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:
(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")
(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)
(defvar smime-details-buffer "*OpenSSL output*")
+;; Use mm-util?
(eval-and-compile
(defalias 'smime-make-temp-file
(if (fboundp 'make-temp-file)
(caddr curkey)
(smime-get-certfiles keyfile otherkeys)))))
+;; Use mm-util?
(eval-and-compile
(defalias 'smime-point-at-eol
(if (fboundp 'point-at-eol)
"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."
+ "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 'regexp
:group 'spam-report)
(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'."
+Also see the variables `spam-regex-headers-spam' and `spam-regex-headers-ham'."
:type 'boolean
:group 'spam)
-;;; 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 <hellan@acm.org>
+;; Maintainer: bugs@gnus.org
;; Keywords: mail
;; This file is part of GNU Emacs.
;; 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))
(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)
(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
(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
(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)
(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)
(with-temp-buffer
(insert string)
(utf7-decode-internal for-imap)
+ (mm-enable-multibyte)
(buffer-string))))
(provide 'utf7)
+2003-05-13 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus.texi (Anti-Spam Basics): Removed mention of gnus-junk.
+
+2003-05-13 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus.texi (Agent Variables, Score File Format)
+ (Troubleshooting, Editing IMAP ACLs, Conformity): a -> an.
+
+ * message.texi (Insertion Variables): do.
+
+2003-05-13 Simon Josefsson <jas@extundo.com>
+
+ * gnus.texi (IMAP, Agent and IMAP, Oort Gnus): s/a/an/. Tiny
+ patch from Niklas Morberg <niklas.morberg@axis.com>.
+
+2003-05-12 Kevin Greiner <kgreiner@xpediantsolutions.com>
+
+ * gnus.texi (Agent Visuals): Add.
+
+2003-05-09 Simon Josefsson <jas@extundo.com>
+
+ * pgg.texi (Default user identity): Add.
+
+2003-05-08 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus.texi (Selecting a Group): Mention nil value
+ gnus-large-newsgroup.
+
+2003-05-07 Jesper Harder <harder@ifa.au.dk>
+
+ * gnus.texi (MIME Commands): Fix typo.
+
+2003-05-05 Jesper Harder <harder@ifa.au.dk>
+
+ * gnusref.tex: Additions.
+
+ * gnus.texi (Oort Gnus): Fix typo.
+
+2003-05-03 Kai Gro\e,A_\e(Bjohann <kai.grossjohann@gmx.net>
+
+ * gnus.texi (Agent Basics): Explain that some servers can be
+ agentized, whereas others aren't.
+
2003-05-01 Reiner Steib <Reiner.Steib@gmx.de>
* gnus.texi (Oort Gnus): Add prefix limit feature.
\makeindex
\begin{document}
-\newcommand{\gnusversionname}{Gnus v5.10.1}
+\newcommand{\gnusversionname}{Gnus v5.10.2}
\newcommand{\gnuschaptername}{}
\newcommand{\gnussectionname}{}
spool or your mbox file. All at the same time, if you want to push your
luck.
-This manual corresponds to Gnus v5.10.1.
+This manual corresponds to Gnus v5.10.2.
@end ifinfo
* 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.
@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 vaule 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
@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}.
doesn't exist actually does 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
@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:
* 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.
@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
@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
@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
+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 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
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
@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
@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.
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
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
@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
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
+a file as an attachment (@kbd{C-c C-a}), open a file using the appropriate
mailcap entry (@kbd{C-c C-l}), and print a file using the mailcap entry
(@kbd{C-c P}). It is enabled with
@lisp
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
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 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
@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.
@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
@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
%% 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{May, 2003}
\def\author{Gnus Bugfixing Girls + Boys $<$bugs@gnus.org$>$}
%%
? & (?, 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
\# & (\#, 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]\\
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} \\
@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}.
@ifinfo
This file describes the PGG.
+Copyright (C) 2003 Free Software Foundation, Inc.
Copyright (C) 2001 Daiki Ueno.
Permission is granted to copy, distribute and/or modify this document
* User Commands::
* Selecting an implementation::
* Caching passphrase::
+* Default user identity::
@end menu
@node User Commands
Elapsed time for expiration in seconds.
@end defvar
+@node Default user identity
+@section Default user identity
+
+The PGP implementation is usually able to select the proper key to use
+for signing and decryption, but if you have more than one key, you may
+need to specify the key id to use.
+
+@defvar pgg-default-user-id
+User ID of your default identity. It defaults to the value returned
+by @samp{(user-login-name)}. You can customize this variable.
+@end defvar
+
+@defvar pgg-gpg-user-id
+User ID of the GnuPG default identity. It defaults to @samp{nil}.
+This overrides @samp{pgg-default-user-id}. You can customize this
+variable.
+@end defvar
+
+@defvar pgg-pgp-user-id
+User ID of the PGP 2.x/6.x default identity. It defaults to
+@samp{nil}. This overrides @samp{pgg-default-user-id}. You can
+customize this variable.
+@end defvar
+
+@defvar pgg-pgp5-user-id
+User ID of the PGP 5.x default identity. It defaults to @samp{nil}.
+This overrides @samp{pgg-default-user-id}. You can customize this
+variable.
+@end defvar
+
@node Architecture
@chapter Architecture