X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b97aca2766d653ab7321668f021e850a4b6e019d..ae2777b77ab61c109b92e0b7fd00fc56f9afb61f:/lisp/cus-edit.el diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index b3d0b52db5..4d4fc08355 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -106,6 +106,10 @@ :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) @@ -408,7 +412,7 @@ Return a list suitable for use in `interactive'." 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))))) @@ -607,6 +611,8 @@ If `last', order groups after non-groups." (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. @@ -809,38 +815,51 @@ are shown; the contents of those subgroups are initially hidden." (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) @@ -853,6 +872,88 @@ are shown; the contents of those subgroups are initially hidden." (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) @@ -1012,7 +1113,7 @@ SYMBOL is a customization option, and WIDGET is a widget for editing 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 @@ -1024,8 +1125,13 @@ SYMBOL is a customization option, and WIDGET is a widget for editing 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))) @@ -1116,7 +1222,7 @@ Reset all values in this buffer to their standard settings." (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 @@ -1129,7 +1235,7 @@ Reset all values in this buffer to their standard settings." 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...") @@ -1147,7 +1253,7 @@ Reset all values in this buffer to their standard settings." (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 @@ -1182,7 +1288,7 @@ item in another window.\n\n")) (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) @@ -1384,8 +1490,8 @@ The list should be sorted most significant first.") "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) @@ -1732,6 +1838,13 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"." "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" @@ -1740,7 +1853,7 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"." :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 @@ -1768,6 +1881,8 @@ Otherwise, look up symbol in `custom-guess-type-alist'." (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)) @@ -1847,7 +1962,7 @@ Otherwise, look up symbol in `custom-guess-type-alist'." (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 @@ -1960,7 +2075,7 @@ Otherwise, look up symbol in `custom-guess-type-alist'." ("Don't show as Lisp expression" custom-variable-edit (lambda (widget) (eq (widget-get widget :custom-form) 'lisp))) - ("Show as Lisp expression" custom-variable-edit-lisp + ("Show initial Lisp expression" custom-variable-edit-lisp (lambda (widget) (eq (widget-get widget :custom-form) 'edit)))) "Alist of actions for the `custom-variable' widget. @@ -2009,7 +2124,7 @@ Optional EVENT is the location for the menu." (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))) @@ -2023,7 +2138,7 @@ Optional EVENT is the location for the menu." (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))) @@ -2031,7 +2146,7 @@ Optional EVENT is the location for the menu." (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))) @@ -2168,6 +2283,14 @@ Match frames with dark backgrounds.") "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 @@ -2177,7 +2300,7 @@ Match frames with dark backgrounds.") :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 @@ -2281,6 +2404,8 @@ Match frames with dark backgrounds.") (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) @@ -2315,7 +2440,7 @@ Match frames with dark backgrounds.") (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))) @@ -2394,14 +2519,20 @@ Optional EVENT is the location for the menu." (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))) @@ -2490,12 +2621,12 @@ Optional EVENT is the location for the menu." (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") @@ -2707,7 +2838,7 @@ If GROUPS-ONLY non-nil, return only those members that are groups." 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))) @@ -2918,23 +3049,27 @@ Optional EVENT is the location for the menu." ;;; The `custom-save-all' Function. ;;;###autoload -(defcustom custom-file (if (boundp 'emacs-user-extension-dir) - (concat "~" - init-file-user - emacs-user-extension-dir - "options.el") - (convert-standard-filename"~/.emacs")) +(defcustom custom-file nil "File used for storing customization information. -If you change this from the default \"~/.emacs\" (or \"~/_emacs\" -on MS-DOS) 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-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 custom-file)) + (let ((default-major-mode)) + (set-buffer (find-file-noselect (custom-file)))) (goto-char (point-min)) (catch 'found (while t @@ -3041,7 +3176,8 @@ Leave point at the location of the call, or after the last expression." (custom-save-variables) (custom-save-faces) (save-excursion - (set-buffer (find-file-noselect custom-file)) + (let ((default-major-mode nil)) + (set-buffer (find-file-noselect (custom-file)))) (save-buffer)))) ;;; The Customize Menu.