Homepage: https://www.emacswiki.org/emacs/download/cus-edit%2b.el
Author: Drew Adams
Updated:
Enhancements to `cus-edit.el'
Enhancements to `cus-edit.el'. Terminology ----------- Most of the enhancements here basically try to make Customize play a little better with Emacs. Customize deals with user preferences, which are faces and variables. User variables are also called "user options"; they are defined by `user-variable-p'. All faces are user preferences. Note: The Customize source code sometimes refers to both faces and user variables (what I am calling "user preferences") as "user options". The latter term has traditionally been used in Emacs for user variables only. Contents -------- The enhancements to standard library `cus-edit.el' provided by `cus-edit+.el' include miscellaneous enhancements, such as formatting the Customize buffer better, and enhancements to make Customize play better with the rest of Emacs. Most of the description here is about the latter. Customizing Options of a Particular Type ---------------------------------------- Command `customize-apropos-options-of-type' is similar to the standard command `customize-apropos-options', but it also lets you specify the type of the options to find. To use `customize-apropos-options-of-type', you specify a `defcustom' type and a regexp. The command opens a Customize buffer for all options that are defined with the specified type and whose names match the specified regexp. With a prefix argument, the matching options need not be defined with exactly the same `defcustom' type. They need only have their current value be compatible with the type you specify. Enhancements to Make Customize Play Better with Emacs ----------------------------------------------------- There are various ways to change preferences outside of Customize, and Customize unfortunately doesn't recognize these changes as preference settings - it considers them to be "changed outside the customize buffer", which really means that it just throws up its hands. The main idea here is to let Customize know about changes made outside it, to make Customize think that they were made inside Customize. In this way, there is no such outside/inside distinction (for user preferences), and it doesn't matter where or how a preference is changed. When this is the case, you can use command `customize-unsaved' to check all preferences that have been changed from their standard or saved settings, and it will take all changes into account, no matter how or where the changes were made. Because this is useful, `customize-unsaved' has been modified to be used as a hook in `kill-emacs-query-functions'. That way, before you quit Emacs, you are notified of all preference changes you have made and given a chance to save them (individually or collectively). This is analogous to Emacs asking you about files you've changed but not saved, before letting you exit. If you also use another hook function to confirm exit from Emacs, and it is invoked after `customize-unsaved', then you will likely want to also customize `customize-unsaved-confirm-exits-flag' to non-`nil'. That stops `customize-unsaved' from canceling quitting. In this scenario, `C-x C-c' becomes, in effect, a key binding for `customize-unsaved': Say `y' to see your unsaved changes and then `y' or `n' to the next prompt to quit Emacs or not, depending on whether you want to save some changes before quitting. Updating Customize with External Changes ---------------------------------------- In order to keep Customize synched with changes made outside it, command `customize-update-all' can be used automatically during idle moments to tell Customize that all user options and faces that have been changed outside it are now set - just as if they were set in Customize. You can turn this automatic updating on and off with command `customize-toggle-outside-change-updates'. Read This If You Use Frame-Specific Faces ----------------------------------------- The automatic updating that you turn on (or off) with `customize-toggle-outside-change-updates' uses internal variable `custom-update-timer' to periodically run command `customize-update-all'. That command in turn uses commands `customize-update-all-vars' to update variables and `customize-update-all-faces' to updated faces. It thus updates Customize with respect to face changes as well as variable changes. Unlike user options (variables), faces can be specific to individual frames. The face updating code used here assumes that you do not use different versions of a face on different frames, that, for example, face `foo' has the same attributes on all frames. If that is not the way you use faces and frames, then you might not want to automatically update Customize to recognize face changes made outside Customize. In that case, change the value of `custom-update-timer' in your init file (~/.emacs) to use `customize-update-all-vars' instead of `customize-update-all': (defvar custom-update-timer (run-with-idle-timer custom-check-for-changes-interval t 'customize-update-all-vars) ; <====== "Timer used to automatically tell Customize of outside changes to preferences when idle.") The automatic face updating works like this: The current-frame definition of each face is compared with the face's definition according to Customize. If these are different, then the Customize definition is updated to the current-frame definition. Since there is no way to know which frame will be current when updating takes place, if you 1) use automatic updating and 2) use different definitions of a given face on different frames, then you probably do not want to update faces automatically. Dealing with Spurious Changes, 1: Save -------------------------------------- Even if you don't change any preferences yourself, when you quit Emacs the first time you are informed that there are lots of changed preferences, and you are given a chance to save those changes. What are those changes? They represent all of the user preferences that Emacs and various Emacs libraries have changed behind Customize's back - even before you did anything. You'll see user options like `baud-rate' that are set in Emacs C code without informing Customize to mark their settings as `standard' (= installed). There shouldn't be any such apparent "changes", since this is part of standard Emacs, but that's the way it is, for now. Customize is still fairly new, and lots of Emacs libraries still define and change user preferences without going through Customize and, in effect, telling it not to consider such preference changes as changes. If you choose to save these preference changes, you will never again be bothered by being informed that they have changed (unless you change them). So, that's one solution to this bother, which makes it a one-time only nuisance: just say "save all". Dealing with Spurious Changes, 2: Ignore ---------------------------------------- Another solution is also possible. Some user preferences, like `case-fold-search' and `debug-on-error' are really the kind of thing that you change often and temporarily - you don't really care about saving their changes, and you certainly don't want to be asked whether or not you want to save them each you quit Emacs. To deal with that, a list of ignored preferences, `customize-unsaved-ignore', is defined here. Its preferences (symbols) are not used by `customize-unsaved' at all (you can override that interactively with a prefix arg). So, the other way to deal with the legacy Emacs preferences, besides just saving them in your custom file, is to add them to `customize-unsaved-ignore' so `customize-unsaved' will ignore them. To make it easy for you to add preferences to this ignore list, `Ignore Unsaved Changes' menu items and buttons have been added. You can choose to ignore specific preferences or all preferences in a Customize buffer - in particular, all preferences in the Customize buffer from `customize-unsaved' (all changed preferences). Dealing with Spurious Changes, 3: Consider Unchanged ---------------------------------------------------- There is also a third way to treat preference changes that you are not responsible for, as an alternative to saving them to your custom file or having Customize always ignore them: tell Customize to consider the current changes as unchanged. This essentially treats them as having been saved, but without saving them. You can do this using the `Consider Unchanged' menu items and buttons added here. For instance, after starting Emacs, you can examine the current preference changes (using `customize-unsaved') from Emacs itself and loaded libraries, and choose `Consider Unchanged' to let Customize know that the current values are to be treated as if they were saved, but without actually saving them to your custom file. That way, your custom file is not polluted with things that you are not really concerned with, yet you are not bothered by seeing such fictitious changes show up each time you check for changes. However, unlike ignoring changes to certain preferences, and really saving current preference values, `Consider Unchanged' is not a persistent change. You can use it at any time to "reset" the change counter for given preferences, so that the current change is considered the new base value (as if it were saved), and any further changes you make to them will show up as changes, using `customize-unsaved'. Updating, Revisited ------------------- Finally, there is one more additional menu item and button provided here, `Set from External Changes', which just executes the appropriate `customize-update-all*' command (depending on the menu/button location). It is useful if you do not choose to use automatic updating of preferences that are changed outside of Customize. Conclusion & Future ------------------- The changes in Customize behavior provided by this library are important, because they can encourage library authors to explore other ways of changing preference values, and still let users save the changes using Customize. For instance in my library `doremi-frm.el' I have defined several commands that let you directly manipulate frame and face properties (e.g. incremental color changes). By making Customize aware of such "outside" changes, you can easily save them in Customize. There are lots of preferences that would be amenable to such "direct-manipulation", which I think would be an improvement in ease of customization. In sum, this library in effect gets rid of the useless "changed outside Customize" state. User preferences have only the `standard', `saved', or `set' (= unsaved) state, regardless of how they are set. Someday, Customize will be more integrated with the rest of Emacs, and "changed outside Customize" will make no more sense than "changed outside of Emacs". Customize will then be just one possible way to access the space of user preferences, the same preference space that other parts of Emacs can access differently. If we're writing on the same blackboard, you can see what I erase, and I can see what you write. That's the goal. This tries to be a step on the way. How To Use ---------- To use this library, put this in your init file (.emacs): (require cus-edit+) To update Customize once, manually, so that it learns about stuff that was customized outside it, use any of these commands: `customize-update-all-faces', `customize-update-all-vars', `customize-update-all' (which is both faces and variables). To do the same updating automatically, add this to your init file (automatic updating is off by default): (customize-toggle-outside-change-updates 99) To turn automatic updating on/off, use command `customize-toggle-outside-change-updates'. To change the number of idle seconds before automatically updating Customize, use command `customize-set-auto-update-timer-period'. To *not* have `customize-unsaved' check for unsaved preference changes when you quit Emacs, add this also: (remove-hook 'kill-emacs-query-functions 'customize-unsaved) Options (variables) defined here: `customp-buffer-create-hook', `custom-buffer-verbose-help' (Emacs 20, 21 only), `customize-unsaved-confirm-exits-flag', `customize-unsaved-ignore'. Commands defined here: `Custom-consider-unchanged', `Custom-ignore-unsaved', `custom-mismatches', `customize-apropos-options-of-type', `customize-consider-all-faces-unchanged', `customize-consider-all-unchanged', `customize-consider-all-vars-unchanged', `customize-other-window', `customize-set-auto-update-timer-period', `customize-toggle-outside-change-updates', `customize-update-all', `customize-update-all-faces', `customize-update-all-vars'. Functions defined here: `cus-editp-remove-duplicates', `custom-consider-face-unchanged', `custom-consider-variable-unchanged', `custom-ignore-unsaved-preference', `custom-type', `custom-update-face', `custom-update-variable', `custom-value-satisfies-type-p', `custom-var-inherits-type-p', `custom-var-is-of-type-p', `custom-var-matches-type-p', `custom-var-val-satisfies-type-p'. Internal variables defined here: `custom-check-for-changes-interval', `custom-check-for-changes-when-idle-p', `custom-update-timer'. ***** NOTE: The following variables defined in `cus-edit.el' have been REDEFINED HERE: `custom-commands', `custom-face-menu', `Custom-mode-menu', `custom-variable-menu'. ***** NOTE: The following functions defined in `cus-edit.el' have been REDEFINED HERE: `custom-add-parent-links', `custom-buffer-create-internal', `customize-group-other-window', `customize-mode', `customize-unsaved'.