*** `gnus-simplify-subject-functions' variable to allow greater
control over simplification.
+*** `A T' -- new command for fetching the current thread.
+
+*** `/ T' -- new command for including the current thread in the
+limit.
+Tue Sep 23 07:45:11 1997 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
+
+ * gnus.el: Quassia Gnus v0.10 is released.
+
+Tue Sep 23 01:41:04 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-sum.el (gnus-read-all-headers): New function.
+ (gnus-select-newsgroup): Use it.
+ (gnus-summary-refer-thread): Ditto.
+ (gnus-refer-thread-limit): New variable.
+ (gnus-summary-refer-thread): Use it.
+
+ * gnus-nocem.el (gnus-nocem-message-wanted-p): New function.
+ (gnus-nocem-check-article): Use it.
+ (gnus-nocem-issuers): Dox ofx.
+
+ * dgnushack.el (dgnushack-compile): Check for cus-edit.
+
+ * message.el (message-included-forward-headers): Include Mime
+ headers.
+ (message-send): Allow posting without confirming from Agent.
+
+Mon Sep 22 05:43:14 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * dgnushack.el (byte-compile-warnings): Don't warn about obsolete
+ variables.
+
+ * gnus-sum.el (gnus-summary-refer-thread): New command and
+ keystroke.
+ (gnus-summary-limit-include-thread): New command and keystroke.
+ (gnus-summary-articles-in-thread): New function.
+ (gnus-articles-in-thread): Renamed.
+
Sun Sep 21 23:54:50 1997 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
* gnus.el: Quassia Gnus v0.9 is released.
(fset 'read-color 'ignore)))
(setq byte-compile-warnings
- '(free-vars unresolved callargs redefine obsolete))
+ '(free-vars unresolved callargs redefine))
(defun dgnushack-compile ()
;;(setq byte-compile-dynamic t)
- (unless (locate-library "custom")
+ (unless (locate-library "cus-edit")
(error "You do not seem to have Custom installed.
Fetch it from <URL:http://www.dina.kvl.dk/~abraham/custom/>.
You also then need to add the following to the lisp/dgnushack.el file:
"snowhare@xmission.com" ; Benjamin "Snowhare" Franz
"red@redpoll.mrfs.oh.us (Richard E. Depew)" ; ARMM! ARMM!
)
- "List of NoCeM issuers to pay attention to."
+ "List of NoCeM issuers to pay attention to.
+
+This can also be a list of `(ISSUER CONDITIONS)' elements."
:group 'gnus-nocem
:type '(repeat string))
(gnus-message 7 "Checking article %d in %s for NoCeM..."
(mail-header-number header) group)
(let ((date (mail-header-date header))
- issuer b e)
+ issuer b e type)
(when (or (not date)
(nnmail-time-less
(nnmail-time-since (nnmail-date-to-time date))
(setq e (search-forward "\n@@BEGIN NCM BODY\n" nil t)))
;; We get the name of the issuer.
(narrow-to-region b e)
- (setq issuer (mail-fetch-field "issuer"))
+ (setq issuer (mail-fetch-field "issuer")
+ type (mail-fetch-field "issuer"))
(widen)
- (or (member issuer gnus-nocem-issuers)
- (message "invalid NoCeM issuer: %s" issuer))
- (and (member issuer gnus-nocem-issuers) ; We like her....
- (gnus-nocem-verify-issuer issuer) ; She is who she says she is...
- (gnus-nocem-enter-article) ; We gobble the message..
- (push (mail-header-message-id header) ; But don't come back for
- gnus-nocem-seen-message-ids)))))) ; second helpings.
+ (if (not (gnus-nocem-message-wanted-p issuer type))
+ (message "invalid NoCeM issuer: %s" issuer)
+ (and (gnus-nocem-verify-issuer issuer) ; She is who she says she is.
+ (gnus-nocem-enter-article) ; We gobble the message.
+ (push (mail-header-message-id header) ; But don't come back for
+ gnus-nocem-seen-message-ids))))))) ; second helpings.
+
+(defun gnus-nocem-message-wanted-p (issuer type)
+ (let ((issuers gnus-nocem-issuers)
+ wanted conditions condition)
+ (cond
+ ;; Do the quick check first.
+ ((member issuer issuers)
+ t)
+ ((setq conditions (cdr (assoc issuer issuers)))
+ ;; Check whether we want this type.
+ (while (setq condition (pop conditions))
+ (cond
+ ((stringp condition)
+ (setq wanted (string-match condition) type))
+ ((and (consp condition)
+ (eq (car condition) 'not)
+ (stringp (cadr condition)))
+ (setq wanted (not (string-match (cadr condition) type))))
+ (t
+ (error "Invalid NoCeM condition: %S" condition))))
+ wanted))))
(defun gnus-nocem-verify-issuer (person)
"Verify using PGP that the canceler is who she says she is."
(decay (car (gnus-score-get 'decay alist)))
(eval (car (gnus-score-get 'eval alist))))
;; Perform possible decays.
- (when gnus-decay-scores
- (when (or (not decay)
- (gnus-decay-scores alist decay))
- (gnus-score-set 'touched '(t) alist)
- (gnus-score-set 'decay (list (gnus-time-to-day (current-time))))))
+ (when (and gnus-decay-scores
+ (or (not decay)
+ (gnus-decay-scores alist decay)))
+ (gnus-score-set 'touched '(t) alist)
+ (gnus-score-set 'decay (list (gnus-time-to-day (current-time)))))
;; We do not respect eval and files atoms from global score
;; files.
- (and files (not global)
- (setq lists (apply 'append lists
- (mapcar (lambda (file)
- (gnus-score-load-file file))
- (if adapt-file (cons adapt-file files)
- files)))))
- (and eval (not global) (eval eval))
+ (when (and files (not global))
+ (setq lists (apply 'append lists
+ (mapcar (lambda (file)
+ (gnus-score-load-file file))
+ (if adapt-file (cons adapt-file files)
+ files)))))
+ (when (and eval (not global))
+ (eval eval))
;; We then expand any exclude-file directives.
(setq gnus-scores-exclude-files
(nconc
(expand-file-name sfile (file-name-directory file)))
exclude-files)
gnus-scores-exclude-files))
- (if (not local)
- ()
+ (unless local
(save-excursion
(set-buffer gnus-summary-buffer)
(while local
number
(sexp :menu-tag "other" t)))
+(defcustom gnus-refer-thread-limit 200
+ "*The number of old headers to fetch when doing \\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
+If t, fetch all the available old headers."
+ :group 'gnus-thread
+ :type '(choice number
+ (sexp :menu-tag "other" t)))
+
(defcustom gnus-summary-make-false-root 'adopt
"*nil means that Gnus won't gather loose threads.
If the root of a thread has expired or been read in a previous
"m" gnus-summary-limit-to-marks
"v" gnus-summary-limit-to-score
"D" gnus-summary-limit-include-dormant
+ "T" gnus-summary-limit-include-thread
"d" gnus-summary-limit-exclude-dormant
"t" gnus-summary-limit-to-age
"E" gnus-summary-limit-include-expunged
"^" gnus-summary-refer-parent-article
"r" gnus-summary-refer-parent-article
"R" gnus-summary-refer-references
+ "T" gnus-summary-refer-thread
"g" gnus-summary-show-article
"s" gnus-summary-isearch-article
"P" gnus-summary-print-article)
["End of the article" gnus-summary-end-of-article t]
["Fetch parent of article" gnus-summary-refer-parent-article t]
["Fetch referenced articles" gnus-summary-refer-references t]
+ ["Fetch current thread" gnus-summary-refer-thread t]
["Fetch article with id..." gnus-summary-refer-article t]
["Redisplay" gnus-summary-show-article t]))
(delq number gnus-newsgroup-unselected)))
(push number gnus-newsgroup-ancient)))))))
+(defun gnus-build-all-threads ()
+ "Read all the headers."
+ (let ((deps gnus-newsgroup-dependencies)
+ (gnus-summary-ignore-duplicates t)
+ found header article)
+ (save-excursion
+ (set-buffer nntp-server-buffer)
+ (let ((case-fold-search nil))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (ignore-errors
+ (setq article (read (current-buffer)))
+ (setq header (gnus-nov-parse-line article deps)))
+ (when header
+ (push header gnus-newsgroup-headers)
+ (if (memq (setq article (mail-header-number header))
+ gnus-newsgroup-unselected)
+ (progn
+ (push article gnus-newsgroup-unreads)
+ (setq gnus-newsgroup-unselected
+ (delq article gnus-newsgroup-unselected)))
+ (push article gnus-newsgroup-ancient))
+ (forward-line 1)))))))
+
(defun gnus-summary-update-article-line (article header)
"Update the line for ARTICLE using HEADERS."
(let* ((id (mail-header-id header))
id (gnus-parent-id (mail-header-references prev))))
last-id))
+(defun gnus-articles-in-thread (thread)
+ "Return the list of articles in THREAD."
+ (cons (mail-header-number (car thread))
+ (apply 'nconc (mapcar 'gnus-articles-in-thread (cdr thread)))))
+
(defun gnus-remove-thread (id &optional dont-remove)
"Remove the thread that has ID in it."
(let ((dep gnus-newsgroup-dependencies)
(when gnus-agent
(gnus-agent-get-undownloaded-list))
;; We might want to build some more threads first.
- (and gnus-fetch-old-headers
- (eq gnus-headers-retrieved-by 'nov)
- (gnus-build-old-threads))
+ (when (and gnus-fetch-old-headers
+ (eq gnus-headers-retrieved-by 'nov))
+ (if (eq gnus-fetch-old-headers 'invisible)
+ (gnus-build-all-threads)
+ (gnus-build-old-threads)))
;; Check whether auto-expire is to be done in this group.
(setq gnus-newsgroup-auto-expire
(gnus-group-auto-expirable-p group))
(gnus-summary-limit articles)
(gnus-summary-position-point))))
+(defun gnus-summary-limit-include-thread (id)
+ "Display all the hidden articles that in the current thread."
+ (interactive (mail-header-id (gnus-summary-article-header)))
+ (gnus-set-global-variables)
+ (let ((articles (gnus-articles-in-thread
+ (gnus-id-to-thread (gnus-root-id id)))))
+ (prog1
+ (gnus-summary-limit (nconc articles gnus-newsgroup-limit))
+ (gnus-summary-position-point))))
+
(defun gnus-summary-limit-include-dormant ()
"Display all the hidden articles that are marked as dormant."
(interactive)
(defun gnus-summary-refer-references ()
"Fetch all articles mentioned in the References header.
-Return how many articles were fetched."
+Return the number of articles fetched."
(interactive)
(gnus-set-global-variables)
(let ((ref (mail-header-references (gnus-summary-article-header)))
(gnus-summary-position-point)
n)))
+(defun gnus-summary-refer-thread (&optional limit)
+ "Fetch all articles in the current thread.
+If LIMIT (the numerical prefix), fetch that many old headers instead
+of what's specified by the `gnus-refer-thread-limit' variable."
+ (interactive "P")
+ (gnus-set-global-variables)
+ (let ((id (mail-header-id (gnus-summary-article-header)))
+ (limit (if limit (prefix-numeric-value limit)
+ gnus-refer-thread-limit))
+ fmethod root)
+ ;; We want to fetch LIMIT *old* headers, but we also have to
+ ;; re-fetch all the headers in the current buffer, because many of
+ ;; them may be undisplayed. So we adjust LIMIT.
+ (when (numberp limit)
+ (incf limit (- gnus-newsgroup-end gnus-newsgroup-begin)))
+ (unless (eq gnus-fetch-old-headers 'invisible)
+ (gnus-message 5 "Fetching headers for %s..." gnus-newsgroup-name)
+ ;; Retrieve the headers and read them in.
+ (if (eq (gnus-retrieve-headers
+ (list gnus-newsgroup-end) gnus-newsgroup-name limit)
+ 'nov)
+ (gnus-build-all-threads)
+ (error "Can't fetch thread from backends that don't support NOV"))
+ (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name))
+ (gnus-summary-limit-include-thread id)))
+
(defun gnus-summary-refer-article (message-id &optional arg)
"Fetch an article specified by MESSAGE-ID.
If ARG (the prefix), fetch the article using `gnus-refer-article-method'
:link '(custom-manual "(gnus)Exiting Gnus")
:group 'gnus)
-(defconst gnus-version-number "0.9"
+(defconst gnus-version-number "0.10"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Quassia Gnus v%s" gnus-version-number)
Checks include subject-cmsg multiple-headers sendsys message-id from
long-lines control-chars size new-text redirected-followup signature
approved sender empty empty-headers message-id from subject
-shorten-followup-to existing-newsgroups."
+shorten-followup-to existing-newsgroups buffer-file-name unchanged."
:group 'message-news)
(defcustom message-required-news-headers
:type 'boolean)
(defcustom message-included-forward-headers
- "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:"
+ "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:\\|^Content-Transfer-Encoding:\\|^Content-Type:\\|^Mime-Version:"
"*Regexp matching headers to be included in forwarded messages."
:group 'message-forwarding
:type 'regexp)
the user from the mailer."
(interactive "P")
;; Disabled test.
- (when (if (and nil buffer-file-name)
+ (when (if (and buffer-file-name
+ (message-check-element 'buffer-file-name))
(y-or-n-p (format "Send buffer contents as %s message? "
(if (message-mail-p)
(if (message-news-p) "mail and news" "mail")
"news")))
(or (buffer-modified-p)
+ (message-check-element 'unchanged)
(y-or-n-p "No changes in the buffer; really send? ")))
;; Make it possible to undo the coming changes.
(undo-boundary)
+Tue Sep 23 07:05:48 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus.texi (NoCeM): Addition.
+ (Finding the Parent): Addition.
+
+Mon Sep 22 06:13:00 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus.texi (Filling In Threads): Addition.
+ (Finding the Parent): Addition.
+
Sun Sep 21 04:35:56 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
* gnus.texi (NNTP): Addition.
\input texinfo @c -*-texinfo-*-
@setfilename gnus
-@settitle Quassia Gnus 0.9 Manual
+@settitle Quassia Gnus 0.10 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Quassia Gnus 0.9 Manual
+@title Quassia Gnus 0.10 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 Quassia Gnus 0.9.
+This manual corresponds to Quassia Gnus 0.10.
@end ifinfo
@findex gnus-summary-limit-exclude-dormant
Hide all dormant articles (@code{gnus-summary-limit-exclude-dormant}).
+@item / T
+@kindex / T (Summary)
+@findex gnus-summary-limit-include-thread
+Include all the articles in the current thread.
+
@item / c
@kindex / c (Summary)
@findex gnus-summary-limit-exclude-childless-dormant
@code{nnml}. Also remember that if the root of the thread has been
expired by the server, there's not much Gnus can do about that.
+This variable can also be set to @code{invisible}. This won't have any
+visible effects, but is useful if you use the @kbd{A T} command a lot
+(@pxref{Finding the Parent}).
+
@item gnus-build-sparse-threads
@vindex gnus-build-sparse-threads
Fetching old headers can be slow. A low-rent similar effect can be
@cindex parent articles
@cindex referring articles
-@findex gnus-summary-refer-parent-article
+@code @kbd
+@item ^
@kindex ^ (Summary)
+@findex gnus-summary-refer-parent-article
If you'd like to read the parent of the current article, and it is not
displayed in the summary buffer, you might still be able to. That is,
if the current group is fetched by @sc{nntp}, the parent hasn't expired
@kbd{-3 ^}, Gnus will only fetch the grandgrandparent of the current
article.
+@item A R (Summary)
@findex gnus-summary-refer-references
@kindex A R (Summary)
-You can have Gnus fetch all articles mentioned in the @code{References}
-header of the article by pushing @kbd{A R}
-(@code{gnus-summary-refer-references}).
-
+Fetch all articles mentioned in the @code{References} header of the
+article (@code{gnus-summary-refer-references}).
+
+@item A T (Summary)
+@findex gnus-summary-refer-thread
+@kindex A T (Summary)
+Display the full thread where the current article appears
+(@code{gnus-summary-refer-thread}). This command has to fetch all the
+headers in the current group to work, so it usually takes a while. If
+you do it often, you may consider setting @code{gnus-fetch-old-headers}
+to @code{invisible} (@pxref{Filling In Threads}). This won't have any
+visible effects normally, but it'll make this command work a whole lot
+faster. Of course, it'll make group entry somewhat slow.
+
+@vindex gnus-refer-thread-limit
+The @code{gnus-refer-thread-limit} variable says how many old (i. e.,
+articles before the first displayed in the current group) headers to
+fetch when doing this command. The default is 200. If @code{t}, all
+the available headers will be fetched. This variable can be overridden
+by giving the @kbd{A T} command a numerical prefix.
+
+@item M-^ (Summary)
@findex gnus-summary-refer-article
@kindex M-^ (Summary)
@cindex Message-ID
@code{Message-ID}, which is one of those long, hard-to-read thingies
that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. You
have to get it all exactly right. No fuzzy searches, I'm afraid.
+@end table
The current select method will be used when fetching by
@code{Message-ID} from non-news select method, but you can override this
@end table
You do not have to heed NoCeM messages from all these people---just the
-ones you want to listen to.
+ones you want to listen to. You also don't have to accept all NoCeM
+messages from the people you like. Each NoCeM message has a @dfn{type}
+header that gives the message a (more or less, usually less) rigorous
+definition. Common types are @samp{spam}, @samp{spew}, @samp{mmf},
+@samp{binary}, and @samp{troll}. To specify this, you have to use
+@var{(issuer conditions ...)} elements in the list. Each condition is
+either a string (which is a regexp that matches types you want to use)
+or a list on the form @code{(not STRING)}, where @var{string} is a
+regexp that matches types you don't want to use.
+
+For instance, if you want all NoCeM messages from Chris Lewis except his
+@samp{troll} messages, you'd say:
+
+@lisp
+("clewis@ferret.ocunix.on.ca" ".*" (not "troll"))
+@end lisp
+
+On the other hand, if you just want nothing but his @samp{spam} and
+@samp{spew} messages, you'd say:
+
+@lisp
+("clewis@ferret.ocunix.on.ca" (not ".*") "spew" "spam")
+@end lisp
+
+The specs are applied left-to-right.
+
@item gnus-nocem-verifyer
@vindex gnus-nocem-verifyer
\input texinfo @c -*-texinfo-*-
@setfilename message
-@settitle Message 0.9 Manual
+@settitle Message 0.10 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Message 0.9 Manual
+@title Message 0.10 Manual
@author by Lars Magne Ingebrigtsen
@page
* Key Index:: List of Message mode keys.
@end menu
-This manual corresponds to Message 0.9. Message is distributed with
+This manual corresponds to Message 0.10. Message is distributed with
the Gnus distribution bearing the same version number as this manual
has.
`gnus-jog-cache' does -- for instance, work on just some groups, or on
some levels, and entering just articles that have a score higher than
a certain number.
-* function to request all articles in a thread.
* nnfolder should append to the folder instead of re-writing
the entire folder to disk when accepting new messages.
* allow all backends to do the proper thing with .gz files.