85

I see a lot of people (extension authors and others) give configuration examples with setq:

(setq foo 'bar)

These parameters are often defined with defcustom, making them available for customization through custom.el.

I typically use custom.el to set them. Would there be any advantage to using setq instead or are the two methods roughly equivalent?

4 Answers 4

110

Some people might think it is simpler to use setq. Some people might think it is more lispy. In reality, it is naive in the general case.

It is true that for some user options it does not matter. But for others, it does matter, and setq is the wrong approach for those options. So as a general rule, setq is the wrong approach.

If you use custom-set-variables or customize-set-variable instead of setq, or if you use the Customize user interface (e.g. M-x customize-option), then you are sure that any intended initialization or updating code that is needed for the option value will be automatically triggered and run as needed. If you use setq, this will not be done.

Now, it is also the case that most user options, especially many of them written for 3rd-party libraries, do not make use of the defcustom keywords :set and :initialize, and using setq does not matter for them. But lots of vanilla Emacs options do use such keywords, and for those that do, setq is not the right thing. So if you want to use Lisp code and not the Customize UI to set your options, then you are better off using custom-set-variables or customize-set-variable instead of setq. It never hurts and it sometimes helps (a lot).

But what I recommend is to do both of these things:

  • Use the Customize UI instead of writing Lisp code for this.

  • Define variable custom-file, so that Customize writes customizations to that file and not to your init file (~/.emacs). IOW, keep your hand-written initialization code separate from the automatic code written by Customize.

8
  • 8
    I think it's worth mentioning that even with the :set and :initialize parameters, setq still works if it gets read before the package is loaded.
    – Malabarba
    Sep 24, 2014 at 6:42
  • 2
    @Willyfrog You can upvote it! Sep 24, 2014 at 7:51
  • 25
    not sure about that Drew. The whole customize thing is rather complex. Without it, the emacs system is much simpler. The customize is a layer that doesn't exactly mesh well with elisp. For one thing, it order all vars by alphabets. Also, many customization are not about variables (e.g. hooks, keys) so can't use customize. So you have a situation of manual elisp code anyway.
    – Xah Lee
    Sep 25, 2014 at 13:06
  • 7
    @XahLee. Well, I'm sure. ;-) But yes, Customize is what it is. It is not the best thing for keys, hooks, font-lock keywords, display tables, etc. But for what it does do (options & faces), it does pretty well. Not that the UI is wonderful, but the handling of triggers, type-checking, etc. are helpful. I even wish programmers could (optionally) use things like :type with defvar - I don't think it should be limited to user options. Unfortunately, many programmers are lazy in their use of :type, and the result is not very helpful (that's not the fault of Customize).
    – Drew
    Sep 25, 2014 at 15:08
  • 5
    Data point: In my 3,300 lines of Emacs init code developed over the better part of a year, I've been bitten by using setq instead of customize-set-variable exactly once. (That one time was for auto-revert-interval, and I later realized that using setq before loading autorevert was actually much faster than using customize-set-variable.) Mar 26, 2017 at 22:50
48

I prefer setq over customize for several reasons:

  1. First and foremost, it allows variables to be set programatically (as in, (setq foo (calculate-foo))). I use this power all the time in my configuration to keep things DRY. For me, the whole point of using Emacs is programmability, and the customize interface does nothing but get in the way.
  2. setq lends itself better to version control and code organization. I split my initialization between dozens of files; if everything was in one huge custom.el file, it would be much harder to quickly find and edit settings.
  3. This is subjective, but to me the whole customize interface feels like a horrible relic from the worst UIs of the 90s. I'd prefer editing text with the power of Emacs any day.

@Drew makes some good points about some subtleties with :set and :initialize. I've been using Emacs for years and have rarely encountered problems like that. When I do, it's easy to swap out setq for custom-set-variable in specific cases.

1
  • 17
    1. You can set customize variables programatically with customize-set-variable(s), and it's better because of the triggers they run automatically. 2. You can use various customize commands to see all of your set and/or saved variables in different hierarchies, so you get the organization of different groups automatically without having to use separate files in version control. 3. It's gotten a lot better. If you don't like the UI, you can still use customize programatically and through the interactive commands that avoid the customize mode to gain all the other benefits of using customize. Dec 20, 2016 at 17:52
27

One advantage of using setq instead of customize is readability. One is free to annotate each customization to one's liking which IMO improves readability. One can also group related customizations together which improves modularity. Finally, I would argue that navigating through an elisp buffer is more "easy" then navigating customize UI and widgets.

On the other hand, customize lets you easily revert to default values which can be priceless when things go haywire.

EDIT: Drew's answer provides a great reason to use customize-set-variables which can provide all the advantages I pointed out. However, the Customize UI does not lend itself to portable configurations among different platforms as easily as raw elisp does. If you require a variable to have os dependent setting, you will have to fallback to elisp in many cases. My point about easier navigation in elisp buffers still stands.

5
  • 1
    You can also revert to the default value with setq, just comment out the setq line and restart emacs.
    – T. Verron
    Sep 24, 2014 at 5:40
  • 6
    Yes, but customize can revert back without pesky restarts. Highly useful for trying out new settings.
    – Vamsi
    Sep 24, 2014 at 5:44
  • 2
    Regarding annotation, the customize interface does allow you to add a comment to each variable you change. Dec 7, 2014 at 10:52
  • 3
    custom-set-variables is "raw elisp", and I use it every day on multiple machines. Just copy it out of the place where customize writes it (if you didn't write it yourself). Nov 13, 2018 at 21:50
  • 1
    The <kbd>M-x customize-*</kbd> interface has a "comment" field that allows storing a comment along with a variable.
    – kdb
    Oct 11, 2019 at 8:11
2

Another alternative is to use John Wiegley's use-package. This provides a programmatic way to configure packages that plays nicely with emacs 24+ package initialization process. Here is an example of use from the readme:

(use-package color-moccur
  :commands (isearch-moccur isearch-all)
  :bind (("M-s O" . moccur)
         :map isearch-mode-map
         ("M-o" . isearch-moccur)
         ("M-O" . isearch-moccur-all))
  :custom (isearch-lazy-highlight t)
  :config (use-package moccur-edit))

The point is that use package is a macro and does not evaluate its arguments immediately. The :init and :config parameters are evaluated at different stages of the initialization process, making it possible to have the configuration of each package in one place, but have each part execute at the appropriate stage of initialization.

Without something like use-package some packages require part of their initialization code to go before (package-initialize) and another part to go after. If you have many packegas like that then theire initializations would have to be interleaved.

Another benefit of use-package is that it can automatically install missing packages from using package.el if you take you .emacs to a new machine or if you share your configuration with another user and all initialization can be deferred until a package actually need to be loaded.

There are also additional keyword arguments that allow more control over the initialization process.

All that said, one big advantage of customize is that it shows you what there is to be configured in any given package. That is one reason I still use it for many of my packages.

3
  • 4
    That doesn't actually answer the question. In your very answer, you use setq with no explanation why. Mar 14, 2016 at 0:59
  • 3
    I think use-package itself offers advantages of modularised configuration, and also importing and configuring packages in one place. But yes, the example's using setq. Could it just as well have used customize-set-variable here? I'm not sure. Could/should we swap it (or customize-set-value) for setq?
    – mike
    Jul 3, 2016 at 10:48
  • 4
    Please change the example to make it use the :custom keyword.
    – Toon Claes
    Feb 20, 2019 at 5:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.