Mercurial > hg > xemacs-beta
comparison lisp/keymap.el @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 ;; keymap.el --- Keymap functions for XEmacs. | |
2 | |
3 ;; Copyright (C) 1993-4, 1997 Free Software Foundation, Inc. | |
4 ;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | |
5 | |
6 ;; Maintainer: XEmacs Development Team | |
7 ;; Keywords: internals, dumped | |
8 | |
9 ;; This file is part of XEmacs. | |
10 | |
11 ;; XEmacs is free software; you can redistribute it and/or modify it | |
12 ;; under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2, or (at your option) | |
14 ;; any later version. | |
15 | |
16 ;; XEmacs is distributed in the hope that it will be useful, but | |
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 ;; General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with XEmacs; see the file COPYING. If not, write to the | |
23 ;; Free Software Foundation, 59 Temple Place - Suite 330, | |
24 ;; Boston, MA 02111-1307, USA. | |
25 | |
26 ;;; Synched up with: FSF 19.28. | |
27 | |
28 ;;; Commentary: | |
29 | |
30 ;; This file is dumped with XEmacs. | |
31 | |
32 ;;; Note: FSF does not have a file keymap.el. This stuff is | |
33 ;;; in keymap.c. | |
34 | |
35 ;Prevent the \{...} documentation construct | |
36 ;from mentioning keys that run this command. | |
37 | |
38 ;;; Code: | |
39 | |
40 (put 'undefined 'suppress-keymap t) | |
41 | |
42 (defun undefined () | |
43 (interactive) | |
44 (ding)) | |
45 | |
46 (defmacro kbd (keys) | |
47 "Convert KEYS to the internal Emacs key representation. | |
48 KEYS should be a string in the format used for saving keyboard macros | |
49 \(see `insert-kbd-macro')." | |
50 (if (or (stringp keys) | |
51 (vectorp keys)) | |
52 (read-kbd-macro keys) | |
53 `(read-kbd-macro ,keys))) | |
54 | |
55 (defun suppress-keymap (map &optional nodigits) | |
56 "Make MAP override all normally self-inserting keys to be undefined. | |
57 Normally, as an exception, digits and minus-sign are set to make prefix args, | |
58 but optional second arg NODIGITS non-nil treats them like other chars." | |
59 (substitute-key-definition 'self-insert-command 'undefined map global-map) | |
60 (or nodigits | |
61 (let ((string (make-string 1 ?0))) | |
62 (define-key map "-" 'negative-argument) | |
63 ;; Make plain numbers do numeric args. | |
64 (while (<= (aref string 0) ?9) | |
65 (define-key map string 'digit-argument) | |
66 (incf (aref string 0)))))) | |
67 | |
68 (defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix) | |
69 "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF. | |
70 In other words, OLDDEF is replaced with NEWDEF wherever it appears. | |
71 Prefix keymaps are checked recursively. If optional fourth argument OLDMAP | |
72 is specified, we redefine in KEYMAP as NEWDEF those chars which are defined | |
73 as OLDDEF in OLDMAP, unless that keybinding is already present in keymap. | |
74 If optional fifth argument PREFIX is defined, then only those occurrences of | |
75 OLDDEF found in keymaps accessible through the keymap bound to PREFIX in | |
76 KEYMAP are redefined. See also `accessible-keymaps'." | |
77 (let ((maps (accessible-keymaps (or oldmap keymap) prefix)) | |
78 (shadowing (not (null oldmap))) | |
79 prefix map) | |
80 (while maps | |
81 (setq prefix (car (car maps)) | |
82 map (cdr (car maps)) | |
83 maps (cdr maps)) | |
84 ;; Substitute in this keymap | |
85 (map-keymap #'(lambda (key binding) | |
86 (if (eq binding olddef) | |
87 ;; The new bindings always go in KEYMAP even if we | |
88 ;; found them in OLDMAP or one of its children. | |
89 ;; If KEYMAP will be shadowing OLDMAP, then do not | |
90 ;; redefine the key if there is another binding | |
91 ;; in KEYMAP that will shadow OLDDEF. | |
92 (or (and shadowing | |
93 (lookup-key keymap key)) | |
94 ;; define-key will give an error if a prefix | |
95 ;; of the key is already defined. Otherwise | |
96 ;; it will define the key in the map. | |
97 ;; #### - Perhaps this should be protected? | |
98 (define-key | |
99 keymap | |
100 (vconcat prefix (list key)) | |
101 newdef)))) | |
102 map) | |
103 ))) | |
104 | |
105 | |
106 ;; From Bill Dubuque <wgd@martigny.ai.mit.edu> | |
107 | |
108 ;; This used to wrap forms into an interactive lambda. It is unclear | |
109 ;; to me why this is needed in this function. Anyway, | |
110 ;; `key-or-menu-binding' doesn't do it, so this function no longer | |
111 ;; does it, either. | |
112 (defun insert-key-binding (key) ; modeled after describe-key | |
113 "Insert the command bound to KEY." | |
114 (interactive "kInsert command bound to key: ") | |
115 (let ((defn (key-or-menu-binding key))) | |
116 (if (or (null defn) (integerp defn)) | |
117 (error "%s is undefined" (key-description key)) | |
118 (if (or (stringp defn) (vectorp defn)) | |
119 (setq defn (key-binding defn))) ;; a keyboard macro | |
120 (insert (format "%s" defn))))) | |
121 | |
122 ;; From Bill Dubuque <wgd@martigny.ai.mit.edu> | |
123 (defun read-command-or-command-sexp (prompt) | |
124 "Read a command symbol or command sexp. | |
125 A command sexp is wrapped in an interactive lambda if needed. | |
126 Prompts with PROMPT." | |
127 ;; Todo: it would be better if we could reject symbols that are not | |
128 ;; commandp (as does 'read-command') but that is not easy to do | |
129 ;; because we must supply arg4 = require-match = nil for sexp case. | |
130 (let ((result (car (read-from-string | |
131 (completing-read prompt obarray 'commandp))))) | |
132 (if (and (consp result) | |
133 (not (eq (car result) 'lambda))) | |
134 `(lambda () | |
135 (interactive) | |
136 ,result) | |
137 result))) | |
138 | |
139 (defun local-key-binding (keys) | |
140 "Return the binding for command KEYS in current local keymap only. | |
141 KEYS is a string, a vector of events, or a vector of key-description lists | |
142 as described in the documentation for the `define-key' function. | |
143 The binding is probably a symbol with a function definition; see | |
144 the documentation for `lookup-key' for more information." | |
145 (let ((map (current-local-map))) | |
146 (if map | |
147 (lookup-key map keys) | |
148 nil))) | |
149 | |
150 (defun global-key-binding (keys) | |
151 "Return the binding for command KEYS in current global keymap only. | |
152 KEYS is a string or vector of events, a sequence of keystrokes. | |
153 The binding is probably a symbol with a function definition; see | |
154 the documentation for `lookup-key' for more information." | |
155 (lookup-key (current-global-map) keys)) | |
156 | |
157 ;; from Bill Dubuque <wgd@martigny.ai.mit.edu> | |
158 (defun global-set-key (key command) | |
159 "Give KEY a global binding as COMMAND. | |
160 COMMAND is a symbol naming an interactively-callable function. | |
161 KEY is a string, a vector of events, or a vector of key-description lists | |
162 as described in the documentation for the `define-key' function. | |
163 Note that if KEY has a local binding in the current buffer | |
164 that local binding will continue to shadow any global binding." | |
165 ;;(interactive "KSet key globally: \nCSet key %s to command: ") | |
166 (interactive (list (setq key (read-key-sequence "Set key globally: ")) | |
167 ;; Command sexps are allowed here so that this arg | |
168 ;; may be supplied interactively via insert-key-binding. | |
169 (read-command-or-command-sexp | |
170 (format "Set key %s to command: " | |
171 (key-description key))))) | |
172 (define-key (current-global-map) key command) | |
173 nil) | |
174 | |
175 ;; from Bill Dubuque <wgd@martigny.ai.mit.edu> | |
176 (defun local-set-key (key command) | |
177 "Give KEY a local binding as COMMAND. | |
178 COMMAND is a symbol naming an interactively-callable function. | |
179 KEY is a string, a vector of events, or a vector of key-description lists | |
180 as described in the documentation for the `define-key' function. | |
181 The binding goes in the current buffer's local map, | |
182 which is shared with other buffers in the same major mode." | |
183 ;;(interactive "KSet key locally: \nCSet key %s locally to command: ") | |
184 (interactive (list (setq key (read-key-sequence "Set key locally: ")) | |
185 ;; Command sexps are allowed here so that this arg | |
186 ;; may be supplied interactively via insert-key-binding. | |
187 (read-command-or-command-sexp | |
188 (format "Set key %s locally to command: " | |
189 (key-description key))))) | |
190 (if (null (current-local-map)) | |
191 (use-local-map (make-sparse-keymap))) | |
192 (define-key (current-local-map) key command) | |
193 nil) | |
194 | |
195 (defun global-unset-key (key) | |
196 "Remove global binding of KEY. | |
197 KEY is a string, a vector of events, or a vector of key-description lists | |
198 as described in the documentation for the `define-key' function." | |
199 (interactive "kUnset key globally: ") | |
200 (global-set-key key nil)) | |
201 | |
202 (defun local-unset-key (key) | |
203 "Remove local binding of KEY. | |
204 KEY is a string, a vector of events, or a vector of key-description lists | |
205 as described in the documentation for the `define-key' function." | |
206 (interactive "kUnset key locally: ") | |
207 (if (current-local-map) | |
208 (define-key (current-local-map) key nil))) | |
209 | |
210 | |
211 ;; FSF-inherited brain-death. | |
212 (defun minor-mode-key-binding (key &optional accept-default) | |
213 "Find the visible minor mode bindings of KEY. | |
214 Return an alist of pairs (MODENAME . BINDING), where MODENAME is | |
215 the symbol which names the minor mode binding KEY, and BINDING is | |
216 KEY's definition in that mode. In particular, if KEY has no | |
217 minor-mode bindings, return nil. If the first binding is a | |
218 non-prefix, all subsequent bindings will be omitted, since they would | |
219 be ignored. Similarly, the list doesn't include non-prefix bindings | |
220 that come after prefix bindings. | |
221 | |
222 If optional argument ACCEPT-DEFAULT is non-nil, recognize default | |
223 bindings; see the description of `lookup-key' for more details about this." | |
224 (let ((tail minor-mode-map-alist) | |
225 a s v) | |
226 (while tail | |
227 (setq a (car tail) | |
228 tail (cdr tail)) | |
229 (and (consp a) | |
230 (symbolp (setq s (car a))) | |
231 (boundp s) | |
232 (symbol-value s) | |
233 ;; indirect-function deals with autoloadable keymaps | |
234 (setq v (indirect-function (cdr a))) | |
235 (setq v (lookup-key v key accept-default)) | |
236 ;; Terminate loop, with v set to non-nil value | |
237 (setq tail nil))) | |
238 v)) | |
239 | |
240 | |
241 (defun current-minor-mode-maps () | |
242 "Return a list of keymaps for the minor modes of the current buffer." | |
243 (let ((l '()) | |
244 (tail minor-mode-map-alist) | |
245 a s v) | |
246 (while tail | |
247 (setq a (car tail) | |
248 tail (cdr tail)) | |
249 (and (consp a) | |
250 (symbolp (setq s (car a))) | |
251 (boundp s) | |
252 (symbol-value s) | |
253 ;; indirect-function deals with autoloadable keymaps | |
254 (setq v (indirect-function (cdr a))) | |
255 (setq l (cons v l)))) | |
256 (nreverse l))) | |
257 | |
258 | |
259 ;;#### What a crock | |
260 (defun define-prefix-command (name &optional mapvar) | |
261 "Define COMMAND as a prefix command. | |
262 A new sparse keymap is stored as COMMAND's function definition. | |
263 If second optional argument MAPVAR is not specified, | |
264 COMMAND's value (as well as its function definition) is set to the keymap. | |
265 If a second optional argument MAPVAR is given and is not `t', | |
266 the map is stored as its value. | |
267 Regardless of MAPVAR, COMMAND's function-value is always set to the keymap." | |
268 (let ((map (make-sparse-keymap name))) | |
269 (fset name map) | |
270 (cond ((not mapvar) | |
271 (set name map)) | |
272 ((eq mapvar 't) | |
273 ) | |
274 (t | |
275 (set mapvar map))) | |
276 name)) | |
277 | |
278 | |
279 ;;; Converting vectors of events to a read-equivalent form. | |
280 ;;; This is used both by call-interactively (for the command history) | |
281 ;;; and by macros.el (for saving keyboard macros to a file). | |
282 | |
283 ;; #### why does (events-to-keys [backspace]) return "\C-h"? | |
284 ;; BTW, this function is a mess, and macros.el does *not* use it, in | |
285 ;; spite of the above comment. `format-kbd-macro' is used to save | |
286 ;; keyboard macros to a file. | |
287 (defun events-to-keys (events &optional no-mice) | |
288 "Given a vector of event objects, returns a vector of key descriptors, | |
289 or a string (if they all fit in the ASCII range). | |
290 Optional arg NO-MICE means that button events are not allowed." | |
291 (if (and events (symbolp events)) (setq events (vector events))) | |
292 (cond ((stringp events) | |
293 events) | |
294 ((not (vectorp events)) | |
295 (signal 'wrong-type-argument (list 'vectorp events))) | |
296 ((let* ((length (length events)) | |
297 (string (make-string length 0)) | |
298 c ce | |
299 (i 0)) | |
300 (while (< i length) | |
301 (setq ce (aref events i)) | |
302 (or (eventp ce) (setq ce (character-to-event ce))) | |
303 ;; Normalize `c' to `?c' and `(control k)' to `?\C-k' | |
304 ;; By passing t for the `allow-meta' arg we could get kbd macros | |
305 ;; with meta in them to translate to the string form instead of | |
306 ;; the list/symbol form; but I expect that would cause confusion, | |
307 ;; so let's use the list/symbol form whenever there's | |
308 ;; any ambiguity. | |
309 (setq c (event-to-character ce)) | |
310 (if (and c | |
311 character-set-property | |
312 (key-press-event-p ce)) | |
313 (cond ((symbolp (event-key ce)) | |
314 (if (get (event-key ce) character-set-property) | |
315 ;; Don't use a string for `backspace' and `tab' to | |
316 ;; avoid that unpleasant little ambiguity. | |
317 (setq c nil))) | |
318 ((and (= (event-modifier-bits ce) 1) ;control | |
319 (integerp (event-key ce))) | |
320 (let* ((te (character-to-event c))) | |
321 (if (and (symbolp (event-key te)) | |
322 (get (event-key te) character-set-property)) | |
323 ;; Don't "normalize" (control i) to tab | |
324 ;; to avoid the ambiguity in the other direction | |
325 (setq c nil)) | |
326 (deallocate-event te))))) | |
327 (if c | |
328 (aset string i c) | |
329 (setq i length string nil)) | |
330 (setq i (1+ i))) | |
331 string)) | |
332 (t | |
333 (let* ((length (length events)) | |
334 (new (copy-sequence events)) | |
335 event mods key | |
336 (i 0)) | |
337 (while (< i length) | |
338 (setq event (aref events i)) | |
339 (cond ((key-press-event-p event) | |
340 (setq mods (event-modifiers event) | |
341 key (event-key event)) | |
342 (if (numberp key) | |
343 (setq key (intern (make-string 1 key)))) | |
344 (aset new i (if mods | |
345 (nconc mods (cons key nil)) | |
346 key))) | |
347 ((misc-user-event-p event) | |
348 (aset new i (list 'menu-selection | |
349 (event-function event) | |
350 (event-object event)))) | |
351 ((or (button-press-event-p event) | |
352 (button-release-event-p event)) | |
353 (if no-mice | |
354 (error | |
355 "Mouse events can't be saved in keyboard macros.")) | |
356 (setq mods (event-modifiers event) | |
357 key (intern (format "button%d%s" | |
358 (event-button event) | |
359 (if (button-release-event-p event) | |
360 "up" "")))) | |
361 (aset new i (if mods | |
362 (nconc mods (cons key nil)) | |
363 key))) | |
364 ((or (and event (symbolp event)) | |
365 (and (consp event) (symbolp (car event)))) | |
366 (aset new i event)) | |
367 (t | |
368 (signal 'wrong-type-argument (list 'eventp event)))) | |
369 (setq i (1+ i))) | |
370 new)))) | |
371 | |
372 | |
373 (defun next-key-event () | |
374 "Return the next available keyboard event." | |
375 (let (event) | |
376 (while (not (key-press-event-p (setq event (next-command-event)))) | |
377 (dispatch-event event)) | |
378 event)) | |
379 | |
380 (defun key-sequence-list-description (keys) | |
381 "Convert a key sequence KEYS to the full [(modifiers... key)...] form. | |
382 Argument KEYS can be in any form accepted by `define-key' function." | |
383 (let ((vec | |
384 (cond ((vectorp keys) | |
385 keys) | |
386 ((stringp keys) | |
387 (vconcat keys)) | |
388 (t | |
389 (vector keys)))) | |
390 (event-to-list | |
391 #'(lambda (ev) | |
392 (append (event-modifiers ev) (list (event-key ev)))))) | |
393 (mapvector | |
394 #'(lambda (key) | |
395 (cond ((key-press-event-p key) | |
396 (funcall event-to-list key)) | |
397 ((characterp key) | |
398 (funcall event-to-list (character-to-event key))) | |
399 ((listp key) | |
400 key) | |
401 (t | |
402 (list key)))) | |
403 vec))) | |
404 | |
405 | |
406 ;;; Support keyboard commands to turn on various modifiers. | |
407 | |
408 ;;; These functions -- which are not commands -- each add one modifier | |
409 ;;; to the following event. | |
410 | |
411 (defun event-apply-alt-modifier (ignore-prompt) | |
412 (event-apply-modifier 'alt)) | |
413 (defun event-apply-super-modifier (ignore-prompt) | |
414 (event-apply-modifier 'super)) | |
415 (defun event-apply-hyper-modifier (ignore-prompt) | |
416 (event-apply-modifier 'hyper)) | |
417 (defun event-apply-shift-modifier (ignore-prompt) | |
418 (event-apply-modifier 'shift)) | |
419 (defun event-apply-control-modifier (ignore-prompt) | |
420 (event-apply-modifier 'control)) | |
421 (defun event-apply-meta-modifier (ignore-prompt) | |
422 (event-apply-modifier 'meta)) | |
423 | |
424 ;;; #### `key-translate-map' is ignored for now. | |
425 (defun event-apply-modifier (symbol) | |
426 "Return the next key event, with a modifier flag applied. | |
427 SYMBOL is the name of this modifier, as a symbol. | |
428 `function-key-map' is scanned for prefix bindings." | |
429 (let (events binding) | |
430 ;; read keystrokes scanning `function-key-map' | |
431 (while (keymapp | |
432 (setq binding | |
433 (lookup-key | |
434 function-key-map | |
435 (vconcat | |
436 (setq events | |
437 (append events (list (next-key-event))))))))) | |
438 (if binding ; found a binding | |
439 (progn | |
440 ;; allow for several modifiers | |
441 (if (and (symbolp binding) (fboundp binding)) | |
442 (setq binding (funcall binding nil))) | |
443 (setq events (append binding nil)) | |
444 ;; put remaining keystrokes back into input queue | |
445 (setq unread-command-events | |
446 (mapcar 'character-to-event (cdr events)))) | |
447 (setq unread-command-events (cdr events))) | |
448 ;; add a modifier SYMBOL to the first keystroke or event | |
449 (vector | |
450 (append (list symbol) | |
451 (delq symbol | |
452 (aref (key-sequence-list-description (car events)) 0)))))) | |
453 | |
454 (defun synthesize-keysym (ignore-prompt) | |
455 "Read a sequence of keys, and returned the corresponding key symbol. | |
456 The characters must be from the [-_a-zA-Z0-9]. Reading is terminated | |
457 by RET (which is discarded)." | |
458 (let ((continuep t) | |
459 event char list) | |
460 (while continuep | |
461 (setq event (next-key-event)) | |
462 (cond ((and (setq char (event-to-character event)) | |
463 (or (memq char '(?- ?_)) | |
464 (eq ?w (char-syntax char (standard-syntax-table))))) | |
465 ;; Advance a character. | |
466 (push char list)) | |
467 ((or (memq char '(?\r ?\n)) | |
468 (memq (event-key event) '(return newline))) | |
469 ;; Legal termination. | |
470 (setq continuep nil)) | |
471 (char | |
472 ;; Illegal character. | |
473 (error "Illegal character in keysym: %c" char)) | |
474 (t | |
475 ;; Illegal event. | |
476 (error "Event has no character equivalent: %s" event)))) | |
477 (vector (intern (concat "" (nreverse list)))))) | |
478 | |
479 ;; This looks dirty. The following code should maybe go to another | |
480 ;; file, and `create-console-hook' should maybe default to nil. | |
481 (add-hook | |
482 'create-console-hook | |
483 #'(lambda (console) | |
484 (letf (((selected-console) console)) | |
485 (define-key function-key-map [?\C-x ?@ ?h] 'event-apply-hyper-modifier) | |
486 (define-key function-key-map [?\C-x ?@ ?s] 'event-apply-super-modifier) | |
487 (define-key function-key-map [?\C-x ?@ ?m] 'event-apply-meta-modifier) | |
488 (define-key function-key-map [?\C-x ?@ ?S] 'event-apply-shift-modifier) | |
489 (define-key function-key-map [?\C-x ?@ ?c] 'event-apply-control-modifier) | |
490 (define-key function-key-map [?\C-x ?@ ?a] 'event-apply-alt-modifier) | |
491 (define-key function-key-map [?\C-x ?@ ?k] 'synthesize-keysym)))) | |
492 | |
493 ;;; keymap.el ends here |