From 30d9f23f0291edcefeca1958befadb992d2982b5 Mon Sep 17 00:00:00 2001 From: yamaoka Date: Sun, 18 Apr 1999 22:10:57 +0000 Subject: [PATCH] Importing Pterodactyl Gnus v0.83. --- lisp/ChangeLog | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++ lisp/gnus-agent.el | 4 + lisp/gnus-art.el | 57 +++++++---- lisp/gnus-cite.el | 20 ++-- lisp/gnus-cus.el | 3 +- lisp/gnus-demon.el | 4 +- lisp/gnus-draft.el | 3 +- lisp/gnus-ems.el | 3 +- lisp/gnus-group.el | 58 ++++++------ lisp/gnus-msg.el | 2 +- lisp/gnus-picon.el | 53 ----------- lisp/gnus-range.el | 14 +-- lisp/gnus-start.el | 27 ++++-- lisp/gnus-sum.el | 125 ++++++++++++++++++++---- lisp/gnus-uu.el | 9 +- lisp/gnus.el | 6 +- lisp/lpath.el | 2 +- lisp/mail-source.el | 44 ++++++++- lisp/message.el | 25 ++--- lisp/mm-decode.el | 153 ++++++++++++++++++------------ lisp/mm-util.el | 1 - lisp/mm-view.el | 12 ++- lisp/mml.el | 208 ++++++++++++++++++++++++++++++---------- lisp/nndoc.el | 9 +- lisp/nndraft.el | 4 +- lisp/nnfolder.el | 8 +- lisp/nnheader.el | 2 + lisp/nnmail.el | 56 ++++++----- lisp/nnml.el | 3 +- lisp/nnvirtual.el | 9 ++ lisp/pop3.el | 14 ++- lisp/rfc2231.el | 101 ++++++++++---------- lisp/uudecode.el | 13 ++- texi/ChangeLog | 33 +++++++ texi/gnus.texi | 185 +++++++++++++++++++++++++++++------- texi/message.texi | 6 +- 36 files changed, 1120 insertions(+), 419 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 200c565..d2317bc 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,261 @@ +Sun Apr 18 12:40:04 1999 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.83 is released. + +1999-04-18 10:55:57 Lars Magne Ingebrigtsen + + * gnus-draft.el (gnus-draft-mode): Use mml minor mode. + + * gnus-cite.el (gnus-dissect-cited-text): Off-by-one error. + + * gnus-uu.el (gnus-uu-mark-thread): Save hidden threads. + + * gnus-art.el (gnus-mime-inline-part): Don't do a charset param. + + * gnus-msg.el (gnus-bug): Use application/x-emacs-lisp. + + * message.el (message-generate-headers): Accept continuation + headers. + +1999-04-18 10:48:57 Renaud Rioboo + + * gnus-demon.el (gnus-demon-time-to-step): Not strings. + +1999-04-18 08:21:52 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treatment-function-alist): use + maybe-hide-headers. + + * message.el (message-inhibit-body-encoding): Typo. + (message-resend): Inhibit encoding. + + * gnus-sum.el (gnus-summary-toggle-header): Decode rfc2047. + + * gnus-art.el (article-remove-cr): Use re-search. + + * rfc2231.el (rfc2231-parse-string): Allow broken elm MIME + headers. + + * mm-decode.el (mm-quote-arg): Quote '. + + * gnus-ems.el (gnus-x-splash): Would place splash wrongly. + + * mm-decode.el (mm-insert-part): Use multibyte for text. + + * gnus-start.el (gnus-read-newsrc-file): New variable. + (gnus-read-newsrc-file): Use it. + +1999-04-17 18:51:54 Lars Magne Ingebrigtsen + + * nnvirtual.el (nnvirtual-request-expire-articles): New function. + + * gnus-group.el (gnus-group-expire-articles-1): Made into own + function. + +Sat Apr 17 16:41:30 1999 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.82 is released. + +1999-04-15 Hrvoje Niksic + + * gnus-sum.el (gnus-group-charset-alist): Include Croatian groups + for iso8859-2. + +1999-04-17 18:23:50 Lars Magne Ingebrigtsen + + * mm-util.el (mm-charset-synonym-alist): Remove iso-2022-jp-2 from + synonym alist. + +1999-04-17 18:03:38 Adam P. Jenkins + + * gnus-sum.el (gnus-summary-local-variables): Mark as global. + +1999-04-17 18:02:05 Ettore Perazzoli + + * mail-source.el (mail-source-fetch): Ask before bugging out. + +1999-03-19 Hrvoje Niksic + + * uudecode.el (uudecode-decode-region-external): Don't assume + uudecode-temporary-file-directory ends with a slash. + +1999-03-18 Simon Josefsson + + * gnus-sum.el (gnus-update-marks): + (gnus-update-read-articles): + (gnus-summary-expire-articles): Check server. + +1999-03-16 Simon Josefsson + + * mml.el (mml-preview): New function. + +1999-04-17 17:10:21 William M. Perry + + * mail-source.el (mail-source-fetch-file): Return the right + value. + +1999-04-17 07:52:17 Lars Magne Ingebrigtsen + + * mml.el (mml-insert-parameter): New function. + (mml-insert-parameter-string): New function. + + * nnmail.el (nnmail-get-new-mail): Say how many new articles. + + * gnus-art.el (gnus-mime-multipart-functions): New variable. + (gnus-mime-display-part): Use it. + + * mm-decode.el (mm-alternative-precedence): Removed. + (mm-discouraged-alternatives): New variable. + (mm-preferred-alternative-precedence): New function. + + * nnmail.el (nnmail-get-new-mail): Use mail-sources. + + * mail-source.el (mail-sources): New variable. + + * gnus-art.el (article-remove-cr): Remove several trailing CRs. + + * mm-decode.el (mm-valid-image-format-p): New function. + (mm-inline-media-tests): Use it. + (mm-valid-and-fit-image-p): New function. + + * gnus-agent.el (gnus-agent-fetch-groups): Error when unplugged. + (gnus-agent-fetch-group): Ditto. + +1999-04-12 Didier Verna + + * nnmail.el (nnmail-article-group): in case of a group name + containing "\\n" constructs, be sure to pass the expanded value to + nn*-save-mail. + +Sat Apr 17 05:40:45 1999 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.81 is released. + +1999-04-16 15:54:02 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-get-split-value): Reverse result. + +1999-04-03 00:17:24 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-always-read-dribble-file): Doc fix. + +1999-04-02 15:33:43 Lars Magne Ingebrigtsen + + * mml.el (mml-insert-tag): Insert concluding part. + + * message.el (message-send-mail): Encode later. + (message-send-news): Ditto. + + * nnfolder.el: Don't use mail delim. + +1999-03-28 19:14:27 Lars Magne Ingebrigtsen + + * gnus-cus.el (gnus-group-customize): Put point at min. + + * mm-view.el (mm-inline-text): Allow toggling html. + +1999-03-28 17:11:15 William M. Perry + + * mail-source.el: Added prescript and postscript to file. + +1999-03-28 13:46:00 Lars Magne Ingebrigtsen + + * nnmail.el: Reverted. + + * gnus-msg.el (gnus-setup-posting-charset): Didn't work. + (gnus-setup-posting-charset): Did work. + +1999-03-28 13:19:50 Jae-you Chung + + * gnus.el (gnus-short-group-name): Use + gnus-group-uncollapsed-levels. + +1999-03-28 13:11:43 Lars Magne Ingebrigtsen + + * gnus-cite.el (gnus-dissect-cited-text): Don't remove overlays. + +1999-03-26 13:18:45 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treat-strip-headers-in-body): New variable. + (article-strip-headers-from-body): New command and keystroke. + +1999-03-14 16:09:10 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-fetch-pop): Check for symbol first. + + * nnheader.el (nnheader-insert-file-contents): Bind + enable-local-eval to nil. + (nnheader-find-file-noselect): Ditto. + + * nnmail.el (nnmail-article-group): Don't remove long lines. + (nnmail-remove-long-lines): New function. + (nnmail-split-header-length-limit): Removed. + + * mml.el (mml-generate-mime-1): Use unibyte buffers. + + * gnus-group.el (gnus-group-kill-all-zombies): Query user. + +1999-03-06 07:20:05 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-generic-mark): New function. + + * nnmail.el (nnmail-split-header-length-limit): Increased. + (nnmail-article-group): Allow nil. + + * gnus-cite.el (gnus-cite-parse-wrapper): Inhibit point-motion. + + * nndoc.el (nndoc-generate-mime-parts-head): Insert real headers + first. + + * mml.el (mml-minibuffer-read-type): Include types from + mailcap-mime-data. + + * nndraft.el (nndraft-request-article): Would clobber Japanese. + +1999-03-05 Hrvoje Niksic + + * mml.el (mml-insert-tag): New function. + (mml-read-file): Renamed to mml-minibuffer-read-file to avoid + confusion with functions like `mml-read-tag'. + (mml-read-type): Ditto with `mml-minibuffer-read-type'. + (mml-minibuffer-read-description): Ditto with + `mml-minibuffer-read-description'. + (mml-attach-buffer): New function. + (mml-mode-map): New entry for /. + (mml-minibuffer-read-type): Accept DEFAULT. + + * mml.el (mml-quote-region): Narrow the region. + + * message.el (message-mode-menu): message-mime-attach-file is now + mml-attach-file. + +1999-03-05 21:24:23 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treatment-function-alist): Do emphasis earlier. + +1999-03-05 21:08:10 Robert Bihlmeyer + + * mml.el (mml-attach-buffer): New command. + +1999-02-27 Simon Josefsson + + * gnus-sum.el (gnus-update-marks): Call gnus-remove-from-range + with a proper range. Compress range. + + * gnus-range.el (gnus-remove-from-range): Protect arguments. + +1999-03-05 20:59:54 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-get-image): Create a temporary file for xbms. + +1999-03-04 04:20:25 Lars Magne Ingebrigtsen + + * gnus-picon.el (gnus-picons-x-face-file-name): Removed. + (gnus-picons-convert-x-face): Removed. + (gnus-picons-article-display-x-face): Removed. + (gnus-picons-x-face-sentinel): Ditto. + (gnus-picons-display-x-face): Ditto. + Thu Mar 4 01:38:00 1999 Lars Magne Ingebrigtsen * gnus.el: Pterodactyl Gnus v0.80 is released. @@ -63,6 +321,11 @@ Thu Mar 4 01:38:00 1999 Lars Magne Ingebrigtsen * nnmail.el (nnmail-get-new-mail): honor suffix for spool-files of type directory. +1999-03-04 Robert Bihlmeyer + + * gnus-art.el (article-hide-boring-headers): Field names must not + contain whitespace. + Fri Feb 26 18:54:16 1999 Lars Magne Ingebrigtsen * gnus.el: Pterodactyl Gnus v0.79 is released. diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index 737bfcf..acc9b0d 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -364,11 +364,15 @@ be a select method." (defun gnus-agent-fetch-groups (n) "Put all new articles in the current groups into the Agent." (interactive "P") + (unless gnus-plugged + (error "Groups can't be fetched when Gnus is unplugged")) (gnus-group-iterate n 'gnus-agent-fetch-group)) (defun gnus-agent-fetch-group (group) "Put all new articles in GROUP into the Agent." (interactive (list (gnus-group-group-name))) + (unless gnus-plugged + (error "Groups can't be fetched when Gnus is unplugged")) (unless group (error "No group on the current line")) (let ((gnus-command-method (gnus-find-method-for-group group))) diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index d26ec60..e519bad 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -120,7 +120,7 @@ "^X-Pgp-Public-Key-Url:" "^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:") + "^Status:" "^X-Gnus-Mail-Source:" "^Cancel-Lock:") "*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." @@ -593,6 +593,9 @@ on parts -- for instance, adding Vcard info to a database." :group 'gnus-article-mime :type 'function) +(defcustom gnus-mime-multipart-functions nil + "An alist of MIME types to functions to display them.") + ;;; ;;; The treatment variables ;;; @@ -773,6 +776,13 @@ See the manual for details." :group 'gnus-article-treat :type gnus-article-treat-head-custom) +(defcustom gnus-treat-strip-headers-in-body t + "Strip the X-No-Archive header line from the beginning of the body. +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-trailing-blank-lines nil "Strip trailing blank lines. Valid values are nil, t, `head', `last', an integer or a predicate. @@ -865,12 +875,14 @@ See the manual for details." (defvar gnus-article-mime-handle-alist-1 nil) (defvar gnus-treatment-function-alist '((gnus-treat-strip-banner gnus-article-strip-banner) + (gnus-treat-strip-headers-in-body gnus-article-strip-headers-in-body) (gnus-treat-highlight-signature gnus-article-highlight-signature) (gnus-treat-buttonize gnus-article-add-buttons) (gnus-treat-fill-article gnus-article-fill-cited-article) (gnus-treat-fill-long-lines gnus-article-fill-long-lines) (gnus-treat-strip-cr gnus-article-remove-cr) - (gnus-treat-hide-headers gnus-article-hide-headers) + (gnus-treat-emphasize gnus-article-emphasize) + (gnus-treat-hide-headers gnus-article-maybe-hide-headers) (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) @@ -879,7 +891,6 @@ See the manual for details." (gnus-treat-highlight-headers gnus-article-highlight-headers) (gnus-treat-highlight-citation gnus-article-highlight-citation) (gnus-treat-highlight-signature gnus-article-highlight-signature) - (gnus-treat-emphasize gnus-article-emphasize) (gnus-treat-date-ut gnus-article-date-ut) (gnus-treat-date-local gnus-article-date-local) (gnus-treat-date-lapsed gnus-article-date-lapsed) @@ -1089,7 +1100,7 @@ always hide." (cond ;; Hide empty headers. ((eq elem 'empty) - (while (re-search-forward "^[^:]+:[ \t]*\n[^ \t]" nil t) + (while (re-search-forward "^[^: \t]+:[ \t]*\n[^ \t]" nil t) (forward-line -1) (gnus-article-hide-text-type (progn (beginning-of-line) (point)) @@ -1282,12 +1293,12 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." (forward-sentence))))) (defun article-remove-cr () - "Translate CRLF pairs into LF, and then CR into LF.." + "Remove trailing CRs and then translate remaining CRs into LFs." (interactive) (save-excursion (let ((buffer-read-only nil)) (goto-char (point-min)) - (while (search-forward "\r$" nil t) + (while (re-search-forward "\r+$" nil t) (replace-match "" t t)) (goto-char (point-min)) (while (search-forward "\r" nil t) @@ -1529,6 +1540,15 @@ always hide." (gnus-article-hide-text-type (point-min) (point-max) 'signature))))))) +(defun article-strip-headers-in-body () + "Strip offensive headers from bodies." + (interactive) + (save-excursion + (article-goto-body) + (let ((case-fold-search t)) + (when (looking-at "x-no-archive:") + (gnus-delete-line))))) + (defun article-strip-leading-blank-lines () "Remove all blank lines from the beginning of the article." (interactive) @@ -2274,6 +2294,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is article-strip-banner article-hide-pem article-hide-signature + article-strip-headers-in-body article-remove-trailing-blank-lines article-strip-leading-blank-lines article-strip-multiple-blank-lines @@ -2540,8 +2561,6 @@ If ALL-HEADERS is non-nil, no headers are hidden." (when (gnus-visual-p 'article-highlight 'highlight) (gnus-run-hooks 'gnus-visual-mark-article-hook)) ;; Set the global newsgroup variables here. - ;; Suggested by Jim Sisolak - ;; . (gnus-set-global-variables) (setq gnus-have-all-headers (or all-headers gnus-show-all-headers)))) @@ -2696,23 +2715,19 @@ If ALL-HEADERS is non-nil, no headers are hidden." (setq buffer-file-name nil)) (goto-char (point-min)))) -(defun gnus-mime-inline-part (&optional charset) +(defun gnus-mime-inline-part (&optional handle) "Insert the MIME part under point into the current buffer." - (interactive "P") ; For compatibility reasons we are not using "z". + (interactive) (gnus-article-check-buffer) - (let* ((data (get-text-property (point) 'gnus-data)) + (let* ((handle (or handle (get-text-property (point) 'gnus-data))) contents (b (point)) buffer-read-only) - (if (mm-handle-undisplayer data) - (mm-remove-part data) - (setq contents (mm-get-part data)) + (if (mm-handle-undisplayer handle) + (mm-remove-part handle) + (setq contents (mm-get-part handle)) (forward-line 2) - (when charset - (unless (symbolp charset) - (setq charset (mm-read-coding-system "Charset: "))) - (setq contents (mm-decode-coding-string contents charset))) - (mm-insert-inline data contents) + (mm-insert-inline handle contents) (goto-char b)))) (defun gnus-mime-externalize-part (&optional handle) @@ -2947,6 +2962,10 @@ If ALL-HEADERS is non-nil, no headers are hidden." ;; Single part. ((not (stringp (car handle))) (gnus-mime-display-single handle)) + ;; User-defined multipart + ((cdr (assoc (car handle) gnus-mime-multipart-functions)) + (funcall (cdr (assoc (car handle) gnus-mime-multipart-functions)) + handle)) ;; multipart/alternative ((and (equal (car handle) "multipart/alternative") (not gnus-mime-display-multipart-as-mixed)) diff --git a/lisp/gnus-cite.el b/lisp/gnus-cite.el index b8d4131..aaf46a5 100644 --- a/lisp/gnus-cite.el +++ b/lisp/gnus-cite.el @@ -366,7 +366,7 @@ Lines matching `gnus-cite-attribution-suffix' and perhaps "Dissect the article buffer looking for cited text." (save-excursion (set-buffer gnus-article-buffer) - (gnus-cite-parse-maybe) + (gnus-cite-parse-maybe nil t) (let ((alist gnus-cite-prefix-alist) prefix numbers number marks m) ;; Loop through citation prefixes. @@ -376,7 +376,7 @@ Lines matching `gnus-cite-attribution-suffix' and perhaps (while numbers (setq number (pop numbers)) (goto-char (point-min)) - (forward-line (1- number)) + (forward-line number) (push (cons (point-marker) "") marks) (while (and numbers (= (1- number) (car numbers))) @@ -613,7 +613,6 @@ See also the documentation for `gnus-article-highlight-citation'." ;;; Internal functions: - (defun gnus-cite-parse-maybe (&optional force no-overlay) "Always parse the buffer." (gnus-cite-localize) @@ -641,14 +640,15 @@ See also the documentation for `gnus-article-highlight-citation'." (gnus-delete-overlay overlay)))) (defun gnus-cite-parse-wrapper () - ;; Wrap chopped gnus-cite-parse + ;; Wrap chopped gnus-cite-parse. (article-goto-body) - (save-excursion - (gnus-cite-parse-attributions)) - (save-excursion - (gnus-cite-parse)) - (save-excursion - (gnus-cite-connect-attributions))) + (let ((inhibit-point-motion-hooks t)) + (save-excursion + (gnus-cite-parse-attributions)) + (save-excursion + (gnus-cite-parse)) + (save-excursion + (gnus-cite-connect-attributions)))) (defun gnus-cite-parse () ;; Parse and connect citation prefixes and attribution lines. diff --git a/lisp/gnus-cus.el b/lisp/gnus-cus.el index e50aef0..0f3d5d3 100644 --- a/lisp/gnus-cus.el +++ b/lisp/gnus-cus.el @@ -273,7 +273,8 @@ form, but who cares?" :tag "Method" :value (gnus-info-method info)))) (use-local-map widget-keymap) - (widget-setup))) + (widget-setup) + (goto-char (point-min)))) (defun gnus-group-customize-done (&rest ignore) "Apply changes and bury the buffer." diff --git a/lisp/gnus-demon.el b/lisp/gnus-demon.el index 3401ed4..7c1fa49 100644 --- a/lisp/gnus-demon.el +++ b/lisp/gnus-demon.el @@ -152,8 +152,8 @@ time Emacs has been idle for IDLE `gnus-demon-timestep's." (nowParts (decode-time now)) ;; obtain THEN as discrete components (thenParts (parse-time-string time)) - (thenHour (string-to-int (elt thenParts 0))) - (thenMin (string-to-int (elt thenParts 1))) + (thenHour (elt thenParts 0)) + (thenMin (elt thenParts 1)) ;; convert time as elements into number of seconds since EPOCH. (then (encode-time 0 thenMin diff --git a/lisp/gnus-draft.el b/lisp/gnus-draft.el index 678f6d9..4ebe3b3 100644 --- a/lisp/gnus-draft.el +++ b/lisp/gnus-draft.el @@ -73,6 +73,7 @@ (when (gnus-visual-p 'draft-menu 'menu) (gnus-draft-make-menu-bar)) (gnus-add-minor-mode 'gnus-draft-mode " Draft" gnus-draft-mode-map) + (mml-mode) (gnus-run-hooks 'gnus-draft-mode-hook)))) ;;; Commands @@ -123,7 +124,7 @@ (gnus-draft-setup article (or group "nndraft:queue")) (let ((message-syntax-checks (if interactive nil 'dont-check-for-anything-just-trust-me)) - (messgage-inhibit-body-encoding t) + (message-inhibit-body-encoding t) message-send-hook type method) ;; We read the meta-information that says how and where ;; this message is to be sent. diff --git a/lisp/gnus-ems.el b/lisp/gnus-ems.el index 6404b27..8cfa6e2 100644 --- a/lisp/gnus-ems.el +++ b/lisp/gnus-ems.el @@ -187,7 +187,6 @@ (ignore-errors (setq pixmap (read (current-buffer)))))) (when pixmap - (erase-buffer) (unless (facep 'gnus-splash) (make-face 'gnus-splash)) (setq height (/ (car pixmap) (frame-char-height)) @@ -197,7 +196,7 @@ (insert-char ?\n (* (/ (window-height) 2 height) height)) (setq i height) (while (> i 0) - (insert-char ? (* (+ (/ (window-width) 2 width) 1) width)) + (insert-char ? (* (/ (window-width) 2 width) width)) (setq beg (point)) (insert-char ? width) (set-text-properties beg (point) '(face gnus-splash)) diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index 30fc67c..0e6f1b1 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -2524,32 +2524,35 @@ or nil if no action could be taken." (error "No groups to expire")) (while (setq group (pop groups)) (gnus-group-remove-mark group) - (when (gnus-check-backend-function 'request-expire-articles group) - (gnus-message 6 "Expiring articles in %s..." group) - (let* ((info (gnus-get-info group)) - (expirable (if (gnus-group-total-expirable-p group) - (cons nil (gnus-list-of-read-articles group)) - (assq 'expire (gnus-info-marks info)))) - (expiry-wait (gnus-group-find-parameter group 'expiry-wait))) - (when expirable - (setcdr - expirable - (gnus-compress-sequence - (if expiry-wait - ;; We set the expiry variables to the group - ;; parameter. - (let ((nnmail-expiry-wait-function nil) - (nnmail-expiry-wait expiry-wait)) - (gnus-request-expire-articles - (gnus-uncompress-sequence (cdr expirable)) group)) - ;; Just expire using the normal expiry values. - (gnus-request-expire-articles - (gnus-uncompress-sequence (cdr expirable)) group)))) - (gnus-close-group group)) - (gnus-message 6 "Expiring articles in %s...done" group))) + (gnus-group-expire-articles-1 group) (gnus-dribble-touch) (gnus-group-position-point)))) +(defun gnus-group-expire-articles-1 (group) + (when (gnus-check-backend-function 'request-expire-articles group) + (gnus-message 6 "Expiring articles in %s..." group) + (let* ((info (gnus-get-info group)) + (expirable (if (gnus-group-total-expirable-p group) + (cons nil (gnus-list-of-read-articles group)) + (assq 'expire (gnus-info-marks info)))) + (expiry-wait (gnus-group-find-parameter group 'expiry-wait))) + (when expirable + (setcdr + expirable + (gnus-compress-sequence + (if expiry-wait + ;; We set the expiry variables to the group + ;; parameter. + (let ((nnmail-expiry-wait-function nil) + (nnmail-expiry-wait expiry-wait)) + (gnus-request-expire-articles + (gnus-uncompress-sequence (cdr expirable)) group)) + ;; Just expire using the normal expiry values. + (gnus-request-expire-articles + (gnus-uncompress-sequence (cdr expirable)) group)))) + (gnus-close-group group)) + (gnus-message 6 "Expiring articles in %s...done" group)))) + (defun gnus-group-expire-all-groups () "Expire all expirable articles in all newsgroups." (interactive) @@ -2680,10 +2683,11 @@ N and the number of steps taken is returned." (defun gnus-group-kill-all-zombies () "Kill all zombie newsgroups." (interactive) - (setq gnus-killed-list (nconc gnus-zombie-list gnus-killed-list)) - (setq gnus-zombie-list nil) - (gnus-dribble-touch) - (gnus-group-list-groups)) + (when (gnus-yes-or-no-p "Really kill all zombies? ") + (setq gnus-killed-list (nconc gnus-zombie-list gnus-killed-list)) + (setq gnus-zombie-list nil) + (gnus-dribble-touch) + (gnus-group-list-groups))) (defun gnus-group-kill-region (begin end) "Kill newsgroups in current region (excluding current point). diff --git a/lisp/gnus-msg.el b/lisp/gnus-msg.el index d8d4d1b..910e874 100644 --- a/lisp/gnus-msg.el +++ b/lisp/gnus-msg.el @@ -852,7 +852,7 @@ If YANK is non-nil, include the original article." (save-excursion (set-buffer (gnus-get-buffer-create " *gnus environment info*")) (gnus-debug)) - (insert "<#part type=application/emacs-lisp buffer=\" *gnus environment info*\" disposition=inline description=\"User settings\"><#/part>") + (insert "<#part type=application/x-emacs-lisp buffer=\" *gnus environment info*\" disposition=inline description=\"User settings\"><#/part>") (goto-char (point-min)) (search-forward "Subject: " nil t) (message ""))) diff --git a/lisp/gnus-picon.el b/lisp/gnus-picon.el index 372bee6..3685732 100644 --- a/lisp/gnus-picon.el +++ b/lisp/gnus-picon.el @@ -87,17 +87,6 @@ Some people may want to add \"unknown\" to this list." :type 'regexp :group 'picons) -(defcustom gnus-picons-x-face-file-name - (format "/tmp/picon-xface.%s.xbm" (user-login-name)) - "*The name of the file in which to store the converted X-face header." - :type 'string - :group 'picons) - -(defcustom gnus-picons-convert-x-face (format "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | pbmtoxbm > %s" gnus-picons-x-face-file-name) - "*Command to convert the x-face header into a xbm file." - :type 'string - :group 'picons) - (defcustom gnus-picons-display-as-address t "*If t display textual email addresses along with pictures." :type 'boolean @@ -258,48 +247,6 @@ arguments necessary for the job.") (set-extent-property annot 'duplicable t) annot)) -(defun gnus-picons-article-display-x-face () - "Display the x-face header bitmap in the 'gnus-picons-display-where buffer." - (let ((gnus-article-x-face-command 'gnus-picons-display-x-face)) - (gnus-article-display-x-face))) - -(defun gnus-picons-x-face-sentinel (process event) - (when (memq process gnus-picons-processes-alist) - (setq gnus-picons-processes-alist - (delq process gnus-picons-processes-alist)) - (gnus-picons-set-buffer) - (gnus-picons-make-annotation - (make-glyph gnus-picons-x-face-file-name) nil 'text) - (when (file-exists-p gnus-picons-x-face-file-name) - (delete-file gnus-picons-x-face-file-name)))) - -(defun gnus-picons-display-x-face (beg end) - "Function to display the x-face header in the picons window. -To use: (setq gnus-article-x-face-command 'gnus-picons-display-x-face)" - (interactive) - (if (featurep 'xface) - ;; Use builtin support - (save-excursion - ;; Don't remove this binding, it is really needed: when - ;; `gnus-picons-set-buffer' changes buffer (like when it is - ;; set to display picons outside of the article buffer), BEG - ;; and END still refer the buffer current now ! - (let ((buf (current-buffer))) - (gnus-picons-set-buffer) - (gnus-picons-make-annotation - (vector 'xface - :data (concat "X-Face: " (buffer-substring beg end buf))) - nil 'text nil nil nil t))) - ;; convert the x-face header to a .xbm file - (let* ((process-connection-type nil) - (process (start-process-shell-command - "gnus-x-face" nil gnus-picons-convert-x-face))) - (push process gnus-picons-processes-alist) - (process-kill-without-query process) - (set-process-sentinel process 'gnus-picons-x-face-sentinel) - (process-send-region process beg end) - (process-send-eof process)))) - (defun gnus-article-display-picons () "Display faces for an author and her domain in gnus-picons-display-where." (interactive) diff --git a/lisp/gnus-range.el b/lisp/gnus-range.el index 97197fe..14b6f49 100644 --- a/lisp/gnus-range.el +++ b/lisp/gnus-range.el @@ -228,13 +228,15 @@ Note: LIST has to be sorted over `<'." "Return a range that has all articles from RANGE2 removed from RANGE1. The returned range is always a list. RANGE2 can also be a unsorted list of articles." - (if (listp (cdr range2)) - (setq range2 (sort range2 (lambda (e1 e2) - (< (if (consp e1) (car e1) e1) - (if (consp e2) (car e2) e2)))))) (if (or (null range1) (null range2)) range1 - (let (out r1 r2 r1_min r1_max r2_min r2_max) + (let (out r1 r2 r1_min r1_max r2_min r2_max + (range1 range1) + (range2 (if (listp (cdr range2)) + (sort range2 (lambda (e1 e2) + (< (if (consp e1) (car e1) e1) + (if (consp e2) (car e2) e2)))) + range2))) (setq range1 (if (listp (cdr range1)) range1 (list range1)) range2 (if (listp (cdr range2)) range2 (list range2)) r1 (car range1) @@ -296,7 +298,7 @@ unsorted list of articles." (push (cons r1_min r1_max) out)) (pop range1)) (while range1 - (push (pop range1) out)) + (push (pop range1) out)) (nreverse out)))) (defun gnus-member-of-range (number ranges) diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index 646c756..45d87a1 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -196,6 +196,16 @@ groups." :type '(choice integer (const :tag "none" nil))) +(defcustom gnus-read-newsrc-file t + "*Non-nil means that Gnus will read the `.newsrc' file. +Gnus always reads its own startup file, which is called +\".newsrc.eld\". The file called \".newsrc\" is in a format that can +be readily understood by other newsreaders. If you don't plan on +using other newsreaders, set this variable to nil to save some time on +entry." + :group 'gnus-newsrc + :type 'boolean) + (defcustom gnus-save-newsrc-file t "*Non-nil means that Gnus will save the `.newsrc' file. Gnus always saves its own startup file, which is called @@ -222,12 +232,12 @@ not match this regexp will be removed before saving the list." :type 'boolean) (defcustom gnus-ignored-newsgroups - (purecopy (mapconcat 'identity - '("^to\\." ; not "real" groups - "^[0-9. \t]+ " ; all digits in name - "[][\"#'()]" ; bogus characters - ) - "\\|")) + (mapconcat 'identity + '("^to\\." ; not "real" groups + "^[0-9. \t]+ " ; all digits in name + "[][\"#'()]" ; bogus characters + ) + "\\|") "*A regexp to match uninteresting newsgroups in the active file. Any lines in the active file matching this regular expression are removed from the newsgroup list before anything else is done to it, @@ -381,7 +391,7 @@ Can be used to turn version control on or off." :type 'hook) (defcustom gnus-always-read-dribble-file nil - "Uncoditionally read the dribble file." + "Unconditionally read the dribble file." :group 'gnus-newsrc :type 'boolean) @@ -1868,7 +1878,8 @@ If FORCE is non-nil, the .newsrc file is read." ;; file (ticked articles, killed groups, foreign methods, etc.) (gnus-read-newsrc-el-file quick-file) - (when (and (file-exists-p gnus-current-startup-file) + (when (and gnus-read-newsrc-file + (file-exists-p gnus-current-startup-file) (or force (and (file-newer-than-file-p newsrc-file quick-file) (file-newer-than-file-p newsrc-file diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index 9a8a28c..8ef602d 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -802,7 +802,7 @@ which it may alter in any way.") ("^cn\\>\\|\\" cn-gb-2312) ("^fj\\>\\|^japan\\>" iso-2022-jp-2) ("^relcom\\>" koi8-r) - ("^\\(cz\\|hun\\|pl\\|sk\\)\\>" iso-8859-2) + ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2) ("^israel\\>" iso-8859-1) ("^han\\>" euc-kr) ("^\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1) @@ -1029,7 +1029,8 @@ variable (string, integer, character, etc).") gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay gnus-newsgroup-scored gnus-newsgroup-kill-headers gnus-thread-expunge-below - gnus-score-alist gnus-current-score-file gnus-summary-expunge-below + gnus-score-alist gnus-current-score-file + (gnus-summary-expunge-below . global) (gnus-summary-mark-below . global) gnus-newsgroup-active gnus-scores-exclude-files gnus-newsgroup-history gnus-newsgroup-ancient @@ -1467,6 +1468,7 @@ increase the score of each group you read." "t" gnus-article-hide-headers "v" gnus-summary-verbose-headers "h" gnus-article-treat-html + "H" gnus-article-strip-headers-in-body "d" gnus-article-treat-dumbquotes) (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map) @@ -4285,28 +4287,31 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq arts (cdr arts))) (setq list (cdr all)))) - (when (gnus-check-backend-function 'request-set-mark - gnus-newsgroup-name) - ;; score & bookmark are not proper flags (they are cons cells) - ;; cache is a internal gnus flag - (unless (memq (cdr type) '(cache score bookmark)) - (let* ((old (cdr (assq (cdr type) (gnus-info-marks info)))) - (del (gnus-remove-from-range old list)) - (add (gnus-remove-from-range list old))) - (if add - (push (list add 'add (list (cdr type))) delta-marks)) - (if del - (push (list del 'del (list (cdr type))) delta-marks))))) - + (when (gnus-check-backend-function 'request-set-mark + gnus-newsgroup-name) + ;; uncompressed:s are not proper flags (they are cons cells) + ;; cache is a internal gnus flag + (unless (memq (cdr type) (cons 'cache uncompressed)) + (let* ((old (cdr (assq (cdr type) (gnus-info-marks info)))) + (list (gnus-compress-sequence (sort list '<))) + (del (gnus-remove-from-range old list)) + (add (gnus-remove-from-range list old))) + (if add + (push (list add 'add (list (cdr type))) delta-marks)) + (if del + (push (list del 'del (list (cdr type))) delta-marks))))) + (push (cons (cdr type) (if (memq (cdr type) uncompressed) list (gnus-compress-sequence (set symbol (sort list '<)) t))) newmarked))) - (if delta-marks - (gnus-request-set-mark gnus-newsgroup-name delta-marks)) - + (when delta-marks + (unless (gnus-check-group gnus-newsgroup-name) + (error "Can't open server for %s" gnus-newsgroup-name)) + (gnus-request-set-mark gnus-newsgroup-name delta-marks)) + ;; Enter these new marks into the info of the group. (if (nthcdr 3 info) (setcar (nthcdr 3 info) newmarked) @@ -7035,6 +7040,7 @@ If ARG is a negative number, hide the unwanted header lines." (insert-buffer-substring gnus-original-article-buffer 1 e) (save-restriction (narrow-to-region (point-min) (point)) + (article-decode-encoded-words) (if (or hidden (and (numberp arg) (< arg 0))) (let ((gnus-treat-hide-headers nil) @@ -7422,6 +7428,8 @@ This will be the case if the article has both been mailed and posted." ;; There are expirable articles in this group, so we run them ;; through the expiry process. (gnus-message 6 "Expiring articles...") + (unless (gnus-check-group gnus-newsgroup-name) + (error "Can't open server for %s" gnus-newsgroup-name)) ;; The list of articles that weren't expired is returned. (save-excursion (if expiry-wait @@ -8775,7 +8783,7 @@ save those articles instead." split-name)) ((consp result) (setq split-name (append result split-name))))))))) - split-name)) + (nreverse split-name))) (defun gnus-valid-move-group-p (group) (and (boundp group) @@ -9131,6 +9139,8 @@ save those articles instead." (let ((del (gnus-remove-from-range (gnus-info-read info) read)) (add (gnus-remove-from-range read (gnus-info-read info)))) (when (or add del) + (unless (gnus-check-group group) + (error "Can't open server for %s" group)) (gnus-request-set-mark group (delq nil (list (if add (list add 'add '(read))) (if del (list del 'del '(read))))))))) @@ -9261,6 +9271,83 @@ Then replace the article with the result." (put 'gnus-with-article 'lisp-indent-function 1) (put 'gnus-with-article 'edebug-form-spec '(form body)) +;;; +;;; Generic summary marking commands +;;; + +(defvar gnus-summary-marking-alist + '((read gnus-del-mark "d") + (unread gnus-unread-mark "u") + (ticked gnus-ticked-mark "!") + (dormant gnus-dormant-mark "?") + (expirable gnus-expirable-mark "e")) + "An alist of names/marks/keystrokes.") + +(defvar gnus-summary-generic-mark-map (make-sparse-keymap)) +(defvar gnus-summary-mark-map) + +(defun gnus-summary-make-all-marking-commands () + (define-key gnus-summary-mark-map "M" gnus-summary-generic-mark-map) + (dolist (elem gnus-summary-marking-alist) + (apply 'gnus-summary-make-marking-command elem))) + +(defun gnus-summary-make-marking-command (name mark keystroke) + (let ((map (make-sparse-keymap))) + (define-key gnus-summary-generic-mark-map keystroke map) + (dolist (lway `((next "next" next nil "n") + (next-unread "next unread" next t "N") + (prev "previous" prev nil "p") + (prev-unread "previous unread" prev t "P") + (nomove "" nil nil ,keystroke))) + (let ((func (gnus-summary-make-marking-command-1 + mark (car lway) lway name))) + (setq func (eval func)) + (define-key map (nth 4 lway) func))))) + +(defun gnus-summary-make-marking-command-1 (mark way lway name) + `(defun ,(intern + (format "gnus-summary-put-mark-as-%s%s" + name (if (eq way 'nomove) + "" + (concat "-" (symbol-name way))))) + (n) + ,(format + "Mark the current article as %s%s. +If N, the prefix, then repeat N times. +If N is negative, move in reverse order. +The difference between N and the actual number of articles marked is +returned." + name (cadr lway)) + (interactive "p") + (gnus-summary-generic-mark n ,mark ',(nth 2 lway) ,(nth 3 lway)))) + +(defun gnus-summary-generic-mark (n mark move unread) + "Mark N articles with MARK." + (unless (eq major-mode 'gnus-summary-mode) + (error "This command can only be used in the summary buffer")) + (gnus-summary-show-thread) + (let ((nummove + (cond + ((eq move 'next) 1) + ((eq move 'prev) -1) + (t 0)))) + (if (zerop nummove) + (setq n 1) + (when (< n 0) + (setq n (abs n) + nummove (* -1 nummove)))) + (while (and (> n 0) + (gnus-summary-mark-article nil mark) + (zerop (gnus-summary-next-subject nummove unread t))) + (setq n (1- n))) + (when (/= 0 n) + (gnus-message 7 "No more %sarticles" (if mark "" "unread "))) + (gnus-summary-recenter) + (gnus-summary-position-point) + (gnus-set-mode-line 'summary) + n)) + +(gnus-summary-make-all-marking-commands) (gnus-ems-redefine) diff --git a/lisp/gnus-uu.el b/lisp/gnus-uu.el index bb557c2..387d178 100644 --- a/lisp/gnus-uu.el +++ b/lisp/gnus-uu.el @@ -621,10 +621,11 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defun gnus-uu-mark-thread () "Marks all articles downwards in this thread." (interactive) - (let ((level (gnus-summary-thread-level))) - (while (and (gnus-summary-set-process-mark (gnus-summary-article-number)) - (zerop (gnus-summary-next-subject 1)) - (> (gnus-summary-thread-level) level)))) + (gnus-save-hidden-threads + (let ((level (gnus-summary-thread-level))) + (while (and (gnus-summary-set-process-mark (gnus-summary-article-number)) + (zerop (gnus-summary-next-subject 1)) + (> (gnus-summary-thread-level) level))))) (gnus-summary-position-point)) (defun gnus-uu-unmark-thread () diff --git a/lisp/gnus.el b/lisp/gnus.el index 1283abc..1dd5bfd 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.80" +(defconst gnus-version-number "0.83" "Version number for this version of Gnus.") (defconst gnus-version (format "Pterodactyl Gnus v%s" gnus-version-number) @@ -1726,7 +1726,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.") gnus-article-delete-invisible-text gnus-treat-article) ("gnus-art" :interactive t gnus-article-hide-headers gnus-article-hide-boring-headers - gnus-article-treat-overstrike gnus-article-word-wrap + gnus-article-treat-overstrike gnus-article-remove-cr gnus-article-remove-trailing-blank-lines gnus-article-display-x-face gnus-article-de-quoted-unreadable gnus-article-hide-pgp @@ -2561,7 +2561,6 @@ If SCORE is nil, add 1 to the score of GROUP." (when info (gnus-info-set-score info (+ (gnus-info-score info) (or score 1)))))) -;; Function written by Stainless Steel Rat (defun gnus-short-group-name (group &optional levels) "Collapse GROUP name LEVELS. Select methods are stripped and any remote host name is stripped down to @@ -2571,6 +2570,7 @@ just the host name." (depth 0) (skip 1) (levels (or levels + gnus-group-uncollapsed-levels (progn (while (string-match "\\." group skip) (setq skip (match-end 0) diff --git a/lisp/lpath.el b/lisp/lpath.el index dab58b5..d1e9a66 100644 --- a/lisp/lpath.el +++ b/lisp/lpath.el @@ -79,7 +79,7 @@ make-annotation w3-do-setup w3-region rmail-summary-exists rmail-select-summary rmail-update-summary - url-generic-parse-url + url-generic-parse-url valid-image-instantiator-format-p ))) (setq load-path (cons "." load-path)) diff --git a/lisp/mail-source.el b/lisp/mail-source.el index bb7590d..5a66e10 100644 --- a/lisp/mail-source.el +++ b/lisp/mail-source.el @@ -34,6 +34,12 @@ "The mail-fetching library." :group 'gnus) +(defcustom mail-sources nil + "*Where the mail backends will look for incoming mail. +This variable is a list of mail source specifiers." + :group 'mail-source + :type 'sexp) + (defcustom mail-source-crash-box "~/.emacs-mail-crash-box" "File where mail will be stored while processing it." :group 'mail-source @@ -62,6 +68,8 @@ (eval-and-compile (defvar mail-source-keyword-map '((file + (:prescript) + (:postscript) (:path (or (getenv "MAIL") (concat "/usr/spool/mail/" (user-login-name))))) (directory @@ -167,8 +175,15 @@ Return the number of files that were found." (when (file-exists-p mail-source-crash-box) (message "Processing mail from %s..." mail-source-crash-box) (setq found (mail-source-callback - callback mail-source-crash-box))) - (+ found (funcall function source callback))))) + callback mail-source-crash-box))) + (+ found + (condition-case err + (funcall function source callback) + (error + (unless (yes-or-no-p + (format "Mail source error. Continue? ")) + (error "Cannot get new mail.")) + 0)))))) (defun mail-source-make-complex-temp-name (prefix) (let ((newname (make-temp-name prefix)) @@ -294,9 +309,26 @@ If ARGS, PROMPT is used as an argument to `format'." (defun mail-source-fetch-file (source callback) "Fetcher for single-file sources." (mail-source-bind (file source) + (when prescript + (if (and (symbolp prescript) (fboundp prescript)) + (funcall prescript) + (call-process shell-file-name nil nil nil + shell-command-switch + (format-spec + prescript + (format-spec-make ?t mail-source-crash-box))))) (let ((mail-source-string (format "file:%s" path))) (if (mail-source-movemail path mail-source-crash-box) - (mail-source-callback callback path) + (prog1 + (mail-source-callback callback path) + (when prescript + (if (and (symbolp prescript) (fboundp prescript)) + (funcall prescript) + (call-process shell-file-name nil nil nil + shell-command-switch + (format-spec + postscript + (format-spec-make ?t mail-source-crash-box)))))) 0)))) (defun mail-source-fetch-directory (source callback) @@ -316,7 +348,8 @@ If ARGS, PROMPT is used as an argument to `format'." "Fetcher for single-file sources." (mail-source-bind (pop source) (when prescript - (if (fboundp prescript) + (if (and (symbolp prescript) + (fboundp prescript)) (funcall prescript) (call-process shell-file-name nil nil nil shell-command-switch @@ -360,7 +393,8 @@ If ARGS, PROMPT is used as an argument to `format'." (prog1 (mail-source-callback callback server) (when prescript - (if (fboundp prescript) + (if (and (symbolp postscript) + (fboundp postscript)) (funcall prescript) (call-process shell-file-name nil nil nil shell-command-switch diff --git a/lisp/message.el b/lisp/message.el index f0eb481..a8042fd 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -1320,7 +1320,7 @@ Point is left at the beginning of the narrowed-to region." ["Newline and Reformat" message-newline-and-reformat t] ["Rename buffer" message-rename-buffer t] ["Spellcheck" ispell-message t] - ["Attach file as MIME" message-mime-attach-file t] + ["Attach file as MIME" mml-attach-file t] "----" ["Send Message" message-send-and-exit t] ["Abort Message" message-dont-send t] @@ -2088,14 +2088,12 @@ the user from the mailer." (case-fold-search nil) (news (message-news-p)) (mailbuf (current-buffer))) - (message-encode-message-body) (save-restriction (message-narrow-to-headers) ;; Insert some headers. (let ((message-deletable-headers (if news nil message-deletable-headers))) (message-generate-headers message-required-mail-headers)) - (mail-encode-encoded-word-buffer) ;; Let the user do all of the above. (run-hooks 'message-header-hook)) (unwind-protect @@ -2108,10 +2106,12 @@ the user from the mailer." (set-buffer mailbuf) (buffer-string)))) ;; Remove some headers. + (message-encode-message-body) (save-restriction (message-narrow-to-headers) ;; Remove some headers. - (message-remove-header message-ignored-mail-headers t)) + (message-remove-header message-ignored-mail-headers t) + (mail-encode-encoded-word-buffer)) (goto-char (point-max)) ;; require one newline at the end. (or (= (preceding-char) ?\n) @@ -2264,13 +2264,10 @@ to find out how to use this." result) (if (not (message-check-news-body-syntax)) nil - (message-encode-message-body) (save-restriction (message-narrow-to-headers) ;; Insert some headers. (message-generate-headers message-required-news-headers) - (let ((mail-parse-charset message-posting-charset)) - (mail-encode-encoded-word-buffer)) ;; Let the user do all of the above. (run-hooks 'message-header-hook)) (message-cleanup-headers) @@ -2286,11 +2283,14 @@ to find out how to use this." "%s" (save-excursion (set-buffer messbuf) (buffer-string)))) + (message-encode-message-body) ;; Remove some headers. (save-restriction (message-narrow-to-headers) ;; Remove some headers. - (message-remove-header message-ignored-news-headers t)) + (message-remove-header message-ignored-news-headers t) + (let ((mail-parse-charset message-posting-charset)) + (mail-encode-encoded-word-buffer))) (goto-char (point-max)) ;; require one newline at the end. (or (= (preceding-char) ?\n) @@ -2988,7 +2988,7 @@ Headers already prepared in the buffer are not modified." ;; colon, if there is none. (if (/= (char-after) ? ) (insert " ") (forward-char 1)) ;; Find out whether the header is empty... - (looking-at "[ \t]*$"))) + (looking-at "[ \t]*\n[^ \t]"))) ;; So we find out what value we should insert. (setq value (cond @@ -3830,7 +3830,8 @@ Optional NEWS will use news to forward instead of mail." (when (looking-at "From ") (replace-match "X-From-Line: ")) ;; Send it. - (let (message-required-mail-headers) + (let ((message-inhibit-body-encoding t) + message-required-mail-headers) (message-send-mail)) (kill-buffer (current-buffer))) (message "Resending message to %s...done" address))) @@ -4105,10 +4106,10 @@ regexp varstr." ;;; MIME functions ;;; -(defvar messgage-inhibit-body-encoding nil) +(defvar message-inhibit-body-encoding nil) (defun message-encode-message-body () - (unless messgage-inhibit-body-encoding + (unless message-inhibit-body-encoding (let ((mail-parse-charset (or mail-parse-charset message-default-charset message-posting-charset)) diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index 83cf901..bbe1ba6 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -57,26 +57,15 @@ ,disposition ,description ,cache ,id)) (defvar mm-inline-media-tests - '(("image/jpeg" mm-inline-image - (and window-system (featurep 'jpeg) (mm-image-fit-p handle))) - ("image/png" mm-inline-image - (and window-system (featurep 'png) (mm-image-fit-p handle))) - ("image/gif" mm-inline-image - (and window-system (featurep 'gif) (mm-image-fit-p handle))) - ("image/tiff" mm-inline-image - (and window-system (featurep 'tiff) (mm-image-fit-p handle))) - ("image/xbm" mm-inline-image - (and window-system (fboundp 'device-type) - (eq (device-type) 'x))) - ("image/x-xbitmap" mm-inline-image - (and window-system (fboundp 'device-type) - (eq (device-type) 'x))) - ("image/xpm" mm-inline-image - (and window-system (featurep 'xpm))) - ("image/x-pixmap" mm-inline-image - (and window-system (featurep 'xpm))) - ("image/bmp" mm-inline-image - (and window-system (featurep 'bmp))) + '(("image/jpeg" mm-inline-image (mm-valid-and-fit-image-p 'jpeg handle)) + ("image/png" mm-inline-image (mm-valid-and-fit-image-p 'png handle)) + ("image/gif" mm-inline-image (mm-valid-and-fit-image-p 'gif handle)) + ("image/tiff" mm-inline-image (mm-valid-and-fit-image-p 'tiff handle)) + ("image/xbm" mm-inline-image (mm-valid-and-fit-image-p 'xbm handle)) + ("image/x-xbitmap" mm-inline-image (mm-valid-and-fit-image-p 'xbm handle)) + ("image/xpm" mm-inline-image (mm-valid-and-fit-image-p 'xpm handle)) + ("image/x-pixmap" mm-inline-image (mm-valid-and-fit-image-p 'xpm handle)) + ("image/bmp" mm-inline-image (mm-valid-and-fit-image-p 'bmp handle)) ("text/plain" mm-inline-text t) ("text/enriched" mm-inline-text t) ("text/richtext" mm-inline-text t) @@ -114,11 +103,16 @@ (defvar mm-user-automatic-external-display nil "List of MIME type regexps that will be displayed externally automatically.") -(defvar mm-alternative-precedence - '("multipart/related" "multipart/mixed" "multipart/alternative" - "image/jpeg" "image/gif" "text/html" "text/enriched" - "text/richtext" "text/plain") - "List that describes the precedence of alternative parts.") +(defvar mm-discouraged-alternatives nil + "List of MIME types that are discouraged when viewing multiapart/alternative. +Viewing agents are supposed to view the last possible part of a message, +as that is supposed to be the richest. However, users may prefer other +types instead, and this list says what types are most unwanted. If, +for instance, text/html parts are very unwanted, and text/richtech are +somewhat unwanted, then the value of this variable should be set +to: + + (\"text/html\" \"text/richtext\")") (defvar mm-tmp-directory (cond ((fboundp 'temp-directory) (temp-directory)) @@ -466,7 +460,7 @@ This overrides entries in the mailcap file." "Return a version of ARG that is safe to evaluate in a shell." (let ((pos 0) new-pos accum) ;; *** bug: we don't handle newline characters properly - (while (setq new-pos (string-match "[;!`\"$\\& \t{} |()<>]" arg pos)) + (while (setq new-pos (string-match "[;!'`\"$\\& \t{} |()<>]" arg pos)) (push (substring arg pos new-pos) accum) (push "\\" accum) (push (list (aref arg new-pos)) accum) @@ -489,14 +483,24 @@ This overrides entries in the mailcap file." "Insert the contents of HANDLE in the current buffer." (let ((cur (current-buffer))) (save-excursion - (mm-with-unibyte-buffer - (insert-buffer-substring (mm-handle-buffer handle)) - (mm-decode-content-transfer-encoding - (mm-handle-encoding handle) - (car (mm-handle-type handle))) - (let ((temp (current-buffer))) - (set-buffer cur) - (insert-buffer-substring temp)))))) + (if (member (car (split-string (car (mm-handle-type handle)) "/")) + '("text" "message")) + (with-temp-buffer + (insert-buffer-substring (mm-handle-buffer handle)) + (mm-decode-content-transfer-encoding + (mm-handle-encoding handle) + (car (mm-handle-type handle))) + (let ((temp (current-buffer))) + (set-buffer cur) + (insert-buffer-substring temp))) + (mm-with-unibyte-buffer + (insert-buffer-substring (mm-handle-buffer handle)) + (mm-decode-content-transfer-encoding + (mm-handle-encoding handle) + (car (mm-handle-type handle))) + (let ((temp (current-buffer))) + (set-buffer cur) + (insert-buffer-substring temp))))))) (defvar mm-default-directory nil) @@ -521,21 +525,21 @@ This overrides entries in the mailcap file." file))) ;; Now every coding system is 100% binary within mm-with-unibyte-buffer ;; Is text still special? - (let ((coding-system-for-write - (if (equal "text" (car (split-string - (car (mm-handle-type handle)) "/"))) - buffer-file-coding-system - '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. - (inhibit-file-name-operation 'write-region) - (inhibit-file-name-handlers - (if (equal (car (mm-handle-type handle)) - "application/octet-stream") - (cons 'jka-compr-handler inhibit-file-name-handlers) - inhibit-file-name-handlers))) - (write-region (point-min) (point-max) file)))))) + (let ((coding-system-for-write + (if (equal "text" (car (split-string + (car (mm-handle-type handle)) "/"))) + buffer-file-coding-system + '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. + (inhibit-file-name-operation 'write-region) + (inhibit-file-name-handlers + (if (equal (car (mm-handle-type handle)) + "application/octet-stream") + (cons 'jka-compr-handler inhibit-file-name-handlers) + inhibit-file-name-handlers))) + (write-region (point-min) (point-max) file)))))) (defun mm-pipe-part (handle) "Pipe HANDLE to a process." @@ -557,7 +561,8 @@ This overrides entries in the mailcap file." (defun mm-preferred-alternative (handles &optional preferred) "Say which of HANDLES are preferred." - (let ((prec (if preferred (list preferred) mm-alternative-precedence)) + (let ((prec (if preferred (list preferred) + (mm-preferred-alternative-precedence handles))) p h result type handle) (while (setq p (pop prec)) (setq h handles) @@ -579,6 +584,15 @@ This overrides entries in the mailcap file." (pop h))) result)) +(defun mm-preferred-alternative-precedence (handles) + "Return the precedence based on HANDLES and mm-discouraged-alternatives." + (let ((seq (mapcar (lambda (h) (car (mm-handle-type h))) handles))) + (dolist (disc (reverse mm-discouraged-alternatives)) + (dolist (elem (copy-sequence seq)) + (when (string-match disc elem) + (setq seq (nconc (delete elem seq) (list elem)))))) + seq)) + (defun mm-get-content-id (id) "Return the handle(s) referred to by ID." (cdr (assoc id mm-content-id-alist))) @@ -601,16 +615,24 @@ This overrides entries in the mailcap file." (prog1 (setq spec (ignore-errors - (make-glyph - (cond - ((equal type "xbm") - (let ((height 32) - (width 32)) - (forward-line 2) - (vector 'xbm :data (list height width - (buffer-substring - (point) (point-max)))))) - (t + (cond + ((equal type "xbm") + ;; xbm images require special handling, since + ;; the only way to create glyphs from these + ;; (without a ton of work) is to write them + ;; out to a file, and then create a file + ;; specifier. + (let ((file (make-temp-name + (expand-file-name "emm.xbm" + mm-tmp-directory)))) + (unwind-protect + (progn + (write-region (point-min) (point-max) file) + (make-glyph (list (cons 'x file)))) + (ignore-errors + (delete-file file))))) + (t + (make-glyph (vector (intern type) :data (buffer-string))))))) (mm-handle-set-cache handle spec)))))) @@ -621,6 +643,17 @@ This overrides entries in the mailcap file." (and (< (glyph-width image) (window-pixel-width)) (< (glyph-height image) (window-pixel-height)))))) +(defun mm-valid-image-format-p (format) + "Say whether FORMAT can be displayed natively by Emacs." + (and (fboundp 'valid-image-instantiator-format-p) + (valid-image-instantiator-format-p format))) + +(defun mm-valid-and-fit-image-p (format handle) + "Say whether FORMAT can be displayed natively and HANDLE fits the window." + (and window-system + (mm-valid-image-format-p format) + (mm-image-fit-p handle))) + (provide 'mm-decode) ;; mm-decode.el ends here diff --git a/lisp/mm-util.el b/lisp/mm-util.el index 1807327..dfad2a2 100644 --- a/lisp/mm-util.el +++ b/lisp/mm-util.el @@ -126,7 +126,6 @@ (defvar mm-charset-synonym-alist '((big5 . cn-big5) (gb2312 . cn-gb-2312) - (iso-2022-jp-2 . iso-2022-7bit-ss2) (x-ctext . ctext)) "A mapping from invalid charset names to the real charset names.") diff --git a/lisp/mm-view.el b/lisp/mm-view.el index 1fc7992..b81c78b 100644 --- a/lisp/mm-view.el +++ b/lisp/mm-view.el @@ -74,15 +74,17 @@ (let ((w3-strict-width width) (url-standalone-mode t)) (w3-region (point-min) (point-max))))) + (narrow-to-region (1+ (point-min)) (point-max)) (mm-handle-set-undisplayer handle `(lambda () (let (buffer-read-only) - (mapc (lambda (prop) - (remove-specifier - (face-property 'default prop) (current-buffer))) - '(background background-pixmap foreground)) - (delete-region ,(point-min-marker) ,(point-max-marker)))))))) + (mapc (lambda (prop) + (remove-specifier + (face-property 'default prop) (current-buffer))) + '(background background-pixmap foreground)) + (delete-region ,(point-min-marker) + ,(point-max-marker)))))))) ((or (equal type "enriched") (equal type "richtext")) (save-excursion diff --git a/lisp/mml.el b/lisp/mml.el index d233adf..70abd88 100644 --- a/lisp/mml.el +++ b/lisp/mml.el @@ -221,7 +221,7 @@ (setq charset (mm-encode-body)) (setq encoding (mm-body-encoding charset)) (setq coded (buffer-string))) - (with-temp-buffer + (mm-with-unibyte-buffer (cond ((cdr (assq 'buffer cont)) (insert-buffer-substring (cdr (assq 'buffer cont)))) @@ -242,21 +242,23 @@ (when name (setq name (mml-parse-file-name name)) (if (stringp name) - (insert ";\n " (mail-header-encode-parameter "name" name) - "\";\n access-type=local-file") - (insert - (format ";\n " - (mail-header-encode-parameter - "name" (file-name-nondirectory (nth 2 name))) - (mail-header-encode-parameter "site" (nth 1 name)) - (mail-header-encode-parameter - "directory" (file-name-directory (nth 2 name))))) - (insert ";\n access-type=" - (if (member (nth 0 name) '("ftp@" "anonymous@")) - "anon-ftp" - "ftp")))) + (mml-insert-parameter + (mail-header-encode-parameter "name" name) + "access-type=local-file") + (mml-insert-parameter + (mail-header-encode-parameter + "name" (file-name-nondirectory (nth 2 name))) + (mail-header-encode-parameter "site" (nth 1 name)) + (mail-header-encode-parameter + "directory" (file-name-directory (nth 2 name)))) + (mml-insert-parameter + (concat "access-type=" + (if (member (nth 0 name) '("ftp@" "anonymous@")) + "anon-ftp" + "ftp"))))) (when parameters - (insert parameters))) + (mml-insert-parameter-string + cont '(expiration size permission)))) (insert "\n\n") (insert "Content-Type: " (cdr (assq 'type cont)) "\n") (insert "Content-ID: " (message-make-message-id) "\n") @@ -338,7 +340,8 @@ (insert "; " (mail-header-encode-parameter "charset" (symbol-name charset)))) (when parameters - (insert parameters)) + (mml-insert-parameter-string + cont '(name access-type expiration size permission))) (insert "\n")) (setq parameters (mml-parameter-string @@ -347,7 +350,8 @@ parameters) (insert "Content-Disposition: " (or disposition "inline")) (when parameters - (insert parameters)) + (mml-insert-parameter-string + cont '(filename creation-date modification-date read-date))) (insert "\n")) (unless (eq encoding '7bit) (insert (format "Content-Transfer-Encoding: %s\n" encoding))) @@ -363,12 +367,23 @@ ;; Strip directory component from the filename parameter. (when (eq type 'filename) (setq value (file-name-nondirectory value))) - (setq string (concat string ";\n " + (setq string (concat string "; " (mail-header-encode-parameter (symbol-name type) value))))) (when (not (zerop (length string))) string))) +(defun mml-insert-parameter-string (cont types) + (let (value type) + (while (setq type (pop types)) + (when (setq value (cdr (assq type cont))) + ;; Strip directory component from the filename parameter. + (when (eq type 'filename) + (setq value (file-name-nondirectory value))) + (mml-insert-parameter + (mail-header-encode-parameter + (symbol-name type) value)))))) + (defvar ange-ftp-path-format) (defvar efs-path-regexp) (defun mml-parse-file-name (path) @@ -455,6 +470,17 @@ (equal (split-string (car (mm-handle-type handle)) "/") "text") (insert ">\n"))) +(defun mml-insert-parameter (&rest parameters) + "Insert PARAMETERS in a nice way." + (dolist (param parameters) + (insert ";") + (let ((point (point))) + (insert " " param) + (when (> (current-column) 71) + (goto-char point) + (insert "\n ") + (end-of-line))))) + ;;; ;;; Mode for inserting and editing MML forms ;;; @@ -464,6 +490,7 @@ (main (make-sparse-keymap))) (define-key map "f" 'mml-attach-file) (define-key map "b" 'mml-attach-buffer) + (define-key map "e" 'mml-attach-external) (define-key map "q" 'mml-quote-region) (define-key map "m" 'mml-insert-multipart) (define-key map "p" 'mml-insert-part) @@ -477,7 +504,8 @@ '("MML" ("Attach" ["File" mml-attach-file t] - ["Buffer" mml-attach-buffer t]) + ["Buffer" mml-attach-buffer t] + ["External" mml-attach-external t]) ("Insert" ["Multipart" mml-insert-multipart t] ["Part" mml-insert-part t]) @@ -504,7 +532,12 @@ minor-mode-map-alist))) (run-hooks 'mml-mode-hook)) -(defun mml-read-file (prompt) +;;; +;;; Helper functions for reading MIME stuff from the minibuffer and +;;; inserting stuff to the buffer. +;;; + +(defun mml-minibuffer-read-file (prompt) (let ((file (read-file-name prompt nil nil t))) ;; Prevent some common errors. This is inspired by similar code in ;; VM. @@ -516,22 +549,41 @@ (error "Permission denied: %s" file)) file)) -(defun mml-read-type (file) - (let* ((default (or (mm-default-file-encoding file) +(defun mml-minibuffer-read-type (name &optional default) + (let* ((default (or default + (mm-default-file-encoding name) ;; Perhaps here we should check what the file ;; looks like, and offer text/plain if it looks ;; like text/plain. "application/octet-stream")) (string (completing-read (format "Content type (default %s): " default) - (delete-duplicates - (mapcar (lambda (m) (list (cdr m))) mailcap-mime-extensions) - :test 'equal)))) + (mapcar + 'list + (delete-duplicates + (nconc + (mapcar (lambda (m) (cdr m)) + mailcap-mime-extensions) + (apply + 'nconc + (mapcar + (lambda (l) + (delq nil + (mapcar + (lambda (m) + (let ((type (cdr (assq 'type (cdr m))))) + (if (equal (cadr (split-string type "/")) + "*") + nil + type))) + (cdr l)))) + mailcap-mime-data))) + :test 'equal))))) (if (not (equal string "")) string default))) -(defun mml-read-description () +(defun mml-minibuffer-read-description () (let ((description (read-string "One line description: "))) (when (string-match "\\`[ \t]*\\'" description) (setq description nil)) @@ -541,12 +593,33 @@ "Quote the MML tags in the region." (interactive "r") (save-excursion - (goto-char beg) - ;; Quote parts. - (while (re-search-forward - "<#/?!*\\(multipart\\|part\\|external\\)" end t) - (goto-char (match-beginning 1)) - (insert "!")))) + (save-restriction + ;; Temporarily narrow the region to defend from changes + ;; invalidating END. + (narrow-to-region beg end) + (goto-char (point-min)) + ;; Quote parts. + (while (re-search-forward + "<#/?!*\\(multipart\\|part\\|external\\)" nil t) + (goto-char (match-beginning 1)) + (insert "!"))))) + +(defun mml-insert-tag (name &rest plist) + "Insert an MML tag described by NAME and PLIST." + (when (symbolp name) + (setq name (symbol-name name))) + (insert "<#" name) + (while plist + (let ((key (pop plist)) + (value (pop plist))) + (when value + ;; Quote VALUE if it contains suspicious characters. + (when (string-match "[\"\\~/* \t\n]" value) + (setq value (prin1-to-string value))) + (insert (format " %s=%s" key value))))) + (insert ">\n<#/part>\n")) + +;;; Attachment functions. (defun mml-attach-file (file &optional type description) "Attach a file to the outgoing MIME message. @@ -557,33 +630,66 @@ FILE is the name of the file to attach. TYPE is its content-type, a string of the form \"type/subtype\". DESCRIPTION is a one-line description of the attachment." (interactive - (let* ((file (mml-read-file "Attach file: ")) - (type (mml-read-type file)) - (description (mml-read-description))) + (let* ((file (mml-minibuffer-read-file "Attach file: ")) + (type (mml-minibuffer-read-type file)) + (description (mml-minibuffer-read-description))) (list file type description))) - (insert - (format - "<#part type=%s name=%s filename=%s%s disposition=attachment><#/part>\n" - type (prin1-to-string (file-name-nondirectory file)) - (prin1-to-string file) - (if description - (format " description=%s" (prin1-to-string description)) - "")))) + (mml-insert-tag 'part 'type type 'filename file 'disposition "attachment" + 'description description)) + +(defun mml-attach-buffer (buffer &optional type description) + "Attach a buffer to the outgoing MIME message. +See `mml-attach-file' for details of operation." + (interactive + (let* ((buffer (read-buffer "Attach buffer: ")) + (type (mml-minibuffer-read-type buffer "text/plain")) + (description (mml-minibuffer-read-description))) + (list buffer type description))) + (mml-insert-tag 'part 'type type 'buffer buffer 'disposition "attachment" + 'description description)) (defun mml-attach-external (file &optional type description) "Attach an external file into the buffer. FILE is an ange-ftp/efs specification of the part location. TYPE is the MIME type to use." (interactive - (let* ((file (mml-read-file "Attach external file: ")) - (type (mml-read-type file)) - (description (mml-read-description))) + (let* ((file (mml-minibuffer-read-file "Attach external file: ")) + (type (mml-minibuffer-read-type file)) + (description (mml-minibuffer-read-description))) (list file type description))) - (insert (format - "<#external type=%s name=%s disposition=attachment><#/external>\n" - type (prin1-to-string file)))) - - + (mml-insert-tag 'external 'type type 'name file 'disposition "attachment" + 'description description)) + +(defun mml-insert-multipart (&optional type) + (interactive (list (completing-read "Multipart type (default mixed): ") + "mixed" + '(("mixed") ("alternative") ("digest") ("parallel") + ("signed") ("encrypted")))) + (or type + (setq type "mixed")) + (mml-insert-tag "multipart" 'type type) + (insert "<#/!multipart>\n") + (forward-line -1)) + +(defun mml-preview (&optional raw) + "Display current buffer with Gnus, in a new buffer. +If RAW, don't highlight the article." + (interactive "P") + (let ((buf (current-buffer))) + (switch-to-buffer (get-buffer-create + (concat (if raw "*Raw MIME preview of " + "*MIME preview of ") (buffer-name)))) + (erase-buffer) + (insert-buffer buf) + (mml-to-mime) + (unless raw + (run-hooks 'gnus-article-decode-hook) + (let ((gnus-newsgroup-name "dummy")) + (gnus-article-prepare-display))) + (fundamental-mode) + (setq buffer-read-only t) + (goto-char (point-min)))) + (provide 'mml) ;;; mml.el ends here diff --git a/lisp/nndoc.el b/lisp/nndoc.el index 8124262..f573b2d 100644 --- a/lisp/nndoc.el +++ b/lisp/nndoc.el @@ -464,10 +464,13 @@ from the document.") (defun nndoc-generate-mime-parts-head (article) (let* ((entry (cdr (assq article nndoc-dissection-alist))) (headers (nth 6 entry))) + (save-restriction + (narrow-to-region (point) (point)) + (insert-buffer-substring + nndoc-current-buffer (car entry) (nth 1 entry)) + (goto-char (point-max))) (when headers - (insert headers)) - (insert-buffer-substring - nndoc-current-buffer (car entry) (nth 1 entry)))) + (insert headers)))) (defun nndoc-clari-briefs-type-p () (when (let ((case-fold-search nil)) diff --git a/lisp/nndraft.el b/lisp/nndraft.el index 662fb09..4e09515 100644 --- a/lisp/nndraft.el +++ b/lisp/nndraft.el @@ -110,7 +110,9 @@ (nntp-server-buffer (or buffer nntp-server-buffer))) (when (and (file-exists-p newest) (let ((nnmail-file-coding-system - message-draft-coding-system)) + (if (file-newer-than-file-p file auto) + 'binary + message-draft-coding-system))) (nnmail-find-file newest))) (save-excursion (set-buffer nntp-server-buffer) diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el index 9c8681e..72770a9 100644 --- a/lisp/nnfolder.el +++ b/lisp/nnfolder.el @@ -407,7 +407,7 @@ time saver for large mailboxes.") (goto-char (point-min)) (if xfrom (insert "From " xfrom "\n") - (unless (looking-at message-unix-mail-delimiter) + (unless (looking-at "From ") (insert "From nobody " (current-time-string) "\n")))) (nnfolder-normalize-buffer) (set-buffer nnfolder-current-buffer) @@ -589,10 +589,10 @@ deleted. Point is left where the deleted region was." (let* (save-list group-art) (goto-char (point-min)) ;; The From line may have been quoted by movemail. - (when (looking-at (concat ">" message-unix-mail-delimiter)) + (when (looking-at ">From") (delete-char 1)) ;; This might come from somewhere else. - (unless (looking-at message-unix-mail-delimiter) + (unless (looking-at "From ") (insert "From nobody " (current-time-string) "\n") (goto-char (point-min))) ;; Quote all "From " lines in the article. @@ -703,7 +703,7 @@ deleted. Point is left where the deleted region was." (save-excursion (nnmail-activate 'nnfolder) ;; Read in the file. - (let ((delim (concat "^" message-unix-mail-delimiter)) + (let ((delim "^From ") (marker (concat "\n" nnfolder-article-marker)) (number "[0-9]+") (active (or (cadr (assoc group nnfolder-group-alist)) diff --git a/lisp/nnheader.el b/lisp/nnheader.el index 3b662a5..02fe048 100644 --- a/lisp/nnheader.el +++ b/lisp/nnheader.el @@ -775,6 +775,7 @@ find-file-hooks, etc. (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))) @@ -785,6 +786,7 @@ find-file-hooks, etc. (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)) (apply 'find-file-noselect args))) diff --git a/lisp/nnmail.el b/lisp/nnmail.el index de31551..d120169 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -174,7 +174,7 @@ Eg.: (defcustom nnmail-spool-file '((file)) "*Where the mail backends will look for incoming mail. This variable is a list of mail source specifiers. -If this variable is nil, no mail backends will read incoming mail." +This variable is obsolete; `mail-sources' should be used instead." :group 'nnmail-files :type 'sexp) @@ -856,7 +856,7 @@ FUNC will be called with the group name to determine the article number." (let ((methods nnmail-split-methods) (obuf (current-buffer)) (beg (point-min)) - end group-art method regrepp) + end group-art method grp) (if (and (sequencep methods) (= (length methods) 1)) ;; If there is only just one group to put everything in, we @@ -923,25 +923,24 @@ FUNC will be called with the group name to determine the article number." (not group-art))) (goto-char (point-max)) (setq method (pop methods) - regrepp nil) + grp (car method)) (if (or methods (not (equal "" (nth 1 method)))) (when (and (ignore-errors (if (stringp (nth 1 method)) - (progn - (setq regrepp - (string-match "\\\\[0-9&]" (car method))) - (re-search-backward (cadr method) nil t)) + (let ((expand (string-match "\\\\[0-9&]" grp)) + (pos (re-search-backward (cadr method) + nil t))) + (and expand + (setq grp (nnmail-expand-newtext grp))) + pos) ;; Function to say whether this is a match. - (funcall (nth 1 method) (car method)))) + (funcall (nth 1 method) grp))) ;; Don't enter the article into the same ;; group twice. - (not (assoc (car method) group-art))) - (push (cons (if regrepp - (nnmail-expand-newtext (car method)) - (car method)) - (funcall func (car method))) + (not (assoc grp group-art))) + (push (cons grp (funcall func grp)) group-art)) ;; This is the final group, which is used as a ;; catch-all. @@ -1337,10 +1336,13 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (defun nnmail-get-new-mail (method exit-func temp &optional group spool-func) "Read new incoming mail." - (let* ((sources (if (listp nnmail-spool-file) nnmail-spool-file - (list nnmail-spool-file))) + (let* ((sources (or mail-sources + (if (listp nnmail-spool-file) nnmail-spool-file + (list nnmail-spool-file)))) (group-in group) (i 0) + (new 0) + (total 0) incoming incomings source) (when (and (nnmail-get-value "%s-get-new-mail" method) nnmail-spool-file) @@ -1375,9 +1377,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (list :predicate `(lambda (file) - (string-match + (string-match ,(concat - (regexp-quote (concat group suffix)) + (regexp-quote (concat group suffix)) "$") file))))))) (when nnmail-fetched-sources @@ -1387,13 +1389,16 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (when source (nnheader-message 4 "%s: Reading incoming mail from %s..." method (car source)) - (when (mail-source-fetch - source - `(lambda (file orig-file) - (nnmail-split-incoming - file ',(intern (format "%s-save-mail" method)) - ',spool-func (nnmail-get-split-group orig-file source) - ',(intern (format "%s-active-number" method))))) + (when (setq new + (mail-source-fetch + source + `(lambda (file orig-file) + (nnmail-split-incoming + file ',(intern (format "%s-save-mail" method)) + ',spool-func + (nnmail-get-split-group orig-file source) + ',(intern (format "%s-active-number" method)))))) + (incf total new) (incf i)))) ;; If we did indeed read any incoming spools, we save all info. (unless (zerop i) @@ -1403,7 +1408,8 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (when exit-func (funcall exit-func)) (run-hooks 'nnmail-read-incoming-hook) - (nnheader-message 4 "%s: Reading incoming mail...done" method)) + (nnheader-message 4 "%s: Reading incoming mail (%d new)...done" method + total)) ;; Close the message-id cache. (nnmail-cache-close) ;; Allow the user to hook. diff --git a/lisp/nnml.el b/lisp/nnml.el index ed3e365..e47448c 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -264,8 +264,7 @@ all. This may very well take some time.") (save-excursion (nnmail-find-file nnml-newsgroups-file))) -(deffoo nnml-request-expire-articles (articles group - &optional server force) +(deffoo nnml-request-expire-articles (articles group &optional server force) (nnml-possibly-change-directory group server) (let ((active-articles (nnheader-directory-articles nnml-current-directory)) diff --git a/lisp/nnvirtual.el b/lisp/nnvirtual.el index 1b745ee..19fa59f 100644 --- a/lisp/nnvirtual.el +++ b/lisp/nnvirtual.el @@ -362,6 +362,15 @@ to virtual article number.") (cdr gnus-message-group-art))))) (gnus-request-post (gnus-find-method-for-group group))))) + +(deffoo nnvirtual-request-expire-articles (articles group + &optional server force) + (nnvirtual-possibly-change-server server) + (setq nnvirtual-component-groups + (delete (nnvirtual-current-group) nnvirtual-component-groups)) + (dolist (group nnvirtual-component-groups) + (gnus-group-expire-articles-1 group))) + ;;; Internal functions. diff --git a/lisp/pop3.el b/lisp/pop3.el index 0b6318b..4b96978 100644 --- a/lisp/pop3.el +++ b/lisp/pop3.el @@ -4,7 +4,7 @@ ;; Author: Richard L. Pieri ;; Keywords: mail, pop3 -;; Version: 1.3q +;; Version: 1.3r ;; This file is part of GNU Emacs. @@ -37,7 +37,7 @@ (require 'mail-utils) (provide 'pop3) -(defconst pop3-version "1.3m") +(defconst pop3-version "1.3r") (defvar pop3-maildrop (or (user-login-name) (getenv "LOGNAME") (getenv "USER") nil) "*POP3 maildrop.") @@ -246,7 +246,15 @@ Return the response string if optional second argument is non-nil." (setq From_ (concat (substring From_ 0 (match-beginning 0)) (substring From_ (match-end 0))))) (goto-char (point-min)) - (insert From_)))))) + (insert From_) + (re-search-forward "\n\n") + (narrow-to-region (point) (point-max)) + (let ((size (- (point-max) (point-min)))) + (goto-char (point-min)) + (widen) + (forward-line -2) + (insert (format "Content-Length: %s\n" size))) + ))))) ;; The Command Set diff --git a/lisp/rfc2231.el b/lisp/rfc2231.el index bbe19a5..8ee24b9 100644 --- a/lisp/rfc2231.el +++ b/lisp/rfc2231.el @@ -60,57 +60,60 @@ The list will be on the form (unless (eq c ?\;) (error "Invalid header: %s" string)) (forward-char 1) - (setq c (char-after)) - (if (and (memq c ttoken) - (not (memq c stoken))) - (setq attribute - (intern - (downcase - (buffer-substring - (point) (progn (forward-sexp 1) (point)))))) - (error "Invalid header: %s" string)) - (setq c (char-after)) - (setq encoded nil) - (when (eq c ?*) - (forward-char 1) + ;; If c in nil, then this is an invalid header, but + ;; since elm generates invalid headers on this form, + ;; we allow it. + (when (setq c (char-after)) + (if (and (memq c ttoken) + (not (memq c stoken))) + (setq attribute + (intern + (downcase + (buffer-substring + (point) (progn (forward-sexp 1) (point)))))) + (error "Invalid header: %s" string)) (setq c (char-after)) - (when (memq c ntoken) - (setq number - (string-to-number - (buffer-substring - (point) (progn (forward-sexp 1) (point))))) + (setq encoded nil) + (when (eq c ?*) + (forward-char 1) (setq c (char-after)) - (when (eq c ?*) - (setq encoded t) - (forward-char 1) - (setq c (char-after))))) - ;; See if we have any previous continuations. - (when (and prev-attribute - (not (eq prev-attribute attribute))) - (push (cons prev-attribute prev-value) parameters) - (setq prev-attribute nil - prev-value "")) - (unless (eq c ?=) - (error "Invalid header: %s" string)) - (forward-char 1) - (setq c (char-after)) - (cond - ((eq c ?\") - (setq value - (buffer-substring (1+ (point)) - (progn (forward-sexp 1) (1- (point)))))) - ((and (memq c ttoken) - (not (memq c stoken))) - (setq value (buffer-substring - (point) (progn (forward-sexp 1) (point))))) - (t - (error "Invalid header: %s" string))) - (when encoded - (setq value (rfc2231-decode-encoded-string value))) - (if number - (setq prev-attribute attribute - prev-value (concat prev-value value)) - (push (cons attribute value) parameters))) + (when (memq c ntoken) + (setq number + (string-to-number + (buffer-substring + (point) (progn (forward-sexp 1) (point))))) + (setq c (char-after)) + (when (eq c ?*) + (setq encoded t) + (forward-char 1) + (setq c (char-after))))) + ;; See if we have any previous continuations. + (when (and prev-attribute + (not (eq prev-attribute attribute))) + (push (cons prev-attribute prev-value) parameters) + (setq prev-attribute nil + prev-value "")) + (unless (eq c ?=) + (error "Invalid header: %s" string)) + (forward-char 1) + (setq c (char-after)) + (cond + ((eq c ?\") + (setq value + (buffer-substring (1+ (point)) + (progn (forward-sexp 1) (1- (point)))))) + ((and (memq c ttoken) + (not (memq c stoken))) + (setq value (buffer-substring + (point) (progn (forward-sexp 1) (point))))) + (t + (error "Invalid header: %s" string))) + (when encoded + (setq value (rfc2231-decode-encoded-string value))) + (if number + (setq prev-attribute attribute + prev-value (concat prev-value value)) + (push (cons attribute value) parameters)))) ;; Take care of any final continuations. (when prev-attribute diff --git a/lisp/uudecode.el b/lisp/uudecode.el index 0703974..299f83b 100644 --- a/lisp/uudecode.el +++ b/lisp/uudecode.el @@ -2,7 +2,7 @@ ;; Copyright (c) 1998 by Shenghuo Zhu ;; Author: Shenghuo Zhu -;; $Revision: 5.6 $ +;; $Revision: 5.7 $ ;; Keywords: uudecode ;; This file is not part of GNU Emacs, but the same permissions @@ -55,7 +55,7 @@ input and write the converted data to its standard output.") (defvar uudecode-temporary-file-directory (cond ((fboundp 'temp-directory) (temp-directory)) ((boundp 'temporary-file-directory) temporary-file-directory) - ("/tmp/"))) + ("/tmp"))) ;;;###autoload (defun uudecode-decode-region-external (start end &optional file-name) @@ -75,9 +75,12 @@ If FILE-NAME is non-nil, save the result to FILE-NAME." (setq file-name (read-file-name "File to Name:" nil nil nil (match-string 1))))) - (setq tempfile (expand-file-name - (or file-name (concat uudecode-temporary-file-directory - (make-temp-name "uu"))))) + (setq tempfile (if file-name + (expand-file-name file-name) + (make-temp-name + ;; /tmp/uu... + (expand-file-name + "uu" uudecode-temporary-file-directory)))) (let ((cdir default-directory) default-process-coding-system) (unwind-protect (progn diff --git a/texi/ChangeLog b/texi/ChangeLog index cd413b4..f090506 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,36 @@ +1999-04-18 12:46:33 Lars Magne Ingebrigtsen + + * gnus.texi (Summary Score Commands): Typo. + (Choosing a Mail Backend): Addition. + +1999-04-18 09:24:51 Yoshiki Hayashi + + * gnus.texi (Startup Variables): Fix. + +1999-04-18 09:12:28 Starback + + * gnus.texi (Subscription Methods): Typo. + +1999-04-18 08:22:27 Lars Magne Ingebrigtsen + + * gnus.texi (Little Disk Space): Addition. + +1999-03-25 Erik Toubro Nielsen + + * gnus.texi (gnus-thread-sort-functions). 'reverse' => 'not' + +1999-04-17 10:21:01 Jack Twilley + + * gnus.texi (Fancy Mail Splitting): Addition. + +1999-04-07 06:13:08 Lars Magne Ingebrigtsen + + * gnus.texi (Gnus Development): New. + +1999-03-06 20:12:50 Lars Magne Ingebrigtsen + + * gnus.texi (Generic Marking Commands): New. + 1999-03-01 16:41:42 Rob Browning * gnus.texi (Score Variables): Clarify. diff --git a/texi/gnus.texi b/texi/gnus.texi index 3665f7b..98e5ac9 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -1,7 +1,8 @@ + \input texinfo @c -*-texinfo-*- @setfilename gnus -@settitle Pterodactyl Gnus 0.80 Manual +@settitle Pterodactyl Gnus 0.83 Manual @synindex fn cp @synindex vr cp @synindex pg cp @@ -318,7 +319,7 @@ into another language, under the above conditions for modified versions. @tex @titlepage -@title Pterodactyl Gnus 0.80 Manual +@title Pterodactyl Gnus 0.83 Manual @author by Lars Magne Ingebrigtsen @page @@ -354,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.80. +This manual corresponds to Pterodactyl Gnus 0.83. @end ifinfo @@ -706,7 +707,7 @@ Subscribe all new groups in alphabetical order. Subscribe all new groups hierarchically. The difference between this function and @code{gnus-subscribe-alphabetically} is slight. @code{gnus-subscribe-alphabetically} will subscribe new groups in a strictly -alphabetical fashion, while this function will enter groups into it's +alphabetical fashion, while this function will enter groups into its hierarchy. So if you want to have the @samp{rec} hierarchy before the @samp{comp} hierarchy, this function will not mess that configuration up. Or something like that. @@ -858,11 +859,15 @@ never delete the @file{.newsrc.eld} file---it contains much information not stored in the @file{.newsrc} file. @vindex gnus-save-newsrc-file +@vindex gnus-read-newsrc-file You can turn off writing the @file{.newsrc} file by setting @code{gnus-save-newsrc-file} to @code{nil}, which means you can delete the file and save some space, as well as exiting from Gnus faster. However, this will make it impossible to use other newsreaders than -Gnus. But hey, who would want to, right? +Gnus. But hey, who would want to, right? Similarly, setting +@code{gnus-read-newsrc-file} to @code{nil} makes Gnus ignore the +@file{.newsrc} file and any @file{.newsrc-SERVER} files, which is +convenient if you have a tendency to use Netscape once in a while. @vindex gnus-save-killed-list If @code{gnus-save-killed-list} (default @code{t}) is @code{nil}, Gnus @@ -1026,8 +1031,8 @@ A hook run as the very last thing after starting up Gnus A hook that is run as the very last thing after starting up Gnus successfully. -@item gnus-started-hook -@vindex gnus-started-hook +@item gnus-setup-news-hook +@vindex gnus-setup-news-hook A hook that is run after reading the @file{.newsrc} file(s), but before generating the group buffer. @@ -4188,8 +4193,9 @@ There's a plethora of commands for manipulating these marks: @end ifinfo @menu -* Setting Marks:: How to set and remove marks. -* Setting Process Marks:: How to mark articles for later processing. +* Setting Marks:: How to set and remove marks. +* Generic Marking Commands:: How to customize the marking. +* Setting Process Marks:: How to mark articles for later processing. @end menu @@ -4507,6 +4513,44 @@ one line up or down. As a special case, if this variable is The default is @code{t}. +@node Generic Marking Commands +@subsection Generic Marking Commands + +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 +previous (unread) article, I'm sure there are people that want that as +well. + +Multiply these five behaviours with five different marking commands, and +you get a potentially complex set of variable to control what each +command should do. + +To sidestep that mess, Gnus provides commands that do all these +different things. They can be found on the @kbd{M M} map in the summary +buffer. Type @kbd{M M C-h} to see them all---there are too many of them +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 +article, you could say something like: + +@lisp +(add-hook 'gnus-summary-mode-hook 'my-alter-summary-map) +(defun my-alter-summary-map () + (local-set-key "!" 'gnus-summary-put-mark-as-ticked-next)) +@end lisp + +or + +@lisp +(defun my-alter-summary-map () + (local-set-key "!" "MM!n")) +@end lisp + + @node Setting Process Marks @subsection Setting Process Marks @cindex setting process marks @@ -5267,7 +5311,7 @@ by number, you could do something like: (setq gnus-thread-sort-functions '(gnus-thread-sort-by-number gnus-thread-sort-by-subject - (reverse gnus-thread-sort-by-total-score))) + (not gnus-thread-sort-by-total-score))) @end lisp The threads that have highest score will be displayed first in the @@ -6475,7 +6519,7 @@ annoying banners and/or signatures that some mailing lists and moderated groups adds to all the messages. The way to use this function is to add the @code{banner} group parameter (@pxref{Group Parameters}) to the group you want banners stripped from. The parameter either be a string, -which will be interpreted as a regulax expression matching text to be +which will be interpreted as a regular expression matching text to be removed, or the symbol @code{signature}, meaning that the (last) signature should be removed. @@ -6696,6 +6740,12 @@ Add clickable buttons to the article (@code{gnus-article-add-buttons}). Add clickable buttons to the article headers (@code{gnus-article-add-buttons-to-head}). +@item W W H +@kindex W W H (Summary) +@findex gnus-article-strip-headers-from-body +Strip headers like the @code{X-No-Archive} header from the beginning of +article bodies (@code{gnus-article-strip-headers-from-body}). + @item W E l @kindex W E l (Summary) @findex gnus-article-strip-leading-blank-lines @@ -7048,6 +7098,10 @@ Here's an example function the does the latter: 'my-save-all-jpeg-parts) @end lisp +@vindex gnus-mime-multipart-functions +@item gnus-mime-multipart-functions +Alist of @sc{mime} multipart types and functions to handle them. + @end table @@ -8347,6 +8401,7 @@ group. @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 @@ -9911,12 +9966,6 @@ links. If that's the case for you, set @code{nnmail-crosspost-link-function} to @code{copy-file}. (This variable is @code{add-name-to-file} by default.) -@findex nnmail-split-header-length-limit -Header lines may be arbitrarily long. However, the longer a line is, -the longer it takes to match them. Very long lines may lead to Gnus -taking forever to split the mail, so Gnus excludes lines that are longer -than @code{nnmail-split-header-length-limit} (which defaults to 1024). - @kindex M-x nnmail-split-history @kindex nnmail-split-history If you wish to see where the previous mail split put the messages, you @@ -10015,6 +10064,10 @@ The default is @code{identity}. This is used as an additional filter---only files that have the right suffix @emph{and} satisfy this predicate are considered. +@item :prescript +@itemx :postscript +Script run before/after fetching mail. + @end table An example directory mail source: @@ -10193,18 +10246,21 @@ All new mail files will get this file mode. The default is 384. @node Fetching Mail @subsubsection Fetching Mail +@vindex mail-sources +@vindex nnmail-spool-file The way to actually tell Gnus where to get new mail from is to set -@code{nnmail-spool-file} to a list of mail source specifiers +@code{mail-sources} to a list of mail source specifiers (@pxref{Mail Source Specifiers}). -If this variable is @code{nil}, the mail backends will never attempt to -fetch mail by themselves. +If this variable (and the obsolescent @code{nnmail-spool-file}) is +@code{nil}, the mail backends will never attempt to fetch mail by +themselves. If you want to fetch mail both from your local spool as well as a POP mail server, you'd say something like: @lisp -(setq nnmail-spool-file +(setq mail-sources '((file) (pop :server "pop3.mail.server" :password "secret"))) @@ -10213,7 +10269,7 @@ mail server, you'd say something like: Or, if you don't want to use any of the keyword defaults: @lisp -(setq nnmail-spool-file +(setq mail-sources '((file :path "/var/spool/mail/user-name") (pop :server "pop3.mail.server" :user "user-name" @@ -10402,6 +10458,9 @@ substitutions in the group names), you can say things like: (any "debian-\\b\\(\\w+\\)@@lists.debian.org" "mail.debian.\\1") @end example +In this example, messages sent to @samp{debian-foo@@lists.debian.org} +will be filed in @samp{mail.debian.foo}. + If the string contains the element @samp{\&}, then the previously matched string will be substituted. Similarly, the elements @samp{\\1} up to @samp{\\9} will be substituted with the text matched by the @@ -10745,8 +10804,9 @@ If you start using any of the mail backends, they have the annoying habit of assuming that you want to read mail with them. This might not be unreasonable, but it might not be what you want. -If you set @code{nnmail-spool-file} to @code{nil}, none of the backends -will ever attempt to read incoming mail, which should help. +If you set @code{mail-sources} and @code{nnmail-spool-file} to +@code{nil}, none of the backends will ever attempt to read incoming +mail, which should help. @vindex nnbabyl-get-new-mail @vindex nnmbox-get-new-mail @@ -10772,6 +10832,11 @@ Gnus will read the mail spool when you activate a mail group. The mail file is first copied to your home directory. What happens after that depends on what format you want to store your mail in. +There are five different mail backends in the standard Gnus, and more +backends are available separately. The mail backend most people use +(because it is the fastest and most flexible) is @code{nnml} +(@pxref{Mail Spool}). + @menu * Unix Mail Box:: Using the (quite) standard Un*x mbox. * Rmail Babyl:: Emacs programs use the rmail babyl format. @@ -12059,7 +12124,9 @@ you're interested in the articles anyway. The main way to control what is to be downloaded is to create a @dfn{category} and then assign some (or all) groups to this category. -Gnus has its own buffer for creating and managing categories. +Groups that do not belong in any other category belong to the +@code{default} category. Gnus has its own buffer for creating and +managing categories. @menu * Category Syntax:: What a category looks like. @@ -12632,12 +12699,11 @@ setup, you may be able to use something like the following as your @lisp ;;; Define how Gnus is to fetch news. We do this over NNTP ;;; from your ISP's server. -(setq gnus-select-method '(nntp "nntp.your-isp.com")) +(setq gnus-select-method '(nntp "news.your-isp.com")) ;;; Define how Gnus is to read your mail. We read mail from ;;; your ISP's POP server. -(setenv "MAILHOST" "pop.your-isp.com") -(setq nnmail-spool-file "po:username") +(setq mail-sources '((pop :server "pop.your-isp.com"))) ;;; Say how Gnus is to store the mail. We use nnml groups. (setq gnus-secondary-select-methods '((nnml ""))) @@ -12895,7 +12961,7 @@ Score on the body. Score on the head. @item t -Score on thead. +Score on thread. @end table @@ -16335,6 +16401,7 @@ to that instead. * Compatibility:: Just how compatible is Gnus with @sc{gnus}? * Conformity:: Gnus tries to conform to all standards. * Emacsen:: Gnus can be run on a few modern Emacsen. +* Gnus Development:: How Gnus is developed. * Contributors:: Oodles of people. * New Features:: Pointers to some of the new stuff in Gnus. * Newest Features:: Features so new that they haven't been written yet. @@ -16516,6 +16583,44 @@ other than that, things should look pretty much the same under all Emacsen. +@node Gnus Development +@subsection Gnus Development + +Gnus is developed in a two-phased cycle. The first phase involves much +discussion on the @samp{ding@@gnus.org} mailing list, where people +propose changes and new features, post patches and new backends. This +phase is called the @dfn{alpha} phase, since the Gnusae released in this +phase are @dfn{alpha releases}, or (perhaps more commonly in other +circles) @dfn{snapshots}. During this phase, Gnus is assumed to be +unstable and should not be used by casual users. Gnus alpha releases +have names like ``Red Gnus'' and ``Quassia Gnus''. + +After futzing around for 50-100 alpha releases, Gnus is declared +@dfn{frozen}, and only bug fixes are applied. Gnus loses the prefix, +and is called things like ``Gnus 5.6.32'' instead. Normal people are +supposed to be able to use these, and these are mostly discussed on the +@samp{gnu.emacs.gnus} newsgroup. + +@cindex Incoming* +@vindex nnmail-delete-incoming +Some variable defaults differ between alpha Gnusae and released Gnusae. +In particular, @code{nnmail-delete-incoming} defaults to @code{nil} in +alpha Gnusae and @code{t} in released Gnusae. This is to prevent +lossage of mail if an alpha release hiccups while handling the mail. + +The division of discussion between the ding mailing list and the Gnus +newsgroup is not purely based on publicity concerns. It's true that +having people write about the horrible things that an alpha Gnus release +can do (sometimes) in a public forum may scare people off, but more +importantly, talking about new experimental features that have been +introduced may confuse casual users. New features are frequently +introduced, fiddled with, and judged to be found wanting, and then +either discarded or totally rewritten. People reading the mailing list +usually keep up with these rapid changes, whille people on the newsgroup +can't be assumed to do so. + + + @node Contributors @subsection Contributors @cindex contributors @@ -18681,10 +18786,6 @@ If point is on a group that appears multiple times in topics, and you press `l', point will move to the first instance of the group. @item -The documentation should mention pop3.el, fetchmail, smtpmail and why -po:username often fails. - -@item Fetch by Message-ID from dejanews. @@ -18702,6 +18803,18 @@ When stading on a topic line and `t'-ing, point goes to the last line. It should go somewhere else. @item +I'm having trouble accessing a newsgroup with a "+" in its name with +Gnus. There is a new newsgroup on msnews.microsoft.com named +"microsoft.public.multimedia.directx.html+time" that I'm trying to +access as +"nntp+msnews.microsoft.com:microsoft.public.multimedia.directx.html+time" +but it gives an error that it cant access the group. + +Is the "+" character illegal in newsgroup names? Is there any way in +Gnus to work around this? (gnus 5.6.45 - XEmacs 20.4) + + +@item Solve the halting problem. @c TODO @@ -19061,6 +19174,12 @@ only save @file{.newsrc.eld}. This means that you will not be able to use any other newsreaders than Gnus. This variable is @code{t} by default. +@item gnus-read-newsrc-file +If this is @code{nil}, Gnus will never read @file{.newsrc}---it will +only read @file{.newsrc.eld}. This means that you will not be able to +use any other newsreaders than Gnus. This variable is @code{t} by +default. + @item gnus-save-killed-list If this is @code{nil}, Gnus will not save the list of dead groups. You should also set @code{gnus-check-new-newsgroups} to @code{ask-server} diff --git a/texi/message.texi b/texi/message.texi index 3350daf..daba9f8 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @setfilename message -@settitle Pterodactyl Message 0.80 Manual +@settitle Pterodactyl Message 0.83 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.80 Manual +@title Pterodactyl Message 0.83 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.80. Message is +This manual corresponds to Pterodactyl Message 0.83. Message is distributed with the Gnus distribution bearing the same version number as this manual. -- 1.7.10.4