Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

*** empty log message ***

  • Loading branch information...
commit cb1472a3d69d4e24415010ee79c375b5ebff14fd 1 parent d5f2a2a
@larsmagne larsmagne authored
View
161 lisp/ChangeLog
@@ -1,5 +1,164 @@
-Sun Dec 10 10:38:47 1995 Lars Magne Ingebrigtsen <larsi@narfi.ifi.uio.no>
+Thu Dec 14 10:48:51 1995 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+ * gnus.el (gnus-summary-toggle-header): Don't do that hook dance.
+
+Thu Dec 14 10:02:08 1995 Lars Magne Ingebrigtsen <larsi@narfi.ifi.uio.no>
+
+ * gnus-xmas.el (gnus-xmas-read-event-char): New function.
+
+ * gnus.el (gnus-summary-last-subject): New function.
+ (gnus-summary-next-article): Understand all key events.
+ (gnus-summary-walk-group-buffer): New function.
+ (gnus-read-event-char): New function.
+
+Wed Dec 13 16:06:29 1995 Lars Ingebrigtsen <lars@eyesore.no>
+
+ * gnus-msg.el (gnus-new-mail, gnus-mail-reply): Didn't insert
+ Gcc.
+
+ * gnus-score.el (gnus-score-load-file): Allow `adapt-file' atom.
+ (gnus-score-adaptive): Use it.
+
+ * gnus.el (gnus-group-visible-select-group): New command and
+ keystroke.
+ (gnus-read-save-file-name): Extend the syntax of
+ `gnus-split-methods'.
+ (gnus-article-archive-name): New function.
+ (gnus-split-methods): New default; use function above.
+ (gnus-summary-update-secondary-mark): Update highlighting after
+ setting secondary marks.
+
+ * nnfolder.el (nnfolder-request-group): Don't load all nnfolder
+ groups on startup.
+
+Tue Dec 12 19:48:55 1995 Lars Ingebrigtsen <lars@eyesore.no>
+
+ * gnus.el (gnus-group-insert-group-line): Number of marked (etc)
+ didn't work.
+
+Tue Dec 12 19:37:05 1995 Timo Metzemakers <metzemakers@labri.u-bordeaux.fr>
+
+ * gnus.el (gnus-summary-reselect-current-group): Really reselect
+ the group.
+
+Tue Dec 12 10:38:05 1995 Lars Ingebrigtsen <lars@eyesore.no>
+
+ * nnmail.el (nnmail-days-to-time): Would result in short expiry
+ times in groups with veeery long expiry times.
+
+ * gnus-vis.el (gnus-summary-highlight-line): Bind `number'.
+
+ * gnus-score.el (gnus-score-find-bnews): Protect agains bogus
+ score file names.
+
+ * gnus.el (gnus-activate-all-groups): New command and keystroke.
+
+ * gnus-vis.el (gnus-article-prev-button): New command and keystroke.
+
+ * gnus-cache.el (gnus-cache-generate-nov-databases): New command.
+
+ * gnus-score.el (gnus-score-load-file): Accept
+ `thread-mark-and-expunge' atom.
+
+ * gnus.el (gnus-newsgroup-saved): New variable.
+ (gnus-summary-set-saved-mark): New function.
+ (gnus-kill-summary-on-exit): New variable.
+ (gnus-dead-summary-mode): New minor mode.
+ (gnus-deaden-summary, gnus-summary-wake-up-the-dead): New
+ functions.
+ (gnus-summary-catchup-and-goto-next-group): Respect
+ `gnus-auto-select-next', etc.
+ (gnus-article-hide-headers): New implementation.
+ (gnus-article-header-rank): New function.
+ (gnus-article-header-less): Ditto.
+ (gnus-visible-headers, gnus-ignored-headers): Can now be lists of
+ regexps.
+ (gnus-thread-expunge-below): New variable.
+ (gnus-expunge-thread): New variable.
+
+ * gnus-mh.el (gnus-summary-save-in-folder): There is no
+ `mh-search-path'.
+
+Mon Dec 11 07:21:25 1995 Lars Ingebrigtsen <lars@eyesore.no>
+
+ * gnus.el (gnus-article-sort-functions): New variable.
+ (gnus-article-sort-by-number, gnus-article-sort-by-author,
+ gnus-article-sort-by-subject, gnus-article-sort-by-date,
+ (gnus-article-sort-by-score): New functions.
+ (gnus-thread-sort-by-number, gnus-thread-sort-by-author,
+ gnus-thread-sort-by-subject, gnus-thread-sort-by-date,
+ gnus-thread-sort-by-score, gnus-summary-sort-by-number,
+ gnus-summary-sort-by-author, gnus-summary-sort-by-subject,
+ gnus-summary-sort-by-date, gnus-summary-sort-by-score,
+ gnus-summary-sort): New implementations.
+ (gnus-summary-mode-line-format): Doc fix.
+ (gnus-insert-pseudo-articles): New variable.
+ (gnus-activate-level): New variable.
+ (gnus-get-unread-articles): Use it.
+
+ * nnkiboze.el (nnkiboze-request-delete-group): New function.
+
+ * gnus.el (gnus-subscribe-killed): New function.
+ (gnus-group-kill-group): Make mass group slaughter faster.
+ (gnus-group-kill-level): New command and keystroke.
+
+ * gnus-cache.el (gnus-cache-generate-active): Messed up the active
+ file.
+
+ * gnus.el (gnus-summary-update-secondary-mark): New function.
+ (gnus-cached-mark): New variable.
+ (gnus-gmt-to-local): Removed function.
+ (gnus-narrow-to-page): New implementation.
+
+ * gnus-cache.el (gnus-cache-enter-article): New command and
+ keystroke.
+ (gnus-cache-remove-article): Ditto.
+ (gnus-passive-cache): New variable.
+ (gnus-cached-article-p): New function.
+
+ * gnus.el (gnus-summary-mode-line-format,
+ gnus-article-mode-line-format, gnus-group-mode-line-format):
+ Include the buffer name in all mode lines.
+
+ * gnus-topic.el (gnus-topic-yank-group, gnus-topic-kill-group):
+ Allow kill/yank inside and in between topics.
+
+ * gnus.el (gnus-request-type): Wouldn't work.
+
+Sun Dec 10 13:16:49 1995 Lars Ingebrigtsen <lars@eyesore.no>
+
+ * gnus-topic.el (gnus-topic-insert-topic-line): Remove old text
+ properties before setting new.
+
+ * nnml.el: Understand jka-compr.
+ (nnml-generate-nov-databases): Would make empty group disappear.
+
+ * nnheader.el (nnheader-numerical-short-files): New variable.
+ (nnheader-numerical-full-files): Ditto.
+
+ * gnus-msg.el (gnus-summary-resend-message): Rename old Resent-*
+ headers.
+
+ * gnus-cache.el (gnus-cache-retrieve-headers): Allow fetching of
+ old headers.
+
+ * nnmail.el (nnmail-get-spool-files): Don't ditch procmail
+ symlinks.
+
+ * gnus-msg.el (gnus-inews-insert-signature): Don't insert
+ signature if mail-signature.
+
+ * gnus.el (gnus-group-make-help-group): Find gnus-tut in the etc
+ directory.
+
+Sun Dec 10 12:29:54 1995 Lars Magne Ingebrigtsen <larsi@narfi.ifi.uio.no>
+
+ * gnus.el (gnus-article-date-ut): Bugged out on pseudos.
+
+Sun Dec 10 10:38:47 1995 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
+
+ * gnus.el: 0.21 is released.
+
* gnus.el (gnus-backlog-shutdown): New function.
(gnus-backlog-buffer): Would return a list the first time called.
View
374 lisp/doc.txt
@@ -0,0 +1,374 @@
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: This is a test version of this group
+Message-ID: <lars-doc0@eyesore.no>
+
+This group will look something like this, but the stuff in here is of
+little worth right now.
+
+For real documentation, you'll have to read the source code. Or you
+can read the info file, which is pretty comprehensive, if somewhat out
+of date.
+
+Gnus is currently in beta.
+
+When you happen upon a bug, please drop me a note.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: So you want to use the new Gnus
+Message-ID: <lars-doc1@eyesore.no>
+
+Actually, since you are reading this, chances are you are already
+using the new Gnus. Congratulations.
+
+This entire newsgroup you are reading is, in fact, no real newsgroup
+at all, in the traditional sense. It is an example of one of the
+"foreign" select methods that Gnus may use.
+
+The text you are now reading is stored in the "etc" directory with the
+rest of the Emacs sources. You are using the "nndir" backend for
+accessing it. Scary, isn't it?
+
+This isn't the real documentation. `M-x info', `m gnus <RET>' to read
+that. This "newsgroup" is intended as a kinder, gentler way of getting
+people started.
+
+Gnus is a rewrite of GNUS 4.1, written by Masanobu Umeda. The rewrite
+was done by moi, yours truly, your humble servant, Lars Magne
+Ingebrigtsen. If you have a WWW browser, you can investigate to your
+heart's delight at "http://www.ifi.uio.no/~larsi/larsi.html".
+
+Much code (especially the score code) was written by Per Abrahamsen.
+
+;; Copyright (C) 1995 Free Software Foundation, Inc.
+
+;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Keywords: news
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: Starting up
+Message-ID: <lars-doc2@eyesore.no>
+
+If you are having problems with Gnus not finding your server, you have
+to set `gnus-select-method'. A "method" is a way of specifying *how*
+the news is to be found, and from *where*.
+
+Say you want to read news from you local, friendly nntp server
+"news.my.local.server".
+
+(setq gnus-select-method '(nntp "news.my.local.server"))
+
+Quite easy, huh?
+
+From the news spool:
+
+(setq gnus-select-method '(nnspool ""))
+
+From your mh-e spool:
+
+(setq gnus-select-method '(nnmh ""))
+
+There's a whole bunch of other methods for reading mail and news, see
+the "Foreign groups" article for that.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: Where are all the groups, then?
+Message-ID: <lars-doc3@eyesore.no>
+
+If this is the first time you have used a newsreader, you won't have a
+.newsrc file. This means that Gnus will think that all the newsgroups
+on the server are "new", and kill them all.
+
+If you have a .newsrc file, the new groups will be processed with the
+function in the `gnus-subscribe-newsgroup-method' variable, which is
+`gnus-subscribe-zombies' by default.
+
+This means that all the groups have been made into "zombies" - not
+quite dead, but not exactly alive, either.
+
+Jump back to the *Group* buffer, and type `C-c C-z' to list all the
+zombie groups. Look though the list, and subscribe to the groups you
+want to read by pressing `u' on the one you think look interesting.
+
+If all the groups have been killed, type `C-c C-k' to list all the
+killed groups. Subscribe to them the same way.
+
+When you are satisfied, press `M-z' to kill all the zombie groups.
+
+Now you should have a nice list of all groups you are interested in.
+
+(If you later want to subscribe to more groups, press `C-c C-k' to
+list all the kill groups, and repeat. You can also type `U' and be
+prompted for groups to subscribe to.)
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: I want to read my mail!
+Message-ID: <lars-doc4@eyesore.no>
+
+Yes, Virginia, you can read mail with Gnus.
+
+First you have to decide which mail backend you want to use. You have
+nnml, which is a one-file-one-mail backend, which is quite nice, but
+apt to make your systems administrator go crazy and come after you
+with a shotgun.
+
+nnmbox uses a Unix mail box to store mail. Nice, but slow.
+
+nnmh uses mh-e folders, which is also a one-file-one-mail thingie, but
+slower than nnml. (It doesn't support NOV files.)
+
+So if you want to go with nnmbox, you can simply say:
+
+(setq gnus-secondary-select-methods '((nnmbox "")))
+
+(The same for the other methods, kind of.)
+
+You should also set `nnmail-split-methods' to something sensible:
+
+(setq nnmail-split-methods
+ '(("mail.junk" "From:.*Lars")
+ ("mail.misc "")))
+
+This will put all mail from me in you junk mail group, and the rest in
+"mail.misc".
+
+These groups will be subscribe the same way as the normal groups, so
+you will probably find them among the zombie groups after you set
+these variables and re-start Gnus.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: Foreign newsgroups
+Message-ID: <lars-doc5@eyesore.no>
+
+These are groups that do not come from `gnus-select-method'.
+
+Say you want to read "alt.furniture.couches" from "news.funet.fi". You
+can then either type `B news.funet.fi <RET>' to browse that server and
+subscribe to that group, or you can type
+`M-a alt.furniture.couches<RET>nntp<RET>news.funet.fi<RET>', if you
+like to type a lot.
+
+If you want to read a directory as a newsgroup, you can create an
+nndir group, much the same way. There's a shorthand for that,
+though. If, for instance, you want to read the (ding) list archives,
+you could type `D /ftp <RET>'.
+
+There's lots more to know about foreign groups, but you have to read
+the info pages to find out more.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: Low level changes in GNUS, or, Wrong type argument: stringp, nil
+Message-ID: <lars-doc6@eyesore.no>
+
+Gnus really isn't GNUS, even though it looks like it. If you scrape
+the surface, you'll find that most things have changed.
+
+This means that old code that relies on GNUS internals will fail.
+
+In particular, `gnus-newsrc-hashtb', `gnus-newsrc-assoc',
+`gnus-killed-list', the `nntp-header-' macros and the display formats
+have all changed. If you have some code lying around that depend on
+these, or change these, you'll have to re-write your code.
+
+Old hilit19 code does not work at all. In fact, you should probably
+remove all hihit code from all the Gnus hooks
+(`gnus-group-prepare-hook', `gnus-summary-prepare-hook' and
+`gnus-summary-article-hook'). (Well, at the very least the first
+two.) Gnus provides various integrated functions for highlighting,
+which are both faster and more accurated.
+
+There is absolutely no chance, whatsoever, of getting Gnus to work
+with Emacs 18.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: Bugs & stuff
+Message-ID: <lars-doc7@eyesore.no>
+
+If you want to report a bug, please type `M-x gnus-bug'. This will
+give me a precice overview of your Gnus and Emacs version numbers,
+along with a look at all Gnus variables you have changed.
+
+Du not expect a reply back, but your bug should be fixed in the next
+version. If the bug persists, please re-submit your bug report.
+
+When a bug occurs, I need a recipe for how to trigger the bug. You
+have to tell me exactly what you do to uncover the bug, and you should
+(setq debug-on-error t) and send me the backtrace along with the bug
+report.
+
+If I am not able to reproduce the bug, I won't be able to fix it.
+
+I would, of course, prefer that you locate the bug, fix it, and mail
+me the patches, but one can't have everything.
+
+If you have any questions on usage, the "ding@ifi.uio.no" mailing list
+is where to post the questions.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: How do I re-scan my mail groups?
+Message-ID: <lars-doc8@eyesore.no>
+
+Reading the active file from the nntp server is a drag.
+
+Just press `M-g' on the mail groups, and they will be re-scanned.
+
+You can also re-scan all the mail groups by putting them on level 1
+(`1 S'), and saying `1 g' to re-scan all level 1 groups.
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: How do I set up virtual newsgroups?
+Message-ID: <lars-doc9@eyesore.no>
+
+Virtual newsgroups are collections of other newsgroups. Why people
+want this is beyond me, but here goes:
+
+Create the group by saying
+
+`M-a my.virtual.newsgroup<RET>nnvirtual<RET>^rec\.aquaria\.*<RET>'
+
+This will create the group "nnvirtual:my.virtual.newsgroup", which
+will collect all articles from all the groups in the "rec.aquaria"
+hierarchy.
+
+If you want to edit the regular expression, just type `M-e' on the
+group line.
+
+Note that all the groups that are part of the virtual group have to be
+alive. This means that the cannot, absolutely not, be zombie or
+killed. They can be unsubscribed; that's no problem.
+
+You can combine groups from different servers in the same virtual
+newsgroup, something that may actually be useful. Say you have the
+group "comp.headers" on the server "news.server.no" and the same group
+on "news.server.edu". If people have posted articles with Distribution
+headers that stop propagation of their articles, combining these two
+newsgroups into one virtual newsgroup should give you a better view of
+what's going on.
+
+One caveat, though: The virtual group article numbers from the first
+source group (group A) will always be lower than the article numbers
+from the second (group B). This means that Gnus will believe that
+articles from group A are older than articles from group B. Threading
+will lessen these problems, but it might be a good idea to sort the
+threads over the date of the articles to get a correct feel for the
+flow of the groups:
+
+(setq gnus-thread-sort-functions '(gnus-thread-sort-by-date))
+
+If you only want this in virtual groups, you could say something along
+the lines of:
+
+(setq gnus-select-group-hook
+ (lambda ()
+ (if (eq 'nnvirtual (car (gnus-find-method-for-group
+ gnus-newsgroup-name)))
+ (progn
+ (make-local-variable 'gnus-thread-sort-functions)
+ (setq gnus-thread-sort-functions '(gnus-thread-sort-by-date))))))
+
+
+From lars Thu Feb 23 23:20:38 1995
+From: larsi@ifi.uio.no (ding)
+Date: Fri Feb 24 13:40:45 1995
+Subject: I want to kiboze everything in sight!
+Message-ID: <lars-doc10@eyesore.no>
+
+The nnkiboze backend collects articles that you are interested in from
+groups you are interested in. Below is a description for how you can
+gather all posts from me, and all posts about Gnus in the gnu.emacs
+hierarchy in one handy, easy to read group.
+
+Gnus will let you eat up all available machine resources, grinding
+everything to a halt. Including your nntp server. Who says Gnus isn't
+friendly?
+
+You want to do this, of course.
+
+Create an nnkiboze group the normal way:
+
+`M-a my.group<RET>nnkiboze<RET>^gnu.emacs.*<RET>'
+
+You now have a shiny new group that you can't enter. How...
+practical.
+
+But just wait, it gets worse.
+
+You now have to create a score file.
+
+`C-x C-f ~/News/nnkiboze:my.group.SCORE<RET>'
+
+Put something like the following in this file:
+
+(setq gnus-score-alist
+ '(("from"
+ ("Ingebrigtsen" nil 1000)
+ ("lmi" nil 5000))
+ ("subject"
+ ("Gnus" nil 10000))
+ (touched)))
+
+Save the file, and go to a shell window.
+
+Type:
+
+$ emacs -batch -l ~/.emacs -l nnkiboze -f nnkiboze-generate-groups
+
+Wait a few hours, and all articles from me, or articles about Gnus,
+will appear, as if by magic, in the nnkiboze group. You really want
+that, of course.
+
+Gnus actually grabs the headers of all the groups that supply the
+nnkiboze group with articles, so this isn't very kind. Pleasy only do
+it at night (`at' is a fine command), and please, *please*, limit the
+number of groups that supply articles to the group. If you specify ""
+as the address of this group, nnkiboze will ask for headers from *all*
+groups, and this is megs and megs and megs of data.
+
+Use it, don't abuse it. Be nice.
+
+
+
+
View
255 lisp/gnus-cache.el
@@ -52,7 +52,6 @@ variable to \"^nnml\".")
;;; Internal variables.
(defvar gnus-cache-buffer nil)
-(defvar gnus-group-alist nil)
(defvar gnus-cache-active-hashtb nil)
(defvar gnus-cache-active-altered nil)
@@ -67,6 +66,7 @@ variable to \"^nnml\".")
(defun gnus-cache-close ()
"Shut down the cache."
(gnus-cache-write-active)
+ (gnus-cache-save-buffers)
(setq gnus-cache-active-hashtb nil))
(defun gnus-cache-save-buffers ()
@@ -102,65 +102,68 @@ variable to \"^nnml\".")
(setq gnus-cache-buffer nil))))
(defun gnus-cache-possibly-enter-article
- (group article headers ticked dormant unread)
- (let ((number (mail-header-number headers))
- file dir)
- (if (or (not (vectorp headers)) ; This might be a dummy article.
- (< number 0) ; Reffed article.
- (and gnus-uncacheable-groups
- (string-match gnus-uncacheable-groups group))
- (not (gnus-cache-member-of-class
- gnus-cache-enter-articles ticked dormant unread))
- (file-exists-p (setq file (gnus-cache-file-name group article))))
- () ; Do nothing.
- ;; Possibly create the cache directory.
- (or (file-exists-p (setq dir (file-name-directory file)))
- (gnus-make-directory dir))
- ;; Save the article in the cache.
- (if (file-exists-p file)
- t ; The article already is saved.
- (let ((gnus-use-cache nil))
- (gnus-summary-select-article))
- (save-excursion
- (set-buffer gnus-original-article-buffer)
- (save-restriction
- (widen)
- (write-region (point-min) (point-max) file nil 'quiet))
- (gnus-cache-change-buffer group)
- (set-buffer (cdr gnus-cache-buffer))
- (goto-char (point-max))
- (forward-line -1)
- (while (condition-case ()
- (and (not (bobp))
- (> (read (current-buffer)) number))
- (error
- ;; The line was malformed, so we just remove it!!
- (gnus-delete-line)
- t))
- (forward-line -1))
- (if (bobp)
- (if (not (eobp))
- (progn
- (beginning-of-line)
- (if (< (read (current-buffer)) number)
- (forward-line 1)))
- (beginning-of-line))
- (forward-line 1))
- (beginning-of-line)
- ;; [number subject from date id references chars lines xref]
- (insert (format "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n"
- (mail-header-number headers)
- (mail-header-subject headers)
- (mail-header-from headers)
- (mail-header-date headers)
- (mail-header-id headers)
- (or (mail-header-references headers) "")
- (or (mail-header-chars headers) "")
- (or (mail-header-lines headers) "")
- (or (mail-header-xref headers) ""))))
- ;; Update the active info.
- (gnus-cache-update-active group number)
- t))))
+ (group article headers ticked dormant unread &optional force)
+ (when (or force (not (eq gnus-use-cache 'passive)))
+ (let ((number (mail-header-number headers))
+ file dir)
+ (when (and (vectorp headers) ; This might be a dummy article.
+ (> number 0) ; Reffed article.
+ (or (not gnus-uncacheable-groups)
+ (not (string-match gnus-uncacheable-groups group)))
+ (or force
+ (gnus-cache-member-of-class
+ gnus-cache-enter-articles ticked dormant unread))
+ (not (file-exists-p (setq file (gnus-cache-file-name
+ group article)))))
+ ;; Possibly create the cache directory.
+ (or (file-exists-p (setq dir (file-name-directory file)))
+ (gnus-make-directory dir))
+ ;; Save the article in the cache.
+ (if (file-exists-p file)
+ t ; The article already is saved.
+ (let ((gnus-use-cache nil))
+ (gnus-summary-select-article))
+ (save-excursion
+ (set-buffer gnus-original-article-buffer)
+ (save-restriction
+ (widen)
+ (write-region (point-min) (point-max) file nil 'quiet))
+ (gnus-cache-change-buffer group)
+ (set-buffer (cdr gnus-cache-buffer))
+ (goto-char (point-max))
+ (forward-line -1)
+ (while (condition-case ()
+ (and (not (bobp))
+ (> (read (current-buffer)) number))
+ (error
+ ;; The line was malformed, so we just remove it!!
+ (gnus-delete-line)
+ t))
+ (forward-line -1))
+ (if (bobp)
+ (if (not (eobp))
+ (progn
+ (beginning-of-line)
+ (if (< (read (current-buffer)) number)
+ (forward-line 1)))
+ (beginning-of-line))
+ (forward-line 1))
+ (beginning-of-line)
+ ;; [number subject from date id references chars lines xref]
+ (insert (format "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n"
+ (mail-header-number headers)
+ (mail-header-subject headers)
+ (mail-header-from headers)
+ (mail-header-date headers)
+ (mail-header-id headers)
+ (or (mail-header-references headers) "")
+ (or (mail-header-chars headers) "")
+ (or (mail-header-lines headers) "")
+ (or (mail-header-xref headers) ""))))
+ ;; Update the active info.
+ (gnus-cache-update-active group number)
+ (push number gnus-newsgroup-cached)
+ t)))))
(defun gnus-cache-enter-remove-article (article)
"Mark ARTICLE for later possible removal."
@@ -169,22 +172,23 @@ variable to \"^nnml\".")
(defun gnus-cache-possibly-remove-articles ()
"Possibly remove some of the removable articles."
- (let ((articles gnus-cache-removeable-articles)
- (cache-articles (gnus-cache-articles-in-group gnus-newsgroup-name))
- article)
- (gnus-cache-change-buffer gnus-newsgroup-name)
- (while articles
- (if (memq (setq article (pop articles)) cache-articles)
- ;; The article was in the cache, so we see whether we are
- ;; supposed to remove it from the cache.
- (gnus-cache-possibly-remove-article
- article (memq article gnus-newsgroup-marked)
- (memq article gnus-newsgroup-dormant)
- (or (memq article gnus-newsgroup-unreads)
- (memq article gnus-newsgroup-unselected))))))
- ;; The overview file might have been modified, save it
- ;; safe because we're only called at group exit anyway
- (gnus-cache-save-buffers))
+ (unless (eq gnus-use-cache 'passive)
+ (let ((articles gnus-cache-removeable-articles)
+ (cache-articles gnus-newsgroup-cached)
+ article)
+ (gnus-cache-change-buffer gnus-newsgroup-name)
+ (while articles
+ (if (memq (setq article (pop articles)) cache-articles)
+ ;; The article was in the cache, so we see whether we are
+ ;; supposed to remove it from the cache.
+ (gnus-cache-possibly-remove-article
+ article (memq article gnus-newsgroup-marked)
+ (memq article gnus-newsgroup-dormant)
+ (or (memq article gnus-newsgroup-unreads)
+ (memq article gnus-newsgroup-unselected))))))
+ ;; The overview file might have been modified, save it
+ ;; safe because we're only called at group exit anyway.
+ (gnus-cache-save-buffers)))
(defun gnus-cache-request-article (article group)
"Retrieve ARTICLE in GROUP from the cache."
@@ -206,16 +210,18 @@ variable to \"^nnml\".")
(> (cdr cache-active) (cdr active))
(setcdr active (cdr cache-active)))))
-(defun gnus-cache-retrieve-headers (articles group)
+(defun gnus-cache-retrieve-headers (articles group &optional fetch-old)
"Retrieve the headers for ARTICLES in GROUP."
- (let* ((cached (gnus-cache-articles-in-group group))
+ (let* ((cached
+ (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group)))
(articles (gnus-sorted-complement articles cached))
(cache-file (gnus-cache-file-name group ".overview"))
type)
;; We first retrieve all the headers that we don't have in
;; the cache.
(let ((gnus-use-cache nil))
- (setq type (and articles (gnus-retrieve-headers articles group))))
+ (setq type (and articles
+ (gnus-retrieve-headers articles group fetch-old))))
(gnus-cache-save-buffers)
;; Then we insert the cached headers.
(save-excursion
@@ -240,6 +246,45 @@ variable to \"^nnml\".")
(gnus-cache-braid-heads group cached)
type)))))
+(defun gnus-cache-enter-article (n)
+ "Enter the next N articles into the cache.
+If not given a prefix, use the process marked articles instead.
+Returns the list of articles entered."
+ (interactive "P")
+ (gnus-set-global-variables)
+ (let ((articles (gnus-summary-work-articles n))
+ article out)
+ (while articles
+ (setq article (pop articles))
+ (when (gnus-cache-possibly-enter-article
+ gnus-newsgroup-name article (gnus-summary-article-header article)
+ nil nil nil t)
+ (push article out))
+ (gnus-summary-remove-process-mark article)
+ (gnus-summary-update-secondary-mark article))
+ (gnus-summary-position-point)
+ (nreverse out)))
+
+(defun gnus-cache-remove-article (n)
+ "Remove the next N articles from the cache.
+If not given a prefix, use the process marked articles instead.
+Returns the list of articles removed."
+ (interactive "P")
+ (gnus-set-global-variables)
+ (let ((articles (gnus-summary-work-articles n))
+ article out)
+ (while articles
+ (setq article (pop articles))
+ (when (gnus-cache-possibly-remove-article article nil nil nil t)
+ (push article out))
+ (gnus-summary-remove-process-mark article)
+ (gnus-summary-update-secondary-mark article))
+ (gnus-summary-position-point)
+ (nreverse out)))
+
+(defun gnus-cached-article-p (article)
+ "Say whether ARTICLE is cached in the current group."
+ (memq article gnus-newsgroup-cached))
;;; Internal functions.
@@ -285,12 +330,13 @@ variable to \"^nnml\".")
(if (stringp article) article (int-to-string article))))
(defun gnus-cache-possibly-remove-article
- (article ticked dormant unread)
+ (article ticked dormant unread &optional force)
+ "Possibly remove ARTICLE from the cache."
(let ((file (gnus-cache-file-name gnus-newsgroup-name article)))
- (if (or (not (file-exists-p file))
- (not (gnus-cache-member-of-class
- gnus-cache-remove-articles ticked dormant unread)))
- nil
+ (when (and (file-exists-p file)
+ (or force
+ (gnus-cache-member-of-class
+ gnus-cache-remove-articles ticked dormant unread)))
(save-excursion
(delete-file file)
(set-buffer (cdr gnus-cache-buffer))
@@ -299,20 +345,19 @@ variable to \"^nnml\".")
(search-forward (concat "\n" (int-to-string article) "\t")
(point-max) t))
(delete-region (progn (beginning-of-line) (point))
- (progn (forward-line 1) (point))))))))
+ (progn (forward-line 1) (point)))))
+ (setq gnus-newsgroup-cached
+ (delq article gnus-newsgroup-cached))
+ t)))
(defun gnus-cache-articles-in-group (group)
+ "Return a sorted list of cached articles in GROUP."
(let ((dir (file-name-directory (gnus-cache-file-name group 1)))
articles)
- (if (not (file-exists-p dir))
- nil
- (setq articles (directory-files dir nil "^[0-9]+$" t))
- (if (not articles)
- nil
- (sort (mapcar (function (lambda (name)
- (string-to-int name)))
- articles)
- '<)))))
+ (when (file-exists-p dir)
+ (sort (mapcar (lambda (name) (string-to-int name))
+ (directory-files dir nil "^[0-9]+$" t))
+ '<))))
(defun gnus-cache-braid-nov (group cached)
(let ((cache-buf (get-buffer-create " *gnus-cache*"))
@@ -420,8 +465,9 @@ variable to \"^nnml\".")
(mapatoms
(lambda (sym)
(when (and sym (boundp sym))
- (insert (symbol-name sym) " " (cdr (symbol-value sym))
- " " (car (symbol-value sym)) " y\n")))
+ (insert (format "%s %d %d y\n"
+ (symbol-name sym) (cdr (symbol-value sym))
+ (car (symbol-value sym))))))
gnus-cache-active-hashtb)
(write-region
(point-min) (point-max) gnus-cache-active-file nil 'silent))
@@ -445,6 +491,7 @@ If LOW, update the lower bound instead."
;;;###autoload
(defun gnus-cache-generate-active (&optional directory)
"Generate the cache active file."
+ (interactive)
(let* ((top (null directory))
(directory (or directory (expand-file-name gnus-cache-directory)))
(files (directory-files directory 'full))
@@ -457,6 +504,7 @@ If LOW, update the lower bound instead."
?/ ?.)))
nums alphs)
(when top
+ (gnus-message 5 "Generating the cache active file...")
(setq gnus-cache-active-hashtb (gnus-make-hashtable 123)))
;; Separate articles from all other files and directories.
(while files
@@ -471,13 +519,24 @@ If LOW, update the lower bound instead."
;; Go through all the other files.
(while alphs
(when (and (file-directory-p (car alphs))
- (not (string-match "^\\.\\.?$" (file-name-nondirectory (car alphs)))))
+ (not (string-match "^\\.\\.?$"
+ (file-name-nondirectory (car alphs)))))
;; We descend directories.
(gnus-cache-generate-active (car alphs)))
(setq alphs (cdr alphs)))
;; Write the new active file.
(when top
- (gnus-cache-write-active t))))
+ (gnus-cache-write-active t)
+ (gnus-message 5 "Generating the cache active file...done"))))
+
+;;;###autoload
+(defun gnus-cache-generate-nov-databases (dir)
+ "Generate NOV files recursively starting in DIR."
+ (interactive (list gnus-cache-directory))
+ (gnus-cache-close)
+ (require 'nnml)
+ (let ((nnml-generate-active-function 'identity))
+ (nnml-generate-nov-databases dir)))
(provide 'gnus-cache)
View
3  lisp/gnus-cus.el
@@ -65,7 +65,8 @@ less space and be faster as a result.")
(summary-highlight
article-highlight
summary-menu group-menu article-menu
- browse-menu server-menu))
+ browse-menu server-menu
+ page-marker))
(name . gnus-visual)
(type . toggle))
((tag . "WWW Browser")
View
8 lisp/gnus-mh.el
@@ -64,18 +64,14 @@ Optional argument FOLDER specifies folder name."
t))))
(errbuf (get-buffer-create " *Gnus rcvstore*"))
;; Find the rcvstore program.
- (rcvstore
- (expand-file-name
- (mh-search-path
- (if mh-lib (cons mh-lib exec-path) exec-path)
- "rcvstore"))))
+ (exec-path (if mh-lib (cons mh-lib exec-path) exec-path)))
(gnus-eval-in-buffer-window
gnus-original-article-buffer
(save-restriction
(widen)
(unwind-protect
(call-process-region
- (point-min) (point-max) rcvstore nil errbuf nil folder)
+ (point-min) (point-max) "rcvstore" nil errbuf nil folder)
(set-buffer errbuf)
(if (zerop (buffer-size))
(message "Article saved in folder: %s" folder)
View
43 lisp/gnus-msg.el
@@ -530,7 +530,7 @@ Type \\[describe-mode] in the buffer to get a list of commands."
"Return non-nil if GROUP (and ARTICLE) come from a news server."
(or (gnus-member-of-valid 'post group) ; Ordinary news group.
(and (gnus-member-of-valid 'post-mail group) ; Combined group.
- (eq (gnus-request-type group article) 'post))))
+ (eq (gnus-request-type group article) 'news))))
(defun gnus-inews-news (&optional use-group-method)
"Send a news message.
@@ -1553,7 +1553,7 @@ Customize the variable gnus-mail-forward-method to use another mailer."
(interactive "sResend message to: ")
(gnus-summary-select-article)
(save-excursion
- (let (resent)
+ (let (resent beg)
;; We first set up a normal mail buffer.
(nnheader-set-temp-buffer " *Gnus resend*")
;; This code from sendmail.el
@@ -1565,8 +1565,7 @@ Customize the variable gnus-mail-forward-method to use another mailer."
(insert mail-header-separator "\n")
;; Insert our usual headers.
(gnus-inews-narrow-to-headers)
- (let ((headers '(From Date To)))
- (gnus-inews-insert-headers headers))
+ (gnus-inews-insert-headers '(From Date To))
(goto-char (point-min))
;; Rename them all to "Resent-*".
(while (re-search-forward "^[A-Za-z]" nil t)
@@ -1575,12 +1574,17 @@ Customize the variable gnus-mail-forward-method to use another mailer."
(widen)
(forward-line)
(delete-region (point) (point-max))
+ (setq beg (point))
;; Insert the message to be resent.
(insert-buffer-substring gnus-original-article-buffer)
(goto-char (point-min))
(search-forward "\n\n")
(forward-char -1)
(insert mail-header-separator)
+ ;; Rename all old ("Also-")Resent headers.
+ (while (re-search-backward "^\\(Also-\\)?Resent-" beg t)
+ (beginning-of-line)
+ (insert "Also-"))
;; Send it.
(mail-send)
(kill-buffer (current-buffer)))))
@@ -1628,6 +1632,7 @@ mailer."
(pop-to-buffer gnus-mail-buffer)
(erase-buffer)
(gnus-mail-setup 'new to subject)
+ (gnus-inews-insert-gcc)
(run-hooks 'gnus-mail-hook)))
(defun gnus-mail-reply (&optional yank to-address followup)
@@ -1739,6 +1744,7 @@ mailer."
(setq gnus-in-reply-to message-of)
(auto-save-mode auto-save-default)
+ (gnus-inews-insert-gcc)
(if (and follow-to (listp follow-to))
(progn
@@ -1821,6 +1827,7 @@ If INHIBIT-PROMPT, never prompt for a Subject."
(insert "\n\n")
(gnus-inews-insert-bfcc)
+ (gnus-inews-insert-gcc)
(gnus-inews-insert-signature)
(and gnus-post-prepare-function
(gnus-functionp gnus-post-prepare-function)
@@ -1981,7 +1988,8 @@ If INHIBIT-PROMPT, never prompt for a Subject."
(insert to))))
(gnus-inews-insert-bfcc)
-
+ (gnus-inews-insert-gcc)
+
;; Now the headers should be ok, so we do the yanking.
(goto-char (point-min))
(re-search-forward
@@ -2449,17 +2457,20 @@ Headers will be generated before sending."
(insert gnus-author-copy))))
(defun gnus-inews-insert-gcc ()
- (let* ((group gnus-outgoing-message-group)
- (gcc (cond
- ((gnus-functionp group)
- (funcall group))
- ((or (stringp group) (list group))
- group))))
- (when gcc
- (insert "Gcc: "
- (if (stringp group) group
- (mapconcat 'identity group " "))
- "\n"))))
+ (save-excursion
+ (save-restriction
+ (gnus-inews-narrow-to-headers)
+ (let* ((group gnus-outgoing-message-group)
+ (gcc (cond
+ ((gnus-functionp group)
+ (funcall group))
+ ((or (stringp group) (list group))
+ group))))
+ (when gcc
+ (insert "Gcc: "
+ (if (stringp group) group
+ (mapconcat 'identity group " "))
+ "\n"))))))
;;; Handling rejected (and postponed) news.
View
98 lisp/gnus-score.el
@@ -693,6 +693,9 @@ SCORE is the score to add."
(exclude-files (gnus-score-get 'exclude-files alist))
(orphan (car (gnus-score-get 'orphan alist)))
(adapt (gnus-score-get 'adapt alist))
+ (thread-mark-and-expunge
+ (car (gnus-score-get 'thread-mark-and-expunge alist)))
+ (adapt-file (car (gnus-score-get 'adapt-file)))
(local (gnus-score-get 'local alist))
(eval (car (gnus-score-get 'eval alist))))
;; We do not respect eval and files atoms from global score
@@ -701,7 +704,8 @@ SCORE is the score to add."
(setq lists (apply 'append lists
(mapcar (lambda (file)
(gnus-score-load-file file))
- files))))
+ (if adapt-file (cons adapt-file files)
+ files)))))
(and eval (not global) (eval eval))
;; We then expand any exclude-file directives.
(setq gnus-scores-exclude-files
@@ -734,10 +738,14 @@ SCORE is the score to add."
(t
;;(setq gnus-newsgroup-adaptive gnus-use-adaptive-scoring)
gnus-default-adaptive-score-alist)))
+ (setq gnus-thread-expunge-below
+ (or thread-mark-and-expunge gnus-thread-expunge-below))
(setq gnus-summary-mark-below
(or mark mark-and-expunge gnus-summary-mark-below))
(setq gnus-summary-expunge-below
- (or expunge mark-and-expunge gnus-summary-expunge-below)))
+ (or expunge mark-and-expunge gnus-summary-expunge-below))
+ (setq gnus-newsgroup-adaptive-score-file
+ (or adapt-file gnus-newsgroup-adaptive-score-file)))
(setq gnus-current-score-file file)
(setq gnus-score-alist alist)
lists))
@@ -1597,8 +1605,10 @@ SCORE is the score to add."
(setq elem (cdr elem)))
(setq malist (cdr malist)))
;; We change the score file to the adaptive score file.
- (gnus-score-load-file (gnus-score-file-name
- gnus-newsgroup-name gnus-adaptive-file-suffix))
+ (gnus-score-load-file
+ (or gnus-newsgroup-adaptive-score-file
+ (gnus-score-file-name
+ gnus-newsgroup-name gnus-adaptive-file-suffix)))
;; The we score away.
(while data
(setq elem (cdr (assq (gnus-data-mark (car data)) alist)))
@@ -1837,46 +1847,46 @@ GROUP using BNews sys file syntax."
(insert (car sfiles))
(goto-char (point-min))
;; First remove the suffix itself.
- (re-search-forward (concat "." score-regexp))
- (replace-match "" t t)
- (goto-char (point-min))
- (if (looking-at (regexp-quote kill-dir))
- ;; If the file name was just "SCORE", `klen' is one character
- ;; too much.
- (delete-char (min (1- (point-max)) klen))
- (goto-char (point-max))
- (search-backward "/")
- (delete-region (1+ (point)) (point-min)))
- ;; If short file names were used, we have to translate slashes.
- (goto-char (point-min))
- (while (re-search-forward "[/:]" nil t)
- (replace-match "." t t))
- ;; Cludge to get rid of "nntp+" problems.
- (goto-char (point-min))
- (and (looking-at "nn[a-z]+\\+")
- (progn
- (search-forward "+")
- (forward-char -1)
- (insert "\\")))
- ;; Translate "all" to ".*".
- (while (search-forward "all" nil t)
- (replace-match ".*" t t))
- (goto-char (point-min))
- ;; Deal with "not."s.
- (if (looking-at "not.")
- (progn
- (setq not-match t)
- (setq regexp (buffer-substring 5 (point-max))))
- (setq regexp (buffer-substring 1 (point-max)))
- (setq not-match nil))
- ;; Finally - if this resulting regexp matches the group name,
- ;; we add this score file to the list of score files
- ;; applicable to this group.
- (if (or (and not-match
- (not (string-match regexp group)))
- (and (not not-match)
- (string-match regexp group)))
- (setq ofiles (cons (car sfiles) ofiles)))
+ (when (re-search-forward (concat "." score-regexp) nil t)
+ (replace-match "" t t)
+ (goto-char (point-min))
+ (if (looking-at (regexp-quote kill-dir))
+ ;; If the file name was just "SCORE", `klen' is one character
+ ;; too much.
+ (delete-char (min (1- (point-max)) klen))
+ (goto-char (point-max))
+ (search-backward "/")
+ (delete-region (1+ (point)) (point-min)))
+ ;; If short file names were used, we have to translate slashes.
+ (goto-char (point-min))
+ (while (re-search-forward "[/:]" nil t)
+ (replace-match "." t t))
+ ;; Cludge to get rid of "nntp+" problems.
+ (goto-char (point-min))
+ (and (looking-at "nn[a-z]+\\+")
+ (progn
+ (search-forward "+")
+ (forward-char -1)
+ (insert "\\")))
+ ;; Translate "all" to ".*".
+ (while (search-forward "all" nil t)
+ (replace-match ".*" t t))
+ (goto-char (point-min))
+ ;; Deal with "not."s.
+ (if (looking-at "not.")
+ (progn
+ (setq not-match t)
+ (setq regexp (buffer-substring 5 (point-max))))
+ (setq regexp (buffer-substring 1 (point-max)))
+ (setq not-match nil))
+ ;; Finally - if this resulting regexp matches the group name,
+ ;; we add this score file to the list of score files
+ ;; applicable to this group.
+ (if (or (and not-match
+ (not (string-match regexp group)))
+ (and (not not-match)
+ (string-match regexp group)))
+ (setq ofiles (cons (car sfiles) ofiles))))
(setq sfiles (cdr sfiles)))
(kill-buffer (current-buffer))
;; Slight kludge here - the last score file returned should be
View
55 lisp/gnus-topic.el
@@ -241,11 +241,11 @@ If LOWEST is non-nil, list all newsgroups of level LOWEST or higher."
(add-text-properties
(point)
(prog1 (1+ (point))
- (eval gnus-topic-line-format-spec))
+ (eval gnus-topic-line-format-spec)
+ (gnus-group-remove-excess-properties))
(list 'gnus-topic name
'gnus-topic-level level
- 'gnus-topic-visible visiblep))
- (gnus-group-remove-excess-properties)))
+ 'gnus-topic-visible visiblep))))
(defun gnus-topic-previous-topic (topic)
"Return the previous topic on the same level as TOPIC."
@@ -526,22 +526,47 @@ group."
(defun gnus-topic-kill-group (&optional n discard)
"Kill the next N groups."
(interactive "P")
- (if (not (gnus-group-topic-p))
- (gnus-group-kill-group n discard)
- (let ((topic (gnus-group-topic-name)))
- (gnus-topic-remove-topic nil t)
- (push (gnus-topic-find-topology topic nil nil gnus-topic-topology)
- gnus-topic-killed-topics))))
+ (if (gnus-group-topic-p)
+ (let ((topic (gnus-group-topic-name)))
+ (gnus-topic-remove-topic nil t)
+ (push (gnus-topic-find-topology topic nil nil gnus-topic-topology)
+ gnus-topic-killed-topics))
+ ;; We first kill the groups the normal way...
+ (let ((killed (gnus-group-kill-group n discard))
+ group alist)
+ ;; Then we remove the killed groups from the topics they belong to.
+ (when (stringp killed)
+ (setq killed (list killed)))
+ (while killed
+ (when (setq alist (assoc (gnus-group-topic (setq group (pop killed)))
+ gnus-topic-alist))
+ (setcdr alist (delete group (cdr alist))))))))
(defun gnus-topic-yank-group (&optional arg)
"Yank the last topic."
(interactive "p")
- (if (null gnus-topic-killed-topics)
- (gnus-group-yank-group arg)
- (let ((previous (gnus-group-parent-topic))
- (item (nth 1 (pop gnus-topic-killed-topics))))
- (gnus-topic-create-topic
- (car item) (gnus-topic-parent-topic previous) previous))))
+ (if gnus-topic-killed-topics
+ (let ((previous (gnus-group-parent-topic))
+ (item (nth 1 (pop gnus-topic-killed-topics))))
+ (gnus-topic-create-topic
+ (car item) (gnus-topic-parent-topic previous) previous))
+ ;; We first yank the groups the normal way...
+ (let* ((topic (gnus-group-parent-topic))
+ (prev (gnus-group-group-name))
+ (alist (assoc topic gnus-topic-alist))
+ (yanked (gnus-group-yank-group arg))
+ group)
+ ;; Then we enter the yanked groups in the topics they belong to.
+ (when (stringp yanked)
+ (setq yanked (list yanked)))
+ (if (not prev)
+ (nconc alist yanked)
+ (setq alist (cdr alist))
+ (while (cdr alist)
+ (when (equal (car (cdr alist)) prev)
+ (setcdr alist (nconc yanked (cdr alist)))
+ (setq alist nil))
+ (setq alist (cdr alist)))))))
(defun gnus-topic-hide-topic ()
"Hide all subtopics under the current topic."
View
3  lisp/gnus-uu.el
@@ -633,7 +633,8 @@ The headers will be included in the sequence they are matched.")
(setq files (gnus-uu-unpack-files files)))
(gnus-uu-add-file (mapcar (lambda (file) (cdr (assq 'name file))) files))
(setq files (nreverse (gnus-uu-get-actions files)))
- (or not-insert (gnus-summary-insert-pseudos files save))))
+ (or not-insert (not gnus-insert-pseudo-articles)
+ (gnus-summary-insert-pseudos files save))))
;; Return a list of files in dir.
(defun gnus-uu-scan-directory (dir)
View
70 lisp/gnus-vis.el
@@ -956,8 +956,8 @@ If nil, the user will be asked for a duration.")
(end (progn (end-of-line) (point)))
;; now find out where the line starts and leave point there.
(beg (progn (beginning-of-line) (point)))
- (score (or (cdr (assq (or (gnus-summary-article-number)
- gnus-current-article)
+ (article (gnus-summary-article-number))
+ (score (or (cdr (assq (or article gnus-current-article)
gnus-newsgroup-scored))
gnus-summary-default-score 0))
(default gnus-summary-default-score)
@@ -1179,20 +1179,31 @@ call it with the value of the `gnus-data' text property."
(fun (get-text-property (point) 'gnus-callback)))
(if fun (funcall fun data))))
-;; Suggested by Arne Elofsson <arne@hodgkin.mbi.ucla.edu>
-(defun gnus-article-next-button ()
- "Move point to next button."
- (interactive)
- (if (get-text-property (point) 'gnus-callback)
- (goto-char (next-single-property-change (point) 'gnus-callback
- nil (point-max))))
- (let ((pos (next-single-property-change (point) 'gnus-callback)))
- (if pos
- (goto-char pos)
- (setq pos (next-single-property-change (point-min) 'gnus-callback))
- (if pos
- (goto-char pos)
- (error "No buttons found")))))
+(defun gnus-article-prev-button (n)
+ "Move point to N buttons backward.
+If N is negative, move forward instead."
+ (interactive "p")
+ (gnus-article-next-button (- n)))
+
+(defun gnus-article-next-button (n)
+ "Move point to N buttons forward.
+If N is negative, move backward instead."
+ (interactive "p")
+ (let ((function (if (< n 0) 'prev-single-property-change
+ 'next-single-property-change))
+ (limit (if (< n 0) (point-min) (point-max))))
+ (setq n (abs n))
+ (while (and (not (= limit (point)))
+ (> n 0))
+ ;; Skip past the current button.
+ (when (get-text-property (point) 'gnus-callback)
+ (goto-char (funcall function (point) 'gnus-callback nil limit)))
+ ;; Go to the next (or previous) button.
+ (funcall function (point) 'gnus-callback nil limit)
+ (decf n))
+ (unless (zerop n)
+ (gnus-message 5 "No more buttons"))
+ n))
(defun gnus-article-highlight (&optional force)
"Highlight current article.
@@ -1467,6 +1478,33 @@ specified by `gnus-button-alist'."
"Browse ADDRESS."
(funcall browse-url-browser-function address))
+;;; Next/prev buttons in the article buffer.
+
+(defvar gnus-next-page-line-format "%{%(Next page...%)%}\n")
+(defvar gnus-prev-page-line-format "%{%(Previous page...%)%}\n")
+
+(defvar gnus-prev-page-map nil)
+(unless gnus-prev-page-map
+ (setq gnus-prev-page-map (make-sparse-keymap))
+ (define-key gnus-prev-page-map "\n" 'gnus-article-prev-page))
+
+(defun gnus-insert-prev-page-button ()
+ (let ((buffer-read-only nil))
+ (gnus-remove-text-with-property 'gnus-prev)
+ (gnus-eval-format gnus-prev-page-line-format nil
+ `(gnus-prev t local-map ,gnus-prev-page-map))))
+
+(defvar gnus-next-page-map nil)
+(unless gnus-next-page-map
+ (setq gnus-next-page-map (make-sparse-keymap))
+ (define-key gnus-next-page-map "\n" 'gnus-article-next-page))
+
+(defun gnus-insert-next-page-button ()
+ (let ((buffer-read-only nil))
+ (gnus-remove-text-with-property 'gnus-next)
+ (gnus-eval-format gnus-next-page-line-format nil
+ `(gnus-next t local-map ,gnus-next-page-map))))
+
;;; Compatibility Functions:
(or (fboundp 'rassoc)
View
124 lisp/gnus-xmas.el
@@ -224,6 +224,15 @@ call it with the value of the `gnus-data' text property."
(easy-menu-add gnus-article-article-menu)
(easy-menu-add gnus-article-treatment-menu))
+(defun gnus-xmas-read-event-char ()
+ "Get the next event."
+ (let ((event (next-event)))
+ (while (timeout-event-p event)
+ (setq event (next-event)))
+ (cons (and (key-press-event-p event)
+ (numberp (event-key event))
+ (event-to-character event))
+ event)))
(defun gnus-xmas-define ()
(setq gnus-mouse-2 [button2])
@@ -244,7 +253,6 @@ call it with the value of the `gnus-data' text property."
(fset 'set-text-properties 'gnus-xmas-set-text-properties)
(or (boundp 'standard-display-table) (setq standard-display-table nil))
- (or (boundp 'read-event) (fset 'read-event 'next-command-event))
(defvar gnus-mouse-face-prop 'highlight)
@@ -302,8 +310,7 @@ pounce directly on the real variables themselves.")
(defun gnus-xmas-redefine ()
-
-
+ "Redefine lots of Gnus functions for XEmacs."
(fset 'gnus-summary-make-display-table (lambda () nil))
(fset 'gnus-visual-turn-off-edit-menu 'identity)
(fset 'gnus-highlight-selected-summary
@@ -316,6 +323,8 @@ pounce directly on the real variables themselves.")
(fset 'gnus-article-add-button 'gnus-xmas-article-add-button)
(fset 'gnus-window-top-edge 'gnus-xmas-window-top-edge)
(fset 'set-text-properties 'gnus-xmas-set-text-properties)
+ (fset 'gnus-read-event-char 'gnus-xmas-read-event-char)
+ (fset 'gnus-group-startup-message 'gnus-xmas-group-startup-message)
(or (fboundp 'appt-select-lowest-window)
(fset 'appt-select-lowest-window
@@ -349,56 +358,75 @@ pounce directly on the real variables themselves.")
(setq path (cdr path))))
gnus-xmas-glyph-directory)))
-(defun gnus-xmas-group-startup (&optional x y)
+(defun gnus-xmas-group-startup-message (&optional x y)
"Insert startup message in current buffer."
;; Insert the message.
+ (gnus-xmas-find-glyph-directory)
(erase-buffer)
- (if (featurep 'xpm)
- (progn
- (set-glyph-property gnus-xmas-logo 'image "~/tmp/gnus.xpm")
- (set-glyph-image gnus-xmas-logo "~/tmp/gnus.xpm" 'global 'x)
-
- (insert " ")
- (set-extent-begin-glyph (make-extent (point) (point)) gnus-xmas-logo)
- (insert "
- Gnus * A newsreader for Emacsen
- A Praxis Release * larsi@ifi.uio.no")
- (goto-char (point-min))
- (while (not (eobp))
- (insert (make-string (/ (max (- (window-width) (or x 35)) 0) 2)
- ? ))
- (forward-line 1))
- (goto-char (point-min))
- ;; +4 is fuzzy factor.
- (insert-char ?\n (/ (max (- (window-height) (or y 24)) 0) 2)))
-
- (insert
- (format "
- %s
- A newsreader
- for GNU Emacs
-
- Based on GNUS
- written by
- Masanobu UMEDA
-
- A Praxis Release
- larsi@ifi.uio.no
+ (let ((file (and gnus-xmas-glyph-directory
+ (concat
+ (file-name-as-directory gnus-xmas-glyph-directory)
+ "gnus.xpm"))))
+ (if (and (featurep 'xpm)
+ file (file-exists-p file))
+ (progn
+ (set-glyph-property gnus-xmas-logo 'image file)
+ (set-glyph-image gnus-xmas-logo file 'global 'x)
+
+ (insert " ")
+ (set-extent-begin-glyph (make-extent (point) (point)) gnus-xmas-logo)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (insert (make-string (/ (max (- (window-width) (or x 35)) 0) 2)
+ ? ))
+ (forward-line 1))
+ (goto-char (point-min))
+ (let* ((pheight (+ 20 (count-lines (point-min) (point-max))))
+ (wheight (window-height))
+ (rest (- wheight pheight)))
+ (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n))))
+
+ (insert
+ (format " %s
+ _ ___ _ _
+ _ ___ __ ___ __ _ ___
+ __ _ ___ __ ___
+ _ ___ _
+ _ _ __ _
+ ___ __ _
+ __ _
+ _ _ _
+ _ _ _
+ _ _ _
+ __ ___
+ _ _ _ _
+ _ _
+ _ _
+ _ _
+ _
+ __
+
"
- gnus-version))
- ;; And then hack it.
- ;; 18 is the longest line.
- (indent-rigidly (point-min) (point-max)
- (/ (max (- (window-width) (or x 28)) 0) 2))
+ ""))
+ ;; And then hack it.
+ (gnus-indent-rigidly (point-min) (point-max)
+ (/ (max (- (window-width) (or x 46)) 0) 2))
+ (goto-char (point-min))
+ (forward-line 1)
+ (let* ((pheight (count-lines (point-min) (point-max)))
+ (wheight (window-height))
+ (rest (- wheight pheight)))
+ (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n))))
+ ;; Fontify some.
+ (goto-char (point-min))
+ (and (search-forward "Praxis" nil t)
+ (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
(goto-char (point-min))
- ;; +4 is fuzzy factor.
- (insert-char ?\n (/ (max (- (window-height) (or y 12)) 0) 2)))
-
- ;; Fontify some.
- (goto-char (point-min))
- (search-forward "Praxis")
- (put-text-property (match-beginning 0) (match-end 0) 'face 'bold)
- (goto-char (point-min)))
+ (let* ((mode-string (gnus-group-set-mode-line)))
+ (setq mode-line-buffer-identification
+ (list (concat gnus-version (substring (car mode-string) 4))))
+ (set-buffer-modified-p t))))
+
;;; The toolbar.
View
1,205 lisp/gnus.el
@@ -254,6 +254,11 @@ saved will be used.")
(defvar gnus-asynchronous nil
"*If non-nil, Gnus will supply backends with data needed for async article fetching.")
+(defvar gnus-kill-summary-on-exit t
+ "*If non-nil, kill the summary buffer when you exit from it.
+If nil, the summary will become a \"*Dead Summary*\" buffer, and
+it will be killed sometime later.")
+
(defvar gnus-large-newsgroup 200
"*The number of articles which indicates a large newsgroup.
If the number of articles in a newsgroup is greater than this value,
@@ -320,16 +325,27 @@ The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER.")
The function is called with NEWSGROUP, HEADERS, and optional
LAST-FILE.")
-(defvar gnus-split-methods nil
+(defvar gnus-split-methods
+ '((gnus-article-archive-name))
"*Variable used to suggest where articles are to be saved.
-The syntax of this variable is the same as `nnmail-split-methods'.
-
For instance, if you would like to save articles related to Gnus in
the file \"gnus-stuff\", and articles related to VM in \"vm-stuff\",
you could set this variable to something like:
'((\"^Subject:.*gnus\\|^Newsgroups:.*gnus\" \"gnus-stuff\")
- (\"^Subject:.*vm\\|^Xref:.*vm\" \"vm-stuff\"))")
+ (\"^Subject:.*vm\\|^Xref:.*vm\" \"vm-stuff\"))
+
+This variable is an alist where the where the key is the match and the
+value is a list of possible files to save in if the match is non-nil.
+
+If the match is a string, it is used as a regexp match on the
+article. If the match is a symbol, that symbol will be funcalled
+from the buffer of the article to be saved with the newsgroup as the
+parameter. If it is a list, it will be evaled in the same buffer.
+
+If this form or function returns a string, this string will be used as
+a possible file name; and if it returns a non-nil list, that list will
+be used as possible file names.")
(defvar gnus-save-score nil
"*If non-nil, save group scoring info.")
@@ -338,7 +354,10 @@ you could set this variable to something like:
"*If non-nil, use some adaptive scoring scheme.")
(defvar gnus-use-cache nil
- "*If non-nil, Gnus will cache (some) articles locally.")
+ "*If nil, Gnus will ignore the article cache.
+If `passive', it will allow entering (and reading) articles
+explicitly entered into the cache. If anything else, use the
+cache to the full extent of the law.")
(defvar gnus-keep-backlog nil
"*If non-nil, Gnus will keep read articles for later re-retrieval.
@@ -514,6 +533,11 @@ less than this variable, are subscribed.")
(defvar gnus-level-default-unsubscribed 6
"*New unsubscribed groups will be unsubscribed at this level.")
+(defvar gnus-activate-level (1+ gnus-level-subscribed)
+ "*Groups higher than this level won't be activated on startup.
+Setting this variable to something log might save lots of time when
+you have many groups that you aren't interested in.")
+
(defvar gnus-activate-foreign-newsgroups 4
"*If nil, Gnus will not check foreign newsgroups at startup.
If it is non-nil, it should be a number between one and nine. Foreign
@@ -654,10 +678,12 @@ thus making them effectively non-existent.")
(defvar gnus-ignored-headers
"^Path:\\|^Posting-Version:\\|^Article-I.D.:\\|^Expires:\\|^Date-Received:\\|^References:\\|^Control:\\|^Xref:\\|^Lines:\\|^Posted:\\|^Relay-Version:\\|^Message-ID:\\|^Nf-ID:\\|^Nf-From:\\|^Approved:\\|^Sender:\\|^Received:\\|^Mail-from:"
"*All headers that match 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.")
(defvar gnus-visible-headers "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Resent-"
"*All headers that do not match this regexp will be hidden.
+This variable can also be a list of regexp of headers to remain visible.
If this variable is non-nil, `gnus-ignored-headers' will be ignored.")
(defvar gnus-sorted-header-list
@@ -820,7 +846,7 @@ inserts new groups at the beginning of the list of groups;
`gnus-subscribe-alphabetically' inserts new groups in strict
alphabetic order; `gnus-subscribe-hierarchically' inserts new groups
in hierarchical newsgroup order; `gnus-subscribe-interactively' asks
-for your decision.")
+for your decision; `gnus-subscribe-killed' kills all new groups.")
;; Suggested by a bug report by Hallvard B Furuseth.
;; <h.b.furuseth@usit.uio.no>.
@@ -884,6 +910,10 @@ list.")
"*Mark used for articles that are caught up.")
(defvar gnus-replied-mark ?A
"*Mark used for articles that have been replied to.")
+(defvar gnus-cached-mark ?*
+ "*Mark used for articles that are in the cache.")
+(defvar gnus-saved-mark ?S
+ "*Mark used for articles that have been saved to.")
(defvar gnus-process-mark ?#
"*Process mark.")
(defvar gnus-ancient-mark ?O
@@ -912,6 +942,9 @@ will not be asked to confirm the command.")
If nil, all files that use the same viewing command will be given as a
list of parameters to that command.")
+(defvar gnus-insert-pseudo-articles t
+ "*If non-nil, insert pseudo-articles when decoding articles.")
+
(defvar gnus-group-line-format "%M%S%p%P%5y: %(%g%)\n"
"*Format of group lines.
It works along the same lines as a normal formatting string,
@@ -1023,14 +1056,37 @@ with some simple extensions.
%S The subject")
-(defvar gnus-summary-mode-line-format "Gnus %G/%A %Z"
- "*The format specification for the summary mode line.")
-
-(defvar gnus-article-mode-line-format "Gnus %G/%A %S"
- "*The format specification for the article mode line.")
+(defvar gnus-summary-mode-line-format "Gnus: %%b [%A] %Z"
+ "*The format specification for the summary mode line.
+It works along the same lines as a normal formatting string,
+with some simple extensions:
+
+%G Group name
+%p Unprefixed group name
+%A Current article number
+%V Gnus version
+%U Number of unread articles in the group
+%e Number of unselected articles in the group
+%Z A string with unread/unselected article counts
+%g Shortish group name
+%S Subject of the current article
+%u User-defined spec
+%s Current score file name
+%d Number of dormant articles
+%r Number of articles that have been marked as read in this session
+%E Number of articles expunged by the score files")
+
+(defvar gnus-article-mode-line-format "Gnus: %%b %S"
+ "*The format specification for the article mode line.
+See `gnus-summary-mode-line-format' for a closer description.")
+
+(defvar gnus-group-mode-line-format "Gnus: %%b {%M:%S}"
+ "*The format specification for the group mode line.
+It works along the same lines as a normal formatting string,
+with some simple extensions:
-(defvar gnus-group-mode-line-format "Gnus List of groups {%M:%S} "
- "*The format specification for the group mode line.")
+%S The native news server.
+%M The native select method.")
(defvar gnus-valid-select-methods
'(("nntp" post address prompt-address)
@@ -1062,7 +1118,7 @@ updated with information that may be pertinent.
If this variable is nil, screen refresh may be quicker.")
;; Added by Keinonen Kari <kk85613@cs.tut.fi>.
-(defvar gnus-mode-non-string-length 25
+(defvar gnus-mode-non-string-length nil
"*Max length of mode-line non-string contents.
If this is nil, Gnus will take space as is needed, leaving the rest
of the modeline intact.")
@@ -1077,6 +1133,9 @@ of the modeline intact.")
This variable is local to each summary buffer and usually set by the
score file.")
+(defvar gnus-article-sort-functions '(gnus-article-sort-by-number)
+ "*List of functions used for sorting articles in the summary buffer.")
+
(defvar gnus-thread-sort-functions '(gnus-thread-sort-by-number)
"*List of functions used for sorting threads in the summary buffer.
By default, threads are sorted by article number.
@@ -1098,6 +1157,14 @@ subthread and should then return the score of the thread.
Some functions you can use are `+', `max', or `min'.")
+(defvar gnus-summary-expunge-below nil
+ "All articles that have a score less than this variable will be expunged.")
+
+(defvar gnus-thread-expunge-below nil
+ "All threads that have a total score less than this variable will be expunged.
+See `gnus-thread-score-function' for en explanation of what a
+\"thread score\" is.")
+
(defvar gnus-auto-subscribed-groups
"^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl"
"*All new groups that match this regexp will be subscribed automatically.
@@ -1318,6 +1385,7 @@ automatically when it is selected.")
(defvar gnus-inhibit-hiding nil)
(defvar gnus-topic-indentation "")
+(defvar gnus-inhibit-limiting nil)
(defvar gnus-article-mode-map nil)
(defvar gnus-dribble-buffer nil)
@@ -1329,6 +1397,7 @@ automatically when it is selected.")
(defvar gnus-nocem-hashtb nil)
(defvar gnus-current-score-file nil)
+(defvar gnus-newsgroup-adaptive-score-file nil)
(defvar gnus-scores-exclude-files nil)
(defvar gnus-opened-servers nil)
@@ -1344,7 +1413,7 @@ automatically when it is selected.")
(defvar gnus-summary-display-table nil)
(defconst gnus-group-line-format-alist
- `((?M gnus-tmp-marked ?c)
+ `((?M gnus-tmp-marked-mark ?c)
(?S gnus-tmp-subscribed ?c)
(?L gnus-tmp-level ?d)
(?N gnus-tmp-number ?s)
@@ -1428,6 +1497,9 @@ variable (string, integer, character, etc).")
(?E gnus-newsgroup-expunged-tally ?d)
(?s (gnus-current-score-file-nondirectory) ?s))))
+(defconst gnus-article-mode-line-format-alist
+ gnus-summary-mode-line-format-alist)
+
(defconst gnus-group-mode-line-format-alist
(` ((?S gnus-tmp-news-server ?s)
(?M gnus-tmp-news-method ?s)
@@ -1439,7 +1511,7 @@ variable (string, integer, character, etc).")
"gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
"The mail address of the Gnus maintainers.")
-(defconst gnus-version "September Gnus v0.21"
+(defconst gnus-version "September Gnus v0.22"
"Version number for this version of Gnus.")
(defvar gnus-info-nodes
@@ -1568,6 +1640,12 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
(defvar gnus-newsgroup-killed nil
"List of ranges of articles that have been through the scoring process.")
+(defvar gnus-newsgroup-cached nil
+ "List of articles that come from the article cache.")
+
+(defvar gnus-newsgroup-saved nil
+ "List of articles that have been saved.")
+
(defvar gnus-newsgroup-kill-headers nil)
(defvar gnus-newsgroup-replied nil
@@ -1613,7 +1691,6 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
(defvar gnus-summary-mark-positions nil)
(defvar gnus-group-mark-positions nil)
-(defvar gnus-summary-expunge-below nil)
(defvar gnus-reffed-article-number nil)
;;; Let the byte-compiler know that we know about this variable.
@@ -1621,6 +1698,8 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
(defvar gnus-cache-removeable-articles nil)
+(defvar gnus-dead-summary nil)
+
(defconst gnus-summary-local-variables
'(gnus-newsgroup-name
gnus-newsgroup-begin gnus-newsgroup-end
@@ -1628,7 +1707,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
gnus-newsgroup-last-folder gnus-newsgroup-last-file
gnus-newsgroup-auto-expire gnus-newsgroup-unreads
gnus-newsgroup-unselected gnus-newsgroup-marked
- gnus-newsgroup-reads
+ gnus-newsgroup-reads gnus-newsgroup-saved
gnus-newsgroup-replied gnus-newsgroup-expirable
gnus-newsgroup-processable gnus-newsgroup-killed
gnus-newsgroup-bookmarks gnus-newsgroup-dormant
@@ -1643,8 +1722,9 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
gnus-summary-mark-below gnus-newsgroup-active gnus-scores-exclude-files
gnus-newsgroup-history gnus-newsgroup-ancient
(gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
+ gnus-newsgroup-adaptive-score-file
(gnus-newsgroup-expunged-tally . 0)
- gnus-cache-removeable-articles
+ gnus-cache-removeable-articles gnus-newsgroup-cached
gnus-newsgroup-data gnus-newsgroup-data-reverse
gnus-newsgroup-limit gnus-newsgroup-limits)
"Variables that are buffer-local to the summary buffers.")
@@ -1715,14 +1795,15 @@ Thank you for your help in stamping out bugs.
gnus-server-make-menu-bar gnus-article-make-menu-bar
gnus-browse-make-menu-bar gnus-highlight-selected-summary
gnus-summary-highlight-line gnus-carpal-setup-buffer
- gnus-article-add-button)
+ gnus-article-add-button gnus-insert-next-page-button
+ gnus-insert-prev-page-button)
("gnus-vis" :interactive t
gnus-article-push-button gnus-article-press-button
gnus-article-highlight gnus-article-highlight-some
gnus-article-hide gnus-article-hide-signature
gnus-article-highlight-headers gnus-article-highlight-signature
gnus-article-add-buttons gnus-article-add-buttons-to-head
- gnus-article-next-button)
+ gnus-article-next-button gnus-article-prev-button)
("gnus-demon" gnus-demon-add-nocem gnus-demon-add-scanmail
gnus-demon-add-disconnection gnus-demon-add-handler
gnus-demon-remove-handler)
@@ -1739,9 +1820,10 @@ Thank you for your help in stamping out bugs.
("gnus-cache" gnus-cache-possibly-enter-article gnus-cache-save-buffers
gnus-cache-possibly-remove-articles gnus-cache-request-article
gnus-cache-retrieve-headers gnus-cache-possibly-alter-active
- gnus-cache-enter-remove-article
+ gnus-cache-enter-remove-article gnus-cached-article-p
gnus-cache-open gnus-cache-close)
- ("gnus-cache" :interactive t gnus-jog-cache)
+ ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article
+ gnus-cache-remove-article)
("gnus-score" :interactive t
gnus-summary-increase-score gnus-summary-lower-score
gnus-score-flush-cache gnus-score-close
@@ -1771,7 +1853,7 @@ Thank you for your help in stamping out bugs.
("gnus-msg" (gnus-summary-send-map keymap)
gnus-mail-yank-original gnus-mail-send-and-exit
gnus-sendmail-setup-mail gnus-article-mail
- gnus-inews-message-id gnus-news-mail gnus-mail-reply)
+ gnus-inews-message-id gnus-new-mail gnus-mail-reply)
("gnus-msg" :interactive t
gnus-group-post-news gnus-group-mail gnus-summary-post-news
gnus-summary-followup gnus-summary-followup-with-original
@@ -1990,6 +2072,7 @@ Thank you for your help in stamping out bugs.
(defvar gnus-tmp-subject-or-nil)
(defvar gnus-tmp-subject)
(defvar gnus-tmp-marked)
+(defvar gnus-tmp-marked-mark)
(defvar gnus-tmp-subscribed)
(defvar gnus-tmp-process-marked)
(defvar gnus-tmp-number-of-unread)
@@ -2038,7 +2121,7 @@ Thank you for your help in stamping out bugs.
(gnus-byte-code 'gnus-summary-dummy-line-format-spec))
(defun gnus-group-line-format-spec ()
- (insert gnus-tmp-marked gnus-tmp-subscribed
+ (insert gnus-tmp-marked-mark gnus-tmp-subscribed
gnus-tmp-process-marked
gnus-topic-indentation
(format "%5s: " gnus-tmp-number-of-unread))
@@ -2051,32 +2134,15 @@ Thank you for your help in stamping out bugs.
(defvar gnus-group-line-format-spec
(gnus-byte-code 'gnus-group-line-format-spec))
-(defun gnus-summary-mode-line-format-spec ()
- (format "Gnus %s/%d %s" gnus-tmp-group-name
- gnus-tmp-article-number gnus-tmp-unread-and-unselected))
-(defvar gnus-summary-mode-line-format-spec
- (gnus-byte-code 'gnus-summary-mode-line-format-spec))
-
-(defun gnus-group-mode-line-format-spec ()
- (format "Gnus List of groups {%s:%s} "
- gnus-tmp-news-method gnus-tmp-news-server))
-(defvar gnus-group-mode-line-format-spec
- (gnus-byte-code 'gnus-group-mode-line-format-spec))
-
-(defun gnus-article-mode-line-format-spec ()
- (format "Gnus %s/%d %s" gnus-tmp-group-name
- gnus-tmp-article-number gnus-tmp-subject))
-(defvar gnus-article-mode-line-format-spec
- (gnus-byte-code 'gnus-article-mode-line-format-spec))
-
(defvar gnus-old-specs
- '((article-mode . "Gnus %G/%A %S")
- (group-mode . "Gnus List of groups {%M:%S} ")
- (summary-mode . "Gnus %G/%A %Z")
- (group . "%M%S%p%5y: %(%g%)\n")
+ '((group . "%M%S%p%5y: %(%g%)\n")
(summary-dummy . "* : : %S\n")
(summary . "%U%R%z%I%(%[%4L: %-20,20n%]%) %s\n")))
+(defvar gnus-article-mode-line-format-spec nil)
+(defvar gnus-summary-mode-line-format-spec nil)
+(defvar gnus-group-mode-line-format-spec nil)
+
;;; Phew. All that gruft is over, fortunately.
@@ -2328,37 +2394,40 @@ Thank you for your help in stamping out bugs.
(goto-char (point-min))
(while (re-search-forward "%[-0-9]*\\(,[0-9]+\\)?\\([^0-9]\\)\\(.\\)?"
nil t)
- (setq spec (string-to-char (match-string 2)))
- ;; First check if there are any specs that look anything like
- ;; "%12,12A", ie. with a "max width specification". These have
- ;; to be treated specially.
- (if (setq beg (match-beginning 1))
- (setq max-width
- (string-to-int
- (buffer-substring (1+ (match-beginning 1)) (match-end 1))))
- (setq max-width 0)
- (setq beg (match-beginning 2)))
- ;; Find the specification from `spec-alist'.
- (unless (setq elem (cdr (assq spec spec-alist)))
- (setq elem '("*" ?s)))
- ;; Treat user defined format specifiers specially.
- (when (eq (car elem) 'gnus-tmp-user-defined)
- (setq elem
- (list
- (list (intern (concat "gnus-user-format-function-"
- (match-string 3)))
- 'gnus-tmp-header) ?s))
- (delete-region (match-beginning 3) (match-end 3)))
- (if (not (zerop max-width))
- (let ((el (car elem)))
- (cond ((= (car (cdr elem)) ?c)
- (setq el (list 'char-to-string el)))
- ((= (car (cdr elem)) ?d)
- (numberp el) (setq el (list 'int-to-string el))))
- (setq flist (cons (gnus-max-width-function el max-width)
- flist))
- (setq newspec ?s))
- (setq flist (cons (car elem) flist))
+ (if (= (setq spec (string-to-char (match-string 2))) ?%)
+ (setq newspec "%"
+ beg (1+ (match-beginning 0)))
+ ;; First check if there are any specs that look anything like
+ ;; "%12,12A", ie. with a "max width specification". These have
+ ;; to be treated specially.
+ (if (setq beg (match-beginning 1))
+ (setq max-width
+ (string-to-int
+ (buffer-substring
+ (1+ (match-beginning 1)) (match-end 1))))
+ (setq max-width 0)
+ (setq beg (match-beginning 2)))
+ ;; Find the specification from `spec-alist'.
+ (unless (setq elem (cdr (assq spec spec-alist)))
+ (setq elem '("*" ?s)))
+ ;; Treat user defined format specifiers specially.
+ (when (eq (car elem) 'gnus-tmp-user-defined)
+ (setq elem
+ (list
+ (list (intern (concat "gnus-user-format-function-"
+ (match-string 3)))
+ 'gnus-tmp-header) ?s))
+ (delete-region (match-beginning 3) (match-end 3)))
+ (if (not (zerop max-width))
+ (let ((el (car elem)))
+ (cond ((= (car (cdr elem)) ?c)
+ (setq el (list 'char-to-string el)))
+ ((= (car (cdr elem)) ?d)
+ (numberp el) (setq el (list 'int-to-string el))))
+ (setq flist (cons (gnus-max-width-function el max-width)
+ flist))
+ (setq newspec ?s))
+ (setq flist (cons (car elem) flist)))
(setq newspec (car (cdr elem))))
;; Remove the old specification (and possibly a ",12" string).
(delete-region beg (match-end 2))
@@ -2411,6 +2480,23 @@ Thank you for your help in stamping out bugs.
(cons 'insert result)))
(or (car result) ""))))
+(defun gnus-eval-format (format &optional alist props)
+ "Eval the format variable FORMAT, using ALIST.
+If INSERT, insert the result."
+ (let ((form (gnus-parse-format format alist props)))
+ (if props
+ (add-text-properties (point) (progn (eval form) (point)) props)
+ (eval form))))
+
+(defun gnus-remove-text-with-property (prop)
+ "Delete all text in the current buffer with text property PROP."
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (when (get-text-property (point) prop)
+ (delete-char 1))
+ (goto-char (next-single-property-change (point) prop nil (point-max))))))
+
(defun gnus-set-work-buffer ()
(if (get-buffer gnus-work-buffer)
(progn
@@ -2580,17 +2666,21 @@ If variable `gnus-use-long-file-name' is non-nil, it is
(substring groupkey (match-beginning 1) (match-end 1)))))
(gnus-subscribe-newsgroup newgroup before))))
-(defun gnus-subscribe-interactively (newsgroup)
- "Subscribe new NEWSGROUP interactively.
+(defun gnus-subscribe-interactively (group)
+ "Subscribe the new GROUP interactively.
It is inserted in hierarchical newsgroup order if subscribed. If not,
it is killed."
- (if (gnus-y-or-n-p (format "Subscribe new newsgroup: %s " newsgroup))
- (gnus-subscribe-hierarchically newsgroup)
- (setq gnus-killed-list (cons newsgroup gnus-killed-list))))
+ (if (gnus-y-or-n-p (format "Subscribe new newsgroup: %s " group))
+ (gnus-subscribe-hierarchically group)
+ (push group gnus-killed-list)))
+
+(defun gnus-subscribe-zombies (group)
+ "Make the new GROUP into a zombie group."
+ (push group gnus-zombie-list))
-(defun gnus-subscribe-zombies (newsgroup)
- "Make new NEWSGROUP a zombie group."
- (setq gnus-zombie-list (cons newsgroup gnus-zombie-list)))
+(defun gnus-subscribe-killed (group)
+ "Make the new GROUP a killed group."
+ (push group gnus-killed-list))
(defun gnus-subscribe-newsgroup (newsgroup &optional next)
"Subscribe new NEWSGROUP.
@@ -3530,6 +3620,7 @@ Note: LIST has to be sorted over `<'."
(suppress-keymap gnus-group-mode-map)
(define-key gnus-group-mode-map " " 'gnus-group-read-group)
(define-key gnus-group-mode-map "=" 'gnus-group-select-group)
+ (define-key gnus-group-mode-map "\M- " 'gnus-group-unhidden-select-group)
(define-key gnus-group-mode-map "\r" 'gnus-group-select-group)
(define-key gnus-group-mode-map "\M-\r" 'gnus-group-quick-select-group)
(define-key gnus-group-mode-map "j" 'gnus-group-jump-to-group)
@@ -3588,6 +3679,7 @@ Note: LIST has to be sorted over `<'."
(define-key gnus-group-mode-map "\C-c\C-b" 'gnus-bug)
(define-key gnus-group-mode-map "\C-c\C-s" 'gnus-group-sort-groups)
(define-key gnus-group-mode-map "t" 'gnus-topic-mode)
+ (define-key gnus-group-mode-map "\C-c\M-g" 'gnus-activate-all-groups)
(define-key gnus-group-mode-map "#" 'gnus-group-mark-group)
(define-key gnus-group-mode-map "\M-#" 'gnus-group-unmark-group)
@@ -3662,6 +3754,7 @@ Note: LIST has to be sorted over `<'."
(define-key gnus-group-sub-map "k" 'gnus-group-kill-group)
(define-key gnus-group-sub-map "y" 'gnus-group-yank-group)
(define-key gnus-group-sub-map "w" 'gnus-group-kill-region)
+ (define-key gnus-group-sub-map "\C-k" 'gnus-group-kill-level)
(define-key gnus-group-sub-map "z" 'gnus-group-kill-all-zombies))
(defun gnus-group-mode ()
@@ -3906,7 +3999,7 @@ This will also compile the user-defined format specs."
(goto-char (point-min))
(let* ((mode-string (gnus-group-set-mode-line)))
(setq mode-line-buffer-identification
- (concat gnus-version (substring mode-string 4)))
+ (list (concat gnus-version (substring (car mode-string) 4))))
(set-buffer-modified-p t)))
(defun gnus-group-startup-message-old (&optional x y)
@@ -4328,7 +4421,7 @@ increase the score of each group you read."
(if gnus-tmp-method
(format "(%s:%s)" (car gnus-tmp-method)
(car (cdr gnus-tmp-method))) ""))
- (gnus-tmp-marked
+ (gnus-tmp-marked-mark
(if (and (numberp number)
(zerop number)
(cdr (assq 'tick gnus-tmp-marked)))
@@ -4352,7 +4445,7 @@ increase the score of each group you read."
gnus-unread ,(if (numberp number)
(string-to-int gnus-tmp-number-of-unread)
t)
- gnus-marked ,gnus-tmp-marked
+ gnus-marked ,gnus-tmp-marked-mark
gnus-level ,gnus-tmp-level))
;; Allow XEmacs to remove front-sticky text properties.
(gnus-group-remove-excess-properties)))
@@ -4421,7 +4514,7 @@ already."
(when (> (length mode-string) max-len)
(setq mode-string (substring mode-string 0 (- max-len 4))))
(prog1
- (setq mode-line-buffer-identification mode-string)
+ (setq mode-line-buffer-identification (list mode-string))
(set-buffer-modified-p t)))))
(defun gnus-group-group-name ()
@@ -4633,6 +4726,12 @@ This means that no highlighting or scoring will be performed."
gnus-summary-expunge-below)
(gnus-group-read-group all t)))
+(defun gnus-group-visible-select-group (&optional all)
+ "Select the current group without hiding any articles."
+ (interactive "P")
+ (let ((gnus-inhibit-limiting t))
+ (gnus-group-read-group all t)))
+
;;;###autoload
(defun gnus-fetch-group (group)
"Start Gnus if necessary and enter GROUP.
@@ -4667,7 +4766,6 @@ Returns whether the fetching was successful or not."
(gnus-group-read-group t t group)
(error nil)
(quit nil))
-; (debug (current-buffer))
(not (equal (current-buffer) cur))))
(defun gnus-group-jump-to-group (group)
@@ -5011,17 +5109,21 @@ of the Earth\". There is no undo."
(defun gnus-group-make-help-group ()
"Create the Gnus documentation group."
(interactive)
- (let ((path (cons (concat installation-directory "etc/") load-path))
+ (let ((path load-path)
(name (gnus-group-prefixed-name "gnus-help" '(nndoc "gnus-help")))
- file)
+ file dir)
(and (gnus-gethash name gnus-newsrc-hashtb)
(error "Documentation group already exists"))
- (while (and path
- (not (file-exists-p
- (setq file (concat (file-name-as-directory (car path))
- "gnus-tut.txt")))))
- (setq path (cdr path)))
- (if (not path)
+ (while path
+ (setq dir (file-name-as-directory (expand-file-name (pop path)))
+ file nil)
+ (when (or (file-exists-p (setq file (concat dir "gnus-tut.txt")))
+ (file-exists-p
+ (setq file (concat (file-name-directory
+ (directory-file-name dir))
+ "etc/gnus-tut.txt"))))
+ (setq path nil)))
+ (if (not file)
(message "Couldn't find doc group")
(gnus-group-make-group
(gnus-group-real-name name)
@@ -5503,16 +5605,16 @@ The killed newsgroups can be yanked by using \\[gnus-group-yank-group]."
The killed newsgroups can be yanked by using \\[gnus-group-yank-group].
However, only groups that were alive can be yanked; already killed
groups or zombie groups can't be yanked.
-The return value is the name of the (last) group that was killed."
+The return value is the name of the group that was killed, or a list
+of groups killed."
(interactive "P")
(let ((buffer-read-only nil)
(groups (gnus-group-process-prefix n))
- group entry level)
- (if (or t (< (length groups) 10))
+ group entry level out)
+ (if (< (length groups) 10)
;; This is faster when there are few groups.
(while groups
- (setq group (car groups)
- groups (cdr groups))
+ (push (setq group (pop groups)) out)
(gnus-group-remove-mark group)
(setq level (gnus-group-group-level))
(gnus-delete-line)
@@ -5525,24 +5627,33 @@ The return value is the name of the (last) group that was killed."
(if entry entry group) gnus-level-killed (if entry nil level)))
;; If there are lots and lots of groups to be killed, we use
;; this thing instead.
- ;; !!! Not written.
- )
-
+ (let (entry)
+ (setq groups (nreverse groups))
+ (while groups
+ (gnus-group-remove-mark (car groups))
+ (gnus-delete-line)
+ (setq entry (gnus-gethash (pop groups) gnus-newsrc-hashtb))
+ (push (cons (car entry) (nth 2 entry))
+ gnus-list-of-killed-groups)
+ (setcdr (cdr entry) (cdr (cdr (cdr entry)))))
+ (gnus-make-hashtable-from-newsrc-alist)))
+
(gnus-group-position-point)
- group))
+ (if (< (length out) 2) (car out) (nreverse out))))
(defun gnus-group-yank-group (&optional arg)
"Yank the last newsgroups killed with \\[gnus-group-kill-group],
inserting it before the current newsgroup. The numeric ARG specifies
-how many newsgroups are to be yanked. The name of the (last)
-newsgroup yanked is returned."
+how many newsgroups are to be yanked. The name of the newsgroup yanked
+is returned, or (if several groups are yanked) a list of yanked groups
+is returned."
(interactive "p")
- (if (not arg) (setq arg 1))
- (let (info group prev)
- (while (>= (setq arg (1- arg)) 0)
- (if (not (setq info (car gnus-list-of-killed-groups)))
+ (setq arg (or arg 1))
+ (let (info group prev out)
+ (while (>= (decf arg) 0)
+ (if (not (setq info (pop gnus-list-of-killed-groups)))
(error "No more newsgroups to yank"))
- (setq group (nth 1 info))
+ (push (setq group (nth 1 info)) out)
;; Find which newsgroup to insert this one before - search
;; backward until something suitable is found. If there are no
;; other newsgroups in this buffer, just make this newsgroup the
@@ -5552,12 +5663,37 @@ newsgroup yanked is returned."
info (nth 2 info) gnus-level-killed
(and prev (gnus-gethash prev gnus-newsrc-hashtb))
t)
- (gnus-group-insert-group-line-info group)
- (setq gnus-list-of-killed-groups
- (cdr gnus-list-of-killed-groups)))
+ (gnus-group-insert-group-line-info group))
(forward-line -1)
(gnus-group-position-point)
- group))
+ (if (< (length out) 2) (car out) (nreverse out))))
+
+(defun gnus-group-kill-level (level)
+ "Kill all groups that is on a certain LEVEL."
+ (interactive "nKill all groups on level: ")
+ (cond
+ ((= level gnus-level-zombie)
+ (setq gnus-killed-list
+ (nconc gnus-zombie-list gnus-killed-list))
+ (setq gnus-zombie-list nil))
+ ((and (< level gnus-level-zombie)
+ (> level 0)
+ (or gnus-expert-user
+ (gnus-yes-or-no-p
+ (format
+ "Do you really want to kill all groups on level %d? "
+ level))))
+ (let* ((prev gnus-newsrc-alist)
+ (alist (cdr prev)))
+ (while alist
+ (if (= (gnus-info-level level) level)
+ (setcdr prev (cdr alist))
+ (setq prev alist))
+ (setq alist (cdr alist)))
+ (gnus-make-hashtable-from-newsrc-alist)
+ (gnus-group-list-groups)))
+ (t
+ (error "Can't kill; illegal level: %d" level))))
(defun gnus-group-list-all-groups (&optional arg)
"List all newsgroups with level ARG or lower.
@@ -5641,6 +5777,13 @@ entail asking the server for the groups."
(setq groups (cdr groups)))
(goto-char (point-min))))
+(defun gnus-activate-all-groups (level)
+ "Activate absolutely all groups."
+ (interactive (list 7))
+ (let ((gnus-activate-level level)
+ (gnus-activate-foreign-newsgroups level))
+ (gnus-group-get-new-news)))
+
(defun gnus-group-get-new-news (&optional arg)
"Get newly arrived articles.
If ARG is a number, it specifies which levels you are interested in
@@ -5662,9 +5805,9 @@ re-scanning. If ARG is non-nil and not a number, this will force
(if (and gnus-read-active-file (not arg))
(progn
(gnus-read-active-file)
- (gnus-get-unread-articles (or arg (1+ gnus-level-subscribed))))
+ (gnus-get-unread-articles arg))
(let ((gnus-read-active-file (if arg nil gnus-read-active-file)))
- (gnus-get-unread-articles (or arg (1+ gnus-level-subscribed)))))
+ (gnus-get-unread-articles arg)))
(gnus-group-list-groups))
(defun gnus-group-get-new-news-this-group (&optional n)