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