Customization buffers
Todays Emacs has a built in customization feature called
customization buffers.
Customization buffers allow you to set package settings in a user friendly
environment with information about the settings you are able to change.
Especially for people new to Emacs this is a very convinient way to
customize Emacs. All packages of the standard distribution of Emacs and
most of the additional packages have support for the customization buffers
build in, even if not all of their customization might be done this way.
cc-mode is an example for such a package. Although a lot of customizing can be
done via the buffer, there are things you have to put in your .emacs manually.
Setting up a personal style for indenting is one of these points.
Customize handles the information which is set through the use of the buffers
with the help of a set of special lists which begin with custom-set.
(custom-set-variables
'(kill-ring-max 70)
'(user-full-name "Ingo Koch"))
(custom-set-faces
'(font-lock-comment-face ((((class color)) (:foreground "red"))))
'(font-lock-string-face ((((class color)) (:foreground "green4"))))
'(font-lock-keyword-face ((((class color)) (:foreground "blue"))))
'(font-lock-type-face ((((class color)) (:foreground "blue"))))
'(font-lock-variable-name-face ((((class color)) (:foreground "brown"))))
'(font-lock-function-name-face ((((class color)) (:foreground "blue")))))
These lists are placed in your .emacs by default and are read on startup to
apply the appropriate changes to the packages.
This works great, so where is the problem ?
Problems that might occur
Dave Love and Kai Großjohan have told me not to encourage
people to copy and paste custom-set-... statements from the
dotfiles of other people into their own one.
"Emacs does, so why shouldn't I do the same" you might ask.
Well, here's the answer:
Anything might work if you do cut and paste, but it is possible to
do it a way so that it won't work as expected.
Kai Großjohan writes this about the problem:
Please do not advise people to copy and paste custom-set-variables
statements into their .emacs file. All too easily, this leads to them
having more than one custom-set-variables statement in their .emacs
file, and down that path lies madness.
People have asked where is the problem with having more than one
custom-set-variables statement in the .emacs file. Here's what
happens: suppose you have the following:
(custom-set-variables '(foo 42) '(bar 23))
(custom-set-variables '(foo 4711))
After starting Emacs, foo will have the value 4711, because both
statements are executed and the last one `wins'.
Then, suppose you type M-x customize-variable RET foo RET and change
the value of foo to, say, 1. Then, you select `save for future
sessions' and you end up with the following .emacs file:
(custom-set-variables '(foo 1) '(bar 23))
(custom-set-variables '(foo 4711))
Customize only changes the first custom-set-variables statement. Of
course, after starting Emacs, foo will have the value 4711. Imagine
the surprise of the user who things that Customize isn't working!
Imagine also that the user now uses Customize to set a new variable,
quux. This works fine:
(custom-set-variables '(foo 1) '(bar 23) '(quux t))
(custom-set-variables '(foo 4711))
.... since the second statement isn't overwriting the quux value from
the first statement. Imagine the even greater surprise of the user
who now thinks that Customize is working for some variables, but not
for others!
Lesson learned: never have more than one custom-set-variables
statement in your ~/.emacs file, for down that path lies madness!
Thanks to Kai for this explanation.
How to avoid these problems
First of all, custom-set is reserved for the use through the customize package.
The best way to avoid any trouble is to keep your hands off.
If you want to use customizations of other people which only are available
via a custom set statement, use the appropriate customization buffer for
setting it or think about translating it into a setq statement.
The second best way (if you know what you're doing) is to take a look at your
dotfile and locate the custom-set section. If you really want to do a cut and
paste, paste it there. Be sure that what you pasted is the only entry
for this variable.
Again: never have more than one custom-set-variables statement in your ~/.emacs file
There is a way to get the custom-set statements out of your .emacs into
a separate file:
(setq custom-file "~/.mycustom")
(load custom-file)
This will use a file named .mycustom in your home directory for all
the custom-set entries. The file has to be there already, even if it
is empty, because otherwise Emacs will complain about not beeing able
to open it.
If you already have custom-set-... statements in your .emacs, you
must remove them, because custom won't do that for you.
Simply cut them out and paste them as the base into the separate custom file.
If you don't remove them, the problems still might occur.
Separating the custom-set statements doesn't solve the problem of
custom reading all, writing to the first and evaluating the last entry
for a variable.
The drawback of this is, that it might scramble up your well organized
.emacs file :)
I like to group all settings concerning a particular package together
in one section. Doing anything concerning the setup of a package via
customization buffers throws these settings out of my .emacs and into
.mycustom. This way I have to take a look at two places and I'm not
sure about who is winning the race if I do different customization via
customization buffers and setq statements.
To be checked and continued ...
custom and setq statements
Having checked this, I now know who will win the race, but this
will make the things even more complicated.
The same thing as for two ore more custom-set-variable statements
applies to the combination of custom-set and setq.
But there is an important difference !
Although custom evaluates the second entry for a variable, it writes
this value to the first custom-set-variables statement if you change
something else.
This way, you've got a chance to see that there might be more than
one statement modifying the variable.
This doesn't happen for setq statements. What happens is:
Supose you have the custom-set-variables statement at the top
of your .emacs and all the setq statements following it.
- Custom loads the custom-set-variables statement. It sets
all variables within this statement to the required values.
- Emacs reads the rest of the .emacs, applying all setq statements
to the variables, thus overwriting the changes done by custom.
- You open the customization buffer for this variable. Custom
tells you that this var was changed outside the buffer.
Ok, you think, I'd like have an other value.
- You change it and save the changes for future
sessions. The change you've made is recorded in the
custom-set-variables statements. The var which is set via
the setq statement is included. Works as expected.
- Next time you start Emacs the var has still the value which
was set via the setq statement. Where is the customization ?
Supose you have the custom-set-variables statement at the end
of your .emacs.
- Emacs reads your .emacs, applying all setq statements
to the variables.
- Custom loads the custom-set-variables statement. It sets
all variables within this statement to the required values.
This overwrites all your setq statements for the variables set
via custom-set-variables.
- You open the customization buffer for this variable. Custom
shows you the customization via the customset-variables
statement.
- Well, you think, I'd like to have an other value.
You change it and save the changes for future
sessions. The change you've made is recorded in the
custom-set-variables statements.
- All works fine. Some day you decide to change this var again.
You do a search for that var to set it in your .emacs.
You get the setq statement and change it.
- Next time you start Emacs the var has still the value which
was set via custom. Where is the setq statement ?
These examples are some kind of constructed, but they show what might
happen.
My advise to avoid all these problems is:
Be sure that you know what you do.
If you ever cut out and paste a piece of code from an other .emacs file
or even write something on your own, be aware of might happen if
you customize a variable twice. It doesn't matter if you use multiple
custom-set or setq statements for one variable or combinations of these,
the results always might be odd.
If you include parts of other .emacs files, check out wether anything
which is set there may influence your current setup.
You're left alone with mixing custom and setq.
The good news
The behaviour of custom due to more than one custom-set-...
statement will be changed in Emacs 21.xx.
I've been told that
> Multiple calls to custom-set-variables should work in Emacs 21;
> if you customize, all the variables go into the first one,
> and the rest are deleted.
|