4

When I install a new package, more often than not there are variables that I can set - to customise the package. I love customisations, which is why I use Emacs in the first place.

For example, I installed the osx-dictionary package. In the sample configuration, there is a setq statement:

(setq osx-dictionary-dictionary-choice "Apple")

Everyone recognises expresions such as these. This one uses the Apple dictionary as standard for all dictionary queries.

I would like to change some settings for that package, e.g. to use more than one dictionary for the output. I could try a hack, entering a list of dictionaries in the place of "Apple". However, I am hoping that there is maybe a better way (than me extremely inefficiently fumbling around with Lisp code), which finds the variable required within said package to do what I want.

When I use C-h f and begin to type: osx-dictio, to display possible completions, I get the following list:

Possible completions are:
osx-dictionary--get-buffer             osx-dictionary--goto-dictionary
osx-dictionary--list-dictionaries      osx-dictionary--region-or-word
osx-dictionary--search                 osx-dictionary--view-result
osx-dictionary-cli-find-or-recompile   osx-dictionary-mode
osx-dictionary-open-dictionary.app     osx-dictionary-quit
osx-dictionary-read-word               osx-dictionary-recompile
osx-dictionary-search-input            osx-dictionary-search-pointer

that is two per line, 7 lines, so 14 possibilities. These are not mentioned in the package description. If anyone can explain the major differences between those with - and those with -- it might help me. But that is not my point.

Is there a way to find definable variables within any given packages, so as to know how one can customise that package WITHOUT having to go and read through all the actual code? [That is namely a massive task for some packages... I don't want to know how the package works, I just want to install it, optimise it for my needs and get on with my life!]

These customisations are the ones I would like to store in my .emacs file. therefore, the descriptions of what it does and what the possible input values are, e.g. boolean or otherwise, would also be great to have.

I apologise if there is an easy answer that I have overlooked, but after searching around for too long, I have drawn a blank. If this is the case, I shall accept the downvote and delete my question in embarrassment, post-haste!

Drew
  • 75,699
  • 9
  • 109
  • 225
n1k31t4
  • 669
  • 8
  • 18
  • 2
    The variables of `packagename--` format are for the package-internal use only and not intended to be modified directly by the user. – Kaushal Modi Oct 14 '15 at 20:45
  • Is the answer maybe that some packages simply lack thorough documentation, and that reading through the code is necessary? I do understand this is open-source, so one cannot assume to have his hand held for everything - I am very grateful that people make there code free to the community! – n1k31t4 Oct 14 '15 at 20:46
  • 4
    The library you are using as an example defines the customization group as `osx-dictionary`. If you use the `M-x customize-group` interface, you can see everything the author has intended that the user be able to customize. There are three (3) items in this example. You can also simply type `M-x customize` and surf through the various groups. – lawlist Oct 14 '15 at 20:49
  • Excellent - thank you. Would you recommend deleting the question (yes, I am embarrassed), or maybe just rewording and shortening it to make it more straight-forward for the next newbie? – n1k31t4 Oct 14 '15 at 20:52
  • Consider searching this forum for `customize-group` and if you find an answer on point, then you can delete the question. If you don't find an answer directly on point, consider writing up a thesis/answer on how to determine the name of a particular group available for customization based upon an installed library, so it is not necessary to surf through the various groups or open the source code to figure it out. I don't actually know the answer and found it by searching for the `defcustom` in the source code and then saw which `:group` was assigned. A `:group` *could* be the library name. – lawlist Oct 14 '15 at 20:54
  • According to [Ergoemacs](http://ergoemacs.org/emacs/emacs_custom_system.html) these 'custom' menus do not show all possible customisations! – n1k31t4 Oct 14 '15 at 21:08
  • @DexterMorgan Yes, the Customize buffers will not show **all** the variables. They will show only the variables the package author thought will be useful for the user to customize. Such variables are declared using the `defcustom` form instead of `defvar` or `defconst`. – Kaushal Modi Oct 14 '15 at 21:22
  • I haven't found anything on Emacs SE from my point of view, i.e. a user looking to find the variables, as opposed to someone who is creating a package (which are of course goes into too much detail). If either of you want to write an answer, I will accept it. Otherwise I will write one sometime soon and accept that. – n1k31t4 Oct 14 '15 at 21:27
  • 1
    @DexterMorgan `osx-dictionary-dictionary-choice` now supports a list of dictionaries, such as `(setq osx-dictionary-dictionary-choice '("Simplified Chinese" "Apple"))`. (I have just implemented this). – xuchunyang Oct 15 '15 at 06:59

2 Answers2

8

For best results and to avoid gotchas, do not use setq to set option values. Get in the habit of doing one of the following instead:

  • Use M-x customize OPTION, where OPTION is the option name. Change the value and save your change.
  • Use custom-set-variables or customize-set-variable in your custom-file (preferably) or in your init file (not as good, because it lets Customize mix the code it manages with your hand-coded code).
  • If the option is the customizable variable for a minor mode, then call the minor-mode command to set it. For example, turn off global minor mode line-number-mode not be setting variable line-number-mode directly but with this: (line-number-mode 0). (See the Elisp manual, node Init Syntax.)

setq does not carry out any special initialization or update operations that might be necessary for the option. Customize and its functions do that -- the necessary initialization and updating are triggered automatically whenever you set the value using Customize.

In addition, setq does no type-checking -- it ignores :type as well as :set, :initialize, and all the rest of a defcustom definition -- except for the variable value and doc string.

The lack of type-checking is in fact the most common way for users to shoot themselves in the foot by using setq, because the use of :set and :initialize (and other keywords) in defcustoms is not so common. It is fairly common for a user to write an Emacs help question asking what went wrong, where the answer is that s?he used setq and assigned a value of a type that does not respect the type specified by the defcustom. Not the end of the world, but it can be quite puzzling when you pay no attention to what user options are all about. They are not just defvars.


To see all loaded user options (or all that match an input pattern):

  • You can use customize-apropos to customize them.

  • You can use M-x set-variable TAB to see them. And you can use it to set any of them, but like setq, bypassing update triggers.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • 2
    I am guilty of setting all variables using `setq` in my init. But I haven't faced any problem with that. Can you please give an example where the variable needs special initialization? – Kaushal Modi Oct 15 '15 at 01:45
  • @kaushalmodi: It's not about guilt. As I said, a `defcustom` can use **`:set`** or **`:initialize`**, which can specify alternative or additional code to be run when the option value is set or initialized. Such *special setter functions* are not triggered, and so not used, when you use `setq`. If a given `defcustom` does not use these things then it is mostly a matter of style whether you use `setq` or Customize. (However, even in that case, if you or some code tries to interact with Customize's view of the value, you or that code might well get confused.) – Drew Oct 15 '15 at 01:50
  • 2
    Related: [Advantages of setting variables with setq instead of custom.el?](http://emacs.stackexchange.com/q/102/115) – Kaushal Modi Oct 15 '15 at 04:12
  • 2
    Downvoted by me because of strong emphasis on "Do not use setq to set option values." which is not true for people not using Customize interface. I have 5k code lines in my init.el with 500 lines containing setq. No errors. I enjoy Emacs daily. You can respond with "Yeah, well, that's just, like, your opinion, man.". Time for hard data: search limited to .init.el* and *.emacs* files https://github.com/search?p=1&q=language%3A%22Emacs+Lisp%22+filename%3A.init.el+filename%3A.emacs+setq+in%3Afile&ref=searchresults&type=Code&utf8=%E2%9C%93e gives 50k lines with `setq`. – kmicu Oct 15 '15 at 19:55
  • Additionally there is almost **100** repositories (each with over 100 stars) using `setq` in their README files: https://github.com/search?utf8=%E2%9C%93&q=stars%3A%3E%3D100+filename%3Areadme+language%3A%22Emacs+Lisp%22+setq+in%3Areadme&type=Repositories&ref=searchresults at the same time there is **9** repos with `custom-set-variables` in README https://github.com/search?utf8=%E2%9C%93&q=stars%3A%3E%3D100+filename%3Areadme+language%3A%22Emacs+Lisp%22+%22custom-set-variables%22+in%3Areadme&type=Repositories&ref=searchresults – kmicu Oct 15 '15 at 20:05
  • 3
    @kmicu: Yes, it is true also for people not using Customize interface. Read what I wrote. Use `customize-set-variable` or `custom-set-variables`, neither of which requires you to use the Customize interface. Both of those respect setter and initializer triggers that were defined by the `defcustom`. And they perform type-checking against the allowable types specified by the `defcustom`. **`setq` knows nothing about `defcustom`** -- it treats user options the same as any other global variables (it treats `defcustom` the same as `defvar`). – Drew Oct 15 '15 at 21:32
  • The fact that there are many people who do not understand `defcustom` and use `setq` means nothing. It is also the case that most `defcustom`s do not use `:set` or `:initialize`, and many of them have poor `:type` specs. *So what?* That does not mean it is smart to do so. You gain nothing by using `setq` here, and you can lose a lot. Believe me, I too used `setq` for many years for this (perhaps more than you have been using Emacs). – Drew Oct 15 '15 at 21:36
  • 1
    @kmicu: And *of course* you will find plenty of `setq` occurrences in README and init files. You will find them in my own init file! Not all `setq` occurrences involve *user options*. And yes, even for many user options, if the value assigned is of the proper type then using `setq` or `set` can be benign. The point is that it is not a good idea to blindly use `setq` for user options. Sooner or later, doing so will bite you. It is better to get in the habit of using `custom-set-variables` or `customize-set-variable`. That's all. Now do as you like... – Drew Oct 15 '15 at 21:47
  • @Drew thank you for your explanations, but I want to clarify: I wanted to show that 1. popular packages 'recommend' `setq` in README files. A lot of those packages were created by excellent elisp hackers (appeal to authority is not the point here) and if they use `setq` then I guess they do not use Customize facilities at all (especially `:set` & `:initialize`) or `setq` is not harmful in general. 2. `setq` is common in *.init* and *.emacs* files and Emacs still works for users. Taking into account above **Do not use setq to set option values.** is oversimplification. Emphasis is unnecessary. – kmicu Oct 16 '15 at 20:21
  • It would be better to follow GNU Emacs' manual *"Although you can use defvar or setq for variables that users set, the defcustom macro is designed for the job."* but if manual is wrong then we should change from *'Although you can'* to *'Do not'*. Another thing *"The custom-set-variables function works somewhat differently than a setq. **While I have never learned the differences**"*. Another thing `(setq colon-double-space t)` in 16.4 Text and Auto Fill Mode chapter. Next manual page and another `setq` used for user option and so on. – kmicu Oct 16 '15 at 20:47
  • @Drew is your .emacs init file available somewhere? I would like to implement your advice, even if Emacs manual does not follow it, but it is hard for me (and probably for others) to find online any examples of an idiomatic init file. (I also upvoted your answer now, because the latest version provides more details.) – kmicu Oct 16 '15 at 20:53
  • Not really. And I'm sure what I use is not idiomatic. My point was that `setq` has limitations when it comes to `defcustom` and so can result in "gotchas". For ordinary `defvar` there are no such gotchas – Drew Oct 16 '15 at 21:10
  • @kmicu: Where do you see any of the text you quote in either the Emacs manual or the Elisp manual (or the Emacs FAQ or the Emacs W32 FAQ? I don't see any of what you quote. At any rate, my answer says what *I* recommend. The Emacs manual does not even recommend using a separate `custom-file`. I do. – Drew Oct 16 '15 at 21:20
  • @Drew Almost all quotes are from https://www.gnu.org/software/emacs/manual/html_node/eintr/Emacs-Initialization.html#Emacs-Initialization and if you search for `(setq ` on https://www.gnu.org/software/emacs/manual/html_mono/emacs.html (warning the whole manual on one page) then you will find many examples of setting user options (defined via `defcustom`) with `setq`. Manual should reflect what is beneficial for the users if that is not the case it is a bug which should be fixed. – kmicu Oct 16 '15 at 22:08
  • @kmicu: OK, so you quoted from the intro-to-Elisp-programming manual, which is trying to teach Elisp - and not from the Emacs manual (or the Elisp manual). And the author of that introductory Lisp-teaching manual admits in it, as you quoted, that he "*never learned the differences*" between `setq` and `custom-set-variables`. Not much of a reference about the difference. It's a fine pedagogical intro to Elisp. It is apparently not a reference wrt Customize or your init file. – Drew Oct 16 '15 at 23:42
  • 1
    @kmicu: Yes, [IMO it is a bug](http://debbugs.gnu.org/cgi/bugreport.cgi?bug=21695) that the Emacs manual still has many examples of setting user options with `setq`. Not that it is wrong to use `setq` to set a user option, but it is asking for trouble to do so systematically or blindly. And IMO it is wrong for the Emacs manual to set a bad example by overusing `setq` to set options. It sends the wrong message (IMHO). – Drew Oct 16 '15 at 23:46
  • This post was very helpful and helped my config load faster for some reason. I used Mx Customize-groupe custom-file and read the information provided there that is manually creating the custom-file. – Asme Just Feb 18 '19 at 03:31
4

If you want the exact analogue of C-hf, that would be C-hv (being the command describe-variable as opposed to describe-function).

n.b. Type C-hC-h to see all of the C-h bindings (there are a lot, and many of them won't seem useful now, but you should remind yourself what's there every now and again -- some of the "not useful" things may seem rather more useful with the benefit of experience...)


In addition:

  • M-x apropos-user-option describes all user options matching a given pattern.
  • M-x apropos-variable does likewise for all variables (whether or not they are user options).

The difference between a user option and other variables is whether they are defined with defcustom or just defvar. Obviously the two have distinct intended purposes, but it's not necessarily the case that the variables you may wish to configure will all be defined as user options.

n.b. Type C-ha apropos RET to see what other kinds of apropos commands you can use to ask Emacs to tell you useful things. (C-h a being the default binding for apropos-command itself).


To access the customize interface for a given library, you typically1 use M-x customize-group RET LIBRARY RET for the LIBRARY in question. That should give you access to all of the user options of that library.

1 Some libraries may divide their user options amongst various different customize groups -- it's really up to the library in question -- but if the library uses sensible (searchable) names for its variables then, between all the methods shown here, you should find everything on offer.


Note that in all cases above, the results are only for currently-loaded (or perhaps auto-loaded) libraries; so make sure that the features you wish to customize are already loaded before you start asking Emacs about the available options.


And last (but definitely not least), in the manual see:

  • C-hig (emacs) Easy Customization RET
  • C-hig (emacs) Variables RET
phils
  • 48,657
  • 3
  • 76
  • 115