(indent-for-tab-command): Doc fix.
[bpt/emacs.git] / lisp / cus-edit.el
index 98e1f49..ae4277e 100644 (file)
@@ -1,10 +1,9 @@
-;;; cus-edit.el --- Tools for customizating Emacs and Lisp packages.
+;;; cus-edit.el --- Tools for customizing Emacs and Lisp packages.
 ;;
-;; Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, faces
-;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ (probably obsolete)
 
 ;; This file is part of GNU Emacs.
 
@@ -37,9 +36,7 @@
 
 (require 'cus-face)
 (require 'wid-edit)
-(require 'easymenu)
 (eval-when-compile
-  (require 'cl)
   (defvar custom-versions-load-alist)) ; from cus-load
 
 (condition-case nil
 (defun custom-quote (sexp)
   "Quote SEXP iff it is not self quoting."
   (if (or (memq sexp '(t nil))
-         (and (symbolp sexp)
-              (eq (aref (symbol-name sexp) 0) ?:))
+         (keywordp sexp)
          (and (listp sexp)
               (memq (car sexp) '(lambda)))
          (stringp sexp)
@@ -387,7 +383,6 @@ IF REGEXP is not a string, return it unchanged."
     regexp))
 
 (defun custom-variable-prompt ()
-  ;; Code stolen from `help.el'.
   "Prompt for a variable, defaulting to the variable at point.
 Return a list suitable for use in `interactive'."
    (let ((v (variable-at-point))
@@ -401,7 +396,7 @@ Return a list suitable for use in `interactive'."
                          (and (boundp symbol)
                               (or (get symbol 'custom-type)
                                   (get symbol 'custom-loads)
-                                  (user-variable-p symbol)))) t))
+                                  (get symbol 'standard-value)))) t))
      (list (if (equal val "")
               (if (symbolp v) v nil)
             (intern val)))))
@@ -426,7 +421,7 @@ WIDGET is the widget to apply the filter entries of MENU on."
 ;;; Unlispify.
 
 (defvar custom-prefix-list nil
-  "List of prefixes that should be ignored by `custom-unlispify'")
+  "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."
@@ -439,7 +434,7 @@ WIDGET is the widget to apply the filter entries of MENU on."
   :type 'boolean)
 
 (defun custom-unlispify-menu-entry (symbol &optional no-suffix)
-  "Convert symbol into a menu entry."
+  "Convert SYMBOL into a menu entry."
   (cond ((not custom-unlispify-menu-entries)
         (symbol-name symbol))
        ((get symbol 'custom-tag)
@@ -479,12 +474,12 @@ WIDGET is the widget to apply the filter entries of MENU on."
   :type 'boolean)
 
 (defun custom-unlispify-tag-name (symbol)
-  "Convert symbol into a menu entry."
+  "Convert SYMBOL into a menu entry."
   (let ((custom-unlispify-menu-entries custom-unlispify-tag-names))
     (custom-unlispify-menu-entry symbol t)))
 
 (defun custom-prefix-add (symbol prefixes)
-  ;; Addd SYMBOL to list of ignored PREFIXES.
+  "Add SYMBOL to list of ignored PREFIXES."
   (cons (or (get symbol 'custom-prefix)
            (concat (symbol-name symbol) "-"))
        prefixes))
@@ -611,7 +606,7 @@ groups after non-groups, if nil do not order groups at all."
   (sort (copy-sequence items)
    (lambda (a b)
      (let ((typea (nth 1 a)) (typeb (nth 1 b))
-          (namea (symbol-name (nth 0 a))) (nameb (symbol-name (nth 0 b))))
+          (namea (nth 0 a)) (nameb (nth 0 b)))
        (cond ((not order-groups)
              ;; Since we don't care about A and B order, maybe sort.
              (when sort-alphabetically
@@ -638,19 +633,19 @@ groups after non-groups, if nil do not order groups at all."
   "Set changes in all modified options."
   (interactive)
   (let ((children custom-options))
-    (mapcar (lambda (child)
-             (when (eq (widget-get child :custom-state) 'modified)
-               (widget-apply child :custom-set)))
+    (mapc (lambda (child)
+           (when (eq (widget-get child :custom-state) 'modified)
+             (widget-apply child :custom-set)))
            children)))
 
 (defun Custom-save ()
   "Set all modified group members and save them."
   (interactive)
   (let ((children custom-options))
-    (mapcar (lambda (child)
-             (when (memq (widget-get child :custom-state)
-                         '(modified set changed rogue))
-               (widget-apply child :custom-save)))
+    (mapc (lambda (child)
+           (when (memq (widget-get child :custom-state)
+                       '(modified set changed rogue))
+             (widget-apply child :custom-save)))
            children))
   (custom-save-all))
 
@@ -660,7 +655,7 @@ groups after non-groups, if nil do not order groups at all."
     ("Erase Customization (use standard settings)" . Custom-reset-standard))
   "Alist of actions for the `Reset' button.
 The key is a string containing the name of the action, the value is a
-lisp function taking the widget as an element which will be called
+Lisp function taking the widget as an element which will be called
 when the action is chosen.")
 
 (defun custom-reset (event)
@@ -676,22 +671,22 @@ when the action is chosen.")
   "Reset all modified group members to their current value."
   (interactive)
   (let ((children custom-options))
-    (mapcar (lambda (widget)
-             (and (default-boundp (widget-value widget))
-                  (if (memq (widget-get widget :custom-state)
-                            '(modified changed))
-                      (widget-apply widget :custom-reset-current))))
+    (mapc (lambda (widget)
+           (and (default-boundp (widget-value widget))
+                (if (memq (widget-get widget :custom-state)
+                          '(modified changed))
+                    (widget-apply widget :custom-reset-current))))
            children)))
 
 (defun Custom-reset-saved (&rest ignore)
   "Reset all modified or set group members to their saved value."
   (interactive)
   (let ((children custom-options))
-    (mapcar (lambda (widget)
-             (and (get (widget-value widget) 'saved-value)
-                  (if (memq (widget-get widget :custom-state)
-                            '(modified set changed rogue))
-                      (widget-apply widget :custom-reset-saved))))
+    (mapc (lambda (widget)
+           (and (get (widget-value widget) 'saved-value)
+                (if (memq (widget-get widget :custom-state)
+                          '(modified set changed rogue))
+                    (widget-apply widget :custom-reset-saved))))
            children)))
 
 (defun Custom-reset-standard (&rest ignore)
@@ -701,11 +696,11 @@ This operation eliminates any saved settings for the group members,
 making them as if they had never been customized at all."
   (interactive)
   (let ((children custom-options))
-    (mapcar (lambda (widget)
-             (and (get (widget-value widget) 'standard-value)
-                  (if (memq (widget-get widget :custom-state)
-                            '(modified set changed saved rogue))
-                      (widget-apply widget :custom-reset-standard))))
+    (mapc (lambda (widget)
+           (and (get (widget-value widget) 'standard-value)
+                (if (memq (widget-get widget :custom-state)
+                          '(modified set changed saved rogue))
+                    (widget-apply widget :custom-reset-standard))))
            children)))
 
 ;;; The Customize Commands
@@ -773,7 +768,7 @@ If given a prefix (or a COMMENT argument), also prompt for a comment."
         (put var 'variable-comment comment))))
 
 ;;;###autoload
-(defun customize-set-variable (var val &optional comment)
+(defun customize-set-variable (variable value &optional comment)
   "Set the default for VARIABLE to VALUE.  VALUE is a Lisp object.
 
 If VARIABLE has a `custom-set' property, that is used for setting
@@ -792,17 +787,17 @@ If given a prefix (or a COMMENT argument), also prompt for a comment."
   (interactive (custom-prompt-variable "Set variable: "
                                       "Set customized value for %s to: "
                                       current-prefix-arg))
-  (funcall (or (get var 'custom-set) 'set-default) var val)
-  (put var 'customized-value (list (custom-quote val)))
+  (funcall (or (get variable 'custom-set) 'set-default) variable value)
+  (put variable 'customized-value (list (custom-quote value)))
   (cond ((string= comment "")
-        (put var 'variable-comment nil)
-        (put var 'customized-variable-comment nil))
+        (put variable 'variable-comment nil)
+        (put variable 'customized-variable-comment nil))
        (comment
-        (put var 'variable-comment comment)
-        (put var 'customized-variable-comment comment))))
+        (put variable 'variable-comment comment)
+        (put variable 'customized-variable-comment comment))))
 
 ;;;###autoload
-(defun customize-save-variable (var val &optional comment)
+(defun customize-save-variable (var value &optional comment)
   "Set the default for VARIABLE to VALUE, and save it for future sessions.
 If VARIABLE has a `custom-set' property, that is used for setting
 VARIABLE, otherwise `set-default' is used.
@@ -820,8 +815,8 @@ If given a prefix (or a COMMENT argument), also prompt for a comment."
   (interactive (custom-prompt-variable "Set and ave variable: "
                                       "Set and save value for %s as: "
                                       current-prefix-arg))
-  (funcall (or (get var 'custom-set) 'set-default) var val)
-  (put var 'saved-value (list (custom-quote val)))
+  (funcall (or (get var 'custom-set) 'set-default) var value)
+  (put var 'saved-value (list (custom-quote value)))
   (cond ((string= comment "")
         (put var 'variable-comment nil)
         (put var 'saved-variable-comment nil))
@@ -941,7 +936,11 @@ version."
 
   (interactive "sCustomize options changed, since version (default all versions): ")
   (if (equal since-version "")
-      (setq since-version nil))
+      (setq since-version nil)
+    (unless (condition-case nil
+               (numberp (read since-version))
+             (error nil))
+      (signal 'wrong-type-argument (list 'numberp since-version))))
   (unless since-version
     (setq since-version customize-changed-options-previous-release))
   (let ((found nil)
@@ -992,17 +991,24 @@ version."
                            "*Customize Changed Options*"))))
 
 (defun customize-version-lessp (version1 version2)
+  ;; Why are the versions strings, and given that they are, why aren't
+  ;; they converted to numbers and compared as such here?  -- fx
+
   ;; In case someone made a mistake and left out the quotes
   ;; in the :version value.
   (if (numberp version2)
       (setq version2 (prin1-to-string version2)))
   (let (major1 major2 minor1 minor2)
-    (string-match "\\([0-9]+\\)[.]\\([0-9]+\\)" version1)
-    (setq major1 (read (match-string 1 version1)))
-    (setq minor1 (read (match-string 2 version1)))
-    (string-match "\\([0-9]+\\)[.]\\([0-9]+\\)" version2)
-    (setq major2 (read (match-string 1 version2)))
-    (setq minor2 (read (match-string 2 version2)))
+    (string-match "\\([0-9]+\\)\\(\\.\\([0-9]+\\)\\)?" version1)
+    (setq major1 (read (or (match-string 1 version1)
+                          "0")))
+    (setq minor1 (read (or (match-string 3 version1)
+                          "0")))
+    (string-match "\\([0-9]+\\)\\(\\.\\([0-9]+\\)\\)?" version2)
+    (setq major2 (read (or (match-string 1 version2)
+                          "0")))
+    (setq minor2 (read (or (match-string 3 version2)
+                          "0")))
     (or (< major1 major2)
        (and (= major1 major2)
             (< minor1 minor2)))))
@@ -1042,7 +1048,7 @@ If SYMBOL is nil, customize all faces."
 
 ;;;###autoload
 (defun customize-face-other-window (&optional symbol)
-  "Show customization buffer for FACE in other window."
+  "Show customization buffer for face SYMBOL in other window."
   (interactive (list (completing-read "Customize face: "
                                      obarray 'custom-facep t)))
   (if (or (null symbol) (and (stringp symbol) (zerop (length symbol))))
@@ -1289,10 +1295,20 @@ Un-customize all values in this buffer.  They get their standard settings."
   (widget-insert "   ")
   (widget-create 'push-button
                 :tag "Finish"
-                :help-echo "Bury or kill the buffer."
+                :help-echo
+                (lambda (&rest ignore)
+                  (concat (cond
+                           ((eq custom-buffer-done-function
+                                'custom-bury-buffer)
+                            "Bury")
+                           ((eq custom-buffer-done-function 'kill-buffer)
+                            "Kill")
+                           (t "Finish with"))              
+                          " the buffer."))
                 :action #'Custom-buffer-done)
   (widget-insert "\n\n")
   (message "Creating customization items...")
+  (buffer-disable-undo)
   (setq custom-options
        (if (= (length options) 1)
            (mapcar (lambda (entry)
@@ -1322,9 +1338,10 @@ Un-customize all values in this buffer.  They get their standard settings."
     (widget-insert "\n"))
   (message "Creating customization items ...%2d%%done" 100)
   (unless (eq custom-buffer-style 'tree)
-    (mapcar 'custom-magic-reset custom-options))
+    (mapc 'custom-magic-reset custom-options))
   (message "Creating customization setup...")
   (widget-setup)
+  (buffer-enable-undo)
   (goto-char (point-min))
   (message "Creating customization buffer...done"))
 
@@ -1609,7 +1626,7 @@ and `face'."
           'hidden)))
 
 (defun custom-magic-value-create (widget)
-  ;; Create compact status report for WIDGET.
+  "Create compact status report for WIDGET."
   (let* ((parent (widget-get widget :parent))
         (state (widget-get parent :custom-state))
         (hidden (eq state 'hidden))
@@ -1689,7 +1706,11 @@ and `face'."
 
 (defface custom-button-face
   '((((type x) (class color))          ; Like default modeline
-     (:box (:line-width 2 :style released-button) :background "lightgrey"))
+     (:box (:line-width 2 :style released-button)
+          :background "lightgrey" :foreground "black"))
+    (((type w32) (class color))                ; Like default modeline
+     (:box (:line-width 2 :style released-button)
+          :background "lightgrey" :foreground "black"))
     (t
      nil))
   "Face used for buttons in customization buffers."
@@ -1698,7 +1719,11 @@ and `face'."
 
 (defface custom-button-pressed-face
   '((((type x) (class color))
-     (:box (:line-width 2 :style pressed-button) :background "lightgrey"))
+     (:box (:line-width 2 :style pressed-button)
+          :background "lightgrey" :foreground "black"))
+    (((type w32) (class color))
+     (:box (:line-width 2 :style pressed-button)
+          :background "lightgrey" :foreground "black"))
     (t
      (:inverse-video t)))
   "Face used for buttons in customization buffers."
@@ -1735,7 +1760,7 @@ and `face'."
   :match (lambda (widget value) (symbolp value)))
 
 (defun custom-convert-widget (widget)
-  ;; Initialize :value and :tag from :args in WIDGET.
+  "Initialize :value and :tag from :args in WIDGET."
   (let ((args (widget-get widget :args)))
     (when args
       (widget-put widget :value (widget-apply widget
@@ -1985,13 +2010,24 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
 
 ;;; The `custom-variable' Widget.
 
-(defface custom-variable-tag-face '((((class color)
-                                     (background dark))
-                                    (:foreground "light blue" :underline t))
-                                   (((class color)
-                                     (background light))
-                                    (:foreground "blue" :underline t))
-                                   (t (:underline t)))
+;; When this was underlined blue, users confused it with a
+;; Mosaic-style hyperlink...
+(defface custom-variable-tag-face
+  `((((class color)
+      (background dark))
+     (:foreground "light blue" :bold t :family "helv"
+                 :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height))))
+    (((class color)
+      (background light))
+     (:foreground "blue" :family "helv" :bold t
+                 :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height))))
+    (t (:bold t)))
   "Face used for unpushable variable tags."
   :group 'custom-faces)
 
@@ -2302,7 +2338,7 @@ Optional EVENT is the location for the menu."
   (custom-redraw widget))
 
 (defun custom-variable-edit-lisp (widget)
-  "Edit the lisp representation of the value of WIDGET."
+  "Edit the Lisp representation of the value of WIDGET."
   (widget-put widget :custom-state 'unknown)
   (widget-put widget :custom-form 'lisp)
   (custom-redraw widget))
@@ -2387,7 +2423,6 @@ Optional EVENT is the location for the menu."
   "Restore the saved value for the variable being edited by WIDGET."
   (let* ((symbol (widget-value widget))
         (set (or (get symbol 'custom-set) 'set-default))
-        (comment-widget (widget-get widget :comment-widget))
         (value (get symbol 'saved-value))
         (comment (get symbol 'saved-variable-comment)))
     (cond ((or value comment)
@@ -2408,8 +2443,7 @@ Optional EVENT is the location for the menu."
 This operation eliminates any saved setting for the variable,
 restoring it to the state of a variable that has never been customized."
   (let* ((symbol (widget-value widget))
-        (set (or (get symbol 'custom-set) 'set-default))
-        (comment-widget (widget-get widget :comment-widget)))
+        (set (or (get symbol 'custom-set) 'set-default)))
     (if (get symbol 'standard-value)
        (funcall set symbol (eval (car (get symbol 'standard-value))))
       (error "No standard setting known for %S" symbol))
@@ -2513,7 +2547,12 @@ Match frames with dark backgrounds.")
 
 ;;; The `custom-face' Widget.
 
-(defface custom-face-tag-face '((t (:underline t)))
+(defface custom-face-tag-face
+  `((t (:bold t :family "helv"
+             :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height)))))
   "Face used for face tags."
   :group 'custom-faces)
 
@@ -2529,8 +2568,7 @@ Match frames with dark backgrounds.")
   "Customize face."
   :sample-face 'custom-face-tag-face
   :help-echo "Set or reset this face."
-  :documentation-property '(lambda (face)
-                            (face-doc-string face))
+  :documentation-property #'face-doc-string
   :value-create 'custom-face-value-create
   :action 'custom-face-action
   :custom-category 'face
@@ -2722,7 +2760,7 @@ widget.  If FILTER is nil, ACTION is always valid.")
   (custom-redraw widget))
 
 (defun custom-face-edit-lisp (widget)
-  "Edit the lisp representation of the value of WIDGET."
+  "Edit the Lisp representation of the value of WIDGET."
   (widget-put widget :custom-state 'unknown)
   (widget-put widget :custom-form 'lisp)
   (custom-redraw widget))
@@ -2871,10 +2909,10 @@ restoring it to the state of a face that has never been customized."
   :value-get 'widget-value-value-get
   :validate 'widget-children-validate
   :action 'widget-face-action
-  :match '(lambda (widget value) (symbolp value)))
+  :match (lambda (widget value) (symbolp value)))
 
 (defun widget-face-value-create (widget)
-  ;; Create a `custom-face' child.
+  "Create a `custom-face' child."
   (let* ((symbol (widget-value widget))
         (custom-buffer-style 'face)
         (child (widget-create-child-and-convert
@@ -2886,7 +2924,7 @@ restoring it to the state of a face that has never been customized."
     (widget-put widget :children (list child))))
 
 (defun widget-face-value-delete (widget)
-  ;; Remove the child from the options.
+  "Remove the child from the options."
   (let ((child (car (widget-get widget :children))))
     (setq custom-options (delq child custom-options))
     (widget-children-value-delete widget)))
@@ -2918,11 +2956,18 @@ restoring it to the state of a face that has never been customized."
   :match (lambda (widget value)
           (or (symbolp value)
               (widget-group-match widget value)))
+  ;; Avoid adding undefined functions to the hook, especially for
+  ;; things like `find-file-hook' or even more basic ones, to avoid
+  ;; chaos.
+  :set (lambda (symbol value)
+        (dolist (elt value)
+          (if (fboundp elt)
+              (add-hook symbol elt))))
   :convert-widget 'custom-hook-convert-widget
   :tag "Hook")
 
 (defun custom-hook-convert-widget (widget)
-  ;; Handle `:custom-options'.
+  ;; Handle `:options'.
   (let* ((options (widget-get widget :options))
         (other `(editable-list :inline t
                                :entry-format "%i %d%v"
@@ -2959,22 +3004,42 @@ and so forth.  The remaining group tags are shown with
   :type '(repeat face)
   :group 'custom-faces)
 
-(defface custom-group-tag-face-1 '((((class color)
-                                    (background dark))
-                                   (:foreground "pink" :underline t))
-                                  (((class color)
-                                    (background light))
-                                   (:foreground "red" :underline t))
-                                  (t (:underline t)))
-  "Face used for group tags.")
-
-(defface custom-group-tag-face '((((class color)
-                                  (background dark))
-                                 (:foreground "light blue" :underline t))
-                                (((class color)
-                                  (background light))
-                                 (:foreground "blue" :underline t))
-                                (t (:underline t)))
+(defface custom-group-tag-face-1
+  `((((class color)
+      (background dark))
+     (:foreground "pink" :family "helv"
+                 :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height))
+                 :bold t))
+    (((class color)
+      (background light))
+     (:foreground "red" :bold t
+                 :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height))))
+    (t (:bold t)))
+  "Face used for group tags."
+  :group 'custom-faces)
+
+(defface custom-group-tag-face
+  `((((class color)
+      (background dark))
+     (:foreground "light blue" :bold t
+                 :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height))))
+    (((class color)
+      (background light))
+     (:foreground "blue" :bold t
+                 :height ,(let ((height (face-attribute 'default :height)))
+                            (if (numberp height)
+                                (floor height 0.9)
+                              height))))
+    (t (:bold t)))
   "Face used for low level group tags."
   :group 'custom-faces)
 
@@ -3229,7 +3294,7 @@ Creating group members... %2d%%"
                                          (widget-insert "\n"))))
                                    members)))
             (message "Creating group magic...")
-            (mapcar 'custom-magic-reset children)
+            (mapc 'custom-magic-reset children)
             (message "Creating group state...")
             (widget-put widget :children children)
             (custom-group-state-update widget)
@@ -3282,42 +3347,42 @@ Optional EVENT is the location for the menu."
 (defun custom-group-set (widget)
   "Set changes in all modified group members."
   (let ((children (widget-get widget :children)))
-    (mapcar (lambda (child)
-             (when (eq (widget-get child :custom-state) 'modified)
-               (widget-apply child :custom-set)))
+    (mapc (lambda (child)
+           (when (eq (widget-get child :custom-state) 'modified)
+             (widget-apply child :custom-set)))
            children )))
 
 (defun custom-group-save (widget)
   "Save all modified group members."
   (let ((children (widget-get widget :children)))
-    (mapcar (lambda (child)
-             (when (memq (widget-get child :custom-state) '(modified set))
-               (widget-apply child :custom-save)))
+    (mapc (lambda (child)
+           (when (memq (widget-get child :custom-state) '(modified set))
+             (widget-apply child :custom-save)))
            children )))
 
 (defun custom-group-reset-current (widget)
   "Reset all modified group members."
   (let ((children (widget-get widget :children)))
-    (mapcar (lambda (child)
-             (when (eq (widget-get child :custom-state) 'modified)
-               (widget-apply child :custom-reset-current)))
+    (mapc (lambda (child)
+           (when (eq (widget-get child :custom-state) 'modified)
+             (widget-apply child :custom-reset-current)))
            children )))
 
 (defun custom-group-reset-saved (widget)
   "Reset all modified or set group members."
   (let ((children (widget-get widget :children)))
-    (mapcar (lambda (child)
-             (when (memq (widget-get child :custom-state) '(modified set))
-               (widget-apply child :custom-reset-saved)))
+    (mapc (lambda (child)
+           (when (memq (widget-get child :custom-state) '(modified set))
+             (widget-apply child :custom-reset-saved)))
            children )))
 
 (defun custom-group-reset-standard (widget)
   "Reset all modified, set, or saved group members."
   (let ((children (widget-get widget :children)))
-    (mapcar (lambda (child)
-             (when (memq (widget-get child :custom-state)
-                         '(modified set saved))
-               (widget-apply child :custom-reset-standard)))
+    (mapc (lambda (child)
+           (when (memq (widget-get child :custom-state)
+                       '(modified set saved))
+             (widget-apply child :custom-reset-standard)))
            children )))
 
 (defun custom-group-state-update (widget)
@@ -3578,20 +3643,11 @@ or (if there were none) at the end of the buffer."
                                   ':style 'toggle
                                   ':selected symbol)))
 
-;; Fixme: sort out use of :filter in Emacs 21.
-(if nil ; (string-match "XEmacs" emacs-version)
-    ;; XEmacs can create menus dynamically.
-    (defun custom-group-menu-create (widget symbol)
-      "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
-      `( ,(custom-unlispify-menu-entry symbol t)
-        :filter (lambda (&rest junk)
-                  (cdr (custom-menu-create ',symbol)))))
-  ;; But emacs can't.
-  (defun custom-group-menu-create (widget symbol)
-    "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
-    ;; Limit the nesting.
-    (let ((custom-menu-nesting (1- custom-menu-nesting)))
-      (custom-menu-create symbol))))
+(defun custom-group-menu-create (widget symbol)
+  "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
+  `( ,(custom-unlispify-menu-entry symbol t)
+     :filter (lambda (&rest junk)
+              (cdr (custom-menu-create ',symbol)))))
 
 ;;;###autoload
 (defun custom-menu-create (symbol)
@@ -3628,14 +3684,9 @@ Otherwise the menu will be named `Customize'.
 The format is suitable for use with `easy-menu-define'."
   (unless name
     (setq name "Customize"))
-  ;; Fixme: sort out use of :filter in Emacs 21.
-  (if nil ;(string-match "XEmacs" emacs-version)
-      ;; We can delay it under XEmacs.
-      `(,name
-       :filter (lambda (&rest junk)
-                 (cdr (custom-menu-create ',symbol))))
-    ;; But we must create it now under Emacs.
-    (cons name (cdr (custom-menu-create symbol)))))
+  `(,name
+    :filter (lambda (&rest junk)
+             (cdr (custom-menu-create ',symbol)))))
 
 ;;; The Custom Mode.
 
@@ -3741,6 +3792,10 @@ if that value is non-nil."
   (add-hook 'widget-edit-functions 'custom-state-buffer-message nil t)
   (run-hooks 'custom-mode-hook))
 
+(add-to-list
+ 'debug-ignored-errors
+ "^No user options have changed defaults in recent Emacs versions$")
+
 ;;; The End.
 
 (provide 'cus-edit)