From: yamaoka Date: Sun, 29 Aug 1999 22:19:33 +0000 (+0000) Subject: Importing Pterodactyl Gnus v0.96. X-Git-Tag: pgnus-0_96~1 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=625b891fc07e1e5fc5f2658176b6c0e3cb244ee0;p=elisp%2Fgnus.git- Importing Pterodactyl Gnus v0.96. --- diff --git a/README b/README index f845bbd..e487c43 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ You should definitely byte-compile the source files. To do that, you can simply say "./configure && make" in this directory. If you are using XEmacs, you *must* say "make EMACS=xemacs". In that case you may also want to pull down the package of nice glyphs from -. It should be installed +. It should be installed into the "gnus-5.6.53/etc" directory. Then you have to tell Emacs where Gnus is. You might put something diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 09a7cf5..b0c1665 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,229 @@ +Fri Aug 27 13:17:48 1999 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.96 is released. + +1999-08-17 Simon Josefsson + + * gnus-start.el (gnus-groups-to-gnus-format): Only use agent + to get active info if method is covered by agent, otherwise + active info is lost. + +1999-08-17 Simon Josefsson + + * gnus-sum.el (gnus-summary-move-article): Report backend errors. + +1999-08-09 Dave Love + + * mm-util.el: Use `defalias', not `fset' for dummy functions. + +1999-08-09 Simon Josefsson + + * gnus-art.el (gnus-ignored-headers): Remove "X-Pgp-*" + (already matched by "^X-Pgp"), removed duplicate + X-Mailing-List, added several new junk headers. + +1999-08-01 Simon Josefsson + + * gnus-art.el (article-decode-charset): Don't assume + gnus-summary-buffer is live. + +1999-08-27 15:07:43 Paul Flinders + + * smiley.el (smiley-deformed-regexp-alist): Fix % smileys. + +1999-08-27 15:02:58 Florian Weimer + + * gnus-score.el (gnus-home-score-file): Work with absolute path + names. + +1999-07-17 Shenghuo ZHU + + * gnus-sum.el (gnus-articles-to-read): Return cached articles if + nothing else in the group. + +1999-07-16 Shenghuo ZHU + + * gnus-bcklg.el (gnus-backlog-enter-article): Check the size of + the article. + +1999-07-15 Shenghuo ZHU + + * mm-uu.el (mm-uu-dissect): Fix for base64 message. + +1999-07-15 Shenghuo ZHU + + * mm-uu.el (mm-uu-forward-end-line): Support forwarded message + from mutt. + +1999-07-14 Shenghuo ZHU + + * mm-bodies.el (mm-decode-content-transfer-encoding): Delete + whitespace. + +1999-07-14 Shenghuo ZHU + + * mm-util.el (mm-text-coding-system-for-write): New variable. + (mm-append-to-file): New function. + (mm-write-region): New function. + + * gnus-art.el (gnus-output-to-file): Use it. + * gnus-util.el (gnus-output-to-rmail): Ditto. + (gnus-output-to-mail): Ditto. + * gnus-uu.el (gnus-uu-binhex-article): Ditto. + +1999-07-14 Shenghuo ZHU + + * nnmail.el (nnmail-find-file): Use mm-auto-mode-alist. + + * nnheader.el (nnheader-insert-file-contents): Revert and use + mm-insert-file-contents. + (nnheader-find-file-noselect): Use mm-auto-mode-alist. + (nnheader-auto-mode-alist): Removed. + + * mm-util.el (mm-inhibit-file-name-handlers): New variable. + (mm-insert-file-contents): Add a new parameter for inserting + compressed file literally. + + * mml.el (mml-generate-mime-1): Insert non-text literally. + + * gnus.el: Change most mm-insert-file-contents back to nnheader. + +1999-07-13 Hrvoje Niksic + + * gnus-art.el (gnus-unbuttonized-mime-types): Fix docstring. + +1999-08-27 14:53:42 Oleg S. Tihonov + + * gnus-sum.el (gnus-group-charset-alist): Default fido7 to + koi8-r. + +1999-07-11 Shenghuo ZHU + + * mml.el (mml-insert-mime): Decode text. + (mml-to-mime): Narrow to headers-or-head. + +1999-07-11 Shenghuo ZHU + + * mm-view.el (mm-inline-text): Check + w3-meta-content-type-charset-regexp. + +1999-07-10 Simon Josefsson + + * gnus-agent.el (gnus-agent-fetch-group-1): Search topics for + predicate. + +1999-07-10 Alexandre Oliva + + * gnus-mlspl.el: Documentation fixes. + +1999-08-27 14:42:14 Rui Zhu + + * gnus-sum.el (gnus-summary-limit-to-age): Prompt better. + +1999-08-27 14:40:52 Michael Cook + + * gnus-art.el (gnus-article-setup-buffer): Kill all local + variables. + +1999-08-27 14:39:34 Hrvoje Niksic + + * nnmail.el (nnmail-get-new-mail): "Done". + +1999-08-27 14:38:14 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-kill-all-zombies): Only prompt when + interactive. + +1999-07-12 Shenghuo ZHU + + * gnus-art.el (article-decode-charset): Fix broken CT. + +1999-07-12 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-fetch-group-1): Recreate agent + overview buffer if it is killed. +1999-08-27 14:26:03 Eric Marsden + + * gnus-art.el (article-babel): New version. + +1999-08-27 14:22:39 Jon Kv + + * nnfolder.el (nnfolder-request-list-newsgroups): Faster expiry. + +1999-07-10 Mike McEwan + + * gnus.texi (More Threading): Document new variable + `gnus-sort-gathered-threads-function'. + +1999-07-10 Mike McEwan + + * gnus.texi (More Threading): Document new variable + `gnus-sort-gathered-threads-function'. + +1999-07-11 Andreas Jaeger + + * gnus-uu.el (gnus-uu-digest-mail-forward): Delete file after + usage. + +1999-07-10 Shenghuo ZHU + + * mm-util.el (mm-running-xemacs): Removed. + (mm-coding-system-p): New function. + (mm-binary-coding-system): Safe guess. + (mm-text-coding-system): Ditto. + (mm-auto-save-coding-system): Ditto. + +1999-07-11 11:02:03 Lars Magne Ingebrigtsen + + * mm-encode.el (mm-qp-or-base64): Also consider control chars. + (mm-qp-or-base64): Reversed logic. + + * mm-decode.el (mm-save-part-to-file): Let coding system be + binary. + +1999-07-15 Mike McEwan + + * gnus-agent.el (gnus-agent-fetch-group-1): Allow 'agent-score' to + be set in topic parameters. + +1999-07-10 Mike McEwan + + * gnus-sum.el (gnus-sort-gathered-threads-function): New variable. + (gnus-sort-gathered-threads): Allow the user to specify the + function to use when sorting gathered threads. + + * gnus-agent.el (gnus-agent-get-undownloaded-list): Don't + mark cached articles as `undownloaded'. + +Tue Jul 20 02:39:56 1999 Peter von der Ahé + + * gnus-sum.el (gnus-summary-exit): Allow gnus-use-adaptive-scoring + to have buffer local values. + +1999-07-25 Matt Pharr + + * gnus-group.el (gnus-group-make-doc-group): Notice when user + types 'g' for 'guess group type. + +1999-07-30 Simon Josefsson + + * nnmail.el (nnmail-remove-list-identifiers): Remove whitespace + after each regexp in nnmail-list-identifiers, not just after last + one. + + * gnus-sum.el (gnus-list-identifiers): New variable. + (gnus-summary-remove-list-identifiers): New function. + (gnus-select-newsgroup): Use it. + (gnus-summary-wash-hide-map): Bind + `gnus-article-hide-list-identifiers' to W W l. + (gnus-summary-make-menu-bar): Add list-identifiers command. + + * gnus-art.el (gnus-treat-strip-list-identifiers): New variable. + (gnus-treatment-function-alist): Add variable. + (article-hide-list-identifiers): New function. + (mapcar): Add function. + (gnus-article-hide): Use it. + Fri Jul 9 22:21:16 1999 Lars Magne Ingebrigtsen * gnus.el: Pterodactyl Gnus v0.95 is released. diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index b0a543c..a05c579 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -135,7 +135,7 @@ If nil, only read articles will be expired." "Load FILE and do a `read' there." (with-temp-buffer (ignore-errors - (mm-insert-file-contents file) + (nnheader-insert-file-contents file) (goto-char (point-min)) (read (current-buffer))))) @@ -521,7 +521,8 @@ the actual number of articles toggled is returned." article) (while (setq article (pop articles)) (unless (or (cdr (assq article gnus-agent-article-alist)) - (memq article gnus-newsgroup-downloadable)) + (memq article gnus-newsgroup-downloadable) + (memq article gnus-newsgroup-cached)) (push article gnus-newsgroup-undownloaded)))) ;; Then mark downloaded downloadable as not-downloadable, ;; if you get my drift. @@ -588,7 +589,7 @@ the actual number of articles toggled is returned." (gnus-make-directory (file-name-directory file)) (with-temp-file file (when (file-exists-p file) - (mm-insert-file-contents file)) + (nnheader-insert-file-contents file)) (goto-char (point-min)) (when (re-search-forward (concat "^" (regexp-quote group) " ") nil t) @@ -773,7 +774,7 @@ the actual number of articles toggled is returned." (when (= (point-max) (point-min)) (push (cons group (current-buffer)) gnus-agent-buffer-alist) (ignore-errors - (mm-insert-file-contents + (nnheader-insert-file-contents (gnus-agent-article-name ".overview" group)))) (nnheader-find-nov-line (string-to-number (cdar crosses))) (insert (string-to-number (cdar crosses))) @@ -853,7 +854,7 @@ the actual number of articles toggled is returned." (goto-char (point-min)) (set-buffer nntp-server-buffer) (erase-buffer) - (mm-insert-file-contents file) + (nnheader-insert-file-contents file) (goto-char (point-max)) (if (or (= (point-min) (point-max)) (progn @@ -949,20 +950,31 @@ the actual number of articles toggled is returned." category predicate info marks score-param) ;; Fetch headers. (when (and (or (gnus-active group) (gnus-activate-group group)) - (setq articles (gnus-agent-fetch-headers group))) - ;; Parse them and see which articles we want to fetch. - (setq gnus-newsgroup-dependencies - (make-vector (length articles) 0)) - ;; No need to call `gnus-get-newsgroup-headers-xover' with - ;; the entire .overview for group as we still have the just - ;; downloaded headers in `gnus-agent-overview-buffer'. - (let ((nntp-server-buffer gnus-agent-overview-buffer)) - (setq gnus-newsgroup-headers - (gnus-get-newsgroup-headers-xover articles nil nil group))) + (setq articles (gnus-agent-fetch-headers group)) + (progn + ;; Parse them and see which articles we want to fetch. + (setq gnus-newsgroup-dependencies + (make-vector (length articles) 0)) + ;; No need to call `gnus-get-newsgroup-headers-xover' with + ;; the entire .overview for group as we still have the just + ;; downloaded headers in `gnus-agent-overview-buffer'. + (let ((nntp-server-buffer gnus-agent-overview-buffer)) + (setq gnus-newsgroup-headers + (gnus-get-newsgroup-headers-xover articles nil nil + group))) + ;; `gnus-agent-overview-buffer' may be killed for + ;; timeout reason. If so, recreate it. + (if (gnus-buffer-live-p gnus-agent-overview-buffer) + t + (setq gnus-agent-overview-buffer + (gnus-get-buffer-create " *Gnus agent overview*")) + (with-current-buffer gnus-agent-overview-buffer + (mm-enable-multibyte)) + nil))) (setq category (gnus-group-category group)) (setq predicate (gnus-get-predicate - (or (gnus-group-get-parameter group 'agent-predicate t) + (or (gnus-group-find-parameter group 'agent-predicate t) (cadr category)))) ;; Do we want to download everything, or nothing? (if (or (eq (caaddr predicate) 'gnus-agent-true) @@ -976,7 +988,7 @@ the actual number of articles toggled is returned." (setq score-param (let ((score-method (or - (gnus-group-get-parameter group 'agent-score t) + (gnus-group-find-parameter group 'agent-score t) (caddr category)))) (when score-method (require 'gnus-score) @@ -1366,156 +1378,160 @@ The following commands are available: (save-excursion (setq overview (gnus-get-buffer-create " *expire overview*")) (while (setq gnus-command-method (pop methods)) - (with-temp-buffer - (insert-file-contents (gnus-agent-lib-file "active")) - (gnus-active-to-gnus-format - gnus-command-method - (setq orig (gnus-make-hashtable - (count-lines (point-min) (point-max)))))) - (let ((expiry-hashtb (gnus-make-hashtable 1023))) - (gnus-agent-open-history) - (set-buffer - (setq gnus-agent-current-history - (setq history (gnus-agent-history-buffer)))) - (goto-char (point-min)) - (when (> (buffer-size) 1) - (goto-char (point-min)) - (while (not (eobp)) - (skip-chars-forward "^\t") - (if (> (read (current-buffer)) day) - ;; New article; we don't expire it. - (forward-line 1) - ;; Old article. Schedule it for possible nuking. - (while (not (eolp)) - (setq sym (let ((obarray expiry-hashtb)) - (read (current-buffer)))) - (if (boundp sym) - (set sym (cons (cons (read (current-buffer)) (point)) - (symbol-value sym))) - (set sym (list (cons (read (current-buffer)) (point))))) - (skip-chars-forward " ")) - (forward-line 1))) - ;; We now have all articles that can possibly be expired. - (mapatoms - (lambda (sym) - (setq group (symbol-name sym) - articles (sort (symbol-value sym) 'car-less-than-car) - low (car (gnus-active group)) - info (gnus-get-info group) - unreads (ignore-errors (gnus-list-of-unread-articles group)) - marked (nconc (gnus-uncompress-range - (cdr (assq 'tick (gnus-info-marks info)))) - (gnus-uncompress-range - (cdr (assq 'dormant - (gnus-info-marks info))))) - nov-file (gnus-agent-article-name ".overview" group) - lowest nil - highest nil) - (gnus-agent-load-alist group) - (gnus-message 5 "Expiring articles in %s" group) - (set-buffer overview) - (erase-buffer) - (when (file-exists-p nov-file) - (mm-insert-file-contents nov-file)) - (goto-char (point-min)) - (setq article 0) - (while (setq elem (pop articles)) - (setq article (car elem)) - (when (or (null low) - (< article low) - gnus-agent-expire-all - (and (not (memq article unreads)) - (not (memq article marked)))) - ;; Find and nuke the NOV line. - (while (and (not (eobp)) - (or (not (numberp - (setq art (read (current-buffer))))) - (< art article))) - (if (file-exists-p - (gnus-agent-article-name - (number-to-string art) group)) - (progn - (unless lowest - (setq lowest art)) - (setq highest art) - (forward-line 1)) - ;; Remove old NOV lines that have no articles. - (gnus-delete-line))) - (if (or (eobp) - (/= art article)) - (beginning-of-line) - (gnus-delete-line)) - ;; Nuke the article. - (when (file-exists-p (setq file (gnus-agent-article-name - (number-to-string article) - group))) - (delete-file file)) - ;; Schedule the history line for nuking. - (push (cdr elem) histories))) - (gnus-make-directory (file-name-directory nov-file)) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) nov-file nil 'silent)) - ;; Delete the unwanted entries in the alist. - (setq gnus-agent-article-alist - (sort gnus-agent-article-alist 'car-less-than-car)) - (let* ((alist gnus-agent-article-alist) - (prev (cons nil alist)) - (first prev) - expired) - (while (and alist - (<= (caar alist) article)) - (if (or (not (cdar alist)) - (not (file-exists-p - (gnus-agent-article-name - (number-to-string - (caar alist)) - group)))) - (progn - (push (caar alist) expired) - (setcdr prev (setq alist (cdr alist)))) - (setq prev alist - alist (cdr alist)))) - (setq gnus-agent-article-alist (cdr first)) - (gnus-agent-save-alist group) - ;; Mark all articles up to the first article - ;; in `gnus-article-alist' as read. - (when (and info (caar gnus-agent-article-alist)) - (setcar (nthcdr 2 info) - (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. - (when (and info - expired - (or (not (caar gnus-agent-article-alist)) - (> (car expired) - (caar gnus-agent-article-alist)))) - (setcar (nthcdr 2 info) - (gnus-add-to-range - (nth 2 info) - (nreverse expired)))) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string info) - ")"))) - (when lowest - (if (gnus-gethash group orig) - (setcar (gnus-gethash group orig) lowest) - (gnus-sethash group (cons lowest highest) orig)))) - expiry-hashtb) - (set-buffer history) - (setq histories (nreverse (sort histories '<))) - (while histories - (goto-char (pop histories)) - (gnus-delete-line)) - (gnus-agent-save-history) - (gnus-agent-close-history) - (gnus-write-active-file - (gnus-agent-lib-file "active") orig)) - (gnus-message 4 "Expiry...done")))))) + (when (file-exists-p (gnus-agent-lib-file "active")) + (with-temp-buffer + (insert-file-contents (gnus-agent-lib-file "active")) + (gnus-active-to-gnus-format + gnus-command-method + (setq orig (gnus-make-hashtable + (count-lines (point-min) (point-max)))))) + (let ((expiry-hashtb (gnus-make-hashtable 1023))) + (gnus-agent-open-history) + (set-buffer + (setq gnus-agent-current-history + (setq history (gnus-agent-history-buffer)))) + (goto-char (point-min)) + (when (> (buffer-size) 1) + (goto-char (point-min)) + (while (not (eobp)) + (skip-chars-forward "^\t") + (if (> (read (current-buffer)) day) + ;; New article; we don't expire it. + (forward-line 1) + ;; Old article. Schedule it for possible nuking. + (while (not (eolp)) + (setq sym (let ((obarray expiry-hashtb)) + (read (current-buffer)))) + (if (boundp sym) + (set sym (cons (cons (read (current-buffer)) (point)) + (symbol-value sym))) + (set sym (list (cons (read (current-buffer)) (point))))) + (skip-chars-forward " ")) + (forward-line 1))) + ;; We now have all articles that can possibly be expired. + (mapatoms + (lambda (sym) + (setq group (symbol-name sym) + articles (sort (symbol-value sym) 'car-less-than-car) + low (car (gnus-active group)) + info (gnus-get-info group) + unreads (ignore-errors + (gnus-list-of-unread-articles group)) + marked (nconc + (gnus-uncompress-range + (cdr (assq 'tick (gnus-info-marks info)))) + (gnus-uncompress-range + (cdr (assq 'dormant + (gnus-info-marks info))))) + nov-file (gnus-agent-article-name ".overview" group) + lowest nil + highest nil) + (gnus-agent-load-alist group) + (gnus-message 5 "Expiring articles in %s" group) + (set-buffer overview) + (erase-buffer) + (when (file-exists-p nov-file) + (nnheader-insert-file-contents nov-file)) + (goto-char (point-min)) + (setq article 0) + (while (setq elem (pop articles)) + (setq article (car elem)) + (when (or (null low) + (< article low) + gnus-agent-expire-all + (and (not (memq article unreads)) + (not (memq article marked)))) + ;; Find and nuke the NOV line. + (while (and (not (eobp)) + (or (not (numberp + (setq art (read (current-buffer))))) + (< art article))) + (if (file-exists-p + (gnus-agent-article-name + (number-to-string art) group)) + (progn + (unless lowest + (setq lowest art)) + (setq highest art) + (forward-line 1)) + ;; Remove old NOV lines that have no articles. + (gnus-delete-line))) + (if (or (eobp) + (/= art article)) + (beginning-of-line) + (gnus-delete-line)) + ;; Nuke the article. + (when (file-exists-p + (setq file (gnus-agent-article-name + (number-to-string article) + group))) + (delete-file file)) + ;; Schedule the history line for nuking. + (push (cdr elem) histories))) + (gnus-make-directory (file-name-directory nov-file)) + (let ((coding-system-for-write + gnus-agent-file-coding-system)) + (write-region (point-min) (point-max) nov-file nil 'silent)) + ;; Delete the unwanted entries in the alist. + (setq gnus-agent-article-alist + (sort gnus-agent-article-alist 'car-less-than-car)) + (let* ((alist gnus-agent-article-alist) + (prev (cons nil alist)) + (first prev) + expired) + (while (and alist + (<= (caar alist) article)) + (if (or (not (cdar alist)) + (not (file-exists-p + (gnus-agent-article-name + (number-to-string + (caar alist)) + group)))) + (progn + (push (caar alist) expired) + (setcdr prev (setq alist (cdr alist)))) + (setq prev alist + alist (cdr alist)))) + (setq gnus-agent-article-alist (cdr first)) + (gnus-agent-save-alist group) + ;; Mark all articles up to the first article + ;; in `gnus-article-alist' as read. + (when (and info (caar gnus-agent-article-alist)) + (setcar (nthcdr 2 info) + (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. + (when (and info + expired + (or (not (caar gnus-agent-article-alist)) + (> (car expired) + (caar gnus-agent-article-alist)))) + (setcar (nthcdr 2 info) + (gnus-add-to-range + (nth 2 info) + (nreverse expired)))) + (gnus-dribble-enter + (concat "(gnus-group-set-info '" + (gnus-prin1-to-string info) + ")"))) + (when lowest + (if (gnus-gethash group orig) + (setcar (gnus-gethash group orig) lowest) + (gnus-sethash group (cons lowest highest) orig)))) + expiry-hashtb) + (set-buffer history) + (setq histories (nreverse (sort histories '<))) + (while histories + (goto-char (pop histories)) + (gnus-delete-line)) + (gnus-agent-save-history) + (gnus-agent-close-history) + (gnus-write-active-file + (gnus-agent-lib-file "active") orig)) + (gnus-message 4 "Expiry...done"))))))) ;;;###autoload (defun gnus-agent-batch () diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index 9836d8a..4c486fb 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -116,11 +116,18 @@ "^Originator:" "^X-Problems-To:" "^X-Auth-User:" "^X-Post-Time:" "^X-Admin:" "^X-UID:" "^Resent-[-A-Za-z]+:" "^X-Mailing-List:" "^Precedence:" "^Original-[-A-Za-z]+:" "^X-filename:" "^X-Orcpt:" - "^Old-Received:" "^X-Pgp-Fingerprint:" "^X-Pgp-Key-Id:" - "^X-Pgp-Public-Key-Url:" "^X-Auth:" "^X-From-Line:" + "^Old-Received:" "^X-Pgp" "^X-Auth:" "^X-From-Line:" "^X-Gnus-Article-Number:" "^X-Majordomo:" "^X-Url:" "^X-Sender:" - "^X-Mailing-List:" "^MBOX-Line" "^Priority:" "^X-Pgp" "^X400-[-A-Za-z]+:" - "^Status:" "^X-Gnus-Mail-Source:" "^Cancel-Lock:") + "^MBOX-Line" "^Priority:" "^X-Pgp" "^X400-[-A-Za-z]+:" + "^Status:" "^X-Gnus-Mail-Source:" "^Cancel-Lock:" + "^X-FTN" "^X-EXP32-SerialNo:" "^Encoding:" "^Importance:" + "^Autoforwarded:" "^Original-Encoded-Information-Types:" "^X-Ya-Pop3:" + "^X-Face-Version:" "^X-Vms-To:" "^X-ML-NAME:" "^X-ML-COUNT:" + "^Mailing-List:" "^X-finfo:" "^X-md5sum:" "^X-md5sum-Origin:" + "^X-Sun-Charset:" "^X-Accept-Language:" "^X-Envelope-Sender:" + "^List-[A-Za-z]+:" "^X-Listprocessor-Version:" + "^X-Received:" "^X-Distribute:" "^X-Sequence:" "^X-Juno-Line-Breaks:" + "^X-Notes-Item:" "^X-MS-TNEF-Correlator:" "^x-uunet-gateway:") "*All headers that start with this regexp will be hidden. This variable can also be a list of regexps of headers to be ignored. If `gnus-visible-headers' is non-nil, this variable will be ignored." @@ -587,7 +594,7 @@ displayed by the first non-nil matching CONTENT face." :type '(repeat regexp)) (defcustom gnus-unbuttonized-mime-types '(".*/.*") - "List of MIME types that should not be given buttons when rendered." + "List of MIME types that should not be given buttons when rendered inline." :group 'gnus-article-mime :type '(repeat regexp)) @@ -709,6 +716,13 @@ See the manual for details." :group 'gnus-article-treat :type gnus-article-treat-custom) +(defcustom gnus-treat-strip-list-identifiers 'head + "Strip list identifiers from `gnus-list-identifiers`. +Valid values are nil, t, `head', `last', an integer or a predicate. +See the manual for details." + :group 'gnus-article-treat + :type gnus-article-treat-custom) + (defcustom gnus-treat-strip-pgp t "Strip PGP signatures. Valid values are nil, t, `head', `last', an integer or a predicate. @@ -902,6 +916,7 @@ See the manual for details." (gnus-treat-hide-boring-headers gnus-article-hide-boring-headers) (gnus-treat-hide-signature gnus-article-hide-signature) (gnus-treat-hide-citation gnus-article-hide-citation) + (gnus-treat-strip-list-identifiers gnus-article-hide-list-identifiers) (gnus-treat-strip-pgp gnus-article-hide-pgp) (gnus-treat-strip-pem gnus-article-hide-pem) (gnus-treat-highlight-headers gnus-article-highlight-headers) @@ -1400,9 +1415,13 @@ If PROMPT (the prefix), prompt for a coding system to use." (mail-content-type-get ctl 'charset)))) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets - (save-excursion (set-buffer gnus-summary-buffer) + (save-excursion (condition-case nil + (set-buffer gnus-summary-buffer) + (error)) gnus-newsgroup-ignored-charsets)) buffer-read-only) + (if (and ctl (not (string-match "/" (car ctl)))) + (setq ctl nil)) (goto-char (point-max)) (widen) (forward-line 1) @@ -1445,6 +1464,24 @@ or not." (when charset (mm-decode-body charset))))))) +(defun article-hide-list-identifiers () + "Remove any list identifiers in `gnus-list-identifiers' from Subject +header in the current article." + (interactive) + (save-excursion + (save-restriction + (let ((inhibit-point-motion-hooks t) + buffer-read-only) + (article-narrow-to-head) + (let ((regexp (if (stringp gnus-list-identifiers) gnus-list-identifiers + (mapconcat 'identity gnus-list-identifiers " *\\|")))) + (when regexp + (goto-char (point-min)) + (when (re-search-forward + (concat "^Subject: +\\(Re: +\\)?\\(" regexp " *\\)") + nil t) + (delete-region (match-beginning 2) (match-end 0))))))))) + (defun article-hide-pgp () "Remove any PGP headers and signatures in the current article." (interactive) @@ -1529,17 +1566,9 @@ always hide." (while (re-search-forward banner nil t) (delete-region (match-beginning 0) (match-end 0)))))))))) -(defun article-babel-prompt () - "Prompt for a babel translation." - (require 'babel) - (completing-read "Translate from: " - babel-translations nil t - (car (car babel-translations)) - babel-history)) - -(defun article-babel (translation) - "Translate article according to TRANSLATION using babelfish." - (interactive (list (article-babel-prompt))) +(defun article-babel () + "Translate article using an online translation service." + (interactive) (require 'babel) (save-excursion (set-buffer gnus-article-buffer) @@ -1547,14 +1576,12 @@ always hide." (let* ((buffer-read-only nil) (start (point)) (end (point-max)) - (msg (buffer-substring start end))) + (orig (buffer-substring start end)) + (trans (babel-as-string orig))) (save-restriction (narrow-to-region start end) (delete-region start end) - (babel-fetch msg (cdr (assoc translation babel-translations))) - (save-restriction - (narrow-to-region start (point-max)) - (babel-wash))))))) + (insert trans)))))) (defun article-hide-signature (&optional arg) "Hide the signature in the current article. @@ -2355,6 +2382,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is article-display-x-face article-de-quoted-unreadable article-mime-decode-quoted-printable + article-hide-list-identifiers article-hide-pgp article-strip-banner article-babel @@ -2513,6 +2541,7 @@ commands: (if (get-buffer name) (save-excursion (set-buffer name) + (kill-all-local-variables) (buffer-disable-undo) (setq buffer-read-only t) (unless (eq major-mode 'gnus-article-mode) @@ -3287,7 +3316,7 @@ Provided for backwards compatibility." ;; save it to file. (goto-char (point-max)) (insert "\n") - (append-to-file (point-min) (point-max) file-name) + (mm-append-to-file (point-min) (point-max) file-name) t))) (defun gnus-narrow-to-page (&optional arg) @@ -3524,6 +3553,7 @@ headers will be hidden. If given a prefix, show the hidden text instead." (interactive (append (gnus-article-hidden-arg) (list 'force))) (gnus-article-hide-headers arg) + (gnus-article-hide-list-identifiers arg) (gnus-article-hide-pgp arg) (gnus-article-hide-citation-maybe arg force) (gnus-article-hide-signature arg)) diff --git a/lisp/gnus-bcklg.el b/lisp/gnus-bcklg.el index 9badf94..a47a199 100644 --- a/lisp/gnus-bcklg.el +++ b/lisp/gnus-bcklg.el @@ -82,7 +82,9 @@ (setq b (point)) (insert-buffer-substring buffer) ;; Tag the beginning of the article with the ident. - (gnus-put-text-property b (1+ b) 'gnus-backlog ident)))))) + (if (> (point-max) b) + (gnus-put-text-property b (1+ b) 'gnus-backlog ident) + (gnus-error 3 "Article %d is blank" number))))))) (defun gnus-backlog-remove-oldest-article () (save-excursion diff --git a/lisp/gnus-cache.el b/lisp/gnus-cache.el index 0f009f3..9a3ce0f 100644 --- a/lisp/gnus-cache.el +++ b/lisp/gnus-cache.el @@ -394,7 +394,7 @@ Returns the list of articles removed." (erase-buffer) (let ((file (gnus-cache-file-name group ".overview"))) (when (file-exists-p file) - (mm-insert-file-contents file))) + (nnheader-insert-file-contents file))) ;; We have a fresh (empty/just loaded) buffer, ;; mark it as unmodified to save a redundant write later. (set-buffer-modified-p nil)))) diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index 5cd3cd8..5423962 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -2046,6 +2046,7 @@ and NEW-NAME will be prompted for." ((= char ?d) 'digest) ((= char ?f) 'forward) ((= char ?a) 'mmfd) + ((= char ?g) 'guess) (t (setq err (format "%c unknown. " char)) nil)))) (setq type found))) @@ -2679,10 +2680,11 @@ N and the number of steps taken is returned." (gnus-group-yank-group) (gnus-group-position-point))) -(defun gnus-group-kill-all-zombies () - "Kill all zombie newsgroups." - (interactive) - (when (gnus-yes-or-no-p "Really kill all zombies? ") +(defun gnus-group-kill-all-zombies (&optional dummy) + "Kill all zombie newsgroups. +The optional DUMMY should always be nil." + (interactive (list (not (gnus-yes-or-no-p "Really kill all zombies? ")))) + (unless dummy (setq gnus-killed-list (nconc gnus-zombie-list gnus-killed-list)) (setq gnus-zombie-list nil) (gnus-dribble-touch) diff --git a/lisp/gnus-mlspl.el b/lisp/gnus-mlspl.el index 8936bc5..716426e 100644 --- a/lisp/gnus-mlspl.el +++ b/lisp/gnus-mlspl.el @@ -38,8 +38,8 @@ default catch-all group") splitting, and defines the variable nnmail-split-fancy according with group parameters. -if AUTO-UPDATE is non-nil (prefix argument accepted, if called -interactive), makes sure nnmail-split-fancy is re-computed before +If AUTO-UPDATE is non-nil (prefix argument accepted, if called +interactively), it makes sure nnmail-split-fancy is re-computed before getting new mail, by adding gnus-group-split-update to nnmail-pre-get-new-mail-hook." (interactive "P") @@ -92,7 +92,7 @@ otherwise, a | split, that does not allow crossposting, will be returned. if CATCH-ALL is not nil, and there is no selected group whose -split-regexp matches the empty string, nor is there a selected group +SPLIT-REGEXP matches the empty string, nor is there a selected group whose SPLIT-SPEC is 'catch-all, this group name will be appended to the returned SPLIT list, as the last element in a '| SPLIT. @@ -121,10 +121,10 @@ nnml:mail.others: Calling (gnus-group-split-fancy nil nil \"mail.misc\") returns: \(| (& (any \"\\\\(bar@femail\\\\.com\\\\|.*@femail\\\\.com\\\\)\" - \"nnml:mail.bar\") + \"mail.bar\") (any \"\\\\(foo@nowhere\\\\.gov\\\\|foo@localhost\\\\|foo-redist@home\\\\)\" - - \"bugs-foo\" - \"rambling-foo\" \"nnml:mail.foo\")) - \"nnml:mail.others\")" + - \"bugs-foo\" - \"rambling-foo\" \"mail.foo\")) + \"mail.others\")" (let* ((newsrc (cdr gnus-newsrc-alist)) split) (dolist (info newsrc) diff --git a/lisp/gnus-score.el b/lisp/gnus-score.el index b9565bd..a599ea0 100644 --- a/lisp/gnus-score.el +++ b/lisp/gnus-score.el @@ -2853,7 +2853,9 @@ If ADAPT, return the home adaptive file instead." (when (string-match (gnus-globalify-regexp (car elem)) group) (replace-match (cadr elem) t nil group )))))) (when found - (nnheader-concat gnus-kill-files-directory found)))) + (if (file-name-absolute-p found) + found + (nnheader-concat gnus-kill-files-directory found))))) (defun gnus-hierarchial-home-score-file (group) "Return the score file of the top-level hierarchy of GROUP." diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index d3c68a3..ef27428 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -804,8 +804,8 @@ prompt the user for the name of an NNTP server to use." ;; Load whichever file is newest -- the auto save file ;; or the "real" file. (if (file-newer-than-file-p auto dribble-file) - (mm-insert-file-contents auto) - (mm-insert-file-contents dribble-file)) + (nnheader-insert-file-contents auto) + (nnheader-insert-file-contents dribble-file)) (unless (zerop (buffer-size)) (set-buffer-modified-p t)) ;; Set the file modes to reflect the .newsrc file modes. @@ -1828,7 +1828,7 @@ newsgroup." (gnus-group-prefixed-name "" method)))) ;; Let the Gnus agent save the active file. - (if (and gnus-agent real-active gnus-plugged) + (if (and gnus-agent real-active gnus-plugged (gnus-agent-method-p method)) (progn (gnus-agent-save-groups method) (gnus-active-to-gnus-format method hashtb nil real-active)) diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index 0b1c359..e46b3a4 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -542,6 +542,15 @@ with some simple extensions: :group 'gnus-summary-format :type 'string) +(defcustom gnus-list-identifiers nil + "Regexp that matches list identifiers to be removed from subject. +This can also be a list of regexps." + :group 'gnus-summary-format + :group 'gnus-article-hiding + :type '(choice (const :tag "none" nil) + (regexp :value ".*") + (repeat :value (".*") regexp))) + (defcustom gnus-summary-mark-below 0 "*Mark all articles with a score below this variable as read. This variable is local to each summary buffer and usually set by the @@ -802,6 +811,7 @@ which it may alter in any way.") ("^cn\\>\\|\\" cn-gb-2312) ("^fj\\>\\|^japan\\>" iso-2022-jp-2) ("^relcom\\>" koi8-r) + ("^fido7\\>" koi8-r) ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2) ("^israel\\>" iso-8859-1) ("^han\\>" euc-kr) @@ -853,6 +863,9 @@ This variable uses the same syntax as `gnus-emphasis-alist'." (defvar gnus-thread-indent-array nil) (defvar gnus-thread-indent-array-level gnus-thread-indent-level) +(defvar gnus-sort-gathered-threads-function 'gnus-thread-sort-by-number + "Function called to sort the articles within a thread after it has +been gathered together.") ;; Avoid highlighting in kill files. (defvar gnus-summary-inhibit-highlight nil) @@ -1502,6 +1515,7 @@ increase the score of each group you read." "s" gnus-article-hide-signature "c" gnus-article-hide-citation "C" gnus-article-hide-citation-in-followups + "l" gnus-article-hide-list-identifiers "p" gnus-article-hide-pgp "B" gnus-article-strip-banner "P" gnus-article-hide-pem @@ -1624,6 +1638,7 @@ increase the score of each group you read." ["Headers" gnus-article-hide-headers t] ["Signature" gnus-article-hide-signature t] ["Citation" gnus-article-hide-citation t] + ["List identifiers" gnus-article-hide-list-identifiers t] ["PGP" gnus-article-hide-pgp t] ["Banner" gnus-article-strip-banner t] ["Boring headers" gnus-article-hide-boring-headers t]) @@ -3008,7 +3023,7 @@ If NO-DISPLAY, don't generate a summary buffer." (while threads (when (stringp (caar threads)) (setcdr (car threads) - (sort (cdar threads) 'gnus-thread-sort-by-number))) + (sort (cdar threads) gnus-sort-gathered-threads-function))) (setq threads (cdr threads))) result)) @@ -4011,6 +4026,22 @@ or a straight list of headers." (cdr (assq number gnus-newsgroup-scored)) (memq number gnus-newsgroup-processable)))))) +(defun gnus-summary-remove-list-identifiers () + "Remove list identifiers in `gnus-list-identifiers' from articles in +the current group." + (let ((regexp (if (stringp gnus-list-identifiers) + gnus-list-identifiers + (mapconcat 'identity gnus-list-identifiers " *\\|")))) + (when regexp + (dolist (header gnus-newsgroup-headers) + (when (string-match (concat "\\(Re: +\\)?\\(" regexp " *\\)") + (mail-header-subject header)) + (mail-header-set-subject + header (concat (substring (mail-header-subject header) + 0 (match-beginning 2)) + (substring (mail-header-subject header) + (match-end 2))))))))) + (defun gnus-select-newsgroup (group &optional read-all select-articles) "Select newsgroup GROUP. If READ-ALL is non-nil, all articles in the group are selected. @@ -4130,6 +4161,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." ;; Let the Gnus agent mark articles as read. (when gnus-agent (gnus-agent-get-undownloaded-list)) + ;; Remove list identifiers from subject + (when gnus-list-identifiers + (gnus-summary-remove-list-identifiers)) ;; Check whether auto-expire is to be done in this group. (setq gnus-newsgroup-auto-expire (gnus-group-auto-expirable-p group)) @@ -4156,7 +4190,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." (zerop (length gnus-newsgroup-unreads))) (eq (gnus-group-find-parameter group 'display) 'all)) - (gnus-uncompress-range (gnus-active group)) + (or + (gnus-uncompress-range (gnus-active group)) + (gnus-cache-articles-in-group group)) (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked (copy-sequence gnus-newsgroup-unreads)) '<))) @@ -5280,7 +5316,8 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil." (unless quit-config ;; Do adaptive scoring, and possibly save score files. (when gnus-newsgroup-adaptive - (gnus-score-adaptive)) + (let ((gnus-newsgroup-adaptive gnus-use-adaptive-scoring)) + (gnus-score-adaptive))) (when gnus-use-scoring (gnus-score-save))) (gnus-run-hooks 'gnus-summary-prepare-exit-hook) @@ -6174,7 +6211,21 @@ If given a prefix, remove all limits." "Limit the summary buffer to articles that are older than (or equal) AGE days. If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to articles that are younger than AGE days." - (interactive "nLimit to articles older than (in days): \nP") + (interactive + (let ((younger current-prefix-arg) + (days-got nil) + days) + (while (not days-got) + (setq days (if younger + (read-string "Limit to articles within (in days): ") + (read-string "Limit to articles old than (in days): "))) + (when (> (length days) 0) + (setq days (read days))) + (if (numberp days) + (setq days-got t) + (message "Please enter a number.") + (sleep-for 1))) + (list days younger))) (prog1 (let ((data gnus-newsgroup-data) (cutoff (days-to-time age)) @@ -7268,8 +7319,9 @@ and `request-accept' functions." art-group)))))) (cond ((not art-group) - (gnus-message 1 "Couldn't %s article %s" - (cadr (assq action names)) article)) + (gnus-message 1 "Couldn't %s article %s: %s" + (cadr (assq action names)) article + (nnheader-get-report (car to-method)))) ((and (eq art-group 'junk) (eq action 'move)) (gnus-summary-mark-article article gnus-canceled-mark) diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index aacb877..c998a65 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -688,7 +688,7 @@ with potentially long computations." ;; Decide whether to append to a file or to an Emacs buffer. (let ((outbuf (get-file-buffer filename))) (if (not outbuf) - (append-to-file (point-min) (point-max) filename) + (mm-append-to-file (point-min) (point-max) filename) ;; File has been visited, in buffer OUTBUF. (set-buffer outbuf) (let ((buffer-read-only nil) @@ -756,7 +756,7 @@ with potentially long computations." (insert "\n")) (insert "\n")) (goto-char (point-max)) - (append-to-file (point-min) (point-max) filename))) + (mm-append-to-file (point-min) (point-max) filename))) ;; File has been visited, in buffer OUTBUF. (set-buffer outbuf) (let ((buffer-read-only nil)) diff --git a/lisp/gnus-uu.el b/lisp/gnus-uu.el index 2380ecb..a765241 100644 --- a/lisp/gnus-uu.el +++ b/lisp/gnus-uu.el @@ -527,6 +527,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (gnus-get-buffer-create " *gnus-uu-forward*"))) (erase-buffer) (insert-file file) + (delete-file file) (let ((fs gnus-uu-digest-from-subject)) (when fs (setq from (caar fs) @@ -955,7 +956,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (beginning-of-line) (forward-line 1) (when (file-exists-p gnus-uu-binhex-article-name) - (append-to-file start-char (point) gnus-uu-binhex-article-name)))) + (mm-append-to-file start-char (point) gnus-uu-binhex-article-name)))) (if (memq 'begin state) (cons gnus-uu-binhex-article-name state) state))) diff --git a/lisp/gnus.el b/lisp/gnus.el index 6b317de..437615e 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -260,7 +260,7 @@ is restarted, and sometimes reloaded." :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) -(defconst gnus-version-number "0.95" +(defconst gnus-version-number "0.96" "Version number for this version of Gnus.") (defconst gnus-version (format "Pterodactyl Gnus v%s" gnus-version-number) diff --git a/lisp/message.el b/lisp/message.el index 6e45b2a..0a32d12 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -1030,7 +1030,7 @@ The cdr of ech entry is a function for applying the face to a region.") (file-readable-p file) (file-regular-p file)) (with-temp-buffer - (mm-insert-file-contents file) + (nnheader-insert-file-contents file) (goto-char (point-min)) (looking-at message-unix-mail-delimiter)))) diff --git a/lisp/mm-bodies.el b/lisp/mm-bodies.el index 1107947..3ced083 100644 --- a/lisp/mm-bodies.el +++ b/lisp/mm-bodies.el @@ -168,6 +168,7 @@ If no encoding was done, nil is returned." (save-excursion (goto-char (point-max)) (skip-chars-backward "\n\t ") + (delete-region (point) (point-max)) (point)))) ((memq encoding '(7bit 8bit binary)) ) diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index 0b5f57f..a658324 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -566,15 +566,10 @@ external if displayed external." (defun mm-save-part-to-file (handle file) (mm-with-unibyte-buffer (mm-insert-part handle) - ;; Now every coding system is 100% binary within mm-with-unibyte-buffer - ;; Is text still special? - (let ((coding-system-for-write - (if (equal "text" (mm-handle-media-supertype handle)) - buffer-file-coding-system - 'binary)) + (let ((coding-system-for-write 'binary) ;; Don't re-compress .gz & al. Arguably we should make ;; `file-name-handler-alist' nil, but that would chop - ;; ange-ftp which it's reasonable to use here. + ;; ange-ftp, which is reasonable to use here. (inhibit-file-name-operation 'write-region) (inhibit-file-name-handlers (if (equal (mm-handle-media-type handle) diff --git a/lisp/mm-encode.el b/lisp/mm-encode.el index d2de87d..908161a 100644 --- a/lisp/mm-encode.el +++ b/lisp/mm-encode.el @@ -132,18 +132,18 @@ The encoding used is returned." (let ((8bit 0)) (cond ((not (featurep 'mule)) - (while (re-search-forward "[^\x00-\x7f]" nil t) + (while (re-search-forward "[^\x20-\x7f\r\n\t]" nil t) (incf 8bit))) (t ;; Mule version (while (not (eobp)) - (skip-chars-forward "\0-\177") + (skip-chars-forward "\x20-\x7f\r\n\t") (unless (eobp) (forward-char 1) (incf 8bit))))) (if (> (/ (* 8bit 1.0) (buffer-size)) 0.166) - 'quoted-printable - 'base64))))) + 'base64 + 'quoted-printable))))) (provide 'mm-encode) diff --git a/lisp/mm-util.el b/lisp/mm-util.el index a8e8f8b..58131ac 100644 --- a/lisp/mm-util.el +++ b/lisp/mm-util.el @@ -24,19 +24,6 @@ ;;; Code: -(defconst mm-running-xemacs (string-match "XEmacs" emacs-version)) - -(defconst mm-binary-coding-system - (if mm-running-xemacs - 'binary 'no-conversion) - "100% binary coding system.") - -(defconst mm-text-coding-system - (and (fboundp 'coding-system-list) - (if (memq system-type '(windows-nt ms-dos ms-windows)) - 'raw-text-dos 'raw-text)) - "Text-safe coding system (For removing ^M).") - (defvar mm-mime-mule-charset-alist '((us-ascii ascii) (iso-8859-1 latin-iso8859-1) @@ -84,8 +71,8 @@ (lambda (elem) (let ((nfunc (intern (format "mm-%s" (car elem))))) (if (fboundp (car elem)) - (fset nfunc (car elem)) - (fset nfunc (cdr elem))))) + (defalias nfunc (car elem)) + (defalias nfunc (cdr elem))))) '((decode-coding-string . (lambda (s a) s)) (encode-coding-string . (lambda (s a) s)) (encode-coding-region . ignore) @@ -118,16 +105,37 @@ (x-ctext . ctext)) "A mapping from invalid charset names to the real charset names.") -(defconst mm-auto-save-coding-system +(defun mm-coding-system-p (sym) + "Return non-nil if SYM is a coding system." + (or (and (fboundp 'coding-system-p) (coding-system-p sym)) + (memq sym (mm-get-coding-system-list)))) + +(defvar mm-binary-coding-system (cond - ((memq 'emacs-mule (mm-get-coding-system-list)) - (if (memq system-type '(windows-nt ms-dos ms-windows)) - 'emacs-mule-dos 'emacs-mule)) - ((memq 'escape-quoted (mm-get-coding-system-list)) - 'escape-quoted) - ((memq 'no-conversion (mm-get-coding-system-list)) - 'no-conversion) + ((mm-coding-system-p 'no-conversion) 'no-conversion) + ((mm-coding-system-p 'binary) 'binary) (t nil)) + "100% binary coding system.") + +(defvar mm-text-coding-system + (or (if (memq system-type '(windows-nt ms-dos ms-windows)) + (and (mm-coding-system-p 'raw-text-dos) 'raw-text-dos) + (and (mm-coding-system-p 'raw-text) 'raw-text)) + mm-binary-coding-system) + "Text-safe coding system (For removing ^M).") + +(defvar mm-text-coding-system-for-write nil + "Text coding system for write.") + +(defvar mm-auto-save-coding-system + (cond + ((mm-coding-system-p 'emacs-mule) + (if (memq system-type '(windows-nt ms-dos ms-windows)) + (if (mm-coding-system-p 'emacs-mule-dos) + 'emacs-mule-dos mm-binary-coding-system) + 'emacs-mule)) + ((mm-coding-system-p 'escape-quoted) 'escape-quoted) + (t mm-binary-coding-system)) "Coding system of auto save file.") ;;; Internal variables: @@ -317,21 +325,74 @@ See also `with-temp-file' and `with-output-to-string'." (pop alist)) (nreverse out))) -(defun mm-insert-file-contents (filename &optional visit beg end replace) +(defvar mm-inhibit-file-name-handlers + '(jka-compr-handler) + "A list of handlers doing (un)compression (etc) thingies.") + +(defun mm-insert-file-contents (filename &optional visit beg end replace + inhibit) "Like `insert-file-contents', q.v., but only reads in the file. A buffer may be modified in several ways after reading into the buffer due to advanced Emacs features, such as file-name-handlers, format decoding, find-file-hooks, etc. +If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers. This function ensures that none of these modifications will take place." (let ((format-alist nil) - (auto-mode-alist (mm-auto-mode-alist)) + (auto-mode-alist (if inhibit nil (mm-auto-mode-alist))) (default-major-mode 'fundamental-mode) (enable-local-variables nil) (after-insert-file-functions nil) (enable-local-eval nil) - (find-file-hooks nil)) + (find-file-hooks nil) + (inhibit-file-name-operation (if inhibit + 'insert-file-contents + inhibit-file-name-operation)) + (inhibit-file-name-handlers + (if inhibit + (append mm-inhibit-file-name-handlers + inhibit-file-name-handlers) + inhibit-file-name-handlers))) (insert-file-contents filename visit beg end replace))) +(defun mm-append-to-file (start end filename &optional codesys inhibit) + "Append the contents of the region to the end of file FILENAME. +When called from a function, expects three arguments, +START, END and FILENAME. START and END are buffer positions +saying what text to write. +Optional fourth argument specifies the coding system to use when +encoding the file. +If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." + (let ((coding-system-for-write + (or codesys mm-text-coding-system-for-write + mm-text-coding-system)) + (inhibit-file-name-operation (if inhibit + 'append-to-file + inhibit-file-name-operation)) + (inhibit-file-name-handlers + (if inhibit + (append mm-inhibit-file-name-handlers + inhibit-file-name-handlers) + inhibit-file-name-handlers))) + (append-to-file start end filename))) + +(defun mm-write-region (start end filename &optional append visit lockname + coding-system inhibit) + + "Like `write-region'. +If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." + (let ((coding-system-for-write + (or coding-system mm-text-coding-system-for-write + mm-text-coding-system)) + (inhibit-file-name-operation (if inhibit + 'write-region + inhibit-file-name-operation)) + (inhibit-file-name-handlers + (if inhibit + (append mm-inhibit-file-name-handlers + inhibit-file-name-handlers) + inhibit-file-name-handlers))) + (write-region start end filename append visit lockname))) + (provide 'mm-util) ;;; mm-util.el ends here diff --git a/lisp/mm-uu.el b/lisp/mm-uu.el index 8d3ff3b..6262930 100644 --- a/lisp/mm-uu.el +++ b/lisp/mm-uu.el @@ -82,7 +82,7 @@ decoder, such as hexbin." ;;; Thanks to Edward J. Sabol and ;;; Peter von der Ah\'e (defconst mm-uu-forward-begin-line "^-+ \\(?:Start of \\)?Forwarded message") -(defconst mm-uu-forward-end-line "^-+ End of forwarded message") +(defconst mm-uu-forward-end-line "^-+ End\\(?: of\\)? forwarded message") (defvar mm-uu-begin-line nil) @@ -146,7 +146,10 @@ To disable dissecting shar codes, for instance, add (if (stringp cte) (setq cte (intern (downcase (mail-header-remove-whitespace (mail-header-remove-comments - cte))))))) + cte)))))) + (if (eq cte 'base64) + (setq charset 'gnus-encoded ;; a fake charset + cte nil))) (goto-char (point-max))) (forward-line) (setq text-start (point) @@ -170,7 +173,9 @@ To disable dissecting shar codes, for instance, add (intern (concat "mm-uu-" (symbol-name type) "-end-line")))) (when (and (re-search-forward end-line nil t) - (not (eq (match-beginning 0) (match-end 0)))) + (not (eq (match-beginning 0) (match-end 0))) + ;; Do not dissect base64 forward. + (not (and (eq charset 'gnus-encoded) (eq type 'forward)))) (setq end-char-1 (match-beginning 0)) (forward-line) (setq end-char (point)) diff --git a/lisp/mm-view.el b/lisp/mm-view.el index 19e017a..4d00c52 100644 --- a/lisp/mm-view.el +++ b/lisp/mm-view.el @@ -81,10 +81,12 @@ (save-restriction (narrow-to-region b (point)) (goto-char (point-min)) - (if (or (re-search-forward - w3-meta-content-type-charset-regexp nil t) - (re-search-forward - w3-meta-charset-content-type-regexp nil t)) + (if (or (and (boundp 'w3-meta-content-type-charset-regexp) + (re-search-forward + w3-meta-content-type-charset-regexp nil t)) + (and (boundp 'w3-meta-charset-content-type-regexp) + (re-search-forward + w3-meta-charset-content-type-regexp nil t))) (setq charset (w3-coding-system-for-mime-charset (buffer-substring-no-properties (match-beginning 2) diff --git a/lisp/mml.el b/lisp/mml.el index 286c8e4..9f4ed01 100644 --- a/lisp/mml.el +++ b/lisp/mml.el @@ -229,7 +229,7 @@ (insert-buffer-substring (cdr (assq 'buffer cont)))) ((and (setq filename (cdr (assq 'filename cont))) (not (equal (cdr (assq 'nofile cont)) "yes"))) - (mm-insert-file-contents filename)) + (mm-insert-file-contents filename nil nil nil nil t)) (t (insert (cdr (assq 'contents cont))))) (setq encoding (mm-encode-buffer type) @@ -430,7 +430,7 @@ "Translate the current buffer from MML to MIME." (message-encode-message-body) (save-restriction - (message-narrow-to-headers) + (message-narrow-to-headers-or-head) (mail-encode-encoded-word-buffer))) (defun mml-insert-mime (handle &optional no-markup) @@ -449,7 +449,10 @@ (mapcar 'mml-insert-mime (cdr handle)) (insert "<#/multipart>\n")) (textp - (mm-insert-part handle) + (let ((text (mm-get-part handle)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset))) + (insert (mm-decode-string text charset))) (goto-char (point-max))) (t (insert "<#/part>\n"))))) diff --git a/lisp/nndoc.el b/lisp/nndoc.el index e2f9be8..66e24cb 100644 --- a/lisp/nndoc.el +++ b/lisp/nndoc.el @@ -290,7 +290,7 @@ from the document.") (mm-enable-multibyte) (erase-buffer) (if (stringp nndoc-address) - (mm-insert-file-contents nndoc-address) + (nnheader-insert-file-contents nndoc-address) (insert-buffer-substring nndoc-address)) (run-hooks 'nndoc-open-document-hook)))) ;; Initialize the nndoc structures according to this new document. diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el index b79299c..a45f4f7 100644 --- a/lisp/nnfolder.el +++ b/lisp/nnfolder.el @@ -295,39 +295,64 @@ If NIL, NNFOLDER-FILE-CODING-SYSTEM is used.") (let ((nnmail-file-coding-system nnfolder-file-coding-system)) (nnmail-find-file nnfolder-newsgroups-file)))) +;; Return a list consisting of all article numbers existing in the +;; current folder. + +(defun nnfolder-existing-articles () + (save-excursion + (when nnfolder-current-buffer + (set-buffer nnfolder-current-buffer) + (goto-char (point-min)) + (let ((marker (concat "\n" nnfolder-article-marker)) + (number "[0-9]+") + numbers) + + (while (and (search-forward marker nil t) + (re-search-forward number nil t)) + (let ((newnum (string-to-number (match-string 0)))) + (if (nnmail-within-headers-p) + (push newnum numbers)))) + numbers)))) + (deffoo nnfolder-request-expire-articles (articles newsgroup &optional server force) (nnfolder-possibly-change-group newsgroup server) (let* ((is-old t) - rest) + ;; The articles we have deleted so far. + (deleted-articles nil) + ;; The articles that really exist and will be expired if they are old enough. + (maybe-expirable (gnus-intersection articles (nnfolder-existing-articles)))) (nnmail-activate 'nnfolder) (save-excursion (set-buffer nnfolder-current-buffer) - (while (and articles is-old) + ;; Since messages are sorted in arrival order and expired in the + ;; same order, we can stop as soon as we find a message that is + ;; too old. + (while (and maybe-expirable is-old) (goto-char (point-min)) - (when (and (nnfolder-goto-article (car articles)) + (when (and (nnfolder-goto-article (car maybe-expirable)) (search-forward (concat "\n" nnfolder-article-marker) nil t)) (forward-sexp) - (if (setq is-old + (when (setq is-old (nnmail-expired-article-p newsgroup (buffer-substring (point) (progn (end-of-line) (point))) force nnfolder-inhibit-expiry)) - (progn (nnheader-message 5 "Deleting article %d..." - (car articles) newsgroup) - (nnfolder-delete-mail)) - (push (car articles) rest))) - (setq articles (cdr articles))) + (car maybe-expirable) newsgroup) + (nnfolder-delete-mail) + ;; Must remember which articles were actually deleted + (push (car maybe-expirable) deleted-articles))) + (setq maybe-expirable (cdr maybe-expirable))) (unless nnfolder-inhibit-expiry (nnheader-message 5 "Deleting articles...done")) (nnfolder-save-buffer) (nnfolder-adjust-min-active newsgroup) (nnfolder-save-active nnfolder-group-alist nnfolder-active-file) - (nconc rest articles)))) + (gnus-sorted-complement articles (nreverse deleted-articles))))) (deffoo nnfolder-request-move-article (article group server accept-form &optional last) diff --git a/lisp/nnheader.el b/lisp/nnheader.el index 696f7c9..d378f03 100644 --- a/lisp/nnheader.el +++ b/lisp/nnheader.el @@ -471,12 +471,12 @@ the line could be found." (when (file-exists-p file) (if (eq nnheader-max-head-length t) ;; Just read the entire file. - (mm-insert-file-contents file) + (nnheader-insert-file-contents file) ;; Read 1K blocks until we find a separator. (let ((beg 0) format-alist) (while (and (eq nnheader-head-chop-length - (nth 1 (mm-insert-file-contents + (nth 1 (nnheader-insert-file-contents file nil beg (incf beg nnheader-head-chop-length)))) (prog1 (not (search-forward "\n\n" nil t)) @@ -765,25 +765,18 @@ If FILE, find the \".../etc/PACKAGE\" file instead." (defvar nnheader-file-coding-system 'raw-text "Coding system used in file backends of Gnus.") -(defun mm-insert-file-contents (filename &optional visit beg end replace) +(defun nnheader-insert-file-contents (filename &optional visit beg end replace) "Like `insert-file-contents', q.v., but only reads in the file. A buffer may be modified in several ways after reading into the buffer due to advanced Emacs features, such as file-name-handlers, format decoding, find-file-hooks, etc. This function ensures that none of these modifications will take place." - (let ((format-alist nil) - (auto-mode-alist (nnheader-auto-mode-alist)) - (default-major-mode 'fundamental-mode) - (enable-local-variables nil) - (after-insert-file-functions nil) - (enable-local-eval nil) - (find-file-hooks nil) - (coding-system-for-read nnheader-file-coding-system)) - (insert-file-contents filename visit beg end replace))) + (let ((coding-system-for-read nnheader-file-coding-system)) + (mm-insert-file-contents filename visit beg end replace))) (defun nnheader-find-file-noselect (&rest args) (let ((format-alist nil) - (auto-mode-alist (nnheader-auto-mode-alist)) + (auto-mode-alist (mm-auto-mode-alist)) (default-major-mode 'fundamental-mode) (enable-local-variables nil) (after-insert-file-functions nil) @@ -792,16 +785,6 @@ find-file-hooks, etc. (coding-system-for-read nnheader-file-coding-system)) (apply 'find-file-noselect args))) -(defun nnheader-auto-mode-alist () - "Return an `auto-mode-alist' with only the .gz (etc) thingies." - (let ((alist auto-mode-alist) - out) - (while alist - (when (listp (cdar alist)) - (push (car alist) out)) - (pop alist)) - (nreverse out))) - (defun nnheader-directory-regular-files (dir) "Return a list of all regular files in DIR." (let ((files (directory-files dir t)) diff --git a/lisp/nnkiboze.el b/lisp/nnkiboze.el index 8818e50..3211d69 100644 --- a/lisp/nnkiboze.el +++ b/lisp/nnkiboze.el @@ -80,7 +80,7 @@ (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) - (mm-insert-file-contents nov) + (nnheader-insert-file-contents nov) (nnheader-nov-delete-outside-range (car articles) (car (last articles))) 'nov)))))) @@ -119,7 +119,7 @@ (nnkiboze-request-scan group)) (if (not (file-exists-p nov-file)) (nnheader-report 'nnkiboze "Can't select group %s" group) - (mm-insert-file-contents nov-file) + (nnheader-insert-file-contents nov-file) (if (zerop (buffer-size)) (nnheader-insert "211 0 0 0 %s\n" group) (goto-char (point-min)) @@ -138,7 +138,7 @@ nnkiboze-remove-read-articles) (with-temp-file (nnkiboze-nov-file-name) (let ((cur (current-buffer))) - (mm-insert-file-contents (nnkiboze-nov-file-name)) + (nnheader-insert-file-contents (nnkiboze-nov-file-name)) (goto-char (point-min)) (while (not (eobp)) (if (not (gnus-article-read-p (read cur))) diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 9af078b..935b929 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -453,7 +453,7 @@ parameter. It should return nil, `warn' or `delete'." (after-insert-file-functions nil)) (condition-case () (let ((coding-system-for-read nnmail-file-coding-system) - (auto-mode-alist (nnheader-auto-mode-alist)) + (auto-mode-alist (mm-auto-mode-alist)) (pathname-coding-system nnmail-pathname-coding-system)) (insert-file-contents file) t) @@ -849,7 +849,7 @@ FUNC will be called with the buffer narrowed to each mail." ;; Insert the incoming file. (set-buffer (get-buffer-create " *nnmail incoming*")) (erase-buffer) - (let ((nnheader-file-coding-system nnmail-incoming-coding-system)) + (let ((coding-system-for-read nnmail-incoming-coding-system)) (mm-insert-file-contents incoming)) (prog1 (if (zerop (buffer-size)) @@ -1040,11 +1040,11 @@ Return the number of characters in the body." (defun nnmail-remove-list-identifiers () "Remove list identifiers from Subject headers." (let ((regexp (if (stringp nnmail-list-identifiers) nnmail-list-identifiers - (mapconcat 'identity nnmail-list-identifiers "\\|")))) + (mapconcat 'identity nnmail-list-identifiers " *\\|")))) (when regexp (goto-char (point-min)) (when (re-search-forward - (concat "^Subject: +\\(Re: +\\)?\\(" regexp "\\) *") + (concat "^Subject: +\\(Re: +\\)?\\(" regexp " *\\)") nil t) (delete-region (match-beginning 2) (match-end 0)))))) @@ -1274,7 +1274,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (setq nnmail-cache-buffer (get-buffer-create " *nnmail message-id cache*"))) (when (file-exists-p nnmail-message-id-cache-file) - (mm-insert-file-contents nnmail-message-id-cache-file)) + (nnheader-insert-file-contents nnmail-message-id-cache-file)) (set-buffer-modified-p nil) (current-buffer)))) @@ -1447,7 +1447,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (incf total new) (incf i)))) ;; If we did indeed read any incoming spools, we save all info. - (unless (zerop total) + (if (zerop total) + (nnheader-message 4 "%s: Reading incoming mail (no new mail)...done" + method (car source)) (nnmail-save-active (nnmail-get-value "%s-group-alist" method) (nnmail-get-value "%s-active-file" method)) diff --git a/lisp/nnml.el b/lisp/nnml.el index 5429682..b9b2661 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -463,7 +463,7 @@ all. This may very well take some time.") (nnheader-report 'nnml "File %s does not exist" file)) (t (with-temp-file file - (mm-insert-file-contents file) + (nnheader-insert-file-contents file) (nnmail-replace-status name value)) t)))) @@ -519,7 +519,7 @@ all. This may very well take some time.") nnml-nov-file-name)) number found) (when (file-exists-p nov) - (mm-insert-file-contents nov) + (nnheader-insert-file-contents nov) (while (and (not found) (search-forward id nil t)) ; We find the ID. ;; And the id is in the fourth field. @@ -541,7 +541,7 @@ all. This may very well take some time.") (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) - (mm-insert-file-contents nov) + (nnheader-insert-file-contents nov) (if (and fetch-old (not (numberp fetch-old))) t ; Don't remove anything. @@ -677,7 +677,7 @@ all. This may very well take some time.") nnml-nov-file-name)) (erase-buffer) (when (file-exists-p nnml-nov-buffer-file-name) - (mm-insert-file-contents nnml-nov-buffer-file-name))) + (nnheader-insert-file-contents nnml-nov-buffer-file-name))) (push (cons group buffer) nnml-nov-buffer-alist) buffer))) @@ -767,7 +767,7 @@ all. This may very well take some time.") (while files (unless (file-directory-p (setq file (concat dir (cdar files)))) (erase-buffer) - (mm-insert-file-contents file) + (nnheader-insert-file-contents file) (narrow-to-region (goto-char (point-min)) (progn diff --git a/lisp/nnsoup.el b/lisp/nnsoup.el index 22c22da..031c0ac 100644 --- a/lisp/nnsoup.el +++ b/lisp/nnsoup.el @@ -535,7 +535,7 @@ backend for the messages.") (set-buffer (get-buffer-create buffer-name)) (buffer-disable-undo) (push (cons nnsoup-current-group (current-buffer)) nnsoup-buffers) - (mm-insert-file-contents (concat nnsoup-directory file)) + (nnheader-insert-file-contents (concat nnsoup-directory file)) (current-buffer)))))) (defun nnsoup-file (prefix &optional message) @@ -752,7 +752,7 @@ backend for the messages.") (while files (nnheader-message 5 "Doing %s..." (car files)) (erase-buffer) - (mm-insert-file-contents (car files)) + (nnheader-insert-file-contents (car files)) (goto-char (point-min)) (if (not (re-search-forward "^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t *\\(Xref: \\)? *[^ ]* \\([^ ]+\\):[0-9]" nil t)) (setq group "unknown") diff --git a/lisp/nnspool.el b/lisp/nnspool.el index 2f5ee8c..59dce98 100644 --- a/lisp/nnspool.el +++ b/lisp/nnspool.el @@ -366,7 +366,7 @@ there.") (erase-buffer) (if nnspool-sift-nov-with-sed (nnspool-sift-nov-with-sed articles nov) - (mm-insert-file-contents nov) + (nnheader-insert-file-contents nov) (if (and fetch-old (not (numberp fetch-old))) t ; We want all the headers. @@ -438,7 +438,7 @@ there.") (set-buffer nntp-server-buffer) (erase-buffer) (condition-case () - (let ((nnheader-file-coding-system nnspool-file-coding-system)) + (let ((coding-system-for-read nnspool-file-coding-system)) (mm-insert-file-contents file) t) (file-error nil))) diff --git a/lisp/nntp.el b/lisp/nntp.el index 8b778d8..32f3a39 100644 --- a/lisp/nntp.el +++ b/lisp/nntp.el @@ -292,6 +292,11 @@ noticing asynchronous data.") (unless discard (erase-buffer))))) +(defun nntp-kill-buffer (buffer) + (when (buffer-name buffer) + (kill-buffer buffer) + (nnheader-init-server-buffer))) + (defsubst nntp-find-connection (buffer) "Find the connection delivering to BUFFER." (let ((alist nntp-connection-alist) @@ -304,8 +309,7 @@ noticing asynchronous data.") (when process (if (memq (process-status process) '(open run)) process - (when (buffer-name (process-buffer process)) - (kill-buffer (process-buffer process))) + (nntp-kill-buffer (process-buffer process)) (setq nntp-connection-alist (delq entry nntp-connection-alist)) nil)))) @@ -696,8 +700,7 @@ noticing asynchronous data.") ;; QUIT command actually is sent out before we kill ;; the process. (sleep-for 1)))) - (when (buffer-name (process-buffer process)) - (kill-buffer (process-buffer process))) + (nntp-kill-buffer (process-buffer process)) (setq process (car (pop nntp-connection-alist)))) (nnoo-close-server 'nntp))) @@ -713,8 +716,7 @@ noticing asynchronous data.") ;; QUIT command actually is sent out before we kill ;; the process. (sleep-for 1)))) - (when (buffer-name (process-buffer process)) - (kill-buffer (process-buffer process)))))) + (nntp-kill-buffer (process-buffer process))))) (deffoo nntp-request-list (&optional server) (nntp-possibly-change-group nil server) @@ -846,8 +848,7 @@ password contained in '~/.nntp-authinfo'." (nnheader-run-at-time nntp-connection-timeout nil `(lambda () - (when (buffer-name ,pbuffer) - (kill-buffer ,pbuffer)))))) + (nntp-kill-buffer ,pbuffer))))) (process (condition-case () (let ((coding-system-for-read nntp-coding-system-for-read) @@ -873,8 +874,7 @@ password contained in '~/.nntp-authinfo'." (let ((nnheader-callback-function nil)) (run-hooks 'nntp-server-opened-hook) (nntp-send-authinfo t)))) - (when (buffer-name (process-buffer process)) - (kill-buffer (process-buffer process))) + (nntp-kill-buffer (process-buffer process)) nil)))) (defun nntp-open-network-stream (buffer) diff --git a/lisp/nnweb.el b/lisp/nnweb.el index 843e220..97c7cd0 100644 --- a/lisp/nnweb.el +++ b/lisp/nnweb.el @@ -228,7 +228,7 @@ and `altavista'.") "Read the overview of GROUP and build the map." (when (file-exists-p (nnweb-overview-file group)) (with-temp-buffer - (mm-insert-file-contents (nnweb-overview-file group)) + (nnheader-insert-file-contents (nnweb-overview-file group)) (goto-char (point-min)) (let (header) (while (not (eobp)) diff --git a/lisp/smiley.el b/lisp/smiley.el index a05d47f..610b130 100644 --- a/lisp/smiley.el +++ b/lisp/smiley.el @@ -65,7 +65,7 @@ ("\\(:-*[)>}»]+\\)\\W" 1 "FaceHappy.xpm") ("\\(=[)»]+\\)\\W" 1 "FaceHappy.xpm") ("\\(:-*[/\\\"]\\)[^/]\\W" 1 "FaceIronic.xpm") - ("\\([8|]-*[|Oo%]\\)\\W" 1 "FaceKOed.xpm") + ("[^.0-9]\\([8|]-*[|Oo%]\\)\\W" 1 "FaceKOed.xpm") ("\\([:|]-*#+\\)\\W" 1 "FaceNyah.xpm") ("\\(:-*[({]+\\)\\W" 1 "FaceSad.xpm") ("\\(=[({]+\\)\\W" 1 "FaceSad.xpm") diff --git a/texi/ChangeLog b/texi/ChangeLog index 42c9e20..152302f 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,24 @@ +1999-08-27 15:09:01 Jim Meyering + + * gnus.texi (The Active File): Typo fix. + +1999-08-27 15:00:23 Yoshiki Hayashi + + * gnus.texi (Generic Marking Commands): Typo fixes. + +1999-08-27 14:46:21 Lee Willis + + * gnus.texi (Customizing Articles): More explanation. + +1999-07-10 Mike McEwan + + * gnus.texi (More Threading): Document new variable + `gnus-sort-gathered-threads-function'. + +1999-07-30 Simon Josefsson + + * gnus.texi: Added `gnus-list-identifiers' stuff. + 1999-07-09 19:41:34 Lars Magne Ingebrigtsen * gnus.texi (Using MIME): Addition. diff --git a/texi/gnus.texi b/texi/gnus.texi index 93f8e06..1cacdac 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -1,7 +1,7 @@ @c \input texinfo @c -*-texinfo-*- @setfilename gnus -@settitle Pterodactyl Gnus 0.95 Manual +@settitle Pterodactyl Gnus 0.96 Manual @synindex fn cp @synindex vr cp @synindex pg cp @@ -319,7 +319,7 @@ into another language, under the above conditions for modified versions. @tex @titlepage -@title Pterodactyl Gnus 0.95 Manual +@title Pterodactyl Gnus 0.96 Manual @author by Lars Magne Ingebrigtsen @page @@ -355,7 +355,7 @@ can be gotten by any nefarious means you can think of---@sc{nntp}, local spool or your mbox file. All at the same time, if you want to push your luck. -This manual corresponds to Pterodactyl Gnus 0.95. +This manual corresponds to Pterodactyl Gnus 0.96. @end ifinfo @@ -995,7 +995,7 @@ is certainly faster than @code{t} over slow lines. Some news servers (Leafnode and old versions of INN, for instance) do not support the @code{LIST ACTIVE group}. For these servers, @code{nil} -is probably the most effficient value for this variable. +is probably the most efficient value for this variable. If this variable is @code{nil}, Gnus will ask for group info in total lock-step, which isn't very fast. If it is @code{some} and you use an @@ -2396,7 +2396,7 @@ Sort the group buffer alphabetically by backend name @end table -All the commands below obeys the process/prefix convention +All the commands below obey the process/prefix convention (@pxref{Process/Prefix}). When given a symbolic prefix (@pxref{Symbolic Prefixes}), all these @@ -3344,7 +3344,7 @@ The following format specification characters are understood: @item N Article number. @item S -Subject string. +Subject string. List identifiers stripped, @code{gnus-list-identifies}. @xref{Article Hiding}. @item s Subject if the article is the root of the thread or the previous article had a different subject, @code{gnus-summary-same-subject} otherwise. @@ -4532,7 +4532,7 @@ The default is @code{t}. Some people would like the command that ticks an article (@kbd{!}) go to the next article. Others would like it to go to the next unread article. Yet others would like it to stay on the current article. And -even though I haven't heard of anybody wanting it to go the the +even though I haven't heard of anybody wanting it to go to the previous (unread) article, I'm sure there are people that want that as well. @@ -4547,7 +4547,7 @@ to list in this manual. While you can use these commands directly, most users would prefer altering the summary mode keymap. For instance, if you would like the -@kbd{!} command to go the the next article instead of the next unread +@kbd{!} command to go to the next article instead of the next unread article, you could say something like: @lisp @@ -5126,6 +5126,18 @@ in a new thread. This is a number that says how much each sub-thread should be indented. The default is 4. +@item gnus-sort-gathered-threads-function +@vindex gnus-sort-gathered-threads-function +Sometimes, particularly with mailing lists, the order in which mails +arrive locally is not necessarily the same as the order in which they +arrived on the mailing list. Consequently, when sorting sub-threads +using the default @code{gnus-thread-sort-by-number}, responses can end +up appearing before the article to which they are responding to. Setting +this variable to an alternate value +(e.g. @code{gnus-thread-sort-by-date}), in a group's parameters or in an +appropriate hook (e.g. @code{gnus-summary-generate-hook}) can produce a +more logical sub-thread ordering in such instances. + @end table @@ -6509,6 +6521,23 @@ Hide headers that aren't particularly interesting Hide signature (@code{gnus-article-hide-signature}). @xref{Article Signature}. +@item W W l +@kindex W W l (Summary) +@findex gnus-article-hide-list-identifiers +@vindex gnus-list-identifiers +Hide list identifiers specified in @code{gnus-list-identifiers}. Theese +are strings some list servers add to the beginning of all @code{Subject} +headers---for example, @samp{[zebra 4711]}. + +@table @code + +@item gnus-list-identifiers +@vindex gnus-list-identifiers +A regular expression that matches list identifiers to be removed from +subject. This can also be a list of regular expressions. + +@end table + @item W W p @kindex W W p (Summary) @findex gnus-article-hide-pgp @@ -6705,7 +6734,7 @@ Fill long lines (@code{gnus-article-fill-long-lines}). @item W C @kindex W C (Summary) -@findex gnus-article-capitalize-sentencse +@findex gnus-article-capitalize-sentences Capitalize the first word in each sentence (@code{gnus-article-capitalize-sentences}). @@ -8394,6 +8423,9 @@ To have them called automatically, you should set the corresponding @code{gnus-treat-hide-headers}. Below is a list of variables that can be set, but first we discuss the values these variables can have. +Note: Some values, while valid, make little sense. Check the list below +for sensible values. + @enumerate @item @code{nil}: Don't do this treatment. @@ -8445,38 +8477,39 @@ controlling variable is a predicate list, as described above. The following treatment options are available. The easiest way to customize this is to examine the @code{gnus-article-treat} customization -group. +group. Values in brackets are suggested sensible values. Others are possible +but those listed are probably sufficient for most people. @table @code -@item gnus-treat-highlight-signature -@item gnus-treat-buttonize -@item gnus-treat-buttonize-head -@item gnus-treat-emphasize -@item gnus-treat-fill-article -@item gnus-treat-strip-cr -@item gnus-treat-hide-headers -@item gnus-treat-hide-boring-headers -@item gnus-treat-hide-signature -@item gnus-treat-hide-citation -@item gnus-treat-strip-pgp -@item gnus-treat-strip-pem -@item gnus-treat-highlight-headers -@item gnus-treat-highlight-citation -@item gnus-treat-highlight-signature -@item gnus-treat-date-ut -@item gnus-treat-date-local -@item gnus-treat-date-lapsed -@item gnus-treat-date-original -@item gnus-treat-strip-headers-in-body -@item gnus-treat-strip-trailing-blank-lines -@item gnus-treat-strip-leading-blank-lines -@item gnus-treat-strip-multiple-blank-lines -@item gnus-treat-overstrike -@item gnus-treat-display-xface -@item gnus-treat-display-smileys -@item gnus-treat-display-picons -@item gnus-treat-capitalize-sentences -@item gnus-treat-fill-long-lines +@item gnus-treat-highlight-signature (t, last) +@item gnus-treat-buttonize (t, integer) +@item gnus-treat-buttonize-head (head) +@item gnus-treat-emphasize (t, head, integer) +@item gnus-treat-fill-article (t, integer) +@item gnus-treat-strip-cr (t, integer) +@item gnus-treat-hide-headers (head) +@item gnus-treat-hide-boring-headers (head) +@item gnus-treat-hide-signature (t, last) +@item gnus-treat-hide-citation (t, integer) +@item gnus-treat-strip-pgp (t, last, integer) +@item gnus-treat-strip-pem (t, last, integer) +@item gnus-treat-highlight-headers (head) +@item gnus-treat-highlight-citation (t, integer) +@item gnus-treat-highlight-signature (t, last, integer) +@item gnus-treat-date-ut (head) +@item gnus-treat-date-local (head) +@item gnus-treat-date-lapsed (head) +@item gnus-treat-date-original (head) +@item gnus-treat-strip-headers-in-body (t, integer) +@item gnus-treat-strip-trailing-blank-lines (t, last, integer) +@item gnus-treat-strip-leading-blank-lines (t, integer) +@item gnus-treat-strip-multiple-blank-lines (t, integer) +@item gnus-treat-overstrike (t, integer) +@item gnus-treat-display-xface (head) +@item gnus-treat-display-smileys (t, integer) +@item gnus-treat-display-picons (head) +@item gnus-treat-capitalize-sentences (t, integer) +@item gnus-treat-fill-long-lines (t, integer) @item gnus-treat-play-sounds @item gnus-treat-translate @end table @@ -9923,6 +9956,7 @@ course. * Mail Sources:: How to tell Gnus where to get mail from. * Mail Backend Variables:: Variables for customizing mail handling. * Fancy Mail Splitting:: Gnus can do hairy splitting of incoming mail. +* Group Mail Splitting:: Use group customize to drive mail splitting. * Incorporating Old Mail:: What about the old mail you have? * Expiring Mail:: Getting rid of unwanted mail. * Washing Mail:: Removing gruft from the mail you get. @@ -10600,6 +10634,131 @@ up to @samp{\\9} will be substituted with the text matched by the groupings 1 through 9. +@node Group Mail Splitting +@subsection Group Mail Splitting +@cindex mail splitting +@cindex group mail splitting + +@findex gnus-group-split +If you subscribe to dozens of mailing lists but you don't want to +maintain mail splitting rules manually, group mail splitting is for you. +You just have to set @var{to-list} and/or @var{to-address} in group +parameters or group customization and set @code{nnmail-split-methods} to +@code{gnus-group-split}. This splitting function will scan all groups +for those parameters and split mail accordingly, i.e., messages posted +from or to the addresses specified in the parameters @var{to-list} or +@var{to-address} of a mail group will be stored in that group. + +Sometimes, mailing lists have multiple addresses, and you may want mail +splitting to recognize them all: just set the @var{extra-aliases} group +parameter to the list of additional addresses and it's done. If you'd +rather use a regular expression, set @var{split-regexp}. + +All these parameters in a group will be used to create an +@code{nnmail-split-fancy} split, in which the @var{FIELD} is @samp{any}, +the @var{VALUE} is a single regular expression that matches +@var{to-list}, @var{to-address}, all of @var{extra-aliases} and all +matches of @var{split-regexp}, and the @var{SPLIT} is the name of the +group. @var{RESTRICT}s are also supported: just set the +@var{split-exclude} parameter to a list of regular expressions. + +If you can't get the right split to be generated using all these +parameters, or you just need something fancier, you can set the +parameter @var{split-spec} to an @code{nnmail-split-fancy} split. In +this case, all other aforementioned parameters will be ignored by +@code{gnus-group-split}. In particular, @var{split-spec} may be set to +@code{nil}, in which case the group will be ignored by +@code{gnus-group-split}. + +@vindex gnus-group-split-default-catch-all-group +@code{gnus-group-split} will do cross-posting on all groups that match, +by defining a single @code{&} fancy split containing one split for each +group. If a message doesn't match any split, it will be stored in the +group named in @code{gnus-group-split-default-catch-all-group}, unless +some group has @var{split-spec} set to @code{catch-all}, in which case +that group is used as the catch-all group. Note that, in this case, +there's no cross-posting, as a @code{|} fancy split encloses the +@code{&} split and the catch-all group. + +It's time for an example. Assume the following group parameters have +been defined: + +@example +nnml:mail.bar: +((to-address . "bar@@femail.com") + (split-regexp . ".*@@femail\\.com")) +nnml:mail.foo: +((to-list . "foo@@nowhere.gov") + (extra-aliases "foo@@localhost" "foo-redist@@home") + (split-exclude "bugs-foo" "rambling-foo") + (admin-address . "foo-request@@nowhere.gov")) +nnml:mail.others: +((split-spec . catch-all)) +@end example + +Setting @code{nnmail-split-methods} to @code{gnus-group-split} will +behave as if @code{nnmail-split-fancy} had been selected and variable +@code{nnmail-split-fancy} had been set as follows: + +@lisp +(| (& (any "\\(bar@@femail\\.com\\|.*@@femail\\.com\\)" "mail.bar") + (any "\\(foo@@nowhere\\.gov\\|foo@@localhost\\|foo-redist@@home\\)" + - "bugs-foo" - "rambling-foo" "mail.foo")) + "mail.others") +@end lisp + +@findex gnus-group-split-fancy +If you'd rather not use group splitting for all your mail groups, you +may use it for only some of them, by using @code{nnmail-split-fancy} +splits like this: + +@lisp +(: gnus-mlsplt-fancy GROUPS NO-CROSSPOST CATCH-ALL) +@end lisp + +@var{GROUPS} may be a regular expression or a list of group names whose +parameters will be scanned to generate the output split. +@var{NO-CROSSPOST} can be used to disable cross-posting; in this case, a +single @code{|} split will be output. @var{CATCH-ALL} may be the name +of a group to be used as the default catch-all group. If +@var{CATCH-ALL} is @code{nil}, or if @var{SPLIT-REGEXP} matches the +empty string in any selected group, no catch-all split will be issued. +Otherwise, if some group has @var{SPLIT-SPEC} set to @code{catch-all}, +this group will override the value of the @var{CATCH-ALL} argument. + +@findex gnus-group-split-setup +Unfortunately, scanning all groups and their parameters can be quite +slow, especially considering that it has to be done for every message. +But don't despair! The function @code{gnus-group-split-setup} can be +used to select @code{gnus-group-split} in a much more efficient way. It +sets @code{nnmail-split-methods} to @code{nnmail-split-fancy} and sets +@code{nnmail-split-fancy} to the split produced by +@code{gnus-group-split-fancy}. Thus, the group parameters are only +scanned once, no matter how many messages are split. + +@findex gnus-group-split-update +However, if you change group parameters, you have to update +@code{nnmail-split-fancy} manually. You can do it by running +@code{gnus-group-split-update}. If you'd rather have it updated +automatically, just tell @code{gnus-group-split-setup} to do it for +you. For example, add to your @file{.gnus}: + +@lisp +(gnus-group-split-setup AUTO-UPDATE CATCH-ALL) +@end lisp + +If @var{AUTO-UPDATE} is non-@code{nil}, @code{gnus-group-split-update} +will be added to @code{nnmail-pre-get-new-mail-hook}, so you won't ever +have to worry about updating @code{nnmail-split-fancy} again. If you +don't omit @var{CATCH-ALL} (it's optional), +@code{gnus-group-split-default-catch-all-group} will be set to its +value. + +@vindex gnus-group-split-updated-hook +Because you may want to change @code{nnmail-split-fancy} after it is set +by @code{gnus-group-split-update}, this function will run +@code{gnus-group-split-updated-hook} just before finishing. + @node Incorporating Old Mail @subsection Incorporating Old Mail @@ -10845,6 +11004,9 @@ For instance, if you want to remove the @samp{(idm)} and the '("(idm)" "nagnagnag")) @end lisp +This can also be done non-destructively with +@code{gnus-list-identifiers}, @xref{Article Hiding}. + @item nnmail-remove-tabs @findex nnmail-remove-tabs Translate all @samp{TAB} characters into @samp{SPACE} characters. @@ -11309,7 +11471,7 @@ slowness of access parsing when learning what's new in one's groups. @item nnfolder -Basically the effetc of @code{nnfolder} is @code{nnmbox} (the first +Basically the effect of @code{nnfolder} is @code{nnmbox} (the first method described above) on a per-group basis. That is, @code{nnmbox} itself puts *all* one's mail in one file; @code{nnfolder} provides a little bit of optimization to this so that each of one's mail groups has @@ -12816,7 +12978,7 @@ Fetch all eligible articles in all groups @kindex J S (Agent Group) @findex gnus-group-send-drafts Send all sendable messages in the draft group -(@code{gnus-agent-fetch-session}). @xref{Drafts}. +(@code{gnus-group-send-drafts}). @xref{Drafts}. @item J a @kindex J a (Agent Group) diff --git a/texi/message.texi b/texi/message.texi index 9cb2fa4..a46d51d 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @setfilename message -@settitle Pterodactyl Message 0.95 Manual +@settitle Pterodactyl Message 0.96 Manual @synindex fn cp @synindex vr cp @synindex pg cp @@ -42,7 +42,7 @@ into another language, under the above conditions for modified versions. @tex @titlepage -@title Pterodactyl Message 0.95 Manual +@title Pterodactyl Message 0.96 Manual @author by Lars Magne Ingebrigtsen @page @@ -83,7 +83,7 @@ Message mode buffers. * Key Index:: List of Message mode keys. @end menu -This manual corresponds to Pterodactyl Message 0.95. Message is +This manual corresponds to Pterodactyl Message 0.96. Message is distributed with the Gnus distribution bearing the same version number as this manual.