Importing pgnus-0.79
[elisp/gnus.git-] / lisp / gnus-topic.el
index 6ee2a63..ed63e62 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-topic.el --- a folding minor mode for Gnus group buffers
-;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
 
 ;; Author: Ilja Weis <kult@uni-paderborn.de>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -74,6 +74,7 @@ with some simple extensions.
 
 (defvar gnus-topic-active-topology nil)
 (defvar gnus-topic-active-alist nil)
+(defvar gnus-topic-unreads nil)
 
 (defvar gnus-topology-checked-p nil
   "Whether the topology has been checked in this session.")
@@ -109,9 +110,7 @@ with some simple extensions.
 
 (defun gnus-topic-unread (topic)
   "Return the number of unread articles in TOPIC."
-  (or (save-excursion
-       (and (gnus-topic-goto-topic topic)
-            (gnus-group-topic-unread)))
+  (or (cdr (assoc topic gnus-topic-unreads))
       0))
 
 (defun gnus-group-topic-p ()
@@ -362,7 +361,8 @@ If TOPIC, start with that topic."
 
 ;;; Generating group buffers
 
-(defun gnus-group-prepare-topics (level &optional all lowest regexp list-topic topic-level)
+(defun gnus-group-prepare-topics (level &optional all lowest
+                                       regexp list-topic topic-level)
   "List all newsgroups with unread articles of level LEVEL or lower.
 Use the `gnus-group-topics' to sort the groups.
 If ALL is non-nil, list groups that have no unread articles.
@@ -417,7 +417,7 @@ articles in the topic and its subtopics."
         (entries (gnus-topic-find-groups
                   (car type) list-level
                   (or all
-                      (cdr (assq 'visible 
+                      (cdr (assq 'visible
                                  (gnus-topic-hierarchical-parameters
                                   (car type)))))
                   lowest))
@@ -445,7 +445,8 @@ articles in the topic and its subtopics."
        (if (stringp entry)
            ;; Dead groups.
            (gnus-group-insert-group-line
-            entry (if (member entry gnus-zombie-list) gnus-level-zombie gnus-level-killed)
+            entry (if (member entry gnus-zombie-list)
+                      gnus-level-zombie gnus-level-killed)
             nil (- (1+ (cdr (setq active (gnus-active entry))))
                    (car active))
             nil)
@@ -472,6 +473,7 @@ articles in the topic and its subtopics."
        (car type) visiblep
        (not (eq (nth 2 type) 'hidden))
        level all-entries unread))
+    (gnus-topic-update-unreads (car type) unread)
     (goto-char end)
     unread))
 
@@ -528,6 +530,7 @@ articles in the topic and its subtopics."
         (number-of-groups (length entries))
         (active-topic (eq gnus-topic-alist gnus-topic-active-alist))
         gnus-tmp-header)
+    (gnus-topic-update-unreads name unread)
     (beginning-of-line)
     ;; Insert the text.
     (gnus-add-text-properties
@@ -540,6 +543,11 @@ articles in the topic and its subtopics."
           'gnus-active active-topic
           'gnus-topic-visible visiblep))))
 
+(defun gnus-topic-update-unreads (topic unreads)
+  (setq gnus-topic-unreads (delq (assoc topic gnus-topic-unreads)
+                                gnus-topic-unreads))
+  (push (cons topic unreads) gnus-topic-unreads))
+
 (defun gnus-topic-update-topics-containing-group (group)
   "Update all topics that have GROUP as a member."
   (when (and (eq major-mode 'gnus-group-mode)
@@ -621,7 +629,7 @@ articles in the topic and its subtopics."
         (parent (gnus-topic-parent-topic topic-name))
         (all-entries entries)
         (unread 0)
-        old-unread entry)
+        old-unread entry new-unread)
     (when (gnus-topic-goto-topic (car type))
       ;; Tally all the groups that belong in this topic.
       (if reads
@@ -637,11 +645,14 @@ articles in the topic and its subtopics."
        (car type) (gnus-topic-visible-p)
        (not (eq (nth 2 type) 'hidden))
        (gnus-group-topic-level) all-entries unread)
-      (gnus-delete-line))
+      (gnus-delete-line)
+      (forward-line -1)
+      (setq new-unread (gnus-group-topic-unread)))
     (when parent
       (forward-line -1)
       (gnus-topic-update-topic-line
-       parent (- (or old-unread 0) (or (gnus-group-topic-unread) 0))))
+       parent
+       (- (or old-unread 0) (or new-unread 0))))
     unread))
 
 (defun gnus-topic-group-indentation ()
@@ -897,6 +908,7 @@ articles in the topic and its subtopics."
     "=" gnus-topic-select-group
     "\r" gnus-topic-select-group
     " " gnus-topic-read-group
+    "\C-c\C-x" gnus-topic-expire-articles
     "\C-k" gnus-topic-kill-group
     "\C-y" gnus-topic-yank-group
     "\M-g" gnus-topic-get-new-news-this-topic
@@ -906,6 +918,8 @@ articles in the topic and its subtopics."
     "\M-#" gnus-topic-unmark-topic
     [tab] gnus-topic-indent
     [(meta tab)] gnus-topic-unindent
+    "\C-i" gnus-topic-indent
+    "\M-\C-i" gnus-topic-unindent
     gnus-mouse-2 gnus-mouse-pick-topic)
 
   ;; Define a new submap.
@@ -925,7 +939,7 @@ articles in the topic and its subtopics."
     "r" gnus-topic-rename
     "\177" gnus-topic-delete
     [delete] gnus-topic-delete
-    "h" gnus-topic-toggle-display-empty-topics)
+    "H" gnus-topic-toggle-display-empty-topics)
 
   (gnus-define-keys (gnus-topic-sort-map "S" gnus-group-topic-map)
     "s" gnus-topic-sort-groups
@@ -975,7 +989,6 @@ articles in the topic and its subtopics."
        (gnus-topic-make-menu-bar))
       (gnus-set-format 'topic t)
       (gnus-add-minor-mode 'gnus-topic-mode " Topic" gnus-topic-mode-map)
-      (add-hook 'gnus-summary-exit-hook 'gnus-topic-update-topic)
       (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic)
       (set (make-local-variable 'gnus-group-prepare-function)
           'gnus-group-prepare-topics)
@@ -1029,6 +1042,19 @@ If performed over a topic line, toggle folding the topic."
   (mouse-set-point e)
   (gnus-topic-read-group nil))
 
+(defun gnus-topic-expire-articles (topic)
+  "Expire articles in this topic or group."
+  (interactive (list (gnus-group-topic-name)))
+  (if (not topic)
+      (call-interactively 'gnus-group-expire-articles)
+    (save-excursion
+      (gnus-message 5 "Expiring groups in %s..." topic)
+      (let ((gnus-group-marked
+            (mapcar (lambda (entry) (car (nth 2 entry)))
+                    (gnus-topic-find-groups topic gnus-level-killed t))))
+       (gnus-group-expire-articles nil))
+      (gnus-message 5 "Expiring groups in %s...done" topic))))
+
 (defun gnus-topic-read-group (&optional all no-article group)
   "Read news in this newsgroup.
 If the prefix argument ALL is non-nil, already read articles become