unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* doc on define-minor-mode hook variable(s)
@ 2006-03-05 19:40 Drew Adams
  2006-03-05 21:01 ` Stefan Monnier
  0 siblings, 1 reply; 11+ messages in thread
From: Drew Adams @ 2006-03-05 19:40 UTC (permalink / raw)


Does `define-minor-mode' define a hook variable? If so, at what point is it
run? These things are not documented clearly, IMO. There is only an oblique
reference to a hook variable.

The doc string of `define-minor-mode' says this:

 "body contains code that will be executed each time the mode is
(dis)activated.
 It will be executed after any toggling but before running the hook variable
 `mode-HOOK'."

(That should presumably be "MODE-hook", BTW, and "disactivate" should be
"deactivate".)

The Emacs-Lisp manual doc on `define-minor-mode' says this:

 "The command named MODE first performs the standard actions such as
 setting the variable named MODE and then executes the BODY forms,
 if any.  It finishes by running the mode hook variable `MODE-hook'."

That seems clear: there is a hook and it is run at the end of entering and
exiting the mode. What's not clear from this doc is whether
`define-minor-mode' creates a variable named `MODE-hook'.

I find no variable named `MODE-hook' in Emacs, where MODE is a minor mode
name. Apparently, what is meant is that *if* someone creates a hook variable
named `MODE-hook', then it will be run.

The code defining `define-minor-mode' does bind hook variables `MODE-hook',
`MODE-on-hook', and `MODE-off-hook'. A comment explains that `*-on-*' and
`*-off-*' are only for backward compatibility. The function created by the
macro runs these hooks not at its end, but before the minor-mode keymap is
defined and the minor mode is added to minor-mode-alist - but that's a
detail.

IIUC -

No global hook vars are defined by `define-minor-mode'. If such variables
happen to be defined, then their values are run as hooks. If this
understanding is correct, then I think it should be reflected in the doc.
The doc (string and manual) should say explicitly that:

 - no hook vars are created by `define-minor-mode'

 - if you create them, they should be named `MODE-hook', `MODE-on-hook', and
`MODE-off-hook' (or perhaps we should not mention the latter two?)

 - if defined, the hooks are run near the end of the minor-mode function,
just before the minor-mode map is defined

The doc for `define-minor-mode' could also remind people that it is
sufficient to use `(add-hook 'MODE-hook...)' to define such a hook.

Since such a hook is likely to be used by an end user (in .emacs), as well
as by a programmer, perhaps it should also be mentioned in the Emacs manual,
node Minor Modes or node Hooks. Node Hooks mentions major-mode hooks, but
not minor-mode hooks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-05 19:40 doc on define-minor-mode hook variable(s) Drew Adams
@ 2006-03-05 21:01 ` Stefan Monnier
  2006-03-05 21:14   ` Drew Adams
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2006-03-05 21:01 UTC (permalink / raw)
  Cc: Emacs-Devel

> exiting the mode. What's not clear from this doc is whether
> `define-minor-mode' creates a variable named `MODE-hook'.

Here is the explanation: a hook is not a *variable* but a *symbol*.
A hook has various elements, all of which happen to be currently stored in
the value part of the symbol (some in the buffer-local parts, others in the
global part).

So whether or not a variable is created is not really relevant: the symbol
is "created" and that's all that's needed.


        Stefan


PS: Yes, this means that the only way to figure out whether a hook exists or
not is by actually placing something on it and checking whether/when it
gets triggered.  That's how hooks have been defined.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: doc on define-minor-mode hook variable(s)
  2006-03-05 21:01 ` Stefan Monnier
@ 2006-03-05 21:14   ` Drew Adams
  2006-03-05 23:33     ` Stefan Monnier
  0 siblings, 1 reply; 11+ messages in thread
From: Drew Adams @ 2006-03-05 21:14 UTC (permalink / raw)


    > exiting the mode. What's not clear from this doc is whether
    > `define-minor-mode' creates a variable named `MODE-hook'.

    Here is the explanation: a hook is not a *variable* but a *symbol*.
    A hook has various elements, all of which happen to be
    currently stored in the value part of the symbol (some in the
    buffer-local parts, others in the global part).

    So whether or not a variable is created is not really relevant:
    the symbol is "created" and that's all that's needed.

    PS: Yes, this means that the only way to figure out whether a
    hook exists or not is by actually placing something on it and
    checking whether/when it gets triggered.  That's how hooks have
    been defined.

OK, thanks for the clarification.

I don't see how that substantially alters my point (or even most of what I
wrote): more should be said about the hook _symbol_ `MODE-hook' in the doc.
Users should be informed how they can take advantage of this feature.

My concern is not really whether or not these hooks exist. My concern is
that they are provided for by `define-minor-mode' but the behavior related
to them is not sufficiently documented. IOW, important functionality
provided by `define-minor-mode' is not revealed by the doc.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-05 21:14   ` Drew Adams
@ 2006-03-05 23:33     ` Stefan Monnier
  2006-03-06  0:40       ` Drew Adams
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2006-03-05 23:33 UTC (permalink / raw)
  Cc: Emacs-Devel

> OK, thanks for the clarification.

> I don't see how that substantially alters my point (or even most of what I
> wrote): more should be said about the hook _symbol_ `MODE-hook' in the doc.
> Users should be informed how they can take advantage of this feature.

The main point I saw was:

> > That seems clear: there is a hook and it is run at the end of entering
> > and exiting the mode.  What's not clear from this doc is whether
> > `define-minor-mode' creates a variable named `MODE-hook'.

And my explanation says that the part that's not clear is related to hooks
in general, not to define-minor-mode's hooks in particular.

> My concern is not really whether or not these hooks exist. My concern is
> that they are provided for by `define-minor-mode' but the behavior related
> to them is not sufficiently documented.  IOW, important functionality
> provided by `define-minor-mode' is not revealed by the doc.

Like what?

Other comment on your previous message:

> > The code defining `define-minor-mode' does bind hook variables
> > `MODE-hook', `MODE-on-hook', and `MODE-off-hook'.  A comment explains
> > that `*-on-*' and `*-off-*' are only for backward compatibility.
> > The function created by the macro runs these hooks not at its end, but
> > before the minor-mode keymap is defined and the minor mode is added to
> > minor-mode-alist - but that's a detail.

It is not true that those hooks are run "before the minor-mode keymap is
defined and the minor mode is added to minor-mode-alist".  Both of those
actions are done at the top-level when the minor-mode function is defined
rather than when it's called, so they should both happen before the hook
is run (even though they indeed appear afterwards in the code).

> >  - no hook vars are created by `define-minor-mode'

3 hooks are defined (the concept of a "hook var" should be avoided since
it's misleading). You can manipulate them with `add-hook' and `remove-hook'
like all other hooks and they are run with `run-hooks'.

> >  - if you create them, they should be named `MODE-hook', `MODE-on-hook',
> > and `MODE-off-hook' (or perhaps we should not mention the latter two?)

*You* don't create them.  They exist already.  And yes, mone-on-hook and
mode-off-hook should not be mentioned.

> >  - if defined, the hooks are run near the end of the minor-mode function,
> > just before the minor-mode map is defined

They're run just like major mode hooks: at the end of the minor mode function.

> > The doc for `define-minor-mode' could also remind people that it is
> > sufficient to use `(add-hook 'MODE-hook...)' to define such a hook.

add-hook modifies it: it doesn't define it.  And saying "it's sufficient to
use add-hook" is misleading: add-hook is the *only* way to manipulate
hooks.  `add-to-list' and `setq' are *wrong*.


        Stefan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: doc on define-minor-mode hook variable(s)
  2006-03-05 23:33     ` Stefan Monnier
@ 2006-03-06  0:40       ` Drew Adams
  2006-03-06  5:05         ` Stefan Monnier
  0 siblings, 1 reply; 11+ messages in thread
From: Drew Adams @ 2006-03-06  0:40 UTC (permalink / raw)


    > important functionality provided by `define-minor-mode' is not
    > revealed by the doc.

    Like what?

Looking at this with my new understanding (thank you) that there are no hook
variables involved, only symbols, I see now that this doc is not incomplete.
Since there are no hook variables involved, there is no need to mention that
the macro doesn't create them and that if you create them then their values
will be run.

The doc could perhaps elaborate a bit on `MODE-hook', however. It might help
to mention that 1) symbol `MODE-hook' is created (interned) by the macro; 2)
it is created as an empty hook; and 3) you can define it (oops - modify it)
using `add-hook'. But I understand that that's always true, so it doesn't
say much: one can always do (add-hook 'foo 'bar) whether or not `foo' was
previously interned. I'm not sure which added info might help.

I think the main thing is to clearly explain what you explained: how hooks
work. That is not specific to `define-minor-mode'. The place to explain it,
in both the Emacs-Lisp manual and the Emacs manual, is in node Hooks. In my
copy of the manuals (perhaps not up to date), what you explained is not
presented, AFAICS. The Elisp manual Hooks node starts like this: "A "hook"
is a variable...". The Emacs manual Hooks node starts by saying "A hook is a
Lisp variable...".

In the past, hook variables were used, and the new notion that a hook need
not be associated with a variable should be explained in the doc. It is not
enough to explain how hooks work now; it should explicitly be pointed out
(at least in AntiNews) that variables need no longer be involved (are no
longer involved).

BTW, the manual info on `define-minor-mode' should also be corrected to not
refer to "the mode hook _variable_ `MODE-hook'" (if that has not already
been done since the CVS snapshot I have).

This seems disturbing: "the only way to figure out whether a hook exists or
not is by actually placing something on it and checking whether/when it gets
triggered." If a variable holds a hook symbol's value, then one can use `C-h
v', which is a lot simpler for users.

IIUC, in Lisp you can use (symbol-value 'my-hook) to see whether or not
there are any candidates for removal by `remove-hook'. I'm avoiding saying
"to see whether or not the hook is defined", since you objected to that. You
used "hook exists", but that seems inaccurate also, since whether or not a
symbol exists has nothing to do with whether or not its symbol-value is a
list of functions usable as a hook. I'd be tempted to speak in terms of the
hook being empty or not. Whatever - just let us know what the correct
terminology is.

Should there be a command that lets a user know whether or not a hook is
empty - that is, a command that does simply (symbol-value 'the-hook)? Users
need to be able to determine this sometimes, and `C-h v' will no longer work
if there is no associated variable. I kept trying `C-h v' after reading the
`define-minor-mode' doc string, thinking that a variable (perhaps with value
nil) was defined.

    It is not true that those hooks are run "before the minor-mode keymap is
    defined and the minor mode is added to minor-mode-alist".

My bad; you're right.

Thanks for clarifying hooks for me. Now, unless it's already been done,
let's do the same for the manuals and doc strings.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-06  0:40       ` Drew Adams
@ 2006-03-06  5:05         ` Stefan Monnier
  2006-03-06 18:35           ` Richard Stallman
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2006-03-06  5:05 UTC (permalink / raw)
  Cc: Emacs-Devel

> I think the main thing is to clearly explain what you explained: how hooks
> work. That is not specific to `define-minor-mode'. The place to explain it,
> in both the Emacs-Lisp manual and the Emacs manual, is in node Hooks. In my
> copy of the manuals (perhaps not up to date), what you explained is not
> presented, AFAICS. The Elisp manual Hooks node starts like this: "A "hook"
> is a variable...". The Emacs manual Hooks node starts by saying "A hook is a
> Lisp variable...".

> In the past, hook variables were used, and the new notion that a hook need
> not be associated with a variable should be explained in the doc.

I'm not so sure.  After all, they *are* associated with a variable (whatever
that means).  I think the important thing is to insist on the fact that
hooks are some abstract concept and that you refer to them with symbols and
you manipulate them with add-hook and remove-hook.

But I don't intend to rewrite this part of the manual(s) and I'm sure some
other people will find my point of view unholy.

> You used "hook exists", but that seems inaccurate also, since whether or
> not a symbol exists has nothing to do with whether or not its symbol-value
> is a list of functions usable as a hook.

A hook exists if its symbol is passed to `run-hooks' or
something equivalent.

> I'd be tempted to speak in terms of the hook being empty or not.

Seems like a bad idea: it's rarely useful to know whether it's empty or not.

> Should there be a command that lets a user know whether or not a hook is
> empty - that is, a command that does simply (symbol-value 'the-hook)? Users
> need to be able to determine this sometimes,

Why would they need to know whether it's empty?
AFAIK they generally want to know whether it exists (the answer often lies
in docstrings, documentation, or when all else fails source-code).


        Stefan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-06  5:05         ` Stefan Monnier
@ 2006-03-06 18:35           ` Richard Stallman
  2006-03-06 19:09             ` Stefan Monnier
  2006-03-06 19:10             ` Drew Adams
  0 siblings, 2 replies; 11+ messages in thread
From: Richard Stallman @ 2006-03-06 18:35 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

    > In the past, hook variables were used, and the new notion that a hook need
    > not be associated with a variable should be explained in the doc.

A hook IS a variable--that is to say, a symbol whose value is used.
It is a mistake to think that a hook is not a variable.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-06 18:35           ` Richard Stallman
@ 2006-03-06 19:09             ` Stefan Monnier
  2006-03-08 21:06               ` Kevin Rodgers
  2006-03-06 19:10             ` Drew Adams
  1 sibling, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2006-03-06 19:09 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

>> In the past, hook variables were used, and the new notion that a hook need
>> not be associated with a variable should be explained in the doc.

> A hook IS a variable--that is to say, a symbol whose value is used.
> It is a mistake to think that a hook is not a variable.

Either way it's a mistake: when people think of a hook as a variable, they
think that (boundp 'foo-hook) can tell them whether the hook exists or not.

So I prefer to think that a hook is its own kind of object, which happens to
be implemented using a variable.


        Stefan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: doc on define-minor-mode hook variable(s)
  2006-03-06 18:35           ` Richard Stallman
  2006-03-06 19:09             ` Stefan Monnier
@ 2006-03-06 19:10             ` Drew Adams
  1 sibling, 0 replies; 11+ messages in thread
From: Drew Adams @ 2006-03-06 19:10 UTC (permalink / raw)


        > In the past, hook variables were used, and the new notion
        > that a hook need not be associated with a variable should
        > be explained in the doc.

    A hook IS a variable--that is to say, a symbol whose value is used.
    It is a mistake to think that a hook is not a variable.

You quoted me, but I got the idea from Stefan - possibly I misunderstood
him.

IIUC, what Stefan meant was this (he will correct me):

 - What makes a hook a hook is its use: if `run-hooks' uses it, then it's a
hook.

 - A symbol used as a hook need not necessarily be bound before it is run.
That is, you can call `run-hooks' on a symbol that has never been bound -
nothing happens.

 - Such an unbound symbol is not a variable. Of course, to do anything
useful as a hook, it must be bound.

 - The way to set up a symbol to serve as a useful hook is to use
`add-hook'. Binding the symbol is not the way to go.

 - For these reasons (I think), Stefan doesn't like to refer to "variable"
in this context: 1) The symbol can be run as an (inert) hook without being
bound. 2) Simply binding a symbol is not the way to make it useful as a
hook.

I don't know or care what terminology is used to describe the behavior of
hooks - I'm just learning.

To me, reading the `define-minor-mode' doc about `MODE-hook', I expected to
find existing (bound) variables named `MODE-hook' after calling
`define-minor-mode'. When I searched for them, I found none and I wondered
what the doc really meant.

It turns out (IIUC) that the doc simply meant that the created minor mode
command does (run-hooks 'MODE-hook). And, given an understanding of hooks
(which, in my case was incomplete), this means:

1. IF someone does (add-hook `MODE-hook' <something>) THEN <something> will
be run when the mode is entered and exited.

2. OTHERWISE, nothing will happen, because (run-hooks 'MODE-hook) does
nothing if `MODE-hook' is not bound or is bound to nil. I should say,
instead of speaking of binding, "if either `add-hook' was never called on it
or `remove-hook' was called to remove everything that `add-hook' had added".
I called this an "empty" hook, but Stefan didn't like that term.

IOW, in Stefan's terminology (IIUC): because `run-hooks' runs it, the hook
exists, even though the hook symbol might not be bound (so, no variable).

All this was not clear to me when I read the `define-minor-mode' doc. I
think it would be good if it were explained (using whatever terminology you
like) in the Hooks nodes of the manuals.

Again, I don't claim that my understanding is correct on this. My message
really is that I was confused by the current doc. Do with that feedback what
you will.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-06 19:09             ` Stefan Monnier
@ 2006-03-08 21:06               ` Kevin Rodgers
  2007-10-29 10:55                 ` Juanma Barranquero
  0 siblings, 1 reply; 11+ messages in thread
From: Kevin Rodgers @ 2006-03-08 21:06 UTC (permalink / raw)


Stefan Monnier wrote:
>>>In the past, hook variables were used, and the new notion that a hook need
>>>not be associated with a variable should be explained in the doc.
> 
> 
>>A hook IS a variable--that is to say, a symbol whose value is used.
>>It is a mistake to think that a hook is not a variable.
> 
> 
> Either way it's a mistake: when people think of a hook as a variable, they
> think that (boundp 'foo-hook) can tell them whether the hook exists or not.
> 
> So I prefer to think that a hook is its own kind of object, which happens to
> be implemented using a variable.

(defmacro defhook (symbol &rest optional-args)
   "Define SYMBOL as a hook.
You are not required to define a hook in order to use it,
but the definition can supply documentation and an initial value
in a way that `\\[describe-variable]' can recognize.

INITVALUE is evaluated, and used to set SYMBOL, only if SYMBOL's value 
is void.
If SYMBOL is buffer-local, its default value is what is set;
  buffer-local values are not affected.
INITVALUE and DOCSTRING are optional.
If INITVALUE is missing, SYMBOL's value is not set."
   `(let ((initvalue (car optional-args))
          (docstring (cadr optional-args)))
      (defvar ,symbol ,initvalue
        ,(if (and docstring
                  (string-match "\\`\\*" docstring))
             (substring docstring 1)
           docstring))
      (when (null optional-args)
        (makunbound ,symbol))))

Just kidding,
-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: doc on define-minor-mode hook variable(s)
  2006-03-08 21:06               ` Kevin Rodgers
@ 2007-10-29 10:55                 ` Juanma Barranquero
  0 siblings, 0 replies; 11+ messages in thread
From: Juanma Barranquero @ 2007-10-29 10:55 UTC (permalink / raw)
  To: Kevin Rodgers; +Cc: emacs-devel

On 3/8/06, Kevin Rodgers <ihs_4664@yahoo.com> wrote:

> (defmacro defhook (symbol &rest optional-args)
>    "Define SYMBOL as a hook.
[...]
> Just kidding,

Hmm. Well, kidding or not, that could be useful (yes, I know that many
people will consider it utterly unnecessary :-).

I'd love a defhook that would get a ":hook-type SOMEVALUE" keyword
argument and would do

  (put my-hook 'hook SOMEVALUE)

where SOMEVALUE could be as simple `t' (normal) or `special', or
perhaps something more sophisticate indicating the expected use
(number or arguments, whether it will return something or not).

No, I don't have a use case for the "more sophisticate" case (though
it could conceivably be used by add-hook to check validity of
functions added). But certainly having all hooks marked with a
property would have uses, the first one getting rid of
`unload-feature-special-hooks'.

Just dreaming,

             Juanma

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-10-29 10:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-05 19:40 doc on define-minor-mode hook variable(s) Drew Adams
2006-03-05 21:01 ` Stefan Monnier
2006-03-05 21:14   ` Drew Adams
2006-03-05 23:33     ` Stefan Monnier
2006-03-06  0:40       ` Drew Adams
2006-03-06  5:05         ` Stefan Monnier
2006-03-06 18:35           ` Richard Stallman
2006-03-06 19:09             ` Stefan Monnier
2006-03-08 21:06               ` Kevin Rodgers
2007-10-29 10:55                 ` Juanma Barranquero
2006-03-06 19:10             ` Drew Adams

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).