]> code.delx.au - gnu-emacs/blobdiff - lisp/gnus/gnus-group.el
Bring the Gnus Cloud package into working order.
[gnu-emacs] / lisp / gnus / gnus-group.el
index 18e899b7bce61f30e917737e796818976f372060..828805384ca7e63f574d449fdc3cf27729bee736 100644 (file)
 
 (autoload 'gnus-group-make-nnir-group "nnir")
 
+(autoload 'gnus-cloud-upload-all-data "gnus-cloud")
+(autoload 'gnus-cloud-download-all-data "gnus-cloud")
+
 (defcustom gnus-no-groups-message "No news is good news"
-  "*Message displayed by Gnus when no groups are available."
+  "Message displayed by Gnus when no groups are available."
   :group 'gnus-start
   :type 'string)
 
 (defcustom gnus-keep-same-level nil
-  "*Non-nil means that the next newsgroup after the current will be on the same level.
+  "Non-nil means that the next newsgroup after the current will be on the same level.
 When you type, for instance, `n' after reading the last article in the
 current newsgroup, you will go to the next newsgroup.  If this variable
 is nil, the next newsgroup will be the next from the group
@@ -74,19 +77,19 @@ with the best level."
                 (sexp :tag "other" t)))
 
 (defcustom gnus-group-goto-unread t
-  "*If non-nil, movement commands will go to the next unread and subscribed group."
+  "If non-nil, movement commands will go to the next unread and subscribed group."
   :link '(custom-manual "(gnus)Group Maneuvering")
   :group 'gnus-group-various
   :type 'boolean)
 
 (defcustom gnus-goto-next-group-when-activating t
-  "*If non-nil, the \\<gnus-group-mode-map>\\[gnus-group-get-new-news-this-group] command will advance point to the next group."
+  "If non-nil, the \\<gnus-group-mode-map>\\[gnus-group-get-new-news-this-group] command will advance point to the next group."
   :link '(custom-manual "(gnus)Scanning New Messages")
   :group 'gnus-group-various
   :type 'boolean)
 
 (defcustom gnus-permanently-visible-groups nil
-  "*Regexp to match groups that should always be listed in the group buffer.
+  "Regexp to match groups that should always be listed in the group buffer.
 This means that they will still be listed even when there are no
 unread articles in the groups.
 
@@ -107,7 +110,7 @@ effective only when emacs-w3m renders html articles, i.e., in the case
                 (const nil)))
 
 (defcustom gnus-list-groups-with-ticked-articles t
-  "*If non-nil, list groups that have only ticked articles.
+  "If non-nil, list groups that have only ticked articles.
 If nil, only list groups that have unread articles."
   :group 'gnus-group-listing
   :type 'boolean)
@@ -120,13 +123,13 @@ Ignored if `gnus-group-use-permanent-levels' is non-nil."
                  (function :tag "Function returning level")))
 
 (defcustom gnus-group-list-inactive-groups t
-  "*If non-nil, inactive groups will be listed."
+  "If non-nil, inactive groups will be listed."
   :group 'gnus-group-listing
   :group 'gnus-group-levels
   :type 'boolean)
 
 (defcustom gnus-group-sort-function 'gnus-group-sort-by-alphabet
-  "*Function used for sorting the group buffer.
+  "Function used for sorting the group buffer.
 This function will be called with group info entries as the arguments
 for the groups to be sorted.  Pre-made functions include
 `gnus-group-sort-by-alphabet', `gnus-group-sort-by-real-name',
@@ -155,7 +158,7 @@ list."
                         (function :tag "other" nil))))
 
 (defcustom gnus-group-line-format "%M\ %S\ %p\ %P\ %5y:%B%(%g%)\n"
-  "*Format of group lines.
+  "Format of group lines.
 It works along the same lines as a normal formatting string,
 with some simple extensions.
 
@@ -213,7 +216,7 @@ See Info node `(gnus)Formatting Variables'."
   :type 'string)
 
 (defcustom gnus-group-mode-line-format "Gnus: %%b {%M\ %:%S}"
-  "*The format specification for the group mode line.
+  "The format specification for the group mode line.
 It works along the same lines as a normal formatting string,
 with some simple extensions:
 
@@ -240,7 +243,7 @@ with some simple extensions:
   :type 'hook)
 
 (defcustom gnus-group-prepare-function 'gnus-group-prepare-flat
-  "*A function that is called to generate the group buffer.
+  "A function that is called to generate the group buffer.
 The function is called with three arguments: The first is a number;
 all group with a level less or equal to that number should be listed,
 if the second is non-nil, empty groups should also be displayed.  If
@@ -297,7 +300,7 @@ If you want to modify the group buffer, you can use this hook."
                       (unless file
                         (error "Couldn't find doc group"))
                       file))))))
-  "*Alist of useful group-server pairs."
+  "Alist of useful group-server pairs."
   :group 'gnus-group-listing
   :type '(repeat (list (string :tag "Description")
                       (string :tag "Name")
@@ -350,7 +353,7 @@ If you want to modify the group buffer, you can use this hook."
      gnus-group-news-low-empty)
     (t .
      gnus-group-news-low))
-  "*Controls the highlighting of group buffer lines.
+  "Controls the highlighting of group buffer lines.
 
 Below is a list of `Form'/`Face' pairs.  When deciding how a
 particular group line should be displayed, each form is
@@ -385,7 +388,7 @@ ticked: The number of ticked articles."
 
 (defcustom gnus-group-icon-list
   nil
-  "*Controls the insertion of icons into group buffer lines.
+  "Controls the insertion of icons into group buffer lines.
 
 Below is a list of `Form'/`File' pairs.  When deciding how a
 particular group line should be displayed, each form is evaluated.
@@ -421,8 +424,7 @@ For example:
   :type '(repeat (cons (sexp :tag "Method") (symbol :tag "Charset"))))
 
 (defcustom gnus-group-name-charset-group-alist
-  (if (or (and (fboundp 'find-coding-system) (find-coding-system 'utf-8))
-         (mm-coding-system-p 'utf-8))
+  (if (mm-coding-system-p 'utf-8)
       '((".*" . utf-8))
     nil)
   "Alist of group regexp and the charset for group names.
@@ -449,10 +451,12 @@ used when no prefix argument is given to `gnus-group-jump-to-group'."
                 (repeat (cons (integer :tag "Argument")
                               (string :tag "Prompt string")))))
 
-(defvar gnus-group-listing-limit 1000
-  "*A limit of the number of groups when listing.
+(defcustom 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.")
+simple manner."
+  :group 'gnus-group-listing
+  :type 'integer)
 
 ;;; Internal variables
 
@@ -635,6 +639,12 @@ simple manner.")
   "#" gnus-group-mark-group
   "\M-#" gnus-group-unmark-group)
 
+(gnus-define-keys (gnus-group-cloud-map "~" gnus-group-mode-map)
+  "u" gnus-cloud-upload-all-data
+  "~" gnus-cloud-upload-all-data
+  "d" gnus-cloud-download-all-data
+  "\r" gnus-cloud-download-all-data)
+
 (gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map)
   "m" gnus-group-mark-group
   "u" gnus-group-unmark-group
@@ -1085,12 +1095,9 @@ When FORCE, rebuild the tool bar."
              (display-graphic-p)
             (or (not gnus-group-tool-bar-map) force))
     (let* ((load-path
-           (gmm-image-load-path-for-library "gnus"
-                                            "gnus/toggle-subscription.xpm"
-                                            nil t))
-           (image-load-path (cons (car load-path)
-                                  (when (boundp 'image-load-path)
-                                    image-load-path)))
+           (image-load-path-for-library
+            "gnus" "gnus/toggle-subscription.xpm" nil t))
+           (image-load-path (cons (car load-path) image-load-path))
           (map (gmm-tool-bar-from-list gnus-group-tool-bar
                                        gnus-group-tool-bar-zap-list
                                        'gnus-group-mode-map)))
@@ -1207,7 +1214,7 @@ The following commands are available:
 
 (defun gnus-group-name-decode (string charset)
   ;; Fixme: Don't decode in unibyte mode.
-  (if (and string charset (featurep 'mule))
+  (if (and string charset)
       (decode-coding-string string charset)
     string))
 
@@ -1372,7 +1379,7 @@ if it is a string, only list groups matching REGEXP."
     (when (or gnus-group-listed-groups
              (and (>= level gnus-level-killed) (<= lowest gnus-level-killed)))
       (gnus-group-prepare-flat-list-dead
-       (gnus-union
+       (cl-union
        not-in-list
        (setq gnus-killed-list (sort gnus-killed-list 'string<))
        :test 'equal)
@@ -1396,7 +1403,7 @@ if it is a string, only list groups matching REGEXP."
                 (or (not regexp)
                     (and (stringp regexp) (string-match regexp group))
                     (and (functionp regexp) (funcall regexp group))))
-           (gnus-add-text-properties
+           (add-text-properties
             (point) (prog1 (1+ (point))
                       (insert " " mark "     *: "
                               (gnus-group-decoded-name group)
@@ -1488,12 +1495,10 @@ if it is a string, only list groups matching REGEXP."
 ;; Date: Mon, 23 Jan 2006 19:59:13 +0100
 ;; Message-ID: <v9acdmrcse.fsf@marauder.physik.uni-ulm.de>
 
-(defcustom gnus-group-update-tool-bar
-  (and (boundp 'tool-bar-mode)
-       tool-bar-mode
-       ;; Using `redraw-frame' (see `gnus-tool-bar-update') in Emacs might
-       ;; be confusing, so maybe we shouldn't call it by default.
-       (fboundp 'force-window-update))
+;; Using `redraw-frame' (see `gnus-tool-bar-update') in Emacs might
+;; be confusing, so maybe we shouldn't call it by default.
+(defcustom gnus-group-update-tool-bar (and (boundp 'tool-bar-mode)
+                                          tool-bar-mode)
   "Force updating the group buffer tool bar."
   :group 'gnus-group
   :version "22.1"
@@ -1574,7 +1579,7 @@ if it is a string, only list groups matching REGEXP."
          gnus-tmp-header)      ; passed as parameter to user-funcs.
     (beginning-of-line)
     (setq beg (point))
-    (gnus-add-text-properties
+    (add-text-properties
      (point)
      (prog1 (1+ (point))
        ;; Insert the text.
@@ -1602,11 +1607,11 @@ if it is a string, only list groups matching REGEXP."
         (progn
           (unless (bound-and-true-p cursor-sensor-mode)
             (cursor-sensor-mode 1))
-          (gnus-put-text-property beg end 'cursor-sensor-functions
+          (put-text-property beg end 'cursor-sensor-functions
                                   '(gnus-tool-bar-update)))
-      (gnus-put-text-property beg end 'point-entered
+      (put-text-property beg end 'point-entered
                               #'gnus-tool-bar-update)
-      (gnus-put-text-property beg end 'point-left
+      (put-text-property beg end 'point-left
                               #'gnus-tool-bar-update))))
 
 (defun gnus-group-update-eval-form (group list)
@@ -1614,25 +1619,30 @@ if it is a string, only list groups matching REGEXP."
 Some value are bound so the form can use them."
   (when list
     (let* ((entry (gnus-group-entry group))
-           (unread (if (numberp (car entry)) (car entry) 0))
            (active (gnus-active group))
-           (total (if active (1+ (- (cdr active) (car active))) 0))
            (info (nth 2 entry))
-           (method (inline (gnus-server-get-method group (gnus-info-method info))))
+           (method (inline (gnus-server-get-method
+                           group (gnus-info-method info))))
            (marked (gnus-info-marks info))
-           (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))))
-           (group-age (gnus-group-timestamp-delta group)))
+          (env
+           (list
+            (cons 'unread (if (numberp (car entry)) (car entry) 0))
+            (cons 'total (if active (1+ (- (cdr active) (car active))) 0))
+            (cons 'mailp (apply
+                          'append
+                          (mapcar
+                           (lambda (x)
+                             (memq x (assoc
+                                      (symbol-name
+                                       (car (or method gnus-select-method)))
+                                      gnus-valid-select-methods)))
+                           '(mail post-mail))))
+            (cons 'level (or (gnus-info-level info) gnus-level-killed))
+            (cons 'score (or (gnus-info-score info) 0))
+            (cons 'ticked (gnus-range-length (cdr (assq 'tick marked))))
+            (cons 'group-age (gnus-group-timestamp-delta group)))))
       (while (and list
-                  (not (eval (caar list))))
+                  (not (eval (caar list) env)))
         (setq list (cdr list)))
       list)))
 
@@ -1641,14 +1651,14 @@ Some value are bound so the form can use them."
 GROUP is current group, and the line to highlight starts at BEG
 and ends at END."
   (let ((face (cdar (gnus-group-update-eval-form
-                    group
-                    gnus-group-highlight))))
-    (unless (eq face (gnus-get-text-property-excluding-characters-with-faces beg 'face))
+                      group
+                      gnus-group-highlight))))
+    (unless (eq face (gnus-get-text-property-excluding-characters-with-faces
+                     beg 'face))
       (let ((inhibit-read-only t))
         (gnus-put-text-property-excluding-characters-with-faces
          beg end 'face
-         (if (boundp face) (symbol-value face) face)))
-      (gnus-extent-start-open beg))))
+         (if (boundp face) (symbol-value face) face))))))
 
 (defun gnus-group-get-icon (group)
   "Return an icon for GROUP according to `gnus-group-icon-list'."
@@ -2197,7 +2207,7 @@ if it is not a list."
       (setq group
            (encode-coding-string
             group (gnus-group-name-charset nil group))))
-    (replace-regexp-in-string group "\n" "")))
+    (replace-regexp-in-string "\n" "" group)))
 
 ;;;###autoload
 (defun gnus-fetch-group (group &optional articles)
@@ -2449,15 +2459,19 @@ the bug number, and browsing the URL must return mbox output."
       (with-temp-file tmpfile
        (mm-disable-multibyte)
        (dolist (id ids)
-         (url-insert-file-contents (format mbox-url id)))
+         (let ((file (format "~/.emacs.d/debbugs-cache/%s" id)))
+           (if (and (not gnus-plugged)
+                    (file-exists-p file))
+               (insert-file-contents file)
+             (url-insert-file-contents (format mbox-url id)))))
        (goto-char (point-min))
        ;; Add the debbugs address so that we can respond to reports easily.
        (while (re-search-forward "^To: " nil t)
          (end-of-line)
          (insert (format ", %s@%s" (car ids)
                          (replace-regexp-in-string
-                          (replace-regexp-in-string mbox-url "^http://" "")
-                          "/.*$" ""))))))
+                          "/.*$" ""
+                          (replace-regexp-in-string "^http://" "" mbox-url)))))))
     (gnus-group-read-ephemeral-group
      (format "nndoc+ephemeral:bug#%s"
             (mapconcat 'number-to-string ids ","))
@@ -3995,7 +4009,7 @@ entail asking the server for the groups."
     (erase-buffer)
     (while groups
       (setq group (pop groups))
-      (gnus-add-text-properties
+      (add-text-properties
        (point) (prog1 (1+ (point))
                 (insert "       *: "
                         (gnus-group-decoded-name group)
@@ -4117,22 +4131,23 @@ If DONT-SCAN is non-nil, scan non-activated groups as well."
                 (gnus-read-all-descriptions-files)))
     (error "Couldn't request descriptions file"))
   (let ((buffer-read-only nil)
-       b)
-    (erase-buffer)
+       b groups)
     (mapatoms
      (lambda (group)
-       (setq b (point))
-       (let ((charset (gnus-group-name-charset nil (symbol-name group))))
-        (insert (format "      *: %-20s %s\n"
-                        (gnus-group-name-decode
-                         (symbol-name group) charset)
-                        (gnus-group-name-decode
-                         (symbol-value group) charset))))
-       (gnus-add-text-properties
-       b (1+ b) (list 'gnus-group group
-                      'gnus-unread t 'gnus-marked nil
-                      'gnus-level (1+ gnus-level-subscribed))))
+       (push (symbol-name group) groups))
      gnus-description-hashtb)
+    (setq groups (sort groups 'string<))
+    (erase-buffer)
+    (dolist (group groups)
+      (setq b (point))
+      (let ((charset (gnus-group-name-charset nil group)))
+       (insert (format "      *: %-20s %s\n"
+                       (gnus-group-name-decode group charset)
+                       (gnus-group-name-decode group charset))))
+      (add-text-properties
+       b (1+ b) (list 'gnus-group (intern group gnus-description-hashtb)
+                     'gnus-unread t 'gnus-marked nil
+                     'gnus-level (1+ gnus-level-subscribed))))
     (goto-char (point-min))
     (gnus-group-position-point)))
 
@@ -4488,7 +4503,7 @@ and the second element is the address."
        (if force
            (if (null articles)
                (setcar (nthcdr 3 info)
-                       (gnus-delete-alist type (car marked)))
+                       (assq-delete-all type (car marked)))
              (setcdr m (gnus-compress-sequence articles t)))
          (setcdr m (gnus-compress-sequence
                     (sort (nconc (gnus-uncompress-range (cdr m))
@@ -4526,7 +4541,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 (time-subtract (current-time) time)))
     (+ (* (nth 0 delta) 65536.0)
        (nth 1 delta))))