- Change the variables for already existing code.
- Create new keybindings (or erase ones that were there already).
- Create new functions to add new interactive capabilities.
- Load new packages that alter the behavior of emacs, and call functions that setup the initial state of those packages.
There are two main ways to change variables: by using setq directly, or by using customize. Looking at my init file, my first line setting a variable directly is this:
;; This only gets set for real when cc mode is enabled (setq c-buffer-is-cc-mode nil)
This is an example of using
setq. If you are new to elisp, you may wonder why it is called
set. The answer is pretty simple:
setqstands for "set quoted", and there already is a
set. Here's the same thing with
(set 'c-buffer-is-cc-mode nil)
The difference here is we have to quote the variable we are setting,
c-buffer-if-cc-mode, whereas in
setqit is done for you. At any rate,
setqis more idiomatic in elisp, so let's use that.
The other main way to set variables in using customize. To set the same variable with customize, we can type
M-x customize-variableand then enter
c-buffer-is-cc-mode. However, if you try this, you'll see that
c-buffer-is-cc-modedoesn't work; it has no customization option. That's probably because it isn't intended to be customized, and indeed if you look at it, you'll see that it is buffer-local, which means that it isn't a global variable, it is one that has a potentially different meaning in every buffer. To such variables, there isn't much need for global customization.
As you can see, you can't customize everything. For many things, though, customization is pretty nice. You can also do
M-x customize-groupand then put the name of some package, such as
ido. You'll see a list of variables printed as phrases: the first letter capitalized and the dashes replaced with spaces. For example, the variable
ido-before-fallback-functionsis referred to as "Ido Before Fallback Functions". For variables with a freeform value, you can edit the value in a small textbox. For lists, you can insert an element at a time. For things that can be one of a few values, you get a selection widget. It's all very nice and easy to use. The documentation is also right there. After making a modification, you can save for the current emacs session, or permanently. Permanently saving puts the customization in your initialization file in a stanza that looks like:
(custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(ido-auto-merge-delay-time 1.5))
There is a choice to make for customizing options, then. Use plain-old
setq, or use the snazzy built-in customization? I think each has it's uses, but my current configuration isn't a good example of this. Let's fix it.
Generally, I think it's best to use customization for machine-specific things, and
setqfor everything else.
setqhas some nice advantages to it, but also a few drawbacks. The advantages are that you can group the
setqstatements with similar customization (for example, keybindings). Also, you can comment on the variable settings. This is very important. Looking at my setting of
c-buffer-is-cc-mode, my only comment is "This only gets set for real when cc mode is enabled". This comment sucks. Looking at this, I don't recall why I felt the need to set it, and this comment does not help at all. Ideally, I'd like to know what horrible fate will befall me if I fail to set this variable. I'm going to remove this from my config. When I figure out why I needed it, I should remember to leave a better comment. Maybe I'll never figure it out, which is fine, since my config will be just that much cleaner.
The drawbacks to
setqare that the UI for changing the settings is not nearly so nice as the built-in customize. That's about it.
A variable can be set with
setqbefore the variable is even defined, and the value set with
setqwill still take effect. For example:
(setq foo 10) (defvar foo 3 "An example variable") (princ foo)
It's also worth noting that you can have one
setqto set many variables, like so:
(setq foo 1 bar 2)
As I mentioned above, customization may be useful for per-machine settings, such as the location of binaries. This is because we can separate out the customization to another file. The docs to
custom-fileexplain this nicely, but the basic idea is that you setup another file to hold your customization. With things split into another file, you can add this file to your
.gitignore, and then just not check it in. There should be no need to.
To do this, first, copy any customizations we have into your new file. If you have an
~/.emacs.d/directory like I suggest, then
~/.emacs.d/custom.elis a reasonable choice.
(setq custom-file "~/.emacs.d/custom.el") (load custom-file t t)
Loading in this way will let the file not be there without throwing an error. That's fine, usually it shouldn't be there when running this config on a new machine.
Just in case you were wondering, customization does not act like
setq; it matters where you do it:
(custom-set-variables '(bar 10)) (defvar bar 3 "An example variable") (princ bar)
This is why customization always happens last.
You can actually change this behavior. And you can add comments.
(custom-set-variables '(baz 10 t nil "With the t argument, this will be evaluated explicitly")) (defvar baz 3 "An example variable") (princ baz)
There is one other interesting thing you can do with
custom-set-variables, which is to have the customization per-feature.
(custom-set-variables '(jabber-keepalive-interval 10 nil (jabber) "Only pertains to feature 'jabber"))
This will load up the feature in question, in this case
jabberwhen customizing. I'm not really sure why this is useful. If anyone knows, please tell me in the comments.
Customization has even more complexity. You can have customization themes that you can change between, or layer on top of each other. It's all very interesting, but to me it's best to just have the separate file, and store machine-specific settings there.
In summary, my suggestions for variable settings are:
setqfor each variable you want to set.
- Unless it is dead obvious, comment on why you are changing the variable.
- Keep all similar variables together.
- If the variable is something inherintly machine-specific, such as the location of a binary, then customize it, and put your customization in a different file that will not be shared between computers.
- Load customization last.
I plan on going through my configuration file and making these changes, and I encourage you to do the same.