aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorJim Blandy1992-09-23 12:46:52 +0000
committerJim Blandy1992-09-23 12:46:52 +0000
commitf5b79c1c36da2b7d5b61920a074798a6a542b613 (patch)
treec2eb2608fecc96bcfe2afda579a814f204dff5f1 /src/keymap.c
parent230a4cbd80a0423b12177a568f523da4acb70ada (diff)
downloademacs-f5b79c1c36da2b7d5b61920a074798a6a542b613.tar.gz
emacs-f5b79c1c36da2b7d5b61920a074798a6a542b613.zip
* keymap.c (DENSE_TABLE_SIZE): Doc fix.
(keymap_table): Function removed; this function exists only to support an incorrect understanding of the format of keymaps. (access_keymap, store_in_keymap, Fcopy_keymap, Faccessible_keymaps): Correctly handle vectors at any point in the keymap; don't assume it must be at the front. (describe_map): Instead of calling describe_vector on the vector in the cadr of the keymap (if present) and then calling describe_alist to do the rest, just call describe_map_2. (describe_alist): Renamed to describe_map_2; call describe_vector when we encounter a vector in the list. * keymap.c (access_keymap, store_in_keymap): Clarify error message for non-ASCII characters. * keymap.c (access_keymap): Return the binding of Qt as the binding for all unbound characters.
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c418
1 files changed, 204 insertions, 214 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 21176546bec..373528655ba 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -28,9 +28,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
28 28
29#define min(a, b) ((a) < (b) ? (a) : (b)) 29#define min(a, b) ((a) < (b) ? (a) : (b))
30 30
31/* Dense keymaps look like (keymap VECTOR . ALIST), where VECTOR is a 31/* The number of elements in keymap vectors. */
32 128-element vector used to look up bindings for ASCII characters,
33 and ALIST is an assoc list for looking up symbols. */
34#define DENSE_TABLE_SIZE (0200) 32#define DENSE_TABLE_SIZE (0200)
35 33
36/* Actually allocate storage for these variables */ 34/* Actually allocate storage for these variables */
@@ -84,7 +82,7 @@ void describe_map_tree ();
84static Lisp_Object describe_buffer_bindings (); 82static Lisp_Object describe_buffer_bindings ();
85static void describe_command (); 83static void describe_command ();
86static void describe_map (); 84static void describe_map ();
87static void describe_alist (); 85static void describe_map_2 ();
88 86
89/* Keymap object support - constructors and predicates. */ 87/* Keymap object support - constructors and predicates. */
90 88
@@ -190,6 +188,7 @@ get_keymap_1 (object, error)
190 tem = indirect_function (object); 188 tem = indirect_function (object);
191 if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap)) 189 if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap))
192 return tem; 190 return tem;
191
193 if (error) 192 if (error)
194 wrong_type_argument (Qkeymapp, object); 193 wrong_type_argument (Qkeymapp, object);
195 else 194 else
@@ -204,27 +203,12 @@ get_keymap (object)
204} 203}
205 204
206 205
207/* If KEYMAP is a dense keymap, return the vector from its cadr.
208 Otherwise, return nil. */
209
210Lisp_Object
211keymap_table (keymap)
212 Lisp_Object keymap;
213{
214 Lisp_Object cadr;
215
216 if (CONSP (XCONS (keymap)->cdr)
217 && XTYPE (cadr = XCONS (XCONS (keymap)->cdr)->car) == Lisp_Vector
218 && XVECTOR (cadr)->size == DENSE_TABLE_SIZE)
219 return cadr;
220 else
221 return Qnil;
222}
223
224
225/* Look up IDX in MAP. IDX may be any sort of event. 206/* Look up IDX in MAP. IDX may be any sort of event.
226 Note that this does only one level of lookup; IDX must 207
227 be a single event, not a sequence. */ 208 Note that this does only one level of lookup; IDX must be a single
209 event, not a sequence. If IDX is unbound in MAP but MAP has a
210 binding for Qt, then Qt's binding is returned; this makes bindings
211 of Qt act like "default" bindings. */
228 212
229Lisp_Object 213Lisp_Object
230access_keymap (map, idx) 214access_keymap (map, idx)
@@ -239,26 +223,39 @@ access_keymap (map, idx)
239 223
240 if (XTYPE (idx) == Lisp_Int 224 if (XTYPE (idx) == Lisp_Int
241 && (XINT (idx) < 0 || XINT (idx) >= DENSE_TABLE_SIZE)) 225 && (XINT (idx) < 0 || XINT (idx) >= DENSE_TABLE_SIZE))
242 error ("Command key is not an ASCII character"); 226 error ("only ASCII characters may used as keymap indices");
243 227
244 { 228 /* If idx is a symbol, it might have modifiers, which need to
245 Lisp_Object table = keymap_table (map); 229 be put in the canonical order. */
230 else if (XTYPE (idx) == Lisp_Symbol)
231 idx = reorder_modifiers (idx);
246 232
247 /* A dense keymap indexed by a character? */ 233 {
248 if (XTYPE (idx) == Lisp_Int 234 Lisp_Object tail;
249 && ! NILP (table)) 235 Lisp_Object t_binding = Qnil;
250 return XVECTOR (table)->contents[XFASTINT (idx)];
251 236
252 /* This lookup will not involve a vector reference. */ 237 for (tail = map; CONSP (tail); tail = XCONS (tail)->cdr)
253 else
254 { 238 {
255 /* If idx is a symbol, it might have modifiers, which need to 239 Lisp_Object binding = XCONS (tail)->car;
256 be put in the canonical order. */ 240
257 if (XTYPE (idx) == Lisp_Symbol) 241 switch (XTYPE (binding))
258 idx = reorder_modifiers (idx); 242 {
259 243 case Lisp_Cons:
260 return Fcdr (Fassq (idx, map)); 244 if (EQ (XCONS (binding)->car, idx))
245 return XCONS (binding)->cdr;
246 if (EQ (XCONS (binding)->car, Qt))
247 t_binding = XCONS (binding)->cdr;
248 break;
249
250 case Lisp_Vector:
251 if (XVECTOR (binding)->size == DENSE_TABLE_SIZE
252 && XTYPE (idx) == Lisp_Int)
253 return XVECTOR (binding)->contents[XINT (idx)];
254 break;
255 }
261 } 256 }
257
258 return t_binding;
262 } 259 }
263} 260}
264 261
@@ -313,6 +310,10 @@ store_in_keymap (keymap, idx, def)
313 register Lisp_Object idx; 310 register Lisp_Object idx;
314 register Lisp_Object def; 311 register Lisp_Object def;
315{ 312{
313 if (XTYPE (keymap) != Lisp_Cons
314 || ! EQ (XCONS (keymap)->car, Qkeymap))
315 error ("attempt to define a key in a non-keymap");
316
316 /* If idx is a list (some sort of mouse click, perhaps?), 317 /* If idx is a list (some sort of mouse click, perhaps?),
317 the index we want to use is the car of the list, which 318 the index we want to use is the car of the list, which
318 ought to be a symbol. */ 319 ought to be a symbol. */
@@ -321,44 +322,71 @@ store_in_keymap (keymap, idx, def)
321 322
322 if (XTYPE (idx) == Lisp_Int 323 if (XTYPE (idx) == Lisp_Int
323 && (XINT (idx) < 0 || XINT (idx) >= DENSE_TABLE_SIZE)) 324 && (XINT (idx) < 0 || XINT (idx) >= DENSE_TABLE_SIZE))
324 error ("Command key is a character outside of the ASCII set."); 325 error ("only ASCII characters may be used as keymap indices");
325 326
327 /* If idx is a symbol, it might have modifiers, which need to
328 be put in the canonical order. */
329 else if (XTYPE (idx) == Lisp_Symbol)
330 idx = reorder_modifiers (idx);
331
332
333 /* Scan the keymap for a binding of idx. */
326 { 334 {
327 Lisp_Object table = keymap_table (keymap); 335 Lisp_Object tail;
328 336
329 /* A dense keymap indexed by a character? */ 337 /* The cons after which we should insert new bindings. If the
330 if (XTYPE (idx) == Lisp_Int && !NILP (table)) 338 keymap has a table element, we record its position here, so new
331 XVECTOR (table)->contents[XFASTINT (idx)] = def; 339 bindings will go after it; this way, the table will stay
340 towards the front of the alist and character lookups in dense
341 keymaps will remain fast. Otherwise, this just points at the
342 front of the keymap. */
343 Lisp_Object insertion_point = keymap;
332 344
333 /* Must be a sparse keymap, or a dense keymap indexed by a symbol. */ 345 for (tail = XCONS (keymap)->cdr; CONSP (tail); tail = XCONS (tail)->cdr)
334 else
335 { 346 {
336 /* Point to the pointer to the start of the assoc-list part 347 Lisp_Object elt = XCONS (tail)->car;
337 of the keymap. */ 348
338 register Lisp_Object *assoc_head 349 switch (XTYPE (elt))
339 = (NILP (table) 350 {
340 ? & XCONS (keymap)->cdr 351 case Lisp_Vector:
341 : & XCONS (XCONS (keymap)->cdr)->cdr); 352 if (XTYPE (idx) == Lisp_Int)
342 register Lisp_Object defining_pair; 353 {
343 354 XVECTOR (elt)->contents[XFASTINT (idx)] = def;
344 /* If idx is a symbol, it might have modifiers, which need to 355 return def;
345 be put in the canonical order. */ 356 }
346 if (XTYPE (idx) == Lisp_Symbol) 357 insertion_point = tail;
347 idx = reorder_modifiers (idx); 358 break;
348 359
349 /* Point to the pair where idx is bound, if any. */ 360 case Lisp_Cons:
350 defining_pair = Fassq (idx, *assoc_head); 361 if (EQ (idx, XCONS (elt)->car))
351 362 {
352 if (NILP (defining_pair)) 363 XCONS (elt)->cdr = def;
353 *assoc_head = Fcons (Fcons (idx, def), *assoc_head); 364 return def;
354 else 365 }
355 Fsetcdr (defining_pair, def); 366 break;
367
368 case Lisp_Symbol:
369 /* If we find a 'keymap' symbol in the spine of KEYMAP,
370 then we must have found the start of a second keymap
371 being used as the tail of KEYMAP, and a binding for IDX
372 should be inserted before it. */
373 if (EQ (elt, Qkeymap))
374 goto keymap_end;
375 break;
376 }
356 } 377 }
357 }
358 378
379 keymap_end:
380 /* We have scanned the entire keymap, and not found a binding for
381 IDX. Let's add one. */
382 XCONS (insertion_point)->cdr =
383 Fcons (Fcons (idx, def), XCONS (insertion_point)->cdr);
384 }
385
359 return def; 386 return def;
360} 387}
361 388
389
362DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0, 390DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0,
363 "Return a copy of the keymap KEYMAP.\n\ 391 "Return a copy of the keymap KEYMAP.\n\
364The copy starts out with the same definitions of KEYMAP,\n\ 392The copy starts out with the same definitions of KEYMAP,\n\
@@ -372,43 +400,29 @@ is not copied.")
372 register Lisp_Object copy, tail; 400 register Lisp_Object copy, tail;
373 401
374 copy = Fcopy_alist (get_keymap (keymap)); 402 copy = Fcopy_alist (get_keymap (keymap));
375 tail = XCONS (copy)->cdr;
376 403
377 /* If this is a dense keymap, copy the vector. */ 404 for (tail = copy; CONSP (tail); tail = XCONS (tail)->cdr)
378 if (CONSP (tail))
379 { 405 {
380 register Lisp_Object table = XCONS (tail)->car; 406 Lisp_Object elt = XCONS (tail)->car;
381 407
382 if (XTYPE (table) == Lisp_Vector 408 if (XTYPE (elt) == Lisp_Vector
383 && XVECTOR (table)->size == DENSE_TABLE_SIZE) 409 && XVECTOR (elt)->size == DENSE_TABLE_SIZE)
384 { 410 {
385 register int i; 411 int i;
386 412
387 table = Fcopy_sequence (table); 413 elt = Fcopy_sequence (elt);
414 XCONS (tail)->car = elt;
388 415
389 for (i = 0; i < DENSE_TABLE_SIZE; i++) 416 for (i = 0; i < DENSE_TABLE_SIZE; i++)
390 if (XTYPE (XVECTOR (copy)->contents[i]) != Lisp_Symbol) 417 if (XTYPE (XVECTOR (elt)->contents[i]) != Lisp_Symbol
391 if (! NILP (Fkeymapp (XVECTOR (table)->contents[i]))) 418 && Fkeymapp (XVECTOR (elt)->contents[i]))
392 XVECTOR (table)->contents[i] 419 XVECTOR (elt)->contents[i] =
393 = Fcopy_keymap (XVECTOR (table)->contents[i]); 420 Fcopy_keymap (XVECTOR (elt)->contents[i]);
394 XCONS (tail)->car = table;
395
396 tail = XCONS (tail)->cdr;
397 } 421 }
398 } 422 else if (CONSP (elt)
399 423 && XTYPE (XCONS (elt)->cdr) != Lisp_Symbol
400 /* Copy the alist portion of the keymap. */ 424 && ! NILP (Fkeymapp (XCONS (elt)->cdr)))
401 while (CONSP (tail))
402 {
403 register Lisp_Object elt;
404
405 elt = XCONS (tail)->car;
406 if (CONSP (elt)
407 && XTYPE (XCONS (elt)->cdr) != Lisp_Symbol
408 && ! NILP (Fkeymapp (XCONS (elt)->cdr)))
409 XCONS (elt)->cdr = Fcopy_keymap (XCONS (elt)->cdr); 425 XCONS (elt)->cdr = Fcopy_keymap (XCONS (elt)->cdr);
410
411 tail = XCONS (tail)->cdr;
412 } 426 }
413 427
414 return copy; 428 return copy;
@@ -897,7 +911,6 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
897 Lisp_Object maps, tail; 911 Lisp_Object maps, tail;
898 912
899 maps = Fcons (Fcons (build_string (""), get_keymap (startmap)), Qnil); 913 maps = Fcons (Fcons (build_string (""), get_keymap (startmap)), Qnil);
900 tail = maps;
901 914
902 /* For each map in the list maps, 915 /* For each map in the list maps,
903 look at any other maps it points to, 916 look at any other maps it points to,
@@ -906,7 +919,7 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
906 This is a breadth-first traversal, where tail is the queue of 919 This is a breadth-first traversal, where tail is the queue of
907 nodes, and maps accumulates a list of all nodes visited. */ 920 nodes, and maps accumulates a list of all nodes visited. */
908 921
909 while (!NILP (tail)) 922 for (tail = maps; CONSP (tail); tail = XCONS (tail)->cdr)
910 { 923 {
911 register Lisp_Object thisseq = Fcar (Fcar (tail)); 924 register Lisp_Object thisseq = Fcar (Fcar (tail));
912 register Lisp_Object thismap = Fcdr (Fcar (tail)); 925 register Lisp_Object thismap = Fcdr (Fcar (tail));
@@ -916,14 +929,13 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
916 int is_metized = (XINT (last) >= 0 929 int is_metized = (XINT (last) >= 0
917 && EQ (Faref (thisseq, last), meta_prefix_char)); 930 && EQ (Faref (thisseq, last), meta_prefix_char));
918 931
919 /* Skip the 'keymap element of the list. */ 932 for (; CONSP (thismap); thismap = XCONS (thismap)->cdr)
920 thismap = Fcdr (thismap);
921
922 if (CONSP (thismap))
923 { 933 {
924 register Lisp_Object table = XCONS (thismap)->car; 934 Lisp_Object elt = XCONS (thismap)->car;
935
936 QUIT;
925 937
926 if (XTYPE (table) == Lisp_Vector) 938 if (XTYPE (elt) == Lisp_Vector)
927 { 939 {
928 register int i; 940 register int i;
929 941
@@ -933,7 +945,7 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
933 register Lisp_Object tem; 945 register Lisp_Object tem;
934 register Lisp_Object cmd; 946 register Lisp_Object cmd;
935 947
936 cmd = get_keyelt (XVECTOR (table)->contents[i]); 948 cmd = get_keyelt (XVECTOR (elt)->contents[i]);
937 if (NILP (cmd)) continue; 949 if (NILP (cmd)) continue;
938 tem = Fkeymapp (cmd); 950 tem = Fkeymapp (cmd);
939 if (!NILP (tem)) 951 if (!NILP (tem))
@@ -946,7 +958,8 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
946 /* If the last key in thisseq is meta-prefix-char, 958 /* If the last key in thisseq is meta-prefix-char,
947 turn it into a meta-ized keystroke. We know 959 turn it into a meta-ized keystroke. We know
948 that the event we're about to append is an 960 that the event we're about to append is an
949 ascii keystroke. */ 961 ascii keystroke since we're processing a
962 keymap table. */
950 if (is_metized) 963 if (is_metized)
951 { 964 {
952 tem = Fcopy_sequence (thisseq); 965 tem = Fcopy_sequence (thisseq);
@@ -966,20 +979,8 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
966 } 979 }
967 } 980 }
968 } 981 }
969 982 }
970 /* Once finished with the lookup elements of the dense 983 else if (CONSP (elt))
971 keymap, go on to scan its assoc list. */
972 thismap = XCONS (thismap)->cdr;
973 }
974 }
975
976 /* The rest is an alist. Scan all the alist elements. */
977 while (CONSP (thismap))
978 {
979 Lisp_Object elt = XCONS (thismap)->car;
980
981 /* Ignore elements that are not conses. */
982 if (CONSP (elt))
983 { 984 {
984 register Lisp_Object cmd = get_keyelt (XCONS (elt)->cdr); 985 register Lisp_Object cmd = get_keyelt (XCONS (elt)->cdr);
985 register Lisp_Object tem; 986 register Lisp_Object tem;
@@ -1017,11 +1018,7 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
1017 } 1018 }
1018 } 1019 }
1019 } 1020 }
1020
1021 thismap = XCONS (thismap)->cdr;
1022 } 1021 }
1023
1024 tail = Fcdr (tail);
1025 } 1022 }
1026 1023
1027 return maps; 1024 return maps;
@@ -1206,10 +1203,14 @@ indirect definition itself.")
1206 1203
1207 for (; !NILP (maps); maps = Fcdr (maps)) 1204 for (; !NILP (maps); maps = Fcdr (maps))
1208 { 1205 {
1209 register this = Fcar (Fcar (maps)); /* Key sequence to reach map */ 1206 /* Key sequence to reach map */
1210 register map = Fcdr (Fcar (maps)); /* The map that it reaches */ 1207 register Lisp_Object this = Fcar (Fcar (maps));
1211 register dense_alist; 1208
1212 register int i = 0; 1209 /* The map that it reaches */
1210 register Lisp_Object map = Fcdr (Fcar (maps));
1211
1212 /* If Fcar (map) is a VECTOR, the current element within that vector. */
1213 int i = 0;
1213 1214
1214 /* In order to fold [META-PREFIX-CHAR CHAR] sequences into 1215 /* In order to fold [META-PREFIX-CHAR CHAR] sequences into
1215 [M-CHAR] sequences, check if last character of the sequence 1216 [M-CHAR] sequences, check if last character of the sequence
@@ -1217,54 +1218,50 @@ indirect definition itself.")
1217 Lisp_Object last = make_number (XINT (Flength (this)) - 1); 1218 Lisp_Object last = make_number (XINT (Flength (this)) - 1);
1218 int last_is_meta = (XINT (last) >= 0 1219 int last_is_meta = (XINT (last) >= 0
1219 && EQ (Faref (this, last), meta_prefix_char)); 1220 && EQ (Faref (this, last), meta_prefix_char));
1220
1221 /* Skip the 'keymap element of the list. */
1222 map = Fcdr (map);
1223
1224 /* If the keymap is sparse, map traverses the alist to the end.
1225 1221
1226 If the keymap is dense, we set map to the vector and 1222 while (CONSP (map))
1227 dense_alist to the assoc-list portion of the keymap. When we
1228 are finished dealing with the vector portion, we set map to
1229 dense_alist, and handle the rest like a sparse keymap. */
1230 if (XTYPE (XCONS (map)->car) == Lisp_Vector)
1231 { 1223 {
1232 dense_alist = XCONS (map)->cdr; 1224 /* Because the code we want to run on each binding is rather
1233 map = XCONS (map)->car; 1225 large, we don't want to have two separate loop bodies for
1234 } 1226 sparse keymap bindings and tables; we want to iterate one
1235 1227 loop body over both keymap and vector bindings.
1236 while (1) 1228
1237 { 1229 For this reason, if Fcar (map) is a vector, we don't
1238 register Lisp_Object key, binding, sequence; 1230 advance map to the next element until i indicates that we
1231 have finished off the vector. */
1239 1232
1240 QUIT; 1233 Lisp_Object elt = XCONS (map)->car;
1241 if (XTYPE (map) == Lisp_Vector) 1234 Lisp_Object key, binding, sequence;
1235
1236 /* Set key and binding to the current key and binding, and
1237 advance map and i to the next binding. */
1238 if (XTYPE (elt) == Lisp_Vector)
1242 { 1239 {
1243 /* In a vector, look at each element. */ 1240 /* In a vector, look at each element. */
1244 binding = XVECTOR (map)->contents[i]; 1241 binding = XVECTOR (elt)->contents[i];
1245 XFASTINT (key) = i; 1242 XFASTINT (key) = i;
1246 i++; 1243 i++;
1247 1244
1248 /* If we've just finished scanning a vector, switch map to 1245 /* If we've just finished scanning a vector, advance map
1249 the assoc-list at the end of the vector. */ 1246 to the next element, and reset i in anticipation of the
1247 next vector we may find. */
1250 if (i >= DENSE_TABLE_SIZE) 1248 if (i >= DENSE_TABLE_SIZE)
1251 map = dense_alist;
1252 }
1253 else if (CONSP (map))
1254 {
1255 /* In an alist, ignore elements that aren't conses. */
1256 if (! CONSP (XCONS (map)->car))
1257 { 1249 {
1258 /* Ignore other elements. */ 1250 map = XCONS (map)->cdr;
1259 map = Fcdr (map); 1251 i = 0;
1260 continue;
1261 } 1252 }
1262 binding = Fcdr (Fcar (map)); 1253 }
1254 else if (CONSP (elt))
1255 {
1263 key = Fcar (Fcar (map)); 1256 key = Fcar (Fcar (map));
1264 map = Fcdr (map); 1257 binding = Fcdr (Fcar (map));
1258
1259 map = XCONS (map)->cdr;
1265 } 1260 }
1266 else 1261 else
1267 break; 1262 /* We want to ignore keymap elements that are neither
1263 vectors nor conses. */
1264 continue;
1268 1265
1269 /* Search through indirections unless that's not wanted. */ 1266 /* Search through indirections unless that's not wanted. */
1270 if (NILP (noindirect)) 1267 if (NILP (noindirect))
@@ -1575,28 +1572,14 @@ describe_map (map, keys, partial, shadow)
1575 else 1572 else
1576 keysdesc = Qnil; 1573 keysdesc = Qnil;
1577 1574
1578 /* Skip the 'keymap element of the list. */ 1575 describe_map_2 (map, keysdesc, describe_command, partial, shadow);
1579 map = Fcdr (map);
1580
1581 /* If this is a dense keymap, take care of the table. */
1582 if (CONSP (map)
1583 && XTYPE (XCONS (map)->car) == Lisp_Vector)
1584 {
1585 describe_vector (XCONS (map)->car, keysdesc, describe_command,
1586 partial, shadow);
1587 map = XCONS (map)->cdr;
1588 }
1589
1590 /* Now map is an alist. */
1591 describe_alist (map, keysdesc, describe_command, partial, shadow);
1592} 1576}
1593 1577
1594/* Insert a description of ALIST into the current buffer. 1578/* Insert a description of KEYMAP into the current buffer. */
1595 Note that ALIST is just a plain association list, not a keymap. */
1596 1579
1597static void 1580static void
1598describe_alist (alist, elt_prefix, elt_describer, partial, shadow) 1581describe_map_2 (keymap, elt_prefix, elt_describer, partial, shadow)
1599 register Lisp_Object alist; 1582 register Lisp_Object keymap;
1600 Lisp_Object elt_prefix; 1583 Lisp_Object elt_prefix;
1601 int (*elt_describer) (); 1584 int (*elt_describer) ();
1602 int partial; 1585 int partial;
@@ -1613,56 +1596,63 @@ describe_alist (alist, elt_prefix, elt_describer, partial, shadow)
1613 suppress = intern ("suppress-keymap"); 1596 suppress = intern ("suppress-keymap");
1614 1597
1615 /* This vector gets used to present single keys to Flookup_key. Since 1598 /* This vector gets used to present single keys to Flookup_key. Since
1616 that is done once per alist element, we don't want to cons up a 1599 that is done once per keymap element, we don't want to cons up a
1617 fresh vector every time. */ 1600 fresh vector every time. */
1618 kludge = Fmake_vector (make_number (1), Qnil); 1601 kludge = Fmake_vector (make_number (1), Qnil);
1619 1602
1620 GCPRO3 (elt_prefix, tem2, kludge); 1603 GCPRO3 (elt_prefix, tem2, kludge);
1621 1604
1622 for (; CONSP (alist); alist = Fcdr (alist)) 1605 for (; CONSP (keymap); keymap = Fcdr (keymap))
1623 { 1606 {
1624 QUIT; 1607 QUIT;
1625 tem1 = Fcar_safe (Fcar (alist));
1626 tem2 = get_keyelt (Fcdr_safe (Fcar (alist)));
1627 1608
1628 /* Don't show undefined commands or suppressed commands. */ 1609 if (XTYPE (XCONS (keymap)->car) == Lisp_Vector)
1629 if (NILP (tem2)) continue; 1610 describe_vector (XCONS (keymap)->car,
1630 if (XTYPE (tem2) == Lisp_Symbol && partial) 1611 elt_prefix, elt_describer, partial, shadow);
1612 else
1631 { 1613 {
1632 this = Fget (tem2, suppress); 1614 tem1 = Fcar_safe (Fcar (keymap));
1633 if (!NILP (this)) 1615 tem2 = get_keyelt (Fcdr_safe (Fcar (keymap)));
1634 continue;
1635 }
1636 1616
1637 /* Don't show a command that isn't really visible 1617 /* Don't show undefined commands or suppressed commands. */
1638 because a local definition of the same key shadows it. */ 1618 if (NILP (tem2)) continue;
1619 if (XTYPE (tem2) == Lisp_Symbol && partial)
1620 {
1621 this = Fget (tem2, suppress);
1622 if (!NILP (this))
1623 continue;
1624 }
1639 1625
1640 if (!NILP (shadow)) 1626 /* Don't show a command that isn't really visible
1641 { 1627 because a local definition of the same key shadows it. */
1642 Lisp_Object tem;
1643 1628
1644 XVECTOR (kludge)->contents[0] = tem1; 1629 if (!NILP (shadow))
1645 tem = Flookup_key (shadow, kludge); 1630 {
1646 if (!NILP (tem)) continue; 1631 Lisp_Object tem;
1647 }
1648 1632
1649 if (first) 1633 XVECTOR (kludge)->contents[0] = tem1;
1650 { 1634 tem = Flookup_key (shadow, kludge);
1651 insert ("\n", 1); 1635 if (!NILP (tem)) continue;
1652 first = 0; 1636 }
1653 }
1654 1637
1655 if (!NILP (elt_prefix)) 1638 if (first)
1656 insert1 (elt_prefix); 1639 {
1640 insert ("\n", 1);
1641 first = 0;
1642 }
1657 1643
1658 /* THIS gets the string to describe the character TEM1. */ 1644 if (!NILP (elt_prefix))
1659 this = Fsingle_key_description (tem1); 1645 insert1 (elt_prefix);
1660 insert1 (this);
1661 1646
1662 /* Print a description of the definition of this character. 1647 /* THIS gets the string to describe the character TEM1. */
1663 elt_describer will take care of spacing out far enough 1648 this = Fsingle_key_description (tem1);
1664 for alignment purposes. */ 1649 insert1 (this);
1665 (*elt_describer) (tem2); 1650
1651 /* Print a description of the definition of this character.
1652 elt_describer will take care of spacing out far enough
1653 for alignment purposes. */
1654 (*elt_describer) (tem2);
1655 }
1666 } 1656 }
1667 1657
1668 UNGCPRO; 1658 UNGCPRO;