Sync
[elisp/gnus.git-] / lisp / gnus.el
index 0563e31..553db6d 100644 (file)
@@ -1,5 +1,6 @@
 ;;; gnus.el --- a newsreader for GNU Emacs
-;; Copyright (C) 1987-1990,1993-1999 Free Software Foundation, Inc.
+;; Copyright (C) 1987, 1988, 1989, 1990, 1993, 1994, 1995, 1996,
+;;        1997, 1998, 2000 Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
 
 (eval '(run-hooks 'gnus-load-hook))
 
-(eval-when-compile
-  (require 'cl)
-  (require 'static))
+(eval-when-compile (require 'cl))
+(eval-when-compile (require 'static))
 
-(require 'custom)
-(eval-and-compile
-  (if (< emacs-major-version 20)
-      (require 'gnus-load)))
+(require 'gnus-vers)
 (require 'message)
 
 (defgroup gnus nil
@@ -263,29 +260,6 @@ is restarted, and sometimes reloaded."
   :link '(custom-manual "(gnus)Exiting Gnus")
   :group 'gnus)
 
-(defconst gnus-product-name "T-gnus"
-  "Product name of this version of gnus.")
-
-(defconst gnus-version-number "6.13.3"
-  "Version number for this version of gnus.")
-
-(defconst gnus-revision-number "01"
-  "Revision number for this version of gnus.")
-
-(defconst gnus-original-version-number "0.98"
-    "Version number for this version of Gnus.")
-
-(provide 'running-pterodactyl-gnus-0_73-or-later)
-
-(defconst gnus-original-product-name "Pterodactyl Gnus"
-  "Product name of the original version of Gnus.")
-
-(defconst gnus-version
-  (format "%s %s (based on %s v%s ; for SEMI 1.13, FLIM 1.13)"
-         gnus-product-name gnus-version-number
-         gnus-original-product-name gnus-original-version-number)
-  "Version string for this version of gnus.")
-
 (defcustom gnus-inhibit-startup-message nil
   "If non-nil, the startup message will not be displayed.
 This variable is used before `.gnus.el' is loaded, so it should
@@ -775,7 +749,47 @@ be set in `.emacs' instead."
   "Insert startup message in current buffer."
   ;; Insert the message.
   (erase-buffer)
-  (insert "
+  (cond
+   ((and (fboundp 'find-image)
+        (display-graphic-p)
+        (let ((image
+               (find-image
+                `((:type xpm :file "gnus.xpm"
+                         :color-symbols
+                         (("thing" . "#724214")
+                          ("shadow" . "#1e3f03")
+                          ("background" . ,(face-background 'default))))
+                  (:type xbm :file "gnus.xbm"
+                         :foreground ,(face-foreground 'gnus-splash-face)
+                         :background ,(face-background 'default))))))
+          (when image
+            (insert-image image)
+            (goto-char (point-min))
+            (insert-char
+             ?\ ;; space
+             (max 0 (let ((cw (frame-char-width)))
+                      (/ (+ (- (* (window-width) cw) 271) cw) 2 cw))))
+            (goto-char (point-min))
+            (insert gnus-product-name " " gnus-version-number
+                    (if (zerop (string-to-number gnus-revision-number))
+                        ""
+                      (concat " (r" gnus-revision-number ")"))
+                    " based on " gnus-original-product-name " v"
+                    gnus-original-version-number "\n")
+            (goto-char (point-min))
+            (put-text-property (point) (gnus-point-at-eol)
+                               'face 'gnus-splash-face)
+            (insert-char ?\ ;; space
+                         (max 0 (/ (- (window-width) (gnus-point-at-eol)) 2)))
+            (forward-line 1)
+            (insert-char
+             ?\n (max 0
+                      (let ((ch (frame-char-height)))
+                        (/ (+ (- (* (1- (window-height)) ch) 273) ch) 2 ch))))
+            (setq gnus-simple-splash nil)
+            t))))
+   (t
+    (insert "
           _    ___ _             _
           _ ___ __ ___  __    _ ___
           __   _     ___    __  ___
@@ -795,32 +809,32 @@ be set in `.emacs' instead."
           __
 
 "
-         )
-  (goto-char (point-min))
-  (insert gnus-product-name " " gnus-version-number
-         (if (zerop (string-to-number gnus-revision-number))
-             ""
-           (concat " (r" gnus-revision-number ")"))
-         " based on " gnus-original-product-name " v"
-         gnus-original-version-number)
-  (goto-char (point-min))
-  (insert-char ?\ ; space
-              (max 0 (/ (- (window-width) (gnus-point-at-eol)) 2)))
-  (forward-line 1)
-  ;; And then hack it.
-  (gnus-indent-rigidly (point) (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.
-  (put-text-property (point-min) (point-max) 'face 'gnus-splash-face)
+           )
+    (goto-char (point-min))
+    (insert gnus-product-name " " gnus-version-number
+           (if (zerop (string-to-number gnus-revision-number))
+               ""
+             (concat " (r" gnus-revision-number ")"))
+           " based on " gnus-original-product-name " v"
+           gnus-original-version-number)
+    (goto-char (point-min))
+    (insert-char ?\ ; space
+                (max 0 (/ (- (window-width) (gnus-point-at-eol)) 2)))
+    (forward-line 1)
+    ;; And then hack it.
+    (gnus-indent-rigidly (point) (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.
+    (put-text-property (point-min) (point-max) 'face 'gnus-splash-face)
+    (setq gnus-simple-splash t)))
   (goto-char (point-min))
   (setq mode-line-buffer-identification (concat " " gnus-version))
-  (setq gnus-simple-splash t)
   (set-buffer-modified-p t))
 
 (eval-when (load)
@@ -915,7 +929,7 @@ used to 899, you would say something along these lines:
           nil
         (list gnus-nntp-service)))
     (error nil))
-  "*Default method for selecting a newsgroup.
+  "Default method for selecting a newsgroup.
 This variable should be a list, where the first element is how the
 news is to be fetched, the second is the address.
 
@@ -946,7 +960,7 @@ see the manual for details."
   "*Method used for archiving messages you've sent.
 This should be a mail method.
 
-It's probably not a very effective to change this variable once you've
+It's probably not very effective to change this variable once you've
 run Gnus once.  After doing that, you must edit this server from the
 server buffer."
   :group 'gnus-server
@@ -1003,8 +1017,8 @@ If, for instance, you want to read your mail with the nnml backend,
 you could set this variable:
 
 \(setq gnus-secondary-select-methods '((nnml \"\")))"
-:group 'gnus-server
-:type '(repeat gnus-select-method))
+  :group 'gnus-server
+  :type '(repeat gnus-select-method))
 
 (defvar gnus-backup-default-subscribed-newsgroups
   '("news.announce.newusers" "news.groups.questions" "gnu.emacs.gnus")
@@ -1033,10 +1047,23 @@ articles by Message-ID is painfully slow.  By setting this method to an
 nntp method, you might get acceptable results.
 
 The value of this variable must be a valid select method as discussed
-in the documentation of `gnus-select-method'."
+in the documentation of `gnus-select-method'.
+
+It can also be a list of select methods, as well as the special symbol
+`current', which means to use the current select method.  If it is a
+list, Gnus will try all the methods in the list until it finds a match."
   :group 'gnus-server
   :type '(choice (const :tag "default" nil)
-                gnus-select-method))
+                (const :tag "DejaNews" (nnweb "refer" (nnweb-type dejanews)))
+                gnus-select-method
+                (repeat :menu-tag "Try multiple"
+                        :tag "Multiple"
+                        :value (current (nnweb "refer" (nnweb-type dejanews)))
+                        (choice :tag "Method"
+                                (const current)
+                                (const :tag "DejaNews"
+                                       (nnweb "refer" (nnweb-type dejanews)))
+                                gnus-select-method))))
 
 (defcustom gnus-group-faq-directory
   '("/ftp@mirrors.aol.com:/pub/rtfm/usenet/"
@@ -1271,6 +1298,9 @@ slower."
     ("nnfolder" mail respool address)
     ("nngateway" post-mail address prompt-address physical-address)
     ("nnweb" none)
+    ("nnslashdot" post)
+    ("nnultimate" none)
+    ("nnwarchive" none)
     ("nnlistserv" none)
     ("nnagent" post-mail)
     ("nnimap" post-mail address prompt-address physical-address))
@@ -1294,18 +1324,28 @@ this variable.  I think."
                                   (const :format "%v " virtual)
                                   (const respool)))))
 
-(define-widget 'gnus-select-method 'list
-  "Widget for entering a select method."
-  :args `((choice :tag "Method"
-                 ,@(mapcar (lambda (entry)
-                             (list 'const :format "%v\n"
-                                   (intern (car entry))))
-                           gnus-valid-select-methods))
-         (string :tag "Address")
-         (editable-list  :inline t
-                         (list :format "%v"
-                               variable
-                               (sexp :tag "Value")))))
+(defun gnus-redefine-select-method-widget ()
+  "Recomputes the select-method widget based on the value of
+`gnus-valid-select-methods'."
+  (define-widget 'gnus-select-method 'list
+    "Widget for entering a select method."
+    :value '(nntp "")
+    :tag "Select Method"
+    :args `((choice :tag "Method"
+                   ,@(mapcar (lambda (entry)
+                               (list 'const :format "%v\n"
+                                     (intern (car entry))))
+                             gnus-valid-select-methods)
+                   (symbol :tag "other"))
+           (string :tag "Address")
+           (repeat :tag "Options"
+                   :inline t
+                   (list :format "%v"
+                         variable
+                         (sexp :tag "Value"))))
+    ))
+
+(gnus-redefine-select-method-widget)
 
 (defcustom gnus-updated-mode-lines '(group article summary tree)
   "List of buffers that should update their mode lines.
@@ -1582,13 +1622,30 @@ This variable can be nil, gnus or gnus-ja."
 
 (defvar gnus-variable-list
   '(gnus-newsrc-options gnus-newsrc-options-n
-    gnus-newsrc-last-checked-date
-    gnus-newsrc-alist gnus-server-alist
-    gnus-killed-list gnus-zombie-list
-    gnus-topic-topology gnus-topic-alist
-    gnus-format-specs)
+                       gnus-newsrc-last-checked-date
+                       gnus-newsrc-alist gnus-server-alist
+                       gnus-killed-list gnus-zombie-list
+                       gnus-topic-topology gnus-topic-alist)
   "Gnus variables saved in the quick startup file.")
 
+(defvar gnus-product-variable-file-list
+  (let ((version (product-version (product-find 'gnus-vers)))
+       (codesys (static-if (boundp 'MULE) '*ctext* 'ctext)))
+    `(("strict-cache" ((product-version ,version) (emacs-version))
+       binary
+       gnus-format-specs-compiled)
+      ("cache" ((product-version ,version))
+       ,codesys
+       gnus-format-specs)))
+  "Gnus variables are saved in the produce depend quick startup files.")
+
+(defcustom gnus-compile-user-specs t
+  "If non-nil, the user-defined format specs will be byte-compiled
+automatically.
+It has an effect on the values of `gnus-*-line-format-spec'."
+  :group 'gnus
+  :type 'boolean)
+
 (defvar gnus-newsrc-alist nil
   "Assoc list of read articles.
 gnus-newsrc-hashtb should be kept so that both hold the same information.")
@@ -1648,15 +1705,15 @@ use the article treating faculties instead.  Is is described in Info node
            (when (consp function)
              (setq keymap (car (memq 'keymap function)))
              (setq function (car function)))
-           (autoload function (car package) nil interactive keymap)))
+           (unless (fboundp function)
+             (autoload function (car package) nil interactive keymap))))
        (if (eq (nth 1 package) ':interactive)
-           (cdddr package)
+           (nthcdr 3 package)
          (cdr package)))))
-   '(("info" Info-goto-node)
+   '(("info" :interactive t Info-goto-node)
      ("pp" pp pp-to-string pp-eval-expression)
      ("ps-print" ps-print-preprint)
-     ("mail-extr" mail-extract-address-components)
-     ("browse-url" browse-url)
+     ("browse-url" :interactive t browse-url)
      ("message" :interactive t
       message-send-and-exit message-yank-original)
      ("babel" babel-as-string)
@@ -1700,27 +1757,29 @@ use the article treating faculties instead.  Is is described in Info node
       gnus-cache-possibly-remove-articles gnus-cache-request-article
       gnus-cache-retrieve-headers gnus-cache-possibly-alter-active
       gnus-cache-enter-remove-article gnus-cached-article-p
-      gnus-cache-open gnus-cache-close gnus-cache-update-article)
-      ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article
-       gnus-cache-remove-article gnus-summary-insert-cached-articles)
-      ("gnus-score" :interactive t
-       gnus-summary-increase-score gnus-summary-set-score
-       gnus-summary-raise-thread gnus-summary-raise-same-subject
-       gnus-summary-raise-score gnus-summary-raise-same-subject-and-select
-       gnus-summary-lower-thread gnus-summary-lower-same-subject
-       gnus-summary-lower-score gnus-summary-lower-same-subject-and-select
-       gnus-summary-current-score gnus-score-default
-       gnus-score-flush-cache gnus-score-close
-       gnus-possibly-score-headers gnus-score-followup-article
-       gnus-score-followup-thread)
-      ("gnus-score"
-       (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers
+      gnus-cache-open gnus-cache-close gnus-cache-update-article
+      gnus-cache-articles-in-group)
+     ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article
+      gnus-cache-remove-article gnus-summary-insert-cached-articles)
+     ("gnus-score" :interactive t
+      gnus-summary-increase-score gnus-summary-set-score
+      gnus-summary-raise-thread gnus-summary-raise-same-subject
+      gnus-summary-raise-score gnus-summary-raise-same-subject-and-select
+      gnus-summary-lower-thread gnus-summary-lower-same-subject
+      gnus-summary-lower-score gnus-summary-lower-same-subject-and-select
+      gnus-summary-current-score gnus-score-delta-default
+      gnus-score-flush-cache gnus-score-close
+      gnus-possibly-score-headers gnus-score-followup-article
+      gnus-score-followup-thread)
+     ("gnus-score"
+      (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers
       gnus-current-score-file-nondirectory gnus-score-adaptive
       gnus-score-find-trace gnus-score-file-name)
      ("gnus-cus" :interactive t gnus-custom-mode gnus-group-customize
       gnus-score-customize)
      ("gnus-topic" :interactive t gnus-topic-mode)
-     ("gnus-topic" gnus-topic-remove-group gnus-topic-set-parameters)
+     ("gnus-topic" gnus-topic-remove-group gnus-topic-set-parameters
+      gnus-subscribe-topics)
      ("gnus-salt" :interactive t gnus-pick-mode gnus-binary-mode)
      ("gnus-uu" (gnus-uu-extract-map keymap) (gnus-uu-mark-map keymap))
      ("gnus-uu" :interactive t
@@ -1738,8 +1797,7 @@ use the article treating faculties instead.  Is is described in Info node
      ("gnus-uu" gnus-uu-delete-work-dir gnus-quote-arg-for-sh-or-csh
       gnus-uu-unmark-thread)
      ("gnus-msg" (gnus-summary-send-map keymap)
-      gnus-article-mail gnus-copy-article-buffer gnus-extended-version
-      gnus-following-method)
+      gnus-article-mail gnus-copy-article-buffer gnus-following-method)
      ("gnus-msg" :interactive t
       gnus-group-post-news gnus-group-mail gnus-summary-post-news
       gnus-summary-followup gnus-summary-followup-with-original
@@ -1758,6 +1816,7 @@ use the article treating faculties instead.  Is is described in Info node
      ("gnus-gl" bbb-login bbb-logout bbb-grouplens-group-p
       gnus-grouplens-mode)
      ("smiley" :interactive t gnus-smiley-display)
+     ("smiley" smiley-toggle-buffer)
      ("gnus-win" gnus-configure-windows gnus-add-configuration)
      ("gnus-sum" gnus-summary-insert-line gnus-summary-read-group
       gnus-list-of-unread-articles gnus-list-of-read-articles
@@ -1781,9 +1840,11 @@ use the article treating faculties instead.  Is is described in Info node
       gnus-article-delete-invisible-text gnus-treat-article)
      ("gnus-art" :interactive t
       gnus-article-hide-headers gnus-article-hide-boring-headers
-      gnus-article-treat-overstrike 
+      gnus-article-treat-overstrike
       gnus-article-remove-cr gnus-article-remove-trailing-blank-lines
       gnus-article-display-x-face
+      gnus-article-decode-HZ
+      gnus-article-wash-html
       gnus-article-hide-pgp
       gnus-article-hide-pem gnus-article-hide-signature
       gnus-article-strip-leading-blank-lines gnus-article-date-local
@@ -1836,7 +1897,8 @@ use the article treating faculties instead.  Is is described in Info node
 
 (eval-and-compile
   (unless (featurep 'xemacs)
-    (autoload 'gnus-smiley-display "gnus-bitmap")
+    (autoload 'gnus-smiley-display "gnus-bitmap" nil t)
+    (autoload 'smiley-toggle-buffer "gnus-bitmap")
     (autoload 'x-face-mule-gnus-article-display-x-face "x-face-mule")))
 
 ;;; gnus-sum.el thingies
@@ -2085,42 +2147,6 @@ STRINGS will be evaluated in normal `or' order."
        (setq strings nil)))
     string))
 
-(defun gnus-version (&optional arg)
-  "Version number of this version of Gnus.
-If ARG, insert string at point."
-  (interactive "P")
-  (if arg
-      (insert (message gnus-version))
-    (message gnus-version)))
-
-(defun gnus-continuum-version (version)
-  "Return VERSION as a floating point number."
-  (when (or (string-match "^\\([^ ]+\\)? ?Gnus v?\\([0-9.]+\\)$" version)
-           (string-match "^\\(.?\\)gnus-\\([0-9.]+\\)$" version))
-    (let ((alpha (and (match-beginning 1) (match-string 1 version)))
-         (number (match-string 2 version))
-         major minor least)
-      (unless (string-match
-              "\\([0-9]\\)\\.\\([0-9]+\\)\\.?\\([0-9]+\\)?" number)
-       (error "Invalid version string: %s" version))
-      (setq major (string-to-number (match-string 1 number))
-           minor (string-to-number (match-string 2 number))
-           least (if (match-beginning 3)
-                     (string-to-number (match-string 3 number))
-                   0))
-      (string-to-number
-       (if (zerop major)
-          (format "%s00%02d%02d"
-                  (if (member alpha '("(ding)" "d"))
-                      "4.99"
-                    (+ 5 (* 0.02
-                            (abs
-                             (- (char-int (aref (downcase alpha) 0))
-                                (char-int ?t))))
-                       -0.01))
-                  minor least)
-        (format "%d.%02d%02d" major minor least))))))
-
 (defun gnus-info-find-node ()
   "Find Info documentation of Gnus."
   (interactive)
@@ -2306,7 +2332,14 @@ that that variable is buffer-local to the summary buffers."
   "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) 'news))))
+          (if (or (null article)
+                  (not (< article 0)))
+              (eq (gnus-request-type group article) 'news)
+            (if (not (vectorp article))
+                nil
+              ;; It's a real article.
+              (eq (gnus-request-type group (mail-header-id article))
+                  'news))))))
 
 ;; Returns a list of writable groups.
 (defun gnus-writable-groups ()
@@ -2522,9 +2555,9 @@ You should probably use `gnus-find-method-for-group' instead."
   (let ((methods gnus-secondary-select-methods)
        (gmethod (gnus-server-get-method nil method)))
     (while (and methods
-               (not (gnus-method-equal
-                     (gnus-server-get-method nil (car methods))
-                     gmethod)))
+               (not (gnus-method-equal
+                     (gnus-server-get-method nil (car methods))
+                     gmethod)))
       (setq methods (cdr methods)))
     methods))
 
@@ -2674,11 +2707,13 @@ just the host name."
        (setq levels (- glen levels))
        (dolist (g glist)
          (push (if (>= (decf levels) 0)
-                   (substring g 0 1)
+                   (if (zerop (length g))
+                       ""
+                     (substring g 0 1))
                  g)
                res))
        (concat foreign (mapconcat 'identity (nreverse res) "."))))))
-      
+
 (defun gnus-narrow-to-body ()
   "Narrow to the body of an article."
   (narrow-to-region
@@ -2755,7 +2790,7 @@ If NEWSGROUP is nil, return the global kill file name instead."
   (let ((opened gnus-opened-servers))
     (while (and method opened)
       (when (and (equal (cadr method) (cadaar opened))
-                (equal (car method) (caaar opened))
+                (equal (car method) (caaar opened))
                 (not (equal method (caar opened))))
        (setq method nil))
       (pop opened))
@@ -2792,6 +2827,8 @@ If NEWSGROUP is nil, return the global kill file name instead."
   (or gnus-override-method
       (and (not group)
           gnus-select-method)
+      (and (not (gnus-group-entry group));; a new group
+          (gnus-group-name-to-method group))
       (let ((info (or info (gnus-get-info group)))
            method)
        (if (or (not info)
@@ -2842,6 +2879,9 @@ Disallow invalid group names."
 Allow completion over sensible values."
   (let* ((servers
          (append gnus-valid-select-methods
+                 (mapcar (lambda (i) (list (format "%s:%s" (caar i)
+                                                   (cadar i))))
+                         gnus-opened-servers)
                  gnus-predefined-server-alist
                  gnus-server-alist))
         (method
@@ -2852,11 +2892,18 @@ Allow completion over sensible values."
      ((equal method "")
       (setq method gnus-select-method))
      ((assoc method gnus-valid-select-methods)
-      (list (intern method)
-           (if (memq 'prompt-address
-                     (assoc method gnus-valid-select-methods))
-               (read-string "Address: ")
-             "")))
+      (let ((address (if (memq 'prompt-address
+                              (assoc method gnus-valid-select-methods))
+                        (read-string "Address: ")
+                      "")))
+       (or (let ((opened gnus-opened-servers))
+             (while (and opened
+                         (not (equal (format "%s:%s" method address)
+                                     (format "%s:%s" (caaar opened)
+                                             (cadaar opened)))))
+               (pop opened))
+             (caar opened))
+           (list (intern method) address))))
      ((assoc method servers)
       method)
      (t
@@ -2937,6 +2984,6 @@ prompt the user for the name of an NNTP server to use."
 
 (gnus-ems-redefine)
 
-(provide 'gnus)
+(product-provide (provide 'gnus) 'gnus-vers)
 
 ;;; gnus.el ends here