;;
;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
;; Keywords: help, faces
-;; Version: 1.9944
+;; Version: 1.9954
;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
;; This file is part of GNU Emacs.
:group 'custom-menu
:type 'boolean)
+(defcustom custom-unlispify-remove-prefixes nil
+ "Non-nil means remove group prefixes from option names in buffer."
+ :group 'custom-menu
+ :type 'boolean)
+
(defun custom-unlispify-menu-entry (symbol &optional no-suffix)
"Convert symbol into a menu entry."
(cond ((not custom-unlispify-menu-entries)
(re-search-forward "-p\\'" nil t))
(replace-match "" t t)
(goto-char (point-min)))
- (let ((prefixes custom-prefix-list)
- prefix)
- (while prefixes
- (setq prefix (car prefixes))
- (if (search-forward prefix (+ (point) (length prefix)) t)
- (progn
- (setq prefixes nil)
- (delete-region (point-min) (point)))
- (setq prefixes (cdr prefixes)))))
+ (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
+ (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
(funcall (or (get var 'custom-set) 'set-default) var val)
(put var 'customized-value (list (custom-quote val))))
+;;;###autoload
+(defun customize-save-variable (var val)
+ "Set the default for VARIABLE to VALUE, and save it for future sessions.
+If VARIABLE has a `custom-set' property, that is used for setting
+VARIABLE, otherwise `set-default' is used.
+
+The `customized-value' property of the VARIABLE will be set to a list
+with a quoted VALUE as its sole list member.
+
+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. "
+ (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))
+
;;;###autoload
(defun customize ()
"Select a customization buffer which you can use to set user options.
(completing-read "Customize group: (default emacs) "
obarray
(lambda (symbol)
- (get symbol 'custom-group))
+ (or (get symbol 'custom-loads)
+ (get symbol 'custom-group)))
t))))
-
(when (stringp 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)
options))))
(unless (eq (preceding-char) ?\n)
(widget-insert "\n"))
+ (message "Creating customization items %2d%%...done" 100)
(unless (eq custom-buffer-style 'tree)
(mapcar 'custom-magic-reset custom-options))
(message "Creating customization setup...")
;;; The Tree Browser.
;;;###autoload
-(defun customize-browse (group)
+(defun customize-browse (&optional group)
"Create a tree browser for the customize hierarchy."
- (interactive (list (let ((completion-ignore-case t))
- (completing-read "Customize group: (default emacs) "
- obarray
- (lambda (symbol)
- (get symbol 'custom-group))
- t))))
-
- (when (stringp group)
- (if (string-equal "" group)
- (setq group 'emacs)
- (setq group (intern group))))
+ (interactive)
+ (unless group
+ (setq group 'emacs))
(let ((name "*Customize Browser*"))
(kill-buffer (get-buffer-create name))
(switch-to-buffer (get-buffer-create name)))
(custom-mode)
(widget-insert "\
-Invoke [+] or [?] below to expand items, and [-] to collapse items.\n")
+Square brackets show active fields; type RET or click mouse-1
+on an active field to invoke its action.
+Invoke [+] below to expand a group, and [-] to collapse an expanded group.\n")
(if custom-browse-only-groups
(widget-insert "\
Invoke the [Group] button below to edit that item in another window.\n\n")
(text (or (and (eq category 'group)
(nth 4 entry))
(nth 3 entry)))
- (lisp (eq (widget-get parent :custom-form) 'lisp))
+ (form (widget-get parent :custom-form))
children)
(while (string-match "\\`\\(.*\\)%c\\(.*\\)\\'" text)
(setq text (concat (match-string 1 text)
(if (eq custom-magic-show 'long)
(insert text)
(insert (symbol-name state)))
- (when lisp
- (insert " (lisp)"))
+ (cond ((eq form 'lisp)
+ (insert " (lisp)"))
+ ((eq form 'mismatch)
+ (insert " (mismatch)")))
(put-text-property start (point) 'face 'custom-state-face))
(insert "\n"))
(when (and (eq category 'group)
:button-suffix ""
:help-echo "Change the state."
:format (if hidden "%t" "%[%t%]")
- :tag (if lisp
+ :tag (if (memq form '(lisp mismatch))
(concat "(" magic ")")
(concat "[" magic "]")))
children)
(require load)
(error nil)))
;; Don't reload a file already loaded.
- ((member load preloaded-file-list))
+ ((and (boundp 'preloaded-file-list)
+ (member load preloaded-file-list)))
((assoc load load-history))
((assoc (locate-library load) load-history))
(t
(when (eq state 'unknown)
(unless (widget-apply conv :match value)
;; (widget-apply (widget-convert type) :match value)
- (setq form 'lisp)))
+ (setq form 'mismatch)))
;; Now we can create the child widget.
(cond ((eq custom-buffer-style 'tree)
(insert prefix (if last " `--- " " |--- "))
:action 'custom-toggle-parent
nil)
buttons))
- ((eq form 'lisp)
+ ((memq form '(lisp mismatch))
;; In lisp mode edit the saved value when possible.
(let* ((value (cond ((get symbol 'saved-value)
(car (get symbol 'saved-value)))
(let* ((format (widget-get type :format))
tag-format value-format)
(unless (string-match ":" format)
- (error "Bad format."))
+ (error "Bad format"))
(setq tag-format (substring format 0 (match-end 0)))
(setq value-format (substring format (match-end 0)))
(push (widget-create-child-and-convert
("---" ignore ignore)
("Don't show as Lisp expression" custom-variable-edit
(lambda (widget)
- (not (eq (widget-get widget :custom-form) 'edit))))
- ("Show as Lisp expression" custom-variable-edit-lisp
+ (eq (widget-get widget :custom-form) 'lisp)))
+ ("Show initial Lisp expression" custom-variable-edit-lisp
(lambda (widget)
- (not (eq (widget-get widget :custom-form) 'lisp)))))
+ (eq (widget-get widget :custom-form) 'edit))))
"Alist of actions for the `custom-variable' widget.
Each entry has the form (NAME ACTION FILTER) where NAME is the name of
the menu entry, ACTION is the function to call on the widget when the
(set (or (get symbol 'custom-set) 'set-default))
val)
(cond ((eq state 'hidden)
- (error "Cannot set hidden variable."))
+ (error "Cannot set hidden variable"))
((setq val (widget-apply child :validate))
(goto-char (widget-get val :from))
(error "%s" (widget-get val :error)))
- ((eq form 'lisp)
+ ((memq form '(lisp mismatch))
(funcall set symbol (eval (setq val (widget-value child))))
(put symbol 'customized-value (list val)))
(t
(custom-redraw-magic widget)))
(defun custom-variable-save (widget)
- "Set the default value for the variable being edited by WIDGET."
+ "Set and save the value for the variable being edited by WIDGET."
(let* ((form (widget-get widget :custom-form))
(state (widget-get widget :custom-state))
(child (car (widget-get widget :children)))
(set (or (get symbol 'custom-set) 'set-default))
val)
(cond ((eq state 'hidden)
- (error "Cannot set hidden variable."))
+ (error "Cannot set hidden variable"))
((setq val (widget-apply child :validate))
(goto-char (widget-get val :from))
(error "%s" (widget-get val :error)))
- ((eq form 'lisp)
+ ((memq form '(lisp mismatch))
(put symbol 'saved-value (list (widget-value child)))
(funcall set symbol (eval (widget-value child))))
(t
:sibling-args (:help-echo "\
OS/2 Presentation Manager.")
pm)
- (const :format "Win32 "
+ (const :format "W32 "
:sibling-args (:help-echo "\
-Windows NT/95/97.")
- win32)
+Windows NT/9X.")
+ w32)
(const :format "DOS "
:sibling-args (:help-echo "\
Plain MS-DOS.")
symbol (selected-frame))))))
(form (widget-get widget :custom-form))
(indent (widget-get widget :indent))
- (edit (widget-create-child-and-convert
+ edit)
+ ;; If the user has changed this face in some other way,
+ ;; 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 edit (widget-create-child-and-convert
widget
(cond ((and (eq form 'selected)
(widget-apply custom-face-selected
(t
(when indent (insert-char ?\ indent))
'sexp))
- :value spec)))
+ :value spec))
(custom-face-state-set widget)
(widget-put widget :children (list edit)))
(message "Creating face editor...done"))))))
(defvar custom-face-menu
'(("Set for Current Session" custom-face-set)
- ("Save for Future Sessions" custom-face-save)
+ ("Save for Future Sessions" custom-face-save-command)
("Reset to Saved" custom-face-reset-saved
(lambda (widget)
(get (widget-value widget) 'saved-face)))
(custom-face-state-set widget)
(custom-redraw-magic widget)))
+(defun custom-face-save-command (widget)
+ "Save in `.emacs' the face attributes in WIDGET."
+ (custom-face-save widget)
+ (custom-save-all))
+
(defun custom-face-save (widget)
- "Make the face attributes in WIDGET default."
+ "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)))
(define-widget 'hook 'list
"A emacs lisp hook"
+ :value-to-internal (lambda (widget value)
+ (if (and value (symbolp value))
+ (list value)
+ value))
+ :match (lambda (widget value)
+ (or (symbolp value)
+ (widget-editable-list-match widget value)))
:convert-widget 'custom-hook-convert-widget
:tag "Hook")
(insert "--------")))
(widget-default-create widget))
+(defun custom-group-members (symbol groups-only)
+ "Return SYMBOL's custom group members.
+If GROUPS-ONLY non-nil, return only those members that are groups."
+ (if (not groups-only)
+ (get symbol 'custom-group)
+ (let (members)
+ (dolist (entry (get symbol 'custom-group))
+ (when (eq (nth 1 entry) 'custom-group)
+ (push entry members)))
+ (nreverse members))))
+
(defun custom-group-value-create (widget)
"Insert a customize group for WIDGET in the current buffer."
- (let ((state (widget-get widget :custom-state))
- (level (widget-get widget :custom-level))
- (indent (widget-get widget :indent))
- (prefix (widget-get widget :custom-prefix))
- (buttons (widget-get widget :buttons))
- (tag (widget-get widget :tag))
- (symbol (widget-value widget)))
+ (let* ((state (widget-get widget :custom-state))
+ (level (widget-get widget :custom-level))
+ ;; (indent (widget-get widget :indent))
+ (prefix (widget-get widget :custom-prefix))
+ (buttons (widget-get widget :buttons))
+ (tag (widget-get widget :tag))
+ (symbol (widget-value widget))
+ (members (custom-group-members symbol
+ (and (eq custom-buffer-style 'tree)
+ custom-browse-only-groups))))
(cond ((and (eq custom-buffer-style 'tree)
(eq state 'hidden)
- (or (get symbol 'custom-group)
- (custom-unloaded-widget-p widget)))
+ (or members (custom-unloaded-widget-p widget)))
(custom-browse-insert-prefix prefix)
(push (widget-create-child-and-convert
widget 'custom-browse-visibility
;; :tag-glyph "plus"
- :tag (if (custom-unloaded-widget-p widget) "?" "+"))
+ :tag "+")
buttons)
(insert "-- ")
;; (widget-glyph-insert nil "-- " "horizontal")
(insert " " tag "\n")
(widget-put widget :buttons buttons))
((and (eq custom-buffer-style 'tree)
- (zerop (length (get symbol 'custom-group))))
+ (zerop (length members)))
(custom-browse-insert-prefix prefix)
(insert "[ ]-- ")
;; (widget-glyph-insert nil "[ ]" "empty")
((eq custom-buffer-style 'tree)
(custom-browse-insert-prefix prefix)
(custom-load-widget widget)
- (if (zerop (length (get symbol 'custom-group)))
+ (if (zerop (length members))
(progn
(custom-browse-insert-prefix prefix)
(insert "[ ]-- ")
(insert " " tag "\n")
(widget-put widget :buttons buttons)
(message "Creating group...")
- (let* ((members (custom-sort-items (get symbol 'custom-group)
+ (let* ((members (custom-sort-items members
custom-browse-sort-alphabetically
custom-browse-order-groups))
(prefixes (widget-get widget :custom-prefixes))
(while members
(setq entry (car members)
members (cdr members))
- (when (or (not custom-browse-only-groups)
- (eq (nth 1 entry) 'custom-group))
- (push (widget-create-child-and-convert
- widget (nth 1 entry)
- :group widget
- :tag (custom-unlispify-tag-name (nth 0 entry))
- :custom-prefixes custom-prefix-list
- :custom-level (1+ level)
- :custom-last (null members)
- :value (nth 0 entry)
- :custom-prefix prefix)
- children)))
+ (push (widget-create-child-and-convert
+ widget (nth 1 entry)
+ :group widget
+ :tag (custom-unlispify-tag-name (nth 0 entry))
+ :custom-prefixes custom-prefix-list
+ :custom-level (1+ level)
+ :custom-last (null members)
+ :value (nth 0 entry)
+ :custom-prefix prefix)
+ children))
(widget-put widget :children (reverse children)))
(message "Creating group...done")))
;; Nested style.
;; Members.
(message "Creating group...")
(custom-load-widget widget)
- (let* ((members (custom-sort-items (get symbol 'custom-group)
+ (let* ((members (custom-sort-items members
custom-buffer-sort-alphabetically
custom-buffer-order-groups))
(prefixes (widget-get widget :custom-prefixes))
;;; The `custom-save-all' Function.
;;;###autoload
-(defcustom custom-file (if (featurep 'xemacs)
- "~/.xemacs-custom"
- "~/.emacs")
+(defcustom custom-file nil
"File used for storing customization information.
-If you change this from the default \"~/.emacs\" you need to
-explicitly load that file for the settings to take effect."
- :type 'file
+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."
+ :type '(choice (const :tag "Your Emacs init file" nil) file)
:group 'customize)
(defun custom-save-delete (symbol)
"Delete the call to SYMBOL form `custom-file'.
Leave point at the location of the call, or after the last expression."
- (set-buffer (find-file-noselect custom-file))
+ (set-buffer (find-file-noselect (or custom-file user-init-file)))
(goto-char (point-min))
(catch 'found
(while t
;;;###autoload
(defun custom-save-all ()
"Save all customizations in `custom-file'."
- (custom-save-variables)
- (custom-save-faces)
- (save-excursion
- (set-buffer (find-file-noselect custom-file))
- (save-buffer)))
+ (let ((inhibit-read-only t))
+ (custom-save-variables)
+ (custom-save-faces)
+ (save-excursion
+ (set-buffer (find-file-noselect (or custom-file user-init-file)))
+ (save-buffer))))
;;; The Customize Menu.
;;; Menu support
-(unless (string-match "XEmacs" emacs-version)
- (defconst custom-help-menu
- '("Customize"
- ["Update menu" Custom-menu-update t]
- ["Browse" (customize-browse 'emacs) t]
- ["Group..." customize-group t]
- ["Option..." customize-option t]
- ["Face..." customize-face t]
- ["Saved..." customize-saved t]
- ["Set..." customize-customized t]
- "--"
- ["Apropos..." customize-apropos t]
- ["Group apropos..." customize-apropos-groups t]
- ["Option apropos..." customize-apropos-options t]
- ["Face apropos..." customize-apropos-faces t])
- ;; This menu should be identical to the one defined in `menu-bar.el'.
- "Customize menu")
-
- (defun custom-menu-reset ()
- "Reset customize menu."
- (remove-hook 'custom-define-hook 'custom-menu-reset)
- (define-key global-map [menu-bar help-menu customize-menu]
- (cons (car custom-help-menu)
- (easy-menu-create-keymaps (car custom-help-menu)
- (cdr custom-help-menu)))))
-
- (defun Custom-menu-update (event)
- "Update customize menu."
- (interactive "e")
- (add-hook 'custom-define-hook 'custom-menu-reset)
- (let* ((emacs (widget-apply '(custom-group) :custom-menu 'emacs))
- (menu `(,(car custom-help-menu)
- ,emacs
- ,@(cdr (cdr custom-help-menu)))))
- (let ((map (easy-menu-create-keymaps (car menu) (cdr menu))))
- (define-key global-map [menu-bar help-menu customize-menu]
- (cons (car menu) map))))))
-
(defcustom custom-menu-nesting 2
"Maximum nesting in custom menus."
:type 'integer
Move to next button or editable field. \\[widget-forward]
Move to previous button or editable field. \\[widget-backward]
+\\<widget-field-keymap>\
+Complete content of editable text field. \\[widget-complete]
+\\<custom-mode-map>\
Invoke button under the mouse pointer. \\[Custom-move-and-invoke]
Invoke button under point. \\[widget-button-press]
Set all modifications. \\[Custom-set]