aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorJim Blandy1992-10-31 05:24:47 +0000
committerJim Blandy1992-10-31 05:24:47 +0000
commitd09b20248ddfb6ffc73afb1ab51485f3d12d2c68 (patch)
tree619edda1474c4bf2c030254a84e1080bee549caf /src/keymap.c
parent5bb46ecf6c71724e39f2cd482d9018a354966533 (diff)
downloademacs-d09b20248ddfb6ffc73afb1ab51485f3d12d2c68.tar.gz
emacs-d09b20248ddfb6ffc73afb1ab51485f3d12d2c68.zip
* keymap.c (Fdefine_key, Flookup_key, describe_map): Don't assume
that Flength returns an integer. * keymap.c: Deal with autoloaded keymaps properly. (get_keymap_1): Renamed to inner_get_keymap; made static. New argument AUTOLOAD says to pursue autoloads if non-zero. (Fkeymapp, get_keymap, get_keyelt, Flookup_key): Ask get_keymap_1 not to perform autoloads. (Fdefine_key): Ask get_keymap_1 to perform autoloads. Since autoloading may GC, remember that we have to GCPRO our local variables now. (Fminor_mode_key_binding): Call get_keymap instead of calling get_keymap_1 with equivalent arguments.
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/src/keymap.c b/src/keymap.c
index a4105aeada1..6275fa990e2 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -175,34 +175,65 @@ VECTOR is a 128-element vector of bindings for ASCII characters.")
175 (object) 175 (object)
176 Lisp_Object object; 176 Lisp_Object object;
177{ 177{
178 return (NILP (get_keymap_1 (object, 0)) ? Qnil : Qt); 178 return (NILP (get_keymap_1 (object, 0, 0)) ? Qnil : Qt);
179} 179}
180 180
181/* Check that OBJECT is a keymap (after dereferencing through any 181/* Check that OBJECT is a keymap (after dereferencing through any
182 symbols). If it is, return it; otherwise, return nil, or signal an 182 symbols). If it is, return it.
183 error if ERROR != 0. */ 183
184 If AUTOLOAD is non-zero and OBJECT is a symbol whose function value
185 is an autoload form, do the autoload and try again.
186
187 ERROR controls how we respond if OBJECT isn't a keymap.
188 If ERROR is non-zero, signal an error; otherwise, just return Qnil.
189
190 Note that most of the time, we don't want to pursue autoloads.
191 Functions like Faccessible_keymaps which scan entire keymap trees
192 shouldn't load every autoloaded keymap. I'm not sure about this,
193 but it seems to me that only read_key_sequence, Flookup_key, and
194 Fdefine_key should cause keymaps to be autoloaded. */
195
184Lisp_Object 196Lisp_Object
185get_keymap_1 (object, error) 197get_keymap_1 (object, error, autoload)
186 Lisp_Object object; 198 Lisp_Object object;
187 int error; 199 int error, autoload;
188{ 200{
189 register Lisp_Object tem; 201 Lisp_Object tem;
190 202
203 autoload_retry:
191 tem = indirect_function (object); 204 tem = indirect_function (object);
192 if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap)) 205 if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap))
193 return tem; 206 return tem;
194 207
208 /* Should we do an autoload? */
209 if (autoload
210 && XTYPE (object) == Lisp_Symbol
211 && CONSP (tem)
212 && EQ (XCONS (tem)->car, Qautoload))
213 {
214 struct gcpro gcpro1, gcpro2;
215
216 GCPRO2 (tem, object)
217 do_autoload (tem, object);
218 UNGCPRO;
219
220 goto autoload_retry;
221 }
222
195 if (error) 223 if (error)
196 wrong_type_argument (Qkeymapp, object); 224 wrong_type_argument (Qkeymapp, object);
197 else 225 else
198 return Qnil; 226 return Qnil;
199} 227}
200 228
229
230/* Follow any symbol chaining, and return the keymap denoted by OBJECT.
231 If OBJECT doesn't denote a keymap at all, signal an error. */
201Lisp_Object 232Lisp_Object
202get_keymap (object) 233get_keymap (object)
203 Lisp_Object object; 234 Lisp_Object object;
204{ 235{
205 return get_keymap_1 (object, 1); 236 return get_keymap_1 (object, 0, 0);
206} 237}
207 238
208 239
@@ -285,7 +316,7 @@ get_keyelt (object)
285 register Lisp_Object map, tem; 316 register Lisp_Object map, tem;
286 317
287 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ 318 /* If the contents are (KEYMAP . ELEMENT), go indirect. */
288 map = get_keymap_1 (Fcar_safe (object), 0); 319 map = get_keymap_1 (Fcar_safe (object), 0, 0);
289 tem = Fkeymapp (map); 320 tem = Fkeymapp (map);
290 if (!NILP (tem)) 321 if (!NILP (tem))
291 object = access_keymap (map, Fcdr (object), 0); 322 object = access_keymap (map, Fcdr (object), 0);
@@ -459,7 +490,7 @@ DEF is anything that can be a key's definition:\n\
459If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at\n\ 490If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at\n\
460the front of KEYMAP.") 491the front of KEYMAP.")
461 (keymap, key, def) 492 (keymap, key, def)
462 register Lisp_Object keymap; 493 Lisp_Object keymap;
463 Lisp_Object key; 494 Lisp_Object key;
464 Lisp_Object def; 495 Lisp_Object def;
465{ 496{
@@ -469,6 +500,7 @@ the front of KEYMAP.")
469 register Lisp_Object cmd; 500 register Lisp_Object cmd;
470 int metized = 0; 501 int metized = 0;
471 int length; 502 int length;
503 struct gcpro gcpro1, gcpro2, gcpro3;
472 504
473 keymap = get_keymap (keymap); 505 keymap = get_keymap (keymap);
474 506
@@ -476,10 +508,12 @@ the front of KEYMAP.")
476 && XTYPE (key) != Lisp_String) 508 && XTYPE (key) != Lisp_String)
477 key = wrong_type_argument (Qarrayp, key); 509 key = wrong_type_argument (Qarrayp, key);
478 510
479 length = Flength (key); 511 length = XFASTINT (Flength (key));
480 if (length == 0) 512 if (length == 0)
481 return Qnil; 513 return Qnil;
482 514
515 GCPRO3 (keymap, key, def);
516
483 idx = 0; 517 idx = 0;
484 while (1) 518 while (1)
485 { 519 {
@@ -502,7 +536,7 @@ the front of KEYMAP.")
502 } 536 }
503 537
504 if (idx == length) 538 if (idx == length)
505 return store_in_keymap (keymap, c, def); 539 RETURN_UNGCPRO (store_in_keymap (keymap, c, def));
506 540
507 cmd = get_keyelt (access_keymap (keymap, c, 0)); 541 cmd = get_keyelt (access_keymap (keymap, c, 0));
508 542
@@ -512,12 +546,10 @@ the front of KEYMAP.")
512 store_in_keymap (keymap, c, cmd); 546 store_in_keymap (keymap, c, cmd);
513 } 547 }
514 548
515 tem = Fkeymapp (cmd); 549 keymap = get_keymap_1 (cmd, 0, 1);
516 if (NILP (tem)) 550 if (NILP (keymap))
517 error ("Key sequence %s uses invalid prefix characters", 551 error ("Key sequence %s uses invalid prefix characters",
518 XSTRING (key)->data); 552 XSTRING (key)->data);
519
520 keymap = get_keymap (cmd);
521 } 553 }
522} 554}
523 555
@@ -548,7 +580,7 @@ it takes to reach a non-prefix command.")
548 && XTYPE (key) != Lisp_String) 580 && XTYPE (key) != Lisp_String)
549 key = wrong_type_argument (Qarrayp, key); 581 key = wrong_type_argument (Qarrayp, key);
550 582
551 length = Flength (key); 583 length = XFASTINT (Flength (key));
552 if (length == 0) 584 if (length == 0)
553 return keymap; 585 return keymap;
554 586
@@ -577,11 +609,10 @@ it takes to reach a non-prefix command.")
577 if (idx == length) 609 if (idx == length)
578 return cmd; 610 return cmd;
579 611
580 tem = Fkeymapp (cmd); 612 keymap = get_keymap_1 (cmd, 0, 0);
581 if (NILP (tem)) 613 if (NILP (keymap))
582 return make_number (idx); 614 return make_number (idx);
583 615
584 keymap = get_keymap (cmd);
585 QUIT; 616 QUIT;
586 } 617 }
587} 618}
@@ -765,7 +796,7 @@ that come after prefix bindings.")
765 && ! NILP (binding = Flookup_key (maps[i], key)) 796 && ! NILP (binding = Flookup_key (maps[i], key))
766 && XTYPE (binding) != Lisp_Int) 797 && XTYPE (binding) != Lisp_Int)
767 { 798 {
768 if (! NILP (get_keymap_1 (binding, 0))) 799 if (! NILP (get_keymap (binding)))
769 maps[j++] = Fcons (modes[i], binding); 800 maps[j++] = Fcons (modes[i], binding);
770 else if (j == 0) 801 else if (j == 0)
771 return Fcons (Fcons (modes[i], binding), Qnil); 802 return Fcons (Fcons (modes[i], binding), Qnil);
@@ -1582,7 +1613,7 @@ describe_map (map, keys, partial, shadow)
1582{ 1613{
1583 register Lisp_Object keysdesc; 1614 register Lisp_Object keysdesc;
1584 1615
1585 if (!NILP (keys) && Flength (keys) > 0) 1616 if (!NILP (keys) && XFASTINT (Flength (keys)) > 0)
1586 keysdesc = concat2 (Fkey_description (keys), 1617 keysdesc = concat2 (Fkey_description (keys),
1587 build_string (" ")); 1618 build_string (" "));
1588 else 1619 else