2002-11-26 Kevin Ryde <user42@zip.com.au>
[gnus] / lisp / gnus.el
index 627c327..7ddf830 100644 (file)
 
 ;; Other
 (defgroup gnus-visual nil
-  "Options controling the visual fluff."
+  "Options controlling the visual fluff."
   :group 'gnus
   :group 'faces)
 
   :group 'gnus)
 
 (defgroup gnus-meta nil
-  "Meta variables controling major portions of Gnus.
+  "Meta variables controlling major portions of Gnus.
 In general, modifying these variables does not take affect until Gnus
 is restarted, and sometimes reloaded."
   :group 'gnus)
@@ -277,7 +277,7 @@ is restarted, and sometimes reloaded."
   :link '(custom-manual "(gnus)Exiting Gnus")
   :group 'gnus)
 
-(defconst gnus-version-number "0.06"
+(defconst gnus-version-number "0.08"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Oort Gnus v%s" gnus-version-number)
@@ -1085,8 +1085,8 @@ used to 899, you would say something along these lines:
 This variable should be a list, where the first element is how the
 news is to be fetched, the second is the address.
 
-For instance, if you want to get your news via NNTP from
-\"flab.flab.edu\", you could say:
+For instance, if you want to get your news via \"flab.flab.edu\" using
+NNTP, you could say:
 
 \(setq gnus-select-method '(nntp \"flab.flab.edu\"))
 
@@ -1154,7 +1154,7 @@ variable instead."
 This is a list where each element is a complete select method (see
 `gnus-select-method').
 
-If, for instance, you want to read your mail with the nnml backend,
+If, for instance, you want to read your mail with the nnml back end,
 you could set this variable:
 
 \(setq gnus-secondary-select-methods '((nnml \"\")))"
@@ -1195,15 +1195,15 @@ It can also be a list of select methods, as well as the special symbol
 list, Gnus will try all the methods in the list until it finds a match."
   :group 'gnus-server
   :type '(choice (const :tag "default" nil)
-                (const :tag "DejaNews" (nnweb "refer" (nnweb-type dejanews)))
+                (const :tag "Google" (nnweb "refer" (nnweb-type google)))
                 gnus-select-method
                 (repeat :menu-tag "Try multiple"
                         :tag "Multiple"
-                        :value (current (nnweb "refer" (nnweb-type dejanews)))
+                        :value (current (nnweb "refer" (nnweb-type google)))
                         (choice :tag "Method"
                                 (const current)
-                                (const :tag "DejaNews"
-                                       (nnweb "refer" (nnweb-type dejanews)))
+                                (const :tag "Google"
+                                       (nnweb "refer" (nnweb-type google)))
                                 gnus-select-method))))
 
 (defcustom gnus-group-faq-directory
@@ -1246,6 +1246,41 @@ If the default site is too slow, try one of these:
   :type '(choice directory
                 (repeat directory)))
 
+(defcustom gnus-group-charter-alist
+  '(("no" . (concat "http://no.news-admin.org/charter/" name ".txt"))
+    ("de" . (concat "http://purl.net/charta/" name ".html"))
+    ("dk" . (concat "http://www.usenet.dk/grupper.pl?get=" name))
+    ("england" . (concat "http://england.news-admin.org/charters/" name))
+    ("fr" . (concat "http://www.usenet-fr.net/fur/chartes/" name ".html"))
+    ("europa" . (concat "http://www.europa.usenet.eu.org/chartas/charta-en-" 
+                       (gnus-replace-in-string name "europa\\." "") ".html"))
+    ("nl" . (concat "http://www.xs4all.nl/~sister/usenet/charters/" name))
+    ("aus" . (concat "http://aus.news-admin.org/groupinfo.php/" name))
+    ("pl" . (concat "http://www.usenet.pl/opisy/" name))
+    ("ch" . (concat "http://www.use-net.ch/Usenet/charter.html#" name))
+    ("at" . (concat "http://www.usenet.at/chartas/" name "/charta"))
+    ("uk" . (concat "http://www.usenet.org.uk/" name ".html"))
+    ("wales" . (concat "http://www.wales-usenet.org/english/groups/" name ".html"))
+    ("dfw" . (concat "http://www.cirr.com/dfw/charters/" name ".html"))
+    ("se" . (concat "http://www.usenet-se.net/Reglementen/" 
+                   (gnus-replace-in-string name "\\." "_") ".html"))
+    ("milw" . (concat "http://usenet.mil.wi.us/" 
+                     (gnus-replace-in-string name "milw\\." "") "-charter"))
+    ("ca" . (concat "http://www.sbay.org/ca/charter-" name ".html"))
+    ("netins" . (concat "http://www.netins.net/usenet/charter/" 
+                       (gnus-replace-in-string name "\\." "-") "-charter.html")))
+  "*An alist of (HIERARCHY . FORM) pairs used to construct the URL of a charter.
+  When FORM is evaluated `name' is bound to the name of the group."
+  :group 'gnus-group-various
+  :type '(repeat (cons (string :tag "Hierarchy") (sexp :tag "Form"))))
+
+(defcustom gnus-group-fetch-control-use-browse-url nil
+  "*Non-nil means that control messages are displayed using `browse-url'.
+Otherwise they are fetched with ange-ftp and displayed in an ephemeral
+group."
+  :group 'gnus-group-various
+  :type 'boolean)
+
 (defcustom gnus-use-cross-reference t
   "*Non-nil means that cross referenced articles will be marked as read.
 If nil, ignore cross references.  If t, mark articles as read in
@@ -1269,7 +1304,8 @@ If the number of articles in a newsgroup is greater than this value,
 confirmation is required for selecting the newsgroup.
 If it is `nil', no confirmation is required."
   :group 'gnus-group-select
-  :type 'integer)
+  :type '(choice (const :tag "No limit" nil)
+                integer))
 
 (defcustom gnus-use-long-file-name (not (memq system-type '(usg-unix-v xenix)))
   "*Non-nil means that the default name of a file to save articles in is the group name.
@@ -1438,7 +1474,8 @@ slower."
     ("nnlistserv" none)
     ("nnagent" post-mail)
     ("nnimap" post-mail address prompt-address physical-address)
-    ("nnmaildir" mail respool address))
+    ("nnmaildir" mail respool address)
+    ("nnnil" none))
   "*An alist of valid select methods.
 The first element of each list lists should be a string with the name
 of the select method.  The other elements may be the category of
@@ -1550,6 +1587,21 @@ present in a news group, you'll get mail group semantics when doing
 The gnus-group-split mail splitting mechanism will behave as if this
 address was listed in gnus-group-split Addresses (see below).")
 
+(gnus-define-group-parameter
+ subscribed
+ :type bool
+ :function-document
+ "Return GROUP's subscription status."
+ :variable-document
+ "*Groups which are automatically considered subscribed."
+ :parameter-type '(const :tag "Subscribed" t)
+ :parameter-document "\
+Gnus assumed that you are subscribed to the To/List address.
+
+When constructing a list of subscribed groups using
+`gnus-find-subscribed-addresses', Gnus includes the To address given
+above, or the list address (if the To address has not been set).")
+
 (gnus-define-group-parameter
  auto-expire
  :type bool
@@ -1610,8 +1662,7 @@ Use with caution.")
    ("\\(^\\|:\\)han\\>" euc-kr)
    ("\\(^\\|:\\)alt.chinese.text.big5\\>" chinese-big5)
    ("\\(^\\|:\\)soc.culture.vietnamese\\>" vietnamese-viqr)
-   ("\\(^\\|:\\)\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)
-   (".*" iso-8859-1))
+   ("\\(^\\|:\\)\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1))
  :variable-document
  "Alist of regexps (to match group names) and default charsets to be used when reading."
  :variable-group gnus-charset
@@ -1642,6 +1693,23 @@ posting an article."
  :parameter-document
  "Posting method for this group.")
 
+(gnus-define-group-parameter
+ large-newsgroup-initial
+ :type integer
+ :function-document
+ "Return GROUP's initial input of the number of articles."
+ :variable-document
+ "*Alist of group regexps and its initial input of the number of articles."
+ :parameter-type '(choice :tag "Initial Input for Large Newsgroup"
+                         (const :tag "All" nil)
+                         (integer))
+ :parameter-document "\
+
+This number will be prompted as the initial value of the number of
+articles to list when the group is a large newsgroup (see
+`gnus-large-newsgroup').  If it is `nil', the default value is the
+total number of articles in the group.")
+
 (defcustom gnus-group-uncollapsed-levels 1
   "Number of group name elements to leave alone when making a short group name."
   :group 'gnus-group-visual
@@ -1765,10 +1833,14 @@ face."
 (defvar gnus-plugged t
   "Whether Gnus is plugged or not.")
 
-(defvar gnus-agent-cache t
-  "Whether Gnus use agent cache.")
+(defcustom gnus-agent-cache t
+  "Whether Gnus use agent cache.
+You also need to enable `gnus-agent'."
+  :version "21.3"
+  :group 'gnus-agent
+  :type 'boolean)
 
-(defcustom gnus-default-charset 'iso-8859-1
+(defcustom gnus-default-charset (mm-guess-mime-charset)
   "Default charset assumed to be used when viewing non-ASCII characters.
 This variable is overridden on a group-to-group basis by the
 gnus-group-charset-alist variable and is only used on groups not
@@ -1776,6 +1848,33 @@ covered by that variable."
   :type 'symbol
   :group 'gnus-charset)
 
+(defcustom gnus-agent t
+  "Whether we want to use the Gnus agent or not.
+Putting (gnus-agentize) in ~/.gnus is obsolete by (setq gnus-agent t)."
+  :version "21.3"
+  :group 'gnus-agent
+  :type 'boolean)
+
+(defcustom gnus-other-frame-function 'gnus
+  "Function called by the command `gnus-other-frame'."
+  :group 'gnus-start
+  :type '(choice (function-item gnus)
+                (function-item gnus-no-server)
+                (function-item gnus-slave)
+                (function-item gnus-slave-no-server)))
+
+(defcustom gnus-other-frame-parameters nil
+  "Frame parameters used by `gnus-other-frame' to create a Gnus frame.
+This should be an alist for FSF Emacs, or a plist for XEmacs."
+  :group 'gnus-start
+  :type (if (featurep 'xemacs)
+           '(repeat (list :inline t :format "%v"
+                          (symbol :tag "Property")
+                          (sexp :tag "Value")))
+         '(repeat (cons :format "%v"
+                        (symbol :tag "Parameter")
+                        (sexp :tag "Value")))))
+
 \f
 ;;; Internal variables
 
@@ -1786,9 +1885,7 @@ covered by that variable."
 (defvar gnus-original-article-buffer " *Original Article*")
 (defvar gnus-newsgroup-name nil)
 (defvar gnus-ephemeral-servers nil)
-
-(defvar gnus-agent nil
-  "Whether we want to use the Gnus agent or not.")
+(defvar gnus-server-method-cache nil)
 
 (defvar gnus-agent-fetching nil
   "Whether Gnus agent is in fetching mode.")
@@ -1796,7 +1893,7 @@ covered by that variable."
 (defvar gnus-agent-covered-methods nil)
 
 (defvar gnus-command-method nil
-  "Dynamically bound variable that says what the current backend is.")
+  "Dynamically bound variable that says what the current back end is.")
 
 (defvar gnus-current-select-method nil
   "The current method for selecting a newsgroup.")
@@ -1857,12 +1954,13 @@ covered by that variable."
 ;; `download' is a agent flag private to each gnus installation
 ;; `unsend' are for nndraft groups only
 ;; `score' is not a proper mark
+;; `bookmark': don't propagated it, or fix the bug in update-mark.
 (defconst gnus-article-unpropagated-mark-lists
-  '(seen cache download unsend score)
-  "Marks that shouldn't be propagated to backends.
-Typical marks are those that make no sense in a standalone backend,
+  '(seen cache download unsend score bookmark)
+  "Marks that shouldn't be propagated to back ends.
+Typical marks are those that make no sense in a standalone back end,
 such as a mark that says whether an article is stored in the cache
-(which doesn't make sense in a standalone backend).")
+\(which doesn't make sense in a standalone back end).")
 
 (defvar gnus-headers-retrieved-by nil)
 (defvar gnus-article-reply nil)
@@ -1948,6 +2046,9 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
 (defvar gnus-invalid-group-regexp "[: `'\"/]\\|^$"
   "Regexp matching invalid groups.")
 
+(defvar gnus-other-frame-object nil
+  "A frame object which will be created by `gnus-other-frame'.")
+
 ;;; End of variables.
 
 ;; Define some autoload functions Gnus might use.
@@ -2103,6 +2204,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
       gnus-article-de-base64-unreadable
       gnus-article-decode-HZ
       gnus-article-wash-html
+      gnus-article-unsplit-urls
       gnus-article-hide-pgp
       gnus-article-hide-pem gnus-article-hide-signature
       gnus-article-strip-leading-blank-lines gnus-article-date-local
@@ -2139,7 +2241,8 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
      ("gnus-draft" :interactive t gnus-draft-mode gnus-group-send-queue)
      ("gnus-mlspl" gnus-group-split gnus-group-split-fancy)
      ("gnus-mlspl" :interactive t gnus-group-split-setup
-      gnus-group-split-update))))
+      gnus-group-split-update)
+     ("gnus-delay" gnus-delay-initialize))))
 
 ;;; gnus-sum.el thingies
 
@@ -2165,6 +2268,8 @@ with some simple extensions.
 %M   Message-id of the article (string)
 %r   References of the article (string)
 %c   Number of characters in the article (integer)
+%k   Pretty-printed version of the above (string)
+     For example, \"1.2k\" or \"0.4M\".
 %L   Number of lines in the article (integer)
 %I   Indentation based on thread level (a string of spaces)
 %B   A complex trn-style thread tree (string)
@@ -2185,6 +2290,8 @@ with some simple extensions.
 %V   Total thread score (number).
 %P   The line number (number).
 %O   Download mark (character).
+%C   If present, indicates desired cursor position
+     (instead of after first colon).
 %u   User defined specifier.  The next character in the format string should
      be a letter.  Gnus will call the function gnus-user-format-function-X,
      where X is the letter following %u.  The function will be passed the
@@ -2204,8 +2311,8 @@ possible.
 
 This restriction may disappear in later versions of Gnus.
 
-General format specifiers can also be used.  
-See (gnus)Formatting Variables."
+General format specifiers can also be used.
+See Info node `(gnus)Formatting Variables'."
   :link '(custom-manual "(gnus)Formatting Variables")
   :type 'string
   :group 'gnus-summary-format)
@@ -2376,12 +2483,14 @@ with a `subscribed' parameter."
   (let (group address addresses)
     (dolist (entry (cdr gnus-newsrc-alist))
       (setq group (car entry))
-      (when (gnus-group-find-parameter group 'subscribed)
-       (setq address (or (gnus-group-fast-parameter group 'to-address)
-                         (gnus-group-fast-parameter group 'to-list)))
+      (when (gnus-parameter-subscribed group)
+       (setq address (mail-strip-quoted-names
+                      (or (gnus-group-fast-parameter group 'to-address)
+                          (gnus-group-fast-parameter group 'to-list))))
        (when address
-         (push address addresses))))
-    (list (mapconcat 'regexp-quote addresses "\\|"))))
+         (add-to-list 'addresses address))))
+    (when addresses
+      (list (mapconcat 'regexp-quote addresses "\\|")))))
 
 (defmacro gnus-string-or (&rest strings)
   "Return the first element of STRINGS that is a non-blank string.
@@ -2663,6 +2772,36 @@ that that variable is buffer-local to the summary buffers."
                                   (nth 1 method))))
       method)))
 
+(defsubst gnus-server-to-method (server)
+  "Map virtual server names to select methods."
+  (or (and server (listp server) server)
+      (cdr (assoc server gnus-server-method-cache))
+      (let ((result
+            (or
+             ;; Perhaps this is the native server?
+             (and (equal server "native") gnus-select-method)
+             ;; It should be in the server alist.
+             (cdr (assoc server gnus-server-alist))
+             ;; It could be in the predefined server alist.
+             (cdr (assoc server gnus-predefined-server-alist))
+             ;; If not, we look through all the opened server
+             ;; to see whether we can find it there.
+             (let ((opened gnus-opened-servers))
+               (while (and opened
+                           (not (equal server (format "%s:%s" (caaar opened)
+                                                      (cadaar opened)))))
+                 (pop opened))
+               (caar opened))
+             ;; It could be a named method, search all servers
+             (let ((servers gnus-secondary-select-methods))
+               (while (and servers
+                           (not (equal server (format "%s:%s" (caar servers)
+                                                      (cadar servers)))))
+                 (pop servers))
+               (car servers)))))
+       (push (cons server result) gnus-server-method-cache)
+       result)))
+
 (defsubst gnus-server-get-method (group method)
   ;; Input either a server name, and extended server name, or a
   ;; select method, and return a select method.
@@ -2680,33 +2819,6 @@ that that variable is buffer-local to the summary buffers."
        (t
         (gnus-server-add-address method))))
 
-(defun gnus-server-to-method (server)
-  "Map virtual server names to select methods."
-  (or
-   ;; Is this a method, perhaps?
-   (and server (listp server) server)
-   ;; Perhaps this is the native server?
-   (and (equal server "native") gnus-select-method)
-   ;; It should be in the server alist.
-   (cdr (assoc server gnus-server-alist))
-   ;; It could be in the predefined server alist.
-   (cdr (assoc server gnus-predefined-server-alist))
-   ;; If not, we look through all the opened server
-   ;; to see whether we can find it there.
-   (let ((opened gnus-opened-servers))
-     (while (and opened
-                (not (equal server (format "%s:%s" (caaar opened)
-                                           (cadaar opened)))))
-       (pop opened))
-     (caar opened))
-   ;; It could be a named method, search all servers
-   (let ((servers gnus-secondary-select-methods))
-     (while (and servers
-                (not (equal server (format "%s:%s" (caar servers)
-                                           (cadar servers)))))
-       (pop servers))
-     (car servers))))
-
 (defmacro gnus-method-equal (ss1 ss2)
   "Say whether two servers are equal."
   `(let ((s1 ,ss1)
@@ -3178,7 +3290,7 @@ If NEWSGROUP is nil, return the global kill file name instead."
         (address (nth 1 server)))
     (if (and address
             (not (zerop (length address))))
-       (format "%s via %s" address (car server))
+       (format "%s using %s" address (car server))
       (format "%s" (car server)))))
 
 (defun gnus-find-method-for-group (group &optional info)
@@ -3309,15 +3421,51 @@ server."
   (gnus arg nil 'slave))
 
 ;;;###autoload
-(defun gnus-other-frame (&optional arg)
-  "Pop up a frame to read news."
+(defun gnus-other-frame (&optional arg display)
+  "Pop up a frame to read news.
+This will call one of the Gnus commands which is specified by the user
+option `gnus-other-frame-function' (default `gnus') with the argument
+ARG if Gnus is not running, otherwise just pop up a Gnus frame.  The
+optional second argument DISPLAY should be a standard display string
+such as \"unix:0\" to specify where to pop up a frame.  If DISPLAY is
+omitted or the function `make-frame-on-display' is not available, the
+current display is used."
   (interactive "P")
-  (let ((window (get-buffer-window gnus-group-buffer)))
-    (cond (window
-          (select-frame (window-frame window)))
-         (t
-          (select-frame (make-frame)))))
-  (gnus arg))
+  (if (fboundp 'make-frame-on-display)
+      (unless display
+       (setq display (gnus-frame-or-window-display-name (selected-frame))))
+    (setq display nil))
+  (let ((alive (gnus-alive-p)))
+    (unless (and alive
+                (catch 'found
+                  (walk-windows
+                   (lambda (window)
+                     (when (and (or (not display)
+                                    (equal display
+                                           (gnus-frame-or-window-display-name
+                                            window)))
+                                (with-current-buffer (window-buffer window)
+                                  (string-match "\\`gnus-"
+                                                (symbol-name major-mode))))
+                       (gnus-select-frame-set-input-focus
+                        (setq gnus-other-frame-object (window-frame window)))
+                       (select-window window)
+                       (throw 'found t)))
+                   'ignore t)))
+      (gnus-select-frame-set-input-focus
+       (setq gnus-other-frame-object
+            (if display
+                (make-frame-on-display display gnus-other-frame-parameters)
+              (make-frame gnus-other-frame-parameters))))
+      (if alive
+         (switch-to-buffer gnus-group-buffer)
+       (funcall gnus-other-frame-function arg)
+       (add-hook 'gnus-exit-gnus-hook
+                 (lambda nil
+                   (when (and (frame-live-p gnus-other-frame-object)
+                              (cdr (frame-list)))
+                     (delete-frame gnus-other-frame-object))
+                   (setq gnus-other-frame-object nil)))))))
 
 ;;(setq thing ?                                ; this is a comment
 ;;      more 'yes)