[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: defcustom: changing from defvar - order of execution

From: Drew Adams
Subject: RE: defcustom: changing from defvar - order of execution
Date: Fri, 6 May 2005 10:00:43 -0700

    > The user in setup #2 has never used the library, let's say
    (and so, does not
    > have the setq in .emacs). The user knows nothing about setq
    and Lisp; he
    > just copies the text "(load-library "foo")(foo-fn)", per the library
    > comments, to his .emacs. He fires up Emacs, and then uses
    Customize to set
    > and save foovar. This causes (custom-set-variables...) to be
    added to the
    > end of his .emacs - after the load-library and the call to foo-fn.

    > The user is then surprised to find that the customization had
    no effect: in
    > subsequent Emacs sessions, load-library does the defcustom, which sets
    > foovar to nil; and foo-fn then executes with foovar=nil,
    returning `t'.

    > What am I missing?

    That this situation you describe is just a bug in the elisp library.
    Most likely in the comment that suggests "(load-library "foo")(foo-fn)",
    but it's hard to say without more info.
    In any case the scenario you describe doesn't seem to be common.

Dunno if it's a bug, but it certainly does not seem that _uncommon_. In my
example scenario, the user puts "(load-library "foo")(foo-fn)" in his
.emacs, but the problem arises, in particular, when library foo itself calls
`foo-fn' (or otherwise references `foovar') at the _top level_. That may not
be good practice (?), but it is not uncommon, and I'm not sure what the
proper fix is.

I see things like this fairly commonly, at the top level of the standard
Emacs libraries:

  (defcustom align-load-hook nil
    "*Hook that gets run after the aligner has been loaded."
    :type 'hook
    :group 'align)

  (run-hooks 'align-load-hook)

That is, I see code that: 1) does a defcustom and then 2) uses the value of
that user variable at the _top level_ of the same library (not just inside a
defun). Loading the library uses the value of the variable defined in the
file (unless the variable is somehow set earlier).

In this case, it looks to me like `align-load-hook' will be nil when
`run-hooks' is evaluated, unless the user somehow sets `align-load-hook'
_before_ this library is loaded. Having custom-set-variables set the
variable at the end of the user's .emacs will be too late, if the user loads
this library before that.

Here's another example:

  (defcustom apropos-symbol-face 'bold
    "*Face for symbol name in Apropos output, or nil for none."
    :group 'apropos
    :type 'face)

  (define-button-type 'apropos-symbol
    'face apropos-symbol-face
    'help-echo "mouse-2, RET: Display more help on this symbol"
    'follow-link t
    'action #'apropos-symbol-button-display-help
    'skip t)

In this case, `apropos-symbol-face' will be `bold' when define-button-type
is run, unless the user somehow sets `apropos-symbol-face' _before_ this
library is loaded. (This code cannot just be an old throw-back, because
`define-button-type' is a new function.)

Here's another example:

  (defcustom mouse-avoidance-mode nil...)
  (if mouse-avoidance-mode
      (mouse-avoidance-mode mouse-avoidance-mode))

Here's another example:

  (defcustom calculator-use-menu t ...)
  (or calculator-mode-map
      (if (and calculator-use-menu ...

These examples are taken from just the first few standard Elisp libraries,
sorted alphabetically. I could go on, but you get the idea.

How is the user's customization (via Customize) taken into account in such
cases, if the custom-set-variables form is inserted at the _end_ of his
.emacs or custom-file? It looks to me like the _library_ (default) values of
such variables, not the user's customized values, will be used in the

To me, it makes sense to generally avoid using user options at the top level
of the library that defines them, but I'm not sure such avoidance is always
feasible. In any case, as the above examples show, the standard libraries
are themselves full of counter examples.

No doubt I'm still missing something - please help me understand. I want to
fix the "bug in the elisp library" in question, but I don't know how to
proceed. I want a user to be able to just load the library and go - not have
to execute foo-fn interactively, but I want the library to take the user's
customized value of foovar into account.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]