]> code.delx.au - gnu-emacs/blobdiff - lisp/cus-edit.el
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-86
[gnu-emacs] / lisp / cus-edit.el
index 9041ec3c14c91378b1c481e59c66081b98884f28..8f88e4d049c6d766d68fe2e6ad3bddc12070775a 100644 (file)
@@ -1,6 +1,7 @@
 ;;; cus-edit.el --- tools for customizing Emacs and Lisp packages
 ;;
 ;;; cus-edit.el --- tools for customizing Emacs and Lisp packages
 ;;
-;; Copyright (C) 1996,97,1999,2000,01,02,2003  Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005 Free Software Foundation, Inc.
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Maintainer: FSF
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Maintainer: FSF
@@ -20,8 +21,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 ;;
 
 ;;; Commentary:
 ;;
 ;; that interferes with completion.  Use `customize-' for commands
 ;; that the user will run with M-x, and `Custom-' for interactive commands.
 
 ;; that interferes with completion.  Use `customize-' for commands
 ;; that the user will run with M-x, and `Custom-' for interactive commands.
 
+;; The identity of a customize option is represented by a Lisp symbol.
+;; The following values are associated with an option.
+
+;; 0. The current value.
+
+;;    This is the value of the option as seen by "the rest of Emacs".
+
+;;    Usually extracted by 'default-value', but can be extracted with
+;;    different means if the option symbol has the 'custom-get'
+;;    property.  Similarly, set-default (or the 'custom-set' property)
+;;    can set it.
+
+;; 1. The widget value.
+
+;;    This is the value shown in the widget in a customize buffer.
+
+;; 2. The customized value.
+
+;;    This is the last value given to the option through customize.
+
+;;    It is stored in the 'customized-value' property of the option, in a
+;;    cons-cell whose car evaluates to the customized value.
+
+;; 3. The saved value.
+
+;;    This is last value saved from customize.
+
+;;    It is stored in the 'saved-value' property of the option, in a
+;;    cons-cell whose car evaluates to the saved value.
+
+;; 4. The standard value.
+
+;;    This is the value given in the 'defcustom' declaration.
+
+;;    It is stored in the 'standard-value' property of the option, in a
+;;    cons-cell whose car evaluates to the standard value.
+
+;; 5. The "think" value.
+
+;;    This is what customize thinks the current value should be.
+
+;;    This is the customized value, if any such value exists, otherwise
+;;    the saved value, if that exists, and as a last resort the standard
+;;    value.
+
+;; The reason for storing values unevaluated: This is so you can have
+;; values that depend on the environment.  For example, you can have a
+;; variable that has one value when Emacs is running under a window
+;; system, and another value on a tty.  Since the evaluation is only done
+;; when the variable is first initialized, this is only relevant for the
+;; saved (and standard) values, but affect others values for
+;; compatibility.
+
+;; You can see (and modify and save) this unevaluated value by selecting
+;; "Show initial Lisp expression" from the Lisp interface.  This will
+;; give you the unevaluated saved value, if any, otherwise the
+;; unevaluated standard value.
+
+;; The possible states for a customize widget are:
+
+;; 0. unknown
+
+;;    The state has not been determined yet.
+
+;; 1. modified
+
+;;    The widget value is different from the current value.
+
+;; 2. changed
+
+;;    The current value is different from the "think" value.
+
+;; 3. set
+
+;;    The "think" value is the customized value.
+
+;; 4. saved
+
+;;    The "think" value is the saved value.
+
+;; 5. standard
+
+;;    The "think" value is the standard value.
+
+;; 6. rogue
+
+;;    There is no standard value.  This means that the variable was
+;;    not defined with defcustom, nor handled in cus-start.el.  You
+;;    can not create a Custom buffer for such variables using the
+;;    normal interactive Custom commands.  However, such Custom
+;;    buffers can be created in other ways, for instance, by calling
+;;    `customize-option' non-interactively.
+
+;; 7. hidden
+
+;;    There is no widget value.
+
+;; 8. mismatch
+
+;;    The widget value is not valid member of the :type specified for the
+;;    option.
+
 ;;; Code:
 
 (require 'cus-face)
 (require 'wid-edit)
 (eval-when-compile
 ;;; Code:
 
 (require 'cus-face)
 (require 'wid-edit)
 (eval-when-compile
-  (defvar custom-versions-load-alist)) ; from cus-load
+  (defvar custom-versions-load-alist)  ; from cus-load
+  (defvar recentf-exclude))            ; from recentf.el
 
 (condition-case nil
     (require 'cus-load)
 
 (condition-case nil
     (require 'cus-load)
 
 (defgroup emulations nil
   "Emulations of other editors."
 
 (defgroup emulations nil
   "Emulations of other editors."
+  :link '(custom-manual "(emacs)Emulation")
   :group 'editing)
 
 (defgroup mouse nil
   :group 'editing)
 
 (defgroup mouse nil
   "Interfacing to external utilities."
   :group 'emacs)
 
   "Interfacing to external utilities."
   :group 'emacs)
 
-(defgroup bib nil
-  "Code related to the `bib' bibliography processor."
-  :tag "Bibliography"
-  :group 'external)
-
 (defgroup processes nil
   "Process, subshell, compilation, and job control support."
   :group 'external
 (defgroup processes nil
   "Process, subshell, compilation, and job control support."
   :group 'external
 
 (defgroup c nil
   "Support for the C language and related languages."
 
 (defgroup c nil
   "Support for the C language and related languages."
+  :link '(custom-manual "(ccmode)")
   :group 'languages)
 
 (defgroup tools nil
   :group 'languages)
 
 (defgroup tools nil
 
 (defgroup news nil
   "Support for netnews reading and posting."
 
 (defgroup news nil
   "Support for netnews reading and posting."
+  :link '(custom-manual "(gnus)")
   :group 'applications)
 
 (defgroup games nil
   :group 'applications)
 
 (defgroup games nil
 
 (defgroup i18n nil
   "Internationalization and alternate character-set support."
 
 (defgroup i18n nil
   "Internationalization and alternate character-set support."
+  :link '(custom-manual "(emacs)International")
   :group 'environment
   :group 'editing)
 
   :group 'environment
   :group 'editing)
 
 
 (defgroup customize '((widgets custom-group))
   "Customization of the Customization support."
 
 (defgroup customize '((widgets custom-group))
   "Customization of the Customization support."
-  :link '(custom-manual "(elisp)Customization")
-  :link '(url-link :tag "(Old?) Development Page"
-                  "http://www.dina.kvl.dk/~abraham/custom/")
   :prefix "custom-"
   :group 'help)
 
   :prefix "custom-"
   :group 'help)
 
 
 (defgroup abbrev-mode nil
   "Word abbreviations mode."
 
 (defgroup abbrev-mode nil
   "Word abbreviations mode."
+  :link '(custom-manual "(emacs)Abbrevs")
   :group 'abbrev)
 
 (defgroup alloc nil
   :group 'abbrev)
 
 (defgroup alloc nil
 
 (defgroup undo nil
   "Undoing changes in buffers."
 
 (defgroup undo nil
   "Undoing changes in buffers."
+  :link '(custom-manual "(emacs)Undo")
   :group 'editing)
 
 (defgroup modeline nil
   "Content of the modeline."
   :group 'environment)
 
   :group 'editing)
 
 (defgroup modeline nil
   "Content of the modeline."
   :group 'environment)
 
-(defgroup fill nil
-  "Indenting and filling text."
-  :group 'editing)
-
 (defgroup editing-basics nil
   "Most basic editing facilities."
   :group 'editing)
 (defgroup editing-basics nil
   "Most basic editing facilities."
   :group 'editing)
   :group 'development)
 
 (defgroup minibuffer nil
   :group 'development)
 
 (defgroup minibuffer nil
-  "Controling the behaviour of the minibuffer."
+  "Controling the behavior of the minibuffer."
+  :link '(custom-manual "(emacs)Minibuffer")
   :group 'environment)
 
 (defgroup keyboard nil
   :group 'environment)
 
 (defgroup keyboard nil
   "Input from the menus."
   :group 'environment)
 
   "Input from the menus."
   :group 'environment)
 
+(defgroup dnd nil
+  "Handling data from drag and drop."
+  :group 'environment)
+
 (defgroup auto-save nil
   "Preventing accidential loss of data."
   :group 'files)
 (defgroup auto-save nil
   "Preventing accidential loss of data."
   :group 'files)
 
 (defgroup windows nil
   "Windows within a frame."
 
 (defgroup windows nil
   "Windows within a frame."
+  :link '(custom-manual "(emacs)Windows")
   :group 'environment)
 
 ;;; Utilities.
   :group 'environment)
 
 ;;; Utilities.
@@ -391,7 +495,7 @@ Return a list suitable for use in `interactive'."
         val)
      (setq val (completing-read
                (if (and (symbolp v) (custom-variable-p v))
         val)
      (setq val (completing-read
                (if (and (symbolp v) (custom-variable-p v))
-                   (format "Customize option: (default %s) " v)
+                   (format "Customize option (default %s): " v)
                  "Customize option: ")
                obarray 'custom-variable-p t))
      (list (if (equal val "")
                  "Customize option: ")
                obarray 'custom-variable-p t))
      (list (if (equal val "")
@@ -863,7 +967,7 @@ then prompt for the MODE to customize."
 (defun customize-group (group)
   "Customize GROUP, which must be a customization group."
   (interactive (list (let ((completion-ignore-case t))
 (defun customize-group (group)
   "Customize GROUP, which must be a customization group."
   (interactive (list (let ((completion-ignore-case t))
-                      (completing-read "Customize group: (default emacs) "
+                      (completing-read "Customize group (default emacs): "
                                        obarray
                                        (lambda (symbol)
                                          (or (get symbol 'custom-loads)
                                        obarray
                                        (lambda (symbol)
                                          (or (get symbol 'custom-loads)
@@ -886,7 +990,7 @@ then prompt for the MODE to customize."
 (defun customize-group-other-window (group)
   "Customize GROUP, which must be a customization group."
   (interactive (list (let ((completion-ignore-case t))
 (defun customize-group-other-window (group)
   "Customize GROUP, which must be a customization group."
   (interactive (list (let ((completion-ignore-case t))
-                      (completing-read "Customize group: (default emacs) "
+                      (completing-read "Customize group (default emacs): "
                                        obarray
                                        (lambda (symbol)
                                          (or (get symbol 'custom-loads)
                                        obarray
                                        (lambda (symbol)
                                          (or (get symbol 'custom-loads)
@@ -899,15 +1003,12 @@ then prompt for the MODE to customize."
   (let ((name (format "*Customize Group: %s*"
                      (custom-unlispify-tag-name group))))
     (if (get-buffer name)
   (let ((name (format "*Customize Group: %s*"
                      (custom-unlispify-tag-name group))))
     (if (get-buffer name)
-       (let ((window (selected-window))
+       (let (
              ;; Copied from `custom-buffer-create-other-window'.
              (pop-up-windows t)
              ;; Copied from `custom-buffer-create-other-window'.
              (pop-up-windows t)
-             (special-display-buffer-names nil)
-             (special-display-regexps nil)
              (same-window-buffer-names nil)
              (same-window-regexps nil))
              (same-window-buffer-names nil)
              (same-window-regexps nil))
-         (pop-to-buffer name)
-         (select-window window))
+         (pop-to-buffer name))
       (custom-buffer-create-other-window
        (list (list group 'custom-group))
        name
       (custom-buffer-create-other-window
        (list (list group 'custom-group))
        name
@@ -921,9 +1022,12 @@ then prompt for the MODE to customize."
 (defun customize-option (symbol)
   "Customize SYMBOL, which must be a user option variable."
   (interactive (custom-variable-prompt))
 (defun customize-option (symbol)
   "Customize SYMBOL, which must be a user option variable."
   (interactive (custom-variable-prompt))
-  (custom-buffer-create (list (list symbol 'custom-variable))
-                       (format "*Customize Option: %s*"
-                               (custom-unlispify-tag-name symbol))))
+  (let ((basevar (indirect-variable symbol)))
+    (custom-buffer-create (list (list basevar 'custom-variable))
+                         (format "*Customize Option: %s*"
+                                 (custom-unlispify-tag-name basevar)))
+    (unless (eq symbol basevar)
+      (message "`%s' is an alias for `%s'" symbol basevar))))
 
 ;;;###autoload
 (defalias 'customize-variable-other-window 'customize-option-other-window)
 
 ;;;###autoload
 (defalias 'customize-variable-other-window 'customize-option-other-window)
@@ -933,9 +1037,12 @@ then prompt for the MODE to customize."
   "Customize SYMBOL, which must be a user option variable.
 Show the buffer in another window, but don't select it."
   (interactive (custom-variable-prompt))
   "Customize SYMBOL, which must be a user option variable.
 Show the buffer in another window, but don't select it."
   (interactive (custom-variable-prompt))
-  (custom-buffer-create-other-window
-   (list (list symbol 'custom-variable))
-   (format "*Customize Option: %s*" (custom-unlispify-tag-name symbol))))
+  (let ((basevar (indirect-variable symbol)))
+    (custom-buffer-create-other-window
+     (list (list basevar 'custom-variable))
+     (format "*Customize Option: %s*" (custom-unlispify-tag-name basevar)))
+    (unless (eq symbol basevar)
+      (message "`%s' is an alias for `%s'" symbol basevar))))
 
 (defvar customize-changed-options-previous-release "20.2"
   "Version for `customize-changed-options' to refer back to by default.")
 
 (defvar customize-changed-options-previous-release "20.2"
   "Version for `customize-changed-options' to refer back to by default.")
@@ -1015,11 +1122,12 @@ version."
 
 ;;;###autoload
 (defun customize-face (&optional face)
 
 ;;;###autoload
 (defun customize-face (&optional face)
-  "Customize SYMBOL, which should be a face name or nil.
-If SYMBOL is nil, customize all faces.
+  "Customize FACE, which should be a face name or nil.
+If FACE is nil, customize all faces.  If FACE is actually a
+face-alias, customize the face it is aliased to.
 
 Interactively, when point is on text which has a face specified,
 
 Interactively, when point is on text which has a face specified,
-suggest to customized that face, if it's customizable."
+suggest to customize that face, if it's customizable."
   (interactive
    (list (read-face-name "Customize face" "all faces" t)))
   (if (member face '(nil ""))
   (interactive
    (list (read-face-name "Customize face" "all faces" t)))
   (if (member face '(nil ""))
@@ -1033,6 +1141,9 @@ suggest to customized that face, if it's customizable."
                                     face)
                             t nil)
                            "*Customize Faces*")
                                     face)
                             t nil)
                            "*Customize Faces*")
+    ;; If FACE is actually an alias, customize the face it is aliased to.
+    (if (get face 'face-alias)
+        (setq face (get face 'face-alias)))
     (unless (facep face)
       (error "Invalid face %S" face))
     (custom-buffer-create (list (list face 'custom-face))
     (unless (facep face)
       (error "Invalid face %S" face))
     (custom-buffer-create (list (list face 'custom-face))
@@ -1041,10 +1152,11 @@ suggest to customized that face, if it's customizable."
 
 ;;;###autoload
 (defun customize-face-other-window (&optional face)
 
 ;;;###autoload
 (defun customize-face-other-window (&optional face)
-  "Show customization buffer for face SYMBOL in other window.
+  "Show customization buffer for face FACE in other window.
+If FACE is actually a face-alias, customize the face it is aliased to.
 
 Interactively, when point is on text which has a face specified,
 
 Interactively, when point is on text which has a face specified,
-suggest to customized that face, if it's customizable."
+suggest to customize that face, if it's customizable."
   (interactive
    (list (read-face-name "Customize face" "all faces" t)))
   (if (member face '(nil ""))
   (interactive
    (list (read-face-name "Customize face" "all faces" t)))
   (if (member face '(nil ""))
@@ -1059,6 +1171,8 @@ suggest to customized that face, if it's customizable."
                face)
        t nil)
        "*Customize Faces*")
                face)
        t nil)
        "*Customize Faces*")
+    (if (get face 'face-alias)
+        (setq face (get face 'face-alias)))
     (unless (facep face)
       (error "Invalid face %S" face))
     (custom-buffer-create-other-window
     (unless (facep face)
       (error "Invalid face %S" face))
     (custom-buffer-create-other-window
@@ -1096,7 +1210,7 @@ suggest to customized that face, if it's customizable."
                                (get symbol 'standard-value))))
                  (when (and cval       ;Declared with defcustom.
                             (default-boundp symbol) ;Has a value.
                                (get symbol 'standard-value))))
                  (when (and cval       ;Declared with defcustom.
                             (default-boundp symbol) ;Has a value.
-                            (not (equal (eval (car cval)) 
+                            (not (equal (eval (car cval))
                                         ;; Which does not match customize.
                                         (default-value symbol))))
                    (push (list symbol 'custom-variable) found)))))
                                         ;; Which does not match customize.
                                         (default-value symbol))))
                    (push (list symbol 'custom-variable) found)))))
@@ -1186,19 +1300,10 @@ links: groups have links to subgroups."
                (const links))
   :group 'custom-buffer)
 
                (const links))
   :group 'custom-buffer)
 
-;; If we pass BUFFER to `bury-buffer', the buffer isn't removed from
-;; the window.
-(defun custom-bury-buffer (buffer)
-  (with-current-buffer buffer
-    (bury-buffer)))
-
-(defcustom custom-buffer-done-function 'custom-bury-buffer
-  "*Function called to remove a Custom buffer when the user is done with it.
-Called with one argument, the buffer to remove."
-  :type '(choice (function-item :tag "Bury buffer" custom-bury-buffer)
-                (function-item :tag "Kill buffer" kill-buffer)
-                (function :tag "Other"))
-  :version "21.1"
+(defcustom custom-buffer-done-kill nil
+  "*Non-nil means exiting a Custom buffer should kill it."
+  :type 'boolean
+  :version "22.1"
   :group 'custom-buffer)
 
 (defcustom custom-buffer-indent 3
   :group 'custom-buffer)
 
 (defcustom custom-buffer-indent 3
@@ -1243,21 +1348,18 @@ that option."
 
 ;;;###autoload
 (defun custom-buffer-create-other-window (options &optional name description)
 
 ;;;###autoload
 (defun custom-buffer-create-other-window (options &optional name description)
-  "Create a buffer containing OPTIONS.
+  "Create a buffer containing OPTIONS, and display it in another window.
+The result includes selecting that window.
 Optional NAME is the name of the buffer.
 OPTIONS should be an alist of the form ((SYMBOL WIDGET)...), where
 SYMBOL is a customization option, and WIDGET is a widget for editing
 that option."
   (unless name (setq name "*Customization*"))
 Optional NAME is the name of the buffer.
 OPTIONS should be an alist of the form ((SYMBOL WIDGET)...), where
 SYMBOL is a customization option, and WIDGET is a widget for editing
 that option."
   (unless name (setq name "*Customization*"))
-  (let ((window (selected-window))
-       (pop-up-windows t)
-       (special-display-buffer-names nil)
-       (special-display-regexps nil)
+  (let ((pop-up-windows t)
        (same-window-buffer-names nil)
        (same-window-regexps nil))
     (pop-to-buffer (custom-get-fresh-buffer name))
        (same-window-buffer-names nil)
        (same-window-regexps nil))
     (pop-to-buffer (custom-get-fresh-buffer name))
-    (custom-buffer-create-internal options description)
-    (select-window window)))
+    (custom-buffer-create-internal options description)))
 
 (defcustom custom-reset-button-menu nil
   "If non-nil, only show a single reset button in customize buffers.
 
 (defcustom custom-reset-button-menu nil
   "If non-nil, only show a single reset button in customize buffers.
@@ -1271,9 +1373,9 @@ This button will have a menu with all three reset operations."
   :group 'custom-buffer)
 
 (defun Custom-buffer-done (&rest ignore)
   :group 'custom-buffer)
 
 (defun Custom-buffer-done (&rest ignore)
-  "Remove current buffer by calling `custom-buffer-done-function'."
+  "Exit current Custom buffer according to `custom-buffer-done-kill'."
   (interactive)
   (interactive)
-  (funcall custom-buffer-done-function (current-buffer)))
+  (quit-window custom-buffer-done-kill))
 
 (defcustom custom-raised-buttons (not (equal (face-valid-attribute-values :box)
                                             '(("unspecified" . unspecified))))
 
 (defcustom custom-raised-buttons (not (equal (face-valid-attribute-values :box)
                                             '(("unspecified" . unspecified))))
@@ -1284,7 +1386,6 @@ Otherwise use brackets."
   :group 'custom-buffer)
 
 (defun custom-buffer-create-internal (options &optional description)
   :group 'custom-buffer)
 
 (defun custom-buffer-create-internal (options &optional description)
-  (message "Creating customization buffer...")
   (custom-mode)
   (if custom-buffer-verbose-help
       (progn
   (custom-mode)
   (if custom-buffer-verbose-help
       (progn
@@ -1294,17 +1395,23 @@ Otherwise use brackets."
        (widget-insert (format ".
 %s show active fields; type RET or click mouse-1
 on an active field to invoke its action.  Editing an option value
        (widget-insert (format ".
 %s show active fields; type RET or click mouse-1
 on an active field to invoke its action.  Editing an option value
-changes the text in the buffer; invoke the State button and
-choose the Set operation to set the option value.
-Invoke " (if custom-raised-buttons
-            "`Raised' buttons"
-            "Square brackets")))
+changes only the text in the buffer.  Invoke the State button to set or
+save the option value.  Saving an option normally edits your init file.
+Invoke "
+                              (if custom-raised-buttons
+                                  "`Raised' buttons"
+                                "Square brackets")))
+       (widget-create 'info-link
+                      :tag "Custom file"
+                      "(emacs)Saving Customizations")
+       (widget-insert
+        " for information on how to save in a different file.
+Invoke ")
        (widget-create 'info-link
                       :tag "Help"
                       :help-echo "Read the online help."
                       "(emacs)Easy Customization")
        (widget-create 'info-link
                       :tag "Help"
                       :help-echo "Read the online help."
                       "(emacs)Easy Customization")
-       (widget-insert " for more information.\n\n")
-       (message "Creating customization buttons...")
+       (widget-insert " for general information.\n\n")
        (widget-insert "Operate on everything in this buffer:\n "))
     (widget-insert " "))
   (widget-create 'push-button
        (widget-insert "Operate on everything in this buffer:\n "))
     (widget-insert " "))
   (widget-create 'push-button
@@ -1317,7 +1424,8 @@ Make your editing in this buffer take effect for this session."
   (widget-create 'push-button
                 :tag "Save for Future Sessions"
                 :help-echo "\
   (widget-create 'push-button
                 :tag "Save for Future Sessions"
                 :help-echo "\
-Make your editing in this buffer take effect for future Emacs sessions."
+Make your editing in this buffer take effect for future Emacs sessions.
+This updates your Emacs initialization file or creates a new one."
                 :action (lambda (widget &optional event)
                           (Custom-save)))
   (if custom-reset-button-menu
                 :action (lambda (widget &optional event)
                           (Custom-save)))
   (if custom-reset-button-menu
@@ -1359,13 +1467,9 @@ Un-customize all values in this buffer.  They get their standard settings."
                 :tag "Finish"
                 :help-echo
                 (lambda (&rest ignore)
                 :tag "Finish"
                 :help-echo
                 (lambda (&rest ignore)
-                  (cond
-                   ((eq custom-buffer-done-function
-                        'custom-bury-buffer)
-                    "Bury this buffer")
-                   ((eq custom-buffer-done-function 'kill-buffer)
-                    "Kill this buffer")
-                   (t "Finish with this buffer")))
+                  (if custom-buffer-done-kill
+                      "Kill this buffer"
+                    "Bury this buffer"))
                 :action #'Custom-buffer-done)
   (widget-insert "\n\n")
   (message "Creating customization items...")
                 :action #'Custom-buffer-done)
   (widget-insert "\n\n")
   (message "Creating customization items...")
@@ -1398,13 +1502,15 @@ Un-customize all values in this buffer.  They get their standard settings."
   (unless (eq (preceding-char) ?\n)
     (widget-insert "\n"))
   (message "Creating customization items ...done")
   (unless (eq (preceding-char) ?\n)
     (widget-insert "\n"))
   (message "Creating customization items ...done")
+  (message "Resetting customization items...")
   (unless (eq custom-buffer-style 'tree)
     (mapc 'custom-magic-reset custom-options))
   (unless (eq custom-buffer-style 'tree)
     (mapc 'custom-magic-reset custom-options))
+  (message "Resetting customization items...done")
   (message "Creating customization setup...")
   (widget-setup)
   (buffer-enable-undo)
   (goto-char (point-min))
   (message "Creating customization setup...")
   (widget-setup)
   (buffer-enable-undo)
   (goto-char (point-min))
-  (message "Creating customization buffer...done"))
+  (message "Creating customization setup...done"))
 
 ;;; The Tree Browser.
 
 
 ;;; The Tree Browser.
 
@@ -1544,71 +1650,90 @@ item in another window.\n\n"))
   :group 'custom-faces
   :group 'custom-buffer)
 
   :group 'custom-faces
   :group 'custom-buffer)
 
-(defface custom-invalid-face '((((class color))
-                               (:foreground "yellow" :background "red"))
-                              (t
-                               (:weight bold :slant italic :underline t)))
+(defface custom-invalid '((((class color))
+                          (:foreground "yellow1" :background "red1"))
+                         (t
+                          (:weight bold :slant italic :underline t)))
   "Face used when the customize item is invalid."
   :group 'custom-magic-faces)
   "Face used when the customize item is invalid."
   :group 'custom-magic-faces)
+;; backward-compatibility alias
+(put 'custom-invalid-face 'face-alias 'custom-invalid)
 
 
-(defface custom-rogue-face '((((class color))
-                             (:foreground "pink" :background "black"))
-                            (t
-                             (:underline t)))
+(defface custom-rogue '((((class color))
+                        (:foreground "pink" :background "black"))
+                       (t
+                        (:underline t)))
   "Face used when the customize item is not defined for customization."
   :group 'custom-magic-faces)
   "Face used when the customize item is not defined for customization."
   :group 'custom-magic-faces)
-
-(defface custom-modified-face '((((class color))
-                                (:foreground "white" :background "blue"))
-                               (t
-                                (:slant italic :bold)))
+;; backward-compatibility alias
+(put 'custom-rogue-face 'face-alias 'custom-rogue)
+
+(defface custom-modified '((((min-colors 88) (class color))
+                           (:foreground "white" :background "blue1"))
+                          (((class color))
+                           (:foreground "white" :background "blue"))
+                          (t
+                           (:slant italic :bold)))
   "Face used when the customize item has been modified."
   :group 'custom-magic-faces)
   "Face used when the customize item has been modified."
   :group 'custom-magic-faces)
-
-(defface custom-set-face '((((class color))
-                               (:foreground "blue" :background "white"))
-                              (t
-                               (:slant italic)))
+;; backward-compatibility alias
+(put 'custom-modified-face 'face-alias 'custom-modified)
+
+(defface custom-set '((((min-colors 88) (class color))
+                      (:foreground "blue1" :background "white"))
+                     (((class color))
+                      (:foreground "blue" :background "white"))
+                     (t
+                      (:slant italic)))
   "Face used when the customize item has been set."
   :group 'custom-magic-faces)
   "Face used when the customize item has been set."
   :group 'custom-magic-faces)
-
-(defface custom-changed-face '((((class color))
-                               (:foreground "white" :background "blue"))
-                              (t
-                               (:slant italic)))
+;; backward-compatibility alias
+(put 'custom-set-face 'face-alias 'custom-set)
+
+(defface custom-changed '((((min-colors 88) (class color))
+                          (:foreground "white" :background "blue1"))
+                         (((class color))
+                          (:foreground "white" :background "blue"))
+                         (t
+                          (:slant italic)))
   "Face used when the customize item has been changed."
   :group 'custom-magic-faces)
   "Face used when the customize item has been changed."
   :group 'custom-magic-faces)
+;; backward-compatibility alias
+(put 'custom-changed-face 'face-alias 'custom-changed)
 
 
-(defface custom-saved-face '((t (:underline t)))
+(defface custom-saved '((t (:underline t)))
   "Face used when the customize item has been saved."
   :group 'custom-magic-faces)
   "Face used when the customize item has been saved."
   :group 'custom-magic-faces)
-
-(defconst custom-magic-alist '((nil "#" underline "\
-uninitialized, you should not see this.")
-                              (unknown "?" italic "\
-unknown, you should not see this.")
-                              (hidden "-" default "\
-hidden, invoke \"Show\" in the previous line to show." "\
+;; backward-compatibility alias
+(put 'custom-saved-face 'face-alias 'custom-saved)
+
+(defconst custom-magic-alist
+  '((nil "#" underline "\
+UNINITIALIZED, you should not see this.")
+    (unknown "?" italic "\
+UNKNOWN, you should not see this.")
+    (hidden "-" default "\
+HIDDEN, invoke \"Show\" in the previous line to show." "\
 group now hidden, invoke \"Show\", above, to show contents.")
 group now hidden, invoke \"Show\", above, to show contents.")
-                              (invalid "x" custom-invalid-face "\
-the value displayed for this %c is invalid and cannot be set.")
-                              (modified "*" custom-modified-face "\
-you have edited the value as text, but you have not set the %c." "\
-you have edited something in this group, but not set it.")
-                              (set "+" custom-set-face "\
-you have set this %c, but not saved it for future sessions." "\
-something in this group has been set, but not saved.")
-                              (changed ":" custom-changed-face "\
-this %c has been changed outside the customize buffer." "\
+    (invalid "x" custom-invalid "\
+INVALID, the displayed value cannot be set.")
+    (modified "*" custom-modified "\
+EDITED, shown value does not take effect until you set or save it." "\
+something in this group has been edited but not set.")
+    (set "+" custom-set "\
+SET for current session only." "\
+something in this group has been set but not saved.")
+    (changed ":" custom-changed "\
+CHANGED outside Customize; operating on it here may be unreliable." "\
 something in this group has been changed outside customize.")
 something in this group has been changed outside customize.")
-                              (saved "!" custom-saved-face "\
-this %c has been set and saved." "\
+    (saved "!" custom-saved "\
+SAVED and set." "\
 something in this group has been set and saved.")
 something in this group has been set and saved.")
-                              (rogue "@" custom-rogue-face "\
-this %c has not been changed with customize." "\
+    (rogue "@" custom-rogue "\
+NO CUSTOMIZATION DATA; you should not see this." "\
 something in this group is not prepared for customization.")
 something in this group is not prepared for customization.")
-                              (standard " " nil "\
-this %c is unchanged from its standard setting." "\
+    (standard " " nil "\
+STANDARD." "\
 visible group members are all at standard settings."))
   "Alist of customize option states.
 Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where
 visible group members are all at standard settings."))
   "Alist of customize option states.
 Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where
@@ -1628,7 +1753,7 @@ STATE is one of the following symbols:
 `set'
    This item has been set but not saved.
 `changed'
 `set'
    This item has been set but not saved.
 `changed'
-   The current value of this item has been changed temporarily.
+   The current value of this item has been changed outside Customize.
 `saved'
    This item is marked for saving.
 `rogue'
 `saved'
    This item is marked for saving.
 `rogue'
@@ -1731,7 +1856,7 @@ and `face'."
               (insert " (lisp)"))
              ((eq form 'mismatch)
               (insert " (mismatch)")))
               (insert " (lisp)"))
              ((eq form 'mismatch)
               (insert " (mismatch)")))
-       (put-text-property start (point) 'face 'custom-state-face))
+       (put-text-property start (point) 'face 'custom-state))
       (insert "\n"))
     (when (and (eq category 'group)
               (not (and (eq custom-buffer-style 'links)
       (insert "\n"))
     (when (and (eq category 'group)
               (not (and (eq custom-buffer-style 'links)
@@ -1765,7 +1890,7 @@ and `face'."
 
 ;;; The `custom' Widget.
 
 
 ;;; The `custom' Widget.
 
-(defface custom-button-face
+(defface custom-button
   '((((type x w32 mac) (class color))          ; Like default modeline
      (:box (:line-width 2 :style released-button)
           :background "lightgrey" :foreground "black"))
   '((((type x w32 mac) (class color))          ; Like default modeline
      (:box (:line-width 2 :style released-button)
           :background "lightgrey" :foreground "black"))
@@ -1774,8 +1899,10 @@ and `face'."
   "Face used for buttons in customization buffers."
   :version "21.1"
   :group 'custom-faces)
   "Face used for buttons in customization buffers."
   :version "21.1"
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-button-face 'face-alias 'custom-button)
 
 
-(defface custom-button-pressed-face
+(defface custom-button-pressed
   '((((type x w32 mac) (class color))
      (:box (:line-width 2 :style pressed-button)
           :background "lightgrey" :foreground "black"))
   '((((type x w32 mac) (class color))
      (:box (:line-width 2 :style pressed-button)
           :background "lightgrey" :foreground "black"))
@@ -1784,20 +1911,26 @@ and `face'."
   "Face used for buttons in customization buffers."
   :version "21.1"
   :group 'custom-faces)
   "Face used for buttons in customization buffers."
   :version "21.1"
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-button-pressed-face 'face-alias 'custom-button-pressed)
 
 
-(defface custom-documentation-face nil
+(defface custom-documentation nil
   "Face used for documentation strings in customization buffers."
   :group 'custom-faces)
   "Face used for documentation strings in customization buffers."
   :group 'custom-faces)
-
-(defface custom-state-face '((((class color)
-                              (background dark))
-                             (:foreground "lime green"))
-                            (((class color)
-                              (background light))
-                             (:foreground "dark green"))
-                            (t nil))
+;; backward-compatibility alias
+(put 'custom-documentation-face 'face-alias 'custom-documentation)
+
+(defface custom-state '((((class color)
+                         (background dark))
+                        (:foreground "lime green"))
+                       (((class color)
+                         (background light))
+                        (:foreground "dark green"))
+                       (t nil))
   "Face used for State descriptions in the customize buffer."
   :group 'custom-faces)
   "Face used for State descriptions in the customize buffer."
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-state-face 'face-alias 'custom-state)
 
 (define-widget 'custom 'default
   "Customize a user option."
 
 (define-widget 'custom 'default
   "Customize a user option."
@@ -1879,7 +2012,7 @@ and `face'."
   (custom-load-symbol (widget-value widget)))
 
 (defun custom-unloaded-symbol-p (symbol)
   (custom-load-symbol (widget-value widget)))
 
 (defun custom-unloaded-symbol-p (symbol)
-  "Return non-nil if the dependencies of SYMBOL has not yet been loaded."
+  "Return non-nil if the dependencies of SYMBOL have not yet been loaded."
   (let ((found nil)
        (loads (get symbol 'custom-loads))
        load)
   (let ((found nil)
        (loads (get symbol 'custom-loads))
        load)
@@ -1897,7 +2030,7 @@ and `face'."
     found))
 
 (defun custom-unloaded-widget-p (widget)
     found))
 
 (defun custom-unloaded-widget-p (widget)
-  "Return non-nil if the dependencies of WIDGET has not yet been loaded."
+  "Return non-nil if the dependencies of WIDGET have not yet been loaded."
   (custom-unloaded-symbol-p (widget-value widget)))
 
 (defun custom-toggle-hide (widget)
   (custom-unloaded-symbol-p (widget-value widget)))
 
 (defun custom-toggle-hide (widget)
@@ -1954,7 +2087,7 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
        (type (widget-type widget))
        (buttons (widget-get widget :buttons))
        (start (point))
        (type (widget-type widget))
        (buttons (widget-get widget :buttons))
        (start (point))
-       found)
+       (parents nil))
     (insert (or initial-string "Parent groups:"))
     (mapatoms (lambda (symbol)
                (let ((entry (assq name (get symbol 'custom-group))))
     (insert (or initial-string "Parent groups:"))
     (mapatoms (lambda (symbol)
                (let ((entry (assq name (get symbol 'custom-group))))
@@ -1965,30 +2098,50 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
                           :tag (custom-unlispify-tag-name symbol)
                           symbol)
                          buttons)
                           :tag (custom-unlispify-tag-name symbol)
                           symbol)
                          buttons)
-                   (setq found t)))))
-    (widget-put widget :buttons buttons)
-    (if found
-       (insert "\n")
+                   (setq parents (cons symbol parents))))))
+    (and (null (get name 'custom-links)) ;No links of its own.
+         (= (length parents) 1)         ;A single parent.
+         (let* ((links (get (car parents) 'custom-links))
+                (many (> (length links) 2)))
+           (when links
+             (insert "\nParent documentation: ")
+             (while links
+               (push (widget-create-child-and-convert widget (car links))
+                     buttons)
+               (setq links (cdr links))
+               (cond ((null links)
+                      (insert ".\n"))
+                     ((null (cdr links))
+                      (if many
+                          (insert ", and ")
+                        (insert " and ")))
+                     (t
+                      (insert ", ")))))))
+    (if parents
+        (insert "\n")
       (delete-region start (point)))
       (delete-region start (point)))
-    found))
+    (widget-put widget :buttons buttons)
+    parents))
 
 ;;; The `custom-comment' Widget.
 
 ;; like the editable field
 
 ;;; The `custom-comment' Widget.
 
 ;; like the editable field
-(defface custom-comment-face '((((class grayscale color)
-                                (background light))
-                               (:background "gray85"))
-                              (((class grayscale color)
-                                (background dark))
-                               (:background "dim gray"))
-                              (t
-                               (:slant italic)))
+(defface custom-comment '((((class grayscale color)
+                           (background light))
+                          (:background "gray85"))
+                         (((class grayscale color)
+                           (background dark))
+                          (:background "dim gray"))
+                         (t
+                          (:slant italic)))
   "Face used for comments on variables or faces"
   :version "21.1"
   :group 'custom-faces)
   "Face used for comments on variables or faces"
   :version "21.1"
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-comment-face 'face-alias 'custom-comment)
 
 ;; like font-lock-comment-face
 
 ;; like font-lock-comment-face
-(defface custom-comment-tag-face
+(defface custom-comment-tag
   '((((class color) (background dark)) (:foreground "gray80"))
     (((class color) (background light)) (:foreground "blue4"))
     (((class grayscale) (background light))
   '((((class color) (background dark)) (:foreground "gray80"))
     (((class color) (background light)) (:foreground "blue4"))
     (((class grayscale) (background light))
@@ -1998,6 +2151,8 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
     (t (:weight bold)))
   "Face used for variables or faces comment tags"
   :group 'custom-faces)
     (t (:weight bold)))
   "Face used for variables or faces comment tags"
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-comment-tag-face 'face-alias 'custom-comment-tag)
 
 (define-widget 'custom-comment 'string
   "User comment."
 
 (define-widget 'custom-comment 'string
   "User comment."
@@ -2037,20 +2192,27 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
 
 ;; When this was underlined blue, users confused it with a
 ;; Mosaic-style hyperlink...
 
 ;; When this was underlined blue, users confused it with a
 ;; Mosaic-style hyperlink...
-(defface custom-variable-tag-face
+(defface custom-variable-tag
   `((((class color)
       (background dark))
      (:foreground "light blue" :weight bold :height 1.2 :inherit variable-pitch))
   `((((class color)
       (background dark))
      (:foreground "light blue" :weight bold :height 1.2 :inherit variable-pitch))
+    (((min-colors 88) (class color)
+      (background light))
+     (:foreground "blue1" :weight bold :height 1.2 :inherit variable-pitch))
     (((class color)
       (background light))
      (:foreground "blue" :weight bold :height 1.2 :inherit variable-pitch))
     (t (:weight bold)))
   "Face used for unpushable variable tags."
   :group 'custom-faces)
     (((class color)
       (background light))
      (:foreground "blue" :weight bold :height 1.2 :inherit variable-pitch))
     (t (:weight bold)))
   "Face used for unpushable variable tags."
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-variable-tag-face 'face-alias 'custom-variable-tag)
 
 
-(defface custom-variable-button-face '((t (:underline t :weight bold)))
+(defface custom-variable-button '((t (:underline t :weight bold)))
   "Face used for pushable variable tags."
   :group 'custom-faces)
   "Face used for pushable variable tags."
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-variable-button-face 'face-alias 'custom-variable-button)
 
 (defcustom custom-variable-default-form 'edit
   "Default form of displaying variable values."
 
 (defcustom custom-variable-default-form 'edit
   "Default form of displaying variable values."
@@ -2059,11 +2221,25 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
   :group 'custom-buffer
   :version "20.3")
 
   :group 'custom-buffer
   :version "20.3")
 
+(defun custom-variable-documentation (variable)
+  "Return documentation of VARIABLE for use in Custom buffer.
+Normally just return the docstring.  But if VARIABLE automatically
+becomes buffer local when set, append a message to that effect."
+  (if (and (local-variable-if-set-p variable)
+          (or (not (local-variable-p variable))
+              (with-temp-buffer
+                (local-variable-if-set-p variable))))
+      (concat (documentation-property variable 'variable-documentation)
+             "\n
+This variable automatically becomes buffer-local when set outside Custom.
+However, setting it through Custom sets the default value.")
+    (documentation-property variable 'variable-documentation)))
+
 (define-widget 'custom-variable 'custom
   "Customize variable."
   :format "%v"
   :help-echo "Set or reset this variable."
 (define-widget 'custom-variable 'custom
   "Customize variable."
   :format "%v"
   :help-echo "Set or reset this variable."
-  :documentation-property 'variable-documentation
+  :documentation-property #'custom-variable-documentation
   :custom-category 'option
   :custom-state nil
   :custom-menu 'custom-variable-menu-create
   :custom-category 'option
   :custom-state nil
   :custom-menu 'custom-variable-menu-create
@@ -2549,7 +2725,7 @@ to switch between two values."
   "Edit face attributes."
   :format "%t: %v"
   :tag "Attributes"
   "Edit face attributes."
   :format "%t: %v"
   :tag "Attributes"
-  :extra-offset 12
+  :extra-offset 13
   :button-args '(:help-echo "Control whether this attribute has any effect.")
   :value-to-internal 'custom-face-edit-fix-value
   :match (lambda (widget value)
   :button-args '(:help-echo "Control whether this attribute has any effect.")
   :value-to-internal 'custom-face-edit-fix-value
   :match (lambda (widget value)
@@ -2631,7 +2807,7 @@ Also change :reverse-video to :inverse-video."
        (widget-setup)))))
 
 (defun custom-face-edit-delete (widget)
        (widget-setup)))))
 
 (defun custom-face-edit-delete (widget)
-  "Remove widget from the buffer."
+  "Remove WIDGET from the buffer."
   (let ((inactive (widget-get widget :inactive))
        (inhibit-read-only t)
        (inhibit-modification-hooks t))
   (let ((inactive (widget-get widget :inactive))
        (inhibit-read-only t)
        (inhibit-modification-hooks t))
@@ -2662,6 +2838,7 @@ Also change :reverse-video to :inverse-video."
   :value t
   :help-echo "Specify frames where the face attributes should be used."
   :args '((const :tag "all" t)
   :value t
   :help-echo "Specify frames where the face attributes should be used."
   :args '((const :tag "all" t)
+         (const :tag "defaults" default)
          (checklist
           :offset 0
           :extra-offset 9
          (checklist
           :offset 0
           :extra-offset 9
@@ -2714,6 +2891,10 @@ Match grayscale frames.")
 Match frames with no color support.")
                                           mono)))
                  (group :sibling-args (:help-echo "\
 Match frames with no color support.")
                                           mono)))
                  (group :sibling-args (:help-echo "\
+The minimum number of colors the frame should support.")
+                        (const :format "" min-colors)
+                        (integer :tag "Minimum number of colors" ))
+                 (group :sibling-args (:help-echo "\
 Only match frames with the specified intensity.")
                         (const :format "\
 Background brightness: "
 Only match frames with the specified intensity.")
                         (const :format "\
 Background brightness: "
@@ -2735,10 +2916,12 @@ Only match frames that support the specified face attributes.")
 
 ;;; The `custom-face' Widget.
 
 
 ;;; The `custom-face' Widget.
 
-(defface custom-face-tag-face
+(defface custom-face-tag
   `((t (:weight bold :height 1.2 :inherit variable-pitch)))
   "Face used for face tags."
   :group 'custom-faces)
   `((t (:weight bold :height 1.2 :inherit variable-pitch)))
   "Face used for face tags."
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-face-tag-face 'face-alias 'custom-face-tag)
 
 (defcustom custom-face-default-form 'selected
   "Default form of displaying face definition."
 
 (defcustom custom-face-default-form 'selected
   "Default form of displaying face definition."
@@ -2786,13 +2969,29 @@ Only match frames that support the specified face attributes.")
 
 (define-widget 'custom-face-selected 'group
   "Edit the attributes of the selected display in a face specification."
 
 (define-widget 'custom-face-selected 'group
   "Edit the attributes of the selected display in a face specification."
-  :args '((repeat :format ""
-                 :inline t
-                 (group custom-display-unselected sexp))
-         (group (sexp :format "") custom-face-edit)
-         (repeat :format ""
-                 :inline t
-                 sexp)))
+  :args '((choice :inline t
+                 (group :tag "With Defaults" :inline t
+                  (group (const :tag "" default)
+                         (custom-face-edit :tag " Default\n Attributes"))
+                  (repeat :format ""
+                          :inline t
+                          (group custom-display-unselected sexp))
+                  (group (sexp :format "")
+                         (custom-face-edit :tag " Overriding\n Attributes"))
+                  (repeat :format ""
+                          :inline t
+                          sexp))
+                 (group :tag "No Defaults" :inline t
+                        (repeat :format ""
+                                :inline t
+                                (group custom-display-unselected sexp))
+                        (group (sexp :format "")
+                               (custom-face-edit :tag "\n Attributes"))
+                        (repeat :format ""
+                                :inline t
+                                sexp)))))
+
+
 
 (defconst custom-face-selected (widget-convert 'custom-face-selected)
   "Converted version of the `custom-face-selected' widget.")
 
 (defconst custom-face-selected (widget-convert 'custom-face-selected)
   "Converted version of the `custom-face-selected' widget.")
@@ -3151,54 +3350,41 @@ restoring it to the state of a face that has never been customized."
 
 ;;; The `face' Widget.
 
 
 ;;; The `face' Widget.
 
-(define-widget 'face 'default
-  "Select and customize a face."
-  :convert-widget 'widget-value-convert-widget
-  :button-prefix 'widget-push-button-prefix
-  :button-suffix 'widget-push-button-suffix
-  :format "%{%t%}: %[select face%] %v"
+(defvar widget-face-prompt-value-history nil
+  "History of input to `widget-face-prompt-value'.")
+
+(define-widget 'face 'symbol
+  "A Lisp face name (with sample)."
+  :format "%t: (%{sample%}) %v"
   :tag "Face"
   :value 'default
   :tag "Face"
   :value 'default
-  :value-create 'widget-face-value-create
-  :value-delete 'widget-face-value-delete
-  :value-get 'widget-value-value-get
-  :validate 'widget-children-validate
-  :action 'widget-face-action
-  :match (lambda (widget value) (symbolp value)))
+  :sample-face-get 'widget-face-sample-face-get
+  :notify 'widget-face-notify
+  :match (lambda (widget value) (facep value))
+  :complete-function (lambda ()
+                      (interactive)
+                      (lisp-complete-symbol 'facep))
+  :prompt-match 'facep
+  :prompt-history 'widget-face-prompt-value-history
+  :validate (lambda (widget)
+             (unless (facep (widget-value widget))
+               (widget-put widget
+                           :error (format "Invalid face: %S"
+                                          (widget-value widget)))
+               widget)))
+
+(defun widget-face-sample-face-get (widget)
+  (let ((value (widget-value widget)))
+    (if (facep value)
+       value
+      'default)))
+
+(defun widget-face-notify (widget child &optional event)
+  "Update the sample, and notify the parent."
+  (overlay-put (widget-get widget :sample-overlay)
+              'face (widget-apply widget :sample-face-get))
+  (widget-default-notify widget child event))
 
 
-(defun widget-face-value-create (widget)
-  "Create a `custom-face' child."
-  (let* ((symbol (widget-value widget))
-        (custom-buffer-style 'face)
-        (child (widget-create-child-and-convert
-                widget 'custom-face
-                :custom-level nil
-                :value symbol)))
-    (custom-magic-reset child)
-    (setq custom-options (cons child custom-options))
-    (widget-put widget :children (list child))))
-
-(defun widget-face-value-delete (widget)
-  "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)))
-
-(defvar face-history nil
-  "History of entered face names.")
-
-(defun widget-face-action (widget &optional event)
-  "Prompt for a face."
-  (let ((answer (completing-read "Face: "
-                                (mapcar (lambda (face)
-                                          (list (symbol-name face)))
-                                        (face-list))
-                                nil nil nil
-                                'face-history)))
-    (unless (zerop (length answer))
-      (widget-value-set widget (intern answer))
-      (widget-apply widget :notify widget event)
-      (widget-setup))))
 
 ;;; The `hook' Widget.
 
 
 ;;; The `hook' Widget.
 
@@ -3254,32 +3440,41 @@ restoring it to the state of a face that has never been customized."
   ;; Fixme: make it do so in Emacs.
   "Face used for group tags.
 The first member is used for level 1 groups, the second for level 2,
   ;; Fixme: make it do so in Emacs.
   "Face used for group tags.
 The first member is used for level 1 groups, the second for level 2,
-and so forth.  The remaining group tags are shown with
-`custom-group-tag-face'."
+and so forth.  The remaining group tags are shown with `custom-group-tag'."
   :type '(repeat face)
   :group 'custom-faces)
 
   :type '(repeat face)
   :group 'custom-faces)
 
-(defface custom-group-tag-face-1
+(defface custom-group-tag-1
   `((((class color)
       (background dark))
      (:foreground "pink" :weight bold :height 1.2 :inherit variable-pitch))
   `((((class color)
       (background dark))
      (:foreground "pink" :weight bold :height 1.2 :inherit variable-pitch))
+    (((min-colors 88) (class color)
+      (background light))
+     (:foreground "red1" :weight bold :height 1.2 :inherit variable-pitch))
     (((class color)
       (background light))
      (:foreground "red" :weight bold :height 1.2 :inherit variable-pitch))
     (t (:weight bold)))
   "Face used for group tags."
   :group 'custom-faces)
     (((class color)
       (background light))
      (:foreground "red" :weight bold :height 1.2 :inherit variable-pitch))
     (t (:weight bold)))
   "Face used for group tags."
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-group-tag-face-1 'face-alias 'custom-group-tag-1)
 
 
-(defface custom-group-tag-face
+(defface custom-group-tag
   `((((class color)
       (background dark))
      (:foreground "light blue" :weight bold :height 1.2))
   `((((class color)
       (background dark))
      (:foreground "light blue" :weight bold :height 1.2))
+    (((min-colors 88) (class color)
+      (background light))
+     (:foreground "blue1" :weight bold :height 1.2))
     (((class color)
       (background light))
      (:foreground "blue" :weight bold :height 1.2))
     (t (:weight bold)))
   "Face used for low level group tags."
   :group 'custom-faces)
     (((class color)
       (background light))
      (:foreground "blue" :weight bold :height 1.2))
     (t (:weight bold)))
   "Face used for low level group tags."
   :group 'custom-faces)
+;; backward-compatibility alias
+(put 'custom-group-tag-face 'face-alias 'custom-group-tag)
 
 (define-widget 'custom-group 'custom
   "Customize group."
 
 (define-widget 'custom-group 'custom
   "Customize group."
@@ -3300,7 +3495,7 @@ and so forth.  The remaining group tags are shown with
 (defun custom-group-sample-face-get (widget)
   ;; Use :sample-face.
   (or (nth (1- (widget-get widget :custom-level)) custom-group-tag-faces)
 (defun custom-group-sample-face-get (widget)
   ;; Use :sample-face.
   (or (nth (1- (widget-get widget :custom-level)) custom-group-tag-faces)
-      'custom-group-tag-face))
+      'custom-group-tag))
 
 (define-widget 'custom-group-visibility 'visibility
   "An indicator and manipulator for hidden group contents."
 
 (define-widget 'custom-group-visibility 'visibility
   "An indicator and manipulator for hidden group contents."
@@ -3641,46 +3836,96 @@ Optional EVENT is the location for the menu."
            (setq magics (cdr magics)))))
       (widget-put widget :custom-state found)))
   (custom-magic-reset widget))
            (setq magics (cdr magics)))))
       (widget-put widget :custom-state found)))
   (custom-magic-reset widget))
+\f
+;;; Reading and writing the custom file.
 
 
-;;; The `custom-save-all' Function.
 ;;;###autoload
 (defcustom custom-file nil
   "File used for storing customization information.
 The default is nil, which means to use your init file
 ;;;###autoload
 (defcustom custom-file nil
   "File used for storing customization information.
 The default is nil, which means to use your init file
-as specified by `user-init-file'.  If you specify some other file,
-you need to explicitly load that file for the settings to take effect.
-
-When you change this variable, look in the previous custom file
-\(usually your init file) for the forms `(custom-set-variables ...)'
-and `(custom-set-faces ...)', and copy them (whichever ones you find)
-to the new custom file.  This will preserve your existing customizations."
-  :type '(choice (const :tag "Your Emacs init file" nil) file)
+as specified by `user-init-file'.  If the value is not nil,
+it should be an absolute file name.
+
+You can set this option through Custom, if you carefully read the
+last paragraph below.  However, usually it is simpler to write
+something like the following in your init file:
+
+\(setq custom-file \"~/.emacs-custom.el\")
+\(load custom-file)
+
+Note that both lines are necessary: the first line tells Custom to
+save all customizations in this file, but does not load it.
+
+When you change this variable outside Custom, look in the
+previous custom file \(usually your init file) for the
+forms `(custom-set-variables ...)'  and `(custom-set-faces ...)',
+and copy them (whichever ones you find) to the new custom file.
+This will preserve your existing customizations.
+
+If you save this option using Custom, Custom will write all
+currently saved customizations, including the new one for this
+option itself, into the file you specify, overwriting any
+`custom-set-variables' and `custom-set-faces' forms already
+present in that file.  It will not delete any customizations from
+the old custom file.  You should do that manually if that is what you
+want.  You also have to put something like `\(load \"CUSTOM-FILE\")
+in your init file, where CUSTOM-FILE is the actual name of the
+file.  Otherwise, Emacs will not load the file when it starts up,
+and hence will not set `custom-file' to that file either."
+  :type '(choice (const :tag "Your Emacs init file" nil)
+                (file :format "%t:%v%d"
+                      :doc
+                      "Please read entire docstring below before setting \
+this through Custom.
+Click om \"More\" \(or position point there and press RETURN)
+if only the first line of the docstring is shown."))
   :group 'customize)
 
 (defun custom-file ()
   "Return the file name for saving customizations."
   :group 'customize)
 
 (defun custom-file ()
   "Return the file name for saving customizations."
-  (setq custom-file
-       (or custom-file
-           (let ((user-init-file user-init-file)
-                 (default-init-file
-                   (if (eq system-type 'ms-dos) "~/_emacs" "~/.emacs")))
-             (when (null user-init-file)
-               (if (or (file-exists-p default-init-file)
-                       (and (eq system-type 'windows-nt)
-                            (file-exists-p "~/_emacs")))
-                   ;; Started with -q, i.e. the file containing
-                   ;; Custom settings hasn't been read.  Saving
-                   ;; settings there would overwrite other settings.
-                   (error "Saving settings from \"emacs -q\" would overwrite existing customizations"))
-               (setq user-init-file default-init-file))
-             user-init-file))))
+  (file-chase-links
+   (or custom-file
+       (let ((user-init-file user-init-file)
+            (default-init-file
+              (if (eq system-type 'ms-dos) "~/_emacs" "~/.emacs")))
+        (when (null user-init-file)
+          (if (or (file-exists-p default-init-file)
+                  (and (eq system-type 'windows-nt)
+                       (file-exists-p "~/_emacs")))
+              ;; Started with -q, i.e. the file containing
+              ;; Custom settings hasn't been read.  Saving
+              ;; settings there would overwrite other settings.
+              (error "Saving settings from \"emacs -q\" would overwrite existing customizations"))
+          (setq user-init-file default-init-file))
+        user-init-file))))
+
+;;;###autoload
+(defun custom-save-all ()
+  "Save all customizations in `custom-file'."
+  (let* ((filename (custom-file))
+        (recentf-exclude (if recentf-mode
+                             (cons (concat "\\`"
+                                           (regexp-quote (custom-file))
+                                           "\\'")
+                                   recentf-exclude)))
+        (old-buffer (find-buffer-visiting filename)))
+    (with-current-buffer (or old-buffer (find-file-noselect filename))
+      (let ((inhibit-read-only t))
+       (custom-save-variables)
+       (custom-save-faces))
+      (let ((file-precious-flag t))
+       (save-buffer))
+      (unless old-buffer
+       (kill-buffer (current-buffer))))))
+\f
+;; Editing the custom file contents in a buffer.
 
 (defun custom-save-delete (symbol)
 
 (defun custom-save-delete (symbol)
-  "Visit `custom-file' and delete all calls to SYMBOL from it.
+  "Delete all calls to SYMBOL from the contents of the current buffer.
 Leave point at the old location of the first such call,
 Leave point at the old location of the first such call,
-or (if there were none) at the end of the buffer."
-  (let ((default-major-mode 'emacs-lisp-mode))
-    (set-buffer (find-file-noselect (custom-file))))
+or (if there were none) at the end of the buffer.
+
+This function does not save the buffer."
   (goto-char (point-min))
   ;; Skip all whitespace and comments.
   (while (forward-comment 1))
   (goto-char (point-min))
   ;; Skip all whitespace and comments.
   (while (forward-comment 1))
@@ -3900,19 +4145,7 @@ or (if there were none) at the end of the buffer."
                  (put symbol 'customized-face-comment nil)))))
   ;; We really should update all custom buffers here.
   (custom-save-all))
                  (put symbol 'customized-face-comment nil)))))
   ;; We really should update all custom buffers here.
   (custom-save-all))
-
-;;;###autoload
-(defun custom-save-all ()
-  "Save all customizations in `custom-file'."
-  (let ((inhibit-read-only t))
-    (custom-save-variables)
-    (custom-save-faces)
-    (save-excursion
-      (let ((default-major-mode nil))
-       (set-buffer (find-file-noselect (custom-file))))
-      (let ((file-precious-flag t))
-       (save-buffer)))))
-
+\f
 ;;; The Customize Menu.
 
 ;;; Menu support
 ;;; The Customize Menu.
 
 ;;; Menu support
@@ -3997,22 +4230,24 @@ The format is suitable for use with `easy-menu-define'."
 
 ;;; The Custom Mode.
 
 
 ;;; The Custom Mode.
 
-(defvar custom-mode-map nil
-  "Keymap for `custom-mode'.")
-
-(unless custom-mode-map
+(defvar custom-mode-map
   ;; This keymap should be dense, but a dense keymap would prevent inheriting
   ;; "\r" bindings from the parent map.
   ;; This keymap should be dense, but a dense keymap would prevent inheriting
   ;; "\r" bindings from the parent map.
-  (setq custom-mode-map (make-sparse-keymap))
-  (set-keymap-parent custom-mode-map widget-keymap)
-  (suppress-keymap custom-mode-map)
-  (define-key custom-mode-map " " 'scroll-up)
-  (define-key custom-mode-map "\177" 'scroll-down)
-  (define-key custom-mode-map "q" 'Custom-buffer-done)
-  (define-key custom-mode-map "u" 'Custom-goto-parent)
-  (define-key custom-mode-map "n" 'widget-forward)
-  (define-key custom-mode-map "p" 'widget-backward)
-  (define-key custom-mode-map [mouse-1] 'Custom-move-and-invoke))
+  ;; Actually, this misfeature of dense keymaps was fixed on 2001-11-26.
+  (let ((map (make-keymap)))
+    (set-keymap-parent map widget-keymap)
+    (suppress-keymap map)
+    (define-key map " " 'scroll-up)
+    (define-key map "\177" 'scroll-down)
+    (define-key map "\C-c\C-c" 'Custom-set)
+    (define-key map "\C-x\C-s" 'Custom-save)
+    (define-key map "q" 'Custom-buffer-done)
+    (define-key map "u" 'Custom-goto-parent)
+    (define-key map "n" 'widget-forward)
+    (define-key map "p" 'widget-backward)
+    (define-key map [mouse-1] 'Custom-move-and-invoke)
+    map)
+  "Keymap for `custom-mode'.")
 
 (defun Custom-move-and-invoke (event)
   "Move to where you click, and if it is an active field, invoke it."
 
 (defun Custom-move-and-invoke (event)
   "Move to where you click, and if it is an active field, invoke it."
@@ -4034,7 +4269,7 @@ The format is suitable for use with `easy-menu-define'."
     ["Reset to Current" Custom-reset-current t]
     ["Reset to Saved" Custom-reset-saved t]
     ["Reset to Standard Settings" Custom-reset-standard t]
     ["Reset to Current" Custom-reset-current t]
     ["Reset to Saved" Custom-reset-saved t]
     ["Reset to Standard Settings" Custom-reset-standard t]
-    ["Info" (Info-goto-node "(emacs)Easy Customization") t]))
+    ["Info" (info "(emacs)Easy Customization") t]))
 
 (defun Custom-goto-parent ()
   "Go to the parent group listed at the top of this buffer.
 
 (defun Custom-goto-parent ()
   "Go to the parent group listed at the top of this buffer.
@@ -4084,13 +4319,12 @@ if that value is non-nil."
   (make-local-variable 'custom-options)
   (make-local-variable 'custom-local-buffer)
   (make-local-variable 'widget-documentation-face)
   (make-local-variable 'custom-options)
   (make-local-variable 'custom-local-buffer)
   (make-local-variable 'widget-documentation-face)
-  (setq widget-documentation-face 'custom-documentation-face)
+  (setq widget-documentation-face 'custom-documentation)
   (make-local-variable 'widget-button-face)
   (make-local-variable 'widget-button-face)
-  (setq widget-button-face 'custom-button-face)
-  (set (make-local-variable 'widget-button-pressed-face)
-       'custom-button-pressed-face)
+  (setq widget-button-face 'custom-button)
+  (set (make-local-variable 'widget-button-pressed-face) 'custom-button-pressed)
   (set (make-local-variable 'widget-mouse-face)
   (set (make-local-variable 'widget-mouse-face)
-       'custom-button-pressed-face)    ; buttons `depress' when moused
+       'custom-button-pressed)         ; buttons `depress' when moused
   ;; When possible, use relief for buttons, not bracketing.  This test
   ;; may not be optimal.
   (when custom-raised-buttons
   ;; When possible, use relief for buttons, not bracketing.  This test
   ;; may not be optimal.
   (when custom-raised-buttons
@@ -4099,7 +4333,7 @@ if that value is non-nil."
     (set (make-local-variable 'widget-link-prefix) "")
     (set (make-local-variable 'widget-link-suffix) ""))
   (add-hook 'widget-edit-functions 'custom-state-buffer-message nil t)
     (set (make-local-variable 'widget-link-prefix) "")
     (set (make-local-variable 'widget-link-suffix) ""))
   (add-hook 'widget-edit-functions 'custom-state-buffer-message nil t)
-  (run-hooks 'custom-mode-hook))
+  (run-mode-hooks 'custom-mode-hook))
 
 (put 'custom-mode 'mode-class 'special)
 
 
 (put 'custom-mode 'mode-class 'special)
 
@@ -4111,4 +4345,5 @@ if that value is non-nil."
 
 (provide 'cus-edit)
 
 
 (provide 'cus-edit)
 
+;; arch-tag: 64533aa4-1b1a-48c3-8812-f9dc718e8a6f
 ;;; cus-edit.el ends here
 ;;; cus-edit.el ends here