+Sat Nov 14 01:51:06 1998 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
+
+ * gnus.el: Pterodactyl Gnus v0.43 is released.
+
+1998-11-07 Karl Kleinpaste <karl@jprc.com>
+
+ * gnus-cus.el (gnus-score-customize): Add "Extra" element.
+ * gnus-score.el (gnus-score-default-header): Ditto.
+ (gnus-header-index): Ditto.
+ (gnus-summary-increase-score): Ditto, & process "extra" requests.
+ (gnus-summary-header): Handle extra headers.
+ (gnus-summary-score-entry): Ditto, & provide new score element.
+ (gnus-summary-score-effect): Ditto.
+ (gnus-score-string): Avoid "extra" string sort, & modify match in
+ "extra" case.
+ * gnus-sum.el (gnus-make-score-map): Add "extra" element.
+
+1998-11-13 20:30:40 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * message.el (message-resend): Bind message-required-mail-headers
+ to nil.
+
+ * mm-view.el (mm-inline-text): Bind w3-strict-width.
+
+ * nngateway.el (require): Require cl.
+
+ * gnus-art.el (gnus-button-alist): Exclude more chars from news:
+ things.
+
+Wed Nov 11 02:15:06 1998 Shenghuo ZHU <zsh@cs.rochester.edu>
+
+ * gnus-agent.el (gnus-agent-fetch-headers): Create directory even
+ when no articles.
+
+1998-11-13 19:25:10 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * message.el (message-ignored-resent-headers): Remove X-Gnus.
+
+1998-11-10 Colin Rafferty <colin@xemacs.org>
+
+ * gnus-sum.el (gnus-ignored-from-addresses): Only quote
+ user-mail-address if non-nil.
+
+1998-11-13 18:50:18 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-util.el (gnus-make-sort-function): Do `reverse'.
+ (gnus-make-sort-function-1): Ditto.
+
+ * gnus-art.el (gnus-mm-display-part): Switch to mm in right
+ window.
+
+1998-11-12 22:31:58 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * mm-util.el (mm-with-unibyte-buffer): Ditto.
+
+ * binhex.el (binhex-decode-region): Quote.
+
+1998-11-10 05:32:28 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-art.el (article-decode-charset): Don't downcase charset.
+
+ * gnus-sum.el (gnus-get-newsgroup-headers-xover): Translate CR's.
+
Sun Nov 8 23:17:24 1998 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
* gnus.el: Pterodactyl Gnus v0.42 is released.
;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
;; Create Date: Oct 1, 1998
-;; $Revision: 1.2 $
+;; $Revision: 5.1 $
;; Time-stamp: <Tue Oct 6 23:48:38 EDT 1998 zsh>
;; Keywords: binhex
(when (re-search-forward binhex-begin-line end t)
(if (boundp 'enable-multibyte-characters)
(let ((multibyte
- (default-value enable-multibyte-characters)))
+ (default-value 'enable-multibyte-characters)))
(setq-default enable-multibyte-characters nil)
(setq work-buffer
(generate-new-buffer " *binhex-work*"))
(gnus-delete-line))
(insert group " " (number-to-string (cdr active)) " "
(number-to-string (car active)) " y\n"))
- (when (re-search-forward (concat (regexp-quote group) "\\($\\| \\)") nil t)
+ (when (re-search-forward
+ (concat (regexp-quote group) "\\($\\| \\)") nil t)
(gnus-delete-line))
(insert-buffer-substring nntp-server-buffer))))))
(cons (1+ (caar (last gnus-agent-article-alist)))
(cdr (gnus-active group)))))
(gnus-list-of-unread-articles group)))
- (gnus-decode-encoded-word-function 'identity))
+ (gnus-decode-encoded-word-function 'identity)
+ (file (gnus-agent-article-name ".overview" group)))
;; Fetch them.
+ (gnus-make-directory (nnheader-translate-file-chars
+ (file-name-directory file)))
(when articles
(gnus-message 7 "Fetching headers for %s..." group)
(save-excursion
(nnvirtual-convert-headers))
;; Save these headers for later processing.
(copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max))
- (let (file)
- (when (file-exists-p
- (setq file (gnus-agent-article-name ".overview" group)))
- (gnus-agent-braid-nov group articles file))
- (gnus-make-directory (nnheader-translate-file-chars
- (file-name-directory file)))
- (let ((coding-system-for-write
- gnus-agent-file-coding-system))
- (write-region (point-min) (point-max) file nil 'silent))
- (gnus-agent-save-alist group articles nil)
- (gnus-agent-enter-history
- "last-header-fetched-for-session"
- (list (cons group (nth (- (length articles) 1) articles)))
- (time-to-days (current-time)))
- articles)))))
+ (when (file-exists-p file)
+ (gnus-agent-braid-nov group articles file))
+ (let ((coding-system-for-write
+ gnus-agent-file-coding-system))
+ (write-region (point-min) (point-max) file nil 'silent))
+ (gnus-agent-save-alist group articles nil)
+ (gnus-agent-enter-history
+ "last-header-fetched-for-session"
+ (list (cons group (nth (- (length articles) 1) articles)))
+ (time-to-days (current-time)))
+ articles))))
(defsubst gnus-agent-copy-nov-line (article)
(let (b e)
(gnus-group-find-parameter
gnus-newsgroup-name 'charset))))
buffer-read-only)
- (when charset
- (setq charset (downcase charset)))
(goto-char (point-max))
(widen)
(forward-line 1)
(gnus-insert-mime-button
handle id (list (not (mm-handle-displayed-p handle))))
(prog1
- (mm-display-part handle)
+ (let ((window (selected-window)))
+ (save-excursion
+ (unwind-protect
+ (progn
+ (select-window (get-buffer-window (current-buffer) t))
+ (mm-display-part handle))
+ (select-window window))))
(goto-char point))))
(defun gnus-article-goto-part (n)
:type 'regexp)
(defcustom gnus-button-alist
- `(("<\\(url:[>\n\t ]*?\\)?news:[>\n\t ]*\\([^>\n\t ]*@[^>\n\t ]*\\)>" 0 t
- gnus-button-message-id 2)
- ("\\bnews:\\([^>\n\t ]*@[^>\n\t ]*\\)" 0 t gnus-button-message-id 1)
+ `(("<\\(url:[>\n\t ]*?\\)?news:[>\n\t ]*\\([^>\n\t ]*@[^)!;:,>\n\t ]*\\)>"
+ 0 t gnus-button-message-id 2)
+ ("\\bnews:\\([^>\n\t ]*@[^>)!;:,\n\t ]*\\)" 0 t gnus-button-message-id 1)
("\\(\\b<\\(url:[>\n\t ]*\\)?news:[>\n\t ]*\\(//\\)?\\([^>\n\t ]*\\)>\\)"
1 t
gnus-button-fetch-group 4)
(gnus-score-string :tag "Subject")
(gnus-score-string :tag "References")
(gnus-score-string :tag "Xref")
+ (gnus-score-string :tag "Extra")
(gnus-score-string :tag "Message-ID")
(gnus-score-integer :tag "Lines")
(gnus-score-integer :tag "Chars")
i: message-id
t: references
x: xref
+ e: `extra' (non-standard overview)
l: lines
d: date
f: followup
(const :tag "message-id" i)
(const :tag "references" t)
(const :tag "xref" x)
+ (const :tag "extra" e)
(const :tag "lines" l)
(const :tag "date" d)
(const :tag "followup" f)
("chars" 6 gnus-score-integer)
("lines" 7 gnus-score-integer)
("xref" 8 gnus-score-string)
+ ("extra" 9 gnus-score-string)
("head" -1 gnus-score-body)
("body" -1 gnus-score-body)
("all" -1 gnus-score-body)
(?i "message-id" nil t string)
(?r "references" "message-id" nil string)
(?x "xref" nil nil string)
+ (?e "extra" nil nil string)
(?l "lines" nil nil number)
(?d "date" nil nil date)
(?f "followup" nil nil string)
(aref (symbol-name gnus-score-default-type) 0)))
(pchar (and gnus-score-default-duration
(aref (symbol-name gnus-score-default-duration) 0)))
- entry temporary type match)
+ entry temporary type match extra)
(unwind-protect
(progn
;; Always kill the score help buffer.
(gnus-score-kill-help-buffer))
+ ;; If scoring an extra (non-standard overview) header,
+ ;; we must find out which header is in question.
+ (setq extra
+ (and gnus-extra-headers
+ (equal (nth 1 entry) "extra")
+ (intern ; need symbol
+ (gnus-completing-read
+ (symbol-name (car gnus-extra-headers)) ; default response
+ "Score extra header:" ; prompt
+ (mapcar (lambda (x) ; completion list
+ (cons (symbol-name x) x))
+ gnus-extra-headers)
+ nil ; no completion limit
+ t)))) ; require match
+ ;; extra is now nil or a symbol.
+
;; We have all the data, so we enter this score.
(setq match (if (string= (nth 2 entry) "") ""
- (gnus-summary-header (or (nth 2 entry) (nth 1 entry)))))
+ (gnus-summary-header (or (nth 2 entry) (nth 1 entry))
+ nil extra)))
;; Modify the match, perhaps.
(cond
(if (eq temporary 'perm) ; Temp
nil
temporary)
- (not (nth 3 entry))) ; Prompt
+ (not (nth 3 entry)) ; Prompt
+ nil ; not silent
+ extra) ; non-standard overview.
(when (eq symp 'a)
;; We change the score file back to the previous one.
(shrink-window-if-larger-than-buffer))
(select-window (get-buffer-window gnus-summary-buffer))))
-(defun gnus-summary-header (header &optional no-err)
+(defun gnus-summary-header (header &optional no-err extra)
;; Return HEADER for current articles, or error.
(let ((article (gnus-summary-article-number))
headers)
(if article
(if (and (setq headers (gnus-summary-article-header article))
(vectorp headers))
- (aref headers (nth 1 (assoc header gnus-header-index)))
+ (if extra ; `header' must be "extra"
+ (or (cdr (assq extra (mail-header-extra headers))) "")
+ (aref headers (nth 1 (assoc header gnus-header-index))))
(if no-err
nil
(error "Pseudo-articles can't be scored")))
(gnus-newsgroup-score-alist)))))
(defun gnus-summary-score-entry (header match type score date
- &optional prompt silent)
+ &optional prompt silent extra)
(interactive)
"Enter score file entry.
HEADER is the header being scored.
SCORE is the score to add.
DATE is the expire date, or nil for no expire, or 'now for immediate expire.
If optional argument `PROMPT' is non-nil, allow user to edit match.
-If optional argument `SILENT' is nil, show effect of score entry."
+If optional argument `SILENT' is nil, show effect of score entry.
+If optional argument `EXTRA' is non-nil, it's a non-standard overview header."
;; Regexp is the default type.
(when (eq type t)
(setq type 'r))
elem)
(setq new
(cond
+ (extra
+ (list match score
+ (and date (if (numberp date) date
+ (date-to-day date)))
+ type (symbol-name extra)))
(type
(list match score
(and date (if (numberp date) date
(if (and (>= (nth 1 (assoc header gnus-header-index)) 0)
(eq (nth 2 (assoc header gnus-header-index))
'gnus-score-string))
- (gnus-summary-score-effect header match type score)
+ (gnus-summary-score-effect header match type score extra)
(gnus-summary-rescore)))
;; Return the new scoring rule.
new))
-(defun gnus-summary-score-effect (header match type score)
+(defun gnus-summary-score-effect (header match type score extra)
"Simulate the effect of a score file entry.
HEADER is the header being scored.
MATCH is the string we are looking for.
TYPE is the score type.
-SCORE is the score to add."
+SCORE is the score to add.
+EXTRA is the possible non-standard header."
(interactive (list (completing-read "Header: "
gnus-header-index
(lambda (x) (fboundp (nth 2 x)))
(t
(regexp-quote match)))))
(while (not (eobp))
- (let ((content (gnus-summary-header header 'noerr))
+ (let ((content (gnus-summary-header header 'noerr extra))
(case-fold-search t))
(and content
(when (if (eq type 'f)
;; and U is the number of unique headers. It is assumed (but
;; untested) this will be a net win because of the large constant
;; factor involved with string matching.
- (setq gnus-scores-articles (sort gnus-scores-articles 'gnus-score-string<)
+ (setq gnus-scores-articles
+ ;; We cannot string-sort the extra headers list. *sigh*
+ (if (= gnus-score-index 9)
+ gnus-scores-articles
+ (sort gnus-scores-articles 'gnus-score-string<))
articles gnus-scores-articles)
(erase-buffer)
(while (setq art (pop articles))
(setq this (aref (car art) gnus-score-index))
+
+ ;; If we're working with non-standard headers, we are stuck
+ ;; with working on them as a group. What a hassle.
+ ;; Just wait 'til you see what horrors we commit against `match'...
+ (if (= gnus-score-index 9)
+ (setq this (prin1-to-string this))) ; ick.
+
(if simplify
(setq this (gnus-map-function gnus-simplify-subject-functions this)))
(if (equal last this)
(type (or (nth 3 kill) 's))
(score (or (nth 1 kill) gnus-score-interactive-default-score))
(date (nth 2 kill))
+ (extra (nth 4 kill)) ; non-standard header; string.
(found nil)
(mt (aref (symbol-name type) 0))
(case-fold-search (not (memq mt '(?R ?S ?E ?F))))
((or (= dmt ?e) (= dmt ?s) (= dmt ?f)) 'search-forward)
((= dmt ?w) nil)
(t (error "Illegal match type: %s" type)))))
+
+ ;; Evil hackery to make match usable in non-standard headers.
+ (when extra
+ (setq match (concat "[ (](" extra " \\. \"[^)]*" match "[^(]*\")[ )]")
+ search-func 're-search-forward)) ; XXX danger?!?
+
(cond
;; Fuzzy matches. We save these for later.
((= dmt ?f)
:group 'gnus-summary
:type '(repeat symbol))
-(defcustom gnus-ignored-from-addresses (regexp-quote user-mail-address)
+(defcustom gnus-ignored-from-addresses
+ (and user-mail-address (regexp-quote user-mail-address))
"*Regexp of From headers that may be suppressed in favor of To headers."
:group 'gnus-summary
:type 'regexp)
("article body" "body" string)
("article head" "head" string)
("xref" "xref" string)
+ ("extra header" "extra" string)
("lines" "lines" number)
("followups to author" "followup" string)))
(types '((number ("less than" <)
number headers header)
(save-excursion
(set-buffer nntp-server-buffer)
+ (goto-char (point-min))
+ (while (search-forward "\r" nil t)
+ (replace-match " " t t))
;; Allow the user to mangle the headers before parsing them.
(gnus-run-hooks 'gnus-parse-headers-hook)
(goto-char (point-min))
;; We have to require this here to make sure that the following
;; dynamic binding isn't shadowed by autoloading.
(require 'gnus-async)
+ (require 'gnus-art)
(let ((gnus-select-article-hook nil) ;Disable hook.
(gnus-article-display-hook nil)
(gnus-mark-article-hook nil) ;Inhibit marking as read.
(gnus-xmas-force-redisplay nil) ;Inhibit XEmacs redisplay.
(gnus-use-trees nil) ;Inhibit updating tree buffer.
(sum (current-buffer))
+ (gnus-display-mime-function nil)
(found nil)
- point gnus-display-mime-function)
+ point)
(gnus-save-hidden-threads
(gnus-summary-select-article)
(set-buffer gnus-article-buffer)
(defun gnus-make-sort-function (funs)
"Return a composite sort condition based on the functions in FUNC."
(cond
- ((not (listp funs)) funs)
+ ;; Just a simple function.
+ ((gnus-functionp funs) funs)
+ ;; No functions at all.
((null funs) funs)
- ((cdr funs)
+ ;; A list of functions.
+ ((or (cdr funs)
+ (listp (car funs)))
`(lambda (t1 t2)
,(gnus-make-sort-function-1 (reverse funs))))
+ ;; A list containing just one function.
(t
(car funs))))
(defun gnus-make-sort-function-1 (funs)
"Return a composite sort condition based on the functions in FUNC."
- (if (cdr funs)
- `(or (,(car funs) t1 t2)
- (and (not (,(car funs) t2 t1))
- ,(gnus-make-sort-function-1 (cdr funs))))
- `(,(car funs) t1 t2)))
+ (let ((function (car funs))
+ (first 't1)
+ (last 't2))
+ (when (consp function)
+ (if (eq (car function) 'not)
+ (setq function (cadr function)
+ first 't2
+ last 't1)
+ (error "Invalid sort spec: %s" function)))
+ (if (cdr funs)
+ `(or (,function ,first ,last)
+ (and (not (,function ,last ,first))
+ ,(gnus-make-sort-function-1 (cdr funs))))
+ `(,function ,first ,last))))
(defun gnus-turn-off-edit-menu (type)
"Turn off edit menu in `gnus-TYPE-mode-map'."
:link '(custom-manual "(gnus)Exiting Gnus")
:group 'gnus)
-(defconst gnus-version-number "0.42"
+(defconst gnus-version-number "0.43"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Pterodactyl Gnus v%s" gnus-version-number)
:group 'message-forwarding
:type 'boolean)
-(defcustom message-ignored-resent-headers "^Return-receipt"
+(defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus"
"*All headers that match this regexp will be deleted when resending a message."
:group 'message-interface
:type 'regexp)
(when (looking-at "From ")
(replace-match "X-From-Line: "))
;; Send it.
- (message-send-mail)
+ (let (message-required-mail-headers)
+ (message-send-mail))
(kill-buffer (current-buffer)))
(message "Resending message to %s...done" address)))
(defsubst mm-enable-multibyte ()
"Enable multibyte in the current buffer."
(when (and (fboundp 'set-buffer-multibyte)
- (default-value enable-multibyte-characters))
+ (default-value 'enable-multibyte-characters))
(set-buffer-multibyte t)))
(defsubst mm-disable-multibyte ()
(multibyte (make-symbol "multibyte")))
`(if (not (boundp 'enable-multibyte-characters))
(with-temp-buffer ,@forms)
- (let ((,multibyte (default-value enable-multibyte-characters))
+ (let ((,multibyte (default-value 'enable-multibyte-characters))
,temp-buffer)
(unwind-protect
(progn
(save-restriction
(narrow-to-region b e)
(goto-char (point-min))
- (let ((entry (assoc current-language-environment language-info-alist)))
+ (let ((entry (assoc (capitalize current-language-environment)
+ language-info-alist)))
(skip-chars-forward "\0-\177")
(if (eobp)
'(ascii)
,(set-marker (make-marker) (point-min))
,(set-marker (make-marker) (point-max)))))))))
((equal type "html")
- (save-excursion
- (w3-do-setup)
- (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)))
- (require 'url)
- (save-window-excursion
- (w3-region (point-min) (point-max))
- (setq text (buffer-string)))))
+ (let ((width (window-width)))
+ (save-excursion
+ (w3-do-setup)
+ (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)))
+ (require 'url)
+ (save-window-excursion
+ (let ((w3-strict-width width))
+ (w3-region (point-min) (point-max)))
+ (setq text (buffer-string))))))
(mm-insert-inline handle text))
((or (equal type "enriched")
(equal type "richtext"))
;;; Code:
+(eval-when-compile (require 'cl))
(require 'nnoo)
(require 'message)
\input texinfo @c -*-texinfo-*-
@setfilename gnus
-@settitle Pterodactyl Gnus 0.42 Manual
+@settitle Pterodactyl Gnus 0.43 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Pterodactyl Gnus 0.42 Manual
+@title Pterodactyl Gnus 0.43 Manual
@author by Lars Magne Ingebrigtsen
@page
spool or your mbox file. All at the same time, if you want to push your
luck.
-This manual corresponds to Pterodactyl Gnus 0.42.
+This manual corresponds to Pterodactyl Gnus 0.43.
@end ifinfo
@findex gnus-thread-sort-by-number
@vindex gnus-thread-sort-functions
If you are using a threaded summary display, you can sort the threads by
-setting @code{gnus-thread-sort-functions}, which is a list of functions.
+setting @code{gnus-thread-sort-functions}, which can be either a single
+function, a list of functions, or a list containing functions and
+@code{(not some-function)} elements.
+
By default, sorting is done on article numbers. Ready-made sorting
predicate functions include @code{gnus-thread-sort-by-number},
@code{gnus-thread-sort-by-author}, @code{gnus-thread-sort-by-subject},
Each function takes two threads and returns non-@code{nil} if the first
thread should be sorted before the other. Note that sorting really is
-normally done by looking only at the roots of each thread. If you use
-more than one function, the primary sort key should be the last function
-in the list. You should probably always include
+normally done by looking only at the roots of each thread.
+
+If you use more than one function, the primary sort key should be the
+last function in the list. You should probably always include
@code{gnus-thread-sort-by-number} in the list of sorting
functions---preferably first. This will ensure that threads that are
equal with respect to the other sort criteria will be displayed in
ascending article order.
-If you would like to sort by score, then by subject, and finally by
-number, you could do something like:
+If you would like to sort by reverse score, then by subject, and finally
+by number, you could do something like:
@lisp
(setq gnus-thread-sort-functions
'(gnus-thread-sort-by-number
gnus-thread-sort-by-subject
- gnus-thread-sort-by-total-score))
+ (reverse gnus-thread-sort-by-total-score)))
@end lisp
The threads that have highest score will be displayed first in the
\input texinfo @c -*-texinfo-*-
@setfilename message
-@settitle Pterodactyl Message 0.42 Manual
+@settitle Pterodactyl Message 0.43 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Pterodactyl Message 0.42 Manual
+@title Pterodactyl Message 0.43 Manual
@author by Lars Magne Ingebrigtsen
@page
* Key Index:: List of Message mode keys.
@end menu
-This manual corresponds to Pterodactyl Message 0.42. Message is
+This manual corresponds to Pterodactyl Message 0.43. Message is
distributed with the Gnus distribution bearing the same version number
as this manual.