[Top][All Lists]

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

RE: customizing key definitions with Customize

From: Drew Adams
Subject: RE: customizing key definitions with Customize
Date: Tue, 13 May 2008 22:24:09 -0700

> > >> I like the idea, but can't it be taken one step further: 
> > >> Wouldn't it be nice with a "sparse-keymap widget"? And then
> > >> of course `customize-sparse-keymap'.
> > >>
> > >> Or have you already done this too, Drew?
> > > 
> > > No, I haven't taken it further than what I wrote. But I 
> > > don't really know what you have in mind. Perhaps you can
> > > elaborate or go further with the idea yourself?
> > 
> > I was just thinking `customize-sparse-keymap'. That would 
> > bring up the current bindings in that keymap in a custom
> > buffer using widgets similar to your `key-definition' widget.
> I see. Yes, that could be easily done.

Not quite as easily as I thought, at least for me. ;-)

I did take a look, however, and came up with the following code (attached).
There are no doubt more elegant and more direct ways to do this than to use
`substitute-command-keys' and `eval'. Probably something like `map-keymap' could
be used, but its automatic ancestor keymap recursion scared me off. 

The approach I used is certainly ugly and perhaps fragile, but it seems to work.
It works for menu maps also. It excludes prefix keys. It special-cases
`mouse-face' and `ignore-event', since they are not in fact commands. (Hence,
the `key-definition' widget is different from what I sent before - it no longer
requires the `Command' sexp to be a command.)

If nothing else, this gives an idea of what a UI for customizing keymaps might
be like. Please try it out, as follows:

Command `custom-create-keymap-option' creates a user option of the same name as
its keymap argument, but with `-defs' appended. E.g.,

 M-x custom-create-keymap-option RET bookmark-map

Completion is available for keymap-valued symbols. Then you can customize the
new option that corresponds to the keymap:

 M-x customize-option RET bookmark-map-defs

Note that, as I mentioned before, you can specify a command to remap instead of
a key to bind (use Value Menu).

And yes, the keymap itself is modified when you change key definitions in
Customize - the option's :set function does that. 

However, the option is currently decoupled from the keymap to some extent: The
:set function currently just does `define-key' for each of its key definitions.
It does not also reinitialize (empty out) the keymap so that it will have only
those definitions. That could be done, but it's worth thinking about whether
that is always what is wanted (probably).

This means that, currently: If you change the command part of a key definition,
the same key becomes bound to the new command. But if you change the key part of
a key definition, the new key becomes bound to the same command - but the old
key is not unbound from the command. Similarly, DEL deletes the key definition
from the user option, but it does not unbind the key in the keymap. IOW, you are
editing the option, and the :set function for the option currently just does
`define-key' for whatever definitions are present.

Also, in a new Emacs session, after saving the option, there is nothing that
automatically defines the corresponding keymap from the option. Currently, the
library that defines the keymap would need to explicitly initialize it from the
option, in order for the saved value to be picked up in a future session. 

In Icicles, for instance, the bindings are picked up from the option whenever
you enter Icicle mode. In Icicles, I use code similar to what I sent previously,
which provides users only some of the key definitions, by default. It is not my
intention to invite users to customize the whole keymap (but they are of course
able to do that via INS).

That I think is a useful part of this approach of having an option separate from
the keymap: Whereas `custom-create-keymap-option' blindly includes all of a
keymap's bindings in the option it creates, libraries could instead choose to
provide a hand-rolled (or pruned) option that includes only some of the

Defining keymaps from their corresponding options could perhaps be built into
Emacs somehow - either generally or just for specific contexts, such as minor
mode keymaps (e.g. via macro `define-minor-mode'). The code responsible for
this, whether automatic or not, would check whether a keymap option existed and,
if so, would use it to define the keymap.

There are lots of possibilities, depending on what uses are seen for something
like this.

While testing the code, BTW, I uncovered 2 or 3 Emacs bugs. These are the bug
report threads:

1. "kbd returns wrong value"
2. "substitute-command-keys incorrect for self-insert-command"
3. "\ is considered whitespace syntax in Lisp mode?" (maybe only a doc bug - not
clear to me, anyway)

#1 is a bug in `edmacro-parse-keys' (or in the `Describe' menu, depending on how
you look at it). It causes a bogus entry if you try `M-x
custom-create-keymap-option menu-bar-help-menu', because `<Brazilian
Portuguese>' has a space in it.

Related to #2 and #3: if you try `custom-create-keymap-option' on a non-sparse
keymap, such as `global-map' or `dired-mode-map', you will see an entry that
looks like this in Customize:

INS DEL Key Definition: List:
 Choice: Value Menu Key: \200 . . ÿ

I haven't tried to make such an entry do anything useful. That is, the custom
type here does not recognize \200 . . ÿ as a key range - it treats it as an
ordinary, single key sequence. Such an entry should probably just be filtered
out, unless it can be made useful.

Attachment: keymap-option.el
Description: Binary data

reply via email to

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