-;;; cus-edit.el --- Tools for customizating Emacs and Lisp packages.
+;;; cus-edit.el --- tools for customizing Emacs and Lisp packages
;;
-;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
;;
;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
+;; Maintainer: FSF
;; Keywords: help, faces
-;; Version: 1.9954
-;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
;; This file is part of GNU Emacs.
;;; Commentary:
;;
;; This file implements the code to create and edit customize buffers.
-;;
+;;
;; See `custom.el'.
;; No commands should have names starting with `custom-' because
(require 'cus-face)
(require 'wid-edit)
-(require 'easymenu)
-(eval-when-compile (require 'cl))
+(eval-when-compile
+ (defvar custom-versions-load-alist)) ; from cus-load
(condition-case nil
(require 'cus-load)
(require 'cus-start)
(error nil))
-(define-widget-keywords :custom-last :custom-prefix :custom-category
- :custom-prefixes :custom-menu
- :custom-show
- :custom-magic :custom-state :custom-level :custom-form
- :custom-set :custom-save :custom-reset-current :custom-reset-saved
- :custom-reset-standard)
-
(put 'custom-define-hook 'custom-type 'hook)
(put 'custom-define-hook 'standard-value '(nil))
(custom-add-to-group 'customize 'custom-define-hook 'custom-variable)
"Support for on-line help systems."
:group 'emacs)
+(defgroup multimedia nil
+ "Non-textual support, specifically images and sound."
+ :group 'emacs)
+
(defgroup local nil
"Code local to your site."
:group 'emacs)
(defgroup customize '((widgets custom-group))
"Customization of the Customization support."
:link '(custom-manual "(elisp)Customization")
- :link '(url-link :tag "Development Page"
+ :link '(url-link :tag "(Old?) Development Page"
"http://www.dina.kvl.dk/~abraham/custom/")
:prefix "custom-"
:group 'help)
;;; Utilities.
-(defun custom-last (x &optional n)
- ;; Stolen from `cl.el'.
- "Returns the last link in the list LIST.
-With optional argument N, returns Nth-to-last link (default 1)."
- (if n
- (let ((m 0) (p x))
- (while (consp p) (incf m) (pop p))
- (if (<= n 0) p
- (if (< n m) (nthcdr (- m n) x) x)))
- (while (consp (cdr x)) (pop x))
- x))
-
(defun custom-quote (sexp)
"Quote SEXP iff it is not self quoting."
(if (or (memq sexp '(t nil))
- (and (symbolp sexp)
- (eq (aref (symbol-name sexp) 0) ?:))
+ (keywordp sexp)
(and (listp sexp)
(memq (car sexp) '(lambda)))
(stringp sexp)
(numberp sexp)
- (and (fboundp 'characterp)
- (characterp sexp)))
+ (vectorp sexp)
+;;; (and (fboundp 'characterp)
+;;; (characterp sexp))
+ )
sexp
(list 'quote sexp)))
(defun custom-split-regexp-maybe (regexp)
"If REGEXP is a string, split it to a list at `\\|'.
-You can get the original back with from the result with:
+You can get the original back with from the result with:
(mapconcat 'identity result \"\\|\")
IF REGEXP is not a string, return it unchanged."
regexp))
(defun custom-variable-prompt ()
- ;; Code stolen from `help.el'.
- "Prompt for a variable, defaulting to the variable at point.
+ "Prompt for a custom variable, defaulting to the variable at point.
Return a list suitable for use in `interactive'."
(let ((v (variable-at-point))
(enable-recursive-minibuffers t)
val)
- (setq val (completing-read
- (if (symbolp v)
+ (setq val (completing-read
+ (if (and (symbolp v) (custom-variable-p v))
(format "Customize option: (default %s) " v)
- "Customize variable: ")
- obarray (lambda (symbol)
- (and (boundp symbol)
- (or (get symbol 'custom-type)
- (get symbol 'custom-loads)
- (user-variable-p symbol)))) t))
+ "Customize option: ")
+ obarray 'custom-variable-p t))
(list (if (equal val "")
(if (symbolp v) v nil)
(intern val)))))
WIDGET is the widget to apply the filter entries of MENU on."
(let ((result nil)
current name action filter)
- (while menu
+ (while menu
(setq current (car menu)
name (nth 0 current)
action (nth 1 current)
;;; Unlispify.
(defvar custom-prefix-list nil
- "List of prefixes that should be ignored by `custom-unlispify'")
+ "List of prefixes that should be ignored by `custom-unlispify'.")
(defcustom custom-unlispify-menu-entries t
"Display menu entries as words instead of symbols if non nil."
(defcustom custom-unlispify-remove-prefixes nil
"Non-nil means remove group prefixes from option names in buffer."
:group 'custom-menu
+ :group 'custom-buffer
:type 'boolean)
(defun custom-unlispify-menu-entry (symbol &optional no-suffix)
- "Convert symbol into a menu entry."
+ "Convert SYMBOL into a menu entry."
(cond ((not custom-unlispify-menu-entries)
(symbol-name symbol))
((get symbol 'custom-tag)
(get symbol 'custom-tag)
(concat (get symbol 'custom-tag) "...")))
(t
- (save-excursion
- (set-buffer (get-buffer-create " *Custom-Work*"))
+ (with-current-buffer (get-buffer-create " *Custom-Work*")
(erase-buffer)
(princ symbol (current-buffer))
(goto-char (point-min))
- (when (and (eq (get symbol 'custom-type) 'boolean)
- (re-search-forward "-p\\'" nil t))
- (replace-match "" t t)
- (goto-char (point-min)))
+ ;; FIXME: Boolean variables are not predicates, so they shouldn't
+ ;; end with `-p'. -stef
+ ;; (when (and (eq (get symbol 'custom-type) 'boolean)
+ ;; (re-search-forward "-p\\'" nil t))
+ ;; (replace-match "" t t)
+ ;; (goto-char (point-min)))
(if custom-unlispify-remove-prefixes
(let ((prefixes custom-prefix-list)
prefix)
(while prefixes
(setq prefix (car prefixes))
(if (search-forward prefix (+ (point) (length prefix)) t)
- (progn
+ (progn
(setq prefixes nil)
(delete-region (point-min) (point)))
(setq prefixes (cdr prefixes))))))
(subst-char-in-region (point-min) (point-max) ?- ?\ t)
(capitalize-region (point-min) (point-max))
- (unless no-suffix
+ (unless no-suffix
(goto-char (point-max))
(insert "..."))
(buffer-string)))))
:type 'boolean)
(defun custom-unlispify-tag-name (symbol)
- "Convert symbol into a menu entry."
+ "Convert SYMBOL into a menu entry."
(let ((custom-unlispify-menu-entries custom-unlispify-tag-names))
(custom-unlispify-menu-entry symbol t)))
(defun custom-prefix-add (symbol prefixes)
- ;; Addd SYMBOL to list of ignored PREFIXES.
+ "Add SYMBOL to list of ignored PREFIXES."
(cons (or (get symbol 'custom-prefix)
(concat (symbol-name symbol) "-"))
prefixes))
("-alist\\'" (repeat (cons sexp sexp))))
"Alist of (MATCH TYPE).
-MATCH should be a regexp matching the name of a symbol, and TYPE should
+MATCH should be a regexp matching the name of a symbol, and TYPE should
be a widget suitable for editing the value of that symbol. The TYPE
of the first entry where MATCH matches the name of the symbol will be
-used.
+used.
This is used for guessing the type of variables not declared with
customize."
(defun custom-guess-type (symbol)
"Guess a widget suitable for editing the value of SYMBOL.
-This is done by matching SYMBOL with `custom-guess-name-alist' and
+This is done by matching SYMBOL with `custom-guess-name-alist' and
if that fails, the doc string with `custom-guess-doc-alist'."
(let ((name (symbol-name symbol))
(names custom-guess-name-alist)
(unless found
(let ((doc (documentation-property symbol 'variable-documentation))
(docs custom-guess-doc-alist))
- (when doc
+ (when doc
(while docs
(setq current (car docs)
docs (cdr docs))
(sort (copy-sequence items)
(lambda (a b)
(let ((typea (nth 1 a)) (typeb (nth 1 b))
- (namea (symbol-name (nth 0 a))) (nameb (symbol-name (nth 0 b))))
+ (namea (nth 0 a)) (nameb (nth 0 b)))
(cond ((not order-groups)
;; Since we don't care about A and B order, maybe sort.
(when sort-alphabetically
"Set changes in all modified options."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (child)
- (when (eq (widget-get child :custom-state) 'modified)
- (widget-apply child :custom-set)))
+ (mapc (lambda (child)
+ (when (eq (widget-get child :custom-state) 'modified)
+ (widget-apply child :custom-set)))
children)))
(defun Custom-save ()
"Set all modified group members and save them."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (child)
- (when (memq (widget-get child :custom-state)
- '(modified set changed rogue))
- (widget-apply child :custom-save)))
+ (mapc (lambda (child)
+ (when (memq (widget-get child :custom-state)
+ '(modified set changed rogue))
+ (widget-apply child :custom-save)))
children))
(custom-save-all))
-(defvar custom-reset-menu
+(defvar custom-reset-menu
'(("Current" . Custom-reset-current)
("Saved" . Custom-reset-saved)
- ("Standard Settings" . Custom-reset-standard))
+ ("Erase Customization (use standard settings)" . Custom-reset-standard))
"Alist of actions for the `Reset' button.
The key is a string containing the name of the action, the value is a
-lisp function taking the widget as an element which will be called
+Lisp function taking the widget as an element which will be called
when the action is chosen.")
(defun custom-reset (event)
"Reset all modified group members to their current value."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (widget)
- (and (default-boundp (widget-value widget))
- (if (memq (widget-get widget :custom-state)
- '(modified changed))
- (widget-apply widget :custom-reset-current))))
- children)))
+ (mapc (lambda (widget)
+ (if (memq (widget-get widget :custom-state)
+ '(modified changed))
+ (widget-apply widget :custom-reset-current)))
+ children)))
(defun Custom-reset-saved (&rest ignore)
"Reset all modified or set group members to their saved value."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (widget)
- (and (get (widget-value widget) 'saved-value)
- (if (memq (widget-get widget :custom-state)
- '(modified set changed rogue))
- (widget-apply widget :custom-reset-saved))))
- children)))
+ (mapc (lambda (widget)
+ (if (memq (widget-get widget :custom-state)
+ '(modified set changed rogue))
+ (widget-apply widget :custom-reset-saved)))
+ children)))
(defun Custom-reset-standard (&rest ignore)
- "Reset all modified, set, or saved group members to their standard settings."
+ "Erase all customization (either current or saved) for the group members.
+The immediate result is to restore them to their standard settings.
+This operation eliminates any saved settings for the group members,
+making them as if they had never been customized at all."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (widget)
- (and (get (widget-value widget) 'standard-value)
- (if (memq (widget-get widget :custom-state)
- '(modified set changed saved rogue))
- (widget-apply widget :custom-reset-standard))))
+ (mapc (lambda (widget)
+ (and (widget-apply widget :custom-standard-value)
+ (if (memq (widget-get widget :custom-state)
+ '(modified set changed saved rogue))
+ (widget-apply widget :custom-reset-standard))))
children)))
;;; The Customize Commands
-(defun custom-prompt-variable (prompt-var prompt-val)
+(defun custom-prompt-variable (prompt-var prompt-val &optional comment)
"Prompt for a variable and a value and return them as a list.
PROMPT-VAR is the prompt for the variable, and PROMPT-VAL is the
prompt for the value. The %s escape in PROMPT-VAL is replaced with
it were the arg to `interactive' (which see) to interactively read the value.
If the variable has a `custom-type' property, it must be a widget and the
-`:prompt-value' property of that widget will be used for reading the value."
+`:prompt-value' property of that widget will be used for reading the value.
+
+If optional COMMENT argument is non nil, also prompt for a comment and return
+it as the third element in the list."
(let* ((var (read-variable prompt-var))
- (minibuffer-help-form '(describe-variable var)))
- (list var
+ (minibuffer-help-form '(describe-variable var))
+ (val
(let ((prop (get var 'variable-interactive))
(type (get var 'custom-type))
(prompt (format prompt-val var)))
(symbol-value var))
(not (boundp var))))
(t
- (eval-minibuffer prompt)))))))
+ (eval-minibuffer prompt))))))
+ (if comment
+ (list var val
+ (read-string "Comment: " (get var 'variable-comment)))
+ (list var val))))
;;;###autoload
-(defun customize-set-value (var val)
- "Set VARIABLE to VALUE. VALUE is a Lisp object.
+(defun customize-set-value (variable value &optional comment)
+ "Set VARIABLE to VALUE, and return VALUE. VALUE is a Lisp object.
If VARIABLE has a `variable-interactive' property, that is used as if
it were the arg to `interactive' (which see) to interactively read the value.
If VARIABLE has a `custom-type' property, it must be a widget and the
-`:prompt-value' property of that widget will be used for reading the value."
+`:prompt-value' property of that widget will be used for reading the value.
+
+If given a prefix (or a COMMENT argument), also prompt for a comment."
(interactive (custom-prompt-variable "Set variable: "
- "Set %s to value: "))
-
- (set var val))
+ "Set %s to value: "
+ current-prefix-arg))
+
+ (cond ((string= comment "")
+ (put variable 'variable-comment nil))
+ (comment
+ (put variable 'variable-comment comment)))
+ (set variable value))
;;;###autoload
-(defun customize-set-variable (var val)
- "Set the default for VARIABLE to VALUE. VALUE is a Lisp object.
+(defun customize-set-variable (variable value &optional comment)
+ "Set the default for VARIABLE to VALUE, and return VALUE.
+VALUE is a Lisp object.
If VARIABLE has a `custom-set' property, that is used for setting
VARIABLE, otherwise `set-default' is used.
it were the arg to `interactive' (which see) to interactively read the value.
If VARIABLE has a `custom-type' property, it must be a widget and the
-`:prompt-value' property of that widget will be used for reading the value. "
+`:prompt-value' property of that widget will be used for reading the value.
+
+If given a prefix (or a COMMENT argument), also prompt for a comment."
(interactive (custom-prompt-variable "Set variable: "
- "Set customized value for %s to: "))
- (funcall (or (get var 'custom-set) 'set-default) var val)
- (put var 'customized-value (list (custom-quote val))))
+ "Set customized value for %s to: "
+ current-prefix-arg))
+ (custom-load-symbol variable)
+ (funcall (or (get variable 'custom-set) 'set-default) variable value)
+ (put variable 'customized-value (list (custom-quote value)))
+ (cond ((string= comment "")
+ (put variable 'variable-comment nil)
+ (put variable 'customized-variable-comment nil))
+ (comment
+ (put variable 'variable-comment comment)
+ (put variable 'customized-variable-comment comment)))
+ value)
;;;###autoload
-(defun customize-save-variable (var val)
+(defun customize-save-variable (variable value &optional comment)
"Set the default for VARIABLE to VALUE, and save it for future sessions.
+Return VALUE.
+
If VARIABLE has a `custom-set' property, that is used for setting
VARIABLE, otherwise `set-default' is used.
it were the arg to `interactive' (which see) to interactively read the value.
If VARIABLE has a `custom-type' property, it must be a widget and the
-`:prompt-value' property of that widget will be used for reading the value. "
- (interactive (custom-prompt-variable "Set and ave variable: "
- "Set and save value for %s as: "))
- (funcall (or (get var 'custom-set) 'set-default) var val)
- (put var 'saved-value (list (custom-quote val)))
- (custom-save-all))
+`:prompt-value' property of that widget will be used for reading the value.
+
+If given a prefix (or a COMMENT argument), also prompt for a comment."
+ (interactive (custom-prompt-variable "Set and save variable: "
+ "Set and save value for %s as: "
+ current-prefix-arg))
+ (funcall (or (get variable 'custom-set) 'set-default) variable value)
+ (put variable 'saved-value (list (custom-quote value)))
+ (custom-push-theme 'theme-value variable 'user 'set (list (custom-quote value)))
+ (cond ((string= comment "")
+ (put variable 'variable-comment nil)
+ (put variable 'saved-variable-comment nil))
+ (comment
+ (put variable 'variable-comment comment)
+ (put variable 'saved-variable-comment comment)))
+ (custom-save-all)
+ value)
;;;###autoload
(defun customize ()
(interactive)
(customize-group 'emacs))
+;;;###autoload
+(defun customize-mode (mode)
+ "Customize options related to the current major mode.
+If a prefix \\[universal-argument] was given (or if the current major mode has no known group),
+then prompt for the MODE to customize."
+ (interactive
+ (list
+ (let ((completion-regexp-list '("-mode\\'"))
+ (group (custom-group-of-mode major-mode)))
+ (if (and group (not current-prefix-arg))
+ major-mode
+ (intern
+ (completing-read (if group
+ (format "Major mode (default %s): " major-mode)
+ "Major mode: ")
+ obarray
+ 'custom-group-of-mode
+ t nil nil (if group (symbol-name major-mode))))))))
+ (customize-group (custom-group-of-mode mode)))
+
+
;;;###autoload
(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) "
- obarray
+ obarray
(lambda (symbol)
(or (get symbol 'custom-loads)
(get symbol 'custom-group)))
(if (string-equal "" group)
(setq group 'emacs)
(setq group (intern group))))
- (or (get group 'custom-group)
- (custom-load-symbol group))
(let ((name (format "*Customize Group: %s*"
(custom-unlispify-tag-name group))))
(if (get-buffer name)
"Customize GROUP, which must be a customization group."
(interactive (list (let ((completion-ignore-case t))
(completing-read "Customize group: (default emacs) "
- obarray
+ obarray
(lambda (symbol)
(or (get symbol 'custom-loads)
(get symbol 'custom-group)))
(if (string-equal "" group)
(setq group 'emacs)
(setq group (intern group))))
- (or (get group 'custom-group)
- (custom-load-symbol group))
(let ((name (format "*Customize Group: %s*"
(custom-unlispify-tag-name group))))
(if (get-buffer name)
- (let ((window (selected-window)))
+ (let ((window (selected-window))
+ ;; 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))
(custom-buffer-create-other-window
(defun customize-option (symbol)
"Customize SYMBOL, which must be a user option variable."
(interactive (custom-variable-prompt))
- ;; If we don't have SYMBOL's real definition loaded,
- ;; try to load it.
- (unless (get symbol 'custom-type)
- (let ((loaddefs-file (locate-library "loaddefs.el" t))
- file)
- ;; See if it is autoloaded from some library.
- (when loaddefs-file
- (with-temp-buffer
- (insert-file-contents loaddefs-file)
- (when (re-search-forward (concat "^(defvar " (symbol-name symbol))
- nil t)
- (search-backward "\n;;; Generated autoloads from ")
- (goto-char (match-end 0))
- (setq file (buffer-substring (point)
- (progn (end-of-line) (point)))))))
- ;; If it is, load that library.
- (when file
- (when (string-match "\\.el\\'" file)
- (setq file (substring file 0 (match-beginning 0))))
- (load file))))
- (unless (get symbol 'custom-type)
- (error "Variable %s cannot be customized" symbol))
(custom-buffer-create (list (list symbol 'custom-variable))
(format "*Customize Option: %s*"
(custom-unlispify-tag-name symbol))))
+;;;###autoload
+(defalias 'customize-variable-other-window 'customize-option-other-window)
+
+;;;###autoload
+(defun customize-option-other-window (symbol)
+ "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))))
+
(defvar customize-changed-options-previous-release "20.2"
"Version for `customize-changed-options' to refer back to by default.")
(interactive "sCustomize options changed, since version (default all versions): ")
(if (equal since-version "")
- (setq since-version nil))
+ (setq since-version nil)
+ (unless (condition-case nil
+ (numberp (read since-version))
+ (error nil))
+ (signal 'wrong-type-argument (list 'numberp since-version))))
(unless since-version
(setq since-version customize-changed-options-previous-release))
- (let ((found nil)
- (versions nil))
- (mapatoms (lambda (symbol)
- (and (or (boundp symbol)
- ;; For variables not yet loaded.
- (get symbol 'standard-value)
- ;; For groups the previous test fails, this one
- ;; could be used to determine if symbol is a
- ;; group. Is there a better way for this?
- (get symbol 'group-documentation))
- (let ((version (get symbol 'custom-version)))
- (and version
- (or (null since-version)
- (customize-version-lessp since-version version))
- (if (member version versions)
- t
- ;;; Collect all versions that we use.
- (push version versions))))
- (setq found
- ;; We have to set the right thing here,
- ;; depending if we have a group or a
- ;; variable.
- (if (get symbol 'group-documentation)
- (cons (list symbol 'custom-group) found)
- (cons (list symbol 'custom-variable) found))))))
- (if (not found)
- (error "No user option defaults have been changed since Emacs %s"
- since-version)
- (let ((flist nil))
- (while versions
- (push (copy-sequence
- (cdr (assoc (car versions) custom-versions-load-alist)))
- flist)
- (setq versions (cdr versions)))
- (put 'custom-versions-load-alist 'custom-loads
- ;; Get all the files that correspond to element from the
- ;; VERSIONS list. This could use some simplification.
- (apply 'nconc flist)))
- ;; Because we set all the files needed to be loaded as a
- ;; `custom-loads' property to `custom-versions-load-alist' this
- ;; call will actually load them.
- (custom-load-symbol 'custom-versions-load-alist)
- ;; Clean up
- (put 'custom-versions-load-alist 'custom-loads nil)
- (custom-buffer-create (custom-sort-items found t 'first)
- "*Customize Changed Options*"))))
+
+ ;; Load the information for versions since since-version. We use
+ ;; custom-load-symbol for this.
+ (put 'custom-versions-load-alist 'custom-loads nil)
+ (dolist (elt custom-versions-load-alist)
+ (if (customize-version-lessp since-version (car elt))
+ (dolist (load (cdr elt))
+ (custom-add-load 'custom-versions-load-alist load))))
+ (custom-load-symbol 'custom-versions-load-alist)
+ (put 'custom-versions-load-alist 'custom-loads nil)
+
+ (let (found)
+ (mapatoms
+ (lambda (symbol)
+ (let ((version (get symbol 'custom-version)))
+ (if version
+ (when (customize-version-lessp since-version version)
+ (if (or (get symbol 'custom-group)
+ (get symbol 'group-documentation))
+ (push (list symbol 'custom-group) found))
+ (if (custom-variable-p symbol)
+ (push (list symbol 'custom-variable) found))
+ (if (custom-facep symbol)
+ (push (list symbol 'custom-face) found)))))))
+ (if found
+ (custom-buffer-create (custom-sort-items found t 'first)
+ "*Customize Changed Options*")
+ (error "No user option defaults have been changed since Emacs %s"
+ since-version))))
(defun customize-version-lessp (version1 version2)
+ ;; Why are the versions strings, and given that they are, why aren't
+ ;; they converted to numbers and compared as such here? -- fx
+
;; In case someone made a mistake and left out the quotes
;; in the :version value.
(if (numberp version2)
(setq version2 (prin1-to-string version2)))
(let (major1 major2 minor1 minor2)
- (string-match "\\([0-9]+\\)[.]\\([0-9]+\\)" version1)
- (setq major1 (read (match-string 1 version1)))
- (setq minor1 (read (match-string 2 version1)))
- (string-match "\\([0-9]+\\)[.]\\([0-9]+\\)" version2)
- (setq major2 (read (match-string 1 version2)))
- (setq minor2 (read (match-string 2 version2)))
+ (string-match "\\([0-9]+\\)\\(\\.\\([0-9]+\\)\\)?" version1)
+ (setq major1 (read (or (match-string 1 version1)
+ "0")))
+ (setq minor1 (read (or (match-string 3 version1)
+ "0")))
+ (string-match "\\([0-9]+\\)\\(\\.\\([0-9]+\\)\\)?" version2)
+ (setq major2 (read (or (match-string 1 version2)
+ "0")))
+ (setq minor2 (read (or (match-string 3 version2)
+ "0")))
(or (< major1 major2)
(and (= major1 major2)
(< minor1 minor2)))))
-
-;;;###autoload
-(defalias 'customize-variable-other-window 'customize-option-other-window)
-
-;;;###autoload
-(defun customize-option-other-window (symbol)
- "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))))
;;;###autoload
-(defun customize-face (&optional symbol)
+(defun customize-face (&optional face)
"Customize SYMBOL, which should be a face name or nil.
-If SYMBOL is nil, customize all faces."
- (interactive (list (completing-read "Customize face: (default all) "
- obarray 'custom-facep)))
- (if (or (null symbol) (and (stringp symbol) (zerop (length symbol))))
+If SYMBOL is nil, customize all faces.
+
+Interactively, when point is on text which has a face specified,
+suggest to customized that face, if it's customizable."
+ (interactive
+ (list (read-face-name "Customize face" "all faces" t)))
+ (if (member face '(nil ""))
+ (setq face (face-list)))
+ (if (and (listp face) (null (cdr face)))
+ (setq face (car face)))
+ (if (listp face)
(custom-buffer-create (custom-sort-items
- (mapcar (lambda (symbol)
- (list symbol 'custom-face))
- (face-list))
+ (mapcar (lambda (s)
+ (list s 'custom-face))
+ face)
t nil)
"*Customize Faces*")
- (when (stringp symbol)
- (setq symbol (intern symbol)))
- (unless (symbolp symbol)
- (error "Should be a symbol %S" symbol))
- (custom-buffer-create (list (list symbol 'custom-face))
+ (unless (facep face)
+ (error "Invalid face %S" face))
+ (custom-buffer-create (list (list face 'custom-face))
(format "*Customize Face: %s*"
- (custom-unlispify-tag-name symbol)))))
+ (custom-unlispify-tag-name face)))))
;;;###autoload
-(defun customize-face-other-window (&optional symbol)
- "Show customization buffer for FACE in other window."
- (interactive (list (completing-read "Customize face: "
- obarray 'custom-facep)))
- (if (or (null symbol) (and (stringp symbol) (zerop (length symbol))))
- ()
- (if (stringp symbol)
- (setq symbol (intern symbol)))
- (unless (symbolp symbol)
- (error "Should be a symbol %S" symbol))
- (custom-buffer-create-other-window
- (list (list symbol 'custom-face))
- (format "*Customize Face: %s*" (custom-unlispify-tag-name symbol)))))
+(defun customize-face-other-window (&optional face)
+ "Show customization buffer for face SYMBOL in other window.
+
+Interactively, when point is on text which has a face specified,
+suggest to customized that face, if it's customizable."
+ (interactive
+ (list (read-face-name "Customize face" "all faces" t)))
+ (if (member face '(nil ""))
+ (setq face (face-list)))
+ (if (and (listp face) (null (cdr face)))
+ (setq face (car face)))
+ (if (listp face)
+ (custom-buffer-create-other-window
+ (custom-sort-items
+ (mapcar (lambda (s)
+ (list s 'custom-face))
+ face)
+ t nil)
+ "*Customize Faces*")
+ (unless (facep face)
+ (error "Invalid face %S" face))
+ (custom-buffer-create-other-window
+ (list (list face 'custom-face))
+ (format "*Customize Face: %s*"
+ (custom-unlispify-tag-name face)))))
;;;###autoload
(defun customize-customized ()
(interactive)
(let ((found nil))
(mapatoms (lambda (symbol)
- (and (get symbol 'customized-face)
+ (and (or (get symbol 'customized-face)
+ (get symbol 'customized-face-comment))
(custom-facep symbol)
(push (list symbol 'custom-face) found))
- (and (get symbol 'customized-value)
+ (and (or (get symbol 'customized-value)
+ (get symbol 'customized-variable-comment))
(boundp symbol)
(push (list symbol 'custom-variable) found))))
(if (not found)
"*Customize Customized*"))))
;;;###autoload
+(defun customize-rogue ()
+ "Customize all user variable modified outside customize."
+ (interactive)
+ (let ((found nil))
+ (mapatoms (lambda (symbol)
+ (let ((cval (or (get symbol 'customized-value)
+ (get symbol 'saved-value)
+ (get symbol 'standard-value))))
+ (when (and cval ;Declared with defcustom.
+ (default-boundp symbol) ;Has a value.
+ (not (equal (eval (car cval))
+ ;; Which does not match customize.
+ (default-value symbol))))
+ (push (list symbol 'custom-variable) found)))))
+ (if (not found)
+ (error "No rogue user options")
+ (custom-buffer-create (custom-sort-items found t nil)
+ "*Customize Rogue*"))))
+;;;###autoload
(defun customize-saved ()
"Customize all already saved user options."
(interactive)
(let ((found nil))
(mapatoms (lambda (symbol)
- (and (get symbol 'saved-face)
+ (and (or (get symbol 'saved-face)
+ (get symbol 'saved-face-comment))
(custom-facep symbol)
(push (list symbol 'custom-face) found))
- (and (get symbol 'saved-value)
+ (and (or (get symbol 'saved-value)
+ (get symbol 'saved-variable-comment))
(boundp symbol)
(push (list symbol 'custom-variable) found))))
(if (not found )
(when (and (not (memq all '(groups faces)))
(boundp symbol)
(or (get symbol 'saved-value)
- (get symbol 'standard-value)
+ (custom-variable-p symbol)
(if (memq all '(nil options))
(user-variable-p symbol)
(get symbol 'variable-documentation))))
(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)
+ (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"
+ :group 'custom-buffer)
+
(defcustom custom-buffer-indent 3
"Number of spaces to indent nested groups."
:type 'integer
:type 'boolean
:group 'custom-buffer)
+(defcustom custom-buffer-verbose-help t
+ "If non-nil, include explanatory text in the customization buffer."
+ :type 'boolean
+ :group 'custom-buffer)
+
+(defun Custom-buffer-done (&rest ignore)
+ "Remove current buffer by calling `custom-buffer-done-function'."
+ (interactive)
+ (funcall custom-buffer-done-function (current-buffer)))
+
+(defcustom custom-raised-buttons (not (equal (face-valid-attribute-values :box)
+ '(("unspecified" . unspecified))))
+ "If non-nil, indicate active buttons in a `raised-button' style.
+Otherwise use brackets."
+ :type 'boolean
+ :version "21.1"
+ :group 'custom-buffer)
+
(defun custom-buffer-create-internal (options &optional description)
(message "Creating customization buffer...")
(custom-mode)
- (widget-insert "This is a customization buffer")
- (if description
- (widget-insert description))
- (widget-insert ".
-Square brackets show active fields; type RET or click mouse-1
+ (if custom-buffer-verbose-help
+ (progn
+ (widget-insert "This is a customization buffer")
+ (if description
+ (widget-insert description))
+ (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 ")
- (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 "Operate on everything in this buffer:\n ")
+Invoke " (if custom-raised-buttons
+ "`Raised' buttons"
+ "Square brackets")))
+ (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 "Operate on everything in this buffer:\n "))
+ (widget-insert " "))
(widget-create 'push-button
:tag "Set for Current Session"
:help-echo "\
:action 'Custom-reset-saved)
(widget-insert " ")
(widget-create 'push-button
- :tag "Reset to Standard"
+ :tag "Erase Customization"
:help-echo "\
-Reset all values in this buffer to their standard settings."
+Un-customize all values in this buffer. They get their standard settings."
:action 'Custom-reset-standard))
+ (if (not custom-buffer-verbose-help)
+ (progn
+ (widget-insert " ")
+ (widget-create 'info-link
+ :tag "Help"
+ :help-echo "Read the online help."
+ "(emacs)Easy Customization")))
(widget-insert " ")
(widget-create 'push-button
- :tag "Bury Buffer"
- :help-echo "Bury the buffer."
- :action (lambda (widget &optional event)
- (bury-buffer)))
+ :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")))
+ :action #'Custom-buffer-done)
(widget-insert "\n\n")
(message "Creating customization items...")
- (setq custom-options
+ (buffer-disable-undo)
+ (setq custom-options
(if (= (length options) 1)
(mapcar (lambda (entry)
(widget-create (nth 1 entry)
(let ((count 0)
(length (length options)))
(mapcar (lambda (entry)
- (prog2
- (message "Creating customization items ...%2d%%"
- (/ (* 100.0 count) length))
- (widget-create (nth 1 entry)
+ (prog2
+ (message "Creating customization items ...%2d%%"
+ (/ (* 100.0 count) length))
+ (widget-create (nth 1 entry)
:tag (custom-unlispify-tag-name
(nth 0 entry))
:value (nth 0 entry))
- (setq count (1+ count))
- (unless (eq (preceding-char) ?\n)
- (widget-insert "\n"))
- (widget-insert "\n")))
- options))))
+ (setq count (1+ count))
+ (unless (eq (preceding-char) ?\n)
+ (widget-insert "\n"))
+ (widget-insert "\n")))
+ options))))
(unless (eq (preceding-char) ?\n)
(widget-insert "\n"))
- (message "Creating customization items ...%2d%%done" 100)
+ (message "Creating customization items ...done")
(unless (eq custom-buffer-style 'tree)
- (mapcar 'custom-magic-reset custom-options))
+ (mapc 'custom-magic-reset custom-options))
(message "Creating customization setup...")
(widget-setup)
+ (buffer-enable-undo)
(goto-char (point-min))
(message "Creating customization buffer...done"))
(if custom-browse-only-groups
(widget-insert "\
Invoke the [Group] button below to edit that item in another window.\n\n")
- (widget-insert "Invoke the ")
- (widget-create 'item
+ (widget-insert "Invoke the ")
+ (widget-create 'item
:format "%t"
:tag "[Group]"
:tag-glyph "folder")
(widget-insert ", ")
- (widget-create 'item
+ (widget-create 'item
:format "%t"
:tag "[Face]"
:tag-glyph "face")
(widget-insert ", and ")
- (widget-create 'item
+ (widget-create 'item
:format "%t"
:tag "[Option]"
:tag-glyph "option")
(widget-insert " buttons below to edit that
item in another window.\n\n"))
(let ((custom-buffer-style 'tree))
- (widget-create 'custom-group
+ (widget-create 'custom-group
:custom-last t
:custom-state 'unknown
:tag (custom-unlispify-tag-name group)
:value group))
+ (widget-setup)
(goto-char (point-min)))
(define-widget 'custom-browse-visibility 'item
(defun custom-browse-insert-prefix (prefix)
"Insert PREFIX. On XEmacs convert it to line graphics."
+ ;; Fixme: do graphics.
(if nil ; (string-match "XEmacs" emacs-version)
- (progn
+ (progn
(insert "*")
(while (not (string-equal prefix ""))
(let ((entry (substring prefix 0 3)))
(defface custom-invalid-face '((((class color))
(:foreground "yellow" :background "red"))
(t
- (:bold t :italic t :underline 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 not defined for customization."
:group 'custom-magic-faces)
-(defface custom-modified-face '((((class color))
+(defface custom-modified-face '((((class color))
(:foreground "white" :background "blue"))
(t
- (:italic t :bold)))
+ (:slant italic :bold)))
"Face used when the customize item has been modified."
:group 'custom-magic-faces)
-(defface custom-set-face '((((class color))
+(defface custom-set-face '((((class color))
(:foreground "blue" :background "white"))
(t
- (:italic t)))
+ (:slant italic)))
"Face used when the customize item has been set."
:group 'custom-magic-faces)
-(defface custom-changed-face '((((class color))
+(defface custom-changed-face '((((class color))
(:foreground "white" :background "blue"))
(t
- (:italic t)))
+ (:slant italic)))
"Face used when the customize item has been changed."
:group 'custom-magic-faces)
this %c is unchanged from its standard setting." "\
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
+Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where
STATE is one of the following symbols:
`unknown'
For internal use, should never occur.
`hidden'
- This item is not being displayed.
+ This item is not being displayed.
`invalid'
This item is modified, but has an invalid form.
`modified'
(defun widget-magic-mouse-down-action (widget &optional event)
;; Non-nil unless hidden.
- (not (eq (widget-get (widget-get (widget-get widget :parent) :parent)
+ (not (eq (widget-get (widget-get (widget-get widget :parent) :parent)
:custom-state)
'hidden)))
(defun custom-magic-value-create (widget)
- ;; Create compact status report for WIDGET.
+ "Create compact status report for WIDGET."
(let* ((parent (widget-get widget :parent))
(state (widget-get parent :custom-state))
(hidden (eq state 'hidden))
(form (widget-get parent :custom-form))
children)
(while (string-match "\\`\\(.*\\)%c\\(.*\\)\\'" text)
- (setq text (concat (match-string 1 text)
+ (setq text (concat (match-string 1 text)
(symbol-name category)
(match-string 2 text))))
(when (and custom-magic-show
(> (widget-get parent :custom-level) 1))))
(insert-char ?\ (* custom-buffer-indent
(widget-get parent :custom-level))))
- (push (widget-create-child-and-convert
- widget 'choice-item
+ (push (widget-create-child-and-convert
+ widget 'choice-item
:help-echo "Change the state of this item."
:format (if hidden "%t" "%[%t%]")
:button-prefix 'widget-push-button-prefix
(let ((indent (widget-get parent :indent)))
(when indent
(insert-char ? indent))))
- (push (widget-create-child-and-convert
- widget 'choice-item
+ (push (widget-create-child-and-convert
+ widget 'choice-item
:mouse-down-action 'widget-magic-mouse-down-action
:button-face face
:button-prefix ""
;;; The `custom' Widget.
-(defface custom-button-face nil
+(defface custom-button-face
+ '((((type x w32 mac) (class color)) ; Like default modeline
+ (:box (:line-width 2 :style released-button)
+ :background "lightgrey" :foreground "black"))
+ (t
+ nil))
"Face used for buttons in customization buffers."
+ :version "21.1"
+ :group 'custom-faces)
+
+(defface custom-button-pressed-face
+ '((((type x w32 mac) (class color))
+ (:box (:line-width 2 :style pressed-button)
+ :background "lightgrey" :foreground "black"))
+ (t
+ (:inverse-video t)))
+ "Face used for buttons in customization buffers."
+ :version "21.1"
:group 'custom-faces)
(defface custom-documentation-face nil
:match (lambda (widget value) (symbolp value)))
(defun custom-convert-widget (widget)
- ;; Initialize :value and :tag from :args in WIDGET.
+ "Initialize :value and :tag from :args in WIDGET."
(let ((args (widget-get widget :args)))
- (when args
+ (when args
(widget-put widget :value (widget-apply widget
:value-to-internal (car args)))
(widget-put widget :tag (custom-unlispify-tag-name (car args)))
(custom-redraw-magic widget))
(when (and (>= pos from) (<= pos to))
(condition-case nil
- (progn
+ (progn
(if (> column 0)
(goto-line line)
(goto-line (1+ line)))
(defun custom-redraw-magic (widget)
"Redraw WIDGET state with current settings."
- (while widget
+ (while widget
(let ((magic (widget-get widget :custom-magic)))
- (cond (magic
+ (cond (magic
(widget-value-set magic (widget-value magic))
(when (setq widget (widget-get widget :group))
(custom-group-state-update widget)))
(t
(funcall show widget value)))))
-(defvar custom-load-recursion nil
- "Hack to avoid recursive dependencies.")
-
-(defun custom-load-symbol (symbol)
- "Load all dependencies for SYMBOL."
- (unless custom-load-recursion
- (let ((custom-load-recursion t)
- (loads (get symbol 'custom-loads))
- load)
- (while loads
- (setq load (car loads)
- loads (cdr loads))
- (cond ((symbolp load)
- (condition-case nil
- (require load)
- (error nil)))
- ;; Don't reload a file already loaded.
- ((and (boundp 'preloaded-file-list)
- (member load preloaded-file-list)))
- ((assoc load load-history))
- ((assoc (locate-library load) load-history))
- (t
- (condition-case nil
- ;; Without this, we would load cus-edit recursively.
- ;; We are still loading it when we call this,
- ;; and it is not in load-history yet.
- (or (equal load "cus-edit")
- (load-library load))
- (error nil))))))))
-
(defun custom-load-widget (widget)
"Load all dependencies for WIDGET."
(custom-load-symbol (widget-value widget)))
(error "There are unset changes"))
((eq state 'hidden)
(widget-put widget :custom-state 'unknown))
- (t
+ (t
(widget-put widget :documentation-shown nil)
(widget-put widget :custom-state 'hidden)))
(custom-redraw widget)
(if many
(insert ", and ")
(insert " and ")))
- (t
+ (t
(insert ", "))))
(widget-put widget :buttons buttons))))
(let ((entry (assq name (get symbol 'custom-group))))
(when (eq (nth 1 entry) type)
(insert " ")
- (push (widget-create-child-and-convert
- widget 'custom-group-link
+ (push (widget-create-child-and-convert
+ widget 'custom-group-link
:tag (custom-unlispify-tag-name symbol)
symbol)
buttons)
(delete-region start (point)))
found))
+;;; 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)))
+ "Face used for comments on variables or faces"
+ :version "21.1"
+ :group 'custom-faces)
+
+;; like font-lock-comment-face
+(defface custom-comment-tag-face
+ '((((class color) (background dark)) (:foreground "gray80"))
+ (((class color) (background light)) (:foreground "blue4"))
+ (((class grayscale) (background light))
+ (:foreground "DimGray" :weight bold :slant italic))
+ (((class grayscale) (background dark))
+ (:foreground "LightGray" :weight bold :slant italic))
+ (t (:weight bold)))
+ "Face used for variables or faces comment tags"
+ :group 'custom-faces)
+
+(define-widget 'custom-comment 'string
+ "User comment."
+ :tag "Comment"
+ :help-echo "Edit a comment here."
+ :sample-face 'custom-comment-tag-face
+ :value-face 'custom-comment-face
+ :shown nil
+ :create 'custom-comment-create)
+
+(defun custom-comment-create (widget)
+ (let* ((null-comment (equal "" (widget-value widget))))
+ (if (or (widget-get (widget-get widget :parent) :comment-shown)
+ (not null-comment))
+ (widget-default-create widget)
+ ;; `widget-default-delete' expects markers in these slots --
+ ;; maybe it shouldn't.
+ (widget-put widget :from (point-marker))
+ (widget-put widget :to (point-marker)))))
+
+(defun custom-comment-hide (widget)
+ (widget-put (widget-get widget :parent) :comment-shown nil))
+
+;; Those functions are for the menu. WIDGET is NOT the comment widget. It's
+;; the global custom one
+(defun custom-comment-show (widget)
+ (widget-put widget :comment-shown t)
+ (custom-redraw widget)
+ (widget-setup))
+
+(defun custom-comment-invisible-p (widget)
+ (let ((val (widget-value (widget-get widget :comment-widget))))
+ (and (equal "" val)
+ (not (widget-get widget :comment-shown)))))
+
;;; The `custom-variable' Widget.
-(defface custom-variable-tag-face '((((class color)
- (background dark))
- (:foreground "light blue" :underline t))
- (((class color)
- (background light))
- (:foreground "blue" :underline t))
- (t (:underline t)))
+;; When this was underlined blue, users confused it with a
+;; Mosaic-style hyperlink...
+(defface custom-variable-tag-face
+ `((((class color)
+ (background dark))
+ (:foreground "light blue" :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)
-(defface custom-variable-button-face '((t (:underline t :bold t)))
+(defface custom-variable-button-face '((t (:underline t :weight bold)))
"Face used for pushable variable tags."
:group 'custom-faces)
:custom-save 'custom-variable-save
:custom-reset-current 'custom-redraw
:custom-reset-saved 'custom-variable-reset-saved
- :custom-reset-standard 'custom-variable-reset-standard)
+ :custom-reset-standard 'custom-variable-reset-standard
+ :custom-standard-value 'custom-variable-standard-value)
(defun custom-variable-type (symbol)
"Return a widget suitable for editing the value of SYMBOL.
-If SYMBOL has a `custom-type' property, use that.
+If SYMBOL has a `custom-type' property, use that.
Otherwise, look up symbol in `custom-guess-type-alist'."
(let* ((type (or (get symbol 'custom-type)
(and (not (get symbol 'standard-value))
tmp))
(defun custom-variable-value-create (widget)
- "Here is where you edit the variables value."
+ "Here is where you edit the variable's value."
(custom-load-widget widget)
(unless (widget-get widget :custom-form)
(widget-put widget :custom-form custom-variable-default-form))
(value (if (default-boundp symbol)
(funcall get symbol)
(widget-get conv :value))))
- ;; If the widget is new, the child determine whether it is hidden.
+ ;; If the widget is new, the child determines whether it is hidden.
(cond (state)
((custom-show type value)
(setq state 'unknown))
(widget-put widget :buttons buttons))
((eq state 'hidden)
;; Indicate hidden value.
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'item
:format "%{%t%}: "
:sample-face 'custom-variable-tag-face
:tag tag
:parent widget)
buttons)
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'visibility
:help-echo "Show the value of this option."
+ :off "Show Value"
:action 'custom-toggle-parent
nil)
buttons))
(t
(custom-quote (widget-get conv :value))))))
(insert (symbol-name symbol) ": ")
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'visibility
:help-echo "Hide the value of this option."
+ :on "Hide Value"
+ :off "Show Value"
:action 'custom-toggle-parent
t)
buttons)
(insert " ")
- (push (widget-create-child-and-convert
- widget 'sexp
+ (push (widget-create-child-and-convert
+ widget 'sexp
:button-face 'custom-variable-button-face
:format "%v"
:tag (symbol-name symbol)
(setq tag-format (substring format 0 (match-end 0)))
(setq value-format (substring format (match-end 0)))
(push (widget-create-child-and-convert
- widget 'item
+ widget 'item
:format tag-format
:action 'custom-tag-action
:help-echo "Change value of this option."
tag)
buttons)
(insert " ")
- (push (widget-create-child-and-convert
- widget 'visibility
- :help-echo "Hide the value of this option."
- :action 'custom-toggle-parent
- t)
- buttons)
(push (widget-create-child-and-convert
- widget type
+ widget 'visibility
+ :help-echo "Hide the value of this option."
+ :on "Hide Value"
+ :off "Show Value"
+ :action 'custom-toggle-parent
+ t)
+ buttons)
+ (push (widget-create-child-and-convert
+ widget type
:format value-format
:value value)
children))))
(unless (eq custom-buffer-style 'tree)
- ;; Now update the state.
(unless (eq (preceding-char) ?\n)
(widget-insert "\n"))
- (if (eq state 'hidden)
- (widget-put widget :custom-state state)
- (custom-variable-state-set widget))
;; Create the magic button.
(let ((magic (widget-create-child-and-convert
widget 'custom-magic nil)))
(widget-put widget :custom-magic magic)
(push magic buttons))
- ;; Update properties.
- (widget-put widget :custom-form form)
+ ;; ### NOTE: this is ugly!!!! I need to update the :buttons property
+ ;; before the call to `widget-default-format-handler'. Otherwise, I
+ ;; loose my current `buttons'. This function shouldn't be called like
+ ;; this anyway. The doc string widget should be added like the others.
+ ;; --dv
(widget-put widget :buttons buttons)
- (widget-put widget :children children)
+ (insert "\n")
;; Insert documentation.
(widget-default-format-handler widget ?h)
+
+ ;; The comment field
+ (unless (eq state 'hidden)
+ (let* ((comment (get symbol 'variable-comment))
+ (comment-widget
+ (widget-create-child-and-convert
+ widget 'custom-comment
+ :parent widget
+ :value (or comment ""))))
+ (widget-put widget :comment-widget comment-widget)
+ ;; Don't push it !!! Custom assumes that the first child is the
+ ;; value one.
+ (setq children (append children (list comment-widget)))))
+ ;; Update the rest of the properties properties.
+ (widget-put widget :custom-form form)
+ (widget-put widget :children children)
+ ;; Now update the state.
+ (if (eq state 'hidden)
+ (widget-put widget :custom-state state)
+ (custom-variable-state-set widget))
;; See also.
(unless (eq state 'hidden)
(when (eq (widget-get widget :custom-level) 1)
(value (if (default-boundp symbol)
(funcall get symbol)
(widget-get widget :value)))
+ (comment (get symbol 'variable-comment))
tmp
- (state (cond ((setq tmp (get symbol 'customized-value))
+ temp
+ (state (cond ((progn (setq tmp (get symbol 'customized-value))
+ (setq temp
+ (get symbol 'customized-variable-comment))
+ (or tmp temp))
(if (condition-case nil
- (equal value (eval (car tmp)))
+ (and (equal value (eval (car tmp)))
+ (equal comment temp))
(error nil))
'set
'changed))
- ((setq tmp (get symbol 'saved-value))
+ ((progn (setq tmp (get symbol 'saved-value))
+ (setq temp (get symbol 'saved-variable-comment))
+ (or tmp temp))
(if (condition-case nil
- (equal value (eval (car tmp)))
+ (and (equal value (eval (car tmp)))
+ (equal comment temp))
(error nil))
'saved
'changed))
((setq tmp (get symbol 'standard-value))
(if (condition-case nil
- (equal value (eval (car tmp)))
+ (and (equal value (eval (car tmp)))
+ (equal comment nil))
(error nil))
'standard
'changed))
(t 'rogue))))
(widget-put widget :custom-state state)))
-(defvar custom-variable-menu
+(defun custom-variable-standard-value (widget)
+ (get (widget-value widget) 'standard-value))
+
+(defvar custom-variable-menu
'(("Set for Current Session" custom-variable-set
(lambda (widget)
(eq (widget-get widget :custom-state) 'modified)))
(memq (widget-get widget :custom-state) '(modified changed)))))
("Reset to Saved" custom-variable-reset-saved
(lambda (widget)
- (and (get (widget-value widget) 'saved-value)
+ (and (or (get (widget-value widget) 'saved-value)
+ (get (widget-value widget) 'saved-variable-comment))
(memq (widget-get widget :custom-state)
'(modified set changed rogue)))))
- ("Reset to Standard Settings" custom-variable-reset-standard
+ ("Erase Customization" custom-variable-reset-standard
(lambda (widget)
(and (get (widget-value widget) 'standard-value)
(memq (widget-get widget :custom-state)
'(modified set changed saved rogue)))))
+ ("Use Backup Value" custom-variable-reset-backup
+ (lambda (widget)
+ (get (widget-value widget) 'backup-value)))
+ ("---" ignore ignore)
+ ("Add Comment" custom-comment-show custom-comment-invisible-p)
("---" ignore ignore)
- ("Don't show as Lisp expression" custom-variable-edit
+ ("Don't show as Lisp expression" custom-variable-edit
(lambda (widget)
(eq (widget-get widget :custom-form) 'lisp)))
("Show initial Lisp expression" custom-variable-edit-lisp
the menu entry, ACTION is the function to call on the widget when the
menu is selected, and FILTER is a predicate which takes a `custom-variable'
widget as an argument, and returns non-nil if ACTION is valid on that
-widget. If FILTER is nil, ACTION is always valid.")
+widget. If FILTER is nil, ACTION is always valid.")
(defun custom-variable-action (widget &optional event)
"Show the menu for `custom-variable' WIDGET.
(custom-redraw widget))
(defun custom-variable-edit-lisp (widget)
- "Edit the lisp representation of the value of WIDGET."
+ "Edit the Lisp representation of the value of WIDGET."
(widget-put widget :custom-state 'unknown)
(widget-put widget :custom-form 'lisp)
(custom-redraw widget))
(child (car (widget-get widget :children)))
(symbol (widget-value widget))
(set (or (get symbol 'custom-set) 'set-default))
- val)
+ (comment-widget (widget-get widget :comment-widget))
+ (comment (widget-value comment-widget))
+ val)
(cond ((eq state 'hidden)
(error "Cannot set hidden variable"))
((setq val (widget-apply child :validate))
(goto-char (widget-get val :from))
(error "%s" (widget-get val :error)))
((memq form '(lisp mismatch))
+ (when (equal comment "")
+ (setq comment nil)
+ ;; Make the comment invisible by hand if it's empty
+ (custom-comment-hide comment-widget))
+ (custom-variable-backup-value widget)
(funcall set symbol (eval (setq val (widget-value child))))
- (put symbol 'customized-value (list val)))
+ (put symbol 'customized-value (list val))
+ (put symbol 'variable-comment comment)
+ (put symbol 'customized-variable-comment comment))
(t
+ (when (equal comment "")
+ (setq comment nil)
+ ;; Make the comment invisible by hand if it's empty
+ (custom-comment-hide comment-widget))
+ (custom-variable-backup-value widget)
(funcall set symbol (setq val (widget-value child)))
- (put symbol 'customized-value (list (custom-quote val)))))
+ (put symbol 'customized-value (list (custom-quote val)))
+ (put symbol 'variable-comment comment)
+ (put symbol 'customized-variable-comment comment)))
(custom-variable-state-set widget)
(custom-redraw-magic widget)))
(child (car (widget-get widget :children)))
(symbol (widget-value widget))
(set (or (get symbol 'custom-set) 'set-default))
+ (comment-widget (widget-get widget :comment-widget))
+ (comment (widget-value comment-widget))
val)
(cond ((eq state 'hidden)
(error "Cannot set hidden variable"))
((setq val (widget-apply child :validate))
(goto-char (widget-get val :from))
- (error "%s" (widget-get val :error)))
+ (error "Saving %s: %s" symbol (widget-get val :error)))
((memq form '(lisp mismatch))
+ (when (equal comment "")
+ (setq comment nil)
+ ;; Make the comment invisible by hand if it's empty
+ (custom-comment-hide comment-widget))
(put symbol 'saved-value (list (widget-value child)))
- (funcall set symbol (eval (widget-value child))))
+ (custom-push-theme 'theme-value symbol 'user
+ 'set (list (widget-value child)))
+ (funcall set symbol (eval (widget-value child)))
+ (put symbol 'variable-comment comment)
+ (put symbol 'saved-variable-comment comment))
(t
- (put symbol
- 'saved-value (list (custom-quote (widget-value
+ (when (equal comment "")
+ (setq comment nil)
+ ;; Make the comment invisible by hand if it's empty
+ (custom-comment-hide comment-widget))
+ (put symbol 'saved-value
+ (list (custom-quote (widget-value child))))
+ (custom-push-theme 'theme-value symbol 'user
+ 'set (list (custom-quote (widget-value
child))))
- (funcall set symbol (widget-value child))))
+ (funcall set symbol (widget-value child))
+ (put symbol 'variable-comment comment)
+ (put symbol 'saved-variable-comment comment)))
(put symbol 'customized-value nil)
+ (put symbol 'customized-variable-comment nil)
(custom-save-all)
(custom-variable-state-set widget)
(custom-redraw-magic widget)))
(defun custom-variable-reset-saved (widget)
- "Restore the saved value for the variable being edited by WIDGET."
+ "Restore the saved value for the variable being edited by WIDGET.
+The value that was current before this operation
+becomes the backup value, so you can get it again."
(let* ((symbol (widget-value widget))
- (set (or (get symbol 'custom-set) 'set-default)))
- (if (get symbol 'saved-value)
- (condition-case nil
- (funcall set symbol (eval (car (get symbol 'saved-value))))
- (error nil))
- (error "No saved value for %s" symbol))
+ (set (or (get symbol 'custom-set) 'set-default))
+ (comment-widget (widget-get widget :comment-widget))
+ (value (get symbol 'saved-value))
+ (comment (get symbol 'saved-variable-comment)))
+ (cond ((or value comment)
+ (put symbol 'variable-comment comment)
+ (custom-variable-backup-value widget)
+ (condition-case nil
+ (funcall set symbol (eval (car value)))
+ (error nil)))
+ (t
+ (error "No saved value for %s" symbol)))
(put symbol 'customized-value nil)
+ (put symbol 'customized-variable-comment nil)
(widget-put widget :custom-state 'unknown)
+ ;; This call will possibly make the comment invisible
(custom-redraw widget)))
(defun custom-variable-reset-standard (widget)
- "Restore the standard setting for the variable being edited by WIDGET."
+ "Restore the standard setting for the variable being edited by WIDGET.
+This operation eliminates any saved setting for the variable,
+restoring it to the state of a variable that has never been customized.
+The value that was current before this operation
+becomes the backup value, so you can get it again."
(let* ((symbol (widget-value widget))
- (set (or (get symbol 'custom-set) 'set-default)))
+ (set (or (get symbol 'custom-set) 'set-default))
+ (comment-widget (widget-get widget :comment-widget)))
(if (get symbol 'standard-value)
- (funcall set symbol (eval (car (get symbol 'standard-value))))
+ (progn
+ (custom-variable-backup-value widget)
+ (funcall set symbol (eval (car (get symbol 'standard-value)))))
(error "No standard setting known for %S" symbol))
+ (put symbol 'variable-comment nil)
(put symbol 'customized-value nil)
- (when (get symbol 'saved-value)
+ (put symbol 'customized-variable-comment nil)
+ (when (or (get symbol 'saved-value) (get symbol 'saved-variable-comment))
(put symbol 'saved-value nil)
+ (custom-push-theme 'theme-value symbol 'user 'reset 'standard)
+ ;; As a special optimizations we do not (explictly)
+ ;; save resets to standard when no theme set the value.
+ (if (null (cdr (get symbol 'theme-value)))
+ (put symbol 'theme-value nil))
+ (put symbol 'saved-variable-comment nil)
(custom-save-all))
(widget-put widget :custom-state 'unknown)
+ ;; This call will possibly make the comment invisible
+ (custom-redraw widget)))
+
+(defun custom-variable-backup-value (widget)
+ "Back up the current value for WIDGET's variable.
+The backup value is kept in the car of the `backup-value' property."
+ (let* ((symbol (widget-value widget))
+ (get (or (get symbol 'custom-get) 'default-value))
+ (type (custom-variable-type symbol))
+ (conv (widget-convert type))
+ (value (if (default-boundp symbol)
+ (funcall get symbol)
+ (widget-get conv :value))))
+ (put symbol 'backup-value (list value))))
+
+(defun custom-variable-reset-backup (widget)
+ "Restore the backup value for the variable being edited by WIDGET.
+The value that was current before this operation
+becomes the backup value, so you can use this operation repeatedly
+to switch between two values."
+ (let* ((symbol (widget-value widget))
+ (set (or (get symbol 'custom-set) 'set-default))
+ (value (get symbol 'backup-value))
+ (comment-widget (widget-get widget :comment-widget))
+ (comment (widget-value comment-widget)))
+ (if value
+ (progn
+ (custom-variable-backup-value widget)
+ (condition-case nil
+ (funcall set symbol (car value))
+ (error nil)))
+ (error "No backup value for %s" symbol))
+ (put symbol 'customized-value (list (car value)))
+ (put symbol 'variable-comment comment)
+ (put symbol 'customized-variable-comment comment)
+ (custom-variable-state-set widget)
+ ;; This call will possibly make the comment invisible
(custom-redraw widget)))
;;; The `custom-face-edit' Widget.
:format "%t: %v"
:tag "Attributes"
:extra-offset 12
- :button-args '(:help-echo "Control whether this attribute have any effect.")
+ :button-args '(:help-echo "Control whether this attribute has any effect.")
+ :value-to-internal 'custom-face-edit-fix-value
+ :match (lambda (widget value)
+ (widget-checklist-match widget
+ (custom-face-edit-fix-value widget value)))
+ :convert-widget 'custom-face-edit-convert-widget
:args (mapcar (lambda (att)
- (list 'group
+ (list 'group
:inline t
:sibling-args (widget-get (nth 1 att) :sibling-args)
- (list 'const :format "" :value (nth 0 att))
+ (list 'const :format "" :value (nth 0 att))
(nth 1 att)))
custom-face-attributes))
+(defun custom-face-edit-fix-value (widget value)
+ "Ignoring WIDGET, convert :bold and :italic in VALUE to new form.
+Also change :reverse-video to :inverse-video."
+ (if (listp value)
+ (let (result)
+ (while value
+ (let ((key (car value))
+ (val (car (cdr value))))
+ (cond ((eq key :italic)
+ (push :slant result)
+ (push (if val 'italic 'normal) result))
+ ((eq key :bold)
+ (push :weight result)
+ (push (if val 'bold 'normal) result))
+ ((eq key :reverse-video)
+ (push :inverse-video result)
+ (push val result))
+ (t
+ (push key result)
+ (push val result))))
+ (setq value (cdr (cdr value))))
+ (setq result (nreverse result))
+ result)
+ value))
+
+(defun custom-face-edit-convert-widget (widget)
+ "Convert :args as widget types in WIDGET."
+ (widget-put
+ widget
+ :args (mapcar (lambda (arg)
+ (widget-convert arg
+ :deactivate 'custom-face-edit-deactivate
+ :activate 'custom-face-edit-activate
+ :delete 'custom-face-edit-delete))
+ (widget-get widget :args)))
+ widget)
+
+(defun custom-face-edit-deactivate (widget)
+ "Make face widget WIDGET inactive for user modifications."
+ (unless (widget-get widget :inactive)
+ (let ((tag (custom-face-edit-attribute-tag widget))
+ (from (copy-marker (widget-get widget :from)))
+ (to (widget-get widget :to))
+ (value (widget-value widget))
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t))
+ (save-excursion
+ (goto-char from)
+ (widget-default-delete widget)
+ (insert tag ": *\n")
+ (widget-put widget :inactive
+ (cons value (cons from (- (point) from))))))))
+
+(defun custom-face-edit-activate (widget)
+ "Make face widget WIDGET inactive for user modifications."
+ (let ((inactive (widget-get widget :inactive))
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t))
+ (when (consp inactive)
+ (save-excursion
+ (goto-char (car (cdr inactive)))
+ (delete-region (point) (+ (point) (cdr (cdr inactive))))
+ (widget-put widget :inactive nil)
+ (widget-apply widget :create)
+ (widget-value-set widget (car inactive))
+ (widget-setup)))))
+
+(defun custom-face-edit-delete (widget)
+ "Remove widget from the buffer."
+ (let ((inactive (widget-get widget :inactive))
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t))
+ (if (not inactive)
+ ;; Widget is alive, we don't have to do anything special
+ (widget-default-delete widget)
+ ;; WIDGET is already deleted because we did so to inactivate it;
+ ;; now just get rid of the label we put in its place.
+ (delete-region (car (cdr inactive))
+ (+ (car (cdr inactive)) (cdr (cdr inactive))))
+ (widget-put widget :inactive nil))))
+
+
+(defun custom-face-edit-attribute-tag (widget)
+ "Returns the first :tag property in WIDGET or one of its children."
+ (let ((tag (widget-get widget :tag)))
+ (or (and (not (equal tag "")) tag)
+ (let ((children (widget-get widget :children)))
+ (while (and (null tag) children)
+ (setq tag (custom-face-edit-attribute-tag (pop children))))
+ tag))))
+
;;; The `custom-display' Widget.
(define-widget 'custom-display 'menu-choice
:sibling-args (:help-echo "\
Windows NT/9X.")
w32)
+ (const :format "MAC "
+ :sibling-args (:help-echo "\
+Macintosh OS.")
+ mac)
(const :format "DOS "
:sibling-args (:help-echo "\
Plain MS-DOS.")
(const :format "Dark\n"
:sibling-args (:help-echo "\
Match frames with dark backgrounds.")
- dark)))))))
+ dark)))
+ (group :sibling-args (:help-echo "\
+Only match frames that support the specified face attributes.")
+ (const :format "Supports attributes:" supports)
+ (custom-face-edit :inline t :format "%n%v"))))))
;;; The `custom-face' Widget.
-(defface custom-face-tag-face '((t (:underline t)))
+(defface custom-face-tag-face
+ `((t (:weight bold :height 1.2 :inherit variable-pitch)))
"Face used for face tags."
:group 'custom-faces)
"Customize face."
:sample-face 'custom-face-tag-face
:help-echo "Set or reset this face."
- :documentation-property '(lambda (face)
- (face-doc-string face))
+ :documentation-property #'face-doc-string
:value-create 'custom-face-value-create
:action 'custom-face-action
:custom-category 'face
:custom-reset-current 'custom-redraw
:custom-reset-saved 'custom-face-reset-saved
:custom-reset-standard 'custom-face-reset-standard
+ :custom-standard-value 'custom-face-standard-value
:custom-menu 'custom-face-menu-create)
-(define-widget 'custom-face-all 'editable-list
+(define-widget 'custom-face-all 'editable-list
"An editable list of display specifications and attributes."
:entry-format "%i %d %v"
:insert-button-args '(:help-echo "Insert new display specification here.")
"Non-nil if VALUE is an unselected display specification."
(not (face-spec-set-match-display value (selected-frame))))
-(define-widget 'custom-face-selected 'group
+(define-widget 'custom-face-selected 'group
"Edit the attributes of the selected display in a face specification."
:args '((repeat :format ""
:inline t
(defconst custom-face-selected (widget-convert 'custom-face-selected)
"Converted version of the `custom-face-selected' widget.")
+(defun custom-filter-face-spec (spec filter-index &optional default-filter)
+ "Return a canonicalized version of SPEC using.
+FILTER-INDEX is the index in the entry for each attribute in
+`custom-face-attributes' at which the appropriate filter function can be
+found, and DEFAULT-FILTER is the filter to apply for attributes that
+don't specify one."
+ (mapcar (lambda (entry)
+ ;; Filter a single face-spec entry
+ (let ((tests (car entry))
+ (unfiltered-attrs
+ ;; Handle both old- and new-style attribute syntax
+ (if (listp (car (cdr entry)))
+ (car (cdr entry))
+ (cdr entry)))
+ (filtered-attrs nil))
+ ;; Filter each face attribute
+ (while unfiltered-attrs
+ (let* ((attr (pop unfiltered-attrs))
+ (pre-filtered-value (pop unfiltered-attrs))
+ (filter
+ (or (nth filter-index (assq attr custom-face-attributes))
+ default-filter))
+ (filtered-value
+ (if filter
+ (funcall filter pre-filtered-value)
+ pre-filtered-value)))
+ (push filtered-value filtered-attrs)
+ (push attr filtered-attrs)))
+ ;;
+ (list tests filtered-attrs)))
+ spec))
+
+(defun custom-pre-filter-face-spec (spec)
+ "Return SPEC changed as necessary for editing by the face customization widget.
+SPEC must be a full face spec."
+ (custom-filter-face-spec spec 2))
+
+(defun custom-post-filter-face-spec (spec)
+ "Return the customized SPEC in a form suitable for setting the face."
+ (custom-filter-face-spec spec 3))
+
(defun custom-face-value-create (widget)
"Create a list of the display specifications for WIDGET."
(let ((buttons (widget-get widget :buttons))
+ children
(symbol (widget-get widget :value))
(tag (widget-get widget :tag))
(state (widget-get widget :custom-state))
(t
;; Create tag.
(insert tag)
+ (widget-specify-sample widget begin (point))
(if (eq custom-buffer-style 'face)
(insert " ")
- (widget-specify-sample widget begin (point))
- (insert ": "))
+ (if (string-match "face\\'" tag)
+ (insert ":")
+ (insert " face: ")))
;; Sample.
- (and (string-match "XEmacs" emacs-version)
- ;; XEmacs cannot display uninitialized faces.
- (not (custom-facep symbol))
- (copy-face 'custom-face-empty symbol))
(push (widget-create-child-and-convert widget 'item
:format "(%{%t%})"
:sample-face symbol
buttons)
;; Visibility.
(insert " ")
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'visibility
:help-echo "Hide or show this face."
+ :on "Hide Face"
+ :off "Show Face"
:action 'custom-toggle-parent
(not (eq state 'hidden)))
buttons)
(widget-put widget :buttons buttons)
;; Insert documentation.
(widget-default-format-handler widget ?h)
+ ;; The comment field
+ (unless (eq state 'hidden)
+ (let* ((comment (get symbol 'face-comment))
+ (comment-widget
+ (widget-create-child-and-convert
+ widget 'custom-comment
+ :parent widget
+ :value (or comment ""))))
+ (widget-put widget :comment-widget comment-widget)
+ (push comment-widget children)))
;; See also.
(unless (eq state 'hidden)
(when (eq (widget-get widget :custom-level) 1)
(unless (widget-get widget :custom-form)
(widget-put widget :custom-form custom-face-default-form))
(let* ((symbol (widget-value widget))
- (spec (or (get symbol 'saved-face)
+ (spec (or (get symbol 'customized-face)
+ (get symbol 'saved-face)
(get symbol 'face-defface-spec)
;; Attempt to construct it.
- (list (list t (custom-face-attributes-get
+ (list (list t (custom-face-attributes-get
symbol (selected-frame))))))
(form (widget-get widget :custom-form))
(indent (widget-get widget :indent))
;; edit it as the user has specified it.
(if (not (face-spec-match-p symbol spec (selected-frame)))
(setq spec (list (list t (face-attr-construct symbol (selected-frame))))))
+ (setq spec (custom-pre-filter-face-spec spec))
(setq edit (widget-create-child-and-convert
widget
(cond ((and (eq form 'selected)
- (widget-apply custom-face-selected
+ (widget-apply custom-face-selected
:match spec))
(when indent (insert-char ?\ indent))
'custom-face-selected)
(widget-apply custom-face-all
:match spec))
'custom-face-all)
- (t
+ (t
(when indent (insert-char ?\ indent))
'sexp))
:value spec))
(custom-face-state-set widget)
- (widget-put widget :children (list edit)))
+ (push edit children)
+ (widget-put widget :children children))
(message "Creating face editor...done"))))))
-(defvar custom-face-menu
+(defvar custom-face-menu
'(("Set for Current Session" custom-face-set)
("Save for Future Sessions" custom-face-save-command)
("Reset to Saved" custom-face-reset-saved
(lambda (widget)
- (get (widget-value widget) 'saved-face)))
- ("Reset to Standard Setting" custom-face-reset-standard
+ (or (get (widget-value widget) 'saved-face)
+ (get (widget-value widget) 'saved-face-comment))))
+ ("Erase Customization" custom-face-reset-standard
(lambda (widget)
(get (widget-value widget) 'face-defface-spec)))
("---" ignore ignore)
+ ("Add Comment" custom-comment-show custom-comment-invisible-p)
+ ("---" ignore ignore)
("Show all display specs" custom-face-edit-all
(lambda (widget)
(not (eq (widget-get widget :custom-form) 'all))))
the menu entry, ACTION is the function to call on the widget when the
menu is selected, and FILTER is a predicate which takes a `custom-face'
widget as an argument, and returns non-nil if ACTION is valid on that
-widget. If FILTER is nil, ACTION is always valid.")
+widget. If FILTER is nil, ACTION is always valid.")
(defun custom-face-edit-selected (widget)
"Edit selected attributes of the value of WIDGET."
(custom-redraw widget))
(defun custom-face-edit-lisp (widget)
- "Edit the lisp representation of the value of WIDGET."
+ "Edit the Lisp representation of the value of WIDGET."
(widget-put widget :custom-state 'unknown)
(widget-put widget :custom-form 'lisp)
(custom-redraw widget))
(defun custom-face-state-set (widget)
"Set the state of WIDGET."
- (let ((symbol (widget-value widget)))
- (widget-put widget :custom-state (cond ((get symbol 'customized-face)
- 'set)
- ((get symbol 'saved-face)
- 'saved)
- ((get symbol 'face-defface-spec)
- 'standard)
- (t
- 'rogue)))))
+ (let* ((symbol (widget-value widget))
+ (comment (get symbol 'face-comment))
+ tmp temp)
+ (widget-put widget :custom-state
+ (cond ((progn
+ (setq tmp (get symbol 'customized-face))
+ (setq temp (get symbol 'customized-face-comment))
+ (or tmp temp))
+ (if (equal temp comment)
+ 'set
+ 'changed))
+ ((progn
+ (setq tmp (get symbol 'saved-face))
+ (setq temp (get symbol 'saved-face-comment))
+ (or tmp temp))
+ (if (equal temp comment)
+ 'saved
+ 'changed))
+ ((get symbol 'face-defface-spec)
+ (if (equal comment nil)
+ 'standard
+ 'changed))
+ (t
+ 'rogue)))))
(defun custom-face-action (widget &optional event)
"Show the menu for `custom-face' WIDGET.
"Make the face attributes in WIDGET take effect."
(let* ((symbol (widget-value widget))
(child (car (widget-get widget :children)))
- (value (widget-value child)))
+ (value (custom-post-filter-face-spec (widget-value child)))
+ (comment-widget (widget-get widget :comment-widget))
+ (comment (widget-value comment-widget)))
+ (when (equal comment "")
+ (setq comment nil)
+ ;; Make the comment invisible by hand if it's empty
+ (custom-comment-hide comment-widget))
(put symbol 'customized-face value)
- (face-spec-set symbol value)
+ (if (face-spec-choose value)
+ (face-spec-set symbol value)
+ ;; face-set-spec ignores empty attribute lists, so just give it
+ ;; something harmless instead.
+ (face-spec-set symbol '((t :foreground unspecified))))
+ (put symbol 'customized-face-comment comment)
+ (put symbol 'face-comment comment)
(custom-face-state-set widget)
(custom-redraw-magic widget)))
"Prepare for saving WIDGET's face attributes, but don't write `.emacs'."
(let* ((symbol (widget-value widget))
(child (car (widget-get widget :children)))
- (value (widget-value child)))
- (face-spec-set symbol value)
- (put symbol 'saved-face value)
+ (value (custom-post-filter-face-spec (widget-value child)))
+ (comment-widget (widget-get widget :comment-widget))
+ (comment (widget-value comment-widget)))
+ (when (equal comment "")
+ (setq comment nil)
+ ;; Make the comment invisible by hand if it's empty
+ (custom-comment-hide comment-widget))
+ (if (face-spec-choose value)
+ (face-spec-set symbol value)
+ ;; face-set-spec ignores empty attribute lists, so just give it
+ ;; something harmless instead.
+ (face-spec-set symbol '((t :foreground unspecified))))
+ (unless (eq (widget-get widget :custom-state) 'standard)
+ (put symbol 'saved-face value))
+ (custom-push-theme 'theme-face symbol 'user 'set value)
(put symbol 'customized-face nil)
+ (put symbol 'face-comment comment)
+ (put symbol 'customized-face-comment nil)
+ (put symbol 'saved-face-comment comment)
(custom-save-all)
(custom-face-state-set widget)
(custom-redraw-magic widget)))
"Restore WIDGET to the face's default attributes."
(let* ((symbol (widget-value widget))
(child (car (widget-get widget :children)))
- (value (get symbol 'saved-face)))
- (unless value
+ (value (get symbol 'saved-face))
+ (comment (get symbol 'saved-face-comment))
+ (comment-widget (widget-get widget :comment-widget)))
+ (unless (or value comment)
(error "No saved value for this face"))
(put symbol 'customized-face nil)
+ (put symbol 'customized-face-comment nil)
(face-spec-set symbol value)
+ (put symbol 'face-comment comment)
(widget-value-set child value)
+ ;; This call manages the comment visibility
+ (widget-value-set comment-widget (or comment ""))
(custom-face-state-set widget)
(custom-redraw-magic widget)))
+(defun custom-face-standard-value (widget)
+ (get (widget-value widget) 'face-defface-spec))
+
(defun custom-face-reset-standard (widget)
- "Restore WIDGET to the face's standard settings."
+ "Restore WIDGET to the face's standard settings.
+This operation eliminates any saved setting for the face,
+restoring it to the state of a face that has never been customized."
(let* ((symbol (widget-value widget))
(child (car (widget-get widget :children)))
- (value (get symbol 'face-defface-spec)))
+ (value (get symbol 'face-defface-spec))
+ (comment-widget (widget-get widget :comment-widget)))
(unless value
(error "No standard setting for this face"))
(put symbol 'customized-face nil)
- (when (get symbol 'saved-face)
+ (put symbol 'customized-face-comment nil)
+ (when (or (get symbol 'saved-face) (get symbol 'saved-face-comment))
(put symbol 'saved-face nil)
+ (custom-push-theme 'theme-face symbol 'user 'reset 'standard)
+ ;; Do not explictly save resets to standards without themes.
+ (if (null (cdr (get symbol 'theme-face)))
+ (put symbol 'theme-face nil))
+ (put symbol 'saved-face-comment nil)
(custom-save-all))
(face-spec-set symbol value)
+ (put symbol 'face-comment nil)
(widget-value-set child value)
+ ;; This call manages the comment visibility
+ (widget-value-set comment-widget "")
(custom-face-state-set widget)
(custom-redraw-magic widget)))
:convert-widget 'widget-value-convert-widget
:button-prefix 'widget-push-button-prefix
:button-suffix 'widget-push-button-suffix
- :format "%t: %[select face%] %v"
+ :format "%{%t%}: %[select face%] %v"
:tag "Face"
:value 'default
:value-create 'widget-face-value-create
:value-get 'widget-value-value-get
:validate 'widget-children-validate
:action 'widget-face-action
- :match '(lambda (widget value) (symbolp value)))
+ :match (lambda (widget value) (symbolp value)))
(defun widget-face-value-create (widget)
- ;; Create a `custom-face' child.
+ "Create a `custom-face' child."
(let* ((symbol (widget-value widget))
(custom-buffer-style 'face)
(child (widget-create-child-and-convert
(widget-put widget :children (list child))))
(defun widget-face-value-delete (widget)
- ;; Remove the child from the options.
+ "Remove the child from the options."
(let ((child (car (widget-get widget :children))))
(setq custom-options (delq child custom-options))
(widget-children-value-delete widget)))
(mapcar (lambda (face)
(list (symbol-name face)))
(face-list))
- nil nil nil
+ nil nil nil
'face-history)))
(unless (zerop (length answer))
(widget-value-set widget (intern answer))
:match (lambda (widget value)
(or (symbolp value)
(widget-group-match widget value)))
+ ;; Avoid adding undefined functions to the hook, especially for
+ ;; things like `find-file-hook' or even more basic ones, to avoid
+ ;; chaos.
+ :set (lambda (symbol value)
+ (dolist (elt value)
+ (if (fboundp elt)
+ (add-hook symbol elt))))
:convert-widget 'custom-hook-convert-widget
:tag "Hook")
(defun custom-hook-convert-widget (widget)
- ;; Handle `:custom-options'.
+ ;; Handle `:options'.
(let* ((options (widget-get widget :options))
- (other `(editable-list :inline t
+ (other `(editable-list :inline t
:entry-format "%i %d%v"
(function :format " %v")))
(args (if options
(defcustom custom-group-tag-faces nil
;; In XEmacs, this ought to play games with font size.
+ ;; 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
:type '(repeat face)
:group 'custom-faces)
-(defface custom-group-tag-face-1 '((((class color)
- (background dark))
- (:foreground "pink" :underline t))
- (((class color)
- (background light))
- (:foreground "red" :underline t))
- (t (:underline t)))
- "Face used for group tags.")
-
-(defface custom-group-tag-face '((((class color)
- (background dark))
- (:foreground "light blue" :underline t))
- (((class color)
- (background light))
- (:foreground "blue" :underline t))
- (t (:underline t)))
+(defface custom-group-tag-face-1
+ `((((class color)
+ (background dark))
+ (:foreground "pink" :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)
+
+(defface custom-group-tag-face
+ `((((class color)
+ (background dark))
+ (:foreground "light blue" :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)
(defun custom-group-value-create (widget)
"Insert a customize group for WIDGET in the current buffer."
+ (unless (eq (widget-get widget :custom-state) 'hidden)
+ (custom-load-widget widget))
(let* ((state (widget-get widget :custom-state))
(level (widget-get widget :custom-level))
;; (indent (widget-get widget :indent))
(or members (custom-unloaded-widget-p widget)))
(custom-browse-insert-prefix prefix)
(push (widget-create-child-and-convert
- widget 'custom-browse-visibility
+ widget 'custom-browse-visibility
;; :tag-glyph "plus"
:tag "+")
buttons)
(insert "[ ]-- ")
;; (widget-glyph-insert nil "[ ]" "empty")
;; (widget-glyph-insert nil "-- " "horizontal")
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'custom-browse-group-tag)
buttons)
(insert " " tag "\n")
(widget-put widget :buttons buttons))
((eq custom-buffer-style 'tree)
(custom-browse-insert-prefix prefix)
- (custom-load-widget widget)
(if (zerop (length members))
- (progn
+ (progn
(custom-browse-insert-prefix prefix)
(insert "[ ]-- ")
;; (widget-glyph-insert nil "[ ]" "empty")
;; (widget-glyph-insert nil "-- " "horizontal")
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'custom-browse-group-tag)
buttons)
(insert " " tag "\n")
(widget-put widget :buttons buttons))
- (push (widget-create-child-and-convert
- widget 'custom-browse-visibility
+ (push (widget-create-child-and-convert
+ widget 'custom-browse-visibility
;; :tag-glyph "minus"
:tag "-")
buttons)
(insert "-\\ ")
;; (widget-glyph-insert nil "-\\ " "top")
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'custom-browse-group-tag)
buttons)
(insert " " tag "\n")
;; Create link/visibility indicator.
(if (eq custom-buffer-style 'links)
(push (widget-create-child-and-convert
- widget 'custom-group-link
+ widget 'custom-group-link
:tag "Go to Group"
symbol)
buttons)
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'custom-group-visibility
:help-echo "Show members of this group."
:action 'custom-toggle-parent
;; Create visibility indicator.
(unless (eq custom-buffer-style 'links)
(insert "--------")
- (push (widget-create-child-and-convert
+ (push (widget-create-child-and-convert
widget 'visibility
:help-echo "Hide members of this group."
:action 'custom-toggle-parent
(insert " "))
;; Create more dashes.
;; Use 76 instead of 75 to compensate for the temporary "<"
- ;; added by `widget-insert'.
+ ;; added by `widget-insert'.
(insert-char ?- (- 76 (current-column)
(* custom-buffer-indent level)))
(insert "\\\n")
;; Create magic button.
(let ((magic (widget-create-child-and-convert
- widget 'custom-magic
+ widget 'custom-magic
:indent 0
nil)))
(widget-put widget :custom-magic magic)
(when (eq level 1)
(insert-char ?\ custom-buffer-indent)
(custom-add-parent-links widget)))
- (custom-add-see-also widget
+ (custom-add-see-also widget
(make-string (* custom-buffer-indent level)
?\ ))
;; Members.
(message "Creating group...")
- (custom-load-widget widget)
(let* ((members (custom-sort-items members
custom-buffer-sort-alphabetically
custom-buffer-order-groups))
(widget-insert "\n"))))
members)))
(message "Creating group magic...")
- (mapcar 'custom-magic-reset children)
+ (mapc 'custom-magic-reset children)
(message "Creating group state...")
(widget-put widget :children children)
(custom-group-state-update widget)
(insert-char ?- (- 75 (current-column) (* custom-buffer-indent level)))
(insert "/\n")))))
-(defvar custom-group-menu
+(defvar custom-group-menu
'(("Set for Current Session" custom-group-set
(lambda (widget)
(eq (widget-get widget :custom-state) 'modified)))
the menu entry, ACTION is the function to call on the widget when the
menu is selected, and FILTER is a predicate which takes a `custom-group'
widget as an argument, and returns non-nil if ACTION is valid on that
-widget. If FILTER is nil, ACTION is always valid.")
+widget. If FILTER is nil, ACTION is always valid.")
(defun custom-group-action (widget &optional event)
"Show the menu for `custom-group' WIDGET.
(defun custom-group-set (widget)
"Set changes in all modified group members."
(let ((children (widget-get widget :children)))
- (mapcar (lambda (child)
- (when (eq (widget-get child :custom-state) 'modified)
- (widget-apply child :custom-set)))
+ (mapc (lambda (child)
+ (when (eq (widget-get child :custom-state) 'modified)
+ (widget-apply child :custom-set)))
children )))
(defun custom-group-save (widget)
"Save all modified group members."
(let ((children (widget-get widget :children)))
- (mapcar (lambda (child)
- (when (memq (widget-get child :custom-state) '(modified set))
- (widget-apply child :custom-save)))
+ (mapc (lambda (child)
+ (when (memq (widget-get child :custom-state) '(modified set))
+ (widget-apply child :custom-save)))
children )))
(defun custom-group-reset-current (widget)
"Reset all modified group members."
(let ((children (widget-get widget :children)))
- (mapcar (lambda (child)
- (when (eq (widget-get child :custom-state) 'modified)
- (widget-apply child :custom-reset-current)))
+ (mapc (lambda (child)
+ (when (eq (widget-get child :custom-state) 'modified)
+ (widget-apply child :custom-reset-current)))
children )))
(defun custom-group-reset-saved (widget)
"Reset all modified or set group members."
(let ((children (widget-get widget :children)))
- (mapcar (lambda (child)
- (when (memq (widget-get child :custom-state) '(modified set))
- (widget-apply child :custom-reset-saved)))
+ (mapc (lambda (child)
+ (when (memq (widget-get child :custom-state) '(modified set))
+ (widget-apply child :custom-reset-saved)))
children )))
(defun custom-group-reset-standard (widget)
"Reset all modified, set, or saved group members."
(let ((children (widget-get widget :children)))
- (mapcar (lambda (child)
- (when (memq (widget-get child :custom-state)
- '(modified set saved))
- (widget-apply child :custom-reset-standard)))
+ (mapc (lambda (child)
+ (when (memq (widget-get child :custom-state)
+ '(modified set saved))
+ (widget-apply child :custom-reset-standard)))
children )))
(defun custom-group-state-update (widget)
"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."
+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)
:group 'customize)
"Return the file name for saving customizations."
(setq custom-file
(or custom-file
- user-init-file
- (read-file-name "File for customizations: "
- "~/" nil nil ".emacs"))))
+ (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)
- "Delete the call to SYMBOL from `custom-file'.
-Leave point at the location of the call, or after the last expression."
- (let ((default-major-mode))
+ "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))
(set-buffer (find-file-noselect (custom-file))))
(goto-char (point-min))
;; Skip all whitespace and comments.
(while (forward-comment 1))
(or (eobp)
(save-excursion (forward-sexp (buffer-size)))) ; Test for scan errors.
- (catch 'found
- (while t
- ;; Skip all whitespace and comments.
- (while (forward-comment 1))
- (let ((start (point))
- (sexp (condition-case nil
- (read (current-buffer))
- (end-of-file (throw 'found nil)))))
- (when (and (listp sexp)
- (eq (car sexp) symbol))
- (delete-region start (point))
- (throw 'found nil))))))
+ (let (first)
+ (catch 'found
+ (while t ;; We exit this loop only via throw.
+ ;; Skip all whitespace and comments.
+ (while (forward-comment 1))
+ (let ((start (point))
+ (sexp (condition-case nil
+ (read (current-buffer))
+ (end-of-file (throw 'found nil)))))
+ (when (and (listp sexp)
+ (eq (car sexp) symbol))
+ (delete-region start (point))
+ (unless first
+ (setq first (point)))))))
+ (if first
+ (goto-char first)
+ ;; Move in front of local variables, otherwise long Custom
+ ;; entries would make them ineffective.
+ (let ((pos (point-max))
+ (case-fold-search t))
+ (save-excursion
+ (goto-char (point-max))
+ (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
+ 'move)
+ (when (search-forward "Local Variables:" nil t)
+ (setq pos (line-beginning-position))))
+ (goto-char pos)))))
(defun custom-save-variables ()
"Save all customized variables in `custom-file'."
(save-excursion
+ (custom-save-delete 'custom-load-themes)
+ (custom-save-delete 'custom-reset-variables)
(custom-save-delete 'custom-set-variables)
+ (custom-save-loaded-themes)
+ (custom-save-resets 'theme-value 'custom-reset-variables nil)
(let ((standard-output (current-buffer))
(saved-list (make-list 1 0))
sort-fold-case)
(setq saved-list (sort (cdr saved-list) 'string<))
(unless (bolp)
(princ "\n"))
- (princ "(custom-set-variables")
- (mapcar
- (lambda (symbol)
- (let ((value (get symbol 'saved-value))
- (requests (get symbol 'custom-requests))
- (now (not (or (get symbol 'standard-value)
- (and (not (boundp symbol))
- (not (get symbol 'force-value)))))))
- (princ "\n '(")
- (princ symbol)
- (princ " ")
- (prin1 (car value))
- (cond (requests
- (if now
- (princ " t ")
- (princ " nil "))
- (prin1 requests)
- (princ ")"))
- (now
- (princ " t)"))
- (t
- (princ ")")))))
- saved-list)
+ (princ "(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.\n")
+ (dolist (symbol saved-list)
+ (let ((spec (car-safe (get symbol 'theme-value)))
+ (value (get symbol 'saved-value))
+ (requests (get symbol 'custom-requests))
+ (now (not (or (custom-variable-p symbol)
+ (and (not (boundp symbol))
+ (not (eq (get symbol 'force-value)
+ 'rogue))))))
+ (comment (get symbol 'saved-variable-comment))
+ sep)
+ ;; Check `requests'.
+ (dolist (request requests)
+ (when (and (symbolp request) (not (featurep request)))
+ (message "Unknown requested feature: %s" request)
+ (setq requests (delq request requests))))
+ (when (or (and spec
+ (eq (nth 0 spec) 'user)
+ (eq (nth 1 spec) 'set))
+ comment
+ (and (null spec) (get symbol 'saved-value)))
+ (unless (bolp)
+ (princ "\n"))
+ (princ " '(")
+ (prin1 symbol)
+ (princ " ")
+ (prin1 (car value))
+ (when (or now requests comment)
+ (princ " ")
+ (prin1 now)
+ (when (or requests comment)
+ (princ " ")
+ (prin1 requests)
+ (when comment
+ (princ " ")
+ (prin1 comment))))
+ (princ ")"))))
+ (if (bolp)
+ (princ " "))
(princ ")")
(unless (looking-at "\n")
(princ "\n")))))
(defun custom-save-faces ()
"Save all customized faces in `custom-file'."
(save-excursion
+ (custom-save-delete 'custom-reset-faces)
(custom-save-delete 'custom-set-faces)
+ (custom-save-resets 'theme-face 'custom-reset-faces '(default))
(let ((standard-output (current-buffer))
(saved-list (make-list 1 0))
sort-fold-case)
(setq saved-list (cons 'default (delq 'default saved-list))))
(unless (bolp)
(princ "\n"))
- (princ "(custom-set-faces")
- (mapcar
- (lambda (symbol)
- (let ((value (get symbol 'saved-face)))
- (unless (eq symbol 'default))
- ;; Don't print default face here.
- (princ "\n '(")
- (princ symbol)
- (princ " ")
- (prin1 value)
- (if (or (get symbol 'face-defface-spec)
- (and (not (custom-facep symbol))
- (not (get symbol 'force-face))))
- (princ ")")
- (princ " t)"))))
- saved-list)
+ (princ "(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.\n")
+ (dolist (symbol saved-list)
+ (let ((spec (car-safe (get symbol 'theme-face)))
+ (value (get symbol 'saved-face))
+ (now (not (or (get symbol 'face-defface-spec)
+ (and (not (custom-facep symbol))
+ (not (get symbol 'force-face))))))
+ (comment (get symbol 'saved-face-comment)))
+ (when (or (and spec
+ (eq (nth 0 spec) 'user)
+ (eq (nth 1 spec) 'set))
+ comment
+ (and (null spec) (get symbol 'saved-face)))
+ ;; Don't print default face here.
+ (unless (bolp)
+ (princ "\n"))
+ (princ " '(")
+ (prin1 symbol)
+ (princ " ")
+ (prin1 value)
+ (when (or now comment)
+ (princ " ")
+ (prin1 now)
+ (when comment
+ (princ " ")
+ (prin1 comment)))
+ (princ ")"))))
+ (if (bolp)
+ (princ " "))
(princ ")")
(unless (looking-at "\n")
(princ "\n")))))
+(defun custom-save-resets (property setter special)
+ (let (started-writing ignored-special)
+ ;; (custom-save-delete setter) Done by caller
+ (let ((standard-output (current-buffer))
+ (mapper `(lambda (object)
+ (let ((spec (car-safe (get object (quote ,property)))))
+ (when (and (not (memq object ignored-special))
+ (eq (nth 0 spec) 'user)
+ (eq (nth 1 spec) 'reset))
+ ;; Do not write reset statements unless necessary.
+ (unless started-writing
+ (setq started-writing t)
+ (unless (bolp)
+ (princ "\n"))
+ (princ "(")
+ (princ (quote ,setter))
+ (princ "\n '(")
+ (prin1 object)
+ (princ " ")
+ (prin1 (nth 3 spec))
+ (princ ")")))))))
+ (mapc mapper special)
+ (setq ignored-special special)
+ (mapatoms mapper)
+ (when started-writing
+ (princ ")\n")))))
+
+(defun custom-save-loaded-themes ()
+ (let ((themes (reverse (get 'user 'theme-loads-themes)))
+ (standard-output (current-buffer)))
+ (when themes
+ (unless (bolp) (princ "\n"))
+ (princ "(custom-load-themes")
+ (mapc (lambda (theme)
+ (princ "\n '")
+ (prin1 theme)) themes)
+ (princ " )\n"))))
+
;;;###autoload
(defun customize-save-customized ()
"Save all user options which have been set in this session."
(interactive)
(mapatoms (lambda (symbol)
(let ((face (get symbol 'customized-face))
- (value (get symbol 'customized-value)))
- (when face
+ (value (get symbol 'customized-value))
+ (face-comment (get symbol 'customized-face-comment))
+ (variable-comment
+ (get symbol 'customized-variable-comment)))
+ (when face
(put symbol 'saved-face face)
+ (custom-push-theme 'theme-face symbol 'user 'set value)
(put symbol 'customized-face nil))
- (when value
+ (when value
(put symbol 'saved-value value)
- (put symbol 'customized-value nil)))))
+ (custom-push-theme 'theme-value symbol 'user 'set value)
+ (put symbol 'customized-value nil))
+ (when variable-comment
+ (put symbol 'saved-variable-comment variable-comment)
+ (put symbol 'customized-variable-comment nil))
+ (when face-comment
+ (put symbol 'saved-face-comment face-comment)
+ (put symbol 'customized-face-comment nil)))))
;; We really should update all custom buffers here.
(custom-save-all))
(save-excursion
(let ((default-major-mode nil))
(set-buffer (find-file-noselect (custom-file))))
- (save-buffer))))
+ (let ((file-precious-flag t))
+ (save-buffer)))))
;;; The Customize Menu.
':style 'toggle
':selected symbol)))
-(if (string-match "XEmacs" emacs-version)
- ;; XEmacs can create menus dynamically.
- (defun custom-group-menu-create (widget symbol)
- "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
- `( ,(custom-unlispify-menu-entry symbol t)
- :filter (lambda (&rest junk)
- (cdr (custom-menu-create ',symbol)))))
- ;; But emacs can't.
- (defun custom-group-menu-create (widget symbol)
- "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
- ;; Limit the nesting.
- (let ((custom-menu-nesting (1- custom-menu-nesting)))
- (custom-menu-create symbol))))
+(defun custom-group-menu-create (widget symbol)
+ "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
+ `( ,(custom-unlispify-menu-entry symbol t)
+ :filter (lambda (&rest junk)
+ (let ((menu (custom-menu-create ',symbol)))
+ (if (consp menu) (cdr menu) menu)))))
;;;###autoload
(defun custom-menu-create (symbol)
t)))
(if (and (or (not (boundp 'custom-menu-nesting))
(>= custom-menu-nesting 0))
- (< (length (get symbol 'custom-group)) widget-menu-max-size))
+ (progn
+ (custom-load-symbol symbol)
+ (< (length (get symbol 'custom-group)) widget-menu-max-size)))
(let ((custom-prefix-list (custom-prefix-add symbol
custom-prefix-list))
(members (custom-sort-items (get symbol 'custom-group)
custom-menu-sort-alphabetically
custom-menu-order-groups)))
- (custom-load-symbol symbol)
`(,(custom-unlispify-menu-entry symbol t)
,item
"--"
;;;###autoload
(defun customize-menu-create (symbol &optional name)
"Return a customize menu for customization group SYMBOL.
-If optional NAME is given, use that as the name of the menu.
+If optional NAME is given, use that as the name of the menu.
Otherwise the menu will be named `Customize'.
The format is suitable for use with `easy-menu-define'."
(unless name
(setq name "Customize"))
- (if (string-match "XEmacs" emacs-version)
- ;; We can delay it under XEmacs.
- `(,name
- :filter (lambda (&rest junk)
- (cdr (custom-menu-create ',symbol))))
- ;; But we must create it now under Emacs.
- (cons name (cdr (custom-menu-create symbol)))))
+ `(,name
+ :filter (lambda (&rest junk)
+ (let ((menu (custom-menu-create ',symbol)))
+ (if (consp menu) (cdr menu) menu)))))
;;; The Custom Mode.
"Keymap for `custom-mode'.")
(unless 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" 'bury-buffer)
+ (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)
(if button
(widget-button-click event)))))
-(easy-menu-define Custom-mode-menu
+(easy-menu-define Custom-mode-menu
custom-mode-map
"Menu used in customization buffers."
`("Custom"
(customize-group parent)))))
(defcustom custom-mode-hook nil
- "Hook called when entering custom-mode."
+ "Hook called when entering Custom mode."
:type 'hook
:group 'custom-buffer )
(use-local-map custom-mode-map)
(easy-menu-add Custom-mode-menu)
(make-local-variable 'custom-options)
+ (make-local-variable 'custom-local-buffer)
(make-local-variable 'widget-documentation-face)
(setq widget-documentation-face 'custom-documentation-face)
(make-local-variable 'widget-button-face)
(setq widget-button-face 'custom-button-face)
- (make-local-hook 'widget-edit-functions)
+ (set (make-local-variable 'widget-button-pressed-face)
+ 'custom-button-pressed-face)
+ (set (make-local-variable 'widget-mouse-face)
+ 'custom-button-pressed-face) ; 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-push-button-prefix) "")
+ (set (make-local-variable 'widget-push-button-suffix) "")
+ (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))
+(put 'custom-mode 'mode-class 'special)
+
+(add-to-list
+ 'debug-ignored-errors
+ "^No user options have changed defaults in recent Emacs versions$")
+
;;; The End.
(provide 'cus-edit)
-;; cus-edit.el ends here
+;;; cus-edit.el ends here