90

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?

Drew
  • 77,472
  • 10
  • 114
  • 243
J David Smith
  • 2,675
  • 1
  • 18
  • 27

5 Answers5

116

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.

Drew
  • 77,472
  • 10
  • 114
  • 243
  • 1
    This answer is great and I think is really really useful for beginners, is there a way to promote this kind of question/answers? – Willyfrog Sep 24 '14 at 05:47
  • 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 '14 at 06:42
  • 2
    @Willyfrog You can upvote it! – Zane Shelby Sep 24 '14 at 07: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 '14 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 '14 at 15:08
  • 6
    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.) – Resigned June 2023 Mar 26 '17 at 22:50
  • 1
    Good answer! Caveat: If you occasionally use Emacs versions from the stone age, like I have to, customize-set-variable was introduced in 21.1. My init file works against 19 with very sparing conditional code. That and the fact that you can set multiple variables at once with setq is why I tend to prefer that mechanism. – cyberbisson Nov 16 '22 at 22:31
  • 1
    @cyberbisson: customize-set-variable (and the other Customize functions) work in Emacs 20 (which I still use, in addition to later versions). I don't have Emacs 19, so I can't speak to that... – Drew Nov 17 '22 at 02:15
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.

shosti
  • 5,058
  • 27
  • 33
  • 17
  • You can set customize variables programatically with customize-set-variable(s), and it's better because of the triggers they run automatically.
  • 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.
  • 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.
  • – Nick McCurdy Dec 20 '16 at 17:52