diff options
| author | Jim Blandy | 1992-10-31 05:24:47 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-10-31 05:24:47 +0000 |
| commit | d09b20248ddfb6ffc73afb1ab51485f3d12d2c68 (patch) | |
| tree | 619edda1474c4bf2c030254a84e1080bee549caf | |
| parent | 5bb46ecf6c71724e39f2cd482d9018a354966533 (diff) | |
| download | emacs-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.
| -rw-r--r-- | src/keymap.c | 73 |
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 | |||
| 184 | Lisp_Object | 196 | Lisp_Object |
| 185 | get_keymap_1 (object, error) | 197 | get_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. */ | ||
| 201 | Lisp_Object | 232 | Lisp_Object |
| 202 | get_keymap (object) | 233 | get_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\ | |||
| 459 | If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at\n\ | 490 | If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at\n\ |
| 460 | the front of KEYMAP.") | 491 | the 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 |