Confusing about the Emacs custom system
Asked Answered
S

5

52

There are several similar setting functions:

  1. set & setq
  2. set-default
  3. defcustom
  4. custom-set-value
  5. custom-set-variables
  6. customize-set-value
  7. customize-set-variable

so, what's the difference between these functions?

If I want setting my own preferences to an add-on, for these scenario:

  1. If a variable setting by defcustom, which setting-function will be better?
  2. And what about a variable setting by defvar?
Stowage answered 21/8, 2012 at 15:55 Comment(0)
K
67

The short answer to you question is:

  • use setq or setq-default for variables defined by defvar.

  • use setq, setq-default, or the Customize mechanism for variables defined by defcustom

Below is the long answer.

The functions that you are going to use are the following:

  • set is the main function to set the value of a variable.

  • setq is another version that automatically quotes its first argument. This is useful since quoting the first argument is what you want to do almost all the time.

  • Some variables cannot be set globally. Whenever you set the variable it is only set for the current buffer. If you want to simulate setting this variable globally you use set-default or setq-default.

The functions that a package writer uses are:

  • defvar which allows the package writer to define a variable and to give some documentation. This function is not required but makes the life of users easier.

  • defcustom builds on defvar. It tells emacs that it is a variable, and it allows the developer to create a custom interface to set the value. The developer can say, things like "this variable can contain only the value 'foo or 'bar".

Setting variables can be done two ways:

  1. if defvar was used, the values can only be set by the user in its .emacs by using the set function (or variants)

  2. if defcustom was used, the values can be set using set (see 1.) OR by using Customize. When using the customize mechanism, emacs will generate some code that it will place in custom-set-variables. The user should not use this function.

Kiersten answered 21/8, 2012 at 16:28 Comment(6)
If the package writer does not use defvar but only setq then you can only override the value after you load the package. However you should never use setq without defvar in your package if the user can change the value. If you use a package written properly, there is no difference between using setq or custom.Kiersten
This statement is not true. This is why I gave the explanation. You can setq anything you want anytime you want and it will not give an error. If defvar was used, then when the package is loaded emacs will realize a value was already set and will not take the default value given in defvar.Kiersten
The errors that you can see before loading a package are happening if you use the content of the package to set the value, for example by using a function provided by the package. If you only set values with "normal" values such as strings you do not run into problems.Kiersten
hmm, seems i was mistaken a bit about how that worked, thatnksNalor
Another error that bit me in the past was trying to add elements to a list. If the package defines a standard list and I want to add to that list I need to wait for the package to be loaded (with eval-after-load) to add to the list, or copy the whole list and add my elements (which is what custom does).Kiersten
Don't forget that a setq can assign to multiple variables, while set can only assign to one.Succinic
R
11

They are, largely all paths to the same thing. There are some important differences though. The best way to get to know them is to read the manuals for Emacs and Elisp (see C-h i). Off the top of the head though:

  • set is a "low-level" variable assignment
  • (setq foo bar) is shorthand for (set (quote foo) bar)
  • (set-default foo bar) means "unless there is a more explicitly scoped definition of foo in the current buffer, use the value bar", and applies to all buffers.
  • defcustom is used to mark a variable as one that the user is expected to be able to safely modify through the customize feature.
  • custom-set-value and customize-set-value are two names that point to the same function. They're convenience methods for working with the customize system.
  • custom-set-variables and customize-set-variables are used to make some set of customized-through-customize variables active, IIRC.

In general, it's recommended to use M-x customize to change things around. You're free to set things defined with defcustom using set or setq in your .emacs, the customize system will warn you about it if you later change it via customize though.

defcustom is generally only used by people writing packages meant for distribution, and I don't think I've seen anyone use custom-set-* outside of files internal to customize. setq is very common in people's initialization files for setting things up how they like them, regardless of whether those things are marked for use with customize or not.

I don't have a full understanding of all this, hopefully someone else can shed more light, but I think that that's a fairly good overview :P

Rabia answered 21/8, 2012 at 16:30 Comment(1)
same answer, same appreciation.Stowage
S
7
  1. set and setq are the lowest level primitives used for assigning any kind of variable.
  2. set-default and setq-default are emacs extensions that go along with buffer-local variables, to allow setting the default values used for new buffers. 3-7. All the "custom" stuff is a later addition that was designed to support a user interface for managing variables that are intended to be used as user preferences.
  3. defcustom is similar to defvar, but allows you to specify a place in the hierarchy of options, as well as data type information so that the UI can display the value as a menu, or automatically convert user input to the appropriate type.
  4. I don't think there is a custom-set-value function.
  5. custom-set-variables is used by the customize UI when saving all the user's options. It lists all the variables that the user has changed from their defaults. 6-7. custom-set-value and custom-set-variable are used by the Customize UI to prompt the user for the current and default values of an option variable, and assign them. You don't normally call this yourself.
Superpatriot answered 21/8, 2012 at 16:45 Comment(0)
C
4

Just as addition, the differences between those commands have increased due to the introduction of lexical binding, though those differences will not really be relevant if you just want to customize some variables.

The def... constructs declare global variables. The set... functions set variables, whether global or local. When x is neither a local variable (a formal parameter of the current function or declared by a let form or similiar) nor defined by a def... form and you write (setq x 0) the byte compiler will even show a warning

Warning: assignment to free variable `x'

Variables declared with defvar, defcustom, defconst are dynamically bound, i.e. when you have a construct

(let ((lisp-indent-offset 2))
  (pp (some-function)))

the function some-function will see the change of the global variable lisp-indent-offset.

When a variable is not dynamically bound, in something like

(let ((my-local-var 1))
  (some-function))

where my-local-var has no global value, then some-function will not see the assigned value, as it is lexically scoped.

On the other hand, dynamically scoped variables will not be captured into lexical closures.

More details can be seen in http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html

Clothes answered 27/6, 2013 at 12:50 Comment(1)
For clarity, unless lexical binding is explicitly enabled for a file, all variables will be dynamically bound, regardless of how they are defined and set.Karykaryl
A
2

A bit of a revision after 12 years of development in Emacs has gone.

To clarify about some differences between set, setq and other mentioned. Those functions are not equal and each function serves a purpose. They are often interchangeable, but not always!

The most important to remember:

  • set sets the value cell of special symbols (global values), even in lexical scope.
  • setq depending on the context can set the value cell of a global variable too, but if used in the lexical context it will set the value of the variable visible in the current lexical environment. If a variable is declared as a buffer-local variable, than it will always set buffer-local value of the variable.
  • setf Same as setq, but with additional powers

setf function not mentioned in answers above, is a "generalized" setq in newer Emacs versions. It should probably be your first and the only choice when setting non-Customize variables. In compiled code it will be just as efficient as setq but it has additional powers to "figure out" a place rather than just use the name of a variable.

To set Customize variables use either customize-set-variable or the newer, setopt function made especially for setting Customize variables and which functions a lot like setq. Setopt is added in Emacs 29, on a popular request. Read what the manual says about setting variables too, and check the setopt docs in your Emacs: C-h f setopt RET.

I would just like to add that in new Emacs, it is a bad advice to use setq as your first get-go for variables defined in Customize interface.

The reason is that a variable might have a specialized code defined in custom-set property that might not run to properly initialize the variable if you use setq to set it.

You can also see this answer by Drew and definitely check the elisp manual for Customize.

Unfortunately, I am new here and couldn't comment under the relevant advice, so I had to make this as an answer. I am also writing this ~12 years after the original answer, please don't see it as a critique to the previous answers. Some of those things didn't even exist back than! I mean it more as an addendum or errata due to changes in Emacs.

Arabele answered 12/6 at 12:30 Comment(2)
See also emacs.stackexchange.com/a/78424/454Karykaryl
Thanks phils, I haven't seen that one myself prior to writing this.Arabele

© 2022 - 2024 — McMap. All rights reserved.