;;; 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
;; 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:
;;
;; 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
- (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)
(defgroup customize '((widgets custom-group))
"Customization of the Customization support."
- :link '(custom-manual "(elisp)Customization")
:prefix "custom-"
:group 'help)
"Content of the modeline."
:group 'environment)
-(defgroup fill nil
- "Indenting and filling text."
- :link '(custom-manual "(emacs)Filling Text")
- :group 'editing)
-
(defgroup editing-basics nil
"Most basic editing facilities."
:group 'editing)
:group 'development)
(defgroup minibuffer nil
- "Controling the behaviour of the minibuffer."
+ "Controling the behavior of the minibuffer."
:link '(custom-manual "(emacs)Minibuffer")
: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)
(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)
- (special-display-buffer-names nil)
- (special-display-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
(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)
"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.")
;;;###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,
-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 ""))
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))
;;;###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,
-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 ""))
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
(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)))))
(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
;;;###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*"))
- (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))
- (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.
: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)
- (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))))
:group 'custom-buffer)
(defun custom-buffer-create-internal (options &optional description)
- (message "Creating customization buffer...")
(custom-mode)
(if custom-buffer-verbose-help
(progn
(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-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-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
: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...")
(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))
+ (message "Resetting customization items...done")
(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.
: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)
+;; 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)
-
-(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)
-
-(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)
-
-(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)
+;; 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)
-
-(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.")
- (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.")
- (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.")
- (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.")
- (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
`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'
(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)
;;; 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"))
"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"))
"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)
-
-(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)
+;; backward-compatibility alias
+(put 'custom-state-face 'face-alias 'custom-state)
(define-widget 'custom 'default
"Customize a user option."
(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)
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)
symbol)
buttons)
(setq parents (cons symbol parents))))))
- (and (null (get symbol 'custom-links)) ;No links of its own.
+ (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)))
;;; 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)
+;; backward-compatibility alias
+(put 'custom-comment-face 'face-alias 'custom-comment)
;; 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))
(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."
;; 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))
+ (((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)
+;; 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)
+;; 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."
: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."
- :documentation-property 'variable-documentation
+ :documentation-property #'custom-variable-documentation
:custom-category 'option
:custom-state nil
:custom-menu 'custom-variable-menu-create
"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)
(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))
: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
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: "
;;; 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)
+;; 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."
(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.")
;;; 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
- :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.
;; 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)
-(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))
+ (((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)
+;; 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))
+ (((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)
+;; backward-compatibility alias
+(put 'custom-group-tag-face 'face-alias 'custom-group-tag)
(define-widget 'custom-group 'custom
"Customize group."
(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."
(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."
- (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))))
(defun custom-save-delete (symbol)
"Visit `custom-file' and delete all calls to SYMBOL from it.
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))
+ (let ((default-major-mode 'emacs-lisp-mode)
+ (recentf-exclude (if recentf-mode
+ (cons (concat "\\`"
+ (regexp-quote (custom-file))
+ "\\'")
+ recentf-exclude))))
(set-buffer (find-file-noselect (custom-file))))
(goto-char (point-min))
;; Skip all whitespace and comments.
(custom-save-variables)
(custom-save-faces)
(save-excursion
- (let ((default-major-mode nil))
+ (let ((default-major-mode nil)
+ (recentf-exclude (if recentf-mode
+ (cons (concat "\\`"
+ (regexp-quote (custom-file))
+ "\\'")
+ recentf-exclude))))
(set-buffer (find-file-noselect (custom-file))))
(let ((file-precious-flag t))
(save-buffer)))))
;;; 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.
- (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."
["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.
(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)
- (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)
- '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
(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)
(provide 'cus-edit)
-;;; arch-tag: 64533aa4-1b1a-48c3-8812-f9dc718e8a6f
+;; arch-tag: 64533aa4-1b1a-48c3-8812-f9dc718e8a6f
;;; cus-edit.el ends here