phs@lifia.UUCP (08/29/87)
I am having problems trying to figure out how one can use the "keypad"
feature of GNU Emacs 18 to bind commands to keys in a terminal-independent
way, which is, as I understand it, the purpose of keypad.el. If you have a
neat solution, please explain to the net ...
1/ What I want to do.
Let's be explicit: I want to define a keymap, called my-map, which, when
it is current, binds the UpArrow function key to command my-move-up. This
should be terminal-independent, ... of course.
The main point is that I want this binding to be mode-dependent: when
my-map is not current, the standard binding for UpArrow should be used.
2/ How to (try to) do it.
One problem with the keypad feature is that the binding from function
keys (e.g. UpArrow) to commands (e.g. previous-line) is stored in only
one place: the FUNCTION-KEYMAP variable, which is then used by the terminal
specific initialization set-up. Of course, you can rebind a function key
in function-keymap but, basically, you have only one function-keymap and
cannot use it for "mode-specific" bindings.
On the other hand, you do have mode-specific keymaps, but these keymaps
do not provide entries for function keys. You have to translate from
function keys to the specific sequence of characters they send. Such a
mapping is done by the terminal-dependent initialization code, using the
setup-terminal-keymap function. This function is a derivative of
define-key, and, roughly, it binds characters sequences to abstract
function keys in a variable keymap. As it is used by the terminal
initialization code, it only acts upon the global keymap.
A better design would have been to use a terminal-dependent phase to
establish a mapping from abstract function keys to the actual sequences of
characters they send, rather than a mapping from character sequences to
function keys. Then, define-key could deal with function keys by looking in
the table, mapping function keys to character sequences, and you could
write something like:
(define-key my-map ?u 'my-move-up)
In a sense, it is already possible to achieve this, but in a somewhat
contrived way. Keypad.el defines a function-key-sequence function, which
given a function-key, returns the characters it sends. So I tried:
(define-key my-map (function-key-sequence ?u) 'my-move-up)
This exhibits two problems. First, as the mapping from function keys to
character sequences is done "the other way around", function-key-sequence
has to scan the entire global keymap, which is time-consuming, and this is
a real problem when you want to bind all the function keys of a normal
terminal. Note that establishing a mapping the other way around would not
induce similar problems: instead of customizing the function-keymap, one
would just use (global-set-key ?u ...). Furthermore, this would probably
provide a simpler way of rebinding function keys for the casual Emacs user,
rather than having to know about function-keymap.
The second problem is that function-key-sequence returns only one
sequence, and that, for some terminals, several character sequences are
bound to a same function keys. Admittedly, this is a problem with the
terminal initialization, but look at the standard term/vt200.el (e.g.) file
and consider that both ESC [ A and ESC O A are defined for the UpArrow
key... Of course function-key-sequence returns ESC O A, and on my
terminal, the UpArrow key actually sends ESC [ A :-).
3/ Disclaimer.
Now, as the Emacs-Lisp manual is not yet written, I may very well have
missed a simple way of solving all these problems. In that case, please,
let me know "the answer". Also, I believe the extension allowing define-key
to handle characters denoting function keys is upward compatible, as it
does not conflict with the actual behaviour of define-key which only
accepts strings as its KEYS argument. Here also I may be wrong. If it is
the case, tell me. Thanks in advance.
--
Philippe SCHNOEBELEN,
LIFIA - INPG, UUCP : phs@lifia.imag.fr
46, Avenue Felix VIALLET
38000 Grenoble, FRANCE
"Algebraic symbols are used when you do not know what you are talking about."