aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorMiles Bader2007-07-15 02:05:20 +0000
committerMiles Bader2007-07-15 02:05:20 +0000
commit7eb1e4534e88a32fe5e549e630fdabf3e062be2b (patch)
tree34fc72789f1cfbfeb067cf507f8871c322df300a /src/keymap.c
parent76d11d2cf9623e9f4c38e8239c4444ffc1fae485 (diff)
parent6f8a87c027ebd6f9cfdac5c0df97d651227bec62 (diff)
downloademacs-7eb1e4534e88a32fe5e549e630fdabf3e062be2b.tar.gz
emacs-7eb1e4534e88a32fe5e549e630fdabf3e062be2b.zip
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 803-813) - Update from CVS - Merge from emacs--rel--22 * emacs--rel--22 (patch 51-58) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 233-236) - Merge from emacs--devo--0 - Update from CVS Revision: emacs@sv.gnu.org/emacs--multi-tty--0--patch-25
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c502
1 files changed, 241 insertions, 261 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 904e3c89d55..869fd7a24a6 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -422,7 +422,7 @@ Return PARENT. PARENT should be nil or another keymap. */)
422 422
423 if (CHAR_TABLE_P (XCAR (list))) 423 if (CHAR_TABLE_P (XCAR (list)))
424 { 424 {
425 Lisp_Object indices[3]; 425 int indices[3];
426 426
427 map_char_table (fix_submap_inheritance, Qnil, 427 map_char_table (fix_submap_inheritance, Qnil,
428 XCAR (list), XCAR (list), 428 XCAR (list), XCAR (list),
@@ -721,7 +721,7 @@ map_keymap (map, fun, args, data, autoload)
721 } 721 }
722 else if (CHAR_TABLE_P (binding)) 722 else if (CHAR_TABLE_P (binding))
723 { 723 {
724 Lisp_Object indices[3]; 724 int indices[3];
725 map_char_table (map_keymap_char_table_item, Qnil, binding, binding, 725 map_char_table (map_keymap_char_table_item, Qnil, binding, binding,
726 Fcons (make_save_value (fun, 0), 726 Fcons (make_save_value (fun, 0),
727 Fcons (make_save_value (data, 0), 727 Fcons (make_save_value (data, 0),
@@ -1072,7 +1072,7 @@ is not copied. */)
1072 Lisp_Object elt = XCAR (keymap); 1072 Lisp_Object elt = XCAR (keymap);
1073 if (CHAR_TABLE_P (elt)) 1073 if (CHAR_TABLE_P (elt))
1074 { 1074 {
1075 Lisp_Object indices[3]; 1075 int indices[3];
1076 elt = Fcopy_sequence (elt); 1076 elt = Fcopy_sequence (elt);
1077 map_char_table (copy_keymap_1, Qnil, elt, elt, elt, 0, indices); 1077 map_char_table (copy_keymap_1, Qnil, elt, elt, elt, 0, indices);
1078 } 1078 }
@@ -1149,7 +1149,7 @@ binding KEY to DEF is added at the front of KEYMAP. */)
1149 if (SYMBOLP (def) && !EQ (Vdefine_key_rebound_commands, Qt)) 1149 if (SYMBOLP (def) && !EQ (Vdefine_key_rebound_commands, Qt))
1150 Vdefine_key_rebound_commands = Fcons (def, Vdefine_key_rebound_commands); 1150 Vdefine_key_rebound_commands = Fcons (def, Vdefine_key_rebound_commands);
1151 1151
1152 meta_bit = (VECTORP (key) || STRINGP (key) && STRING_MULTIBYTE (key) 1152 meta_bit = (VECTORP (key) || (STRINGP (key) && STRING_MULTIBYTE (key))
1153 ? meta_modifier : 0x80); 1153 ? meta_modifier : 0x80);
1154 1154
1155 if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0))) 1155 if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
@@ -1534,14 +1534,47 @@ current_minor_maps (modeptr, mapptr)
1534} 1534}
1535 1535
1536DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps, 1536DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
1537 0, 1, 0, 1537 0, 2, 0,
1538 doc: /* Return a list of the currently active keymaps. 1538 doc: /* Return a list of the currently active keymaps.
1539OLP if non-nil indicates that we should obey `overriding-local-map' and 1539OLP if non-nil indicates that we should obey `overriding-local-map' and
1540`overriding-terminal-local-map'. */) 1540`overriding-terminal-local-map'. POSITION can specify a click position
1541 (olp) 1541like in the respective argument of `key-binding'. */)
1542 Lisp_Object olp; 1542 (olp, position)
1543 Lisp_Object olp, position;
1543{ 1544{
1544 Lisp_Object keymaps = Fcons (current_global_map, Qnil); 1545 int count = SPECPDL_INDEX ();
1546
1547 Lisp_Object keymaps;
1548
1549 /* If a mouse click position is given, our variables are based on
1550 the buffer clicked on, not the current buffer. So we may have to
1551 switch the buffer here. */
1552
1553 if (CONSP (position))
1554 {
1555 Lisp_Object window;
1556
1557 window = POSN_WINDOW (position);
1558
1559 if (WINDOWP (window)
1560 && BUFFERP (XWINDOW (window)->buffer)
1561 && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
1562 {
1563 /* Arrange to go back to the original buffer once we're done
1564 processing the key sequence. We don't use
1565 save_excursion_{save,restore} here, in analogy to
1566 `read-key-sequence' to avoid saving point. Maybe this
1567 would not be a problem here, but it is easier to keep
1568 things the same.
1569 */
1570
1571 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1572
1573 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
1574 }
1575 }
1576
1577 keymaps = Fcons (current_global_map, Qnil);
1545 1578
1546 if (!NILP (olp)) 1579 if (!NILP (olp))
1547 { 1580 {
@@ -1555,15 +1588,76 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
1555 } 1588 }
1556 if (NILP (XCDR (keymaps))) 1589 if (NILP (XCDR (keymaps)))
1557 { 1590 {
1558 Lisp_Object local;
1559 Lisp_Object *maps; 1591 Lisp_Object *maps;
1560 int nmaps, i; 1592 int nmaps, i;
1561 1593
1562 /* This usually returns the buffer's local map, 1594 Lisp_Object keymap, local_map;
1563 but that can be overridden by a `local-map' property. */ 1595 EMACS_INT pt;
1564 local = get_local_map (PT, current_buffer, Qlocal_map); 1596
1565 if (!NILP (local)) 1597 pt = INTEGERP (position) ? XINT (position)
1566 keymaps = Fcons (local, keymaps); 1598 : MARKERP (position) ? marker_position (position)
1599 : PT;
1600
1601 /* Get the buffer local maps, possibly overriden by text or
1602 overlay properties */
1603
1604 local_map = get_local_map (pt, current_buffer, Qlocal_map);
1605 keymap = get_local_map (pt, current_buffer, Qkeymap);
1606
1607 if (CONSP (position))
1608 {
1609 Lisp_Object string;
1610
1611 /* For a mouse click, get the local text-property keymap
1612 of the place clicked on, rather than point. */
1613
1614 if (POSN_INBUFFER_P (position))
1615 {
1616 Lisp_Object pos;
1617
1618 pos = POSN_BUFFER_POSN (position);
1619 if (INTEGERP (pos)
1620 && XINT (pos) >= BEG && XINT (pos) <= Z)
1621 {
1622 local_map = get_local_map (XINT (pos),
1623 current_buffer, Qlocal_map);
1624
1625 keymap = get_local_map (XINT (pos),
1626 current_buffer, Qkeymap);
1627 }
1628 }
1629
1630 /* If on a mode line string with a local keymap,
1631 or for a click on a string, i.e. overlay string or a
1632 string displayed via the `display' property,
1633 consider `local-map' and `keymap' properties of
1634 that string. */
1635
1636 if (string = POSN_STRING (position),
1637 (CONSP (string) && STRINGP (XCAR (string))))
1638 {
1639 Lisp_Object pos, map;
1640
1641 pos = XCDR (string);
1642 string = XCAR (string);
1643 if (INTEGERP (pos)
1644 && XINT (pos) >= 0
1645 && XINT (pos) < SCHARS (string))
1646 {
1647 map = Fget_text_property (pos, Qlocal_map, string);
1648 if (!NILP (map))
1649 local_map = map;
1650
1651 map = Fget_text_property (pos, Qkeymap, string);
1652 if (!NILP (map))
1653 keymap = map;
1654 }
1655 }
1656
1657 }
1658
1659 if (!NILP (local_map))
1660 keymaps = Fcons (local_map, keymaps);
1567 1661
1568 /* Now put all the minor mode keymaps on the list. */ 1662 /* Now put all the minor mode keymaps on the list. */
1569 nmaps = current_minor_maps (0, &maps); 1663 nmaps = current_minor_maps (0, &maps);
@@ -1572,12 +1666,12 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
1572 if (!NILP (maps[i])) 1666 if (!NILP (maps[i]))
1573 keymaps = Fcons (maps[i], keymaps); 1667 keymaps = Fcons (maps[i], keymaps);
1574 1668
1575 /* This returns nil unless there is a `keymap' property. */ 1669 if (!NILP (keymap))
1576 local = get_local_map (PT, current_buffer, Qkeymap); 1670 keymaps = Fcons (keymap, keymaps);
1577 if (!NILP (local))
1578 keymaps = Fcons (local, keymaps);
1579 } 1671 }
1580 1672
1673 unbind_to (count, Qnil);
1674
1581 return keymaps; 1675 return keymaps;
1582} 1676}
1583 1677
@@ -1945,12 +2039,23 @@ DEFUN ("current-minor-mode-maps", Fcurrent_minor_mode_maps, Scurrent_minor_mode_
1945 2039
1946/* Help functions for describing and documenting keymaps. */ 2040/* Help functions for describing and documenting keymaps. */
1947 2041
2042struct accessible_keymaps_data {
2043 Lisp_Object maps, tail, thisseq;
2044 /* Does the current sequence end in the meta-prefix-char? */
2045 int is_metized;
2046};
1948 2047
1949static void 2048static void
1950accessible_keymaps_1 (key, cmd, maps, tail, thisseq, is_metized) 2049accessible_keymaps_1 (key, cmd, args, data)
1951 Lisp_Object maps, tail, thisseq, key, cmd; 2050 Lisp_Object key, cmd, args;
1952 int is_metized; /* If 1, `key' is assumed to be INTEGERP. */ 2051 /* Use void* to be compatible with map_keymap_function_t. */
2052 void *data;
1953{ 2053{
2054 struct accessible_keymaps_data *d = data; /* Cast! */
2055 Lisp_Object maps = d->maps;
2056 Lisp_Object tail = d->tail;
2057 Lisp_Object thisseq = d->thisseq;
2058 int is_metized = d->is_metized && INTEGERP (key);
1954 Lisp_Object tem; 2059 Lisp_Object tem;
1955 2060
1956 cmd = get_keymap (get_keyelt (cmd, 0), 0, 0); 2061 cmd = get_keymap (get_keyelt (cmd, 0), 0, 0);
@@ -2004,17 +2109,6 @@ accessible_keymaps_1 (key, cmd, maps, tail, thisseq, is_metized)
2004 } 2109 }
2005} 2110}
2006 2111
2007static void
2008accessible_keymaps_char_table (args, index, cmd)
2009 Lisp_Object args, index, cmd;
2010{
2011 accessible_keymaps_1 (index, cmd,
2012 XCAR (XCAR (args)),
2013 XCAR (XCDR (args)),
2014 XCDR (XCDR (args)),
2015 XINT (XCDR (XCAR (args))));
2016}
2017
2018/* This function cannot GC. */ 2112/* This function cannot GC. */
2019 2113
2020DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps, 2114DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
@@ -2029,14 +2123,11 @@ then the value includes only maps for prefixes that start with PREFIX. */)
2029 Lisp_Object keymap, prefix; 2123 Lisp_Object keymap, prefix;
2030{ 2124{
2031 Lisp_Object maps, tail; 2125 Lisp_Object maps, tail;
2032 int prefixlen = 0; 2126 int prefixlen = XINT (Flength (prefix));
2033 2127
2034 /* no need for gcpro because we don't autoload any keymaps. */ 2128 /* no need for gcpro because we don't autoload any keymaps. */
2035 2129
2036 if (!NILP (prefix)) 2130 if (!NILP (prefix))
2037 prefixlen = XINT (Flength (prefix));
2038
2039 if (!NILP (prefix))
2040 { 2131 {
2041 /* If a prefix was specified, start with the keymap (if any) for 2132 /* If a prefix was specified, start with the keymap (if any) for
2042 that prefix, so we don't waste time considering other prefixes. */ 2133 that prefix, so we don't waste time considering other prefixes. */
@@ -2046,7 +2137,9 @@ then the value includes only maps for prefixes that start with PREFIX. */)
2046 if the prefix is not defined in this particular map. 2137 if the prefix is not defined in this particular map.
2047 It might even give us a list that isn't a keymap. */ 2138 It might even give us a list that isn't a keymap. */
2048 tem = get_keymap (tem, 0, 0); 2139 tem = get_keymap (tem, 0, 0);
2049 if (CONSP (tem)) 2140 /* If the keymap is autoloaded `tem' is not a cons-cell, but we still
2141 want to return it. */
2142 if (!NILP (tem))
2050 { 2143 {
2051 /* Convert PREFIX to a vector now, so that later on 2144 /* Convert PREFIX to a vector now, so that later on
2052 we don't have to deal with the possibility of a string. */ 2145 we don't have to deal with the possibility of a string. */
@@ -2086,57 +2179,26 @@ then the value includes only maps for prefixes that start with PREFIX. */)
2086 2179
2087 for (tail = maps; CONSP (tail); tail = XCDR (tail)) 2180 for (tail = maps; CONSP (tail); tail = XCDR (tail))
2088 { 2181 {
2089 register Lisp_Object thisseq, thismap; 2182 struct accessible_keymaps_data data;
2183 register Lisp_Object thismap = Fcdr (XCAR (tail));
2090 Lisp_Object last; 2184 Lisp_Object last;
2091 /* Does the current sequence end in the meta-prefix-char? */
2092 int is_metized;
2093 2185
2094 thisseq = Fcar (Fcar (tail)); 2186 data.thisseq = Fcar (XCAR (tail));
2095 thismap = Fcdr (Fcar (tail)); 2187 data.maps = maps;
2096 last = make_number (XINT (Flength (thisseq)) - 1); 2188 data.tail = tail;
2097 is_metized = (XINT (last) >= 0 2189 last = make_number (XINT (Flength (data.thisseq)) - 1);
2190 /* Does the current sequence end in the meta-prefix-char? */
2191 data.is_metized = (XINT (last) >= 0
2098 /* Don't metize the last char of PREFIX. */ 2192 /* Don't metize the last char of PREFIX. */
2099 && XINT (last) >= prefixlen 2193 && XINT (last) >= prefixlen
2100 && EQ (Faref (thisseq, last), meta_prefix_char)); 2194 && EQ (Faref (data.thisseq, last), meta_prefix_char));
2101
2102 for (; CONSP (thismap); thismap = XCDR (thismap))
2103 {
2104 Lisp_Object elt;
2105
2106 elt = XCAR (thismap);
2107
2108 QUIT;
2109
2110 if (CHAR_TABLE_P (elt))
2111 {
2112 Lisp_Object indices[3];
2113
2114 map_char_table (accessible_keymaps_char_table, Qnil, elt,
2115 elt, Fcons (Fcons (maps, make_number (is_metized)),
2116 Fcons (tail, thisseq)),
2117 0, indices);
2118 }
2119 else if (VECTORP (elt))
2120 {
2121 register int i;
2122
2123 /* Vector keymap. Scan all the elements. */
2124 for (i = 0; i < ASIZE (elt); i++)
2125 accessible_keymaps_1 (make_number (i), AREF (elt, i),
2126 maps, tail, thisseq, is_metized);
2127 2195
2128 } 2196 /* Since we can't run lisp code, we can't scan autoloaded maps. */
2129 else if (CONSP (elt)) 2197 if (CONSP (thismap))
2130 accessible_keymaps_1 (XCAR (elt), XCDR (elt), 2198 map_keymap (thismap, accessible_keymaps_1, Qnil, &data, 0);
2131 maps, tail, thisseq,
2132 is_metized && INTEGERP (XCAR (elt)));
2133
2134 }
2135 } 2199 }
2136
2137 return maps; 2200 return maps;
2138} 2201}
2139
2140Lisp_Object Qsingle_key_description, Qkey_description; 2202Lisp_Object Qsingle_key_description, Qkey_description;
2141 2203
2142/* This function cannot GC. */ 2204/* This function cannot GC. */
@@ -2407,7 +2469,7 @@ around function keys and event symbols. */)
2407 { 2469 {
2408 char buf[256]; 2470 char buf[256];
2409 2471
2410 sprintf (buf, "Invalid char code %d", XINT (key)); 2472 sprintf (buf, "Invalid char code %ld", XINT (key));
2411 return build_string (buf); 2473 return build_string (buf);
2412 } 2474 }
2413 else if (charset 2475 else if (charset
@@ -2550,8 +2612,8 @@ ascii_sequence_p (seq)
2550/* where-is - finding a command in a set of keymaps. */ 2612/* where-is - finding a command in a set of keymaps. */
2551 2613
2552static Lisp_Object where_is_internal (); 2614static Lisp_Object where_is_internal ();
2553static Lisp_Object where_is_internal_1 (); 2615static void where_is_internal_1 P_ ((Lisp_Object key, Lisp_Object binding,
2554static void where_is_internal_2 (); 2616 Lisp_Object args, void *data));
2555 2617
2556/* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map. 2618/* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map.
2557 Returns the first non-nil binding found in any of those maps. */ 2619 Returns the first non-nil binding found in any of those maps. */
@@ -2580,6 +2642,12 @@ shadow_lookup (shadow, key, flag)
2580 2642
2581static Lisp_Object Vmouse_events; 2643static Lisp_Object Vmouse_events;
2582 2644
2645struct where_is_internal_data {
2646 Lisp_Object definition, noindirect, this, last;
2647 int last_is_meta;
2648 Lisp_Object sequences;
2649};
2650
2583/* This function can GC if Flookup_key autoloads any keymaps. */ 2651/* This function can GC if Flookup_key autoloads any keymaps. */
2584 2652
2585static Lisp_Object 2653static Lisp_Object
@@ -2617,6 +2685,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2617 { 2685 {
2618 /* Key sequence to reach map, and the map that it reaches */ 2686 /* Key sequence to reach map, and the map that it reaches */
2619 register Lisp_Object this, map, tem; 2687 register Lisp_Object this, map, tem;
2688 struct where_is_internal_data data;
2620 2689
2621 /* In order to fold [META-PREFIX-CHAR CHAR] sequences into 2690 /* In order to fold [META-PREFIX-CHAR CHAR] sequences into
2622 [M-CHAR] sequences, check if last character of the sequence 2691 [M-CHAR] sequences, check if last character of the sequence
@@ -2641,148 +2710,94 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2641 2710
2642 QUIT; 2711 QUIT;
2643 2712
2644 while (CONSP (map)) 2713 data.definition = definition;
2645 { 2714 data.noindirect = noindirect;
2646 /* Because the code we want to run on each binding is rather 2715 data.this = this;
2647 large, we don't want to have two separate loop bodies for 2716 data.last = last;
2648 sparse keymap bindings and tables; we want to iterate one 2717 data.last_is_meta = last_is_meta;
2649 loop body over both keymap and vector bindings. 2718 data.sequences = Qnil;
2650 2719
2651 For this reason, if Fcar (map) is a vector, we don't 2720 if (CONSP (map))
2652 advance map to the next element until i indicates that we 2721 map_keymap (map, where_is_internal_1, Qnil, &data, 0);
2653 have finished off the vector. */
2654 Lisp_Object elt, key, binding;
2655 elt = XCAR (map);
2656 map = XCDR (map);
2657 2722
2658 sequences = Qnil; 2723 sequences = data.sequences;
2659 2724
2660 QUIT; 2725 while (CONSP (sequences))
2661 2726 {
2662 /* Set key and binding to the current key and binding, and 2727 Lisp_Object sequence, remapped, function;
2663 advance map and i to the next binding. */ 2728
2664 if (VECTORP (elt)) 2729 sequence = XCAR (sequences);
2730 sequences = XCDR (sequences);
2731
2732 /* If the current sequence is a command remapping with
2733 format [remap COMMAND], find the key sequences
2734 which run COMMAND, and use those sequences instead. */
2735 remapped = Qnil;
2736 if (NILP (no_remap)
2737 && VECTORP (sequence) && XVECTOR (sequence)->size == 2
2738 && EQ (AREF (sequence, 0), Qremap)
2739 && (function = AREF (sequence, 1), SYMBOLP (function)))
2665 { 2740 {
2666 Lisp_Object sequence; 2741 Lisp_Object remapped1;
2667 int i; 2742
2668 /* In a vector, look at each element. */ 2743 remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
2669 for (i = 0; i < XVECTOR (elt)->size; i++) 2744 if (CONSP (remapped1))
2670 { 2745 {
2671 binding = AREF (elt, i); 2746 /* Verify that this key binding actually maps to the
2672 XSETFASTINT (key, i); 2747 remapped command (see below). */
2673 sequence = where_is_internal_1 (binding, key, definition, 2748 if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
2674 noindirect, this, 2749 continue;
2675 last, nomenus, last_is_meta); 2750 sequence = XCAR (remapped1);
2676 if (!NILP (sequence)) 2751 remapped = XCDR (remapped1);
2677 sequences = Fcons (sequence, sequences); 2752 goto record_sequence;
2678 } 2753 }
2679 } 2754 }
2680 else if (CHAR_TABLE_P (elt))
2681 {
2682 Lisp_Object indices[3];
2683 Lisp_Object args;
2684
2685 args = Fcons (Fcons (Fcons (definition, noindirect),
2686 Qnil), /* Result accumulator. */
2687 Fcons (Fcons (this, last),
2688 Fcons (make_number (nomenus),
2689 make_number (last_is_meta))));
2690 map_char_table (where_is_internal_2, Qnil, elt, elt, args,
2691 0, indices);
2692 sequences = XCDR (XCAR (args));
2693 }
2694 else if (CONSP (elt))
2695 {
2696 Lisp_Object sequence;
2697 2755
2698 key = XCAR (elt); 2756 /* Verify that this key binding is not shadowed by another
2699 binding = XCDR (elt); 2757 binding for the same key, before we say it exists.
2700 2758
2701 sequence = where_is_internal_1 (binding, key, definition, 2759 Mechanism: look for local definition of this key and if
2702 noindirect, this, 2760 it is defined and does not match what we found then
2703 last, nomenus, last_is_meta); 2761 ignore this key.
2704 if (!NILP (sequence))
2705 sequences = Fcons (sequence, sequences);
2706 }
2707 2762
2763 Either nil or number as value from Flookup_key
2764 means undefined. */
2765 if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
2766 continue;
2708 2767
2709 while (!NILP (sequences)) 2768 record_sequence:
2769 /* Don't annoy user with strings from a menu such as
2770 Select Paste. Change them all to "(any string)",
2771 so that there seems to be only one menu item
2772 to report. */
2773 if (! NILP (sequence))
2710 { 2774 {
2711 Lisp_Object sequence, remapped, function; 2775 Lisp_Object tem;
2712 2776 tem = Faref (sequence, make_number (XVECTOR (sequence)->size - 1));
2713 sequence = XCAR (sequences); 2777 if (STRINGP (tem))
2714 sequences = XCDR (sequences); 2778 Faset (sequence, make_number (XVECTOR (sequence)->size - 1),
2715 2779 build_string ("(any string)"));
2716 /* If the current sequence is a command remapping with 2780 }
2717 format [remap COMMAND], find the key sequences
2718 which run COMMAND, and use those sequences instead. */
2719 remapped = Qnil;
2720 if (NILP (no_remap)
2721 && VECTORP (sequence) && XVECTOR (sequence)->size == 2
2722 && EQ (AREF (sequence, 0), Qremap)
2723 && (function = AREF (sequence, 1), SYMBOLP (function)))
2724 {
2725 Lisp_Object remapped1;
2726
2727 remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
2728 if (CONSP (remapped1))
2729 {
2730 /* Verify that this key binding actually maps to the
2731 remapped command (see below). */
2732 if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
2733 continue;
2734 sequence = XCAR (remapped1);
2735 remapped = XCDR (remapped1);
2736 goto record_sequence;
2737 }
2738 }
2739
2740 /* Verify that this key binding is not shadowed by another
2741 binding for the same key, before we say it exists.
2742
2743 Mechanism: look for local definition of this key and if
2744 it is defined and does not match what we found then
2745 ignore this key.
2746
2747 Either nil or number as value from Flookup_key
2748 means undefined. */
2749 if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
2750 continue;
2751
2752 record_sequence:
2753 /* Don't annoy user with strings from a menu such as
2754 Select Paste. Change them all to "(any string)",
2755 so that there seems to be only one menu item
2756 to report. */
2757 if (! NILP (sequence))
2758 {
2759 Lisp_Object tem;
2760 tem = Faref (sequence, make_number (XVECTOR (sequence)->size - 1));
2761 if (STRINGP (tem))
2762 Faset (sequence, make_number (XVECTOR (sequence)->size - 1),
2763 build_string ("(any string)"));
2764 }
2765 2781
2766 /* It is a true unshadowed match. Record it, unless it's already 2782 /* It is a true unshadowed match. Record it, unless it's already
2767 been seen (as could happen when inheriting keymaps). */ 2783 been seen (as could happen when inheriting keymaps). */
2768 if (NILP (Fmember (sequence, found))) 2784 if (NILP (Fmember (sequence, found)))
2769 found = Fcons (sequence, found); 2785 found = Fcons (sequence, found);
2770 2786
2771 /* If firstonly is Qnon_ascii, then we can return the first 2787 /* If firstonly is Qnon_ascii, then we can return the first
2772 binding we find. If firstonly is not Qnon_ascii but not 2788 binding we find. If firstonly is not Qnon_ascii but not
2773 nil, then we should return the first ascii-only binding 2789 nil, then we should return the first ascii-only binding
2774 we find. */ 2790 we find. */
2775 if (EQ (firstonly, Qnon_ascii)) 2791 if (EQ (firstonly, Qnon_ascii))
2776 RETURN_UNGCPRO (sequence); 2792 RETURN_UNGCPRO (sequence);
2777 else if (!NILP (firstonly) && ascii_sequence_p (sequence)) 2793 else if (!NILP (firstonly) && ascii_sequence_p (sequence))
2778 RETURN_UNGCPRO (sequence); 2794 RETURN_UNGCPRO (sequence);
2779 2795
2780 if (CONSP (remapped)) 2796 if (CONSP (remapped))
2781 { 2797 {
2782 sequence = XCAR (remapped); 2798 sequence = XCAR (remapped);
2783 remapped = XCDR (remapped); 2799 remapped = XCDR (remapped);
2784 goto record_sequence; 2800 goto record_sequence;
2785 }
2786 } 2801 }
2787 } 2802 }
2788 } 2803 }
@@ -2835,7 +2850,7 @@ remapped command in the returned list. */)
2835 else if (!NILP (keymap)) 2850 else if (!NILP (keymap))
2836 keymaps = Fcons (keymap, Fcons (current_global_map, Qnil)); 2851 keymaps = Fcons (keymap, Fcons (current_global_map, Qnil));
2837 else 2852 else
2838 keymaps = Fcurrent_active_maps (Qnil); 2853 keymaps = Fcurrent_active_maps (Qnil, Qnil);
2839 2854
2840 /* Only use caching for the menubar (i.e. called with (def nil t nil). 2855 /* Only use caching for the menubar (i.e. called with (def nil t nil).
2841 We don't really need to check `keymap'. */ 2856 We don't really need to check `keymap'. */
@@ -2901,53 +2916,19 @@ remapped command in the returned list. */)
2901 return result; 2916 return result;
2902} 2917}
2903 2918
2904/* This is the function that Fwhere_is_internal calls using map_char_table.
2905 ARGS has the form
2906 (((DEFINITION . NOINDIRECT) . (KEYMAP . RESULT))
2907 .
2908 ((THIS . LAST) . (NOMENUS . LAST_IS_META)))
2909 Since map_char_table doesn't really use the return value from this function,
2910 we the result append to RESULT, the slot in ARGS.
2911
2912 This function can GC because it calls where_is_internal_1 which can
2913 GC. */
2914
2915static void
2916where_is_internal_2 (args, key, binding)
2917 Lisp_Object args, key, binding;
2918{
2919 Lisp_Object definition, noindirect, this, last;
2920 Lisp_Object result, sequence;
2921 int nomenus, last_is_meta;
2922 struct gcpro gcpro1, gcpro2, gcpro3;
2923
2924 GCPRO3 (args, key, binding);
2925 result = XCDR (XCAR (args));
2926 definition = XCAR (XCAR (XCAR (args)));
2927 noindirect = XCDR (XCAR (XCAR (args)));
2928 this = XCAR (XCAR (XCDR (args)));
2929 last = XCDR (XCAR (XCDR (args)));
2930 nomenus = XFASTINT (XCAR (XCDR (XCDR (args))));
2931 last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args))));
2932
2933 sequence = where_is_internal_1 (binding, key, definition, noindirect,
2934 this, last, nomenus, last_is_meta);
2935
2936 if (!NILP (sequence))
2937 XSETCDR (XCAR (args), Fcons (sequence, result));
2938
2939 UNGCPRO;
2940}
2941
2942
2943/* This function can GC because get_keyelt can. */ 2919/* This function can GC because get_keyelt can. */
2944 2920
2945static Lisp_Object 2921static void
2946where_is_internal_1 (binding, key, definition, noindirect, this, last, 2922where_is_internal_1 (key, binding, args, data)
2947 nomenus, last_is_meta) 2923 Lisp_Object key, binding, args;
2948 Lisp_Object binding, key, definition, noindirect, this, last; 2924 void *data;
2949 int nomenus, last_is_meta;
2950{ 2925{
2926 struct where_is_internal_data *d = data; /* Cast! */
2927 Lisp_Object definition = d->definition;
2928 Lisp_Object noindirect = d->noindirect;
2929 Lisp_Object this = d->this;
2930 Lisp_Object last = d->last;
2931 int last_is_meta = d->last_is_meta;
2951 Lisp_Object sequence; 2932 Lisp_Object sequence;
2952 2933
2953 /* Search through indirections unless that's not wanted. */ 2934 /* Search through indirections unless that's not wanted. */
@@ -2961,7 +2942,7 @@ where_is_internal_1 (binding, key, definition, noindirect, this, last,
2961 || EQ (binding, definition) 2942 || EQ (binding, definition)
2962 || (CONSP (definition) && !NILP (Fequal (binding, definition))))) 2943 || (CONSP (definition) && !NILP (Fequal (binding, definition)))))
2963 /* Doesn't match. */ 2944 /* Doesn't match. */
2964 return Qnil; 2945 return;
2965 2946
2966 /* We have found a match. Construct the key sequence where we found it. */ 2947 /* We have found a match. Construct the key sequence where we found it. */
2967 if (INTEGERP (key) && last_is_meta) 2948 if (INTEGERP (key) && last_is_meta)
@@ -2976,10 +2957,9 @@ where_is_internal_1 (binding, key, definition, noindirect, this, last,
2976 { 2957 {
2977 Lisp_Object sequences = Fgethash (binding, where_is_cache, Qnil); 2958 Lisp_Object sequences = Fgethash (binding, where_is_cache, Qnil);
2978 Fputhash (binding, Fcons (sequence, sequences), where_is_cache); 2959 Fputhash (binding, Fcons (sequence, sequences), where_is_cache);
2979 return Qnil;
2980 } 2960 }
2981 else 2961 else
2982 return sequence; 2962 d->sequences = Fcons (sequence, d->sequences);
2983} 2963}
2984 2964
2985/* describe-bindings - summarizing all the bindings in a set of keymaps. */ 2965/* describe-bindings - summarizing all the bindings in a set of keymaps. */