:group 'external
:group 'development)
+(defgroup convenience nil
+ "Convenience features for faster editing."
+ :group 'emacs)
+
(defgroup programming nil
"Support for programming in other languages."
:group 'emacs)
(defgroup customize '((widgets custom-group))
"Customization of the Customization support."
- :link '(custom-manual "(custom)Top")
+ :link '(custom-manual "(elisp)Customization")
:link '(url-link :tag "Development Page"
"http://www.dina.kvl.dk/~abraham/custom/")
:prefix "custom-"
obarray (lambda (symbol)
(and (boundp symbol)
(or (get symbol 'custom-type)
- (user-variable-p symbol))))))
+ (user-variable-p symbol)))) t))
(list (if (equal val "")
(if (symbolp v) v nil)
(intern val)))))
(const :tag "none" nil))
:group 'custom-menu)
+;;;###autoload (add-hook 'same-window-regexps "\\`\\*Customiz.*\\*\\'")
+
(defun custom-sort-items (items sort-alphabetically order-groups)
"Return a sorted copy of ITEMS.
ITEMS should be a `custom-group' property.
(interactive)
(let ((children custom-options))
(mapcar (lambda (child)
- (when (memq (widget-get child :custom-state) '(modified set))
+ (when (memq (widget-get child :custom-state)
+ '(modified set changed rogue))
(widget-apply child :custom-save)))
children))
(custom-save-all))
"Reset all modified group members to their current value."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (child)
- (when (eq (widget-get child :custom-state) 'modified)
- (widget-apply child :custom-reset-current)))
+ (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)))
(defun Custom-reset-saved (&rest ignore)
"Reset all modified or set group members to their saved value."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (child)
- (when (eq (widget-get child :custom-state) 'modified)
- (widget-apply child :custom-reset-saved)))
+ (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)))
(defun Custom-reset-standard (&rest ignore)
"Reset all modified, set, or saved group members to their standard settings."
(interactive)
(let ((children custom-options))
- (mapcar (lambda (child)
- (when (eq (widget-get child :custom-state) 'modified)
- (widget-apply child :custom-reset-standard)))
+ (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))))
children)))
;;; The Customize Commands
(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)
- (switch-to-buffer name)
+ (pop-to-buffer name)
(custom-buffer-create (list (list group 'custom-group))
name
(concat " for group "
(custom-unlispify-tag-name group))))))
;;;###autoload
-(defun customize-group-other-window (symbol)
- "Customize SYMBOL, which must be a customization group."
- (interactive (list (completing-read "Customize group: (default emacs) "
- obarray
- (lambda (symbol)
- (get symbol 'custom-group))
- t)))
-
- (when (stringp symbol)
- (if (string-equal "" symbol)
- (setq symbol 'emacs)
- (setq symbol (intern symbol))))
- (custom-buffer-create-other-window
- (list (list symbol 'custom-group))
- (format "*Customize Group: %s*" (custom-unlispify-tag-name symbol))))
+(defun customize-group-other-window (group)
+ "Customize GROUP, which must be a customization group."
+ (interactive (list (let ((completion-ignore-case t))
+ (completing-read "Customize group: (default emacs) "
+ obarray
+ (lambda (symbol)
+ (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)
+ (let ((window (selected-window)))
+ (pop-to-buffer name)
+ (select-window window))
+ (custom-buffer-create-other-window
+ (list (list group 'custom-group))
+ name
+ (concat " for group "
+ (custom-unlispify-tag-name group))))))
;;;###autoload
(defalias 'customize-variable 'customize-option)
(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))))
+(defvar customize-changed-options-previous-release "20.2"
+ "Version for `customize-changed-options' to refer back to by default.")
+
+;;;###autoload
+(defun customize-changed-options (since-version)
+ "Customize all user option variables changed in Emacs itself.
+This includes new user option variables and faces, and new
+customization groups, as well as older options and faces whose default
+values have changed since the previous major Emacs release.
+
+With argument SINCE-VERSION (a string), customize all user option
+variables that were added (or their meanings were changed) since that
+version."
+
+ (interactive "sCustomize options changed, since version (default all versions): ")
+ (if (equal since-version "")
+ (setq since-version nil))
+ (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*"))))
+
+(defun customize-version-lessp (version1 version2)
+ ;; 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)))
+ (or (< major1 major2)
+ (and (= major1 major2)
+ (< minor1 minor2)))))
+
;;;###autoload
(defalias 'customize-variable-other-window 'customize-option-other-window)
that option."
(unless name (setq name "*Customization*"))
(kill-buffer (get-buffer-create name))
- (switch-to-buffer (get-buffer-create name))
+ (pop-to-buffer (get-buffer-create name))
(custom-buffer-create-internal options description))
;;;###autoload
that option."
(unless name (setq name "*Customization*"))
(kill-buffer (get-buffer-create name))
- (let ((window (selected-window)))
- (switch-to-buffer-other-window (get-buffer-create name))
+ (let ((window (selected-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 (get-buffer-create name))
(custom-buffer-create-internal options description)
(select-window window)))
(length (length options)))
(mapcar (lambda (entry)
(prog2
- (message "Creating customization items %2d%%..."
+ (message "Creating customization items ...%2d%%"
(/ (* 100.0 count) length))
(widget-create (nth 1 entry)
:tag (custom-unlispify-tag-name
options))))
(unless (eq (preceding-char) ?\n)
(widget-insert "\n"))
- (message "Creating customization items %2d%%...done" 100)
+ (message "Creating customization items ...%2d%%done" 100)
(unless (eq custom-buffer-style 'tree)
(mapcar 'custom-magic-reset custom-options))
(message "Creating customization setup...")
(setq group 'emacs))
(let ((name "*Customize Browser*"))
(kill-buffer (get-buffer-create name))
- (switch-to-buffer (get-buffer-create name)))
+ (pop-to-buffer (get-buffer-create name)))
(custom-mode)
(widget-insert "\
Square brackets show active fields; type RET or click mouse-1
(goto-char (point-min)))
(define-widget 'custom-browse-visibility 'item
- "Control visibility of of items in the customize tree browser."
+ "Control visibility of items in the customize tree browser."
:format "%[[%t]%]"
:action 'custom-browse-visibility-action)
"If non-nil, show textual description of the state.
If `long', show a full-line description, not just one word."
:type '(choice (const :tag "no" nil)
- (const short)
- (const long))
+ (const long)
+ (other :tag "short" short))
:group 'custom-buffer)
(defcustom custom-magic-show-hidden '(option face)
"Face used for pushable variable tags."
:group 'custom-faces)
+(defcustom custom-variable-default-form 'edit
+ "Default form of displaying variable values."
+ :type '(choice (const edit)
+ (const lisp))
+ :group 'custom-buffer
+ :version "20.3")
+
(define-widget 'custom-variable 'custom
"Customize variable."
:format "%v"
:custom-category 'option
:custom-state nil
:custom-menu 'custom-variable-menu-create
- :custom-form 'edit
+ :custom-form nil ; defaults to value of `custom-variable-default-form'
:value-create 'custom-variable-value-create
:action 'custom-variable-action
:custom-set 'custom-variable-set
(defun custom-variable-value-create (widget)
"Here is where you edit the variables value."
(custom-load-widget widget)
+ (unless (widget-get widget :custom-form)
+ (widget-put widget :custom-form custom-variable-default-form))
(let* ((buttons (widget-get widget :buttons))
(children (widget-get widget :children))
(form (widget-get widget :custom-form))
(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
(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)))
(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)))
"Face used for face tags."
:group 'custom-faces)
+(defcustom custom-face-default-form 'selected
+ "Default form of displaying face definition."
+ :type '(choice (const all)
+ (const selected)
+ (const lisp))
+ :group 'custom-buffer
+ :version "20.3")
+
(define-widget 'custom-face 'custom
"Customize face."
:sample-face 'custom-face-tag-face
:value-create 'custom-face-value-create
:action 'custom-face-action
:custom-category 'face
- :custom-form 'selected
+ :custom-form nil ; defaults to value of `custom-face-default-form'
:custom-set 'custom-face-set
:custom-save 'custom-face-save
:custom-reset-current 'custom-redraw
(unless (eq state 'hidden)
(message "Creating face editor...")
(custom-load-widget widget)
+ (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)
(get symbol 'face-defface-spec)
(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)))
(face-spec-set symbol value)
(put symbol 'saved-face value)
(put symbol 'customized-face nil)
+ (custom-save-all)
(custom-face-state-set widget)
(custom-redraw-magic widget)))
(define-widget 'hook 'list
"A emacs lisp hook"
:value-to-internal (lambda (widget value)
- (if (symbolp value)
+ (if (and value (symbolp value))
(list value)
value))
:match (lambda (widget value)
(or (symbolp value)
- (widget-editable-list-match widget value)))
+ (widget-group-match widget value)))
:convert-widget 'custom-hook-convert-widget
:tag "Hook")
symbol)
buttons)
(push (widget-create-child-and-convert
- widget 'group-visibility
+ widget 'custom-group-visibility
:help-echo "Show members of this group."
:action 'custom-toggle-parent
(not (eq state 'hidden)))
:type '(choice (const :tag "Your Emacs init file" nil) file)
:group 'customize)
+(defun custom-file ()
+ "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"))))
+
(defun custom-save-delete (symbol)
- "Delete the call to SYMBOL form `custom-file'.
+ "Delete the call to SYMBOL from `custom-file'.
Leave point at the location of the call, or after the last expression."
- (set-buffer (find-file-noselect (or custom-file user-init-file)))
+ (let ((default-major-mode))
+ (set-buffer (find-file-noselect (custom-file))))
(goto-char (point-min))
(catch 'found
(while t
(custom-save-variables)
(custom-save-faces)
(save-excursion
- (set-buffer (find-file-noselect (or custom-file user-init-file)))
+ (let ((default-major-mode nil))
+ (set-buffer (find-file-noselect (custom-file))))
(save-buffer))))
;;; The Customize Menu.
["Reset to Current" Custom-reset-current t]
["Reset to Saved" Custom-reset-saved t]
["Reset to Standard Settings" Custom-reset-standard t]
- ["Info" (Info-goto-node "(custom)The Customization Buffer") t]))
+ ["Info" (Info-goto-node "(emacs)Easy Customization") t]))
(defun Custom-goto-parent ()
"Go to the parent group listed at the top of this buffer.