aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorKim F. Storm2002-02-06 22:57:42 +0000
committerKim F. Storm2002-02-06 22:57:42 +0000
commit0c412762ee4eb9288dd33602d73f11f565f779e8 (patch)
tree7318341509c171fe1075cc49b16123bee52d22fc /src/keymap.c
parentc897578d7d532c0d9fa5b5cc35e05fbd5dec4100 (diff)
downloademacs-0c412762ee4eb9288dd33602d73f11f565f779e8.tar.gz
emacs-0c412762ee4eb9288dd33602d73f11f565f779e8.zip
(Fdefine_key): Allow symbol as KEY argument for
defining command remapping. Doc updated. (Flookup_key): Remap command through keymap if KEY is a symbol. (is_command_symbol): New function. (Fkey_binding): Use it. New optional argument NO-REMAP. Doc updated. Callers changed. Perform command remapping via recursive call unless that arg is non-nil. (where_is_internal): New argument no_remap. Callers changed. Call recursively to find original key bindings for a remapped comand unless that arg is non-nil. (Fwhere_is_internal): New optional argument NO-REMAP. Doc updated. Callers changed. Pass arg to where_is_internal.
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c188
1 files changed, 158 insertions, 30 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 362f022b100..21c78780252 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -954,10 +954,12 @@ is not copied. */)
954 954
955DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0, 955DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0,
956 doc: /* Args KEYMAP, KEY, DEF. Define key sequence KEY, in KEYMAP, as DEF. 956 doc: /* Args KEYMAP, KEY, DEF. Define key sequence KEY, in KEYMAP, as DEF.
957KEYMAP is a keymap. KEY is a string or a vector of symbols and characters 957KEYMAP is a keymap.
958meaning a sequence of keystrokes and events. 958
959Non-ASCII characters with codes above 127 (such as ISO Latin-1) 959KEY is a string or a vector of symbols and characters meaning a
960can be included if you use a vector. 960sequence of keystrokes and events. Non-ASCII characters with codes
961above 127 (such as ISO Latin-1) can be included if you use a vector.
962
961DEF is anything that can be a key's definition: 963DEF is anything that can be a key's definition:
962 nil (means key is undefined in this keymap), 964 nil (means key is undefined in this keymap),
963 a command (a Lisp function suitable for interactive calling) 965 a command (a Lisp function suitable for interactive calling)
@@ -971,7 +973,10 @@ DEF is anything that can be a key's definition:
971 or a cons (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP. 973 or a cons (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP.
972 974
973If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at 975If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at
974the front of KEYMAP. */) 976the front of KEYMAP.
977
978KEY may also be a command name which is remapped to DEF. In this case,
979DEF must be a symbol or nil (to remove a previous binding of KEY). */)
975 (keymap, key, def) 980 (keymap, key, def)
976 Lisp_Object keymap; 981 Lisp_Object keymap;
977 Lisp_Object key; 982 Lisp_Object key;
@@ -987,8 +992,24 @@ the front of KEYMAP. */)
987 992
988 keymap = get_keymap (keymap, 1, 1); 993 keymap = get_keymap (keymap, 1, 1);
989 994
990 if (!VECTORP (key) && !STRINGP (key)) 995 if (SYMBOLP (key))
991 key = wrong_type_argument (Qarrayp, key); 996 {
997 /* A command may only be remapped to another command. */
998
999 /* I thought of using is_command_symbol above and below instead
1000 of SYMBOLP, since remapping only works for sych symbols.
1001 However, to make that a requirement would make it impossible
1002 to remap a command before it has been defined, e.g. if a minor
1003 mode were to remap a command of another minor mode which has
1004 not yet been loaded, it would fail. So just use the least
1005 restrictive sanity check here. */
1006 if (!SYMBOLP (def))
1007 key = wrong_type_argument (Qsymbolp, def);
1008 else
1009 key = Fmake_vector (make_number (1), key);
1010 }
1011 else if (!VECTORP (key) && !STRINGP (key))
1012 key = wrong_type_argument (Qarrayp, key);
992 1013
993 length = XFASTINT (Flength (key)); 1014 length = XFASTINT (Flength (key));
994 if (length == 0) 1015 if (length == 0)
@@ -1084,6 +1105,10 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1084 1105
1085 keymap = get_keymap (keymap, 1, 1); 1106 keymap = get_keymap (keymap, 1, 1);
1086 1107
1108 /* Command remapping is simple. */
1109 if (SYMBOLP (key))
1110 return access_keymap (keymap, key, t_ok, 0, 1);
1111
1087 if (!VECTORP (key) && !STRINGP (key)) 1112 if (!VECTORP (key) && !STRINGP (key))
1088 key = wrong_type_argument (Qarrayp, key); 1113 key = wrong_type_argument (Qarrayp, key);
1089 1114
@@ -1361,9 +1386,44 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
1361 return keymaps; 1386 return keymaps;
1362} 1387}
1363 1388
1389/* Like Fcommandp, but looks specifically for a command symbol, and
1390 doesn't signal errors. Returns 1 if FUNCTION is a command symbol. */
1391int
1392is_command_symbol (function)
1393 Lisp_Object function;
1394{
1395 if (!SYMBOLP (function) || EQ (function, Qunbound))
1396 return 0;
1397
1398 function = indirect_function (function);
1399 if (SYMBOLP (function) && EQ (function, Qunbound))
1400 return 0;
1401
1402 if (SUBRP (function))
1403 return (XSUBR (function)->prompt != 0);
1404
1405 if (COMPILEDP (function))
1406 return ((ASIZE (function) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE);
1407
1408 if (CONSP (function))
1409 {
1410 Lisp_Object funcar;
1411
1412 funcar = Fcar (function);
1413 if (SYMBOLP (funcar))
1414 {
1415 if (EQ (funcar, Qlambda))
1416 return !NILP (Fassq (Qinteractive, Fcdr (Fcdr (function))));
1417 if (EQ (funcar, Qautoload))
1418 return !NILP (Fcar (Fcdr (Fcdr (Fcdr (function)))));
1419 }
1420 }
1421 return 0;
1422}
1423
1364/* GC is possible in this function if it autoloads a keymap. */ 1424/* GC is possible in this function if it autoloads a keymap. */
1365 1425
1366DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 2, 0, 1426DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 3, 0,
1367 doc: /* Return the binding for command KEY in current keymaps. 1427 doc: /* Return the binding for command KEY in current keymaps.
1368KEY is a string or vector, a sequence of keystrokes. 1428KEY is a string or vector, a sequence of keystrokes.
1369The binding is probably a symbol with a function definition. 1429The binding is probably a symbol with a function definition.
@@ -1372,9 +1432,14 @@ Normally, `key-binding' ignores bindings for t, which act as default
1372bindings, used when nothing else in the keymap applies; this makes it 1432bindings, used when nothing else in the keymap applies; this makes it
1373usable as a general function for probing keymaps. However, if the 1433usable as a general function for probing keymaps. However, if the
1374optional second argument ACCEPT-DEFAULT is non-nil, `key-binding' does 1434optional second argument ACCEPT-DEFAULT is non-nil, `key-binding' does
1375recognize the default bindings, just as `read-key-sequence' does. */) 1435recognize the default bindings, just as `read-key-sequence' does.
1376 (key, accept_default) 1436
1377 Lisp_Object key, accept_default; 1437Like the normal command loop, `key-binding' will remap the command
1438resulting from looking up KEY by looking up the command in the
1439currrent keymaps. However, if the optional third argument NO-REMAP
1440is non-nil, `key-binding' returns the unmapped command. */)
1441 (key, accept_default, no_remap)
1442 Lisp_Object key, accept_default, no_remap;
1378{ 1443{
1379 Lisp_Object *maps, value; 1444 Lisp_Object *maps, value;
1380 int nmaps, i; 1445 int nmaps, i;
@@ -1387,13 +1452,13 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1387 value = Flookup_key (current_kboard->Voverriding_terminal_local_map, 1452 value = Flookup_key (current_kboard->Voverriding_terminal_local_map,
1388 key, accept_default); 1453 key, accept_default);
1389 if (! NILP (value) && !INTEGERP (value)) 1454 if (! NILP (value) && !INTEGERP (value))
1390 RETURN_UNGCPRO (value); 1455 goto done;
1391 } 1456 }
1392 else if (!NILP (Voverriding_local_map)) 1457 else if (!NILP (Voverriding_local_map))
1393 { 1458 {
1394 value = Flookup_key (Voverriding_local_map, key, accept_default); 1459 value = Flookup_key (Voverriding_local_map, key, accept_default);
1395 if (! NILP (value) && !INTEGERP (value)) 1460 if (! NILP (value) && !INTEGERP (value))
1396 RETURN_UNGCPRO (value); 1461 goto done;
1397 } 1462 }
1398 else 1463 else
1399 { 1464 {
@@ -1404,7 +1469,7 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1404 { 1469 {
1405 value = Flookup_key (local, key, accept_default); 1470 value = Flookup_key (local, key, accept_default);
1406 if (! NILP (value) && !INTEGERP (value)) 1471 if (! NILP (value) && !INTEGERP (value))
1407 RETURN_UNGCPRO (value); 1472 goto done;
1408 } 1473 }
1409 1474
1410 nmaps = current_minor_maps (0, &maps); 1475 nmaps = current_minor_maps (0, &maps);
@@ -1416,7 +1481,7 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1416 { 1481 {
1417 value = Flookup_key (maps[i], key, accept_default); 1482 value = Flookup_key (maps[i], key, accept_default);
1418 if (! NILP (value) && !INTEGERP (value)) 1483 if (! NILP (value) && !INTEGERP (value))
1419 RETURN_UNGCPRO (value); 1484 goto done;
1420 } 1485 }
1421 1486
1422 local = get_local_map (PT, current_buffer, Qlocal_map); 1487 local = get_local_map (PT, current_buffer, Qlocal_map);
@@ -1424,16 +1489,30 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1424 { 1489 {
1425 value = Flookup_key (local, key, accept_default); 1490 value = Flookup_key (local, key, accept_default);
1426 if (! NILP (value) && !INTEGERP (value)) 1491 if (! NILP (value) && !INTEGERP (value))
1427 RETURN_UNGCPRO (value); 1492 goto done;
1428 } 1493 }
1429 } 1494 }
1430 1495
1431 value = Flookup_key (current_global_map, key, accept_default); 1496 value = Flookup_key (current_global_map, key, accept_default);
1497
1498 done:
1432 UNGCPRO; 1499 UNGCPRO;
1433 if (! NILP (value) && !INTEGERP (value)) 1500 if (NILP (value) || INTEGERP (value))
1434 return value; 1501 return Qnil;
1502
1503 /* If the result of the ordinary keymap lookup is an interactive
1504 command, look for a key binding (ie. remapping) for that command. */
1505
1506 if (NILP (no_remap) && is_command_symbol (value))
1507 {
1508 Lisp_Object value1;
1509
1510 value1 = Fkey_binding (value, accept_default, Qt);
1511 if (!NILP (value1) && is_command_symbol (value1))
1512 value = value1;
1513 }
1435 1514
1436 return Qnil; 1515 return value;
1437} 1516}
1438 1517
1439/* GC is possible in this function if it autoloads a keymap. */ 1518/* GC is possible in this function if it autoloads a keymap. */
@@ -2156,6 +2235,7 @@ ascii_sequence_p (seq)
2156 2235
2157/* where-is - finding a command in a set of keymaps. */ 2236/* where-is - finding a command in a set of keymaps. */
2158 2237
2238static Lisp_Object where_is_internal ();
2159static Lisp_Object where_is_internal_1 (); 2239static Lisp_Object where_is_internal_1 ();
2160static void where_is_internal_2 (); 2240static void where_is_internal_2 ();
2161 2241
@@ -2180,9 +2260,9 @@ shadow_lookup (shadow, key, flag)
2180/* This function can GC if Flookup_key autoloads any keymaps. */ 2260/* This function can GC if Flookup_key autoloads any keymaps. */
2181 2261
2182static Lisp_Object 2262static Lisp_Object
2183where_is_internal (definition, keymaps, firstonly, noindirect) 2263where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2184 Lisp_Object definition, keymaps; 2264 Lisp_Object definition, keymaps;
2185 Lisp_Object firstonly, noindirect; 2265 Lisp_Object firstonly, noindirect, no_remap;
2186{ 2266{
2187 Lisp_Object maps = Qnil; 2267 Lisp_Object maps = Qnil;
2188 Lisp_Object found, sequences; 2268 Lisp_Object found, sequences;
@@ -2190,6 +2270,12 @@ where_is_internal (definition, keymaps, firstonly, noindirect)
2190 /* 1 means ignore all menu bindings entirely. */ 2270 /* 1 means ignore all menu bindings entirely. */
2191 int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii); 2271 int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii);
2192 2272
2273 /* If this command is remapped, then it has no key bindings
2274 of its own. */
2275 if (NILP (no_remap)
2276 && !NILP (Fkey_binding (definition, Qnil, Qt)))
2277 return Qnil;
2278
2193 found = keymaps; 2279 found = keymaps;
2194 while (CONSP (found)) 2280 while (CONSP (found))
2195 { 2281 {
@@ -2295,11 +2381,41 @@ where_is_internal (definition, keymaps, firstonly, noindirect)
2295 } 2381 }
2296 2382
2297 2383
2298 for (; !NILP (sequences); sequences = XCDR (sequences)) 2384 while (!NILP (sequences))
2299 { 2385 {
2300 Lisp_Object sequence; 2386 Lisp_Object sequence;
2387 Lisp_Object remapped;
2301 2388
2302 sequence = XCAR (sequences); 2389 sequence = XCAR (sequences);
2390 sequences = XCDR (sequences);
2391
2392 /* If the current sequence is of the form [command],
2393 this may be a remapped command, so look for the key
2394 sequences which run that command, and return those
2395 sequences instead. */
2396 remapped = Qnil;
2397 if (NILP (no_remap)
2398 && VECTORP (sequence) && XVECTOR (sequence)->size == 1)
2399 {
2400 Lisp_Object function;
2401
2402 function = AREF (sequence, 0);
2403 if (is_command_symbol (function))
2404 {
2405 Lisp_Object remapped1;
2406 remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
2407 if (CONSP (remapped1))
2408 {
2409 /* Verify that this key binding actually maps to the
2410 remapped command (see below). */
2411 if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
2412 continue;
2413 sequence = XCAR (remapped1);
2414 remapped = XCDR (remapped1);
2415 goto record_sequence;
2416 }
2417 }
2418 }
2303 2419
2304 /* Verify that this key binding is not shadowed by another 2420 /* Verify that this key binding is not shadowed by another
2305 binding for the same key, before we say it exists. 2421 binding for the same key, before we say it exists.
@@ -2313,6 +2429,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect)
2313 if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition)) 2429 if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
2314 continue; 2430 continue;
2315 2431
2432 record_sequence:
2316 /* It is a true unshadowed match. Record it, unless it's already 2433 /* It is a true unshadowed match. Record it, unless it's already
2317 been seen (as could happen when inheriting keymaps). */ 2434 been seen (as could happen when inheriting keymaps). */
2318 if (NILP (Fmember (sequence, found))) 2435 if (NILP (Fmember (sequence, found)))
@@ -2326,6 +2443,13 @@ where_is_internal (definition, keymaps, firstonly, noindirect)
2326 RETURN_UNGCPRO (sequence); 2443 RETURN_UNGCPRO (sequence);
2327 else if (!NILP (firstonly) && ascii_sequence_p (sequence)) 2444 else if (!NILP (firstonly) && ascii_sequence_p (sequence))
2328 RETURN_UNGCPRO (sequence); 2445 RETURN_UNGCPRO (sequence);
2446
2447 if (CONSP (remapped))
2448 {
2449 sequence = XCAR (remapped);
2450 remapped = XCDR (remapped);
2451 goto record_sequence;
2452 }
2329 } 2453 }
2330 } 2454 }
2331 } 2455 }
@@ -2343,7 +2467,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect)
2343 return found; 2467 return found;
2344} 2468}
2345 2469
2346DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0, 2470DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
2347 doc: /* Return list of keys that invoke DEFINITION. 2471 doc: /* Return list of keys that invoke DEFINITION.
2348If KEYMAP is non-nil, search only KEYMAP and the global keymap. 2472If KEYMAP is non-nil, search only KEYMAP and the global keymap.
2349If KEYMAP is nil, search all the currently active keymaps. 2473If KEYMAP is nil, search all the currently active keymaps.
@@ -2358,10 +2482,14 @@ and entirely reject menu bindings.
2358 2482
2359If optional 4th arg NOINDIRECT is non-nil, don't follow indirections 2483If optional 4th arg NOINDIRECT is non-nil, don't follow indirections
2360to other keymaps or slots. This makes it possible to search for an 2484to other keymaps or slots. This makes it possible to search for an
2361indirect definition itself. */) 2485indirect definition itself.
2362 (definition, keymap, firstonly, noindirect) 2486
2487If optional 5th arg NO-REMAP is non-nil, don't search for key sequences
2488that invoke a command which is remapped to DEFINITION, but include the
2489remapped command in the returned list. */)
2490 (definition, keymap, firstonly, noindirect, no_remap)
2363 Lisp_Object definition, keymap; 2491 Lisp_Object definition, keymap;
2364 Lisp_Object firstonly, noindirect; 2492 Lisp_Object firstonly, noindirect, no_remap;
2365{ 2493{
2366 Lisp_Object sequences, keymaps; 2494 Lisp_Object sequences, keymaps;
2367 /* 1 means ignore all menu bindings entirely. */ 2495 /* 1 means ignore all menu bindings entirely. */
@@ -2382,7 +2510,7 @@ indirect definition itself. */)
2382 { 2510 {
2383 Lisp_Object *defns; 2511 Lisp_Object *defns;
2384 int i, j, n; 2512 int i, j, n;
2385 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 2513 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
2386 2514
2387 /* Check heuristic-consistency of the cache. */ 2515 /* Check heuristic-consistency of the cache. */
2388 if (NILP (Fequal (keymaps, where_is_cache_keymaps))) 2516 if (NILP (Fequal (keymaps, where_is_cache_keymaps)))
@@ -2396,8 +2524,8 @@ indirect definition itself. */)
2396 where_is_cache_keymaps = Qt; 2524 where_is_cache_keymaps = Qt;
2397 2525
2398 /* Fill in the cache. */ 2526 /* Fill in the cache. */
2399 GCPRO4 (definition, keymaps, firstonly, noindirect); 2527 GCPRO5 (definition, keymaps, firstonly, noindirect, no_remap);
2400 where_is_internal (definition, keymaps, firstonly, noindirect); 2528 where_is_internal (definition, keymaps, firstonly, noindirect, no_remap);
2401 UNGCPRO; 2529 UNGCPRO;
2402 2530
2403 where_is_cache_keymaps = keymaps; 2531 where_is_cache_keymaps = keymaps;
@@ -2434,7 +2562,7 @@ indirect definition itself. */)
2434 /* Kill the cache so that where_is_internal_1 doesn't think 2562 /* Kill the cache so that where_is_internal_1 doesn't think
2435 we're filling it up. */ 2563 we're filling it up. */
2436 where_is_cache = Qnil; 2564 where_is_cache = Qnil;
2437 result = where_is_internal (definition, keymaps, firstonly, noindirect); 2565 result = where_is_internal (definition, keymaps, firstonly, noindirect, no_remap);
2438 } 2566 }
2439 2567
2440 return result; 2568 return result;