+2002-01-15 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * lisp/nntp.el (nntp-send-buffer): Bind `mc-flag' to nil.
+
+ * lisp/nnheader.el (mm-with-unibyte-buffer): Alias to
+ `nnheader-with-unibyte-buffer'.
+ (nnheader-with-unibyte-buffer): New macro.
+
2002-01-12 Katsuhiro Hermit Endo <hermit@koka-in.org>
* texi/gnus-ja.texi (Article Date): Update Japanese translation.
\f
* Changes in Oort Gnus
+** 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
+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.
+
+** Gnus supports the "format=flowed" (RFC 2646) parameter.
+
+On composing messages, it is enabled by `use-hard-newlines'. Decoding
+format=flowed was present but not documented in earlier versions.
+
** Gnus supports the generation of RFC 2298 Disposition Notification requests.
This is invoked with the C-c M-n key binding from message mode.
** Gnus supports Maildir groups.
-Gnus includes a new backend nnmaildir.el, by Paul Jarc.
+Gnus includes a new backend nnmaildir.el.
** Printing capabilities are enhanced.
+2002-01-14 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus.el: We don't need gnus-article-show-all-headers.
+
+ * gnus-art.el (article-show-all, gnus-article-show-all-header):
+ Ditto.
+
+ * gnus-sum.el (gnus-summary-select-article): Don't call
+ show-all-headers, because hidden headers are not hidden text any
+ more.
+
+2002-01-13 Simon Josefsson <jas@extundo.com>
+
+ * message.el (message-newline-and-reformat): Use `newline' instead
+ of inserting \n, so that the newline is marked as hard.
+
+ * gnus-spec.el (gnus-pad-form): Don't evaluate EL multiple times.
+ From Jesper Harder <harder@ifa.au.dk>.
+
+2002-01-12 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * imap.el (imap-close): Keep going if quit.
+
+ * gnus-agent.el (gnus-agent-retrieve-headers): Erase
+ nntp-server-buffer.
+
+2002-01-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * mm-view.el (mm-display-inline-fontify): Require font-lock to
+ avoid unbinding shadowed variables.
+
+ * gnus-art.el (gnus-picon-databases): Moved here.
+ (gnus-picons-installed-p): Moved here.
+ (gnus-article-reply-with-original): Use `mark'.
+
+ * gnus.el (gnus-picon): Moved here and renamed.
+
+ * gnus-art.el (gnus-treat-from-picon): Only be on if picons are
+ installed.
+ (gnus-treat-mail-picon): Ditto.
+ (gnus-treat-newsgroups-picon): Ditto.
+
+ * gnus-picon.el (gnus-picons-installed-p): New function.
+
+2002-01-12 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-agent.el (gnus-agent-go-online): Fix doc.
+
+2002-01-12 Simon Josefsson <jas@extundo.com>
+
+ * nnimap.el (nnimap-need-unselect-to-notice-new-mail)
+ (nnimap-before-find-minmax-bugworkaround): Use it.
+ (nnimap-find-minmax-uid): Don't reselect current mailbox.
+ (nnimap-dont-close): New variable.
+ (nnimap-close-group): Use it.
+
+2002-01-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-art.el (gnus-article-reply-with-original): Use
+ `mark-active'.
+
+ * gnus-msg.el (gnus-summary-reply): Don't bug out on regions.
+
+ * gnus-logic.el (gnus-advanced-score-rule): Thinko fix.
+ (gnus-score-advanced): Clean up.
+ (gnus-score-advanced): Accept a multiple of the score.
+
+2002-01-12 Simon Josefsson <jas@extundo.com>
+
+ * flow-fill.el (fill-flowed-display-column)
+ (fill-flowed-encode-columnq): New variables. Suggested by
+ Kai.Grossjohann@CS.Uni-Dortmund.DE (Kai Gro\e,A_\e(Bjohann).
+ (fill-flowed-encode, fill-flowed): Use them.
+
+ * message.el (message-send-news, message-send-mail): Use
+ m-b-s-n-p-e-h-n.
+
+ * mml.el (autoload): Autoload fill-flowed-encode.
+ (mml-buffer-substring-no-properties-except-hard-newlines): New
+ function.
+ (mml-read-part): Use it.
+ (mml-generate-mime-1): Encode format=flowed if appropriate.
+ (mml-insert-mime-headers): Insert format=flowed.
+
+ * flow-fill.el (fill-flowed-encode): New function.
+ (fill-flowed): Bind fill-column to window width.
+
+2002-01-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-sum.el (gnus-summary-buffer-name): Return the dead name if
+ it exists.
+ (gnus-summary-setup-buffer): Wake up dead summary buffers.
+ (gnus-summary-buffer-name): Don't return the dead name after all.
+ (gnus-summary-setup-buffer): Kill the dead buffer.
+
+ * gnus-art.el (gnus-article-followup-with-original): Store the
+ value of the mark before deactivating it.
+
+2002-01-11 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-fun.el (gnus-display-x-face-in-from): Fake it.
+ From: Karl Kleinpaste <karl@charcoal.com>
+
+ * gnus-art.el (article-display-x-face): Ditto.
+ (gnus-article-reply-with-original): Use gnus-region-active-p.
+ (gnus-article-followup-with-original): Ditto.
+
+ * gnus-sum.el (gnus-summary-read-group-1): Don't select
+ downloadable article either.
+
+2002-01-11 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-art.el (article-display-x-face): Insert From:.
+
+ * gnus-sum.el (gnus-summary-move-article): Don't draw the
+ article. Bind gnus-display-mime-function and
+ gnus-article-prepare-hook.
+
+ * gnus-agent.el (gnus-agent-retrieve-headers): Load agentview.
+ (gnus-agent-toggle-plugged): Use gnus-agent-go-online. Move
+ gnus-agent-possibly-synchronize-flags to the last.
+ (gnus-agent-go-online): New function. New variable.
+
+2002-01-11 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-agent.el (gnus-agent-regenerate-group): Add clean option.
+ (gnus-agent-regenerate): Ditto.
+
+2002-01-11 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * message.el (message-ignored-news-headers)
+ (message-ignored-mail-headers): Add X-Gnus-Agent-Meta-Information:.
+ Suggested by ARISAWA Akihiro <ari@atesoft.advantest.co.jp>
+
+ * gnus.el (gnus-gethash-safe): New macro.
+
+ * gnus-agent.el (gnus-agent-regenerate-history): New function.
+ (gnus-agent-regenerate): Show messages.
+
+2002-01-11 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-agent.el (gnus-agent-regenerate-group): New function.
+ (gnus-agent-regenerate): New function.
+ (gnus-agent-save-alist): Sort.
+ (gnus-agent-copy-nov-line): Test eobp.
+ (gnus-agent-retrieve-headers): Erase buffer.
+
2002-01-10 ShengHuo ZHU <zsh@cs.rochester.edu>
* mm-util.el (mm-charset-to-coding-system): Change charset to cs.
;;; flow-fill.el --- interprete RFC2646 "flowed" text
-;; Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
;; Author: Simon Josefsson <jas@pdc.kth.se>
;; Keywords: mail
;; paragraph and we let `fill-region' fill the long line into several
;; lines with the quote prefix as `fill-prefix'.
-;; Todo: encoding, implement basic `fill-region' (Emacs and XEmacs
+;; Todo: implement basic `fill-region' (Emacs and XEmacs
;; implementations differ..)
;;; History:
;; 2000-03-26 commited to gnus cvs
;; 2000-10-23 don't flow "-- " lines, make "quote-depth wins" rule
;; work when first line is at level 0.
+;; 2002-01-12 probably incomplete encoding support
;;; Code:
(eval-when-compile (require 'cl))
+(defcustom fill-flowed-display-column 'fill-column
+ "Column beyond which format=flowed lines are wrapped, when displayed.
+This can be a lisp expression or an integer."
+ :type '(choice (const :tag "Standard `fill-column'" fill-column)
+ (const :tag "Fit Window" (- (window-width) 5))
+ (sexp)
+ (integer)))
+
+(defcustom fill-flowed-encode-column 66
+ "Column beyond which format=flowed lines are wrapped, in outgoing messages.
+This can be a lisp expression or an integer.
+RFC 2646 suggests 66 characters for readability."
+ :type '(choice (const :tag "Standard fill-column" fill-column)
+ (const :tag "RFC 2646 default (66)" 66)
+ (sexp)
+ (integer)))
+
(eval-and-compile
(defalias 'fill-flowed-point-at-bol
(if (fboundp 'point-at-bol)
'point-at-eol
'line-end-position)))
+(defun fill-flowed-encode (&optional buffer)
+ (with-current-buffer (or buffer (current-buffer))
+ ;; No point in doing this unless hard newlines is used.
+ (when use-hard-newlines
+ (let ((start (point-min)) end)
+ ;; Go through each paragraph, filling it and adding SPC
+ ;; as the last character on each line.
+ (while (setq end (text-property-any start (point-max) 'hard 't))
+ (let ((fill-column (eval fill-flowed-encode-column)))
+ (fill-region start end t 'nosqueeze 'to-eop))
+ (goto-char start)
+ ;; `fill-region' probably distorted end.
+ (setq end (text-property-any start (point-max) 'hard 't))
+ (while (and (< (point) end)
+ (re-search-forward "$" (1- end) t))
+ (insert " ")
+ (setq end (1+ end))
+ (forward-char))
+ (goto-char (setq start (1+ end)))))
+ t)))
+
(defun fill-flowed (&optional buffer)
(save-excursion
(set-buffer (or (current-buffer) buffer))
(beginning-of-line)
(when (> (skip-chars-forward ">") 0)
(insert " "))))
+ ;; XXX slightly buggy handling of "-- "
(while (and (save-excursion
(ignore-errors (backward-char 3))
(setq sig (looking-at "-- "))
(backward-delete-char -1)
(end-of-line))
(unless sig
- (let ((fill-prefix (when quote (concat quote " "))))
+ (let ((fill-prefix (when quote (concat quote " ")))
+ (fill-column (eval fill-flowed-display-column)))
(fill-region (fill-flowed-point-at-bol)
(min (1+ (fill-flowed-point-at-eol)) (point-max))
'left 'nosqueeze))))))))
(const :tag "Ask" ask))
:group 'gnus-agent)
+(defcustom gnus-agent-go-online 'ask
+ "Indicate if offline servers go online when you plug in.
+If this is `ask' the hook will query the user."
+ :version "21.1"
+ :type '(choice (const :tag "Always" t)
+ (const :tag "Never" nil)
+ (const :tag "Ask" ask))
+ :group 'gnus-agent)
+
;;; Internal variables
(defvar gnus-agent-history-buffers nil)
(if plugged
(progn
(setq gnus-plugged plugged)
- (gnus-agent-possibly-synchronize-flags)
(gnus-run-hooks 'gnus-agent-plugged-hook)
(setcar (cdr gnus-agent-mode-status)
(gnus-agent-make-mode-line-string " Plugged"
'mouse-2
- 'gnus-agent-toggle-plugged)))
+ 'gnus-agent-toggle-plugged))
+ (gnus-agent-go-online gnus-agent-go-online)
+ (gnus-agent-possibly-synchronize-flags))
(gnus-agent-close-connections)
(setq gnus-plugged plugged)
(gnus-run-hooks 'gnus-agent-unplugged-hook)
(defsubst gnus-agent-copy-nov-line (article)
(let (b e)
(set-buffer gnus-agent-overview-buffer)
- (setq b (point))
- (if (eq article (read (current-buffer)))
- (setq e (progn (forward-line 1) (point)))
- (progn
- (beginning-of-line)
- (setq e b)))
- (set-buffer nntp-server-buffer)
- (insert-buffer-substring gnus-agent-overview-buffer b e)))
+ (unless (eobp)
+ (setq b (point))
+ (if (eq article (read (current-buffer)))
+ (setq e (progn (forward-line 1) (point)))
+ (progn
+ (beginning-of-line)
+ (setq e b)))
+ (set-buffer nntp-server-buffer)
+ (insert-buffer-substring gnus-agent-overview-buffer b e))))
(defun gnus-agent-braid-nov (group articles file)
(set-buffer gnus-agent-overview-buffer)
"Save the article-state alist for GROUP."
(let ((file-name-coding-system nnmail-pathname-coding-system)
(pathname-coding-system nnmail-pathname-coding-system)
- print-level print-length)
+ print-level print-length item)
+ (dolist (art articles)
+ (if (setq item (memq art gnus-agent-article-alist))
+ (setcdr item state)
+ (push (cons art state) gnus-agent-article-alist)))
+ (setq gnus-agent-article-alist
+ (sort gnus-agent-article-alist 'car-less-than-car))
(with-temp-file (if dir
(expand-file-name ".agentview" dir)
(gnus-agent-article-name ".agentview" group))
- (princ (setq gnus-agent-article-alist
- (nconc gnus-agent-article-alist
- (mapcar (lambda (article) (cons article state))
- articles)))
- (current-buffer))
+ (princ gnus-agent-article-alist (current-buffer))
(insert "\n"))))
(defun gnus-agent-article-name (article group)
(gnus-range-add
(nth 2 info)
(cons 1 (- (caar gnus-agent-article-alist) 1)))))
- ;; Maybe everything has been expired from `gnus-article-alist'
- ;; and so the above marking as read could not be conducted,
- ;; or there are expired article within the range of the alist.
+ ;; Maybe everything has been expired from
+ ;; `gnus-article-alist' and so the above marking as
+ ;; read could not be conducted, or there are
+ ;; expired article within the range of the alist.
(when (and info
expired
(or (not (caar gnus-agent-article-alist))
(file (gnus-agent-article-name ".overview" group))
cached-articles uncached-articles)
(gnus-make-directory (nnheader-translate-file-chars
- (file-name-directory file) t))
+ (file-name-directory file) t))
(when (file-exists-p file)
(with-current-buffer gnus-agent-overview-buffer
(erase-buffer)
- (nnheader-insert-file-contents file)
- (goto-char (point-min))
+ (let ((nnheader-file-coding-system
+ gnus-agent-file-coding-system))
+ (nnheader-insert-file-contents file))
+ (goto-char (point-min))
(while (not (eobp))
(when (looking-at "[0-9]")
(push (read (current-buffer)) cached-articles))
(forward-line 1))
(setq cached-articles (sort cached-articles '<))))
- (when (setq uncached-articles
+ (when (setq uncached-articles
(gnus-set-difference articles cached-articles))
+ (set-buffer nntp-server-buffer)
+ (erase-buffer)
(let (gnus-agent-cache)
- (unless (eq 'nov
- (gnus-retrieve-headers
+ (unless (eq 'nov
+ (gnus-retrieve-headers
uncached-articles group fetch-old))
(nnvirtual-convert-headers)))
+ (set-buffer gnus-agent-overview-buffer)
+ (erase-buffer)
(set-buffer nntp-server-buffer)
- (with-current-buffer gnus-agent-overview-buffer
- (erase-buffer))
(copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max))
(when (and uncached-articles (file-exists-p file))
(gnus-agent-braid-nov group uncached-articles file))
(write-region-as-coding-system gnus-agent-file-coding-system
(point-min) (point-max)
file nil 'silent)
+ (gnus-agent-load-alist group)
(gnus-agent-save-alist group uncached-articles nil)
(gnus-agent-open-history)
(setq gnus-agent-current-history (gnus-agent-history-buffer))
(time-to-days (current-time)))
(gnus-agent-save-history)))
(set-buffer nntp-server-buffer)
+ (erase-buffer)
(insert-buffer-substring gnus-agent-overview-buffer)
(if (and fetch-old
(not (numberp fetch-old)))
(insert-file-contents-as-coding-system gnus-cache-coding-system file)
t)))
+(defun gnus-agent-regenerate-group (group &optional clean)
+ "Regenerate GROUP."
+ (let ((dir (concat (gnus-agent-directory)
+ (gnus-agent-group-path group) "/"))
+ (file (gnus-agent-article-name ".overview" group))
+ n point arts alist header new-alist changed)
+ (when (file-exists-p dir)
+ (setq arts
+ (sort (mapcar (lambda (name) (string-to-int name))
+ (directory-files dir nil "^[0-9]+$" t))
+ '<)))
+ (gnus-make-directory (nnheader-translate-file-chars
+ (file-name-directory file) t))
+ (mm-with-unibyte-buffer
+ (if (file-exists-p file)
+ (let ((nnheader-file-coding-system gnus-agent-file-coding-system))
+ (nnheader-insert-file-contents file)))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (while (not (or (eobp) (looking-at "[0-9]")))
+ (setq point (point))
+ (forward-line 1)
+ (delete-region point (point)))
+ (unless (eobp)
+ (setq n (read (current-buffer)))
+ (when (and arts (> n (car arts)))
+ (beginning-of-line)
+ (while (and arts (> n (car arts)))
+ (message "Regenerating NOV %s %d..." group (car arts))
+ (mm-with-unibyte-buffer
+ (nnheader-insert-file-contents
+ (concat dir (number-to-string (car arts))))
+ (goto-char (point-min))
+ (if (search-forward "\n\n" nil t)
+ (delete-region (point) (point-max))
+ (goto-char (point-max)))
+ (setq header (nnheader-parse-head t)))
+ (mail-header-set-number header (car arts))
+ (nnheader-insert-nov header)
+ (setq changed t)
+ (push (cons (car arts) t) alist)
+ (pop arts)))
+ (if (and arts (= n (car arts)))
+ (progn
+ (push (cons n t) alist)
+ (pop arts))
+ (push (cons n nil) alist))
+ (forward-line 1)))
+ (if changed
+ (write-region-as-coding-system gnus-agent-file-coding-system
+ (point-min) (point-max)
+ file nil 'silent)))
+ (setq gnus-agent-article-alist nil)
+ (unless clean
+ (gnus-agent-load-alist group))
+ (setq alist (sort alist 'car-less-than-car))
+ (setq gnus-agent-article-alist (sort gnus-agent-article-alist
+ 'car-less-than-car))
+ (while (and alist gnus-agent-article-alist)
+ (cond
+ ((< (caar alist) (caar gnus-agent-article-alist))
+ (push (pop alist) new-alist))
+ ((> (caar alist) (caar gnus-agent-article-alist))
+ (push (list (car (pop gnus-agent-article-alist))) new-alist))
+ (t
+ (pop gnus-agent-article-alist)
+ (while (and gnus-agent-article-alist
+ (= (caar alist) (caar gnus-agent-article-alist)))
+ (pop gnus-agent-article-alist))
+ (push (pop alist) new-alist))))
+ (while alist
+ (push (pop alist) new-alist))
+ (while gnus-agent-article-alist
+ (push (list (car (pop gnus-agent-article-alist))) new-alist))
+ (setq gnus-agent-article-alist (nreverse new-alist))
+ (gnus-agent-save-alist group)))
+
+(defun gnus-agent-regenerate-history (group article)
+ (let ((file (concat (gnus-agent-directory)
+ (gnus-agent-group-path group) "/"
+ (number-to-string article))) id)
+ (mm-with-unibyte-buffer
+ (nnheader-insert-file-contents file)
+ (message-narrow-to-head)
+ (goto-char (point-min))
+ (if (not (re-search-forward "^Message-ID: *<\\([^>\n]+\\)>" nil t))
+ (setq id "No-Message-ID-in-article")
+ (setq id (buffer-substring (match-beginning 1) (match-end 1))))
+ (gnus-agent-enter-history
+ id (list (cons group article))
+ (time-to-days (nth 5 (file-attributes file)))))))
+
+;;;###autoload
+(defun gnus-agent-regenerate (&optional clean)
+ "Regenerate all agent covered files.
+If CLEAN, don't read existing active and agentview files."
+ (interactive "P")
+ (message "Regenerating Gnus agent files...")
+ (dolist (gnus-command-method gnus-agent-covered-methods)
+ (let ((active-file (gnus-agent-lib-file "active"))
+ history-hashtb active-hashtb active-changed
+ history-changed point)
+ (gnus-make-directory (file-name-directory active-file))
+ (if clean
+ (setq active-hashtb (gnus-make-hashtable 1000))
+ (mm-with-unibyte-buffer
+ (if (file-exists-p active-file)
+ (let ((nnheader-file-coding-system
+ gnus-agent-file-coding-system))
+ (nnheader-insert-file-contents active-file))
+ (setq active-changed t))
+ (gnus-active-to-gnus-format
+ nil (setq active-hashtb
+ (gnus-make-hashtable
+ (count-lines (point-min) (point-max)))))))
+ (gnus-agent-open-history)
+ (setq history-hashtb (gnus-make-hashtable 1000))
+ (with-current-buffer
+ (setq gnus-agent-current-history (gnus-agent-history-buffer))
+ (goto-char (point-min))
+ (forward-line 1)
+ (while (not (eobp))
+ (if (looking-at
+ "\\([^\t\n]+\\)\t[0-9]+\t\\([^ \n]+\\) \\([0-9]+\\)")
+ (progn
+ (unless (string= (match-string 1)
+ "last-header-fetched-for-session")
+ (gnus-sethash (match-string 2)
+ (cons (string-to-number (match-string 3))
+ (gnus-gethash-safe (match-string 2)
+ history-hashtb))
+ history-hashtb))
+ (forward-line 1))
+ (setq point (point))
+ (forward-line 1)
+ (delete-region point (point))
+ (setq history-changed t))))
+ (dolist (group (gnus-groups-from-server gnus-command-method))
+ (gnus-agent-regenerate-group group clean)
+ (let ((min (or (caar gnus-agent-article-alist) 1))
+ (max (or (caar (last gnus-agent-article-alist)) 0))
+ (active (gnus-gethash-safe (gnus-group-real-name group)
+ active-hashtb)))
+ (if (not active)
+ (progn
+ (setq active (cons min max)
+ active-changed t)
+ (gnus-sethash group active active-hashtb))
+ (when (> (car active) min)
+ (setcar active min)
+ (setq active-changed t))
+ (when (< (cdr active) max)
+ (setcdr active max)
+ (setq active-changed t))))
+ (let ((arts (sort (gnus-gethash-safe group history-hashtb) '<))
+ n)
+ (gnus-sethash group arts history-hashtb)
+ (while (and arts gnus-agent-article-alist)
+ (cond
+ ((> (car arts) (caar gnus-agent-article-alist))
+ (when (cdar gnus-agent-article-alist)
+ (gnus-agent-regenerate-history
+ group (caar gnus-agent-article-alist))
+ (setq history-changed t))
+ (setq n (car (pop gnus-agent-article-alist)))
+ (while (and gnus-agent-article-alist
+ (= n (caar gnus-agent-article-alist)))
+ (pop gnus-agent-article-alist)))
+ ((< (car arts) (caar gnus-agent-article-alist))
+ (setq n (pop arts))
+ (while (and arts (= n (car arts)))
+ (pop arts)))
+ (t
+ (setq n (car (pop gnus-agent-article-alist)))
+ (while (and gnus-agent-article-alist
+ (= n (caar gnus-agent-article-alist)))
+ (pop gnus-agent-article-alist))
+ (setq n (pop arts))
+ (while (and arts (= n (car arts)))
+ (pop arts)))))
+ (while gnus-agent-article-alist
+ (when (cdar gnus-agent-article-alist)
+ (gnus-agent-regenerate-history
+ group (caar gnus-agent-article-alist))
+ (setq history-changed t))
+ (pop gnus-agent-article-alist))))
+ (when history-changed
+ (message "Regenerate the history file of %s:%s"
+ (car gnus-command-method)
+ (cadr gnus-command-method))
+ (gnus-agent-save-history))
+ (gnus-agent-close-history)
+ (when active-changed
+ (message "Regenerate %s" active-file)
+ (let ((nnmail-active-file-coding-system gnus-agent-file-coding-system))
+ (gnus-write-active-file active-file active-hashtb)))))
+ (message "Regenerating Gnus agent files...done"))
+
+(defun gnus-agent-go-online (&optional force)
+ "Switch servers into online status."
+ (interactive (list t))
+ (dolist (server gnus-opened-servers)
+ (when (eq (nth 1 server) 'offline)
+ (if (if (eq force 'ask)
+ (gnus-y-or-n-p
+ (format "Switch %s:%s into online status? "
+ (caar server) (cadar server)))
+ force)
+ (setcar (nthcdr 1 server) 'close)))))
+
(provide 'gnus-agent)
;;; gnus-agent.el ends here
:type '(choice (item :tag "None" :value nil)
string))
+(defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces")
+ "*Defines the location of the faces database.
+For information on obtaining this database of pretty pictures, please
+see http://www.cs.indiana.edu/picons/ftp/index.html"
+ :type 'directory
+ :group 'gnus-picon)
+
+(defun gnus-picons-installed-p ()
+ "Say whether picons are installed on your machine."
+ (let ((installed nil))
+ (dolist (database gnus-picon-databases)
+ (when (file-exists-p database)
+ (setq installed t)))
+ installed))
+
(defcustom gnus-article-mime-part-function nil
"Function called with a MIME handle as the argument.
This is meant for people who want to do something automatic based
(put 'gnus-treat-display-smileys 'highlight t)
(defcustom gnus-treat-from-picon
- (if (gnus-image-type-available-p 'xpm)
+ (if (and (gnus-image-type-available-p 'xpm)
+ (gnus-picons-installed-p))
'head nil)
"Display picons in the From header.
Valid values are nil, t, `head', `last', an integer or a predicate.
(put 'gnus-treat-from-picon 'highlight t)
(defcustom gnus-treat-mail-picon
- (if (gnus-image-type-available-p 'xpm)
+ (if (and (gnus-image-type-available-p 'xpm)
+ (gnus-picons-installed-p))
'head nil)
"Display picons in To and Cc headers.
Valid values are nil, t, `head', `last', an integer or a predicate.
(put 'gnus-treat-mail-picon 'highlight t)
(defcustom gnus-treat-newsgroups-picon
- (if (gnus-image-type-available-p 'xpm)
+ (if (and (gnus-image-type-available-p 'xpm)
+ (gnus-picons-installed-p))
'head nil)
"Display picons in the Newsgroups and Followup-To headers.
Valid values are nil, t, `head', `last', an integer or a predicate.
(when xpm
(setq image (gnus-create-image xpm 'xpm t))
(gnus-article-goto-header "from")
+ (when (bobp)
+ (insert "From: [no `from' set]\n")
+ (forward-char -17))
(gnus-add-wash-type 'xface)
(gnus-add-image 'xface image)
(gnus-put-image image)))
(interactive (list t))
(article-date-ut 'iso8601 highlight))
-(defun article-show-all ()
- "Show all hidden text in the article buffer."
- (interactive)
- (save-excursion
- (widen)
- (let ((buffer-read-only nil))
- (gnus-article-unhide-text (point-min) (point-max))
- (gnus-remove-text-with-property 'gnus-prev)
- (gnus-remove-text-with-property 'gnus-next))))
+;; (defun article-show-all ()
+;; "Show all hidden text in the article buffer."
+;; (interactive)
+;; (save-excursion
+;; (widen)
+;; (let ((buffer-read-only nil))
+;; (gnus-article-unhide-text (point-min) (point-max))
+;; (gnus-remove-text-with-property 'gnus-prev)
+;; (gnus-remove-text-with-property 'gnus-next))))
(defun article-show-all-headers ()
"Show all hidden headers in the article buffer."
article-treat-dumbquotes
article-normalize-headers
(article-show-all-headers . gnus-article-show-all-headers)
- (article-show-all . gnus-article-show-all))))
+;; (article-show-all . gnus-article-show-all)
+ )))
\f
;;;
;;; Gnus article mode
The text in the region will be yanked. If the region isn't active,
the entire article will be yanked."
(interactive "P")
- (let ((article (cdr gnus-article-current)))
- (if (not mark-active)
+ (let ((article (cdr gnus-article-current)) cont)
+ (if (not (mark))
(gnus-summary-reply (list (list article)) wide)
+ (setq cont (buffer-substring (point) (mark)))
;; Deactivate active regions.
(when (and (boundp 'transient-mark-mode)
transient-mark-mode)
(setq mark-active nil))
(gnus-summary-reply
- (list (list article (buffer-substring (point) (mark)))) wide))))
+ (list (list article cont)) wide))))
(defun gnus-article-followup-with-original ()
"Compose a followup to the current article.
The text in the region will be yanked. If the region isn't active,
the entire article will be yanked."
(interactive)
- (let ((article (cdr gnus-article-current)))
- (if (not mark-active)
+ (let ((article (cdr gnus-article-current))
+ cont)
+ (if (not (gnus-region-active-p))
(gnus-summary-followup (list (list article)))
+ (setq cont (buffer-substring (point) (mark)))
;; Deactivate active regions.
(when (and (boundp 'transient-mark-mode)
transient-mark-mode)
(setq mark-active nil))
(gnus-summary-followup
- (list (list article (buffer-substring (point) (mark))))))))
+ (list (list article cont))))))
(defun gnus-article-hide (&optional arg force)
"Hide all the gruft in the current article.
(article-narrow-to-head)
(gnus-article-goto-header "from")
(when (bobp)
- (insert "From: \n")
- (forward-char -2))
+ (insert "From: [no `from' set]\n")
+ (forward-char -17))
(gnus-add-image
'xface
(gnus-put-image
;;; gnus-logic.el --- advanced scoring code for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
(defun gnus-score-advanced (rule &optional trace)
"Apply advanced scoring RULE to all the articles in the current group."
- (let ((headers gnus-newsgroup-headers)
- gnus-advanced-headers score)
- (while (setq gnus-advanced-headers (pop headers))
- (when (gnus-advanced-score-rule (car rule))
- ;; This rule was successful, so we add the score to
- ;; this article.
+ (let (new-score score multiple)
+ (dolist (gnus-advanced-headers gnus-newsgroup-headers)
+ (when (setq multiple (gnus-advanced-score-rule (car rule)))
+ (setq new-score (or (nth 1 rule)
+ gnus-score-interactive-default-score))
+ (when (numberp multiple)
+ (setq new-score (* multiple new-score)))
+ ;; This rule was successful, so we add the score to this
+ ;; article.
(if (setq score (assq (mail-header-number gnus-advanced-headers)
gnus-newsgroup-scored))
(setcdr score
- (+ (cdr score)
- (or (nth 1 rule)
- gnus-score-interactive-default-score)))
+ (+ (cdr score) new-score))
(push (cons (mail-header-number gnus-advanced-headers)
- (or (nth 1 rule)
- gnus-score-interactive-default-score))
+ new-score)
gnus-newsgroup-scored)
(when trace
(push (cons "A file" rule)
;; 1- type redirection.
(string-to-number
(substring (symbol-name type)
- (match-beginning 0) (match-end 0)))
+ (match-beginning 1) (match-end 1)))
;; ^^^ type redirection.
(length (symbol-name type))))))
(when gnus-advanced-headers
(error "Unknown advanced score type: %s" rule)))))
(defun gnus-advanced-score-article (rule)
- ;; `rule' is a semi-normal score rule, so we find out
- ;; what function that's supposed to do the actual
- ;; processing.
+ ;; `rule' is a semi-normal score rule, so we find out what function
+ ;; that's supposed to do the actual processing.
(let* ((header (car rule))
(func (assoc (downcase header) gnus-advanced-index)))
(if (not func)
'gnus-request-body)
(t 'gnus-request-article)))
ofunc article)
- ;; Not all backends support partial fetching. In that case,
- ;; we just fetch the entire article.
+ ;; Not all backends support partial fetching. In that case, we
+ ;; just fetch the entire article.
(unless (gnus-check-backend-function
(intern (concat "request-" header))
gnus-newsgroup-name)
(when (funcall request-func article gnus-newsgroup-name)
(goto-char (point-min))
;; If just parts of the article is to be searched and the
- ;; backend didn't support partial fetching, we just narrow
- ;; to the relevant parts.
+ ;; backend didn't support partial fetching, we just narrow to
+ ;; the relevant parts.
(when ofunc
(if (eq ofunc 'gnus-request-head)
(narrow-to-region
(interactive
(list (and current-prefix-arg
(gnus-summary-work-articles 1))))
- ;; Stripping headers should be specified with mail-yank-ignored-headers.
- (when yank
- (gnus-summary-goto-subject
- (if (listp (car yank))
- (caar yank)
- (car yank))))
- (let ((gnus-article-reply (or yank (gnus-summary-article-number)))
- (headers ""))
+ (let* ((article
+ (if (listp (car yank))
+ (caar yank)
+ (car yank)))
+ (gnus-article-reply (or article (gnus-summary-article-number)))
+ (headers ""))
+ ;; Stripping headers should be specified with mail-yank-ignored-headers.
+ (when yank
+ (gnus-summary-goto-subject article))
(gnus-setup-message (if yank 'reply-yank 'reply)
(if (not very-wide)
(gnus-summary-select-article)
;;; User variables:
-(defgroup picon nil
- "Show pictures of people, domains, and newsgroups."
- :group 'gnus-visual)
-
-(defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces")
- "*Defines the location of the faces database.
-For information on obtaining this database of pretty pictures, please
-see http://www.cs.indiana.edu/picons/ftp/index.html"
- :type 'directory
- :group 'picon)
-
(defcustom gnus-picon-news-directories '("news")
"*List of directories to search for newsgroups faces."
:type '(repeat string)
- :group 'picon)
+ :group 'gnus-picon)
(defcustom gnus-picon-user-directories '("users" "usenix" "local" "misc")
"*List of directories to search for user faces."
:type '(repeat string)
- :group 'picon)
+ :group 'gnus-picon)
(defcustom gnus-picon-domain-directories '("domains")
"*List of directories to search for domain faces.
Some people may want to add \"unknown\" to this list."
:type '(repeat string)
- :group 'picon)
+ :group 'gnus-picon)
(defcustom gnus-picon-file-types
(let ((types (list "xbm")))
types)
"*List of suffixes on picon file names to try."
:type '(repeat string)
- :group 'picon)
+ :group 'gnus-picon)
(defface gnus-picon-xbm-face '((t (:foreground "black" :background "white")))
"Face to show xbm picon in."
- :group 'picon)
+ :group 'gnus-picon)
(defface gnus-picon-face '((t (:foreground "black" :background "white")))
"Face to show picon in."
- :group 'picon)
+ :group 'gnus-picon)
;;; Internal variables:
`(let* ((val (eval ,el))
(need (- ,pad (,(if gnus-use-correct-string-widths
'gnus-correct-length
- 'length) ,el))))
+ 'length) val))))
(if (> need 0)
(concat ,(when side '(make-string need ?\ ))
- ,el
+ val
,(when (not side) '(make-string need ?\ )))
- ,el)))))
+ val)))))
(defun gnus-parse-format (format spec-alist &optional insert)
;; This function parses the FORMAT string with the help of the
(defun gnus-summary-setup-buffer (group)
"Initialize summary buffer."
- (let ((buffer (gnus-summary-buffer-name group)))
+ (let ((buffer (gnus-summary-buffer-name group))
+ (dead-name (concat "*Dead Summary "
+ (gnus-group-decoded-name group) "*")))
+ ;; If a dead summary buffer exists, we kill it.
+ (when (gnus-buffer-live-p dead-name)
+ (gnus-kill-buffer dead-name))
(if (get-buffer buffer)
(progn
(set-buffer buffer)
(progn
(gnus-configure-windows 'summary)
(let ((art (gnus-summary-article-number)))
- (unless (memq art gnus-newsgroup-undownloaded)
+ (unless (or (memq art gnus-newsgroup-undownloaded)
+ (memq art gnus-newsgroup-downloadable))
(gnus-summary-goto-article art))))
;; Don't select any articles.
(gnus-summary-position-point)
(set-buffer buffer)
(gnus-kill-buffer gnus-article-buffer)
(gnus-kill-buffer gnus-original-article-buffer)))
- (cond (gnus-kill-summary-on-exit
- (when (and gnus-use-trees
- (gnus-buffer-exists-p buffer))
- (save-excursion
- (set-buffer buffer)
- (gnus-tree-close gnus-newsgroup-name)))
- (gnus-kill-buffer buffer))
- ((gnus-buffer-exists-p buffer)
- (save-excursion
- (set-buffer buffer)
- (gnus-deaden-summary))))))
+ (cond
+ ;; Kill the buffer.
+ (gnus-kill-summary-on-exit
+ (when (and gnus-use-trees
+ (gnus-buffer-exists-p buffer))
+ (save-excursion
+ (set-buffer buffer)
+ (gnus-tree-close gnus-newsgroup-name)))
+ (gnus-kill-buffer buffer))
+ ;; Deaden the buffer.
+ ((gnus-buffer-exists-p buffer)
+ (save-excursion
+ (set-buffer buffer)
+ (gnus-deaden-summary))))))
(defun gnus-summary-wake-up-the-dead (&rest args)
"Wake up the dead summary buffer."
;; The requested article is different from the current article.
(progn
(gnus-summary-display-article article all-headers)
- (when (or all-headers gnus-show-all-headers)
- (gnus-article-show-all-headers))
+;;; Hidden headers are not hidden text any more.
+;; (when (or all-headers gnus-show-all-headers)
+;; (gnus-article-show-all-headers))
(gnus-article-set-window-start
(cdr (assq article gnus-newsgroup-bookmarks)))
article)
- (when (or all-headers gnus-show-all-headers)
- (gnus-article-show-all-headers))
+;; (when (or all-headers gnus-show-all-headers)
+;; (gnus-article-show-all-headers))
'old))))
(defun gnus-summary-force-verify-and-decrypt ()
;; `gnus-read-move-group-name' an opportunity to suggest an
;; appropriate default.
(unless (gnus-buffer-live-p gnus-original-article-buffer)
- (gnus-summary-select-article nil nil nil (car articles)))
+ (let ((gnus-display-mime-function nil)
+ (gnus-article-prepare-hook nil))
+ (gnus-summary-select-article nil nil nil (car articles))))
;; Read the newsgroup name.
(when (and (not to-newsgroup)
(not select-method))
:link '(custom-manual "(gnus)Summary Maneuvering")
:group 'gnus-summary)
+(defgroup gnus-picon nil
+ "Show pictures of people, domains, and newsgroups."
+ :group 'gnus-visual)
+
(defgroup gnus-summary-mail nil
"Mail group commands."
:link '(custom-manual "(gnus)Mail Group Commands")
gnus-article-hide-pem gnus-article-hide-signature
gnus-article-strip-leading-blank-lines gnus-article-date-local
gnus-article-date-original gnus-article-date-lapsed
- gnus-article-show-all-headers gnus-article-show-all
+ gnus-article-show-all-headers
+ ;; gnus-article-show-all
gnus-article-edit-mode gnus-article-edit-article
gnus-article-edit-done article-decode-encoded-words
gnus-start-date-timer gnus-stop-date-timer
"Get hash value of STRING in HASHTABLE."
`(symbol-value (intern-soft ,string ,hashtable)))
+(defmacro gnus-gethash-safe (string hashtable)
+ "Get hash value of STRING in HASHTABLE.
+Return nil if not defined."
+ `(let ((sym (intern-soft ,string ,hashtable)))
+ (and (boundp sym) (symbol-value sym))))
+
(defmacro gnus-sethash (string value hashtable)
"Set hash value. Arguments are STRING, VALUE, and HASHTABLE."
`(set (intern ,string ,hashtable) ,value))
If BUFFER is nil, the current buffer is used."
(with-current-buffer (or buffer (current-buffer))
(when (imap-opened)
- (imap-send-command-wait "LOGOUT"))
+ (condition-case nil
+ (imap-send-command-wait "LOGOUT")
+ (quit nil)))
(when (and imap-process
(memq (process-status imap-process) '(open run)))
(delete-process imap-process))
:type 'sexp)
(defcustom message-ignored-news-headers
- "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:"
+ "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
"*Regexp of headers to be removed unconditionally before posting."
:group 'message-news
:group 'message-headers
:type 'regexp)
(defcustom message-ignored-mail-headers
- "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:"
+ "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
"*Regexp of headers to be removed unconditionally before mailing."
:group 'message-mail
:group 'message-headers
(if not-break
(setq point nil)
(if bolp
- (insert "\n")
- (insert "\n\n"))
+ (newline)
+ (newline)
+ (newline))
(setq point (point))
- (insert "\n\n")
+ ;; (newline 2) doesn't mark both newline's as hard, so call
+ ;; newline twice. -jas
+ (newline)
+ (newline)
(delete-region (point) (re-search-forward "[ \t]*"))
(when (and quoted (not bolp))
(insert quoted leading-space)))
(save-excursion
(set-buffer message-encoding-buffer)
(erase-buffer)
- ;; ;; Avoid copying text props.
+ ;; ;; Avoid copying text props (except hard newlines).
;; T-gnus change: copy all text props from the editing buffer
;; into the encoding buffer.
(insert-buffer message-edit-buffer)
(save-excursion
(set-buffer tembuf)
(erase-buffer)
+ ;; ;; Avoid copying text props (except hard newlines).
+ ;; T-gnus change: copy all text props from the editing buffer
+ ;; into the encoding buffer.
(insert-buffer message-encoding-buffer)
;; Remove some headers.
(save-restriction
;; ;; We (re)generate the Lines header.
;; (when (memq 'Lines message-required-mail-headers)
;; (message-generate-headers '(Lines)))
- ;; Remove some headers.
(message-remove-header message-ignored-mail-headers t))
(goto-char (point-max))
;; require one newline at the end.
;;; mm-view.el --- functions for viewing MIME objects
-;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; This file is part of GNU Emacs.
(buffer-disable-undo)
(mm-insert-part handle)
(funcall mode)
+ (require 'font-lock)
(let ((font-lock-verbose nil))
;; I find font-lock a bit too verbose.
(font-lock-fontify-buffer))
(autoload 'gnus-setup-posting-charset "gnus-msg")
(autoload 'gnus-add-minor-mode "gnus-ems")
(autoload 'message-fetch-field "message")
+ (autoload 'fill-flowed-encode "flow-fill")
(autoload 'message-posting-charset "message"))
(defcustom mml-content-type-parameters
(setq contents (append (list (cons 'tag-location orig-point)) contents))
(cons (intern name) (nreverse contents))))
+(defun mml-buffer-substring-no-properties-except-hard-newlines (start end)
+ (let ((str (buffer-substring-no-properties start end))
+ (bufstart start) tmp)
+ (while (setq tmp (text-property-any start end 'hard 't))
+ (set-text-properties (- tmp bufstart) (- tmp bufstart -1)
+ '(hard t) str)
+ (setq start (1+ tmp)))
+ str))
+
(defun mml-read-part (&optional mml)
"Return the buffer up till the next part, multipart or closing part or multipart.
If MML is non-nil, return the buffer up till the correspondent mml tag."
(if (re-search-forward "<#\\(/\\)?mml." nil t)
(setq count (+ count (if (match-beginning 1) -1 1)))
(goto-char (point-max))))
- (buffer-substring-no-properties beg (if (> count 0)
- (point)
- (match-beginning 0))))
+ (mml-buffer-substring-no-properties-except-hard-newlines
+ beg (if (> count 0)
+ (point)
+ (match-beginning 0))))
(if (re-search-forward
"<#\\(/\\)?\\(multipart\\|part\\|external\\|mml\\)." nil t)
(prog1
- (buffer-substring-no-properties beg (match-beginning 0))
+ (mml-buffer-substring-no-properties-except-hard-newlines
+ beg (match-beginning 0))
(if (or (not (match-beginning 1))
(equal (match-string 2) "multipart"))
(goto-char (match-beginning 0))
(when (looking-at "[ \t]*\n")
(forward-line 1))))
- (buffer-substring-no-properties beg (goto-char (point-max)))))))
+ (mml-buffer-substring-no-properties-except-hard-newlines
+ beg (goto-char (point-max)))))))
(defvar mml-boundary nil)
(defvar mml-base-boundary "-=-=")
(cond
((or (eq (car cont) 'part) (eq (car cont) 'mml))
(let ((raw (cdr (assq 'raw cont)))
- coded encoding charset filename type)
+ coded encoding charset filename type flowed)
(setq type (or (cdr (assq 'type cont)) "text/plain"))
(if (and (not raw)
(member (car (split-string type "/")) '("text" "message")))
(setq charset (mm-encode-body charset))
(setq encoding (mm-body-encoding
charset (cdr (assq 'encoding cont))))))
+ ;; Only perform format=flowed filling on text/plain
+ ;; parts where there either isn't a format parameter
+ ;; in the mml tag or it says "flowed" and there
+ ;; actually are hard newlines in the text.
+ (let (use-hard-newlines)
+ (when (and (string= type "text/plain")
+ (or (null (assq 'format cont))
+ (string= (assq 'format cont) "flowed"))
+ (setq use-hard-newlines
+ (text-property-any
+ (point-min) (point-max) 'hard 't)))
+ (fill-flowed-encode)
+ ;; Indicate that `mml-insert-mime-headers' should
+ ;; insert a "; format=flowed" string unless the
+ ;; user has already specified it.
+ (setq flowed (null (assq 'format cont)))))
(setq coded (buffer-string)))
- (mml-insert-mime-headers cont type charset encoding)
+ (mml-insert-mime-headers cont type charset encoding flowed)
(insert "\n")
(insert coded))
(mm-with-unibyte-buffer
(insert (cdr (assq 'contents cont)))))
(setq encoding (mm-encode-buffer type)
coded (mm-string-as-multibyte (buffer-string))))
- (mml-insert-mime-headers cont type charset encoding)
+ (mml-insert-mime-headers cont type charset encoding nil)
(insert "\n")
(mm-with-unibyte-current-buffer
(insert coded)))))
"")
mml-base-boundary))
-(defun mml-insert-mime-headers (cont type charset encoding)
+(defun mml-insert-mime-headers (cont type charset encoding flowed)
(let (parameters disposition description)
(setq parameters
(mml-parameter-string
cont mml-content-type-parameters))
(when (or charset
parameters
+ flowed
(not (equal type mml-generate-default-type)))
(when (consp charset)
(error
(when charset
(insert "; " (mail-header-encode-parameter
"charset" (symbol-name charset))))
+ (when flowed
+ (insert "; format=flowed"))
(when parameters
(mml-insert-parameter-string
cont mml-content-type-parameters))
"Detect MIME charset of the text in the region between START and END."
(coding-system-to-mime-charset
(nnheader-detect-coding-region start end)))
- (defalias 'mm-detect-mime-charset-region 'nnheader-detect-mime-charset-region))
+ (defalias 'mm-detect-mime-charset-region
+ 'nnheader-detect-mime-charset-region)
+
+ (defmacro nnheader-with-unibyte-buffer (&rest forms)
+ "Create a temporary buffer, and evaluate FORMS there like `progn'.
+Use unibyte mode for this."
+ `(let (default-enable-multibyte-characters mc-flag)
+ (with-temp-buffer ,@forms)))
+ (put 'nnheader-with-unibyte-buffer 'lisp-indent-function 0)
+ (put 'nnheader-with-unibyte-buffer 'edebug-form-spec '(body))
+ (put 'mm-with-unibyte-buffer 'lisp-indent-function 0)
+ (put 'mm-with-unibyte-buffer 'edebug-form-spec '(body))
+ (defalias 'mm-with-unibyte-buffer 'nnheader-with-unibyte-buffer))
;; mail-parse stuff.
(unless (featurep 'mail-parse)
:group 'nnimap
:type 'sexp)
+;; Performance / bug workaround variables
+
(defcustom nnimap-close-asynchronous nil
"Close mailboxes asynchronously in `nnimap-close-group'.
This means that errors cought by nnimap when closing the mailbox will
:type 'boolean
:group 'nnimap)
+(defcustom nnimap-dont-close t
+ "Never close mailboxes.
+This increases the speed of closing mailboxes (quiting group) but may
+decrease the speed of selecting another mailbox later. Re-selecting
+the same mailbox will be faster though."
+ :type 'boolean
+ :group 'nnimap)
+
+(defvoo nnimap-need-unselect-to-notice-new-mail nil
+ "Unselect mailboxes before looking for new mail in them.
+Some servers seem to need this under some circumstances.")
+
;; Authorization / Privacy variables
(defvoo nnimap-auth-method nil
(defun nnimap-before-find-minmax-bugworkaround ()
"Function called before iterating through mailboxes with
`nnimap-find-minmax-uid'."
- ;; XXX this is for UoW imapd problem, it doesn't notice new mail in
- ;; currently selected mailbox without a re-select/examine.
- (or (null (imap-current-mailbox nnimap-server-buffer))
- (imap-mailbox-unselect nnimap-server-buffer)))
+ (when nnimap-need-unselect-to-notice-new-mail
+ ;; XXX this is for UoW imapd problem, it doesn't notice new mail in
+ ;; currently selected mailbox without a re-select/examine.
+ (or (null (imap-current-mailbox nnimap-server-buffer))
+ (imap-mailbox-unselect nnimap-server-buffer))))
(defun nnimap-find-minmax-uid (group &optional examine)
"Find lowest and highest active article nummber in GROUP.
If EXAMINE is non-nil the group is selected read-only."
(with-current-buffer nnimap-server-buffer
- (when (imap-mailbox-select group examine)
+ (when (or (string= group (imap-current-mailbox))
+ (imap-mailbox-select group examine))
(let (minuid maxuid)
(when (> (imap-mailbox-get 'exists) 0)
(imap-fetch "1,*" "UID" nil 'nouidfetch)
(when (and (imap-opened)
(nnimap-possibly-change-group group server))
(case nnimap-expunge-on-close
- (always (imap-mailbox-expunge nnimap-close-asynchronous)
- (imap-mailbox-close nnimap-close-asynchronous))
+ (always (unless nnimap-dont-close
+ (imap-mailbox-expunge nnimap-close-asynchronous)
+ (imap-mailbox-close nnimap-close-asynchronous)))
(ask (if (and (imap-search "DELETED")
- (gnus-y-or-n-p (format
- "Expunge articles in group `%s'? "
- imap-current-mailbox)))
- (progn (imap-mailbox-expunge nnimap-close-asynchronous)
- (imap-mailbox-close nnimap-close-asynchronous))
- (imap-mailbox-unselect)))
+ (gnus-y-or-n-p (format "Expunge articles in group `%s'? "
+ imap-current-mailbox)))
+ (unless nnimap-dont-close
+ (imap-mailbox-expunge nnimap-close-asynchronous)
+ (imap-mailbox-close nnimap-close-asynchronous))
+ (imap-mailbox-unselect)))
(t (imap-mailbox-unselect)))
(not imap-current-mailbox))))
(defsubst nnmail-search-unix-mail-delim ()
"Put point at the beginning of the next Unix mbox message."
- ;; Algorithm used to find the the next article in the
+ ;; Algorithm used to find the next article in the
;; brain-dead Unix mbox format:
;;
;; 1) Search for "^From ".
(defun nnmail-search-unix-mail-delim-backward ()
"Put point at the beginning of the current Unix mbox message."
- ;; Algorithm used to find the the next article in the
+ ;; Algorithm used to find the next article in the
;; brain-dead Unix mbox format:
;;
;; 1) Search for "^From ".
(set-buffer buffer)
(goto-char pos)
(if (looking-at (regexp-quote command))
- (delete-region pos (progn (forward-line 1) (gnus-point-at-bol))))
- )))
- ))
+ (delete-region pos (progn
+ (forward-line 1)
+ (gnus-point-at-bol)))))))))
(defun nntp-send-command-nodelete (wait-for &rest strings)
"Send STRINGS to server and wait until WAIT-FOR returns."
(set-buffer buffer)
(goto-char pos)
(if (looking-at (regexp-quote command))
- (delete-region pos (progn (forward-line 1) (gnus-point-at-bol))))
- )))
- ))
+ (delete-region pos (progn
+ (forward-line 1)
+ (gnus-point-at-bol)))))))))
(defun nntp-send-command-and-decode (wait-for &rest strings)
"Send STRINGS to server and wait until WAIT-FOR returns."
(set-buffer buffer)
(goto-char pos)
(if (looking-at (regexp-quote command))
- (delete-region pos (progn (forward-line 1) (gnus-point-at-bol))))
- )))
- ))
-
+ (delete-region pos (progn
+ (forward-line 1)
+ (gnus-point-at-bol)))))))))
(defun nntp-send-buffer (wait-for)
"Send the current buffer to server and wait until WAIT-FOR returns."
(symbol-value 'enable-multibyte-characters))))
(unwind-protect
;; Some encoded unicode text contains character 0x80-0x9f e.g. Euro.
- (let (default-enable-multibyte-characters)
+ (let (default-enable-multibyte-characters mc-flag)
;; `set-buffer-multibyte' will be provided by APEL for all Emacsen.
(set-buffer-multibyte nil)
(process-send-region (nntp-find-connection nntp-server-buffer)
;;; We map between virtual articles and real articles in a manner
-;;; which keeps the size of the virtual active list the same as
-;;; the sum of the component active lists.
-;;; To achieve fair mixing of the groups, the last article in
-;;; each of N component groups will be in the the last N articles
-;;; in the virtual group.
-
-;;; If you have 3 components A, B and C, with articles 1-8, 1-5, and 6-7
-;;; resprectively, then the virtual article numbers look like:
+;;; which keeps the size of the virtual active list the same as the
+;;; sum of the component active lists.
+
+;;; To achieve fair mixing of the groups, the last article in each of
+;;; N component groups will be in the last N articles in the virtual
+;;; group.
+
+;;; If you have 3 components A, B and C, with articles 1-8, 1-5, and
+;;; 6-7 resprectively, then the virtual article numbers look like:
;;;
;;; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
;;; A1 A2 A3 A4 B1 A5 B2 A6 B3 A7 B4 C6 A8 B5 C7
+2002-01-15 Tue Jari Aalto <jari.aalto@poboxes.com>
+
+ * gnus.texi (Really Various Summary Commands): Added commands how
+ to create nnvirtual group and and how to modify the nnvirtual
+ regexp
+
+2002-01-12 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus.texi (Agent Caveats): Add agent cache.
+ (Agent Variables): Addition.
+
+2002-01-12 Simon Josefsson <jas@extundo.com>
+
+ * gnus.texi (Conformity): Fix typo.
+
+ * emacs-mime.texi (Flowed text, Standards): Add.
+
+2002-01-11 ShengHuo ZHU <zsh@cs.rochester.edu>
+
+ * message.texi (Mailing Lists): Addition.
+ * gnus.texi (Group Parameters): Addition.
+ From Sriram Karra <karra@cs.utah.edu>.
+
2002-01-10 Colin Marquardt <c.marquardt@alcatel.de>
* gnus.texi (Changing Servers): Addition.
This file documents the Emacs MIME interface functionality.
-Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
* Advanced MML Example:: Another example MML document.
* Charset Translation:: How charsets are mapped from @sc{mule} to MIME.
* Conversion:: Going from @sc{mime} to MML and vice versa.
+* Flowed text:: Soft and hard newlines.
@end menu
if not identical.
+@node Flowed text
+@section Flowed text
+@cindex format=flowed
+
+The Emacs @sc{mime} library will respect the @code{use-hard-newlines}
+variable (@pxref{Hard and Soft Newlines, ,Hard and Soft Newlines,
+emacs, Emacs Manual}) when encoding a message, and the
+``format=flowed'' Content-Type parameter when decoding a message.
+
+On encoding text, lines terminated by soft newline characters are
+filled together and wrapped after the column decided by
+@code{fill-flowed-encode-column}. This variable controls how the text
+will look in a client that does not support flowed text, the default
+is to wrap after 66 characters. If hard newline characters are not
+present in the buffer, no flow encoding occurs.
+
+On decoding flowed text, lines with soft newline characters are filled
+together and wrapped after the column decided by
+@code{fill-flowed-display-column}. The default is to wrap after
+@code{fill-column}.
+
@node Standards
@chapter Standards
Communicating Presentation Information in Internet Messages: The
Content-Disposition Header Field
+@item RFC2646
+Documentation of the text/plain format parameter for flowed text.
+
@end table
@c Insert "\input texinfo" at 1st line before texing this file alone.
@c -*-texinfo-*-
-@c Copyright (C) 1995, 2001 Free Software Foundation, Inc.
+@c Copyright (C) 1995, 2001, 2002 Free Software Foundation, Inc.
@setfilename gnus-faq.info
@node Frequently Asked Questions
\thispagestyle{empty}
-Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
\e$B$3$N%U%!%$%k$O\e(B GNU Emacs \e$B$N%K%e!<%9%j!<%@$G$"$k\e(B gnus \e$B$K4X$9$k@bL@=q$G$9!#\e(B
-Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
@code{gnus-parameter-to-list-alist} \e$B$b;2>H$7$F2<$5$$!#\e(B
+@item subscribed
+@cindex subscribed
+\e$B$b$7$3$N%Q%i%a!<%?$,\e(B @code{t} \e$B$K@_Dj$5$l$F$$$k$H!"\e(Bgnus \e$B$O$"$J$?$,$3$N%0\e(B
+\e$B%k!<%W$r\e(B to-address \e$B$H\e(B to-list \e$B%Q%i%a!<%?$N%"%I%l%9$G9XFI$7$F$$$k%a!<%j\e(B
+\e$B%s%0%j%9%H$G$"$k$H2r<a$7$^$9!#$3$N>pJs$r\e(B gnus \e$B$KM?$($k$3$H$O!"$"$J$?$,$=\e(B
+\e$B$l$i$N%a!<%j%s%0%j%9%H$KEj9F$9$k$H$-$K!"@5$7$$\e(B Mail-Followup-To \e$B%X%C%@!<\e(B
+\e$B$r@8@.$9$kLr$KN)$A$^$9!#\e(B
+
+@code{gnus-find-subscribed-addresses} \e$B$b;2>H$7$F2<$5$$!#$3$N4X?t$O$3$N%0\e(B
+\e$B%k!<%W%Q%i%a!<%?$rD>@\$K;H$$$^$9!#\e(B
+
@item visible
@cindex visible
\e$B%0%k!<%W%Q%i%a!<%?$N%j%9%HCf$K\e(B @code{(visible . t)} \e$B$H$$$&MWAG$,$"$l$P!"\e(B
\e$B$l$^$9!#$D$^$j!"$b$72>A[%0%k!<%WFb$G5-;v$K2D;k5-;v$N0u$r$D$1$k$H!"$=$N5-\e(B
\e$B;v$O$b$H$b$H$N9=@.%0%k!<%W$NCf$G$b2D;k5-;v$K$J$j$^$9!#\e(B(\e$B$=$7$F5U$b@.$jN)\e(B
\e$B$A$^$9\e(B --- \e$B9=@.%0%k!<%WFb$GIU$1$?0u$O2>A[%0%k!<%WFb$G$bI=<($5$l$^$9!#\e(B)
+\e$B6u$N2>A[%0%k!<%W$r:n$k$K$O!"%0%k!<%W%P%C%U%!$G\e(B @kbd{G V}
+(@code{gnus-group-make-empty-virtual}) \e$B$r<B9T$7!"\e(B@kbd{M-e}
+(@code{gnus-group-edit-group-method}) \e$B$G%a%=%C%I$N@55,I=8=$rJT=8$7$F2<$5\e(B
+\e$B$$!#\e(B
\e$B$3$l$,!"\e(BAndrea Dworkin \e$B$K4X$9$kA4$F$N%K%e!<%9%0%k!<%W$r!"0l$D$N5pBg$G%7\e(B
\e$B%"%o%;$J%K%e!<%9%0%k!<%W$K$^$H$a$k\e(B @code{nnvirtual} \e$BJ}K!$NNc$G$9!#\e(B
@item gnus-agent-fetched-hook
@vindex gnus-agent-fetched-hook
\e$B5-;v$r<h$j9~$_=*$o$C$?$H$-$K<B9T$5$l$k%U%C%/!#\e(B
+
+@item gnus-agent-cache
+@vindex gnus-agent-cache
+plugged \e$B$N$H$-$K!"%m!<%+%k$K;}$C$F$$$k\e(B NOV \e$B$H5-;v$r;H$&$+$I$&$+$r@)8f$9\e(B
+\e$B$kJQ?t!#\e(B
+
+@item gnus-agent-go-online
+@vindex gnus-agent-go-online
+@code{gnus-agent-go-online} \e$B$,\e(B @code{nil} \e$B$@$C$?$i!"%(!<%8%'%s%H$O%*%U%i\e(B
+\e$B%$%s>uBV$N%5!<%P!<$r%*%s%i%$%s>uBV$K$7$^$;$s!#\e(B@code{ask} \e$B$@$C$?$i!"$=$l\e(B
+\e$B$,%G%#%U%)%k%H$G$9$,!"%(!<%8%'%s%H$O:F@\B3$9$k$H$-$K%*%U%i%$%s>uBV$N%5!<\e(B
+\e$B%P!<$r%*%s%i%$%s>uBV$K$9$k$+$I$&$+$r?R$M$^$9!#$=$l0J30$NCM$@$C$?$i!"%*%U\e(B
+\e$B%i%$%s>uBV$N%5!<%P!<$O<+F0E*$K%*%s%i%$%s>uBV$K$J$j$^$9!#\e(B
@end table
@node Example Setup
@table @dfn
@item \e$B@\B3$5$l$F$$$k$H$-$K5-;v$rFI$s$@$i!"$=$l$O\e(B Agent \e$B$KF~$k$N$G$9$+\e(B?
-@strong{\e$B$$$$$(!#\e(B}
+@strong{\e$B$$$$$(\e(B}\e$B!#\e(B
@item \e$B@\B3$5$l$F$$$k$H$-$K5-;v$rFI$s$G!"\e(BAgent \e$B$K5-;v$,B8:_$7$F$$$k>l9g!"\e(B
\e$B$b$&0l2s%@%&%s%m!<%I$5$l$k$N$G$9$+\e(B?
-@strong{\e$B$O$$!#\e(B}
+@strong{\e$B$$$$$(\e(B}\e$B!"$?$@$7\e(B @code{gnus-agent-cache} \e$B$,\e(B `nil' \e$B$G$J$+$C$?$i!"\e(B
+\e$B$G$9$,!#\e(B
@end table
-\e$BMWLs$9$k$H!"\e(Bgnus \e$B$,@Z$jN%$5$l$F$$$k$H$-$O!"%m!<%+%k$KJ]B8$5$l$?5-;v$r8+\e(B
-\e$B$k$@$1$G$9!#@\B3$5$l$F$$$k$H$-$O!"\e(BISP \e$B$HOC$9$@$1$G$9!#\e(B
+\e$BMWLs$9$k$H!"\e(Bgnus \e$B$,@Z$jN%$5$l$F$$$k$H$-$O%m!<%+%k$KJ]B8$5$l$?5-;v$r8+$k\e(B
+\e$B$@$1$G$9!#@\B3$5$l$F$$$k$H$-$O\e(B ISP \e$B$HOC$9$@$1$G!"$+$D%m!<%+%k$K;}$C$F$$\e(B
+\e$B$k5-;v$r;H$$$^$9!#\e(B
@node Scoring
@chapter \e$B%9%3%"\e(B
@cindex MIME
MIME \e$B4XO"$N$9$Y$F$N\e(B RFC \e$B$,%5%]!<%H$5$l$F$$$^$9!#\e(B
-@item Disposition Notifications - RFC 2289
+@item Disposition Notifications - RFC 2298
Message Mode \e$B$O<u?.<T$K3+Iu3NG'$rMW5a$9$k$3$H$,$G$-$^$9!#\e(B
@ignore
\thispagestyle{empty}
-Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright \copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file documents gnus, the GNU Emacs newsreader.
-Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
See also @code{gnus-parameter-to-list-alist}.
+@item subscribed
+@cindex subscribed
+If this parameter is set to @code{t}, Gnus will consider the
+to-address and to-list parameters for this group as addresses of
+mailing lists you are subscribed to. Giving Gnus this information
+will help it to generate correct Mail-Followup-To headers for your
+posts to these lists.
+
+See also @code{gnus-find-subscribed-addresses}, the function that
+directly uses this group parameter.
+
@item visible
@cindex visible
If the group parameter list has the element @code{(visible . t)},
All marks in the virtual group will stick to the articles in the
component groups. So if you tick an article in a virtual group, the
-article will also be ticked in the component group from whence it came.
-(And vice versa---marks from the component groups will also be shown in
-the virtual group.)
+article will also be ticked in the component group from whence it
+came. (And vice versa---marks from the component groups will also be
+shown in the virtual group.). To create an empty virtual group, run
+@kbd{G V} (@code{gnus-group-make-empty-virtual}) in the group buffer
+and edit the method regexp with @kbd{M-e}
+(@code{gnus-group-edit-group-method})
Here's an example @code{nnvirtual} method that collects all Andrea Dworkin
newsgroups into one, big, happy newsgroup:
@vindex gnus-agent-fetched-hook
Hook run when after finishing fetching articles.
+@item gnus-agent-cache
+@vindex gnus-agent-cache
+Variable to control whether use the locally stored NOV and articles when
+plugged.
+
+@item gnus-agent-go-online
+@vindex gnus-agent-go-online
+If @code{gnus-agent-go-online} is @code{nil}, the Agent will never
+automatically switch offline servers into online status. If it is
+@code{ask}, the default, the Agent will ask if you wish to switch
+offline servers into online status when you re-connect. If it has any
+other value, all offline servers will be automatically switched into
+online status.
+
@end table
may ask:
@table @dfn
-@item If I read an article while plugged, do they get entered into the
-Agent?
+@item If I read an article while plugged, do they get entered into the Agent?
-@strong{No.}
+@strong{No}.
-@item If I read an article while plugged, and the article already exists
-in the Agent, will it get downloaded once more?
+@item If I read an article while plugged, and the article already exists in the Agent, will it get downloaded once more?
-@strong{Yes.}
+@strong{No}, unless @code{gnus-agent-cache} is `nil'.
@end table
In short, when Gnus is unplugged, it only looks into the locally stored
-articles; when it's plugged, it only talks to your ISP.
+articles; when it's plugged, it only talks to your ISP and also uses the
+locally stored articles.
@node Scoring
@cindex MIME
All the various MIME RFCs are supported.
-@item Disposition Notifications - RFC 2289
+@item Disposition Notifications - RFC 2298
Message Mode is able to request notifications from the receiver.
@item PGP - RFC 1991 and RFC 2440
\e$B$3$N%U%!%$%k$O\e(B Emacs \e$B$N%a%C%;!<%8:n@.%b!<%I$G$"$k\e(B Message \e$B$K4X$9$k@bL@J8\e(B
\e$B=q$G$9!#\e(B
-Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
* Forwarding:: \e$B%a%C%;!<%8$r%K%e!<%9$b$7$/$O%a!<%k$GE>Aw$9$k\e(B
* Resending:: \e$B%a!<%k%a%C%;!<%8$r:FAw$9$k\e(B
* Bouncing:: \e$B%a!<%k%a%C%;!<%8$N<:GT$r:FAw$9$k\e(B
+* Mailing Lists:: \e$B%a!<%j%s%0%j%9%H$K%a!<%k$rAw$k\e(B
@end menu
@node New Mail Message
\e$B%U%!$r:n$j>e$2$kA0$K<h$j=|$+$l$^$9!#=i4|CM\e(B
\e$B$O\e(B @samp{^\\(Received\\|Return-Path\\):} \e$B$G$9!#\e(B
+@c TRANSLATE_ME!!
+@node Mailing Lists
+@section Mailing Lists
+
+Sometimes while posting to mailing lists, the poster needs to direct
+followups to the post to specific places. The Mail-Followup-To (MFT)
+was created to enable just this. Two example scenarios where this is
+useful:
+
+@itemize
+@item
+A mailing list poster can use MFT to express that responses should be
+sent to just the list, and not the poster as well. This will happen
+if the poster is already subscribed to the list.
+
+@item
+If a message is posted to several mailing lists, MFT may also be used
+to direct the following discussion to one list only, because
+discussions that are spread over several lists tend to be fragmented
+and very difficult to follow.
+
+@end itemize
+
+Gnus honors the MFT header in other's messages (i.e. while following
+up to someone else's post) and also provides support for generating
+sensible MFT headers for outgoing messages as well.
+
+@c @menu
+@c * Honoring an MFT post:: What to do when one already exists
+@c * Composing with a MFT header:: Creating one from scratch.
+@c @end menu
+
+@c @node Composing with a MFT header
+@subsection Composing a correct MFT header automagically
+
+The first step in getting Gnus to automagically generate a MFT header
+in posts you make is to give Gnus a list of the mailing lists
+addresses you are subscribed to. You can do this in more than one
+way. The following variables would come in handy.
+
+@table @code
+
+@item message-subscribed-addresses
+This should be a list of addresses the user is subscribed to. Its
+default value is @code{nil}. Example:
+@lisp
+(setq message-subscribed-addresses
+ '("ding@@gnus.org" "bing@@noose.org"))
+@end lisp
+
+@item message-subscribed-regexps
+This should be a list of regexps denoting the addresses of mailing
+lists subscribed to. Default value is @code{nil}. Example: If you
+want to achieve the same result as above:
+@lisp
+(setq message-subscribed-regexps
+ '("[bd]ing@@\\(gnus\\|noose\\)\\.org"))
+@end lisp
+
+@item message-subscribed-address-functions
+This can be a list of functions to be called (one at a time!!) to
+determine the value of MFT headers. It is advisable that these
+functions not take any arguments. Default value is @code{nil}.
+
+@item message-subscribed-address-file
+You might be one organised human freak and have a list of addresses of
+all subscribed mailing lists in a separate file! Then you can just
+set this variable to the name of the file and life would be good.
+
+@end table
+
+You can use one or more of the above variables. All their values are
+``added'' in some way that works :-)
+
+Now you are all set. Just start composing a message as you normally
+do. And just send it; as always. Just before the message is sent
+out, Gnus' MFT generation thingy kicks in and checks if the message
+already has a MFT header. If there is one, the header is left alone.
+If not then the list of recipient addresses (in the To: and Cc:
+headers) is checked to see if one of them is a list address you are
+subscribed to. If none of them is a list address, then no MFT is
+generated; otherwise, a MFT is added to the other headers and set to
+the value of all addresses in To: and Cc:
+
+Hm. ``So'', you ask, ``what if I send an email to a list I am not
+subscribed to?'' Well, the kind folks at Gnus Towers are working on a
+database of all known mailing list addresses that can be used for this
+purpose. Till then, you could, like, insert a MFT header manually,
+with the help of @kbd{C-c C-f m} !!
+
+@c @node Honoring an MFT post
+@subsection Honoring an MFT post
+
+When you followup to a post on a mailing list, and the post has a MFT
+header, Gnus' action will depend on the value of the variable
+@code{message-use-mail-followup-to}. This variable can be one of:
+
+@table @code
+@item t
+ Always honor MFTs. The To: and Cc: headers in your followup will be
+ derived from the MFT header of the original post.
+
+@item nil
+ Always dishonor MFTs (just ignore the darned thing)
+
+@item ask
+Gnus will prompt you for an action. This is the default.
+
+@end table
+
+It is considered good nettiquette to honor MFT, as it is assumed the
+fellow who posted a message knows where the followups need to go
+better than you do.
+
@node Commands
@chapter \e$BL?Na\e(B
This file documents Message, the Emacs message composition mode.
-Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
* Forwarding:: Forwarding a message via news or mail.
* Resending:: Resending a mail message.
* Bouncing:: Bouncing a mail message.
+* Mailing Lists:: Send mail to mailing lists.
@end menu
@samp{^\\(Received\\|Return-Path\\):}.
+@node Mailing Lists
+@section Mailing Lists
+
+Sometimes while posting to mailing lists, the poster needs to direct
+followups to the post to specific places. The Mail-Followup-To (MFT)
+was created to enable just this. Two example scenarios where this is
+useful:
+
+@itemize
+@item
+A mailing list poster can use MFT to express that responses should be
+sent to just the list, and not the poster as well. This will happen
+if the poster is already subscribed to the list.
+
+@item
+If a message is posted to several mailing lists, MFT may also be used
+to direct the following discussion to one list only, because
+discussions that are spread over several lists tend to be fragmented
+and very difficult to follow.
+
+@end itemize
+
+Gnus honors the MFT header in other's messages (i.e. while following
+up to someone else's post) and also provides support for generating
+sensible MFT headers for outgoing messages as well.
+
+@c @menu
+@c * Honoring an MFT post:: What to do when one already exists
+@c * Composing with a MFT header:: Creating one from scratch.
+@c @end menu
+
+@c @node Composing with a MFT header
+@subsection Composing a correct MFT header automagically
+
+The first step in getting Gnus to automagically generate a MFT header
+in posts you make is to give Gnus a list of the mailing lists
+addresses you are subscribed to. You can do this in more than one
+way. The following variables would come in handy.
+
+@table @code
+
+@item message-subscribed-addresses
+This should be a list of addresses the user is subscribed to. Its
+default value is @code{nil}. Example:
+@lisp
+(setq message-subscribed-addresses
+ '("ding@@gnus.org" "bing@@noose.org"))
+@end lisp
+
+@item message-subscribed-regexps
+This should be a list of regexps denoting the addresses of mailing
+lists subscribed to. Default value is @code{nil}. Example: If you
+want to achieve the same result as above:
+@lisp
+(setq message-subscribed-regexps
+ '("[bd]ing@@\\(gnus\\|noose\\)\\.org"))
+@end lisp
+
+@item message-subscribed-address-functions
+This can be a list of functions to be called (one at a time!!) to
+determine the value of MFT headers. It is advisable that these
+functions not take any arguments. Default value is @code{nil}.
+
+@item message-subscribed-address-file
+You might be one organised human freak and have a list of addresses of
+all subscribed mailing lists in a separate file! Then you can just
+set this variable to the name of the file and life would be good.
+
+@end table
+
+You can use one or more of the above variables. All their values are
+``added'' in some way that works :-)
+
+Now you are all set. Just start composing a message as you normally
+do. And just send it; as always. Just before the message is sent
+out, Gnus' MFT generation thingy kicks in and checks if the message
+already has a MFT header. If there is one, the header is left alone.
+If not then the list of recipient addresses (in the To: and Cc:
+headers) is checked to see if one of them is a list address you are
+subscribed to. If none of them is a list address, then no MFT is
+generated; otherwise, a MFT is added to the other headers and set to
+the value of all addresses in To: and Cc:
+
+Hm. ``So'', you ask, ``what if I send an email to a list I am not
+subscribed to?'' Well, the kind folks at Gnus Towers are working on a
+database of all known mailing list addresses that can be used for this
+purpose. Till then, you could, like, insert a MFT header manually,
+with the help of @kbd{C-c C-f m} !!
+
+@c @node Honoring an MFT post
+@subsection Honoring an MFT post
+
+When you followup to a post on a mailing list, and the post has a MFT
+header, Gnus' action will depend on the value of the variable
+@code{message-use-mail-followup-to}. This variable can be one of:
+
+@table @code
+@item t
+ Always honor MFTs. The To: and Cc: headers in your followup will be
+ derived from the MFT header of the original post.
+
+@item nil
+ Always dishonor MFTs (just ignore the darned thing)
+
+@item ask
+Gnus will prompt you for an action. This is the default.
+
+@end table
+
+It is considered good nettiquette to honor MFT, as it is assumed the
+fellow who posted a message knows where the followups need to go
+better than you do.
+
@node Commands
@chapter Commands