From: Lars Ingebrigtsen Date: Mon, 13 Feb 2012 11:15:57 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/no-gnus' X-Git-Url: http://cgit.sxemacs.org/?p=gnus;a=commitdiff_plain;h=5d97eabba7d837af355df0e772bd9e2f585b7a22;hp=3614422b660cbb37541de79822260a74f359fb55 Merge remote-tracking branch 'origin/no-gnus' --- diff --git a/.gitignore b/.gitignore index 840562a30..6445f3398 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ contrib/gnus-mdrtn.el contrib/on-loginfo contrib/request-assign.future etc/Makefile +.gitattributes lisp/.gitattributes lisp/*.elc lisp/*.rej @@ -27,6 +28,7 @@ lisp/gnus-load.el lisp/old lisp/semantic.cache lisp/version +texi/.gitattributes texi/Makefile texi/auth texi/emacs-mime diff --git a/GNUS-NEWS b/GNUS-NEWS index 12e4c622b..bf4430789 100644 --- a/GNUS-NEWS +++ b/GNUS-NEWS @@ -7,257 +7,28 @@ Please send Gnus bug reports to bugs@gnus.org. For older news, see Gnus info node "New Features". -* Installation changes +* New features -** Upgrading from previous (stable) version if you have used No Gnus. +** If you have the "tnef" program installed, Gnus will display ms-tnef + files, aka "winmail.dat". -If you have tried No Gnus (the unstable Gnus branch leading to this -release) but went back to a stable version, be careful when upgrading to -this version. In particular, you will probably want to remove the -`~/News/marks' directory (perhaps selectively), so that flags are read -from your `~/.newsrc.eld' instead of from the stale marks file, where -this release will store flags for nntp. See a later entry for more -information about nntp marks. Note that downgrading isn't safe in -general. +** Archives (like tar and zip files) will be automatically unpacked, + and the files inside the packages will be displayed as MIME parts. -** Incompatibility when switching from Emacs 23 to Emacs 22 In Emacs 23, -Gnus uses Emacs' new internal coding system `utf-8-emacs' for saving -articles drafts and `~/.newsrc.eld'. These files may not be read -correctly in Emacs 22 and below. If you want to use Gnus across -different Emacs versions, you may set `mm-auto-save-coding-system' to -`emacs-mule'. +** shr has a new command `z' that cycles through image sizes. -** Lisp files are now installed in `.../site-lisp/gnus/' by default. It -defaulted to `.../site-lisp/' formerly. In addition to this, the new -installer issues a warning if other Gnus installations which will shadow -the latest one are detected. You can then remove those shadows manually -or remove them using `make remove-installed-shadows'. +** `backtab' in the summary buffer now selects the previous link in + the article buffer. -** The installation directory name is allowed to have spaces and/or tabs. +** Using the "X-Message-SMTP-Method" header in Message buffers now + allows specifying how messages are to be sent. For example: - -* New packages and libraries within Gnus - -** Gnus includes the Emacs Lisp SASL library. - -This provides a clean API to SASL mechanisms from within Emacs. The -user visible aspects of this, compared to the earlier situation, include -support for DIGEST-MD5 and NTLM. *Note Emacs SASL: (sasl)Top. - -** ManageSieve connections uses the SASL library by default. - -The primary change this brings is support for DIGEST-MD5 and NTLM, when -the server supports it. - -** Gnus includes a password cache mechanism in password-cache.el. - -It is enabled by default (see `password-cache'), with a short timeout of -16 seconds (see `password-cache-expiry'). If PGG is used as the PGP -back end, the PGP passphrase is managed by this mechanism. Passwords -for ManageSieve connections are managed by this mechanism, after -querying the user about whether to do so. - -** Using EasyPG with Gnus When EasyPG, is available, Gnus will use it -instead of PGG. EasyPG is an Emacs user interface to GNU Privacy Guard. - *Note EasyPG Assistant user's manual: (epa)Top. EasyPG is included in -Emacs 23 and available separately as well. - - -* Changes in group mode - -** Old intermediate incoming mail files (`Incoming*') are deleted after a -couple of days, not immediately. *Note Mail Source Customization::. -(New in Gnus 5.10.10 / No Gnus 0.8) - - - -* Changes in summary and article mode - -** Gnus now supports sticky article buffers. Those are article buffers -that are not reused when you select another article. *Note Sticky -Articles::. - -** Gnus can selectively display `text/html' articles with a WWW browser -with `K H'. *Note MIME Commands::. - -** International host names (IDNA) can now be decoded inside article bodies -using `W i' (`gnus-summary-idna-message'). This requires that GNU Libidn -(`http://www.gnu.org/software/libidn/') has been installed. - -** The non-ASCII group names handling has been much improved. The back -ends that fully support non-ASCII group names are now `nntp', `nnml', -and `nnrss'. Also the agent, the cache, and the marks features work -with those back ends. *Note Non-ASCII Group Names::. + X-Message-SMTP-Method: smtp smtp.fsf.org 587 -** Gnus now displays DNS master files sent as text/dns using dns-mode. - -** Gnus supports new limiting commands in the Summary buffer: `/ r' -(`gnus-summary-limit-to-replied') and `/ R' -(`gnus-summary-limit-to-recipient'). *Note Limiting::. - -** You can now fetch all ticked articles from the server using `Y t' -(`gnus-summary-insert-ticked-articles'). *Note Summary Generation -Commands::. - -** Gnus supports a new sort command in the Summary buffer: `C-c C-s C-t' -(`gnus-summary-sort-by-recipient'). *Note Summary Sorting::. - -** S/MIME now features LDAP user certificate searches. You need to -configure the server in `smime-ldap-host-list'. - -** URLs inside OpenPGP headers are retrieved and imported to your PGP key -ring when you click on them. - -** Picons can be displayed right from the textual address, see -`gnus-picon-style'. *Note Picons::. - -** ANSI SGR control sequences can be transformed using `W A'. - -ANSI sequences are used in some Chinese hierarchies for highlighting -articles (`gnus-article-treat-ansi-sequences'). - -** Gnus now MIME decodes articles even when they lack "MIME-Version" header. -This changes the default of `gnus-article-loose-mime'. - -** `gnus-decay-scores' can be a regexp matching score files. For example, -set it to `\\.ADAPT\\'' and only adaptive score files will be decayed. - *Note Score Decays::. - -** Strings prefixing to the `To' and `Newsgroup' headers in summary lines -when using `gnus-ignored-from-addresses' can be customized with -`gnus-summary-to-prefix' and `gnus-summary-newsgroup-prefix'. *Note To -From Newsgroups::. - -** You can replace MIME parts with external bodies. See -`gnus-mime-replace-part' and `gnus-article-replace-part'. *Note MIME -Commands::, *note Using MIME::. - -** The option `mm-fill-flowed' can be used to disable treatment of -format=flowed messages. Also, flowed text is disabled when sending -inline PGP signed messages. *Note Flowed text: (emacs-mime)Flowed text. -(New in Gnus 5.10.7) - -** Now the new command `S W' (`gnus-article-wide-reply-with-original') for -a wide reply in the article buffer yanks a text that is in the active -region, if it is set, as well as the `R' -(`gnus-article-reply-with-original') command. Note that the `R' command -in the article buffer no longer accepts a prefix argument, which was -used to make it do a wide reply. *Note Article Keymap::. - -** The new command `C-h b' (`gnus-article-describe-bindings') used in the -article buffer now shows not only the article commands but also the real -summary commands that are accessible from the article buffer. - - - -* Changes in Message mode - -** Gnus now supports the "hashcash" client puzzle anti-spam mechanism. Use -`(setq message-generate-hashcash t)' to enable. *Note Hashcash::. - -** You can now drag and drop attachments to the Message buffer. See -`mml-dnd-protocol-alist' and `mml-dnd-attach-options'. *Note MIME: -(message)MIME. - -** The option `message-yank-empty-prefix' now controls how empty lines are -prefixed in cited text. *Note Insertion Variables: (message)Insertion -Variables. - -** Gnus uses narrowing to hide headers in Message buffers. The -`References' header is hidden by default. To make all headers visible, -use `(setq message-hidden-headers nil)'. *Note Message Headers: -(message)Message Headers. - -** You can highlight different levels of citations like in the article -buffer. See `gnus-message-highlight-citation'. - -** `auto-fill-mode' is enabled by default in Message mode. See -`message-fill-column'. *Note Message Headers: (message)Various Message -Variables. - -** You can now store signature files in a special directory named -`message-signature-directory'. - -** The option `message-citation-line-format' controls the format of the -"Whomever writes:" line. You need to set -`message-citation-line-function' to -`message-insert-formatted-citation-line' as well. - - -* Changes in back ends - -** The nntp back end stores article marks in `~/News/marks'. - -The directory can be changed using the (customizable) variable -`nntp-marks-directory', and marks can be disabled using the (back end) -variable `nntp-marks-is-evil'. The advantage of this is that you can -copy `~/News/marks' (using rsync, scp or whatever) to another Gnus -installation, and it will realize what articles you have read and -marked. The data in `~/News/marks' has priority over the same data in -`~/.newsrc.eld'. - -** You can import and export your RSS subscriptions from OPML files. *Note -RSS::. - -** IMAP identity (RFC 2971) is supported. - -By default, Gnus does not send any information about itself, but you can -customize it using the variable `nnimap-id'. - -** The `nnrss' back end now supports multilingual text. Non-ASCII group -names for the `nnrss' groups are also supported. *Note RSS::. - -** Retrieving mail with POP3 is supported over SSL/TLS and with StartTLS. - -** The nnml back end allows other compression programs beside `gzip' for -compressed message files. *Note Mail Spool::. - -** The nnml back end supports group compaction. - -This feature, accessible via the functions `gnus-group-compact-group' -(`G z' in the group buffer) and `gnus-server-compact-server' (`z' in the -server buffer) renumbers all articles in a group, starting from 1 and -removing gaps. As a consequence, you get a correct total article count -(until messages are deleted again). - - - -* Appearance - -** The tool bar has been updated to use GNOME icons. You can also -customize the tool bars: `M-x customize-apropos RET -tool-bar$' should -get you started. (Only for Emacs, not in XEmacs.) - -** The tool bar icons are now (de)activated correctly in the group buffer, -see the variable `gnus-group-update-tool-bar'. Its default value -depends on your Emacs version. - -** You can change the location of XEmacs' toolbars in Gnus buffers. See -`gnus-use-toolbar' and `message-use-toolbar'. - - - -* Miscellaneous changes - -** Having edited the select-method for the foreign server in the server -buffer is immediately reflected to the subscription of the groups which -use the server in question. For instance, if you change -`nntp-via-address' into `bar.example.com' from `foo.example.com', Gnus -will connect to the news host by way of the intermediate host -`bar.example.com' from next time. - -** The `all.SCORE' file can be edited from the group buffer using `W e'. - -** You can set `gnus-mark-copied-or-moved-articles-as-expirable' to a -non-`nil' value so that articles that have been read may be marked as -expirable automatically when copying or moving them to a group that has -auto-expire turned on. The default is `nil' and copying and moving of -articles behave as before; i.e., the expirable marks will be unchanged -except that the marks will be removed when copying or moving articles to -a group that has not turned auto-expire on. *Note Expiring Mail::. - - - +** Gnus keeps track of non-existent articles for nnimap groups, so + that sparse IMAP folders now list a correct number of messages in + them. + * For older news, see Gnus info node "New Features". ---------------------------------------------------------------------- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6341feda2..e3bf51c31 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,6 +1,7 @@ 2012-02-13 Lars Ingebrigtsen * shr.el (shr-rescale-image): Allow viewing large images. + (shr-rescale-image): Fix wrong merge. 2012-02-12 Lars Ingebrigtsen @@ -35,6 +36,24 @@ * auth-source.el (auth-source-cache-expiry): Add missing :version tags to new defcustoms and defgroups. +2012-02-11 Lars Ingebrigtsen + + * gnus-sum.el (gnus-adjust-marked-articles): Add to + `gnus-newsgroup-unexist'. + + * gnus.el (gnus-article-mark-lists): Add `unexist' to the list of + marks. + (gnus-article-special-mark-lists): Put the `unexist' in the special + marks list instead. + + * gnus-sum.el (gnus-articles-to-read): Don't include unexisting + articles in the list of articles to be selected. + + * nnimap.el (nnimap-retrieve-group-data-early): Query for unexisting + articles. + (nnimap-update-info): Keep track of unexisting articles. + (nnimap-update-qresync-info): Ditto. + 2012-02-10 Lars Ingebrigtsen * message.el (message-default-send-mail-function): Made into own @@ -45,6 +64,45 @@ * gnus.el (gnus-method-ephemeral-p): Move after declaration of defsubst `gnus-sloppily-equal-method-parameters' to avoid a warning. +2012-02-09 Lars Ingebrigtsen + + * mm-archive.el (mm-archive-dissect-and-inline): New function. + (mm-archive-dissect-and-inline): Fix up the undisplayer. + + * gnus-compat.el: Define `timer-set-function'. + + * mm-decode.el (mm-display-external): Output the text from the command + in the buffer after the command finished. This makes text-based + commands behave better. + +2012-02-08 Lars Ingebrigtsen + + * gnus-compat.el: Add a compat for the old `url-retrieve'. + +2012-02-07 Lars Ingebrigtsen + + * gnus-compat.el: Make `help-function-arglist' be compatible on Emacs + 23.1. + +2012-02-07 Katsumi Yamaoka + + * gnus-sum.el (gnus-summary-show-thread): Revert last two changes. + +2012-02-07 Lars Ingebrigtsen + + * message.el (smtpmail-smtp-user): Silence compiler warning. + +2012-02-06 Lars Ingebrigtsen + + * message.el (message-multi-smtp-send-mail): Also allow specifying the + SMTP user name. + +2012-02-06 Katsumi Yamaoka + + * gnus-sum.el (gnus-summary-show-thread): + next-single-char-property-change may return nil in XEmacs. + (gnus-summary-article-map): Fix typo. + 2012-02-09 Lars Ingebrigtsen * gnus-msg.el (gnus-msg-mail): Use `message-mail' if Gnus isn't @@ -112,6 +170,98 @@ * gnus-sum.el (gnus-summary-show-thread): next-single-char-property-change never returns nil (Bug#8657). +2012-02-02 Lars Ingebrigtsen + + * message.el (message-multi-smtp-send-mail): New function. + (message-multi-smtp-send-mail): Respect the X-Message-SMTP-Method + header to implement multi-SMTP functionality. + + * gnus-agent.el (gnus-agent-send-mail-function): Removed. + (gnus-agentize): Don't set it. + (gnus-agent-send-mail): Don't use it. + + * gnus-sum.el (gnus-summary-widget-backward): New function and + keystroke. + + * gnus-compat.el: More the compat functions more compatible. + + * shr.el (shr-put-image): Remove underlines from sliced images. + (shr-zoom-image): Compute the region to be replaced more correctly. + +2012-02-02 Katsumi Yamaoka + + * gnus-msg.el (gnus-gcc-self-resent-messages): New user option. + (gnus-summary-resend-message-insert-gcc): New function. + (gnus-summary-resend-message): Modify message-header-setup-hook and + message-sent-hook to make it work for Gcc. + (gnus-inews-do-gcc): Update the number of unread articles of groups + that messages are Gcc'd to. + + * message.el (message-resend): Run message-sent-hook to do Gcc. + +2012-02-01 Lars Ingebrigtsen + + * lpath.el: Fix an XEmacs compilation warning. + + * gnus-compat.el: Require `help-fns' to fix compilation error. + + * gnus-registry.el (gnus-registry-fixup-registry): Move the message to + a higher level to silence compilation. + + * gnus-art.el (gnus-shr-put-image): Take and pass on a `flags' + parameter to allow controlling the scaling. + + * shr.el (shr-zoom-image): New command and keystroke. + (shr-put-image): Take a `size' flag to say how to scale the image. + + * gnus-compat.el: Redefine `delete-directory' to provide recursive + deletion unless already defined. + + * gnus.el (gnus-compat): Require it. + + * gnus-compat.el: New file. + + * gnus-start.el (gnus-clean-old-newsrc): New function. + (gnus-read-newsrc-file): Use it. + + * mm-archive.el (mm-dissect-archive): Use it to get all file names. + Use recursive deletion. + (mm-dissect-archive): Add support for zip files. + + * gnus-util.el (gnus-recursive-directory-files): New function. + + * mm-archive.el (mm-archive-list-files): Inline text and image parts. + (mm-archive-decoders): Add tgz support. + + * mm-decode.el (mm-shr): Make sure that the HTML ends with a newline. + Otherwise inserting text into the Gnus buffer can look odd. + + * gnus-art.el (gnus-mime-inline-part): Slight clean-up. + + * mm-archive.el (mm-archive-decoders): Add support for tar. + + * gnus.el (gnus-logo-color-alist): Change the colours for Ma Gnus. + + * nnmail.el (nnmail-extra-headers): Add Cc to the default. + +2012-01-31 Lars Ingebrigtsen + + * mm-decode.el (mm-dissect-singlepart): Check that the decoder exists. + + * mm-archive.el: New file. + + * mm-decode.el (mm-dissect-singlepart): Use it to decode ms-tnef files. + + * mm-util.el (mm-find-buffer-file-coding-system): Comment fix. + + * message.el (message-goto-*): Make all the `message-goto-*' commands + push the mark before moving point. This makes it easier to go back to + where you came from after editing whatever you jumped to. + +2012-01-31 Lars Magne Ingebrigtsen + + * gnus.el: Ma Gnus v0.1 is released. + 2012-02-05 Lars Ingebrigtsen * nnimap.el (nnimap-open-server): Allow switching the nnoo server @@ -153,9 +303,9 @@ * gnus-agent.el (gnus-agent-expire-unagentized-dirs): Correct a comment (insert "not") and hide nominally-doubled "to". -2012-01-31 Lars Magne Ingebrigtsen +2012-01-31 Lars Ingebrigtsen - * gnus.el: No Gnus v0.19 is released. + * gnus.el (gnus-version): Change name to "Ma Gnus". 2012-01-30 Philipp Haselwarter (tiny change) diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index 5178220af..284a37838 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -242,7 +242,6 @@ NOTES: (defvar gnus-category-group-cache nil) (defvar gnus-agent-spam-hashtb nil) (defvar gnus-agent-file-name nil) -(defvar gnus-agent-send-mail-function nil) (defvar gnus-agent-file-coding-system 'raw-text) (defvar gnus-agent-file-loading-cache nil) (defvar gnus-agent-total-fetched-hashtb nil) @@ -683,11 +682,7 @@ This will modify the `gnus-setup-news-hook', and minor mode in all Gnus buffers." (interactive) (gnus-open-agent) - (unless gnus-agent-send-mail-function - (setq gnus-agent-send-mail-function - (or message-send-mail-real-function - (function (lambda () (funcall message-send-mail-function)))) - message-send-mail-real-function 'gnus-agent-send-mail)) + (setq message-send-mail-real-function 'gnus-agent-send-mail) ;; If the servers file doesn't exist, auto-agentize some servers and ;; save the servers file so this auto-agentizing isn't invoked @@ -723,7 +718,7 @@ Optional arg GROUP-NAME allows to specify another group." (defun gnus-agent-send-mail () (if (or (not gnus-agent-queue-mail) (and gnus-plugged (not (eq gnus-agent-queue-mail 'always)))) - (funcall gnus-agent-send-mail-function) + (message-multi-smtp-send-mail) (goto-char (point-min)) (re-search-forward (concat "^" (regexp-quote mail-header-separator) "\n")) diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index 048f89565..32399e158 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -5327,9 +5327,8 @@ Compressed files like .gz and .bz2 are decompressed." (or (cdr (assq arg gnus-summary-show-article-charset-alist)) (mm-read-coding-system "Charset: ")))) - (t - (if (mm-handle-undisplayer handle) - (mm-remove-part handle)))) + ((mm-handle-undisplayer handle) + (mm-remove-part handle))) (forward-line 2) (mm-display-inline handle) (goto-char b))))) @@ -6198,12 +6197,13 @@ Provided for backwards compatibility." (not gnus-inhibit-hiding)) (gnus-article-hide-headers))) -(declare-function shr-put-image "shr" (data alt)) +(declare-function shr-put-image "shr" (data alt &optional flags)) -(defun gnus-shr-put-image (data alt) +(defun gnus-shr-put-image (data alt &optional flags) "Put image DATA with a string ALT. Enable image to be deleted." (let ((image (shr-put-image data (propertize (or alt "*") - 'gnus-image-category 'shr)))) + 'gnus-image-category 'shr) + flags))) (when image (gnus-add-image 'shr image)))) diff --git a/lisp/gnus-compat.el b/lisp/gnus-compat.el new file mode 100644 index 000000000..130748853 --- /dev/null +++ b/lisp/gnus-compat.el @@ -0,0 +1,102 @@ +;;; gnus-compat.el --- Compatability functions for Gnus + +;; Copyright (C) 2012 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: compat + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This package defines and redefines a bunch of functions for Gnus +;; usage. The basic (and somewhat unsound) idea is to make all +;; Emacsen look like the current trunk of Emacs. So it will define +;; functions "missing" in other Emacs instances, and redefine other +;; functions to work like the Emacs trunk versions. + +(eval-when-compile (require 'cl)) + +(ignore-errors + (require 'help-fns)) + +;; XEmacs doesn't have this function. +(when (and (not (fboundp 'help-function-arglist)) + (fboundp 'function-arglist)) + (defun help-function-arglist (def &optional preserve-names) + "Return a formal argument list for the function DEF. +PRESERVE-NAMES is ignored." + (cdr (car (read-from-string (downcase (function-arglist def))))))) + +;; Modify this function on Emacs 23.1 and earlier to always return the +;; right answer. +(when (and (fboundp 'help-function-arglist) + (eq (help-function-arglist 'car) t)) + (defvar gnus-compat-original-help-function-arglist + (symbol-function 'help-function-arglist)) + (defun help-function-arglist (def &optional preserve-names) + "Return a formal argument list for the function DEF. +PRESERVE-NAMES is ignored." + (let ((orig (funcall gnus-compat-original-help-function-arglist def))) + (if (not (eq orig t)) + orig + ;; Built-in subrs have the arglist hidden in the doc string. + (let ((doc (documentation def))) + (when (and doc + (string-match "\n\n\\((fn\\( .*\\)?)\\)\\'" doc)) + (cdr (car (read-from-string (downcase (match-string 1 doc))))))))))) + +(when (= (length (help-function-arglist 'delete-directory)) 1) + (defvar gnus-compat-original-delete-directory + (symbol-function 'delete-directory)) + (defun delete-directory (directory &optional recursive trash) + "Delete the directory named DIRECTORY. Does not follow symlinks. +If RECURSIVE is non-nil, all files in DIRECTORY are deleted as well. +TRASH is ignored." + (interactive "DDirectory: ") + (if (not recursive) + (funcall gnus-compat-original-delete-directory directory) + (dolist (file (directory-files directory t)) + (unless (member (file-name-nondirectory file) '("." "..")) + (if (file-directory-p file) + (delete-directory file t) + (delete-file file)))) + (delete-directory directory)))) + +;; Emacs 24.0.93 +(require 'url) +(when (= (length (help-function-arglist 'url-retrieve)) 5) + (defvar gnus-compat-original-url-retrieve + (symbol-function 'url-retrieve)) + (defun url-retrieve (url callback &optional cbargs silent inhibit-cookies) + "Retrieve URL asynchronously and call CALLBACK with CBARGS when finished." + (funcall gnus-compat-original-url-retrieve + url callback cbargs silent))) + +;; XEmacs +(when (and (not (fboundp 'timer-set-function)) + (fboundp 'set-itimer-function)) + (defun timer-set-function (timer function &optional args) + "Make TIMER call FUNCTION with optional ARGS when triggering." + (lexical-let ((function function) + (args args)) + (set-itimer-function timer + (lambda (process status) + (apply function process status args)))))) + +(provide 'gnus-compat) + +;; gnus-compat.el ends here diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index 5165e9c53..f75ef37da 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -56,7 +56,7 @@ (autoload 'gnus-group-make-nnir-group "nnir") -(defcustom gnus-no-groups-message "No Gnus is good news" +(defcustom gnus-no-groups-message "No news is good news" "*Message displayed by Gnus when no groups are available." :group 'gnus-start :type 'string) diff --git a/lisp/gnus-msg.el b/lisp/gnus-msg.el index f92dc5e91..3867a58bd 100644 --- a/lisp/gnus-msg.el +++ b/lisp/gnus-msg.el @@ -163,6 +163,22 @@ if nil, attach files as normal parts." (const all :tag "Any") (string :tag "Regexp"))) +(defcustom gnus-gcc-self-resent-messages 'no-gcc-self + "Like `gcc-self' group parameter, only for unmodified resent messages. +Applied to messages sent by `gnus-summary-resend-message'. Non-nil +value of this variable takes precedence over any existing Gcc header. + +If this is `none', no Gcc copy will be made. If this is t, messages +resent will be Gcc'd to the current group. If this is a string, it +specifies a group to which resent messages will be Gcc'd. If this is +nil, Gcc will be done according to existing Gcc header(s), if any. +If this is `no-gcc-self', resent messages will be Gcc'd to groups that +existing Gcc header specifies, except for the current group." + :version "24.2" + :group 'gnus-message + :type '(choice (const none) (const t) string (const nil) + (const no-gcc-self))) + (gnus-define-group-parameter posting-charset-alist :type list @@ -1268,6 +1284,43 @@ For the \"inline\" alternatives, also see the variable (set-buffer gnus-original-article-buffer) (message-forward post))))))) +(defun gnus-summary-resend-message-insert-gcc () + "Insert Gcc header according to `gnus-gcc-self-resent-messages'." + (gnus-inews-insert-gcc) + (let ((gcc (mapcar + (lambda (group) + (mm-encode-coding-string + group + (gnus-group-name-charset (gnus-inews-group-method group) + group))) + (message-unquote-tokens + (message-tokenize-header (mail-fetch-field "gcc" nil t) + " ,"))))) + (message-remove-header "gcc") + (when gcc + (goto-char (point-max)) + (cond ((eq gnus-gcc-self-resent-messages 'none)) + ((eq gnus-gcc-self-resent-messages t) + (insert "Gcc: \"" gnus-newsgroup-name "\"\n")) + ((stringp gnus-gcc-self-resent-messages) + (insert "Gcc: " + (mm-encode-coding-string + (if (string-match " " gnus-gcc-self-resent-messages) + (concat "\"" gnus-gcc-self-resent-messages "\"") + gnus-gcc-self-resent-messages) + (gnus-group-name-charset + (gnus-inews-group-method gnus-gcc-self-resent-messages) + gnus-gcc-self-resent-messages)) + "\n")) + ((null gnus-gcc-self-resent-messages) + (insert "Gcc: " (mapconcat 'identity gcc ", ") "\n")) + ((eq gnus-gcc-self-resent-messages 'no-gcc-self) + (when (setq gcc (delete + gnus-newsgroup-name + (delete (concat "\"" gnus-newsgroup-name "\"") + gcc))) + (insert "Gcc: " (mapconcat 'identity gcc ", ") "\n"))))))) + (defun gnus-summary-resend-message (address n) "Resend the current article to ADDRESS." (interactive @@ -1281,12 +1334,20 @@ For the \"inline\" alternatives, also see the variable (with-current-buffer gnus-original-article-buffer (nnmail-fetch-field "to")))) current-prefix-arg)) - (dolist (article (gnus-summary-work-articles n)) - (gnus-summary-select-article nil nil nil article) - (with-current-buffer gnus-original-article-buffer - (let ((gnus-gcc-externalize-attachments nil)) - (message-resend address))) - (gnus-summary-mark-article-as-forwarded article))) + (let ((message-header-setup-hook (copy-sequence message-header-setup-hook)) + (message-sent-hook (copy-sequence message-sent-hook))) + (add-hook 'message-header-setup-hook + 'gnus-summary-resend-message-insert-gcc) + (add-hook 'message-sent-hook (if gnus-agent + 'gnus-agent-possibly-do-gcc + 'gnus-inews-do-gcc)) + (dolist (article (gnus-summary-work-articles n)) + (gnus-summary-select-article nil nil nil article) + (with-current-buffer gnus-original-article-buffer + (let ((gnus-gcc-externalize-attachments nil) + (message-inhibit-body-encoding t)) + (message-resend address))) + (gnus-summary-mark-article-as-forwarded article)))) ;; From: Matthieu Moy (defun gnus-summary-resend-message-edit () @@ -1628,12 +1689,16 @@ this is a reply." (when (and group-art ;; FIXME: Should gcc-mark-as-read work when ;; Gnus is not running? - (gnus-alive-p) - (or gnus-gcc-mark-as-read - (and - (boundp 'gnus-inews-mark-gcc-as-read) - (symbol-value 'gnus-inews-mark-gcc-as-read)))) - (gnus-group-mark-article-read group (cdr group-art))) + (gnus-alive-p)) + (if (or gnus-gcc-mark-as-read + (and (boundp 'gnus-inews-mark-gcc-as-read) + (symbol-value 'gnus-inews-mark-gcc-as-read))) + (gnus-group-mark-article-read group (cdr group-art)) + (with-current-buffer gnus-group-buffer + (let ((gnus-group-marked (list group)) + (gnus-get-new-news-hook nil) + (inhibit-read-only t)) + (gnus-group-get-new-news-this-group nil t))))) (setq options message-options) (with-current-buffer cur (setq message-options options)) (kill-buffer (current-buffer))))))))) diff --git a/lisp/gnus-registry.el b/lisp/gnus-registry.el index f1618b376..8e83c323d 100644 --- a/lisp/gnus-registry.el +++ b/lisp/gnus-registry.el @@ -267,7 +267,7 @@ the Bit Bucket." (append gnus-registry-track-extra '(mark group keyword))) (when (not (equal old (oref db :tracked))) - (gnus-message 4 "Reindexing the Gnus registry (tracked change)") + (gnus-message 9 "Reindexing the Gnus registry (tracked change)") (registry-reindex db)))) db) diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index 801f7723a..f7d7d8856 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -2303,7 +2303,19 @@ If FORCE is non-nil, the .newsrc file is read." (gnus-message 5 "Reading %s...done" newsrc-file))) ;; Convert old to new. - (gnus-convert-old-newsrc)))) + (gnus-convert-old-newsrc) + (gnus-clean-old-newsrc)))) + +(defun gnus-clean-old-newsrc () + (when gnus-newsrc-file-version + (when (< (gnus-continuum-version gnus-newsrc-file-version) + (gnus-continuum-version "Ma Gnus v0.02")) + ;; Remove old `exist' marks from old nnimap groups. + (dolist (info (cdr gnus-newsrc-alist)) + (let ((exist (assoc 'unexist (gnus-info-marks info)))) + (when exist + (gnus-info-set-marks + info (delete exist (gnus-info-marks info))))))))) (defun gnus-convert-old-newsrc () "Convert old newsrc formats into the current format, if needed." diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index 8ae8d0b8a..dfd1421cf 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -1530,6 +1530,9 @@ This list will always be a subset of gnus-newsgroup-undownloaded.") (defvar gnus-newsgroup-seen nil "Range of seen articles in the current newsgroup.") +(defvar gnus-newsgroup-unexist nil + "Range of unexistent articles in the current newsgroup.") + (defvar gnus-newsgroup-articles nil "List of articles in the current newsgroup.") @@ -1918,6 +1921,7 @@ increase the score of each group you read." "x" gnus-summary-limit-to-unread "s" gnus-summary-isearch-article [tab] gnus-summary-widget-forward + [backtab] gnus-summary-widget-backward "t" gnus-summary-toggle-header "g" gnus-summary-show-article "l" gnus-summary-goto-last-article @@ -2082,6 +2086,7 @@ increase the score of each group you read." "g" gnus-summary-show-article "s" gnus-summary-isearch-article [tab] gnus-summary-widget-forward + [backtab] gnus-summary-widget-backward "P" gnus-summary-print-article "S" gnus-sticky-article "M" gnus-mailing-list-insinuate @@ -5673,7 +5678,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq gnus-newsgroup-unselected (gnus-sorted-difference gnus-newsgroup-unreads articles)) (setq articles (gnus-articles-to-read group read-all))) - + (cond ((null articles) ;;(gnus-message 3 "Couldn't select newsgroup -- no articles to display") @@ -5812,6 +5817,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." "Find out what articles the user wants to read." (let* ((only-read-p t) (articles + (gnus-list-range-difference ;; Select all articles if `read-all' is non-nil, or if there ;; are no unread articles. (if (or read-all @@ -5838,7 +5844,8 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq only-read-p nil) (gnus-sorted-nunion (gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked) - gnus-newsgroup-unreads))) + gnus-newsgroup-unreads)) + (cdr (assq 'unexist (gnus-info-marks (gnus-get-info group)))))) (scored-list (gnus-killed-articles gnus-newsgroup-killed articles)) (scored (length scored-list)) (number (length articles)) @@ -6020,7 +6027,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." (and (numberp (car articles)) (> min (car articles))))) (pop articles)) - (set var articles)))))))) + (set var articles)) + ((eq mark 'unexist) + (set var (cdr marks))))))))) (defun gnus-update-missing-marks (missing) "Go through the list of MISSING articles and remove them from the mark lists." @@ -9266,6 +9275,17 @@ With optional ARG, move across that many fields." (select-window (gnus-get-buffer-window gnus-article-buffer)) (widget-forward arg)) +(defun gnus-summary-widget-backward (arg) + "Move point to the previous field or button in the article. +With optional ARG, move across that many fields." + (interactive "p") + (gnus-summary-select-article) + (gnus-configure-windows 'article) + (select-window (gnus-get-buffer-window gnus-article-buffer)) + (unless (widget-at (point)) + (goto-char (point-max))) + (widget-backward arg)) + (defun gnus-summary-isearch-article (&optional regexp-p) "Do incremental search forward on the current article. If REGEXP-P (the prefix) is non-nil, do regexp isearch." diff --git a/lisp/gnus-sync.el b/lisp/gnus-sync.el index 57c834add..6a45c672e 100644 --- a/lisp/gnus-sync.el +++ b/lisp/gnus-sync.el @@ -172,14 +172,11 @@ and `gnus-topic-alist'. Also see `gnus-variable-list'." (defun gnus-sync-lesync-call (url method headers &optional kvdata) "Make an access request to URL using KVDATA and METHOD. KVDATA must be an alist." - ;;(debug (json-encode kvdata)) - ;; (when (string-match-p "gmane.emacs.devel" url) (debug kvdata)) (flet ((json-alist-p (list) (gnus-sync-json-alist-p list))) ; temp patch (let ((url-request-method method) (url-request-extra-headers headers) (url-request-data (if kvdata (json-encode kvdata) nil))) (with-current-buffer (url-retrieve-synchronously url) - ;;(debug (buffer-string)) (let ((data (gnus-sync-lesync-parse))) (gnus-message 12 "gnus-sync-lesync-call: %s URL %s sent %S got %S" method url `((headers . ,headers) (data ,kvdata)) data) diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index da899f4bf..fef67cd52 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -1927,6 +1927,19 @@ Sizes are in pixels." image))) image))) +(defun gnus-recursive-directory-files (dir) + "Return all regular files below DIR." + (let (files) + (dolist (file (directory-files dir t)) + (when (and (not (member (file-name-nondirectory file) '("." ".."))) + (file-readable-p file)) + (cond + ((file-regular-p file) + (push file files)) + ((file-directory-p file) + (setq files (append (gnus-recursive-directory-files file) files)))))) + files)) + (defun gnus-list-memq-of-list (elements list) "Return non-nil if any of the members of ELEMENTS are in LIST." (let ((found nil)) diff --git a/lisp/gnus.el b/lisp/gnus.el index f2b2982a5..240b59023 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -36,6 +36,7 @@ (require 'wid-edit) (require 'mm-util) (require 'nnheader) +(require 'gnus-compat) ;; These are defined afterwards with gnus-define-group-parameter (defvar gnus-ham-process-destinations) @@ -293,10 +294,10 @@ is restarted, and sometimes reloaded." :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) -(defconst gnus-version-number "0.20" +(defconst gnus-version-number "0.2" "Version number for this version of Gnus.") -(defconst gnus-version (format "No Gnus v%s" gnus-version-number) +(defconst gnus-version (format "Ma Gnus v%s" gnus-version-number) "Version string for this version of Gnus.") (defcustom gnus-inhibit-startup-message nil @@ -1008,10 +1009,11 @@ be set in `.emacs' instead." (purp "#9999cc" "#666699") (no "#ff0000" "#ffff00") (neutral "#b4b4b4" "#878787") + (ma "#2020e0" "#8080ff") (september "#bf9900" "#ffcc00")) "Color alist used for the Gnus logo.") -(defcustom gnus-logo-color-style 'no +(defcustom gnus-logo-color-style 'ma "*Color styles used for the Gnus logo." :type `(choice ,@(mapcar (lambda (elem) (list 'const (car elem))) gnus-logo-color-alist)) @@ -2618,10 +2620,11 @@ a string, be sure to use a valid format, see RFC 2616." (scored . score) (saved . save) (cached . cache) (downloadable . download) (unsendable . unsend) (forwarded . forward) - (seen . seen))) + (seen . seen) (unexist . unexist))) (defconst gnus-article-special-mark-lists '((seen range) + (unexist range) (killed range) (bookmark tuple) (uid tuple) @@ -2636,7 +2639,7 @@ a string, be sure to use a valid format, see RFC 2616." ;; `score' is not a proper mark ;; `bookmark': don't propagated it, or fix the bug in update-mark. (defconst gnus-article-unpropagated-mark-lists - '(seen cache download unsend score bookmark) + '(seen cache download unsend score bookmark unexist) "Marks that shouldn't be propagated to back ends. Typical marks are those that make no sense in a standalone back end, such as a mark that says whether an article is stored in the cache diff --git a/lisp/lpath.el b/lisp/lpath.el index 857a53602..91613a221 100644 --- a/lisp/lpath.el +++ b/lisp/lpath.el @@ -26,7 +26,7 @@ (defun netrc-machine-user-or-password (mode authinfo-file-or-list machines ports defaults)) (defun netrc-parse (file)) - (defun shr-put-image (data alt)) + (defun shr-put-image (data alt &optional flags)) (maybe-fbind '(Info-index Info-index-next Info-menu bbdb-complete-name bookmark-default-handler @@ -52,7 +52,7 @@ ports defaults)) (defun netrc-parse (file)) (defun split-line (&optional arg)) - (defun shr-put-image (data alt)) + (defun shr-put-image (data alt &optional flags)) (eval-after-load "rmail" '(defun rmail-toggle-header (&optional arg))) (maybe-fbind diff --git a/lisp/message.el b/lisp/message.el index 416a4c8c3..f32981fba 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -3101,66 +3101,79 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (defun message-goto-to () "Move point to the To header." (interactive) + (push-mark) (message-position-on-field "To")) (defun message-goto-from () "Move point to the From header." (interactive) + (push-mark) (message-position-on-field "From")) (defun message-goto-subject () "Move point to the Subject header." (interactive) + (push-mark) (message-position-on-field "Subject")) (defun message-goto-cc () "Move point to the Cc header." (interactive) + (push-mark) (message-position-on-field "Cc" "To")) (defun message-goto-bcc () "Move point to the Bcc header." (interactive) + (push-mark) (message-position-on-field "Bcc" "Cc" "To")) (defun message-goto-fcc () "Move point to the Fcc header." (interactive) + (push-mark) (message-position-on-field "Fcc" "To" "Newsgroups")) (defun message-goto-reply-to () "Move point to the Reply-To header." (interactive) + (push-mark) (message-position-on-field "Reply-To" "Subject")) (defun message-goto-newsgroups () "Move point to the Newsgroups header." (interactive) + (push-mark) (message-position-on-field "Newsgroups")) (defun message-goto-distribution () "Move point to the Distribution header." (interactive) + (push-mark) (message-position-on-field "Distribution")) (defun message-goto-followup-to () "Move point to the Followup-To header." (interactive) + (push-mark) (message-position-on-field "Followup-To" "Newsgroups")) (defun message-goto-mail-followup-to () "Move point to the Mail-Followup-To header." (interactive) + (push-mark) (message-position-on-field "Mail-Followup-To" "To")) (defun message-goto-keywords () "Move point to the Keywords header." (interactive) + (push-mark) (message-position-on-field "Keywords" "Subject")) (defun message-goto-summary () "Move point to the Summary header." (interactive) + (push-mark) (message-position-on-field "Summary" "Subject")) (eval-when-compile @@ -3181,6 +3194,7 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (when (and (message-called-interactively-p 'any) (looking-at "[ \t]*\n")) (expand-abbrev)) + (push-mark) (goto-char (point-min)) (or (search-forward (concat "\n" mail-header-separator "\n") nil t) (search-forward-regexp "[^:]+:\\([^\n]\\|\n[ \t]\\)+\n\n" nil t))) @@ -3201,6 +3215,7 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." If there is no signature in the article, go to the end and return nil." (interactive) + (push-mark) (goto-char (point-min)) (if (re-search-forward message-signature-separator nil t) (forward-line 1) @@ -4523,8 +4538,9 @@ This function could be useful in `message-setup-hook'." (end-of-line) (insert (format " (%d/%d)" n total)) (widen) - (funcall (or message-send-mail-real-function - message-send-mail-function))) + (if message-send-mail-real-function + (funcall message-send-mail-real-function) + (message-multi-smtp-send-mail))) (setq n (+ n 1)) (setq p (pop plist)) (erase-buffer))) @@ -4678,8 +4694,9 @@ If you always want Gnus to send messages in one piece, set "))) (progn (message "Sending via mail...") - (funcall (or message-send-mail-real-function - message-send-mail-function))) + (if message-send-mail-real-function + (funcall message-send-mail-real-function) + (message-multi-smtp-send-mail))) (message-send-mail-partially)) (setq options message-options)) (kill-buffer tembuf)) @@ -4688,6 +4705,28 @@ If you always want Gnus to send messages in one piece, set (push 'mail message-sent-message-via))) (defvar sendmail-program) +(defvar smtpmail-smtp-user) + +(defun message-multi-smtp-send-mail () + "Send the current buffer to `message-send-mail-function'. +Or, if there's a header that specifies a different method, use +that instead." + (let ((method (message-field-value "X-Message-SMTP-Method"))) + (if (not method) + (funcall message-send-mail-function) + (message-remove-header "X-Message-SMTP-Method") + (setq method (split-string method)) + (cond + ((equal (car method) "sendmail") + (message-send-mail-with-sendmail)) + ((equal (car method) "smtp") + (require 'smtpmail) + (let ((smtpmail-smtp-server (nth 1 method)) + (smtpmail-smtp-service (nth 2 method)) + (smtpmail-smtp-user (or (nth 3 method) smtpmail-smtp-user))) + (message-smtpmail-send-it))) + (t + (error "Unknown method %s" method)))))) (defun message-send-mail-with-sendmail () "Send off the prepared buffer with sendmail." @@ -7574,7 +7613,7 @@ is for the internal use." (message "Resending message to %s..." address) (save-excursion (let ((cur (current-buffer)) - beg) + gcc beg) ;; We first set up a normal mail buffer. (unless (message-mail-user-agent) (set-buffer (get-buffer-create " *message resend*")) @@ -7587,6 +7626,8 @@ is for the internal use." ;; Insert our usual headers. (message-generate-headers '(From Date To Message-ID)) (message-narrow-to-headers) + (when (setq gcc (mail-fetch-field "gcc" nil t)) + (message-remove-header "gcc")) ;; Remove X-Draft-From header etc. (message-remove-header message-ignored-mail-headers t) ;; Rename them all to "Resent-*". @@ -7628,6 +7669,10 @@ is for the internal use." message-generate-hashcash rfc2047-encode-encoded-words) (message-send-mail)) + (when gcc + (message-goto-eoh) + (insert "Gcc: " gcc "\n")) + (run-hooks 'message-sent-hook) (kill-buffer (current-buffer))) (message "Resending message to %s...done" address))) diff --git a/lisp/mm-archive.el b/lisp/mm-archive.el new file mode 100644 index 000000000..5ca6616ab --- /dev/null +++ b/lisp/mm-archive.el @@ -0,0 +1,100 @@ +;;; mm-archive.el --- Functions for parsing archive files as MIME + +;; Copyright (C) 2012 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(defvar mm-archive-decoders + '(("application/ms-tnef" t "tnef" "-f" "-" "-C") + ("application/zip" nil "unzip" "-j" "-x" "%f" "-d") + ("application/x-gtar-compressed" nil "tar" "xzf" "-" "-C") + ("application/x-tar" nil "tar" "xf" "-" "-C"))) + +(defun mm-dissect-archive (handle) + (let ((decoder (cddr (assoc (car (mm-handle-type handle)) + mm-archive-decoders))) + (dir (mm-make-temp-file + (expand-file-name "emm." mm-tmp-directory) 'dir))) + (set-file-modes dir #o700) + (unwind-protect + (progn + (mm-with-unibyte-buffer + (mm-insert-part handle) + (if (member "%f" decoder) + (let ((file (expand-file-name "mail.zip" dir))) + (write-region (point-min) (point-max) file nil 'silent) + (setq decoder (copy-sequence decoder)) + (setcar (member "%f" decoder) file) + (apply 'call-process (car decoder) nil nil nil + (append (cdr decoder) (list dir))) + (delete-file file)) + (apply 'call-process-region (point-min) (point-max) (car decoder) + nil (get-buffer-create "*tnef*") + nil (append (cdr decoder) (list dir))))) + `("multipart/mixed" + ,handle + ,@(mm-archive-list-files (gnus-recursive-directory-files dir)))) + (delete-directory dir t)))) + +(defun mm-archive-list-files (files) + (let ((handles nil) + type disposition) + (dolist (file files) + (with-temp-buffer + (when (string-match "\\.\\([^.]+\\)$" file) + (setq type (mailcap-extension-to-mime (match-string 1 file)))) + (unless type + (setq type "application/octet-stream")) + (setq disposition + (if (string-match "^image/\\|^text/" type) + "inline" + "attachment")) + (insert (format "Content-type: %s\n" type)) + (insert "Content-Transfer-Encoding: 8bit\n\n") + (insert-file-contents file) + (push + (mm-make-handle (mm-copy-to-buffer) + (list type) + '8bit nil + `(,disposition (filename . ,file)) + nil nil nil) + handles))) + handles)) + +(defun mm-archive-dissect-and-inline (handle) + (let ((start (point-marker))) + (save-restriction + (narrow-to-region (point) (point)) + (dolist (handle (cddr (mm-dissect-archive handle))) + (goto-char (point-max)) + (mm-display-inline handle)) + (goto-char (point-max)) + (mm-handle-set-undisplayer + handle + `(lambda () + (let ((inhibit-read-only t) + (end ,(point-marker))) + (remove-images ,start end) + (delete-region ,start end))))))) + +(provide 'mm-archive) + +;; mm-archive.el ends here diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index dd3eb6c9d..03bcaa15f 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -29,6 +29,7 @@ (require 'mail-parse) (require 'mm-bodies) +(require 'mm-archive) (eval-when-compile (require 'cl) (require 'term)) @@ -248,6 +249,8 @@ before the external MIME handler is invoked." ("message/partial" mm-inline-partial identity) ("message/external-body" mm-inline-external-body identity) ("text/.*" mm-inline-text identity) + ("application/x-.?tar\\(-.*\\)?" mm-archive-dissect-and-inline identity) + ("application/zip" mm-archive-dissect-and-inline identity) ("audio/wav" mm-inline-audio (lambda (handle) (and (or (featurep 'nas-sound) (featurep 'native-sound)) @@ -297,6 +300,9 @@ before the external MIME handler is invoked." "application/pgp-signature" "application/x-pkcs7-signature" "application/pkcs7-signature" "application/x-pkcs7-mime" "application/pkcs7-mime" + "application/x-gtar-compressed" + "application/x-tar" + "application/zip" ;; Mutt still uses this even though it has already been withdrawn. "application/pgp") "List of media types that are to be displayed inline. @@ -653,8 +659,16 @@ Postpone undisplaying of viewers for types in (if (equal "text/plain" (car ctl)) (assoc 'format ctl) t)) - (mm-make-handle - (mm-copy-to-buffer) ctl cte nil cdl description nil id))) + (let ((handle + (mm-make-handle + (mm-copy-to-buffer) ctl cte nil cdl description nil id)) + (decoder (assoc (car ctl) mm-archive-decoders))) + (if (and decoder + ;; Do automatic decoding + (cadr decoder) + (executable-find (caddr decoder))) + (mm-dissect-archive handle) + handle)))) (defun mm-dissect-multipart (ctl from) (goto-char (point-min)) @@ -918,46 +932,38 @@ external if displayed external." shell-command-switch command) (set-process-sentinel (get-buffer-process buffer) - (lexical-let ;; Don't use `let'. - ;; Function used to remove temp file and directory. - ((fn `(lambda nil - ;; Don't use `ignore-errors'. - (condition-case nil - (delete-file ,file) - (error)) - (condition-case nil - (delete-directory - ,(file-name-directory file)) - (error)))) - ;; Form uses to kill the process buffer and - ;; remove the undisplayer. - (fm `(progn - (kill-buffer ,buffer) - ,(macroexpand - (list 'mm-handle-set-undisplayer - (list 'quote handle) - nil)))) - ;; Message to be issued when the process exits. - (done (format "Displaying %s...done" command)) - ;; In particular, the timer object (which is - ;; a vector in Emacs but is a list in XEmacs) - ;; requires that it is lexically scoped. - (timer (run-at-time 30.0 nil 'ignore))) - (if (featurep 'xemacs) - (lambda (process state) - (when (eq 'exit (process-status process)) - (if (memq timer itimer-list) - (set-itimer-function timer fn) - (funcall fn)) - (ignore-errors (eval fm)) - (message "%s" done))) - (lambda (process state) - (when (eq 'exit (process-status process)) - (if (memq timer timer-list) - (timer-set-function timer fn) - (funcall fn)) - (ignore-errors (eval fm)) - (message "%s" done))))))) + (lexical-let ((outbuf outbuf) + (file file) + (buffer buffer) + (command command) + (handle handle)) + (run-at-time + 30.0 nil + (lambda () + (ignore-errors + (delete-file file)) + (ignore-errors + (delete-directory (file-name-directory file))))) + (lambda (process state) + (when (eq (process-status process) 'exit) + (condition-case nil + (delete-file file) + (error)) + (condition-case nil + (delete-directory (file-name-directory file)) + (error)) + (when (buffer-live-p outbuf) + (with-current-buffer outbuf + (let ((buffer-read-only nil) + (point (point))) + (forward-line 2) + (mm-insert-inline + handle (with-current-buffer buffer + (buffer-string))) + (goto-char point)))) + (when (buffer-live-p buffer) + (kill-buffer buffer))) + (message "Displaying %s...done" command))))) (mm-handle-set-external-undisplayer handle (cons file buffer))) (message "Displaying %s..." command)) @@ -1758,6 +1764,8 @@ If RECURSIVE, search recursively." mm-extra-numeric-entities))) (replace-match (char-to-string char)))) (libxml-parse-html-region (point-min) (point-max)))) + (unless (bobp) + (insert "\n")) (mm-handle-set-undisplayer handle `(lambda () diff --git a/lisp/mm-util.el b/lisp/mm-util.el index e9119284a..4fb5ea704 100644 --- a/lisp/mm-util.el +++ b/lisp/mm-util.el @@ -1592,7 +1592,7 @@ gzip, bzip2, etc. are allowed." (unless filename (setq filename buffer-file-name)) (save-excursion - (let ((decomp (unless ;; No worth to examine charset of tar files. + (let ((decomp (unless ;; Not worth it to examine charset of tar files. (and filename (string-match "\\.\\(?:tar\\.[^.]+\\|tbz\\|tgz\\)\\'" diff --git a/lisp/nnimap.el b/lisp/nnimap.el index 73f9b917e..a78346c60 100644 --- a/lisp/nnimap.el +++ b/lisp/nnimap.el @@ -1230,7 +1230,8 @@ textual parts.") (setf (nnimap-group nnimap-object) nil) (setf (nnimap-initial-resync nnimap-object) 0) (let ((qresyncp (nnimap-capability "QRESYNC")) - params groups sequences active uidvalidity modseq group) + params groups sequences active uidvalidity modseq group + unexist) ;; Go through the infos and gather the data needed to know ;; what and how to request the data. (dolist (info infos) @@ -1238,13 +1239,15 @@ textual parts.") group (nnimap-decode-gnus-group (gnus-group-real-name (gnus-info-group info))) active (cdr (assq 'active params)) + unexist (assq 'unexist (gnus-info-marks info)) uidvalidity (cdr (assq 'uidvalidity params)) modseq (cdr (assq 'modseq params))) (setf (nnimap-examined nnimap-object) group) (if (and qresyncp uidvalidity active - modseq) + modseq + unexist) (push (list (nnimap-send-command "EXAMINE %S (%s (%s %s))" (utf7-encode group t) @@ -1263,11 +1266,10 @@ textual parts.") ;; is read-only or not. "SELECT")) start) - (if (and active uidvalidity) + (if (and active uidvalidity unexist) ;; Fetch the last 100 flags. (setq start (max 1 (- (cdr active) 100))) - (setf (nnimap-initial-resync nnimap-object) - (1+ (nnimap-initial-resync nnimap-object))) + (incf (nnimap-initial-resync nnimap-object)) (setq start 1)) (push (list (nnimap-send-command "%s %S" command (utf7-encode group t)) @@ -1444,6 +1446,20 @@ textual parts.") (setq new-marks (gnus-range-nconcat old-marks new-marks))) (when new-marks (push (cons (car type) new-marks) marks))))) + ;; Keep track of non-existing articles. + (let* ((old-unexists (assq 'unexist marks)) + (unexists + (if completep + (gnus-range-difference + (gnus-active group) + (gnus-compress-sequence existing)) + (gnus-add-to-range + (cdr old-unexists) + (gnus-list-range-difference + existing (gnus-active group)))))) + (if old-unexists + (setcdr old-unexists unexists) + (push (cons 'unexist unexists) marks))) (gnus-info-set-marks info marks t)))) ;; Tell Gnus whether there are any \Recent messages in any of ;; the groups. @@ -1487,6 +1503,14 @@ textual parts.") (gnus-sorted-complement existing new-marks)))) (when ticks (push (cons (car type) ticks) marks))) + (gnus-info-set-marks info marks t)) + ;; Add vanished to the list of unexisting articles. + (when vanished + (let* ((old-unexists (assq 'unexist marks)) + (unexists (gnus-range-add (cdr old-unexists) vanished))) + (if old-unexists + (setcdr old-unexists unexists) + (push (cons 'unexist unexists) marks))) (gnus-info-set-marks info marks t)))) (defun nnimap-imap-ranges-to-gnus-ranges (irange) diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 9c3a814d3..988e1cdc1 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -553,11 +553,11 @@ parameter. It should return nil, `warn' or `delete'." (const warn) (const delete))) -(defcustom nnmail-extra-headers '(To Newsgroups) +(defcustom nnmail-extra-headers '(To Newsgroups Cc) "Extra headers to parse. In addition to the standard headers, these extra headers will be included in NOV headers (and the like) when backends parse headers." - :version "21.1" + :version "24.2" :group 'nnmail :type '(repeat symbol)) diff --git a/lisp/shr.el b/lisp/shr.el index 47622f518..2f6a04cde 100644 --- a/lisp/shr.el +++ b/lisp/shr.el @@ -119,6 +119,7 @@ cid: URL as the argument.") (let ((map (make-sparse-keymap))) (define-key map "a" 'shr-show-alt-text) (define-key map "i" 'shr-browse-image) + (define-key map "z" 'shr-zoom-image) (define-key map "I" 'shr-insert-image) (define-key map "u" 'shr-copy-url) (define-key map "v" 'shr-browse-url) @@ -235,6 +236,40 @@ the URL of the image to the kill buffer instead." (list (current-buffer) (1- (point)) (point-marker)) t t)))) +(defun shr-zoom-image () + "Toggle the image size. +The size will be rotated between the default size, the original +size, and full-buffer size." + (interactive) + (let ((url (get-text-property (point) 'image-url)) + (size (get-text-property (point) 'image-size)) + (buffer-read-only nil)) + (if (not url) + (message "No image under point") + ;; Delete the old picture. + (while (get-text-property (point) 'image-url) + (forward-char -1)) + (forward-char 1) + (let ((start (point))) + (while (get-text-property (point) 'image-url) + (forward-char 1)) + (forward-char -1) + (put-text-property start (point) 'display nil) + (when (> (- (point) start) 2) + (delete-region start (1- (point))))) + (message "Inserting %s..." url) + (url-retrieve url 'shr-image-fetched + (list (current-buffer) (1- (point)) (point-marker) + (list (cons 'size + (cond ((or (eq size 'default) + (null size)) + 'original) + ((eq size 'original) + 'full) + ((eq size 'full) + 'default))))) + t)))) + ;;; Utility functions. (defun shr-transform-dom (dom) @@ -523,7 +558,7 @@ the URL of the image to the kill buffer instead." (expand-file-name (file-name-nondirectory url) directory))))) -(defun shr-image-fetched (status buffer start end) +(defun shr-image-fetched (status buffer start end &optional flags) (when (and (buffer-name buffer) (not (plist-get status :error))) (url-store-in-cache (current-buffer)) @@ -533,30 +568,53 @@ the URL of the image to the kill buffer instead." (with-current-buffer buffer (save-excursion (let ((alt (buffer-substring start end)) + (properties (text-properties-at start)) (inhibit-read-only t)) (delete-region start end) (goto-char start) - (funcall shr-put-image-function data alt))))))) + (funcall shr-put-image-function data alt flags) + (while properties + (let ((type (pop properties)) + (value (pop properties))) + (unless (memq type '(display image-size)) + (put-text-property start (point) type value)))))))))) (kill-buffer (current-buffer))) -(defun shr-put-image (data alt) +(defun shr-put-image (data alt &optional flags) "Put image DATA with a string ALT. Return image." (if (display-graphic-p) - (let ((image (ignore-errors - (shr-rescale-image data)))) + (let* ((size (cdr (assq 'size flags))) + (start (point)) + (image (cond + ((eq size 'original) + (create-image data nil t :ascent 100)) + ((eq size 'full) + (ignore-errors + (shr-rescale-image data t))) + (t + (ignore-errors + (shr-rescale-image data)))))) (when image ;; When inserting big-ish pictures, put them at the ;; beginning of the line. (when (and (> (current-column) 0) (> (car (image-size image t)) 400)) (insert "\n")) - (insert-image image (or alt "*")) + (if (eq size 'original) + (let ((overlays (overlays-at (point)))) + (insert-sliced-image image (or alt "*") nil 20 1) + (dolist (overlay overlays) + (overlay-put overlay 'face 'default))) + (insert-image image (or alt "*"))) + (put-text-property start (point) 'image-size size) (when (image-animated-p image) (image-animate image nil 60))) image) (insert alt))) -(defun shr-rescale-image (data) +(defun shr-rescale-image (data &optional force) + "Rescale DATA, if too big, to fit the current buffer. +If FORCE, rescale the image anyway." (let* ((max-image-size nil) (image (create-image data nil t :ascent 100))) (if (or (not (fboundp 'imagemagick-types)) @@ -572,7 +630,8 @@ the URL of the image to the kill buffer instead." (window-height (truncate (* shr-max-image-proportion (- (nth 3 edges) (nth 1 edges))))) scaled-image) - (when (> height window-height) + (when (or force + (> height window-height)) (setq image (or (create-image data 'imagemagick t :height window-height :ascent 100) diff --git a/makepub b/makepub index 4159d0f18..58c51cba8 100755 --- a/makepub +++ b/makepub @@ -1,5 +1,5 @@ #!/bin/bash -name="No Gnus" +name="Ma Gnus" if [ `whoami` != "larsi" ]; then echo "This script is for larsi only" diff --git a/texi/ChangeLog b/texi/ChangeLog index 9ed122d82..6894461cc 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,22 @@ +2012-02-08 Katsumi Yamaoka + + * gnus.texi (Archived Messages): Document gnus-gcc-self-resent-messages. + +2012-02-06 Lars Ingebrigtsen + + * message.texi (Mail Variables): Mention the optional user parameter + for X-Message-SMTP-Method. + +2012-02-02 Lars Ingebrigtsen + + * gnus.texi (Posting Styles): Mention X-Message-SMTP-Method. + + * message.texi (Mail Variables): Document X-Message-SMTP-Method. + +2012-01-31 Lars Ingebrigtsen + + * gnus.texi (Key Index): Change encoding to utf-8. + 2012-02-07 Lars Ingebrigtsen * gnus.texi (Mail Source Specifiers): Add a pop3 via an SSH tunnel diff --git a/texi/gnus.texi b/texi/gnus.texi index 1241ad77a..fb1f539d4 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -8,7 +8,7 @@ @syncodeindex vr cp @syncodeindex pg cp -@documentencoding ISO-8859-1 +@documentencoding UTF-8 @copying Copyright @copyright{} 1995-2012 Free Software Foundation, Inc. @@ -47,7 +47,7 @@ developing GNU and promoting software freedom.'' \begin{document} % Adjust ../Makefile.in if you change the following line: -\newcommand{\gnusversionname}{No Gnus v0.20} +\newcommand{\gnusversionname}{Ma Gnus v0.2} \newcommand{\gnuschaptername}{} \newcommand{\gnussectionname}{} @@ -358,7 +358,7 @@ spool or your mbox file. All at the same time, if you want to push your luck. @c Adjust ../Makefile.in if you change the following line: -This manual corresponds to No Gnus v0.20 +This manual corresponds to Ma Gnus v0.2 @ifnottex @insertcopying @@ -392,7 +392,7 @@ people should be empowered to do what they want by using (or abusing) the program. @c Adjust ../Makefile.in if you change the following line: -This manual corresponds to No Gnus v0.20 +This manual corresponds to Ma Gnus v0.2 @heading Other related manuals @itemize @@ -907,7 +907,8 @@ New Features * Quassia Gnus:: Two times two is four, or Gnus 5.6/5.7. * Pterodactyl Gnus:: Pentad also starts with P, AKA Gnus 5.8/5.9. * Oort Gnus:: It's big. It's far out. Gnus 5.10/5.11. -* No Gnus:: Very punny. +* No Gnus:: Very punny. Gnus 5.12/5.13 +* Ma Gnus:: Celebrating 25 years of Gnus. Customization @@ -2884,7 +2885,7 @@ composed messages will be @code{Gcc}'d to the current group. If generated, if @code{(gcc-self . "string")} is present, this string will be inserted literally as a @code{gcc} header. This parameter takes precedence over any default @code{Gcc} rules as described later -(@pxref{Archived Messages}). +(@pxref{Archived Messages}), with the exception for messages to resend. @strong{Caveat}: Adding @code{(gcc-self . t)} to the parameter list of @code{nntp} groups (or the like) isn't valid. An @code{nntp} server @@ -3027,6 +3028,7 @@ like this in the group parameters: @example (posting-style (name "Funky Name") + ("X-Message-SMTP-Method" "smtp smtp.example.org 587") ("X-My-Header" "Funky Value") (signature "Funky Signature")) @end example @@ -8981,7 +8983,7 @@ Translate many non-@acronym{ASCII} characters into their @acronym{ASCII} equivalents (@code{gnus-article-treat-non-ascii}). This is mostly useful if you're on a terminal that has a limited font and doesn't show accented characters, ``advanced'' punctuation, and the -like. For instance, @samp{»} is translated into @samp{>>}, and so on. +like. For instance, @samp{»} is translated into @samp{>>}, and so on. @item W Y f @kindex W Y f (Summary) @@ -12669,6 +12671,22 @@ and matches the Gcc group name, attach files as external parts; if it is non-@code{nil}, the behavior is the same as @code{all}, but it may be changed in the future. +@item gnus-gcc-self-resent-messages +@vindex gnus-gcc-self-resent-messages +Like the @code{gcc-self} group parameter, applied only for unmodified +messages that @code{gnus-summary-resend-message} (@pxref{Summary Mail +Commands}) resends. Non-@code{nil} value of this variable takes +precedence over any existing @code{Gcc} header. + +If this is @code{none}, no @code{Gcc} copy will be made. If this is +@code{t}, messages resent will be @code{Gcc} copied to the current +group. If this is a string, it specifies a group to which resent +messages will be @code{Gcc} copied. If this is @code{nil}, @code{Gcc} +will be done according to existing @code{Gcc} header(s), if any. If +this is @code{no-gcc-self}, that is the default, resent messages will be +@code{Gcc} copied to groups that existing @code{Gcc} header specifies, +except for the current group. + @end table @@ -12800,6 +12818,7 @@ So here's a new example: (signature-file "~/.work-signature") (address "user@@bar.foo") (body "You are fired.\n\nSincerely, your boss.") + ("X-Message-SMTP-Method" "smtp smtp.example.org 587") (organization "Important Work, Inc")) ("nnml:.*" (From (with-current-buffer gnus-article-buffer @@ -12814,6 +12833,13 @@ if you fill many roles. You may also use @code{message-alternative-emails} instead. @xref{Message Headers, ,Message Headers, message, Message Manual}. +Of particular interest in the ``work-mail'' style is the +@samp{X-Message-SMTP-Method} header. It specifies how to send the +outgoing email. You may want to sent certain emails through certain +@acronym{SMTP} servers due to company policies, for instance. +@xref{Mail Variables, ,Message Variables, message, Message Manual}. + + @node Drafts @section Drafts @cindex drafts @@ -20865,7 +20891,7 @@ then this operator will return @code{false}. @item ! @itemx not -@itemx ¬ +@itemx ¬ This logical operator only takes a single argument. It returns the logical negation of the value of its argument. @@ -22505,7 +22531,7 @@ and so on. Create as many faces as you wish. The same goes for the @samp{hello} mouse-highlighted with @code{gnus-mouse-face-3}. @cindex %<<, %>>, guillemets -@c @cindex %<<, %>>, %«, %», guillemets +@c @cindex %<<, %>>, %«, %», guillemets @vindex gnus-balloon-face-0 Text inside the @samp{%<<} and @samp{%>>} specifiers will get the special @code{balloon-help} property set to @@ -26399,6 +26425,7 @@ renamed it back again to ``Gnus''. But in mixed case. ``Gnus'' vs. @cindex Pterodactyl Gnus @cindex Oort Gnus @cindex No Gnus +@cindex Ma Gnus @cindex Gnus versions The first ``proper'' release of Gnus 5 was done in November 1995 when it @@ -26427,12 +26454,15 @@ On April 19, 2010 Gnus development was moved to Git. See http://git.gnus.org for details (http://www.gnus.org will be updated with the information when possible). +On the January 31th 2012, Ma Gnus was begun. + If you happen upon a version of Gnus that has a prefixed name -- ``(ding) Gnus'', ``September Gnus'', ``Red Gnus'', ``Quassia Gnus'', -``Pterodactyl Gnus'', ``Oort Gnus'', ``No Gnus'' -- don't panic. -Don't let it know that you're frightened. Back away. Slowly. Whatever -you do, don't run. Walk away, calmly, until you're out of its reach. -Find a proper released version of Gnus and snuggle up to that instead. +``Pterodactyl Gnus'', ``Oort Gnus'', ``No Gnus'', ``Ma Gnus'' -- don't +panic. Don't let it know that you're frightened. Back away. Slowly. +Whatever you do, don't run. Walk away, calmly, until you're out of +its reach. Find a proper released version of Gnus and snuggle up to +that instead. @node Why? @@ -27035,7 +27065,8 @@ actually are people who are using Gnus. Who'd'a thunk it! * Quassia Gnus:: Two times two is four, or Gnus 5.6/5.7. * Pterodactyl Gnus:: Pentad also starts with P, AKA Gnus 5.8/5.9. * Oort Gnus:: It's big. It's far out. Gnus 5.10/5.11. -* No Gnus:: Very punny. +* No Gnus:: Very punny. Gnus 5.12/5.13. +* Ma Gnus:: Celebrating 25 years of Gnus. @end menu These lists are, of course, just @emph{short} overviews of the @@ -28410,6 +28441,13 @@ New features in No Gnus: @include gnus-news.texi +@node Ma Gnus +@subsubsection Ma Gnus +@cindex Ma Gnus + +I'm sure there will be lots of text here. It's really spelled 真 +Gnus. + @iftex @page @@ -28913,7 +28951,7 @@ Gnus will work. @item Try doing an @kbd{M-x gnus-version}. If you get something that looks like @c -@samp{No Gnus v0.20} @c Adjust ../Makefile.in if you change this line! +@samp{Ma Gnus v0.2} @c Adjust ../Makefile.in if you change this line! @c you have the right files loaded. Otherwise you have some old @file{.el} files lying around. Delete these. @@ -30632,5 +30670,5 @@ former). The manual is unambiguous, but it can be confusing. @c Local Variables: @c mode: texinfo -@c coding: iso-8859-1 +@c coding: utf-8 @c End: diff --git a/texi/message.texi b/texi/message.texi index bc5efe119..5fc109c1a 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -77,7 +77,7 @@ Message mode buffers. @c Adjust ../Makefile.in if you change the following lines: Message is distributed with Gnus. The Gnus distribution @c -corresponding to this manual is No Gnus v0.20 +corresponding to this manual is Ma Gnus v0.2 @node Interface @@ -1641,6 +1641,40 @@ To the thing similar to this, there is requires the @acronym{POP}-before-@acronym{SMTP} authentication. @xref{POP before SMTP, , POP before SMTP, gnus, The Gnus Manual}. +@cindex X-Message-SMTP-Method +If you have a complex @acronym{SMTP} setup, and want some messages to +go via one mail server, and other messages to go through another, you +can use the @samp{X-Message-SMTP-Method} header. These are the +supported values: + +@table @samp +@item smtpmail + +@example +X-Message-SMTP-Method: smtp smtp.fsf.org 587 +@end example + +This will send the message via @samp{smtp.fsf.org}, using port 587. + +@example +X-Message-SMTP-Method: smtp smtp.fsf.org 587 other-user +@end example + +This is the same as the above, but uses @samp{other-user} as the user +name when authenticating. This is handy if you have several +@acronym{SMTP} accounts on the same server. + +@item sendmail + +@example +X-Message-SMTP-Method: sendmail +@end example + +This will send the message via the locally installed sendmail/exim/etc +installation. + +@end table + @item message-mh-deletable-headers @vindex message-mh-deletable-headers Most versions of MH doesn't like being fed messages that contain the