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."