* gnus-spec.el (gnus-compile): Don't compile gnus-version.
[gnus] / lisp / gnus-group.el
index 387fecf..d4857a0 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-group.el --- group mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -295,52 +295,52 @@ variable."
                       (sexp :tag "Method"))))
 
 (defcustom gnus-group-highlight
-  '(;; News.
-    ((and (= unread 0) (not mailp) (eq level 1)) .
+  '(;; Mail.
+    ((and mailp (= unread 0) (eq level 1)) .
+     gnus-group-mail-1-empty-face)
+    ((and mailp (eq level 1)) .
+     gnus-group-mail-1-face)
+    ((and mailp (= unread 0) (eq level 2)) .
+     gnus-group-mail-2-empty-face)
+    ((and mailp (eq level 2)) .
+     gnus-group-mail-2-face)
+    ((and mailp (= unread 0) (eq level 3)) .
+     gnus-group-mail-3-empty-face)
+    ((and mailp (eq level 3)) .
+     gnus-group-mail-3-face)
+    ((and mailp (= unread 0)) .
+     gnus-group-mail-low-empty-face)
+    ((and mailp) .
+     gnus-group-mail-low-face)
+    ;; News.
+    ((and (= unread 0) (eq level 1)) .
      gnus-group-news-1-empty-face)
-    ((and (not mailp) (eq level 1)) .
+    ((and (eq level 1)) .
      gnus-group-news-1-face)
-    ((and (= unread 0) (not mailp) (eq level 2)) .
+    ((and (= unread 0) (eq level 2)) .
      gnus-group-news-2-empty-face)
-    ((and (not mailp) (eq level 2)) .
+    ((and (eq level 2)) .
      gnus-group-news-2-face)
-    ((and (= unread 0) (not mailp) (eq level 3)) .
+    ((and (= unread 0) (eq level 3)) .
      gnus-group-news-3-empty-face)
-    ((and (not mailp) (eq level 3)) .
+    ((and (eq level 3)) .
      gnus-group-news-3-face)
-    ((and (= unread 0) (not mailp) (eq level 4)) .
+    ((and (= unread 0) (eq level 4)) .
      gnus-group-news-4-empty-face)
-    ((and (not mailp) (eq level 4)) .
+    ((and (eq level 4)) .
      gnus-group-news-4-face)
-    ((and (= unread 0) (not mailp) (eq level 5)) .
+    ((and (= unread 0) (eq level 5)) .
      gnus-group-news-5-empty-face)
-    ((and (not mailp) (eq level 5)) .
+    ((and (eq level 5)) .
      gnus-group-news-5-face)
-    ((and (= unread 0) (not mailp) (eq level 6)) .
+    ((and (= unread 0) (eq level 6)) .
      gnus-group-news-6-empty-face)
-    ((and (not mailp) (eq level 6)) .
+    ((and (eq level 6)) .
      gnus-group-news-6-face)
-    ((and (= unread 0) (not mailp)) .
+    ((and (= unread 0)) .
      gnus-group-news-low-empty-face)
-    ((and (not mailp)) .
-     gnus-group-news-low-face)
-    ;; Mail.
-    ((and (= unread 0) (eq level 1)) .
-     gnus-group-mail-1-empty-face)
-    ((eq level 1) .
-     gnus-group-mail-1-face)
-    ((and (= unread 0) (eq level 2)) .
-     gnus-group-mail-2-empty-face)
-    ((eq level 2) .
-     gnus-group-mail-2-face)
-    ((and (= unread 0) (eq level 3)) .
-     gnus-group-mail-3-empty-face)
-    ((eq level 3) .
-     gnus-group-mail-3-face)
-    ((= unread 0) .
-     gnus-group-mail-low-empty-face)
     (t .
-       gnus-group-mail-low-face))
+     gnus-group-news-low-face))
   "*Controls the highlighting of group buffer lines.
 
 Below is a list of `Form'/`Face' pairs.  When deciding how a a
@@ -427,7 +427,12 @@ in which case `gnus-group-jump-to-group' offers \"Group: nnml:\"
 in the minibuffer prompt."
   :group 'gnus-group-various
   :type '(choice (string :tag "Prompt string")
-                 (const :tag "Empty" nil)))
+                (const :tag "Empty" nil)))
+
+(defvar gnus-group-listing-limit 1000
+  "*A limit of the number of groups when listing.
+If the number of groups is larger than the limit, list them in a
+simple manner.")
 
 ;;; Internal variables
 
@@ -844,7 +849,7 @@ in the minibuffer prompt."
 
     (easy-menu-define
      gnus-group-misc-menu gnus-group-mode-map ""
-     `("Misc"
+     `("Gnus"
        ("SOUP"
        ["Pack replies" nnsoup-pack-replies (fboundp 'nnsoup-request-group)]
        ["Send replies" gnus-soup-send-replies
@@ -855,7 +860,7 @@ in the minibuffer prompt."
        ["Send a mail" gnus-group-mail t]
        ["Post an article..." gnus-group-post-news t]
        ["Check for new news" gnus-group-get-new-news
-       ,@(if (featurep 'xemacs) nil
+       ,@(if (featurep 'xemacs) '(t)
            '(:help "Get newly arrived articles"))
        ]
        ["Activate all groups" gnus-activate-all-groups t]
@@ -874,7 +879,7 @@ in the minibuffer prompt."
        ["Toggle topics" gnus-topic-mode t]
        ["Send a bug report" gnus-bug t]
        ["Exit from Gnus" gnus-group-exit
-       ,@(if (featurep 'xemacs) nil
+       ,@(if (featurep 'xemacs) '(t)
            '(:help "Quit reading news"))]
        ["Exit without saving" gnus-group-quit t]))
 
@@ -952,6 +957,7 @@ The following commands are available:
 (defun gnus-update-group-mark-positions ()
   (save-excursion
     (let ((gnus-process-mark ?\200)
+         (gnus-group-update-hook nil)
          (gnus-group-marked '("dummy.group"))
          (gnus-active-hashtb (make-vector 10 0))
          (topic ""))
@@ -1187,32 +1193,38 @@ if it is a string, only list groups matching REGEXP."
   ;; suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.  It does
   ;; this by ignoring the group format specification altogether.
   (let (group)
-    (while groups
-      (setq group (pop groups))
-      (when (gnus-group-prepare-logic
-            group
-            (or (not regexp)
-                (and (stringp regexp) (string-match regexp group))
-                (and (functionp regexp) (funcall regexp group))))
-;;;    (gnus-add-text-properties
-;;;     (point) (prog1 (1+ (point))
-;;;               (insert " " mark "     *: "
-;;;                       (gnus-group-name-decode group
-;;;                                               (gnus-group-name-charset
-;;;                                                nil group))
-;;;                       "\n"))
-;;;     (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb)
-;;;           'gnus-unread t
-;;;           'gnus-level level))
-       (gnus-group-insert-group-line
-        group level nil
-        (let ((active (gnus-active group)))
-          (if active
-              (if (zerop (cdr active))
-                  0
-                (- (1+ (cdr active)) (car active)))
-            nil))
-        (gnus-method-simplify (gnus-find-method-for-group group)))))))
+    (if (> (length groups) gnus-group-listing-limit)
+       (while groups
+         (setq group (pop groups))
+         (when (gnus-group-prepare-logic
+                group
+                (or (not regexp)
+                    (and (stringp regexp) (string-match regexp group))
+                    (and (functionp regexp) (funcall regexp group))))
+           (gnus-add-text-properties
+            (point) (prog1 (1+ (point))
+                      (insert " " mark "     *: "
+                              (gnus-group-decoded-name group)
+                              "\n"))
+            (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb)
+                  'gnus-unread t
+                  'gnus-level level))))
+      (while groups
+       (setq group (pop groups))
+       (when (gnus-group-prepare-logic
+              group
+              (or (not regexp)
+                  (and (stringp regexp) (string-match regexp group))
+                  (and (functionp regexp) (funcall regexp group))))
+         (gnus-group-insert-group-line
+          group level nil
+          (let ((active (gnus-active group)))
+            (if active
+                (if (zerop (cdr active))
+                    0
+                  (- (1+ (cdr active)) (car active)))
+              nil))
+          (gnus-method-simplify (gnus-find-method-for-group group))))))))
 
 (defun gnus-group-update-group-line ()
   "Update the current line in the group buffer."
@@ -1353,9 +1365,13 @@ if it is a string, only list groups matching REGEXP."
         (info (nth 2 entry))
         (method (gnus-server-get-method group (gnus-info-method info)))
         (marked (gnus-info-marks info))
-        (mailp (memq 'mail (assoc (symbol-name
-                                   (car (or method gnus-select-method)))
-                                  gnus-valid-select-methods)))
+        (mailp (apply 'append
+                      (mapcar
+                       (lambda (x)
+                         (memq x (assoc (symbol-name
+                                         (car (or method gnus-select-method)))
+                                        gnus-valid-select-methods)))
+                       '(mail post-mail))))
         (level (or (gnus-info-level info) gnus-level-killed))
         (score (or (gnus-info-score info) 0))
         (ticked (gnus-range-length (cdr (assq 'tick marked))))
@@ -1761,6 +1777,7 @@ group."
 (defun gnus-group-select-group (&optional all)
   "Select this newsgroup.
 No article is selected automatically.
+If the group is opened, just switch the summary buffer.
 If ALL is non-nil, already read articles become readable.
 If ALL is a number, fetch this number of articles."
   (interactive "P")
@@ -2226,7 +2243,17 @@ and NEW-NAME will be prompted for."
        (t "group info"))
       (gnus-group-decoded-name group))
      `(lambda (form)
-       (gnus-group-edit-group-done ',part ,group form)))))
+       (gnus-group-edit-group-done ',part ,group form)))
+    (local-set-key
+     "\C-c\C-i" 
+     (gnus-create-info-command
+      (cond
+       ((eq part 'method)
+       "(gnus)Select Methods")
+       ((eq part 'params)
+       "(gnus)Group Parameters")
+       (t
+       "(gnus)Group Info"))))))
 
 (defun gnus-group-edit-group-method (group)
   "Edit the select method of GROUP."
@@ -2771,7 +2798,7 @@ sort in reverse order."
 
 (defun gnus-group-sort-by-score (info1 info2)
   "Sort by group score."
-  (< (gnus-info-score info1) (gnus-info-score info2)))
+  (> (gnus-info-score info1) (gnus-info-score info2)))
 
 (defun gnus-group-sort-by-rank (info1 info2)
   "Sort by level and score."
@@ -2811,13 +2838,22 @@ sort in reverse order."
 
 (defun gnus-info-clear-data (info)
   "Clear all marks and read ranges from INFO."
-  (let ((group (gnus-info-group info)))
+  (let ((group (gnus-info-group info))
+       action)
+    (dolist (el (gnus-info-marks info))
+      (push `(,(cdr el) add (,(car el))) action))
+    (push `(,(gnus-info-read info) add (read)) action)
     (gnus-undo-register
       `(progn
+        (gnus-request-set-mark ,group ',action)
         (gnus-info-set-marks ',info ',(gnus-info-marks info) t)
         (gnus-info-set-read ',info ',(gnus-info-read info))
         (when (gnus-group-goto-group ,group)
+          (gnus-get-unread-articles-in-group ',info ',(gnus-active group) t)
           (gnus-group-update-group-line))))
+    (setq action (mapcar (lambda (el) (list (nth 0 el) 'del (nth 2 el)))
+                        action))
+    (gnus-request-set-mark group action)
     (gnus-info-set-read info nil)
     (when (gnus-info-marks info)
       (gnus-info-set-marks info nil))))
@@ -3284,9 +3320,7 @@ entail asking the server for the groups."
       (gnus-add-text-properties
        (point) (prog1 (1+ (point))
                 (insert "       *: "
-                        (gnus-group-name-decode group
-                                                (gnus-group-name-charset
-                                                 nil group))
+                        (gnus-group-decoded-name group)
                         "\n"))
        (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb)
             'gnus-unread t
@@ -3610,11 +3644,12 @@ In fact, cleanup buffers except for group mode buffer.
 The hook gnus-suspend-gnus-hook is called before actually suspending."
   (interactive)
   (gnus-run-hooks 'gnus-suspend-gnus-hook)
+  (gnus-offer-save-summaries)
   ;; Kill Gnus buffers except for group mode buffer.
   (let ((group-buf (get-buffer gnus-group-buffer)))
     (mapcar (lambda (buf)
              (unless (member buf (list group-buf gnus-dribble-buffer))
-               (kill-buffer buf)))
+               (gnus-kill-buffer buf)))
            (gnus-buffers))
     (gnus-kill-gnus-frames)
     (when group-buf
@@ -3662,6 +3697,12 @@ The hook `gnus-exit-gnus-hook' is called before actually exiting."
                     (file-name-nondirectory gnus-current-startup-file))))
     (gnus-run-hooks 'gnus-exit-gnus-hook)
     (gnus-configure-windows 'group t)
+    (when (and (gnus-buffer-live-p gnus-dribble-buffer)
+              (not (zerop (save-excursion
+                           (set-buffer gnus-dribble-buffer)
+                           (buffer-size)))))
+      (gnus-dribble-enter
+       ";;; Gnus was exited on purpose without saving the .newsrc files."))
     (gnus-dribble-save)
     (gnus-close-backends)
     (gnus-clear-system)
@@ -3818,7 +3859,7 @@ or `gnus-group-catchup-group-hook'."
   "Return the offset in seconds from the timestamp for GROUP to the current time, as a floating point number."
   (let* ((time (or (gnus-group-timestamp group)
                   (list 0 0)))
-         (delta (subtract-time (current-time) time)))
+        (delta (subtract-time (current-time) time)))
     (+ (* (nth 0 delta) 65536.0)
        (nth 1 delta))))
 
@@ -3925,6 +3966,30 @@ This command may read the active file."
   (let ((gnus-group-list-option 'limit))
     (gnus-group-list-plus args)))
 
+(defun gnus-group-mark-article-read (group article)
+  "Mark ARTICLE read."
+  (gnus-activate-group group)
+  (let ((buffer (gnus-summary-buffer-name group))
+       (mark gnus-read-mark))
+    (unless
+       (and
+        (get-buffer buffer)
+        (with-current-buffer buffer
+          (when gnus-newsgroup-prepared
+            (when (and gnus-newsgroup-auto-expire
+                       (memq mark gnus-auto-expirable-marks))
+              (setq mark gnus-expirable-mark))
+            (setq mark (gnus-request-update-mark
+                        group article mark))
+            (gnus-mark-article-as-read article mark)
+            (setq gnus-newsgroup-active (gnus-active group))
+            t)))
+      (gnus-group-make-articles-read group
+                                    (list article))
+      (when (gnus-group-auto-expirable-p group)
+       (gnus-add-marked-articles
+        group 'expire (list article))))))
+
 (provide 'gnus-group)
 
 ;;; gnus-group.el ends here