[Top][All Lists]

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

Re: comint-carriage-motion causes severe problems.

From: Richard Stallman
Subject: Re: comint-carriage-motion causes severe problems.
Date: Thu, 4 Jul 2002 12:24:08 -0600 (MDT)

    Actually, there are some unclear semantics when you do things like

            (add-hook 'foo 'bar)
            (add-hook 'foo 'bar nil 'local)
            (remove-hook 'foo 'bar 'local)

    The current code removes `bar' from the local value of `foo' but
    leaves it in the global one.  My new code does the same and only a second
    (remove-hook 'foo 'bar 'local) will add a (not . bar) such that the
    global setting is overridden.

This is semantically incoherent.  It is very dangerous for two
identical calls to remove-hook to be different in effect from one.

    I am starting to believe that it might be good to keep the present
    behavior of remove-hook, unless the third argument is the symbol
    'override, in which case it would override any function later in the
    hook, including global functions.

That gives a clean and predictable semantics for remove-hook.
However, this leaves the question of how you remove one of these
overrides.  Related question: how should add-hook deal with them?

This relates to another question: what should (remove-hook 'foo 'bar
'local) do after (remove-hook 'foo 'bar 'override)?  Nothing?  I don't
think that is right, because doing nothing would leave the override
marker in place; the state for `bar' would not be "no local hook".

There are three states that the local hook list can have, for any
function `bar':

1. Present
2. Absent
3. Overridden.

We could say that (add-hook 'foo 'bar 'local) puts it in state 1,
(remove-hook 'foo 'bar 'local) puts it in state 2, and (remove-hook
'foo 'bar 'override) puts it in state 3.  None of them changes the
global hook list, and global use of add-hook or remove-hook does not
change the local hook list.  Now we have fully coherent semantics
for both add-hook and remove-hook.

However, I think it is even cleaner to regard (not . bar) as a kind
of local hook value in its own right, and use add-hook to add that
and remove-hook to remove it.

(add-hook 'foo 'bar 'local) puts it in state 1
(remove-hook 'foo 'bar 'local) puts it in state 2
(add-hook 'foo '(not . bar) 'local) puts it in state 3
(remove-hook 'foo '(not . bar) 'local) puts it in state 2
so this is equivalent to (remove-hook 'foo 'bar 'local).

This is a coherent feature.  Is it really useful?  I am not sure.

The reason is, it is wrong to call comint-carriage-motion by adding it
globally and unconditionally to the hook.  When a function should be
called unconditionally, it should be called explicitly from the code,
not thru a hook.

Once this change is made, the way to fix the present problem is for
ielm to bind a variable that tells the code not to call
comint-carriage-motion, or tells comint-carriage-motion to do nothing.
The hook override feature won't be used here.

Do we have any other occasion to use the hook override feature?
Is that a useful feature?

reply via email to

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