emacs-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] Run hook when variable is set


From: Kelly Dean
Subject: Re: [PATCH] Run hook when variable is set
Date: Fri, 30 Jan 2015 07:34:23 +0000

> If we want to use such hooks for purposes such as "automatically
> recompute values of dependent vars", then I think the right way is to
> introduce a new layer which checks&runs these hooks, using the "raw"
> `setq' underneath.

You mean something like setq-with-hook, which you can use in place of setq? 
Then in general, you also need set-with-hook, setq-default-with-hook, 
set-default-with-hook, setq-local-with-hook, and let-with-hook. That seems 
cumbersome.

Varhook handles even that last case. E.g. with my fix for bug #19068, you can 
do:

message-directory ; → "~/mail/"
message-auto-save-directory ; → "/root/mail/drafts/"

(let ((message-directory "foo"))
  message-auto-save-directory ; → "/root/foo/drafts/"
  (setq message-directory "bar")
  message-auto-save-directory) ; → "/root/bar/drafts/"

message-directory ; → "~/mail/"
message-auto-save-directory ; → "/root/mail/drafts/" (restored because the 
«let» exited)

I didn't do anything special to enable synchronized let-binding for #19068; 
that ability comes automatically from varhook. Of course, in the particular 
case of message-directory, you're unlikely to want to let-bind it. But in 
general, varhook lets you easily keep your variables synchronized.

> For the same reason I want to kill the `intangible' text-property: this
> operates at too-low a level, so it's bound to introduce buggy
> interactions between unsuspecting packages.

But for variables that are supposed to be linked, requiring use of higher-level 
«-with-hook» functions results in bugs when you use the regular «set» functions.

Having documentation saying, ‟for this variable, use the «-with-hook» functions 
rather than the regular «set» functions”, and expecting everybody to remember 
to do that, doesn't seem like a good solution.

If you do that, then in case a user is prone to forgetting which variables need 
setq-with-hook and which ones only need setq, he can just always use the former 
(which works like setq if there's no hook). But then, why use the longer name 
for the more common function?

It makes more sense to have the default behavior (and short name) be to run the 
hook. You can still disable the hook (or remove the relevant function from the 
hook) when you need to intentionally unsynchronize your variables, which you'll 
normally only need to do during debugging.

>> And I explained why your code doesn't provide a complete solution.
>> You didn't respond.
>
> I must have misunderstood or overlooked it.  Can you retry?

The message is here:
https://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00786.html

In summary:
cursor-type can be changed buffer-locally, which doesn't affect other buffers 
or the global setting. Therefore dynamic-cursor-mode must be disabled in the 
same buffer, but not in other buffers or globally.

CT can be changed globally, which doesn't affect CT in buffers that have it set 
locally. Therefore DCM must be disabled globally, but not in buffers that have 
it enabled locally.

Turning on DCM globally must work, regardless of whether the user previously 
globally set CT to a nonstandard value.

Turning on DCM locally must not affect CT globally.

Turning off DCM locally must affect neither CT nor DCM in other buffers.

It doesn't appear to be possible to satisfy all of those conditions without 
varhook. With varhook, it's easy: the hook function disables DCM globally when 
CT is set globally, and disables DCM locally when CT is set locally.


BTW, define-minor-mode (with the fix for bug #19685 applied) does produce 
documentation implying that it's appropriate to set a mode's variable directly; 
you were right about that. So the updated patch I sent you a couple days ago 
implements DCM as a mode.

And I implemented a minor enhancement (bug #19690) to help prevent users from 
being confused about setting local vs. global minor modes in general.



reply via email to

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