*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Wed, 5 Mar 1997 01:23:33 +0000 (01:23 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Wed, 5 Mar 1997 01:23:33 +0000 (01:23 +0000)
24 files changed:
lisp/ChangeLog
lisp/article.el
lisp/custom-edit.el
lisp/custom-opt.el [new file with mode: 0644]
lisp/custom.el
lisp/gnus-art.el
lisp/gnus-cache.el
lisp/gnus-cite.el
lisp/gnus-nocem.el
lisp/gnus-score.el
lisp/gnus-start.el
lisp/gnus-sum.el
lisp/gnus-topic.el
lisp/gnus-util.el
lisp/gnus.el
lisp/nnfolder.el
lisp/nntp.el
lisp/nnvirtual.el
lisp/widget-edit.el
lisp/widget.el
texi/ChangeLog
texi/custom.texi
texi/gnus.texi
texi/widget.texi

index 5ff1ebc..405d912 100644 (file)
@@ -1,3 +1,93 @@
+Fri Dec 13 04:49:21 1996  Andre Deparade  <deparade@i3.informatik.rwth-aachen.de>
+
+       * gnus-cite.el (gnus-cited-text-button-line-format-alist): Make %b
+       and %e usable.
+
+Fri Dec 13 01:06:09 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * article.el (article-decode-rfc1522): Would collate subsequent
+       encodings. 
+
+       * gnus-start.el (gnus-check-bogus-newsgroups): Use
+       `map-y-or-n-p'. 
+
+       * gnus-topic.el (gnus-topic-kill-group): Save topic contents.
+       (gnus-topic-yank-group): Insert topic contents.
+
+       * gnus-sum.el (gnus-simplify-subject-fuzzy-regexp): Changed
+       default to "".
+
+       * gnus-score.el (gnus-score-find-favourite-words): Put point at bob.
+
+       * gnus-sum.el (gnus-summary-limit-to-age): Dox fix & interactive
+       spec. 
+
+Fri Dec 13 01:01:46 1996  David Moore  <dmoore@ucsd.edu>
+
+       * gnus-sum.el (gnus-summary-limit-to-age): New function and
+       keystroke. 
+
+Tue Dec 10 23:42:00 1996  David Moore  <dmoore@ucsd.edu>
+
+       * gnus-nocem.el (gnus-nocem-groups): news.lists.filters is to
+       replace alt.nocem.misc
+
+Wed Dec 11 01:15:31 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * nnfolder.el (nnfolder-request-expire-articles): Better message.
+       (nnfolder-delete-mail): Actually delete.
+
+       * gnus-sum.el (gnus-summary-update-info): Don't run
+       `gnus-exit-group-hook'. 
+       (gnus-summary-expire-articles): Do it.
+       (gnus-summary-exit): Ditto.
+       (gnus-summary-save-newsrc): New command and keystroke.
+
+Wed Dec 11 00:38:12 1996  Stainless Steel Rat  <ratinox@peorth.gweep.net>
+
+       * gnus-sum.el (gnus-simplify-buffer-fuzzy): New version.
+
+Mon Dec  9 21:00:09 1996  David Moore  <dmoore@ucsd.edu>
+
+       * gnus-sum.el (gnus-summary-catchup): Out dated catchup code
+       removed.
+
+       * nnvirtual.el (nnvirtual-update-read-and-marked): Work around a
+       cache of active count in gnus-update-read-articles.
+
+Mon Dec  9 22:55:56 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * article.el (article-emphasize): Use it.
+
+       * gnus-util.el (gnus-put-text-property-excluding-newlines): New
+       function. 
+
+Mon Dec  9 08:38:08 1996  Per Abrahamsen  <abraham@dina.kvl.dk>
+
+       * gnus-sum.el: Split customize groups and added links to the manual.
+
+1996-12-08  Dave Love  <d.love@dl.ac.uk>
+
+       * gnus-vis.el (gnus-button-alist): Allow whitespace in `<URL:...'
+       markup (rfc1738), done last, after possible partial matches.
+       (gnus-button-url): Zap any whitespace from a <URL:...> match.
+
+Mon Dec  9 02:18:35 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus-art.el (gnus-button-embedded-url): New function.
+       (gnus-button-alist): Use it.
+
+       * gnus-util.el (gnus-strip-whitespace): New function.
+
+Mon Dec  9 00:04:24 1996  Richard Stallman  <rms@gnu.ai.mit.edu>
+
+       * gnus-start.el (gnus-read-init-file): Don't read init file when
+       started with "emacs -q".
+
+Sun Dec  8 18:25:34 1996  Lars Magne Ingebrigtsen  <menja.larsi@ifi.uio.no>
+
+       * gnus.el: Red Gnus v0.74 is released.
+
 Fri Dec  6 12:47:24 1996  Wes Hardaker  <Wesley.Hardaker@sphys.unil.ch>
 
        * gnus-picon.el (gnus-picons-insert-face-if-exists): Don't reverse
index 1576622..805f5ab 100644 (file)
@@ -533,8 +533,6 @@ always hide."
           (goto-char (point-min)) (point-max))
          (subst-char-in-region (point-min) (point-max) ?_ ? )
          (goto-char (point-max)))
-       (when (looking-at "\\([ \t\n]+\\)=\\?")
-         (replace-match "" t t nil 1))
        (goto-char (point-min))))))
 
 (defun article-de-quoted-unreadable (&optional force)
@@ -957,7 +955,7 @@ function and want to see what the date was before converting."
               (match-beginning invisible) (match-end invisible) props)
              (article-unhide-text-type
               (match-beginning visible) (match-end visible) 'emphasis)
-             (put-text-property 
+             (gnus-put-text-property-excluding-newlines
               (match-beginning visible) (match-end visible) 'face face)
              (goto-char (match-end invisible)))))))))
 
index c3ce9f0..31752e8 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, faces
-;; Version: 1.04
+;; Version: 1.12
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
@@ -17,7 +17,7 @@
 (require 'widget-edit)
 (require 'easymenu)
 
-(define-widget-keywords :custom-show :custom-magic
+(define-widget-keywords :custom-menu :custom-show :custom-magic
   :custom-state :custom-level :custom-form
   :custom-apply :custom-set-default :custom-reset)
 
@@ -50,6 +50,44 @@ IF REGEXP is not a string, return it unchanged."
        (nreverse (cons (substring regexp start) all)))
     regexp))
 
+(defvar custom-prefix-list nil
+  "List of prefixes that should be ignored by `custom-unlispify'")
+
+(defcustom custom-unlispify-menu-entries t
+  "Display menu entries as words instead of symbols if non nil."
+  :group 'customize
+  :type 'boolean)
+
+(defun custom-unlispify-menu-entry (symbol &optional no-suffix)
+  "Convert symbol into a menu entry."
+  (cond ((not custom-unlispify-menu-entries)
+        (symbol-name symbol))
+       ((get symbol 'custom-tag)
+        (if no-suffix
+            (get symbol 'custom-tag)
+          (concat (get symbol 'custom-tag) "...")))
+       (t
+        (save-excursion
+          (set-buffer (get-buffer-create " *Custom-Work*"))
+          (erase-buffer)
+          (princ symbol (current-buffer))
+          (goto-char (point-min))
+          (let ((prefixes custom-prefix-list)
+                prefix)
+            (while prefixes
+              (setq prefix (car prefixes))
+              (if (search-forward prefix (+ (point) (length prefix)) t)
+                  (progn 
+                    (setq prefixes nil)
+                    (delete-region (point-min) (point)))
+                (setq prefixes (cdr prefixes)))))
+          (subst-char-in-region (point-min) (point-max) ?- ?\  t)
+          (capitalize-region (point-min) (point-max))
+          (unless no-suffix 
+            (goto-char (point-max))
+            (insert "..."))
+          (buffer-string)))))
+
 ;;; The Custom Mode.
 
 (defvar custom-options nil
@@ -71,6 +109,11 @@ IF REGEXP is not a string, return it unchanged."
       ["Reset" custom-reset t]
       ["Save" custom-save t]))
 
+(defcustom custom-mode-hook nil
+  "Hook called when entering custom-mode."
+  :type 'hook
+  :group 'customize)
+
 (defun custom-mode ()
   "Major mode for editing customization buffers.
 
@@ -528,6 +571,23 @@ The list should be sorted most significant first."
          (t
           (funcall show widget value)))))
 
+(defun custom-load-symbol (symbol)
+  "Load all dependencies for SYMBOL."
+  (let ((loads (get symbol 'custom-loads))
+       load)
+    (while loads
+      (setq load (car loads)
+           loads (cdr loads))
+      (cond ((symbolp load)
+            (require load))
+           ((member load load-history))
+           (t
+            (load-library load))))))
+
+(defun custom-load-widget (widget)
+  "Load all dependencies for WIDGET."
+  (custom-load-symbol (widget-value widget)))
+
 ;;; The `custom-variable' Widget.
 
 (define-widget 'custom-variable 'custom
@@ -536,6 +596,7 @@ The list should be sorted most significant first."
   :help-echo "Push me to set or reset this variable."
   :documentation-property 'variable-documentation
   :custom-state nil
+  :custom-menu 'custom-variable-menu-create
   :custom-form 'edit
   :value-create 'custom-variable-value-create
   :action 'custom-variable-action
@@ -545,6 +606,7 @@ The list should be sorted most significant first."
 
 (defun custom-variable-value-create (widget)
   "Here is where you edit the variables value."
+  (custom-load-widget widget)
   (let* ((buttons (widget-get widget :buttons))
         (children (widget-get widget :children))
         (form (widget-get widget :custom-form))
@@ -570,7 +632,8 @@ The list should be sorted most significant first."
           (setq state 'hidden)))
     ;; If we don't know the state, see if we need to edit it in lisp form.
     (when (eq state 'unknown)
-      (unless (widget-apply (widget-convert type) :match value)
+      (unless (widget-apply conv :match value)
+       ;; (widget-apply (widget-convert type) :match value)
        (setq form 'lisp)))
     ;; Now we can create the child widget.
     (cond ((eq state 'hidden)
@@ -597,6 +660,7 @@ The list should be sorted most significant first."
                   children)))
          (t
           ;; Edit mode.
+
           (push (widget-create-child-and-convert widget type 
                                                  :tag (symbol-name symbol)
                                                  :value value)
@@ -614,7 +678,9 @@ The list should be sorted most significant first."
 (defun custom-variable-state-set (widget)
   "Set the state of WIDGET."
   (let* ((symbol (widget-value widget))
-        (value (default-value symbol))
+        (value (if (default-boundp symbol)
+                   (default-value symbol)
+                 (widget-get widget :value)))
         (state (if (get symbol 'saved-value)
                    (if (condition-case nil
                            (equal value
@@ -800,7 +866,8 @@ Optional EVENT is the location for the menu."
   :action 'custom-face-action
   :custom-apply 'custom-face-apply
   :custom-set-default 'custom-face-set-default
-  :custom-reset 'custom-redraw)
+  :custom-reset 'custom-redraw
+  :custom-menu 'custom-face-menu-create)
 
 (defun custom-face-format-handler (widget escape)
   ;; We recognize extra escape sequences.
@@ -808,6 +875,10 @@ Optional EVENT is the location for the menu."
        (state (widget-get widget :custom-state))
        (symbol (widget-get widget :value)))
     (cond ((eq escape ?s)
+          (and (string-match "XEmacs" emacs-version)
+               ;; XEmacs cannot display initialized faces.
+               (not (custom-facep symbol))
+               (copy-face 'custom-face-empty symbol))
           (setq child (widget-create-child-and-convert 
                        widget 'custom-level
                        :format "(%[%t%])\n"
@@ -824,6 +895,7 @@ Optional EVENT is the location for the menu."
   (unless (eq (preceding-char) ?\n)
     (insert "\n"))
   (when (not (eq (widget-get widget :custom-state) 'hidden))
+    (custom-load-widget widget)
     (let* ((symbol (widget-value widget))
           (edit (widget-create-child-and-convert
                  widget 'editable-list
@@ -970,7 +1042,9 @@ Optional EVENT is the location for the menu."
 (defun custom-hook-convert-widget (widget)
   ;; Handle `:custom-options'.
   (let* ((options (widget-get widget :options))
-        (other `(editable-list :inline t (function :format "%v")))
+        (other `(editable-list :inline t 
+                               :entry-format "%i %d%v"
+                               (function :format " %v")))
         (args (if options
                   (list `(checklist :inline t
                                     ,@(mapcar (lambda (entry)
@@ -992,15 +1066,17 @@ Optional EVENT is the location for the menu."
   :action 'custom-group-action
   :custom-apply 'custom-group-apply
   :custom-set-default 'custom-group-set-default
-  :custom-reset 'custom-group-reset)
+  :custom-reset 'custom-group-reset
+  :custom-menu 'custom-group-menu-create)
 
 (defun custom-group-value-create (widget)
-  (let* ((state (widget-get widget :custom-state))
-        (level (widget-get widget :custom-level))
-        (symbol (widget-value widget))
-        (members (get symbol 'custom-group)))
+  (let ((state (widget-get widget :custom-state)))
     (unless (eq state 'hidden)
-      (let* ((children (mapcar (lambda (entry)
+      (custom-load-widget widget)
+      (let* ((level (widget-get widget :custom-level))
+            (symbol (widget-value widget))
+            (members (get symbol 'custom-group))
+            (children (mapcar (lambda (entry)
                                 (widget-insert "\n")
                                 (prog1
                                     (widget-create-child-and-convert
@@ -1162,6 +1238,123 @@ Leave point at the location of the call, or after the last expression."
     (set-buffer (find-file-noselect custom-file))
     (save-buffer)))
 
+;;; The Customize Menu.
+
+(defcustom custom-menu-nesting 2
+  "Maximum nesting in custom menus."
+  :type 'integer
+  :group 'customize)
+
+(defun custom-face-menu-create (widget symbol)
+  "Ignoring WIDGET, create a menu entry for customization face SYMBOL."
+  (vector (custom-unlispify-menu-entry symbol)
+         `(custom-buffer-create '((,symbol custom-face)))
+         t))
+
+(defun custom-variable-menu-create (widget symbol)
+  "Ignoring WIDGET, create a menu entry for customization variable SYMBOL."
+  (let ((type (get symbol 'custom-type)))
+    (unless (listp type)
+      (setq type (list type)))
+    (if (and type (widget-get type :custom-menu))
+       (widget-apply type :custom-menu symbol)
+      (vector (custom-unlispify-menu-entry symbol)
+             `(custom-buffer-create '((,symbol custom-variable)))
+             t))))
+
+(widget-put (get 'boolean 'widget-type)
+           :custom-menu (lambda (widget symbol)
+                          (vector (custom-unlispify-menu-entry symbol)
+                                  `(custom-buffer-create
+                                    '((,symbol custom-variable)))
+                                  ':style 'toggle
+                                  ':selected symbol)))
+
+(defun custom-group-menu-create (widget symbol)
+  "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
+  (custom-menu-create symbol))
+
+(defun custom-menu-create (symbol &optional name)
+  "Create menu for customization group SYMBOL.
+If optional NAME is given, use that as the name of the menu. 
+Otherwise make up a name from SYMBOL.
+The menu is in a format applicable to `easy-menu-define'."
+  (unless name
+    (setq name (custom-unlispify-menu-entry symbol)))
+  (let ((item (vector name
+                     `(custom-buffer-create '((,symbol custom-group)))
+                     t)))
+    (if (> custom-menu-nesting 0)
+       (let ((custom-menu-nesting (1- custom-menu-nesting))
+             (custom-prefix-list (cons (or (get symbol 'custom-prefix)
+                                           (concat (symbol-name symbol) "-"))
+                                       custom-prefix-list)))
+         (custom-load-symbol symbol)
+         `(,(custom-unlispify-menu-entry symbol t)
+           ,item
+           "--"
+           ,@(mapcar (lambda (entry)
+                       (widget-apply (if (listp (nth 1 entry))
+                                         (nth 1 entry)
+                                       (list (nth 1 entry)))
+                                     :custom-menu (nth 0 entry)))
+                     (get symbol 'custom-group))))
+      item)))
+
+;;;###autoload
+(defun custom-menu-update ()
+  "Update customize menu."
+  (interactive)
+  (add-hook 'custom-define-hook 'custom-menu-reset)
+  (let ((menu `(,(car custom-help-menu)
+               ,(widget-apply '(custom-group) :custom-menu 'emacs)
+               ,@(cdr (cdr custom-help-menu)))))
+    (if (fboundp 'add-submenu)
+       (add-submenu '("Help") menu)
+      (define-key global-map [menu-bar help-menu customize-menu]
+       (cons (car menu) (easy-menu-create-keymaps (car menu) (cdr menu)))))))
+
+;;; Dependencies.
+
+;;;###autoload
+(defun custom-make-dependencies ()
+  "Batch function to extract custom dependencies from .el files.
+Usage: emacs -batch *.el -f custom-make-dependencies > deps.el"
+  (let ((buffers (buffer-list)))
+    (while buffers
+      (set-buffer (car buffers))
+      (setq buffers (cdr buffers))
+      (let ((file (buffer-file-name)))
+       (when (and file (string-match "\\`\\(.*\\)\\.el\\'" file))
+         (goto-char (point-min))
+         (condition-case nil
+             (let ((name (file-name-nondirectory (match-string 1 file))))
+               (while t
+                 (let ((expr (read (current-buffer))))
+                   (when (and (listp expr)
+                              (memq (car expr) '(defcustom defface defgroup)))
+                     (eval expr)
+                     (put (nth 1 expr) 'custom-where name)))))
+           (error nil))))))
+  (mapatoms (lambda (symbol)
+             (let ((members (get symbol 'custom-group))
+                   item where found)
+               (when members
+                 (princ "(put '")
+                 (princ symbol)
+                 (princ " 'custom-loads '(")
+                 (while members
+                   (setq item (car (car members))
+                         members (cdr members)
+                         where (get item 'custom-where))
+                   (unless (or (null where)
+                               (member where found))
+                     (when found
+                       (princ " "))
+                     (prin1 where)
+                     (push where found)))
+                 (princ "))\n"))))))
+
 ;;; The End.
 
 (provide 'custom-edit)
diff --git a/lisp/custom-opt.el b/lisp/custom-opt.el
new file mode 100644 (file)
index 0000000..c39a55c
--- /dev/null
@@ -0,0 +1,45 @@
+;;; custom-opt.el --- An option group.
+;;
+;; Copyright (C) 1996 Free Software Foundation, Inc.
+;;
+;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
+;; Keywords: help, faces
+;; Version: 1.12
+;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
+
+;;; Code:
+
+(require 'custom)
+
+(defgroup options nil
+  "This group contains often used customization options."
+  :group 'emacs)
+
+(defvar custom-options 
+  '((line-number-mode boolean)
+    (column-number-mode boolean)
+    (debug-on-error boolean)
+    (debug-on-quit boolean)
+    (case-fold-search boolean)
+    (case-replace boolean)
+    (transient-mark-mode boolean))
+  "Alist of customization options.
+The first element of each entry should be a variable name, the second
+a widget type.")
+
+(let ((options custom-options)
+      option name type)
+  (while options
+    (setq option (car options)
+         options (cdr options)
+         name (nth 0 option)
+         type (nth 1 option))
+    (put name 'custom-type type)
+    (custom-add-to-group 'options name 'custom-variable))
+  (run-hooks 'custom-define-hook))
+
+;;; The End.
+
+(provide 'custom-opt)
+
+;; custom-edit.el ends here
index 56c874a..7e0c299 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, faces
-;; Version: 1.04
+;; Version: 1.12
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
@@ -19,7 +19,7 @@
 
 (require 'widget)
 
-(define-widget-keywords :link :options :type :group)
+(define-widget-keywords :prefix :tag :load :link :options :type :group)
 
 ;; These autoloads should be deleted when the file is added to Emacs
 (autoload 'customize "custom-edit" nil t)
@@ -28,6 +28,8 @@
 (autoload 'customize-apropos "custom-edit" nil t)
 (autoload 'customize-customized "custom-edit" nil t)
 (autoload 'custom-buffer-create "custom-edit")
+(autoload 'custom-menu-update "custom-edit")
+(autoload 'custom-make-dependencies "custom-edit")
 
 ;;; Compatibility.
 
@@ -74,7 +76,8 @@ If FRAME is omitted or nil, use the selected frame."
                             (list (cons 'background-mode mode)))
     mode))
 
-;; XEmacs and Emacs have two different definitions of `facep'.
+;; XEmacs and Emacs have different definitions of `facep'.  
+;; The Emacs definition is the useful one, so emulate that. 
 (cond ((not (fboundp 'facep))
        (defun custom-facep (face) 
         "No faces"
@@ -120,12 +123,9 @@ If FRAME is omitted or nil, use the selected frame."
                           value)
                 ;; Fast code for the common case.
                 (put symbol 'custom-options (copy-list value))))
-             ((eq keyword :group)
-              (custom-add-to-group value symbol 'custom-variable))
-             ((eq keyword :link)
-              (custom-add-link symbol value))
              (t
-              (error "Unknown keyword %s" keyword))))))
+              (custom-handle-keyword symbol keyword value
+                                     'custom-variable))))))
   (run-hooks 'custom-define-hook)
   symbol)
 
@@ -166,22 +166,7 @@ information."
        (custom-face-display-set face value))))
   (when doc
     (put face 'face-documentation doc))
-  (while args 
-    (let ((arg (car args)))
-      (setq args (cdr args))
-      (unless (symbolp arg)
-       (error "Junk in args %S" args))
-      (let ((keyword arg)
-           (value (car args)))
-       (unless args
-         (error "Keyword %s is missing an argument" :type))
-       (setq args (cdr args))
-       (cond ((eq keyword :group)
-              (custom-add-to-group value face 'custom-face))
-             ((eq keyword :link)
-              (custom-add-link face value))
-             (t
-              (error "Unknown keyword %s" face))))))
+  (custom-handle-all-keywords face args 'custom-face)
   (run-hooks 'custom-define-hook)
   face)
 
@@ -249,14 +234,13 @@ information."
       (let ((keyword arg)
            (value (car args)))
        (unless args
-         (error "Keyword %s is missing an argument" :type))
+         (error "Keyword %s is missing an argument" keyword))
        (setq args (cdr args))
-       (cond ((eq keyword :group)
-              (custom-add-to-group value symbol 'custom-group))
-             ((eq keyword :link)
-              (custom-add-link symbol value))
+       (cond ((eq keyword :prefix)
+              (put symbol 'custom-prefix value))
              (t
-              (error "Unknown keyword %s" symbol))))))
+              (custom-handle-keyword symbol keyword value
+                                     'custom-group))))))
   (run-hooks 'custom-define-hook)
   symbol)
 
@@ -297,6 +281,35 @@ If there already is an entry for that option, overwrite it."
 
 ;;; Properties.
 
+(defun custom-handle-all-keywords (symbol args type)
+  "For customization option SYMBOL, handle keyword arguments ARGS.
+Third argument TYPE is the custom option type."
+  (while args 
+    (let ((arg (car args)))
+      (setq args (cdr args))
+      (unless (symbolp arg)
+       (error "Junk in args %S" args))
+      (let ((keyword arg)
+           (value (car args)))
+       (unless args
+         (error "Keyword %s is missing an argument" keyword))
+       (setq args (cdr args))
+       (custom-handle-keyword symbol keyword value type)))))  
+
+(defun custom-handle-keyword (symbol keyword value type)
+  "For customization option SYMBOL, handle KEYWORD with VALUE.
+Fourth argument TYPE is the custom option type."
+  (cond ((eq keyword :group)
+        (custom-add-to-group value symbol type))
+       ((eq keyword :link)
+        (custom-add-link symbol value))
+       ((eq keyword :load)
+        (custom-add-load symbol value))
+       ((eq keyword :tag)
+        (put symbol 'custom-tag value))
+       (t
+        (error "Unknown keyword %s" symbol))))  
+
 (defun custom-add-option (symbol option)
   "To the variable SYMBOL add OPTION.
 
@@ -312,6 +325,13 @@ For other types variables, the effect is undefined."
     (unless (member widget links)
       (put symbol 'custom-links (cons widget links)))))
 
+(defun custom-add-load (symbol load)
+  "To the custom option SYMBOL add the dependency LOAD.
+LOAD should be either a library file name, or a feature name."
+  (let ((loads (get symbol 'custom-loads)))
+    (unless (member load loads)
+      (put symbol 'custom-loads (cons load loads)))))
+
 ;;; Face Utilities.
 
 (and (fboundp 'make-face)
@@ -526,6 +546,7 @@ See `defface' for the format of SPEC."
   :link '(custom-manual "(custom)Top")
   :link '(url-link :tag "Development Page" 
                   "http://www.dina.kvl.dk/~abraham/custom/")
+  :prefix "custom-"
   :group 'emacs)
 
 (defcustom custom-define-hook nil
@@ -535,32 +556,6 @@ See `defface' for the format of SPEC."
 
 ;;; Menu support
 
-(defcustom custom-menu-nesting 2
-  "Maximum nesting in custom menus."
-  :type 'integer
-  :group 'customize)
-
-(defun custom-menu-create-entry (entry)
-  "Create a easy menu entry for customization option ENTRY.
-
-ENTRY should be list whose first element is a symbol, and second
-element is a widget type used to customize the symbol.  The widget
-type `custom-group' is recognized, and will return a submenu
-specification containing the group members.
-
-The maximum nesting in the submenu is specified by `custom-menu-nesting'."
-  (let ((item (vector (symbol-name (nth 0 entry))
-                     `(custom-buffer-create (list (quote ,entry)))
-                     t)))
-    (if (and (> custom-menu-nesting 0)
-            (eq (nth 1 entry) 'custom-group))
-       (let ((custom-menu-nesting (1- custom-menu-nesting))
-             (symbol (nth 0 entry)))
-         `(,(symbol-name symbol)
-           ,item
-           ,@(mapcar 'custom-menu-create-entry (get symbol 'custom-group))))
-      item)))
-
 (defconst custom-help-menu '("Customize"
                             ["Update menu..." custom-menu-update t]
                             ["Group..." customize t]
@@ -580,18 +575,6 @@ The maximum nesting in the submenu is specified by `custom-menu-nesting'."
            (easy-menu-create-keymaps (car custom-help-menu)
                                      (cdr custom-help-menu))))))
 
-(defun custom-menu-update ()
-  "Update customize menu."
-  (interactive)
-  (add-hook 'custom-define-hook 'custom-menu-reset)
-  (let ((menu `(,(car custom-help-menu)
-               ,(custom-menu-create-entry '(emacs custom-group))
-               ,@(cdr (cdr custom-help-menu)))))
-    (if (fboundp 'add-submenu)
-       (add-submenu '("Help") menu)
-      (define-key global-map [menu-bar help-menu customize-menu]
-       (cons (car menu) (easy-menu-create-keymaps (car menu) (cdr menu)))))))
-
 (custom-menu-reset)
 
 ;;; The End.
index 1ea2d44..c84272f 100644 (file)
@@ -1504,9 +1504,8 @@ groups."
      gnus-button-message-id 3)
     ("\\(<URL: *\\)?mailto: *\\([^> \n\t]+\\)>?" 0 t gnus-url-mailto 2)
     ;; This is how URLs _should_ be embedded in text...
-    ("<URL: *\\([^\n\r>]*\\)>" 0 t gnus-button-url 1)
-    ;; Next regexp stolen from highlight-headers.el.
-    ;; Modified by Vladimir Alexiev.
+    ("<URL: *\\([^>]*\\)>" 0 t gnus-button-embedded-url 1)
+    ;; Raw URLs.
     (,gnus-button-url-regexp 0 t gnus-button-url 0))
   "Alist of regexps matching buttons in article bodies.
 
@@ -1828,9 +1827,7 @@ specified by `gnus-button-alist'."
           (inhibit-point-motion-hooks t)
           (fun (nth 3 entry))
           (args (mapcar (lambda (group)
-                          (let ((string (buffer-substring
-                                         (match-beginning group)
-                                         (match-end group))))
+                          (let ((string (match-string group)))
                             (gnus-set-text-properties
                              0 (length string) nil string)
                             string))
@@ -1958,6 +1955,10 @@ forbidden in URL encoding."
   "Browse ADDRESS."
   (funcall browse-url-browser-function address))
 
+(defun gnus-button-embedded-url (address)
+  "Browse ADDRESS."
+  (funcall browse-url-browser-function (gnus-strip-whitespace address)))
+
 ;;; Next/prev buttons in the article buffer.
 
 (defvar gnus-next-page-line-format "%{%(Next page...%)%}\n")
index 438bfd8..721b4ff 100644 (file)
@@ -90,7 +90,7 @@ variable to \"^nnml\"."
                 (not (eq gnus-use-cache 'passive))))
     (gnus-cache-read-active)))
 
-;; Complexities of byte-compiling makes this kludge necessary.  Eeek.
+;; Complexities of byte-compiling make this kludge necessary.  Eeek.
 (ignore-errors
   (gnus-add-shutdown 'gnus-cache-close 'gnus))
 
index 1a200ec..1da62e9 100644 (file)
@@ -264,8 +264,8 @@ This should make it easier to see who wrote what."
 ;; TAG: Is a Supercite tag, if any.
 
 (defvar gnus-cited-text-button-line-format-alist 
-  `((?b beg ?d)
-    (?e end ?d)
+  `((?b (marker-position beg) ?d)
+    (?e (marker-position end) ?d)
     (?l (- end beg) ?d)))
 (defvar gnus-cited-text-button-line-format-spec nil)
 
index 1b96b2c..d5b1f6a 100644 (file)
@@ -36,7 +36,7 @@
   :group 'gnus-score)
 
 (defcustom gnus-nocem-groups 
-  '("alt.nocem.misc" "news.admin.net-abuse.announce")
+  '("news.lists.filters" "alt.nocem.misc" "news.admin.net-abuse.announce")
   "List of groups that will be searched for NoCeM messages."
   :group 'gnus-nocem
   :type '(repeat (string :tag "Group")))
index dd82f1a..06d77bc 100644 (file)
@@ -2230,8 +2230,8 @@ SCORE is the score to add."
        (insert (format "%-5d: %s\n" (caar rules) (cdar rules)))
        (pop rules))
       (gnus-add-current-to-buffer-list)
-      (gnus-configure-windows 'score-words)
-      (goto-char (point-min)))))
+      (goto-char (point-min))
+      (gnus-configure-windows 'score-words))))
 
 (defun gnus-summary-rescore ()
   "Redo the entire scoring process in the current summary."
index 315f527..d12c188 100644 (file)
@@ -389,22 +389,24 @@ Can be used to turn version control on or off."
 ;; Suggested by Brian Edmonds <edmonds@cs.ubc.ca>.
 (defvar gnus-init-inhibit nil)
 (defun gnus-read-init-file (&optional inhibit-next)
-  (if gnus-init-inhibit
-      (setq gnus-init-inhibit nil)
-    (setq gnus-init-inhibit inhibit-next)
-    (let ((files (list gnus-site-init-file gnus-init-file))
-         file)
-      (while files
-       (and (setq file (pop files))
-            (or (and (file-exists-p file)
-                     ;; Don't try to load a directory.
-                     (not (file-directory-p file)))
-                (file-exists-p (concat file ".el"))
-                (file-exists-p (concat file ".elc")))
-            (condition-case var
-                (load file nil t)
-              (error
-               (error "Error in %s: %s" file var))))))))
+  ;; Don't load .gnus if -q option was used.
+  (when init-file-user
+    (if gnus-init-inhibit
+       (setq gnus-init-inhibit nil)
+      (setq gnus-init-inhibit inhibit-next)
+      (let ((files (list gnus-site-init-file gnus-init-file))
+           file)
+       (while files
+         (and (setq file (pop files))
+              (or (and (file-exists-p file)
+                       ;; Don't try to load a directory.
+                       (not (file-directory-p file)))
+                  (file-exists-p (concat file ".el"))
+                  (file-exists-p (concat file ".elc")))
+              (condition-case var
+                  (load file nil t)
+                (error
+                 (error "Error in %s: %s" file var)))))))))
 
 ;; For subscribing new newsgroup
 
@@ -1220,19 +1222,25 @@ newsgroup."
        (setq info (pop newsrc)
              group (gnus-info-group info))
        (unless (or (gnus-active group) ; Active
-                   (gnus-info-method info) ; Foreign
-                   (and confirm
-                        (not (gnus-y-or-n-p
-                              (format "Remove bogus newsgroup: %s " group)))))
+                   (gnus-info-method info)) ; Foreign
          ;; Found a bogus newsgroup.
          (push group bogus)))
-      ;; Remove all bogus subscribed groups by first killing them, and
-      ;; then removing them from the list of killed groups.
-      (while bogus
-       (when (setq entry (gnus-gethash (setq group (pop bogus))
-                                       gnus-newsrc-hashtb))
-         (gnus-group-change-level entry gnus-level-killed)
-         (setq gnus-killed-list (delete group gnus-killed-list))))
+      (if confirm
+         (map-y-or-n-p
+          "Remove bogus group %s? "
+          (lambda (group)
+            ;; Remove all bogus subscribed groups by first killing them, and
+            ;; then removing them from the list of killed groups.
+            (when (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+              (gnus-group-change-level entry gnus-level-killed)
+              (setq gnus-killed-list (delete group gnus-killed-list))))
+          bogus)
+       (while (setq group (pop bogus))
+         ;; Remove all bogus subscribed groups by first killing them, and
+         ;; then removing them from the list of killed groups.
+         (when (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+           (gnus-group-change-level entry gnus-level-killed)
+           (setq gnus-killed-list (delete group gnus-killed-list)))))
       ;; Then we remove all bogus groups from the list of killed and
       ;; zombie groups.  They are removed without confirmation.
       (let ((dead-lists '(gnus-killed-list gnus-zombie-list))
index e1c3bf4..879ef9d 100644 (file)
 (require 'gnus-int)
 (require 'gnus-undo)
 
+;; Belongs to to gnus.el
+(defgroup gnus-various nil
+  "Other Gnus options."
+  :link '(custom-manual "(gnus)Various Various")
+  :group 'gnus)
+
+;; Belongs to to gnus-group.el
+(defgroup gnus-group-select nil
+  "Selecting a Group."
+  :link '(custom-manual "(gnus)Selecting a Group")
+  :group 'gnus-group)
+
+;; Belongs to to gnus-uu.el
+(defgroup gnus-extract-view nil
+  "Viewing extracted files."
+  :link '(custom-manual "(gnus)Viewing Files")
+  :group 'gnus-extract)
+
+;; Belongs to article.el
+(defgroup article-hiding-headers nil
+  "Hiding headers in the article buffer."
+  :link '(custom-manual "(gnus)Hiding Headers")
+  :group 'article)
+
+(defgroup article-various nil
+  "Miscellaneous article options."
+  :link '(custom-manual "(gnus)Misc Article")
+  :group 'article)
+
+(defgroup article-mime nil
+  "Encoding articles and including attachments."
+  :link '(custom-manual "(gnus)Using MIME")
+  :group 'article)
+
+;; These belong here.
 (defgroup gnus-summary nil
   "Summary buffers."
+  :link '(custom-manual "(gnus)The Summary Buffer")
   :group 'gnus)
 
+(defgroup gnus-summary-exit nil
+  "Leaving summary buffers."
+  :link '(custom-manual "(gnus)Exiting the Summary Buffer")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-marks nil
+  "Marks used in summary buffers."
+  :link '(custom-manual "(gnus)Marking Articles")
+  :group 'gnus-summary)
+
+(defgroup gnus-thread nil
+  "Ordering articles according to replies."
+  :link '(custom-manual "(gnus)Threading")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-format nil
+  "Formatting of the summary buffer."
+  :link '(custom-manual "(gnus)Summary Buffer Format")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-choose nil
+  "Choosing Articles."
+  :link '(custom-manual "(gnus)Choosing Articles")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-maneuvering nil
+  "Summary movement commands."
+  :link '(custom-manual "(gnus)Summary Maneuvering")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-mail nil
+  "Mail group commands."
+  :link '(custom-manual "(gnus)Mail Group Commands")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-sort nil
+  "Sorting the summary buffer."
+  :link '(custom-manual "(gnus)Sorting")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-visual nil
+  "Highlighting and menus in the summary buffer."
+  :link '(custom-manual "(gnus)Summary Highlighting")
+  :group 'gnus-visual
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-various nil
+  "Various summary buffer options."
+  :link '(custom-manual "(gnus)Various Summary Stuff")
+  :group 'gnus-summary)
+
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
 If nil, the summary will become a \"*Dead Summary*\" buffer, and
 it will be killed sometime later."
-  :group 'gnus-summary
+  :group 'gnus-summary-exit
   :type 'boolean)
 
 (defcustom gnus-fetch-old-headers nil
@@ -55,7 +142,7 @@ This variable can also be a number.  In that case, no more than that
 number of old headers will be fetched.
 
 The server has to support NOV for any of this to work."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const some)
                 number
@@ -83,7 +170,7 @@ the parent and mark all the step-children as such.
 If this variable is `empty', the \"children\" are printed with empty
 subject fields.         (Or rather, they will be printed with a string
 given by the `gnus-summary-same-subject' variable.)"
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const none)
                 (const dummy)
@@ -95,7 +182,7 @@ given by the `gnus-summary-same-subject' variable.)"
 As loose thread gathering is done on subjects only, that means that
 there can be many false gatherings performed.  By rooting out certain
 common subjects, gathering might become saner."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type 'regexp)
 
 (defcustom gnus-summary-gather-subject-limit nil
@@ -108,14 +195,14 @@ same few characters will be incorrectly gathered.
 
 If this variable is `fuzzy', Gnus will use a fuzzy algorithm when
 comparing subjects."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const fuzzy)
                 (sexp :menu-tag "on" t)))
 
 (defcustom gnus-simplify-ignored-prefixes nil
   "*Regexp, matches for which are removed from subject lines when simplifying fuzzily."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 regexp))
 
@@ -124,7 +211,7 @@ comparing subjects."
 If `some', only fill in the gaps that are needed to tie loose threads
 together.  If `more', fill in all leaf nodes that Gnus can find.  If
 non-nil and non-`some', fill in all gaps that Gnus manages to guess."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const some)
                 (const more)
@@ -136,7 +223,7 @@ There are two pre-defined functions: `gnus-gather-threads-by-subject',
 which only takes Subjects into consideration; and
 `gnus-gather-threads-by-references', which compared the References
 headers of the articles to find matches."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(set (function-item gnus-gather-threads-by-subject)
              (function-item gnus-gather-threads-by-references)
              (function :tag "other")))
@@ -146,7 +233,7 @@ headers of the articles to find matches."
   "*String indicating that the current article has the same subject as the previous.
 This variable will only be used if the value of
 `gnus-summary-make-false-root' is `empty'."
-  :group 'gnus-summary
+  :group 'gnus-summary-format
   :type 'string)
 
 (defcustom gnus-summary-goto-unread t
@@ -154,7 +241,8 @@ This variable will only be used if the value of
 If `never', commands that usually go to the next unread article, will
 go to the next article, whether it is read or not.
 If nil, only the marking commands will go to the next (un)read article."
-  :group 'gnus-summary
+  :group 'gnus-summary-marks
+  :link '(custom-manual "(gnus)Setting Marks")
   :type '(choice (const :tag "off" nil)
                 (const never)
                 (sexp :menu-tag "on" t)))
@@ -162,7 +250,7 @@ If nil, only the marking commands will go to the next (un)read article."
 (defcustom gnus-summary-default-score 0
   "*Default article score level.
 If this variable is nil, scoring will be disabled."
-  :group 'gnus-summary
+  :group 'gnus-score
   :type '(choice (const :tag "disable")
                 integer))
 
@@ -170,20 +258,20 @@ If this variable is nil, scoring will be disabled."
   "*Fuzziness factor for the zcore in the summary buffer.
 Articles with scores closer than this to `gnus-summary-default-score'
 will not be marked."
-  :group 'gnus-summary
+  :group 'gnus-summary-format
   :type 'integer)
 
-(defcustom gnus-simplify-subject-fuzzy-regexp nil
+(defcustom gnus-simplify-subject-fuzzy-regexp ""
   "*Strings to be removed when doing fuzzy matches.
 This can either be a regular expression or list of regular expressions
 that will be removed from subject strings if fuzzy subject
 simplification is selected."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(repeat regexp))
 
 (defcustom gnus-show-threads t
   "*If non-nil, display threads in summary mode."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type 'boolean)
 
 (defcustom gnus-thread-hide-subtree nil
@@ -191,19 +279,19 @@ simplification is selected."
 If threads are hidden, you have to run the command
 `gnus-summary-show-thread' by hand or use `gnus-select-article-hook'
 to expose hidden threads."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type 'boolean)
 
 (defcustom gnus-thread-hide-killed t
   "*If non-nil, hide killed threads automatically."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type 'boolean)
 
 (defcustom gnus-thread-ignore-subject nil
   "*If non-nil, ignore subjects and do all threading based on the Reference header.
 If nil, which is the default, articles that have different subjects
 from their parents will start separate threads."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type 'boolean)
 
 (defcustom gnus-thread-operation-ignore-subject t
@@ -215,19 +303,19 @@ If this variable is nil, articles in the same thread with different
 subjects will not be included in the operation in question.  If this
 variable is `fuzzy', only articles that have subjects that are fuzzily
 equal will be included."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const fuzzy)
                 (sexp :tag "on" t)))
 
 (defcustom gnus-thread-indent-level 4
   "*Number that says how much each sub-thread should be indented."
-  :group 'gnus-summary
+  :group 'gnus-thread
   :type 'integer)
 
 (defcustom gnus-auto-extend-newsgroup t
   "*If non-nil, extend newsgroup forward and backward when requested."
-  :group 'gnus-summary
+  :group 'gnus-summary-choose
   :type 'boolean)
 
 (defcustom gnus-auto-select-first t
@@ -239,7 +327,7 @@ article.
 If you want to prevent automatic selection of the first unread article
 in some newsgroups, set the variable to nil in
 `gnus-select-group-hook'."
-  :group 'gnus-summary
+  :group 'gnus-group-select
   :type '(choice (const :tag "none" nil)
                 (const best)
                 (sexp :menu-tag "first" t)))
@@ -255,7 +343,7 @@ newsgroup will be selected without any confirmation, and if it is
 confirmation if you are located on the last article in the group.
 Finally, if this variable is `slightly-quietly', the `Z n' command
 will go to the next group without confirmation."
-  :group 'gnus-summary
+  :group 'gnus-summary-maneuvering
   :type '(choice (const :tag "off" nil)
                 (const quietly)
                 (const almost-quietly)
@@ -264,54 +352,54 @@ will go to the next group without confirmation."
 
 (defcustom gnus-auto-select-same nil
   "*If non-nil, select the next article with the same subject."
-  :group 'gnus-summary
+  :group 'gnus-summary-maneuvering
   :type 'boolean)
 
 (defcustom gnus-summary-check-current nil
   "*If non-nil, consider the current article when moving.
 The \"unread\" movement commands will stay on the same line if the
 current article is unread."
-  :group 'gnus-summary
+  :group 'gnus-summary-maneuvering
   :type 'boolean)
 
 (defcustom gnus-auto-center-summary t
   "*If non-nil, always center the current summary buffer.
 In particular, if `vertical' do only vertical recentering.  If non-nil
 and non-`vertical', do both horizontal and vertical recentering."
-  :group 'gnus-summary
+  :group 'gnus-summary-maneuvering
   :type '(choice (const :tag "none" nil)
                 (const vertical)
                 (sexp :menu-tag "both" t)))
 
 (defcustom gnus-show-all-headers nil
   "*If non-nil, don't hide any headers."
-  :group 'gnus-summary
+  :group 'article-hiding-headers
   :type 'boolean)
 
 (defcustom gnus-single-article-buffer t
   "*If non-nil, display all articles in the same buffer.
 If nil, each group will get its own article buffer."
-  :group 'gnus-summary
+  :group 'article-various
   :type 'boolean)
 
 (defcustom gnus-break-pages t
   "*If non-nil, do page breaking on articles.
 The page delimiter is specified by the `gnus-page-delimiter'
 variable."
-  :group 'gnus-summary
+  :group 'article-various
   :type 'boolean)
 
 (defcustom gnus-show-mime nil
   "*If non-nil, do mime processing of articles.
 The articles will simply be fed to the function given by
 `gnus-show-mime-method'."
-  :group 'gnus-summary
+  :group 'article-mime
   :type 'boolean)
 
 (defcustom gnus-move-split-methods nil
   "*Variable used to suggest where articles are to be moved to.
 It uses the same syntax as the `gnus-split-methods' variable."
-  :group 'gnus-summary
+  :group 'gnus-summary-mail
   :type '(repeat (choice (list function)
                         (cons regexp (repeat string))
                         sexp)))
@@ -319,10 +407,6 @@ It uses the same syntax as the `gnus-split-methods' variable."
 ;; Mark variables suggested by Thomas Michanek
 ;; <Thomas.Michanek@telelogic.se>.
 
-(defgroup gnus-summary-marks nil
-  "Marks used in summary buffers."
-  :group 'gnus-summary)
-
 (defcustom gnus-unread-mark ? 
   "*Mark used for unread articles."
   :group 'gnus-summary-marks
@@ -435,14 +519,14 @@ It uses the same syntax as the `gnus-split-methods' variable."
 
 (defcustom gnus-view-pseudo-asynchronously nil
   "*If non-nil, Gnus will view pseudo-articles asynchronously."
-  :group 'gnus-summary
+  :group 'gnus-extract-view
   :type 'boolean)
 
 (defcustom gnus-view-pseudos nil
   "*If `automatic', pseudo-articles will be viewed automatically.
 If `not-confirm', pseudos will be viewed automatically, and the user
 will not be asked to confirm the command."
-  :group 'gnus-summary
+  :group 'gnus-extract-view
   :type '(choice (const :tag "off" nil)
                 (const automatic)
                 (const not-confirm)))
@@ -451,12 +535,12 @@ will not be asked to confirm the command."
   "*If non-nil, one pseudo-article will be created for each file to be viewed.
 If nil, all files that use the same viewing command will be given as a
 list of parameters to that command."
-  :group 'gnus-summary
+  :group 'gnus-extract-view
   :type 'boolean)
 
 (defcustom gnus-insert-pseudo-articles t
   "*If non-nil, insert pseudo-articles when decoding articles."
-  :group 'gnus-summary
+  :group 'gnus-extract-view
   :type 'boolean)
 
 (defcustom gnus-summary-dummy-line-format
@@ -466,7 +550,7 @@ It works along the same lines as a normal formatting string,
 with some simple extensions.
 
 %S  The subject"
-  :group 'gnus-summary
+  :group 'gnus-threading
   :type 'string)
 
 (defcustom gnus-summary-mode-line-format "Gnus: %%b [%A] %Z"
@@ -488,20 +572,20 @@ with some simple extensions:
 %d  Number of dormant articles
 %r  Number of articles that have been marked as read in this session
 %E  Number of articles expunged by the score files"
-  :group 'gnus-summary
+  :group 'gnus-summary-format
   :type 'string)
 
 (defcustom gnus-summary-mark-below 0
   "*Mark all articles with a score below this variable as read.
 This variable is local to each summary buffer and usually set by the
 score file."
-  :group 'gnus-summary
+  :group 'gnus-score
   :type 'integer)
 
 (defcustom gnus-article-sort-functions '(gnus-article-sort-by-number)
   "*List of functions used for sorting articles in the summary buffer.
 This variable is only used when not using a threaded display."
-  :group 'gnus-summary
+  :group 'gnus-summary-sort
   :type '(repeat (choice (function-item gnus-article-sort-by-number)
                         (function-item gnus-article-sort-by-author)
                         (function-item gnus-article-sort-by-subject)
@@ -523,7 +607,7 @@ Ready-made functions include `gnus-thread-sort-by-number',
 `gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
 `gnus-thread-sort-by-date', `gnus-thread-sort-by-score' and
 `gnus-thread-sort-by-total-score' (see `gnus-thread-score-function')."
-  :group 'gnus-summary
+  :group 'gnus-summary-sort
   :type '(repeat (choice (function-item gnus-thread-sort-by-number)
                         (function-item gnus-thread-sort-by-author)
                         (function-item gnus-thread-sort-by-subject)
@@ -539,12 +623,12 @@ The function is called with the scores of the article and each
 subthread and should then return the score of the thread.
 
 Some functions you can use are `+', `max', or `min'."
-  :group 'gnus-summary
+  :group 'gnus-summary-sort
   :type 'function)
 
 (defcustom gnus-summary-expunge-below nil
   "All articles that have a score less than this variable will be expunged."
-  :group 'gnus-summary
+  :group 'gnus-score
   :type '(choice (const :tag "off" nil)
                 integer))
 
@@ -552,37 +636,38 @@ Some functions you can use are `+', `max', or `min'."
   "All threads that have a total score less than this variable will be expunged.
 See `gnus-thread-score-function' for en explanation of what a
 \"thread score\" is."
-  :group 'gnus-summary
+  :group 'gnus-treading
+  :group 'gnus-score
   :type '(choice (const :tag "off" nil)
                 integer))
 
 (defcustom gnus-summary-mode-hook nil
   "*A hook for Gnus summary mode.
 This hook is run before any variables are set in the summary buffer."
-  :group 'gnus-summary
+  :group 'gnus-summary-various
   :type 'hook)
 
 (defcustom gnus-summary-menu-hook nil
   "*Hook run after the creation of the summary mode menu."
-  :group 'gnus-summary
+  :group 'gnus-summary-visual
   :type 'hook)
 
 (defcustom gnus-summary-exit-hook nil
   "*A hook called on exit from the summary buffer."
-  :group 'gnus-summary
+  :group 'gnus-summary-exit
   :type 'hook)
 
 (defcustom gnus-summary-prepare-hook nil
   "*A hook called after the summary buffer has been generated.
 If you want to modify the summary buffer, you can use this hook."
-  :group 'gnus-summary
+  :group 'gnus-summary-various
   :type 'hook)
 
 (defcustom gnus-summary-generate-hook nil
   "*A hook run just before generating the summary buffer.
 This hook is commonly used to customize threading variables and the
 like."
-  :group 'gnus-summary
+  :group 'gnus-summary-various
   :type 'hook)
 
 (defcustom gnus-select-group-hook nil
@@ -601,12 +686,12 @@ following hook:
                      (gnus-simplify-subject
                       (mail-header-subject header) 're-only)))
                  gnus-newsgroup-headers))))"
-  :group 'gnus-summary
+  :group 'gnus-group-select
   :type 'hook)
 
 (defcustom gnus-select-article-hook nil
   "*A hook called when an article is selected."
-  :group 'gnus-summary
+  :group 'gnus-summary-choose
   :type 'hook)
 
 (defcustom gnus-visual-mark-article-hook
@@ -614,18 +699,18 @@ following hook:
   "*Hook run after selecting an article in the summary buffer.
 It is meant to be used for highlighting the article in some way.  It
 is not run if `gnus-visual' is nil."
-  :group 'gnus-summary
+  :group 'gnus-summary-visual
   :type 'hook)
 
 (defcustom gnus-parse-headers-hook 
   (list 'gnus-decode-rfc1522)
   "*A hook called before parsing the headers."
-  :group 'gnus-summary
+  :group 'gnus-various
   :type 'hook)
 
 (defcustom gnus-exit-group-hook nil
   "*A hook called when exiting (not quitting) summary mode."
-  :group 'gnus-summary
+  :group 'gnus-various
   :type 'hook)
 
 (defcustom gnus-summary-update-hook
@@ -636,19 +721,19 @@ The hook will not be called if `gnus-visual' is nil.
 The default function `gnus-summary-highlight-line' will
 highlight the line according to the `gnus-summary-highlight'
 variable."
-  :group 'gnus-summary
+  :group 'gnus-summary-visual
   :type 'hook)
 
 (defcustom gnus-mark-article-hook '(gnus-summary-mark-read-and-unread-as-read)
   "*A hook called when an article is selected for the first time.
 The hook is intended to mark an article as read (or unread)
 automatically when it is selected."
-  :group 'gnus-summary
+  :group 'gnus-summary-choose
   :type 'hook)
 
 (defcustom gnus-group-no-more-groups-hook nil
   "*A hook run when returning to group mode having no more (unread) groups."
-  :group 'gnus-summary
+  :group 'gnus-group-select
   :type 'hook)
 
 (defface gnus-summary-selected-face '((t 
@@ -657,7 +742,7 @@ automatically when it is selected."
 
 (defcustom gnus-summary-selected-face 'gnus-summary-selected-face
   "Face used for highlighting the current article in the summary buffer."
-  :group 'gnus-summary
+  :group 'gnus-summary-visual
   :type 'face)
 
 (defface gnus-summary-cancelled-face 
@@ -828,7 +913,7 @@ score:   The articles score
 default: The default article score.
 below:   The score below which articles are automatically marked as read. 
 mark:    The articles mark."
-  :group 'gnus-summary
+  :group 'gnus-summary-visual
   :type '(repeat (cons (sexp :tag "Form" nil)
                       face)))
 
@@ -1104,10 +1189,15 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
     (re-search-forward "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *" nil t)
     (goto-char (match-beginning 0))
     (while (or
+           (looking-at gnus-simplify-subject-fuzzy-regexp)
            (looking-at "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *")
            (looking-at "^[[].*: .*[]]$"))
       (goto-char (point-min))
-      (while (re-search-forward "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *"
+      (while (re-search-forward gnus-simplify-subject-fuzzy-regexp
+                               nil t)
+       (replace-match "" t t))
+      (goto-char (point-min))
+      (while (re-search-forward "^ *\\(re\\|fw\\|fwd\\)[[{(^0-9]*[])}]?[:;] *"
                                nil t)
        (replace-match "" t t))
       (goto-char (point-min))
@@ -1128,18 +1218,7 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
       (replace-match "" t t))
     (goto-char (point-min))
     (while (re-search-forward "^ +" nil t)
-      (replace-match "" t t))
-    (goto-char (point-min))
-    (when gnus-simplify-subject-fuzzy-regexp
-      (if (listp gnus-simplify-subject-fuzzy-regexp)
-         (let ((list gnus-simplify-subject-fuzzy-regexp))
-           (while list
-             (goto-char (point-min))
-             (while (re-search-forward (car list) nil t)
-               (replace-match "" t t))
-             (setq list (cdr list))))
-       (while (re-search-forward gnus-simplify-subject-fuzzy-regexp nil t)
-         (replace-match "" t t))))))
+      (replace-match "" t t))))
 
 (defun gnus-simplify-subject-fuzzy (subject)
   "Simplify a subject string fuzzily."
@@ -1355,7 +1434,7 @@ increase the score of each group you read."
     "v" gnus-summary-limit-to-score
     "D" gnus-summary-limit-include-dormant
     "d" gnus-summary-limit-exclude-dormant
-    ;;  "t" gnus-summary-limit-exclude-thread
+    "t" gnus-summary-limit-to-age
     "E" gnus-summary-limit-include-expunged
     "c" gnus-summary-limit-exclude-childless-dormant
     "C" gnus-summary-limit-mark-excluded-as-read)
@@ -1409,6 +1488,7 @@ increase the score of each group you read."
     "R" gnus-summary-reselect-current-group
     "G" gnus-summary-rescan-group
     "N" gnus-summary-next-group
+    "s" gnus-summary-save-newsrc
     "P" gnus-summary-prev-group)
 
   (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
@@ -1806,6 +1886,7 @@ increase the score of each group you read."
        ["Marks..." gnus-summary-limit-to-marks t]
        ["Subject..." gnus-summary-limit-to-subject t]
        ["Author..." gnus-summary-limit-to-author t]
+       ["Age..." gnus-summary-limit-to-age t]
        ["Score" gnus-summary-limit-to-score t]
        ["Unread" gnus-summary-limit-to-unread t]
        ["Non-dormant" gnus-summary-limit-exclude-dormant t]
@@ -1893,7 +1974,8 @@ increase the score of each group you read."
        ["Exit and goto next group" gnus-summary-next-group t]
        ["Exit and goto prev group" gnus-summary-prev-group t]
        ["Reselect group" gnus-summary-reselect-current-group t]
-       ["Rescan group" gnus-summary-rescan-group t])))
+       ["Rescan group" gnus-summary-rescan-group t]
+       ["Save newsrc" gnus-summary-save-newsrc t])))
 
     (run-hooks 'gnus-summary-menu-hook)))
 
@@ -4838,7 +4920,6 @@ The prefix argument ALL means to select all articles."
       (unless (listp (cdr gnus-newsgroup-killed))
        (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
       (let ((headers gnus-newsgroup-headers))
-       (run-hooks 'gnus-exit-group-hook)
        (unless gnus-save-score
          (setq gnus-newsgroup-scored nil))
        ;; Set the new ranges of read articles.
@@ -4859,6 +4940,14 @@ The prefix argument ALL means to select all articles."
        (unless (gnus-ephemeral-group-p gnus-newsgroup-name)
          (gnus-group-update-group group))))))
 
+(defun gnus-summary-save-newsrc ()
+  "Save the .newsrc file.
+The current number of read/marked articles in the summary buffer
+will also be saved."
+  (interactive)
+  (gnus-summary-update-info)
+  (gnus-save-newsrc-file))
+
 (defun gnus-summary-exit (&optional temporary)
   "Exit reading current newsgroup, and then return to group selection mode.
 gnus-exit-group-hook is called with no arguments if that value is non-nil."
@@ -4884,6 +4973,7 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
       (gnus-tree-close group))
     ;; Make all changes in this group permanent.
     (unless quit-config
+      (run-hooks 'gnus-exit-group-hook)
       (gnus-summary-update-info))
     (gnus-close-group group)
     ;; Make sure where I was, and go to next newsgroup.
@@ -5702,6 +5792,26 @@ If given a prefix, remove all limits."
   (interactive "sRegexp: ")
   (gnus-summary-limit-to-subject from "from"))
 
+(defun gnus-summary-limit-to-age (age &optional younger-p)
+  "Limit the summary buffer to articles that are older than (or equal) AGE days. 
+If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to
+articles that are younger than AGE days."
+  (interactive "nTime in days: \nP")
+  (prog1
+      (let ((data gnus-newsgroup-data)
+           (cutoff (nnmail-days-to-time age))
+           articles d date is-younger)
+       (while (setq d (pop data))
+         (when (and (vectorp (gnus-data-header d))
+                    (setq date (mail-header-date (gnus-data-header d))))
+           (setq is-younger (nnmail-time-less
+                             (nnmail-time-since (nnmail-date-to-time date))
+                             cutoff))
+           (when (if younger-p is-younger (not is-younger))
+             (push (gnus-data-number d) articles))))
+       (gnus-summary-limit (nreverse articles)))
+    (gnus-summary-position-point)))
+
 (defalias 'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread)
 (make-obsolete
  'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread)
@@ -6746,7 +6856,7 @@ re-spool using this method."
   "Default method for respooling an article.  
 If nil, use to the current newsgroup method."
   :type 'gnus-select-method-name
-  :group 'gnus-summary)
+  :group 'gnus-summary-mail)
 
 (defun gnus-summary-respool-article (&optional n method)
   "Respool the current article.
@@ -6855,6 +6965,7 @@ This will be the case if the article has both been mailed and posted."
                            ;; We need to update the info for
                            ;; this group for `gnus-list-of-read-articles'
                            ;; to give us the right answer.
+                           (run-hooks 'gnus-exit-group-hook)
                            (gnus-summary-update-info)
                            (gnus-list-of-read-articles gnus-newsgroup-name))
                        (setq gnus-newsgroup-expirable
@@ -7642,11 +7753,6 @@ The number of articles marked as read is returned."
            (unless to-here
              (setq gnus-newsgroup-unreads nil))
            (gnus-set-mode-line 'summary))
-         (let ((method (gnus-find-method-for-group gnus-newsgroup-name)))
-           (when (and (not to-here) (eq 'nnvirtual (car method)))
-             (nnvirtual-catchup-group
-              (gnus-group-real-name gnus-newsgroup-name)
-              (nth 1 method) all)))
          t))
     (gnus-summary-position-point)))
 
index 18135e0..dd7d963 100644 (file)
@@ -1051,9 +1051,12 @@ If COPYP, copy the groups instead."
   (interactive "P")
   (if (gnus-group-topic-p)
       (let ((topic (gnus-group-topic-name)))
-       (gnus-topic-remove-topic nil t)
-       (push (gnus-topic-find-topology topic nil nil gnus-topic-topology)
+       (push (cons 
+              (gnus-topic-find-topology topic)
+              (assoc topic gnus-topic-alist))
              gnus-topic-killed-topics)
+       (gnus-topic-remove-topic nil t)
+       (gnus-topic-find-topology topic nil nil gnus-topic-topology)
        (gnus-topic-enter-dribble))
     (gnus-group-kill-group n discard)
     (gnus-topic-update-topic)))
@@ -1062,10 +1065,13 @@ If COPYP, copy the groups instead."
   "Yank the last topic."
   (interactive "p")
   (if gnus-topic-killed-topics
-      (let ((previous 
-            (or (gnus-group-topic-name)
-                (gnus-topic-next-topic (gnus-current-topic))))
-           (item (cdr (pop gnus-topic-killed-topics))))
+      (let* ((previous 
+             (or (gnus-group-topic-name)
+                 (gnus-topic-next-topic (gnus-current-topic))))
+            (data (pop gnus-topic-killed-topics))
+            (alist (cdr data))
+            (item (cdar data)))
+       (push alist gnus-topic-alist)
        (gnus-topic-create-topic
         (caar item) (gnus-topic-parent-topic previous) previous
         item)
@@ -1205,7 +1211,7 @@ If UNINDENT, remove an indentation."
        (gnus-topic-goto-topic topic)
        (gnus-topic-kill-group)
        (gnus-topic-create-topic
-        topic parent nil (cdr (pop gnus-topic-killed-topics)))
+        topic parent nil (cdar (pop gnus-topic-killed-topics)))
        (or (gnus-topic-goto-topic topic)
            (gnus-topic-goto-topic parent))))))
 
@@ -1222,7 +1228,7 @@ If UNINDENT, remove an indentation."
       (gnus-topic-kill-group)
       (gnus-topic-create-topic
        topic grandparent (gnus-topic-next-topic parent)
-       (cdr (pop gnus-topic-killed-topics)))
+       (cdar (pop gnus-topic-killed-topics)))
       (gnus-topic-goto-topic topic))))
 
 (defun gnus-topic-list-active (&optional force)
index e763d13..4e26802 100644 (file)
@@ -598,6 +598,22 @@ Bind `print-quoted' to t while printing."
   (when (file-exists-p file)
     (delete-file file)))
 
+(defun gnus-strip-whitespace (string)
+  "Return STRING stripped of all whitespace."
+  (while (string-match "[\r\n\t ]+" string)
+    (setq string (replace-match "" t t string)))
+  string)
+
+(defun gnus-put-text-property-excluding-newlines (beg end prop val)
+  "The same as `put-text-property', but don't put this prop on any newlines in the region."
+  (save-match-data
+    (save-excursion
+      (save-restriction
+       (goto-char beg)
+       (while (re-search-forward "[ \t]*\n" end 'move)
+         (put-text-property beg (match-beginning 0) prop val)
+         (setq beg (point)))
+       (put-text-property beg (point) prop val)))))
 
 ;;; Protected and atomic operations.  dmoore@ucsd.edu 21.11.1996
 ;;; The primary idea here is to try to protect internal datastructures
@@ -621,7 +637,6 @@ variables and then do only the assignment atomically."
 
 (put 'gnus-atomic-progn 'lisp-indent-function 0)
 
-
 (defmacro gnus-atomic-progn-assign (protect &rest forms)
   "Evaluate FORMS, but insure that the variables listed in PROTECT
 are not changed if anything in FORMS signals an error or otherwise
@@ -658,7 +673,6 @@ non-local exit, it will still be unbound."
 (put 'gnus-atomic-progn-assign 'lisp-indent-function 1)
 ;(put 'gnus-atomic-progn-assign 'edebug-form-spec '(sexp body))
 
-
 (defmacro gnus-atomic-setq (&rest pairs)
   "Similar to setq, except that the real symbols are only assigned when
 there are no errors.  And when the real symbols are assigned, they are
@@ -676,7 +690,6 @@ with potentially long computations."
 ;(put 'gnus-atomic-setq 'edebug-form-spec '(body))
 
 
-
 (provide 'gnus-util)
 
 ;;; gnus-util.el ends here
index bd4d95c..bfbd4d5 100644 (file)
@@ -42,7 +42,7 @@
   "Score and kill file handling."
   :group 'gnus )
 
-(defconst gnus-version-number "0.74"
+(defconst gnus-version-number "0.75"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Red Gnus v%s" gnus-version-number)
index 7e239ab..ba998ef 100644 (file)
@@ -315,6 +315,7 @@ time saver for large mailboxes.")
                (nnfolder-delete-mail))
            (push (car articles) rest)))
        (setq articles (cdr articles)))
+      (nnheader-message 5 "Deleting articles...done")
       (nnfolder-save-buffer)
       ;; Find the lowest active article in this group.
       (let* ((active (cadr (assoc newsgroup nnfolder-group-alist)))
@@ -454,7 +455,7 @@ time saver for large mailboxes.")
   (save-excursion
     (delete-region
      (save-excursion
-       (nnmail-search-unix-mail-delim)
+       (nnmail-search-unix-mail-delim-backward)
        (if leave-delim (progn (forward-line 1) (point))
         (match-beginning 0)))
      (progn
index b394b16..6038511 100644 (file)
@@ -79,7 +79,7 @@ telnets to a remote system, logs in and does the same")
 
 (defvoo nntp-rlogin-parameters '("telnet" "-8" "${NNTPSERVER:=news}" "nntp")
   "*Parameters to `nntp-open-login'.
-That function may be used as `nntp-open-server-function'.  In that
+That function may be used as `nntp-open-connection-function'.  In that
 case, this list will be used as the parameter list given to rsh.")
 
 (defvoo nntp-rlogin-user-name nil
@@ -87,7 +87,7 @@ case, this list will be used as the parameter list given to rsh.")
 
 (defvoo nntp-telnet-parameters '("exec" "telnet" "-8" "${NNTPSERVER:=news}" "nntp")
   "*Parameters to `nntp-open-telnet'.
-That function may be used as `nntp-open-server-function'.  In that
+That function may be used as `nntp-open-connection-function'.  In that
 case, this list will be executed as a command after logging in
 via telnet.")
 
index a08dc37..8488ea8 100644 (file)
@@ -401,8 +401,9 @@ If UPDATE-P is not nil, call gnus-group-update-group on the components."
     ;; hits C-g, you won't leave the component groups in a half-way state.
     (gnus-atomic-progn
       ;; move (un)read
-      (while (setq entry (pop unreads))
-       (gnus-update-read-articles (car entry) (cdr entry)))
+      (let ((gnus-newsgroup-active nil)) ;workaround guns-update-read-articles
+       (while (setq entry (pop unreads))
+         (gnus-update-read-articles (car entry) (cdr entry))))
 
       ;; clear all existing marks on the component groups
       (setq groups nnvirtual-component-groups)
index cbc1fc7..c125bd2 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: extensions
-;; Version: 1.04
+;; Version: 1.12
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
 (autoload 'pp-to-string "pp")
 (autoload 'Info-goto-node "info")
 
+(if (string-match "XEmacs" emacs-version)
+    ;; XEmacs spell `intangible' as `atomic'.
+    (defun widget-make-intangible (from to side)
+      "Make text between FROM and TO atomic with regard to movement.
+Third argument should be `start-open' if it should be sticky to the rear,
+and `end-open' if it should sticky to the front."
+      (require 'atomic-extents)
+      (let ((ext (make-extent from to)))
+        ;; XEmacs doesn't understant different kinds of read-only, so
+        ;; we have to use extents instead.  
+       (put-text-property from to 'read-only nil)
+       (set-extent-property ext 'read-only t)
+       (set-extent-property ext 'start-open nil)
+       (set-extent-property ext 'end-open nil)
+       (set-extent-property ext side t)
+       (set-extent-property ext 'atomic t)))
+  (defun widget-make-intangible (from to size)
+    "Make text between FROM and TO intangible."
+    (put-text-property from to 'intangible 'front)))
+         
 ;; The following should go away when bundled with Emacs.
 (eval-and-compile
   (condition-case ()
       (require 'custom)
-    (error nil)))
-
-(unless (and (featurep 'custom) (fboundp 'custom-declare-variable))
-  ;; We have the old custom-library, hack around it!
-  (defmacro defgroup (&rest args) nil)
-  (defmacro defcustom (&rest args) nil)
-  (defmacro defface (&rest args) nil)
-  (when (fboundp 'copy-face)
-    (copy-face 'default 'widget-documentation-face)
-    (copy-face 'bold 'widget-button-face)
-    (copy-face 'italic 'widget-field-face))
-  (defvar widget-mouse-face 'highlight)
-  (defvar widget-menu-max-size 40))
+    (error nil))
+
+  (unless (and (featurep 'custom) (fboundp 'custom-declare-variable))
+    ;; We have the old custom-library, hack around it!
+    (defmacro defgroup (&rest args) nil)
+    (defmacro defcustom (&rest args) nil)
+    (defmacro defface (&rest args) nil)
+    (when (fboundp 'copy-face)
+      (copy-face 'default 'widget-documentation-face)
+      (copy-face 'bold 'widget-button-face)
+      (copy-face 'italic 'widget-field-face))
+    (defvar widget-mouse-face 'highlight)
+    (defvar widget-menu-max-size 40)))
 
 ;;; Compatibility.
 
@@ -54,6 +74,7 @@ into the buffer visible in the event's window."
   :link '(custom-manual "(widget)Top")
   :link '(url-link :tag "Development Page" 
                   "http://www.dina.kvl.dk/~abraham/custom/")
+  :prefix "widget-"
   :group 'emacs)
 
 (defface widget-documentation-face '((t ()))
@@ -167,6 +188,8 @@ minibuffer."
   ;; Default properties.
   (add-text-properties from to (list 'read-only t
                                     'front-sticky t
+                                    'start-open t
+                                    'end-open t
                                     'rear-nonsticky nil)))
 
 (defun widget-specify-field (widget from to)
@@ -183,21 +206,32 @@ minibuffer."
     ;; before the field can be modified (e.g. if it belongs to a
     ;; choice widget).  We try to compensate by checking the format
     ;; string, and hope the user hasn't changed the :create method.
-    (put-text-property (- from 2) from 'intangible 'front))
+    (widget-make-intangible (- from 2) from 'end-open))
   
   ;; Make it possible to edit back end of the field.
   (add-text-properties to (1+ to) (list 'front-sticky nil
+                                       'read-only t
                                        'start-open t))
 
-  (when (widget-get widget :size)
-    (put-text-property to (1+ to) 'invisible t)
-    (when (or (string-match "%v\\(.\\|\n\\)" (widget-get widget :format))
-             (widget-get widget :hide-rear-space))
-      ;; WARNING: This is going to lose horrible if the character just
-      ;; after the field can be modified (e.g. if it belongs to a
-      ;; choice widget).  We try to compensate by checking the format
-      ;; string, and hope the user hasn't changed the :create method.
-      (put-text-property to (+ to 2) 'intangible 'rear))))
+  (cond ((widget-get widget :size)
+        (put-text-property to (1+ to) 'invisible t)
+        (when (or (string-match "%v\\(.\\|\n\\)" (widget-get widget :format))
+                  (widget-get widget :hide-rear-space))
+          ;; WARNING: This is going to lose horrible if the character just
+          ;; after the field can be modified (e.g. if it belongs to a
+          ;; choice widget).  We try to compensate by checking the format
+          ;; string, and hope the user hasn't changed the :create method.
+          (widget-make-intangible to (+ to 2) 'start-open)))
+       ((string-match "XEmacs" emacs-version)
+        ;; XEmacs does not allow you to insert before a read-only
+        ;; character, even if it is start.open.
+        ;; XEmacs does allow you to delete an read-only extent, so
+        ;; making the terminating newline read only doesn't help.
+        ;; I tried putting an invisible intangible read-only space
+        ;; before the newline, which gave really weird effects.
+        ;; So for now, we just have trust the user not to delete the
+        ;; newline.  
+        (put-text-property to (1+ to) 'read-only nil))))
 
 (defun widget-specify-field-update (widget from to)
   ;; Specify editable button for WIDGET between FROM and TO.
@@ -315,11 +349,24 @@ The child is converted, using the keyword arguments ARGS."
     widget))
 
 (defun widget-create-child (parent type)
-  "Create widget of TYPE.  "
+  "Create widget of TYPE."
   (let ((widget (copy-list type)))
     (widget-put widget :parent parent)
     (unless (widget-get widget :indent)
       (widget-put widget :indent (+ (or (widget-get parent :indent) 0)
+                                   (or (widget-get widget :extra-offset) 0)
+                                   (widget-get parent :offset))))
+    (widget-apply widget :create)
+    widget))
+
+(defun widget-create-child-value (parent type value)
+  "Create widget of TYPE with value VALUE."
+  (let ((widget (copy-list type)))
+    (widget-put widget :value (widget-apply widget :value-to-internal value))
+    (widget-put widget :parent parent)
+    (unless (widget-get widget :indent)
+      (widget-put widget :indent (+ (or (widget-get parent :indent) 0)
+                                   (or (widget-get widget :extra-offset) 0)
                                    (widget-get parent :offset))))
     (widget-apply widget :create)
     widget))
@@ -562,11 +609,6 @@ With optional ARG, move across that many fields."
               (message "Error: `widget-after-change' called on two fields"))
              (t
               (let ((size (widget-get field :size)))
-                (and (string-match "XEmacs" emacs-version)
-                     ;; XEmacs cannot handle zero-sized fields.
-                     (or (null size)
-                         (zerop size))
-                     (setq size 1))
                 (if size 
                     (let ((begin (1+ (widget-get field :value-from)))
                           (end (1- (widget-get field :value-to))))
@@ -898,18 +940,10 @@ With optional ARG, move across that many fields."
   (let ((size (widget-get widget :size))
        (value (widget-get widget :value))
        (from (point)))
-    (if (null size)
-       (if (zerop (length value))
-           (insert "")
-         (insert value))
-      (insert value)
-      (if (< (length value) size)
-         (insert-char ?\  (- size (length value)))))
-    (and (string-match "XEmacs" emacs-version)
-        ;; XEmacs cannot handle zero-sized fields.
-        (or (null size)
-            (zerop size))
-        (insert " "))
+    (insert value)
+    (and size
+        (< (length value) size)
+        (insert-char ?\  (- size (length value))))
     (unless (memq widget widget-field-list)
       (setq widget-field-new (cons widget widget-field-new)))
     (widget-put widget :value-to (copy-marker (point)))
@@ -983,8 +1017,8 @@ With optional ARG, move across that many fields."
       (setq current (car args)
            args (cdr args))
       (when (widget-apply current :match value)
-       (widget-put widget :children (list (widget-create-child-and-convert
-                                           widget current :value value)))
+       (widget-put widget :children (list (widget-create-child-value
+                                           widget current value)))
        (widget-put widget :choice current)
        (setq args nil
              current nil)))
@@ -1159,11 +1193,11 @@ With optional ARG, move across that many fields."
                      (cond ((not chosen)
                             (widget-create-child widget type))
                            ((widget-get type :inline)
-                            (widget-create-child-and-convert
-                             widget type :value (cdr chosen)))
+                            (widget-create-child-value
+                             widget type (cdr chosen)))
                            (t
-                            (widget-create-child-and-convert
-                             widget type :value (car (cdr chosen)))))))
+                            (widget-create-child-value
+                             widget type (car (cdr chosen)))))))
               (t 
                (error "Unknown escape `%c'" escape)))))
      ;; Update properties.
@@ -1335,8 +1369,8 @@ With optional ARG, move across that many fields."
                              :value (not (null chosen)))))
               ((eq escape ?v)
                (setq child (if chosen
-                               (widget-create-child-and-convert
-                                widget type :value value)
+                               (widget-create-child-value
+                                widget type value)
                              (widget-create-child widget type))))
               (t 
                (error "Unknown escape `%c'" escape)))))
@@ -1610,8 +1644,8 @@ With optional ARG, move across that many fields."
                              widget 'delete-button)))
               ((eq escape ?v)
                (if conv
-                   (setq child (widget-create-child-and-convert 
-                                widget type :value value))
+                   (setq child (widget-create-child-value 
+                                widget type value))
                  (setq child (widget-create-child widget type))))
               (t 
                (error "Unknown escape `%c'" escape)))))
@@ -1659,11 +1693,9 @@ With optional ARG, move across that many fields."
       (push (cond ((null answer)
                   (widget-create-child widget arg))
                  ((widget-get arg :inline)
-                  (widget-create-child-and-convert
-                   widget arg :value (car answer)))
+                  (widget-create-child-value widget arg  (car answer)))
                  (t
-                  (widget-create-child-and-convert
-                   widget arg :value (car (car answer)))))
+                  (widget-create-child-value widget arg  (car (car answer)))))
            children))
     (widget-put widget :children (nreverse children))))
 
index a10d535..0677474 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, extensions, faces, hypermedia
-;; Version: 1.04
+;; Version: 1.12
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
 (eval-when-compile (require 'cl))
 
 (defmacro define-widget-keywords (&rest keys)
-  `(eval-and-compile
-     (let ((keywords (quote ,keys)))
+  (`
+   (eval-and-compile
+     (let ((keywords (quote (, keys))))
        (while keywords
         (or (boundp (car keywords))
             (set (car keywords) (car keywords)))
-        (setq keywords (cdr keywords))))))
+        (setq keywords (cdr keywords)))))))
 
 (define-widget-keywords :case-fold :widget-doc
   :create :convert-widget :format :value-create :offset :extra-offset
index 371b128..6ebd396 100644 (file)
@@ -1,3 +1,7 @@
+Fri Dec 13 01:04:41 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus.texi (Limiting): Addition.
+
 Sat Dec  7 21:10:23 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
 
        * gnus.texi (Example Methods): Addition.
index b3d1d9a..1ed37bb 100644 (file)
@@ -9,22 +9,11 @@
 @end iftex
 @c %**end of header
 
-@menu
-* Introduction::                
-* User Commands::               
-* The Customization Buffer::    
-* Declaring Groups::            
-* Declaring Variables::         
-* Declaring Faces::             
-* The Init File::               
-* Wishlist::                    
-@end menu
-
 @node Top, Introduction, (dir), (dir)
 @comment  node-name,  next,  previous,  up
 @top The Customization Library
 
-Version: 0.995
+Version: 1.12
 
 @menu
 * Introduction::                
@@ -33,6 +22,7 @@ Version: 0.995
 * Declaring Groups::            
 * Declaring Variables::         
 * Declaring Faces::             
+* Utilities::            
 * The Init File::               
 * Wishlist::                    
 @end menu
@@ -434,6 +424,17 @@ The following @var{keyword}'s are defined:
 @item :group
 @var{value} should be a customization group. 
 Add @var{symbol} to that group. 
+@item :link
+@var{value} should be a widget type. 
+Add @var{value} to the extrenal links for this customization option.
+Useful widget types include @code{custom-manual}, @code{info-link}, and
+@code{url-link}. 
+@item :load
+Add @var{value} to the files that should be loaded nefore displaying
+this customization option.  The value should be iether a string, which
+should be a string which will be loaded with @code{load-library} unless
+present in @code{load-history}, or a symbol which will be loaded with
+@code{require}. 
 @end table
 @end defun
 
@@ -465,6 +466,17 @@ For hooks, this is a list of function names.
 @item :group
 @var{value} should be a customization group. 
 Add @var{symbol} to that group. 
+@item :link
+@var{value} should be a widget type. 
+Add @var{value} to the extrenal links for this customization option.
+Useful widget types include @code{custom-manual}, @code{info-link}, and
+@code{url-link}. 
+@item :load
+Add @var{value} to the files that should be loaded nefore displaying
+this customization option.  The value should be iether a string, which
+should be a string which will be loaded with @code{load-library} unless
+present in @code{load-history}, or a symbol which will be loaded with
+@code{require}. 
 @end table
 
 @xref{Sexp Types,,,widget,The Widget Library}, for information about
@@ -477,8 +489,17 @@ specified default value, @code{default-value} for a user specified
 default value, and @code{variable-documentation} for the documentation
 string.
 
+Use @code{custom-add-option} to specify that a specific function is
+useful as an meber of a hook.
+
+@defun custom-add-option symbol option
+To the variable @var{symbol} add @var{option}.
 
-@node  Declaring Faces, The Init File, Declaring Variables, Top
+If @var{symbol} is a hook variable, @var{option} should be a hook
+member.  For other types variables, the effect is undefined."
+@end defun
+
+@node  Declaring Faces, Utilities, Declaring Variables, Top
 @comment  node-name,  next,  previous,  up
 @section Declaring Faces
 
@@ -501,6 +522,17 @@ The following @var{keyword}'s are defined:
 @item :group
 @var{value} should be a customization group. 
 Add @var{symbol} to that group. 
+@item :link
+@var{value} should be a widget type. 
+Add @var{value} to the extrenal links for this customization option.
+Useful widget types include @code{custom-manual}, @code{info-link}, and
+@code{url-link}. 
+@item :load
+Add @var{value} to the files that should be loaded nefore displaying
+this customization option.  The value should be iether a string, which
+should be a string which will be loaded with @code{load-library} unless
+present in @code{load-history}, or a symbol which will be loaded with
+@code{require}. 
 @end table
 
 @var{spec} should be an alist of the form @samp{((@var{display} @var{atts})...)}.
@@ -540,7 +572,32 @@ documentation string.@refill
 
 @end defun
 
-@node  The Init File, Wishlist, Declaring Faces, Top
+@node  Utilities, The Init File, Declaring Faces, Top
+@comment  node-name,  next,  previous,  up
+@section Utilities
+
+These utilities can come in handy when adding customization support. 
+
+@deffn Widget custom-manual
+Widget type for specifying the info manual entry for a customization
+option.  It takes one argument, an info address.
+@end deffn
+
+@defun custom-add-to-group group member widget
+To existing @var{group} add a new @var{member} of type @var{widget},
+If there already is an entry for that member, overwrite it.
+@end defun
+
+@defun custom-add-link symbol widget
+To the custom option @var{symbol} add the link @var{widget}.
+@end defun
+
+@defun custom-add-load symbol load
+To the custom option @var{symbol} add the dependency @var{load}.
+@var{load} should be either a library file name, or a feature name.
+@end defun
+
+@node  The Init File, Wishlist, Utilities, Top
 @comment  node-name,  next,  previous,  up
 @section The Init File
 
@@ -564,17 +621,6 @@ should not be allowed to select the @samp{Factory} menu item.
 We need @strong{much} better support for keyboard operations in the
 customize buffer.
 
-@item
-There should be a function to create a customize menu from a group.
-
-@item
-There should be a `Help | Customize' entry in the menu bar with a user
-specified number of levels of submenus.  
-
-@item
-It would be nice if one could set simple variables directly from the
-menu. 
-
 @item
 Support real specifiers under XEmacs.
 
@@ -584,10 +630,8 @@ better formatting.  I'm thinking about adding a <custom>name</custom>
 tag. 
 
 @item
-Try to keep track of whether it is necessary to save or not.
-
-@item
-Offer to save if you exit emacs with unsaved customizations.
+Add an `examples' section, with explained examples of custom type
+definitions. 
 
 @end itemize
 
index b9ca4b5..16d3539 100644 (file)
@@ -1,7 +1,7 @@
 \input texinfo                  @c -*-texinfo-*-
 
 @setfilename gnus
-@settitle Red Gnus 0.74 Manual
+@settitle Red Gnus 0.75 Manual
 @synindex fn cp
 @synindex vr cp
 @synindex pg cp
@@ -287,7 +287,7 @@ into another language, under the above conditions for modified versions.
 @tex
 
 @titlepage
-@title Red Gnus 0.74 Manual
+@title Red Gnus 0.75 Manual
 
 @author by Lars Magne Ingebrigtsen
 @page
@@ -323,7 +323,7 @@ can be gotten by any nefarious means you can think of---@sc{nntp}, local
 spool or your mbox file.  All at the same time, if you want to push your
 luck.
 
-This manual corresponds to Red Gnus 0.74
+This manual corresponds to Red Gnus 0.75
 
 @end ifinfo
 
@@ -4228,6 +4228,14 @@ dormant articles will also be excluded.
 Ask for a mark and then limit to all articles that have not been marked
 with that mark (@code{gnus-summary-limit-to-marks}).
 
+@item / t
+@kindex / t (Summary)
+@findex gnus-summary-limit-to-age
+Ask for a number and then limit the summary buffer to articles that are
+older than (or equal to) that number of days
+(@code{gnus-summary-limit-to-marks}).  If given a prefix, limit to
+articles that are younger than that number of days.
+
 @item / n
 @kindex / n (Summary)
 @findex gnus-summary-limit-to-articles
@@ -6885,6 +6893,13 @@ Exit the group and go to the next group
 @findex gnus-summary-prev-group
 Exit the group and go to the previous group
 (@code{gnus-summary-prev-group}). 
+
+@item Z s
+@kindex Z s (Summary)
+@findex gnus-summary-save-newsrc
+Save the @file{.newsrc} file(s).  The current number of read/marked
+articles in the summary buffer will also be saved.  This will make exit
+without updating (the @kbd{Q} command) worthless.
 @end table
 
 @vindex gnus-exit-group-hook
@@ -8034,7 +8049,7 @@ should probably look something like this:
 @lisp
 (nntp "firewall"
       (nntp-address "the.firewall.machine")
-      (nntp-open-server-function nntp-open-rlogin)
+      (nntp-open-connection-function nntp-open-rlogin)
       (nntp-end-of-line "\n")
       (nntp-rlogin-parameters
        ("telnet" "the.real.nntp.host" "nntp")))
@@ -8293,8 +8308,8 @@ server.
 
 @findex nntp-open-rlogin
 @findex nntp-open-network-stream
-@item nntp-open-server-function
-@vindex nntp-open-server-function
+@item nntp-open-connection-function
+@vindex nntp-open-connection-function
 This function is used to connect to the remote system.  Two pre-made
 functions are @code{nntp-open-network-stream}, which is the default, and
 simply connects to some port or other on the remote system.  The other
@@ -8304,7 +8319,7 @@ and then does a telnet to the @sc{nntp} server available there.
 @item nntp-rlogin-parameters
 @vindex nntp-rlogin-parameters
 If you use @code{nntp-open-rlogin} as the
-@code{nntp-open-server-function}, this list will be used as the
+@code{nntp-open-connection-function}, this list will be used as the
 parameter list given to @code{rsh}.
 
 @item nntp-end-of-line
@@ -11182,6 +11197,11 @@ After using this scheme for a while, it might be nice to write a
 @code{gnus-psychoanalyze-user} command to go through the rules and see
 what words you like and what words you don't like.  Or perhaps not.
 
+Note that the adaptive word scoring thing is highly experimental and is
+likely to change in the future.  Initial impressions seem to indicate
+that it's totally useless as it stands.  Some more work (involving more
+rigorous statistical methods) will have to be done to make this useful. 
+
 
 @node Home Score File
 @section Home Score File
@@ -13701,6 +13721,7 @@ Michael R. Cook,
 Glenn Coombs, 
 Frank D. Cringle, 
 Geoffrey T. Dairiki,
+Andre Deparade,
 Ulrik Dickow,
 Dave Disser,
 Joev Dubach,
@@ -13719,10 +13740,13 @@ Francois Felix Ingrand,
 Lee Iverson, 
 Randell Jesup,
 Fred Johansen, 
+Shuhei Kobayashi, @c Kobayashi
 Thor Kristoffersen,
 Jens Lautenbacher,
 Carsten Leonhardt,
 Christian Limpach,
+Markus Linnala,
+Dave Love,
 Tonny Madsen,
 Shlomo Mahlab,
 Nat Makarevitch,
@@ -13742,6 +13766,7 @@ Stephen Peters,
 Ulrich Pfeifer,
 Colin Rafferty,
 Bart Robinson,
+Loren Schall,
 Ralph Schleicher,
 Randal L. Schwartz,
 Danny Siu, 
index 66d0272..52a6d55 100644 (file)
@@ -1,6 +1,6 @@
 \input texinfo.tex
 
-@c $Id: widget.texi,v 1.2 1996/10/30 19:27:41 steve Exp $
+@c $Id: widget.texi,v 1.3 1996/12/14 09:53:45 steve Exp $
 
 @c %**start of header
 @setfilename widget
@@ -15,7 +15,7 @@
 @comment  node-name,  next,  previous,  up
 @top The Emacs Widget Library
 
-Version: 0.995
+Version: 1.12
 
 @menu
 * Introduction::                
@@ -183,9 +183,9 @@ Editing text fields are created by the @code{editable-field} widget.
 The editing text fields are highlighted with the
 @code{widget-field-face} face, making them easy to find.
 
-@defopt widget-field-face
+@deffn Face widget-field-face
 Face used for other editing fields.
-@end defopt
+@end deffn
 
 @subsection Buttons
 
@@ -243,9 +243,9 @@ enough.
 
 To make them easier to locate, buttons are emphasized in the buffer.  
 
-@defopt widget-button-face
+@deffn Face widget-button-face
 Face used for buttons.
-@end defopt
+@end deffn
 
 @defopt widget-mouse-face
 Face used for buttons when the mouse pointer is above it.
@@ -528,20 +528,22 @@ The parent of a nested widget (e.g. a @code{menu-choice} item or an element of a
 
 @menu
 * link::                        
-* push-button::                        
-* editable-field::                       
+* url-link::                    
+* info-link::                   
+* push-button::                 
+* editable-field::              
 * text::                        
-* menu-choice::                      
-* radio-button-choice::                       
+* menu-choice::                 
+* radio-button-choice::         
 * item::                        
 * choice-item::                 
 * toggle::                      
 * checkbox::                    
 * checklist::                   
-* editable-list::                      
+* editable-list::               
 @end menu
 
-@node link, push-button, Basic Types, Basic Types
+@node link, url-link, Basic Types, Basic Types
 @comment  node-name,  next,  previous,  up
 @subsection The @code{link} Widget
 
@@ -555,7 +557,33 @@ The @var{value}, if present, is used to initialize the @code{:value}
 property.  The value should be a string, which will be inserted in the
 buffer. 
 
-@node  push-button, editable-field, link, Basic Types
+@node url-link, info-link, link, Basic Types
+@comment  node-name,  next,  previous,  up
+@subsection The @code{url-link} Widget
+
+Syntax:
+
+@example
+TYPE ::= (url-link [KEYWORD ARGUMENT]...  URL)
+@end example
+
+When this link is activated, the @sc{www} browser specified by
+@code{browse-url-browser-function} will be called with @var{url}. 
+
+@node info-link, push-button, url-link, Basic Types
+@comment  node-name,  next,  previous,  up
+@subsection The @code{info-link} Widget
+
+Syntax:
+
+@example
+TYPE ::= (info-link [KEYWORD ARGUMENT]...  ADDRESS)
+@end example
+
+When this link is activated, the build-in info browser is started on
+@var{address}. 
+
+@node  push-button, editable-field, info-link, Basic Types
 @comment  node-name,  next,  previous,  up
 @subsection The @code{push-button} Widget