emacs-devel
[Top][All Lists]
Advanced

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

Re: Suggestion: Simple way to make conditional key bindings.


From: Stefan Monnier
Subject: Re: Suggestion: Simple way to make conditional key bindings.
Date: Mon, 26 Aug 2002 11:47:50 -0400

> > You want to have a code.  That's what functions are for.  I think `eval'
> > should generally be avoided, and `funcall' used instead.
> > This is especially true if we care about lexical scoping.
> 
> I don't quite follow, but I take your word for it :-)

When you construct a function, the Elisp interpreter/compiler knows that
it's a piece of code and can do all kinds of things with it (byte-compile
it, analyze it and put out warnings, build a closure to remember the
current lexical bindings, ...).
OTOH, when you build a piece of code to be eval'd, the Elisp
interpreter/compiler usually has no idea that this is code rather
than just some kind of list of elements, so it can't do anything
clever with it.

> > One problem with your change is "what binding do we use when we don't want
> > to run code?".  The `menu-item' syntax provides a binding (in the example
> > above it's "my-filter" which is not very useful indeed) for the case
> > where code should not be evalled (for example in `where-is').
> 
> Who said we don't want to run code :-)

The current code says so.

> > > It will then be quite trivial to enhance `define-key' to handle
> > > conditional bindings:
> > 
> > But is it desirable ?
> 
> Don't really know...   It seems like a simple approach to allow
> packages to hook into "standard bindings".

How about a set of examples where the current code does not provide
sufficient flexibility ?  I can come up with plenty of examples
where we could use your code, but for most/all of them we could
just as well put the bindings in minor/major-mode-maps or text-property
keymaps.

> > > (define-key global-map "\C-y" 'yank)  ; this sets the default
> > > 
> > > (define-key global-map "\C-y" 'yank-with-properties
> > >         '(and kill-ring (table-recognize-table (car kill-ring))))
> > > 
> > > The second call would automatically changes the non-cond binding into
> > > a cond binding with the previous binding as default.
> > 
> > Why not
> > 
> >   (define-key global-map "\C-y" 'yank-careful)
> >   (defun yank-careful (...)
> >     "Reinsert the last stretch of killed text, like `yank'.
> >   Contrary to `yank' this function is careful to preserve some important
> >   text properties when yanking tables."
> >     ...)
> 
> The point is that you can install a package - like table.el - which is
> then able to install its own conditional binding on C-y *without*
> interferring with (or even knowning) the standard binding.

I don't think that's right.  I don't believe that table wants to override
C-y sometimes: instead it wants to override `yank' sometimes.
So what you want to do is to create `yank-careful' and then use
either the `remap' thingy or substitute-key-definition or something
like that.

> Suppose we have a conditional binding like this
> 
>   (define-key global-map "\C-y" 'yank-rectangle
>         '(rectangle-p (car kill-ring)))
> 
> to be able to insert rectangles from the kill-ring using C-y.

The behavior would be really odd if the user had rebound C-y
to `comment-dwim'.

> Then table.el would still be able to install its own conditional
> binding on C-y.

Now that's a more interesting example.  But maybe that calls for
replacing `yank-careful' with a (defadvice yank ...) or something
like that.  I admit that I don't think either of yank-careful or
defadvice are quite satisfactory for this case.
But maybe, using `remap', we could check for an existing `remap'
binding before adding our own, so that table.el would not defer
to `yank' but to `yank-careful'.

> > The advantage is that C-h k C-y doesn't just give you one of the two
> > bindings but a docstring that describes both.  Of course we could also
> > improve C-h k to recognize your `cond' construct, etc... but is it
> > really worth the trouble ?
> 
> I didn't think about that, but it would be a nice way to report such
> "multiple" bindings on a key...
> 
> But you may also consider this as a different approach than using a
> minor-mode-keymap, and in that case, I think C-h k doesn't report all
> possible bindings for a key -- only the "currently active" binding, so
> why does `cond' have to behave differently?

It depends on whether the conditional that determines if the binding
is active changes frequently or not (or implicitly or not).

By the way, you can also get a behavior similar to the one you suggest
using minor-mode maps (or major-mode maps or text-property maps) where
the menu-item's filter returns nil in some cases (thus deferring to
lower-precedence keymaps).


        Stefan





reply via email to

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