Drew Adams wrote:
WRT the guideline of "loading must not change anything" - I agree, but I
think that turning on a minor mode is usually relatively benign, because it
can be turned off easily. Users loading a library that defines a minor mode
will not be shocked if the mode is turned on by default, if the logical
initial value to use is something other than nil.
Otherwise, if we're going to be rigid about this guideline (perhaps there
are good reasons to do that, even in this case),
Emacs is completely inconsistent in how well it follows these
guidelines.
The _default_ :initialize function is custom-initialize-reset. That
means that whenever a file containing a defcustom with a :set function
is loaded, that :set function is called _even_ if the user customized
the variable outside Custom, possibly in an attempt to avoid the :set
function. In vain. The `custom-initialize-reset' bully will force
the :set function on the user anyway. This has repeatedly caused me
(and other people) problems in practice. We have systematically dealt
with these problems on a one by one basis by overriding the default
with an explicit, more polite, :initialize function for those
defcustoms for which problems were reported. But additional problems
keep popping up on a regular basis (see the `fringe-indicators'
thread). The problems are often not that easy to trace down to
custom-initialize-reset, because they occur when a file is loaded and
for instance Custom loads tons of files behind the user's back. The
reason for picking `custom-initialize-reset' as the default are
autoloaded defcustoms with a :set function. But I believe that there
_must_ be other ways to deal with such defcustoms than the bullyish
custom-initialize-reset.
A second :initialize function is custom-initialize-set. That one only
calls the :set function if the variable is still unbound. This means
that, if nothing else, the user can avoid the :set function by setting
the variable outside Custom in his .emacs file. (For preloaded
defcustoms, the user can undo the effects of the :set function in his
.emacs file.) For non-preloaded defcustoms, even setting the variable
to its standard value avoids calling the :set function, which could be
useful, if you do not want the :set function to set a timer, hide some
text, make some text read-only or perform all kind of other
"courtesies" that :set functions like to do.
On the other hand, the only :set function considered safe for minor
modes is custom-initialize-default, which _never_ calls the :set
function on initialization. This is completely inconsistent as the
minor-mode :set functions are usually benign compared to some other
:set functions that are out there. (See `fringe-indicators' for a
really bad example of :set function abuse.) Actually, the standard
:set function of define-minor-mode is one of the few classes of
functions for which even custom-initialize-reset would be safe.
So on the one hand I have trouble convincing people that we should
try to get rid (after the release) of custom-initialize-reset by
finding another solution for the autoload problem and on the other
hand, I have trouble convincing Stefan that the _much_ more benign
custom-initialize-set can be safe for minor modes that are natural to
enable by default.
Sincerely,
Luc.