add-hook versus custom-set-variables

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

add-hook versus custom-set-variables

Bill Wohler
I set mh-folder-mode-hook to bw-mh-folder-mode-hook in my
custom-set-variables stanza.

When I start Emacs, I see that mh-folder-mode-hook is set to
mc-install-read-mode instead. I'd expect to see both
mc-install-read-mode and bw-mh-folder-mode-hook. This reminded me a lot
of the problems we had with the defvar of the hook in
define-derived-mode.

It appears that an add-hook call during the mailcrypt initialization is
binding mh-folder-mode-hook so that the custom-set-variables is losing.
I think Luc's explanation in
http://article.gmane.org/gmane.emacs.pretest.bugs/9993 is germane.

Since users will use the Customization interface to set hooks (at least
166 of them in my instance), I think it is important to figure out a
general resolution to this problem.

Two workarounds which aren't pretty are to insist that the user add a
defvar in .emacs for any hook he customizes or for system libraries to
delay the evaluation of add-hook until after the related
custom-set-variables and defcustom have been evaluated.

When I modified mailcrypt-init.el as follows:

    ;; MH-E hooks
    (eval-after-load 'mh-customize
      (progn
        (message "Adding mailcrypt hooks to MH-E...")
        (add-hook 'mh-folder-mode-hook 'mc-install-read-mode)
        (add-hook 'mh-letter-mode-hook 'mc-install-write-mode)))

I found that the eval-after-load form was evaluated during
initialization rather than after I loaded MH-E. From *Messages*:

    Loading 50mailcrypt (source)...
    Adding mailcrypt hooks to MH-E...

Any thoughts as to why this happened? No, mh-customize had not been
loaded yet.

For the Debian folks, I have the following code in my .emacs so that I
can use Debian Emacs Lisp packages while running CVS Emacs:

    (when (eq emacs-major-version 22)
      (add-to-list 'load-path "/usr/share/emacs/site-lisp")
      (load-library "debian-startup")
      (setq debian-emacs-flavor 'emacs-snapshot)
      (debian-startup 'emacs-snapshot))

--
Bill Wohler <[hidden email]>  http://www.newt.com/wohler/  GnuPG ID:610BD9AD
Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian!
If you're passed on the right, you're in the wrong lane.


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Stefan Monnier
> Two workarounds which aren't pretty are to insist that the user add a
> defvar in .emacs for any hook he customizes

I don't understand what you're suggesting here.
How could a defvar in .emacs help?

>     ;; MH-E hooks
>     (eval-after-load 'mh-customize
>       (progn
> (message "Adding mailcrypt hooks to MH-E...")
> (add-hook 'mh-folder-mode-hook 'mc-install-read-mode)
> (add-hook 'mh-letter-mode-hook 'mc-install-write-mode)))

eval-after-load is a function, not a macro.  I know it's counter
intuitive.


        Stefan


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Bill Wohler
Stefan Monnier <[hidden email]> writes:

>> Two workarounds which aren't pretty are to insist that the user add a
>> defvar in .emacs for any hook he customizes
>
> I don't understand what you're suggesting here.
> How could a defvar in .emacs help?

Please read Luc's article where he describes the technique and why.

  http://article.gmane.org/gmane.emacs.pretest.bugs/9993

>>     ;; MH-E hooks
>>     (eval-after-load 'mh-customize
>>       (progn
>> (message "Adding mailcrypt hooks to MH-E...")
>> (add-hook 'mh-folder-mode-hook 'mc-install-read-mode)
>> (add-hook 'mh-letter-mode-hook 'mc-install-write-mode)))
>
> eval-after-load is a function, not a macro.  I know it's counter
> intuitive.

I don't know enough about the internals to know why this would be
counter-intuitive. I read your answer as: macros do what you expect,
functions don't. Please elaborate if this is not what you mean. Why
doesn't eval-after-load do what I expect?

--
Bill Wohler <[hidden email]>  http://www.newt.com/wohler/  GnuPG ID:610BD9AD
Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian!
If you're passed on the right, you're in the wrong lane.



_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Stefan Monnier
>>> Two workarounds which aren't pretty are to insist that the user add a
>>> defvar in .emacs for any hook he customizes
>>
>> I don't understand what you're suggesting here.
>> How could a defvar in .emacs help?

> Please read Luc's article where he describes the technique and why.

>   http://article.gmane.org/gmane.emacs.pretest.bugs/9993

Oh, I see.  It's not specific to defvar: setq works just as well.

>>> ;; MH-E hooks
>>> (eval-after-load 'mh-customize
>>> (progn
>>> (message "Adding mailcrypt hooks to MH-E...")
>>> (add-hook 'mh-folder-mode-hook 'mc-install-read-mode)
>>> (add-hook 'mh-letter-mode-hook 'mc-install-write-mode)))
>>
>> eval-after-load is a function, not a macro.  I know it's counter
>> intuitive.

> I don't know enough about the internals to know why this would be
> counter-intuitive. I read your answer as: macros do what you expect,
> functions don't. Please elaborate if this is not what you mean. Why
> doesn't eval-after-load do what I expect?

The evaluation of a form (A B C) can follow the following two paths:

- if it's a macro:

   (eval (macrocall A B C))

- if it's a function

   (funcall A (eval B) (eval C))

Note how a function cannot delay the evaluation of its arguments.


        Stefan


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Bill Wohler
Stefan Monnier <[hidden email]> wrote:

> >>> Two workarounds which aren't pretty are to insist that the user add a
> >>> defvar in .emacs for any hook he customizes
> >>
> >> I don't understand what you're suggesting here.
> >> How could a defvar in .emacs help?
>
> > Please read Luc's article where he describes the technique and why.
>
> >   http://article.gmane.org/gmane.emacs.pretest.bugs/9993
>
> Oh, I see.  It's not specific to defvar: setq works just as well.
>
> >>> ;; MH-E hooks
> >>> (eval-after-load 'mh-customize
> >>> (progn
> >>> (message "Adding mailcrypt hooks to MH-E...")
> >>> (add-hook 'mh-folder-mode-hook 'mc-install-read-mode)
> >>> (add-hook 'mh-letter-mode-hook 'mc-install-write-mode)))
> >>
> >> eval-after-load is a function, not a macro.  I know it's counter
> >> intuitive.
>
> > I don't know enough about the internals to know why this would be
> > counter-intuitive. I read your answer as: macros do what you expect,
> > functions don't. Please elaborate if this is not what you mean. Why
> > doesn't eval-after-load do what I expect?
>
> The evaluation of a form (A B C) can follow the following two paths:
>
> - if it's a macro:
>
>    (eval (macrocall A B C))
>
> - if it's a function
>
>    (funcall A (eval B) (eval C))
>
> Note how the function cannot delay the evaluation of its arguments.

Thanks for the explanation. There's a lot of strange things in
elisp--mostly around compilation and evaluation--that I don't understand
and every little bit helps. Maybe another reading of these sections in
the elisp manual will make more sense now.

In any event, I think I get it now. To keep eval-after-load from being
completely useless, the idiom is to quote the form. Right?

This works:

 (eval-after-load "mh-e"
   '(progn
     (add-hook 'mh-folder-mode-hook 'mc-install-read-mode)
     (add-hook 'mh-letter-mode-hook 'mc-install-write-mode)))

BUT!

While coming up with a recipe to prove that the semantics had changed
between Emacs 21 and 22, I discovered I was inadvertently performing my
"site-init" *after* I ran custom-set-variables. (Recall that I'm
simulating the Debian site-init from my .emacs while using CVS Emacs.)
Normally, site-init is performed *before* one's .emacs is loaded. After
moving the site-init to the top of my .emacs file, I regained Emacs 21
semantics and all is well.

Sorry about the false alarm; at least I learned a few things.

--
Bill Wohler <[hidden email]>  http://www.newt.com/wohler/  GnuPG ID:610BD9AD
Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian!
If you're passed on the right, you're in the wrong lane.


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Stefan Monnier
>> The evaluation of a form (A B C) can follow the following two paths:
>>
>> - if it's a macro:
>>
>> (eval (macrocall A B C))
>>
>> - if it's a function
>>
>> (funcall A (eval B) (eval C))
>>
>> Note how the function cannot delay the evaluation of its arguments.

> Thanks for the explanation. There's a lot of strange things in
> elisp--mostly around compilation and evaluation--that I don't understand
> and every little bit helps.  Maybe another reading of these sections in
> the elisp manual will make more sense now.

Actually this difference between macros and functions applies to 99% of
all languages.


        Stefan


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Tomas Zerolo
On Thu, Dec 29, 2005 at 02:12:40PM -0500, Stefan Monnier wrote:
[...]
> > Thanks for the explanation. There's a lot of strange things in
> > elisp--mostly around compilation and evaluation--that I don't understand
> > and every little bit helps.  Maybe another reading of these sections in
> > the elisp manual will make more sense now.
>
> Actually this difference between macros and functions applies to 99% of
> all languages.

Yes, but for a big proportion of those 99% your theorem applies trivially
(there are no macros), and for the rest... in most of thenm macros look
so utterly different from the rest of the language that this is a
non-issue.

The Lisp way of macros is a very special beast indeed.

Regards
-- tomas

_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel

signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Bill Wohler
In reply to this post by Stefan Monnier
Stefan Monnier <[hidden email]> writes:

> eval-after-load is a function, not a macro.  I know it's counter
> intuitive.

Perhaps the docstring and manual for eval-after-load should highlight
this pitfall. Maybe it should mention that its form is evaluated
immediately and that the form should be quoted to get expected
behavior.

--
Bill Wohler <[hidden email]>  http://www.newt.com/wohler/  GnuPG ID:610BD9AD
Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian!
If you're passed on the right, you're in the wrong lane.



_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Stefan Monnier
>> eval-after-load is a function, not a macro.  I know it's counter
>> intuitive.

> Perhaps the docstring and manual for eval-after-load should highlight
> this pitfall. Maybe it should mention that its form is evaluated
> immediately and that the form should be quoted to get expected
> behavior.

Better would be to kill the beast and replace it with a macro.
Sadly, keeping the same name is not an option for backward
compatibility reasons.

Maybe we could introduce a new macro `do-after-load' or `after-load' or
`eval-after'?


        Stefan


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

Richard Stallman
    Maybe we could introduce a new macro `do-after-load' or `after-load' or
    `eval-after'?

Since this is not a new feature, and the issue is not a bug, let's not
consider changing it now.


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

David Kastrup
"Richard M. Stallman" <[hidden email]> writes:

>     Maybe we could introduce a new macro `do-after-load' or
>     `after-load' or `eval-after'?
>
> Since this is not a new feature, and the issue is not a bug, let's not
> consider changing it now.

If it helps getting the release out this year.

--
David Kastrup, Kriemhildstr. 15, 44793 Bochum


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

seewhydee
> If it helps getting the release out this year.

We have only a few hours left, so this seems unlikely.


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel
Reply | Threaded
Open this post in threaded view
|

Re: add-hook versus custom-set-variables

David Kastrup
Chong Yidong <[hidden email]> writes:

>> If it helps getting the release out this year.
>
> We have only a few hours left, so this seems unlikely.

Your name would suggest that you have _quite_ a lot of hours in your
current year left, but maybe some of your relatives are in a better
position.

--
David Kastrup, Kriemhildstr. 15, 44793 Bochum


_______________________________________________
Emacs-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/emacs-devel