< '''Update:''' After some more excavation, I discovered that Customize stores ''saved'' values (for future sessions) in the propery ##saved-value##. The line above checks if Customize has changed the value during the current session, while the function below also returns non-##nil## when the variable is Customize'd in ##.emacs##. -- VegardOye
> '''Update:''' After some more excavation, I discovered that Customize stores ''saved'' values (for future sessions) in the property ##saved-value##. The line above checks if Customize has changed the value during the current session, while the function below also returns non-##nil## when the variable is Customize'd in ##.emacs##. -- VegardOye
This page is about customizing Emacs using the so-called “Easy Customize” feature (aka Customize), and saving your changes. It is not about using Customize generally, however – it is specifically about the relation between making changes to preferences and saving them.
The first thing to recognize is that not every Emacs setting is a savable preference. You can save user options and faces.
So, what’s a face? See Face.
So, what’s a user option? It’s a variable whose DocString begins with
‘*’. That’s an odd definition, but that’s what a user option is. The Lisp predicate that describes this class of beasts is
‘user-variable-p’. Other ways to characterize a user option are as something that you can see using
‘list-options’ and something that you can change using
‘set-variable’. In general, a user option is a variable that is intended to be changed by users – you – as opposed to an internal variable that is modified by program only.
There has been some discussion lately on the bug list (emacs-pretest-bug) about what term to use for what I’ve called here “preference”. I think that the decision will be to change the term “user option” to mean that (a preference, whether variable or face), and to use only “user variable” for a variable that is
‘user-variable-p’. Until that change is made (in the UI and the doc), I’ll leave “preference” as the term here, to avoid confusion. – DrewAdams [new]
Actually, if you use Customize to save preferences, then not all user options can be saved. You can only use Customize to save those things (user options and faces) that you can change within the Customize user interface (UI). In other words, Customize handles a subset of user options, and user options are a subset of all variables. While
‘user-variable-p’ corresponds to
‘custom-variable-p’ corresponds to
‘customize-variable’. The latter two functions test whether you can use Customize with a given variable and set such a variable, respectively.
You can always save any preferences by inserting appropriate Lisp code in your init file (
.emacs). But this page is concerned with preferences that you save using Customize.
A very useful command, which is not bound to any key sequence, by default, is
‘customize-unsaved’. This command opens a Customize buffer with all of the preferences that you have changed in the current session but not yet saved. You can then look over the changes and save individual preferences.
Another useful command (also not bound, by default) is
‘customize-save-customized’ – it saves all of the changes you have made in the current session.
However, it is important to realize that both of these commands work only with the set of changes that Customize recognizes, and not every preference change is recognized by Customize. This is an important gotcha!! – see next.
Changes you make outside Customize are not always taken into account by Customize. Usually Customize will recognize that a change has been made, but it normally does not consider such an outside change as equivalent to the corresponding change within Customize. This is unfortunate: Emacs behaves correctly according to changes that you have made, but Customize does not recognize the change.
For example: If you set the value of a user variable using
‘setq’ instead of changing it using the Customize UI, then Customize will declare that the value has changed outside Customize and that it is not considered set for the current session. This is a strange status: the variable has in fact had its value changed for the current session, but Customize does not want to recognize that. Go figure…
So, why is this important? Not only because it can help you understand why Customize doesn’t seem to recognize changes you have made using things like
‘set-variable’ (well, maybe “understand why” is too strong here; let’s say “recognize that”). More importantly, you need to be aware of this if you write Lisp code that others will use. If you create, for example, a command that lets users change the color of a face, then you need to know that such a change will generally not be reflected in the Customize UI – so, users will not be able to save such a change using Customize.
This is the key question for this page. And finding the answer is not as simple as you might expect. The Lisp code that implements Customize is, well, not the easiest code to understand. So, without further suspense, and at no expense to you, here are the secrets discovered from untold diggings among the ruins of Customize code:
(put variable 'customized-value (list (custom-quote (eval variable))))
‘variable’ is a symbol that names a variable.
That’s it! That’s all you have to add to your Lisp code that sets user option
‘variable’, in order to tell Customize that it has been set to its current value,
(eval variable). You can do this interactively using command
‘tell-customize-var-has-changed’, which is defined in library Lisp:frame-cmds.el using the one-liner shown here.
To tell Customize that the definition of a face has changed (e.g. different foreground color), just add this to your Lisp code that changes a face:
(put face 'customized-face spec) (face-spec-set face spec)
‘face’ is a face and
‘spec’ is its new definition (face specification). This code is available as function
‘doremi-face-set’ in library Lisp:doremi-frm.el.
How Can I Get Customize to Recognize a Changed Preference? explains how to set a value that Customize will recognize. How do I do the opposite, namely making my own code recognize that Customize (the user) has set a value for a certain variable? – VegardOye
What you’re looking for is this, I believe:
(or (get symbol 'customized-value) (get symbol 'customized-face))
That is useful. Thanks. Why Customize doesn’t ship with ready-made functions for these things is beyond me. I may put the phrase “secrets discovered from untold diggings among the ruins of Customize code” in a code comment. – VegardOye
Update: After some more excavation, I discovered that Customize stores saved values (for future sessions) in the property
saved-value. The line above checks if Customize has changed the value during the current session, while the function below also returns non-
nil when the variable is Customize’d in
.emacs. – VegardOye
(defun custom-value-p (symbol) "Non-nil if SYMBOL has a customized value." (or (get symbol 'customized-value) (get symbol 'customized-face) (get symbol 'saved-value)))
Each Emacs Frame has a set of frame parameters, or properties, that define its behavior and appearance. These parameters are not variables, and they are not faces (though a few of the parameters correspond to standard faces). Each frame has its own set of parameter values, so if you change, say, the
‘background-color’ parameter value of one frame it does not usually affect the value of that parameter for another frame.
You can change various parameter values for a given frame in different ways. See, for instance, the commands in library Lisp:doremi-frm.el. But, suppose that you change a frame so that, for instance, it has the right color background, and you would like to use that color for all of your frames in the future. What do you do?
First, since a frame parameter is neither a variable nor a face, it is not a Customize preference. So, it would appear that you cannot save such a property for future use.
However, there are two things that come to your rescue here:
‘default-frame-alist’, which defines the properties of most new frames that you create.
So, you can use frame-alist variables to save frame parameters for future sessions. But how can you copy frame parameter values from a given frame that you like to a frame-alist variable like
‘default-frame-alist’? There are two commands defined in library Lisp:frame-cmds.el that help here:
‘set-frame-alist-parameter-from-frame’– Copies the value of a particular frame parameter from a given frame (the selected frame, by default) to a given frame-alist, such as
‘default-frame-alist’. If you use library Lisp:menu-bar+.el, then this is item Set Frame Parameter from Frame on the Frames menu.
‘set-all-frame-alist-parameters-from-frame’– Copies all of the frame-parameter values from a given frame to a given frame-alist. If you use library Lisp:menu-bar+.el, then this is item Set All Frame Parameters from Frame on the Frames menu.
Of course, a few frame parameters that it really doen’t make sense to copy. For example, the frame parameter
‘window-id’ is a unique frame ID used to communicate between Emacs and the window manager. You wouldn’t want to copy that to
‘default-frame-alist’ so that all new frames would get the same ID.
For that reason, there is a user option,
‘frame-parameters-to-exclude’, which is a list of frame parameters to not copy when using the
‘set-*-frame-alist-*’ commands. It is an option so that you can tweak which parameters are included and excluded from copying.
Example: Here’s a typical example of using these commands.
‘doremi-bg’to modify the background color of a frame (any frame): Let’s say that you change its red, green, and blue components, or you darken or brighten it (“value”).
‘set-frame-alist-parameter-from-frame’to copy the
‘background-color’parameter from the frame you changed to
‘default-frame-alist’in Customize (after using
‘customize-customized’to get to its Customize buffer).
(Each of the
‘set-*-frame-alist-*’ commands takes care of letting Customize know that the frame-alist user option has been changed.)
You might be wondering, “Why doesn’t Customize get along better with the rest of Emacs?” “Why doesn’t it pay attention to changes made outside it?” Don’t ask. But that might become a topic for discussion for the next (post 22.1) Emacs release. The time seems ripe for looking the question in the face.
The historical explanation might be that Customize grew up as a separate library, and it hasn’t yet completely taken hold or become significant enough to be more tightly integrated with the rest of Emacs. It is a lot more integrated now than it was a few releases ago, however, and as a result it has become more and more expected that it play well with Emacs.
Another explanation might be that an initial goal for Customize was to provide a way to customize Emacs that would not require users to be Lisp programmers. In that Customize has succeeded. As such, many Lispers who use Emacs have not bothered much with Customize (“real Emacs users don’t use Customize” seems to be their credo). The idea is that Customize doesn’t need to play well with Emacs because there are two separate Emacs user groups: the non-Lispers, who won’t change things outside Customize, and the Lispers, who won’t change things inside Customize.
But this split into two different kind of users is pretty artificial – things are not so black and white. In practice, Emacs has always been about looking under the hood – or at least being able to look under the hood if you’re curious or you just like to fiddle with the guts of a machine. Many Emacs users are just a little Lispian, and even newbies often like to learn some Lisp, even when they don’t have to.
So, some folks figure that it would be good if all changes to user options and faces were automatically recognized as new preference settings by Customize (recognized, but not saved, by default). The idea would be that you can change something anywhere and the change is taken into account elsewhere. See, for example, CustomizePlus.
What do you think? Are there good reasons for Customize not to recognize changes to user options by
‘setq’, and so on?
Of course, even if everyone were to agree on the desirability of a closer integration, there might be problems implementing it. Stay tuned…
Well, I have never seen this as a problem at all. My background is that I first started doing all customization the “hard-core” way, using setq and so on. I later discovered Customize and have since found it to be a neat way to browse the different settings, and changing them from there. Nowadays by .emacs file consists of a mix of the two ways to customize Emacs and I can see a trent towards using Customize more and more. I personally think that I would be confused if Customize DID save (or suggested me to save) settings I had done outside it (i.e. using setq). I don’t say that it is a bad idea though. – MathiasDahl
If you change preferences in your init file (
.emacs), then they are of course saved, by definition, so that is beside the point here. The point is that if you change user preferences outside of Customize – say by way of a command, such as
‘set-variable’, then Customize doesn’t recognize those changes as unsaved preference changes. That’s all. This is not about changes to things other than user preferences; and it is not about changes made in your init file – it is about changes to user preferences that are not recognized as such by Customize. It is precisely to further the “trend towards using Customize more and more” that it should be helped to play better with the rest of Emacs. – DrewAdams
Sorry to be misleading. I knew what you meant, and using “.emacs” in my text was a mistake. I understand that what you mean is things you might try out using set-variable, setq in scratch, M-: or just a C-x C-e. Still, I do not see the problem (again, even if I don’t think it is a bad idea to “fix” this) . – MathiasDahl
And not just things you might try out in those ways, but also, and in particular, things that are changed by commands intended to change things .
The Customize UI leaves something to be desired in terms of directly manipulating user preferences to change them. Libraries can improve the ways users interact to change preferences (e.g. commands like
‘doremi-face-fg’), and users can still use Customize to save such changes or reset to the installed settings – provided that Customize recognizes that such commands have in fact changed a setting.
The idea is to open up Customize, so that it sees changes that are made elsewhere – regardless of how they are made. You should be able to say “Show me what has changed” and then “Save these particular changes”. Library writers should be able to write commands that improve ways to change things, without suffering the restriction that users won’t be able to easily handle such changes from within Customize. – DrewAdams
I could not agree more, even though I did not think about it before (I’m repeating myself, I know, I know… . – MathiasDahl
After I wrote the text on this page a few days ago, I set about trying to come up with a better solution than requiring individual functions to inform Customize that they’ve set something. The result is library Lisp:cus-edit+.el. Here is the executive summary (from the source-code commentary):
‘set’(= unsaved) state, regardless of how they are set. Someday, Customize might be more integrated with the rest of Emacs, and “changed outside of 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. Simple.
There is a detailed explanation of what that library does in the source-code comments, so I won’t repeat that all here. Here are the highlights:
‘C-x C-c’) if you have unsaved customizations. It asks if you want to review them. If so, it opens a Customize buffer with all of your changes – variables and faces. This is analogous to Emacs asking you about files you’ve changed but not saved, before letting you exit.
‘kill-emacs-query-functions’hook – or, rather, it uses a new version of
‘customize-customized’that does the following:
‘customize-customized-ignore’. Typically, you list variables there that you modify frequently and don’t care about saving. Examples are
‘debug-on-error’– 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. (A prefix argument to
‘customize-customized’lets you override this ignoring.)
‘kill-emacs-query-functions’hook), it asks you for confirmation before proceeding.
‘customize-customized-ignore’. You can, for instance, add every preference in a Customize buffer to the ignore list with one click – just as you can save all changes in a Customize buffer with one click.
‘customize-update-all’(which does both of the first two) dig up all of the variables and faces that have been modified outside of Customize and tell Customize to consider them as having been modified inside Customize. IOW, they bring everything that is outside of Customize into the Customize fold. Using these commands, you can manually update Customize at any time, to synch Customize with the wider Emacs world. These updating commands are also available as buttons and menu items (Set from External Changes).
‘customize-update-all’can run as an idle timer, synching up Customize in idle moments, so you don’t need to do anything to make Customize behave as it should. You can then change anything anywhere in Emacs. When you exit, Emacs will inform you of all the changes and ask if you want to save them. You can modify how long the idle period needs to be before an update is done.
Interestingly, it turns out that even if you don’t change any preferences, when you quit Emacs the first time you try CustomizePlus (`
cus-edit+.el’), you are informed that there are lots of changed preferences. Those changes represent all of the user preferences that Emacs and various Emacs libraries have changed behind the back of Customize – even before you do 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 should not be any such apparent “changes”, since this is all part of standard Emacs (or libraries that you load), but that’s the way it is, for now. Someday, I hope, you’ll be able to live with Customize without CustomizePlus .
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 yourself). So, that’s one solution to this bother: just click Save to save all the phony customizations. Alternatively, you can click Ignore Unsaved Changes to ignore them all in the future; either way, this is only a one-time nuisance. And of course, you can save some and ignore other changes, individually.
There is a third way, in addition to saving and ignoring such “spurious” changes (that is, changes that you didn’t really make yourself, interactively): tell Customize to treat them as if they were saved, but not to save them – menu items/button Consider Unchanged. Unlike Save and Ignore, this has a non-persistent effect. It just resets the state for the preferences in question to “saved”, so that they are not considered changed, but if you change them later (in the same session) they are then treated as changed.
This is useful for dealing with user-preference changes that are done by libraries that you might load, including some standard libraries that don’t correctly tell Customize to consider the settings they make as “standard”. It can also be used for your own interactive changes that you might not want to save immediately, but that you want to treat as base-line values for a time.
However, unlike the case of “saved” and “standard” values, there is no way to reset to such a virtually saved value. It is designed for settings that are taken care of by program in a sure way – instead of such settings coming from your custom file, they come from a library. You don’t want to see such non-personal changes popping up each time you check for changes, but you also don’t usually want to save them to your custom file (which could even have a perverse effect if a library depends on a value not yet being set when it is loaded). Usually, when you load a library that messes with a user preference, you want to know that, but you then want to “reset” the status to unchanged (Consider Unchanged), so you can notice any further changes to it. Since loading the library again will (usually) reestablish the same user-preference values, there is no need to save them in your custom file (and that could have a perverse effect, as mentioned).
In the menus, Ignore Unsaved Changes is active only if there are such changes; Consider Unchanged is active only if the current preference values have not been saved; and Set from External Changes (manual updating) is active only if there actually are external changes to update to.
Customize is still fairly new, and lots of Emacs libraries still define and change user preferences without going through Customize – that’s the reason for a large set of behind-the-scenes changes. In fact, Customize does not at all make it easy for Lisp code to go through Customize to update variables and faces – you really have to know what you’re doing to get that done at all (see the rest of this page, above). Customize was designed, I guess, as an enclave apart (why, I don’t know).
Anyway, I hope that CustomizePlus will help people get more out of Customize, and, more importantly, encourage Lisp authors to come up with new ways to let users define and modify preferences. That’s the idea behind the direct manipulation of DoReMi, and CustomizePlus might open the door to other new ways to change settings. For now, try the idea out with DoReMi and CustomizePlus: incrementally change face colors and settings, and then use Customize to save your changes.