;;; Code:
(eval-when-compile
- (load "cl-macs"))
+ (load "cl-macs" nil t))
-(if (not (fboundp 'defun*))
- (autoload 'defun* "cl-macs"))
+(autoload 'custom-declare-face "cus-face")
+(autoload 'defun* "cl-macs")
(require 'widget)
`custom-initialize-set'
:set VALUE should be a function to set the value of the symbol.
It takes two arguments, the symbol to set and the value to
- give it. The default is `set-default'.
+ give it. The default is `custom-set-default'.
:get VALUE should be a function to extract the value of symbol.
The function takes one argument, a symbol, and should return
the current value for that symbol. The default is
`default-value'.
:require VALUE should be a feature symbol. Each feature will be
- required after initialization, of the the user have saved this
+ required after initialization, of the user have saved this
option.
+:version VALUE should be a string specifying that the variable was
+ first introduced, or its default value was changed, in Emacs
+ version VERSION.
+:set-after VARIABLE specifies that SYMBOL should be set after VARIABLE when
+ both have been customized.
Read the section about customization in the Emacs Lisp manual for more
information."
match one of the ITEM. The following REQ are defined:
`type' (the value of `window-system')
- Should be one of `x' or `tty'.
+ Should be one of `x', `mswindows', or `tty'.
`class' (the frame's color support)
Should be one of `color', `grayscale', or `mono'.
"For customization option SYMBOL, handle KEYWORD with VALUE.
Fourth argument TYPE is the custom option type."
(cond ((eq keyword :group)
- (custom-add-to-group value symbol type))
- ((eq keyword :version)
- (custom-add-version symbol value))
- ((eq keyword :link)
- (custom-add-link symbol value))
- ((eq keyword :load)
- (custom-add-load symbol value))
- ((eq keyword :tag)
- (put symbol 'custom-tag value))
- (t
- (signal 'error (list "Unknown keyword" keyword)))))
+ (custom-add-to-group value symbol type))
+ ((eq keyword :version)
+ (custom-add-version symbol value))
+ ((eq keyword :link)
+ (custom-add-link symbol value))
+ ((eq keyword :load)
+ (custom-add-load symbol value))
+ ((eq keyword :tag)
+ (put symbol 'custom-tag value))
+ ((eq keyword :set-after)
+ (custom-add-dependencies symbol value))
+ (t
+ (signal 'error (list "Unknown keyword" keyword)))))
+
+(defun custom-add-dependencies (symbol value)
+ "To the custom option SYMBOL, add dependencies specified by VALUE.
+VALUE should be a list of symbols. For each symbol in that list,
+this specifies that SYMBOL should be set after the specified symbol, if
+both appear in constructs like `custom-set-variables'."
+ (unless (listp value)
+ (error "Invalid custom dependency `%s'" value))
+ (let* ((deps (get symbol 'custom-dependencies))
+ (new-deps deps))
+ (while value
+ (let ((dep (car value)))
+ (unless (symbolp dep)
+ (error "Invalid custom dependency `%s'" dep))
+ (unless (memq dep new-deps)
+ (setq new-deps (cons dep new-deps)))
+ (setq value (cdr value))))
+ (unless (eq deps new-deps)
+ (put symbol 'custom-dependencies new-deps))))
(defun custom-add-option (symbol option)
"To the variable SYMBOL add OPTION.
"(deftheme THEME &optional DOC &key KEYWORDS)
Define a theme labeled by SYMBOL THEME. The optional argument DOC is a
-doc string describing the the theme. It is optionally followed by the
-following keyboard arguments
+doc string describing the theme. It is optionally followed by the
+following keyword arguments
:short-description DESC
DESC is a short (one line) description of the theme. If not given DOC
(memq theme custom-known-themes))
(defsubst custom-check-theme (theme)
- "Check whether THEME is valid and signal an error if NOT"
+ "Check whether THEME is valid and signal an error if NOT."
(unless (custom-theme-p theme)
(error "Unknown theme `%s'" theme)))
(setq old (cdr old)))
(put symbol prop (cons (list theme mode value) old))))
+(defvar custom-local-buffer nil
+ "Non-nil, in a Customization buffer, means customize a specific buffer.
+If this variable is non-nil, it should be a buffer,
+and it means customize the local bindings of that buffer.
+This variable is a permanent local, and it normally has a local binding
+in every Customization buffer.")
+(put 'custom-local-buffer 'permanent-local t)
+
(defun custom-set-variables (&rest args)
"Initialize variables according to user preferences.
The settings are registered as theme `user'.
-The arguments should be a list where each entry has the form:
+Each argument should be a list of the form:
(SYMBOL VALUE [NOW [REQUEST [COMMENT]]])
See `custom-set-variables' for a description of the arguments ARGS."
(custom-check-theme theme)
+ (setq args
+ (sort args
+ (lambda (a1 a2)
+ (let* ((sym1 (car a1))
+ (sym2 (car a2))
+ (1-then-2 (memq sym1 (get sym2 'custom-dependencies)))
+ (2-then-1 (memq sym2 (get sym1 'custom-dependencies))))
+ (cond ((and 1-then-2 2-then-1)
+ (error "Circular custom dependency between `%s' and `%s'"
+ sym1 sym2))
+ (1-then-2 t)
+ (2-then-1 nil)
+ ;; Put symbols with :require last. The macro
+ ;; define-minor-mode generates a defcustom
+ ;; with a :require and a :set, where the
+ ;; setter function calls the mode function.
+ ;; Putting symbols with :require last ensures
+ ;; that the mode function will see other
+ ;; customized values rather than default
+ ;; values.
+ (t (nth 3 a2)))))))
(let ((immediate (get theme 'theme-immediate)))
- (while args * etc/custom/example-themes/example-theme.el:
+ (while args
(let ((entry (car args)))
(if (listp entry)
(let* ((symbol (nth 0 entry))
(now (nth 2 entry))
(requests (nth 3 entry))
(comment (nth 4 entry))
- (set (or (get symbol 'custom-set) 'set-default)))
+ (set (or (get symbol 'custom-set) 'custom-set-default)))
(put symbol 'saved-value (list value))
(custom-push-theme 'theme-value symbol theme 'set value)
(put symbol 'saved-variable-comment comment)
+ ;; Allow for errors in the case where the setter has
+ ;; changed between versions, say, but let the user know.
+ (condition-case data
(cond ((or now immediate)
;; Rogue variable, set it now.
(put symbol 'force-value (if now 'rogue 'immediate))
((default-boundp symbol)
;; Something already set this, overwrite it.
(funcall set symbol (eval value))))
+ (error
+ (message "Error setting %s: %s" symbol data)))
(and (or now (default-boundp symbol))
(put symbol 'variable-comment comment))
(when requests
(defun custom-theme-load-themes (by-theme &rest body)
"Load the themes specified by BODY and record them as required by
-theme BY-THEME. BODY is a secuence of
+theme BY-THEME. BODY is a sequence of
- a SYMBOL
require the theme SYMBOL
- a list (reset THEME)
(defsubst copy-upto-last (elt list)
- "Copy all the elements of the list upto the last occurence of elt"
+ "Copy all the elements of the list upto the last occurrence of elt."
;; Is it faster to do more work in C than to do less in elisp?
(nreverse (cdr (member elt (reverse list)))))
(defun custom-theme-reset-variables (theme &rest args)
"Reset the value of the variables to values previously defined.
-Assosiate this setting with THEME.
+Associate this setting with THEME.
ARGS is a list of lists of the form
(defun custom-reset-variables (&rest args)
"Reset the value of the variables to values previously defined.
-Assosiate this setting with the `user' theme.
+Associate this setting with the `user' theme.
The ARGS are as in `custom-theme-reset-variables'."
(apply #'custom-theme-reset-variables 'user args))
+(defun custom-set-default (variable value)
+ "Default :set function for a customizable variable.
+Normally, this sets the default value of VARIABLE to VALUE,
+but if `custom-local-buffer' is non-nil,
+this sets the local binding in that buffer instead."
+ (if custom-local-buffer
+ (with-current-buffer custom-local-buffer
+ (set variable value))
+ (set-default variable value)))
;;; The End.