2001-08-19 Simon Josefsson <jas@extundo.com>
[gnus] / lisp / gnus.el
index e0698c7..f5576ff 100644 (file)
@@ -30,6 +30,7 @@
 (eval '(run-hooks 'gnus-load-hook))
 
 (eval-when-compile (require 'cl))
+(require 'wid-edit)
 (require 'mm-util)
 
 (defgroup gnus nil
   :group 'news
   :group 'mail)
 
+(defgroup gnus-format nil
+  "Dealing with formatting issues."
+  :group 'news
+  :group 'mail)
+
 (defgroup gnus-charset nil
   "Group character set issues."
   :link '(custom-manual "(gnus)Charsets")
@@ -256,7 +262,7 @@ is restarted, and sometimes reloaded."
   :link '(custom-manual "(gnus)Exiting Gnus")
   :group 'gnus)
 
-(defconst gnus-version-number "0.01"
+(defconst gnus-version-number "0.04"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Oort Gnus v%s" gnus-version-number)
@@ -848,19 +854,22 @@ be set in `.emacs' instead."
 (require 'gnus-util)
 (require 'nnheader)
 
-(defvar gnus-parameters nil
+(defcustom gnus-parameters nil
   "Alist of group parameters.
 
 For example:
    ((\"mail\\\\..*\"  (gnus-show-threads nil)
-                  (gnus-use-scoring nil)
-                  (gnus-summary-line-format
-                        \"%U%R%z%I%(%[%d:%ub%-20,20f%]%) %s\\n\")
-                  (gcc-self . t)
-                  (display . all))
+                 (gnus-use-scoring nil)
+                 (gnus-summary-line-format
+                       \"%U%R%z%I%(%[%d:%ub%-23,23f%]%) %s\\n\")
+                 (gcc-self . t)
+                 (display . all))
      (\"mail\\\\.me\" (gnus-use-scoring  t))
      (\"list\\\\..*\" (total-expire . t)
-                  (broken-reply-to . t)))")
+                 (broken-reply-to . t)))"
+  :group 'gnus-group-various
+  :type '(repeat (cons regexp
+                      (repeat sexp))))
 
 (defvar gnus-group-parameters-more nil)
 
@@ -888,8 +897,9 @@ REST is a plist of following:
         (variable-document (or (plist-get rest :variable-document) ""))
         (variable-group (plist-get rest :variable-group))
         (variable-type (or (plist-get rest :variable-type)
-                           `(quote (repeat (list (regexp :tag "Group")
-                                                 ,parameter-type)))))
+                           `(quote (repeat
+                                    (list (regexp :tag "Group")
+                                          ,(car (cdr parameter-type)))))))
         (variable-default (plist-get rest :variable-default)))
     (list
      'progn
@@ -1040,23 +1050,9 @@ see the manual for details."
   :group 'gnus-server
   :type 'gnus-select-method)
 
-(defcustom gnus-message-archive-method
-  (progn
-    ;; Don't require it at top level to avoid circularity.
-    (require 'message)
-    `(nnfolder
-      "archive"
-      (nnfolder-directory ,(nnheader-concat message-directory "archive"))
-      (nnfolder-active-file
-       ,(nnheader-concat message-directory "archive/active"))
-      (nnfolder-get-new-mail nil)
-      (nnfolder-inhibit-expiry t)))
+(defcustom gnus-message-archive-method "archive"
   "*Method used for archiving messages you've sent.
-This should be a mail method.
-
-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."
+This should be a mail method."
   :group 'gnus-server
   :group 'gnus-message
   :type 'gnus-select-method)
@@ -1072,9 +1068,9 @@ If you want to save your mail in one group and the news articles you
 write in another group, you could say something like:
 
  \(setq gnus-message-archive-group
-        '((if (message-news-p)
-              \"misc-news\"
-            \"misc-mail\")))
+       '((if (message-news-p)
+             \"misc-news\"
+           \"misc-mail\")))
 
 Normally the group names returned by this variable should be
 unprefixed -- which implicitly means \"store on the archive server\".
@@ -1189,9 +1185,9 @@ If the default site is too slow, try one of these:
                  ftp.seas.gwu.edu               /pub/rtfm
                  rtfm.mit.edu                   /pub/usenet
    Europe:       ftp.uni-paderborn.de           /pub/FAQ
-                  src.doc.ic.ac.uk               /usenet/news-FAQS
+                 src.doc.ic.ac.uk               /usenet/news-FAQS
                  ftp.sunet.se                   /pub/usenet
-                 sunsite.auc.dk                 /pub/usenet
+                 sunsite.auc.dk                 /pub/usenet
    Asia:         nctuccca.edu.tw                /USENET/FAQ
                  hwarang.postech.ac.kr          /pub/usenet
                  ftp.hk.super.net               /mirror/faqs"
@@ -1219,7 +1215,8 @@ newsgroups."
 (defcustom gnus-large-newsgroup 200
   "*The number of articles which indicates a large newsgroup.
 If the number of articles in a newsgroup is greater than this value,
-confirmation is required for selecting the newsgroup."
+confirmation is required for selecting the newsgroup.
+If it is `nil', no confirmation is required."
   :group 'gnus-group-select
   :type 'integer)
 
@@ -1374,7 +1371,7 @@ slower."
     ("nnspool" post address)
     ("nnvirtual" post-mail virtual prompt-address)
     ("nnmbox" mail respool address)
-    ("nnml" mail respool address)
+    ("nnml" post-mail respool address)
     ("nnmh" mail respool address)
     ("nndir" post-mail prompt-address physical-address)
     ("nneething" none address prompt-address physical-address)
@@ -1388,6 +1385,7 @@ slower."
     ("nnweb" none)
     ("nnslashdot" post)
     ("nnultimate" none)
+    ("nnrss" none)
     ("nnwfm" none)
     ("nnwarchive" none)
     ("nnlistserv" none)
@@ -1457,14 +1455,18 @@ to be desirable; see the manual for further details."
   :type '(choice (const nil)
                 integer))
 
+;; There should be special validation for this.
+(define-widget 'gnus-email-address 'string
+  "An email address")
+
 (gnus-define-group-parameter
  to-address
  :function-document
  "Return GROUP's to-address."
  :variable-document
 "*Alist of group regexps and correspondent to-addresses."
 :parameter-type '(gnus-email-address :tag "To Address")
 :parameter-document "\
+ "*Alist of group regexps and correspondent to-addresses."
+ :parameter-type '(gnus-email-address :tag "To Address")
+ :parameter-document "\
 This will be used when doing followups and posts.
 
 This is primarily useful in mail groups that represent closed
@@ -1509,15 +1511,15 @@ address was listed in gnus-group-split Addresses (see below).")
  :variable gnus-auto-expirable-newsgroups
  :variable-default nil
  :variable-document
 "*Groups in which to automatically mark read articles as expirable.
+ "*Groups in which to automatically mark read articles as expirable.
 If non-nil, this should be a regexp that should match all groups in
 which to perform auto-expiry.  This only makes sense for mail groups."
 :variable-group nnmail-expire
 :variable-type '(choice (const nil)
-                         regexp)
 :parameter-type '(const :tag "Automatic Expire" t)
 :parameter-document
 "All articles that are read will be marked as expirable.")
+ :variable-group nnmail-expire
+ :variable-type '(choice (const nil)
+                        regexp)
+ :parameter-type '(const :tag "Automatic Expire" t)
+ :parameter-document
+ "All articles that are read will be marked as expirable.")
 
 (gnus-define-group-parameter
  total-expire
@@ -1533,12 +1535,12 @@ Use with extreme caution.  All groups that match this regexp will be
 expiring - which means that all read articles will be deleted after
 \(say) one week.        (This only goes for mail groups and the like, of
 course.)"
 :variable-group nnmail-expire
 :variable-type '(choice (const nil)
-                         regexp)
 :parameter-type '(const :tag "Total Expire" t)
 :parameter-document
 "All read articles will be put through the expiry process
+ :variable-group nnmail-expire
+ :variable-type '(choice (const nil)
+                        regexp)
+ :parameter-type '(const :tag "Total Expire" t)
+ :parameter-document
+ "All read articles will be put through the expiry process
 
 This happens even if they are not marked as expirable.
 Use with caution.")
@@ -1548,7 +1550,7 @@ Use with caution.")
  :function-document
  "Return the default charset of GROUP."
  :variable gnus-group-charset-alist
- :variable-default 
+ :variable-default
  '(("\\(^\\|:\\)hk\\>\\|\\(^\\|:\\)tw\\>\\|\\<big5\\>" cn-big5)
    ("\\(^\\|:\\)cn\\>\\|\\<chinese\\>" cn-gb-2312)
    ("\\(^\\|:\\)fj\\>\\|\\(^\\|:\\)japan\\>" iso-2022-jp-2)
@@ -1563,14 +1565,36 @@ Use with caution.")
    ("\\(^\\|:\\)\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)
    (".*" iso-8859-1))
  :variable-document
 "Alist of regexps (to match group names) and default charsets to be used when reading."
 :variable-group gnus-charset
 :variable-type '(repeat (list (regexp :tag "Group")
-                               (symbol :tag "Charset")))
 :parameter-type '(symbol :tag "Charset")
 :parameter-document "\
+ "Alist of regexps (to match group names) and default charsets to be used when reading."
+ :variable-group gnus-charset
+ :variable-type '(repeat (list (regexp :tag "Group")
+                              (symbol :tag "Charset")))
+ :parameter-type '(symbol :tag "Charset")
+ :parameter-document "\
 The default charset to use in the group.")
 
+(gnus-define-group-parameter
+ post-method
+ :type list
+ :function-document
+ "Return a posting method for GROUP."
+ :variable gnus-post-method-alist
+ :variable-document
+ "Alist of regexps (to match group names) and method to be used when
+posting an article."
+ :variable-group gnus-group-foreign
+ :parameter-type
+ '(choice :tag "Posting Method"
+         (const nil)
+         (const current)
+         (const native)
+         (list :convert-widget
+               (lambda (widget)
+                 (list 'sexp :tag "Methods"
+                       :value gnus-select-method))))
+ :parameter-document
+ "Posting method for this 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
@@ -1746,7 +1770,7 @@ covered by that variable."
       ,(nnheader-concat gnus-cache-directory "active"))))
   "List of predefined (convenience) servers.")
 
-(defvar gnus-topic-indentation "");; Obsolete variable.
+(defvar gnus-topic-indentation "") ;; Obsolete variable.
 
 (defconst gnus-article-mark-lists
   '((marked . tick) (replied . reply)
@@ -1754,7 +1778,8 @@ covered by that variable."
     (bookmarks . bookmark) (dormant . dormant)
     (scored . score) (saved . save)
     (cached . cache) (downloadable . download)
-    (unsendable . unsend)))
+    (unsendable . unsend) (forwarded . forward)
+    (recent . recent)))
 
 (defvar gnus-headers-retrieved-by nil)
 (defvar gnus-article-reply nil)
@@ -1771,10 +1796,10 @@ covered by that variable."
   "The mail address of the Gnus maintainers.")
 
 (defvar gnus-info-nodes
-  '((gnus-group-mode "(gnus)The Group Buffer")
-    (gnus-summary-mode "(gnus)The Summary Buffer")
-    (gnus-article-mode "(gnus)The Article Buffer")
-    (gnus-server-mode "(gnus)The Server Buffer")
+  '((gnus-group-mode "(gnus)Group Buffer")
+    (gnus-summary-mode "(gnus)Summary Buffer")
+    (gnus-article-mode "(gnus)Article Buffer")
+    (gnus-server-mode "(gnus)Server Buffer")
     (gnus-browse-mode "(gnus)Browse Foreign Server")
     (gnus-tree-mode "(gnus)Tree Display"))
   "Alist of major modes and related Info nodes.")
@@ -2034,7 +2059,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
 ;;; gnus-sum.el thingies
 
 
-(defcustom gnus-summary-line-format "%U%R%z%I%(%[%4L: %-20,20n%]%) %s\n"
+(defcustom gnus-summary-line-format "%U%R%z%I%(%[%4L: %-23,23n%]%) %s\n"
   "*The format specification of the lines in the summary buffer.
 
 It works along the same lines as a normal formatting string,
@@ -2051,11 +2076,14 @@ with some simple extensions.
 %x   Contents of the Xref: header (string)
 %D   Date of the article (string)
 %d   Date of the article (string) in DD-MMM format
+%o   Date of the article (string) in YYYYMMDD`T'HHMMSS format
 %M   Message-id of the article (string)
 %r   References of the article (string)
 %c   Number of characters in the article (integer)
 %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)
+     The variables `gnus-sum-thread-*' can be used for customization.
 %T   A string with two possible values: 80 spaces if the article
      is on thread level two or larger and 0 spaces on level one
 %R   \"A\" if this article has been replied to, \" \" otherwise (character)
@@ -2090,7 +2118,7 @@ it is invalid to have these specs after a variable-length spec.    Well,
 you might not be arrested, but your summary buffer will look strange,
 which is bad enough.
 
-The smart choice is to have these specs as for to the left as
+The smart choice is to have these specs as far to the left as
 possible.
 
 This restriction may disappear in later versions of Gnus."
@@ -2313,12 +2341,12 @@ If ARG, insert string at point."
                   minor least)
         (format "%d.%02d%02d" major minor least))))))
 
-(defun gnus-info-find-node ()
+(defun gnus-info-find-node (&optional nodename)
   "Find Info documentation of Gnus."
   (interactive)
   ;; Enlarge info window if needed.
   (let (gnus-info-buffer)
-    (Info-goto-node (cadr (assq major-mode gnus-info-nodes)))
+    (Info-goto-node (or nodename (cadr (assq major-mode gnus-info-nodes))))
     (setq gnus-info-buffer (current-buffer))
     (gnus-configure-windows 'info)))
 
@@ -2419,8 +2447,8 @@ g -- Group name."
        out)
       (cond
        ((= c ?r)
-       (push (if (< (point) (mark) (point) (mark))) out)
-       (push (if (> (point) (mark) (point) (mark))) out))))
+       (push (if (< (point) (mark)) (point) (mark)) out)
+       (push (if (> (point) (mark)) (point) (mark)) out))))
     (setq out (delq 'gnus-prefix-nil out))
     (nreverse out)))
 
@@ -2736,22 +2764,27 @@ You should probably use `gnus-find-method-for-group' instead."
 
 (defun gnus-parameters-get-parameter (group)
   "Return the group parameters for GROUP from `gnus-parameters'."
-  (let ((alist gnus-parameters)
-       params-list)
-    (while alist
-      (when (string-match (caar alist) group)
-       (setq params-list 
-             (nconc (copy-sequence (cdar alist))
-                    params-list)))
-      (pop alist))
+  (let (params-list)
+    (dolist (elem gnus-parameters)
+      (when (string-match (car elem) group)
+       (setq params-list
+             (nconc (gnus-expand-group-parameters
+                     (copy-sequence (cdr elem)) group)
+                    params-list))))
     params-list))
 
+(defun gnus-expand-group-parameters (parameters group)
+  "Go through PARAMETERS and expand them according to the match data."
+  (dolist (elem parameters)
+    (when (stringp (cdr elem))
+      (setcdr elem (replace-match (cdr elem) nil nil group)))))
+
 (defun gnus-group-find-parameter (group &optional symbol allow-list)
   "Return the group parameters for GROUP.
 If SYMBOL, return the value of that symbol in the group parameters."
   (save-excursion
     (set-buffer gnus-group-buffer)
-    (let ((parameters 
+    (let ((parameters
           (nconc
            (copy-sequence
             (funcall gnus-group-get-parameter-function group))
@@ -2843,7 +2876,7 @@ just the host name."
                               depth (+ depth 1)))
                       depth))))
     ;; Separate foreign select method from group name and collapse.
-    ;; If method contains a server, collapse to non-domain server name,
+   ;; If method contains a server, collapse to non-domain server name,
     ;; otherwise collapse to select method.
     (let* ((colon (string-match ":" group))
           (server (and colon (substring group 0 colon)))
@@ -2990,12 +3023,21 @@ If NEWSGROUP is nil, return the global kill file name instead."
          (list (intern server) "")))
     gnus-select-method))
 
+(defun gnus-server-string (server)
+  "Return a readable string that describes SERVER."
+  (let* ((server (gnus-server-to-method server))
+        (address (nth 1 server)))
+    (if (and address
+            (not (zerop (length address))))
+       (format "%s via %s" address (car server))
+      (format "%s" (car server)))))
+
 (defun gnus-find-method-for-group (group &optional info)
   "Find the select method that GROUP uses."
   (or gnus-override-method
       (and (not group)
           gnus-select-method)
-      (and (not (gnus-group-entry group));; a new group
+      (and (not (gnus-group-entry group)) ;; a new group
           (gnus-group-name-to-method group))
       (let ((info (or info (gnus-get-info group)))
            method)
@@ -3045,7 +3087,7 @@ Disallow invalid group names."
 (defun gnus-read-method (prompt)
   "Prompt the user for a method.
 Allow completion over sensible values."
-  (let* ((open-servers 
+  (let* ((open-servers
          (mapcar (lambda (i) (cons (format "%s:%s" (caar i) (cadar i)) i))
                  gnus-opened-servers))
         (valid-methods
@@ -3111,8 +3153,8 @@ As opposed to `gnus', this command will not connect to the local server."
   (let ((window (get-buffer-window gnus-group-buffer)))
     (cond (window
           (select-frame (window-frame window)))
-         (t
-          (select-frame (make-frame)))))
+         (t
+          (select-frame (make-frame)))))
   (gnus arg))
 
 ;;(setq thing ?                                ; this is a comment