aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c204
1 files changed, 174 insertions, 30 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 9e1f01e7a79..065631ccff5 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -23,6 +23,9 @@ Boston, MA 02110-1301, USA. */
23 23
24#include <config.h> 24#include <config.h>
25#include <stdio.h> 25#include <stdio.h>
26#if HAVE_ALLOCA_H
27# include <alloca.h>
28#endif
26#include "lisp.h" 29#include "lisp.h"
27#include "commands.h" 30#include "commands.h"
28#include "buffer.h" 31#include "buffer.h"
@@ -34,6 +37,7 @@ Boston, MA 02110-1301, USA. */
34#include "puresize.h" 37#include "puresize.h"
35#include "intervals.h" 38#include "intervals.h"
36#include "keymap.h" 39#include "keymap.h"
40#include "window.h"
37 41
38/* The number of elements in keymap vectors. */ 42/* The number of elements in keymap vectors. */
39#define DENSE_TABLE_SIZE (0200) 43#define DENSE_TABLE_SIZE (0200)
@@ -739,7 +743,10 @@ map_keymap_call (key, val, fun, dummy)
739DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0, 743DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0,
740 doc: /* Call FUNCTION once for each event binding in KEYMAP. 744 doc: /* Call FUNCTION once for each event binding in KEYMAP.
741FUNCTION is called with two arguments: the event that is bound, and 745FUNCTION is called with two arguments: the event that is bound, and
742the definition it is bound to. 746the definition it is bound to. If the event is an integer, it may be
747a generic character (see Info node `(elisp)Splitting Characters'), and
748that means that all actual character events belonging to that generic
749character are bound to the definition.
743 750
744If KEYMAP has a parent, the parent's bindings are included as well. 751If KEYMAP has a parent, the parent's bindings are included as well.
745This works recursively: if the parent has itself a parent, then the 752This works recursively: if the parent has itself a parent, then the
@@ -1142,7 +1149,7 @@ binding KEY to DEF is added at the front of KEYMAP. */)
1142 1149
1143 meta_bit = VECTORP (key) ? meta_modifier : 0x80; 1150 meta_bit = VECTORP (key) ? meta_modifier : 0x80;
1144 1151
1145 if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, make_number (0)))) 1152 if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
1146 { /* DEF is apparently an XEmacs-style keyboard macro. */ 1153 { /* DEF is apparently an XEmacs-style keyboard macro. */
1147 Lisp_Object tmp = Fmake_vector (make_number (ASIZE (def)), Qnil); 1154 Lisp_Object tmp = Fmake_vector (make_number (ASIZE (def)), Qnil);
1148 int i = ASIZE (def); 1155 int i = ASIZE (def);
@@ -1209,17 +1216,23 @@ binding KEY to DEF is added at the front of KEYMAP. */)
1209 1216
1210/* This function may GC (it calls Fkey_binding). */ 1217/* This function may GC (it calls Fkey_binding). */
1211 1218
1212DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 1, 0, 1219DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 2, 0,
1213 doc: /* Return the remapping for command COMMAND in current keymaps. 1220 doc: /* Return the remapping for command COMMAND in current keymaps.
1214Returns nil if COMMAND is not remapped (or not a symbol). */) 1221Returns nil if COMMAND is not remapped (or not a symbol).
1215 (command) 1222
1216 Lisp_Object command; 1223If the optional argument POSITION is non-nil, it specifies a mouse
1224position as returned by `event-start' and `event-end', and the
1225remapping occurs in the keymaps associated with it. It can also be a
1226number or marker, in which case the keymap properties at the specified
1227buffer position instead of point are used. */)
1228 (command, position)
1229 Lisp_Object command, position;
1217{ 1230{
1218 if (!SYMBOLP (command)) 1231 if (!SYMBOLP (command))
1219 return Qnil; 1232 return Qnil;
1220 1233
1221 ASET (command_remapping_vector, 1, command); 1234 ASET (command_remapping_vector, 1, command);
1222 return Fkey_binding (command_remapping_vector, Qnil, Qt); 1235 return Fkey_binding (command_remapping_vector, Qnil, Qt, position);
1223} 1236}
1224 1237
1225/* Value is number if KEY is too long; nil if valid but has no definition. */ 1238/* Value is number if KEY is too long; nil if valid but has no definition. */
@@ -1545,7 +1558,7 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
1545 1558
1546/* GC is possible in this function if it autoloads a keymap. */ 1559/* GC is possible in this function if it autoloads a keymap. */
1547 1560
1548DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 3, 0, 1561DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 4, 0,
1549 doc: /* Return the binding for command KEY in current keymaps. 1562 doc: /* Return the binding for command KEY in current keymaps.
1550KEY is a string or vector, a sequence of keystrokes. 1563KEY is a string or vector, a sequence of keystrokes.
1551The binding is probably a symbol with a function definition. 1564The binding is probably a symbol with a function definition.
@@ -1559,24 +1572,82 @@ recognize the default bindings, just as `read-key-sequence' does.
1559Like the normal command loop, `key-binding' will remap the command 1572Like the normal command loop, `key-binding' will remap the command
1560resulting from looking up KEY by looking up the command in the 1573resulting from looking up KEY by looking up the command in the
1561current keymaps. However, if the optional third argument NO-REMAP 1574current keymaps. However, if the optional third argument NO-REMAP
1562is non-nil, `key-binding' returns the unmapped command. */) 1575is non-nil, `key-binding' returns the unmapped command.
1563 (key, accept_default, no_remap) 1576
1564 Lisp_Object key, accept_default, no_remap; 1577If KEY is a key sequence initiated with the mouse, the used keymaps
1578will depend on the clicked mouse position with regard to the buffer
1579and possible local keymaps on strings.
1580
1581If the optional argument POSITION is non-nil, it specifies a mouse
1582position as returned by `event-start' and `event-end', and the lookup
1583occurs in the keymaps associated with it instead of KEY. It can also
1584be a number or marker, in which case the keymap properties at the
1585specified buffer position instead of point are used.
1586 */)
1587 (key, accept_default, no_remap, position)
1588 Lisp_Object key, accept_default, no_remap, position;
1565{ 1589{
1566 Lisp_Object *maps, value; 1590 Lisp_Object *maps, value;
1567 int nmaps, i; 1591 int nmaps, i;
1568 struct gcpro gcpro1; 1592 struct gcpro gcpro1, gcpro2;
1593 int count = SPECPDL_INDEX ();
1569 1594
1570 GCPRO1 (key); 1595 GCPRO2 (key, position);
1571 1596
1572 if (!NILP (current_kboard->Voverriding_terminal_local_map)) 1597 if (NILP (position) && VECTORP (key))
1598 {
1599 Lisp_Object event
1600 /* mouse events may have a symbolic prefix indicating the
1601 scrollbar or mode line */
1602 = AREF (key, SYMBOLP (AREF (key, 0)) && ASIZE (key) > 1 ? 1 : 0);
1603
1604 /* We are not interested in locations without event data */
1605
1606 if (EVENT_HAS_PARAMETERS (event))
1607 {
1608 Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (event));
1609 if (CONSP (XCDR (event)) && EQ (kind, Qmouse_click))
1610 position = EVENT_START (event);
1611 }
1612 }
1613
1614 /* Key sequences beginning with mouse clicks
1615 are read using the keymaps of the buffer clicked on, not
1616 the current buffer. So we may have to switch the buffer
1617 here. */
1618
1619 if (CONSP (position))
1620 {
1621 Lisp_Object window;
1622
1623 window = POSN_WINDOW (position);
1624
1625 if (WINDOWP (window)
1626 && BUFFERP (XWINDOW (window)->buffer)
1627 && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
1628 {
1629 /* Arrange to go back to the original buffer once we're done
1630 processing the key sequence. We don't use
1631 save_excursion_{save,restore} here, in analogy to
1632 `read-key-sequence' to avoid saving point. Maybe this
1633 would not be a problem here, but it is easier to keep
1634 things the same.
1635 */
1636
1637 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1638
1639 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
1640 }
1641 }
1642
1643 if (! NILP (current_kboard->Voverriding_terminal_local_map))
1573 { 1644 {
1574 value = Flookup_key (current_kboard->Voverriding_terminal_local_map, 1645 value = Flookup_key (current_kboard->Voverriding_terminal_local_map,
1575 key, accept_default); 1646 key, accept_default);
1576 if (! NILP (value) && !INTEGERP (value)) 1647 if (! NILP (value) && !INTEGERP (value))
1577 goto done; 1648 goto done;
1578 } 1649 }
1579 else if (!NILP (Voverriding_local_map)) 1650 else if (! NILP (Voverriding_local_map))
1580 { 1651 {
1581 value = Flookup_key (Voverriding_local_map, key, accept_default); 1652 value = Flookup_key (Voverriding_local_map, key, accept_default);
1582 if (! NILP (value) && !INTEGERP (value)) 1653 if (! NILP (value) && !INTEGERP (value))
@@ -1584,12 +1655,71 @@ is non-nil, `key-binding' returns the unmapped command. */)
1584 } 1655 }
1585 else 1656 else
1586 { 1657 {
1587 Lisp_Object local; 1658 Lisp_Object keymap, local_map;
1659 EMACS_INT pt;
1588 1660
1589 local = get_local_map (PT, current_buffer, Qkeymap); 1661 pt = INTEGERP (position) ? XINT (position)
1590 if (! NILP (local)) 1662 : MARKERP (position) ? marker_position (position)
1663 : PT;
1664
1665 local_map = get_local_map (pt, current_buffer, Qlocal_map);
1666 keymap = get_local_map (pt, current_buffer, Qkeymap);
1667
1668 if (CONSP (position))
1591 { 1669 {
1592 value = Flookup_key (local, key, accept_default); 1670 Lisp_Object string;
1671
1672 /* For a mouse click, get the local text-property keymap
1673 of the place clicked on, rather than point. */
1674
1675 if (POSN_INBUFFER_P (position))
1676 {
1677 Lisp_Object pos;
1678
1679 pos = POSN_BUFFER_POSN (position);
1680 if (INTEGERP (pos)
1681 && XINT (pos) >= BEG && XINT (pos) <= Z)
1682 {
1683 local_map = get_local_map (XINT (pos),
1684 current_buffer, Qlocal_map);
1685
1686 keymap = get_local_map (XINT (pos),
1687 current_buffer, Qkeymap);
1688 }
1689 }
1690
1691 /* If on a mode line string with a local keymap,
1692 or for a click on a string, i.e. overlay string or a
1693 string displayed via the `display' property,
1694 consider `local-map' and `keymap' properties of
1695 that string. */
1696
1697 if (string = POSN_STRING (position),
1698 (CONSP (string) && STRINGP (XCAR (string))))
1699 {
1700 Lisp_Object pos, map;
1701
1702 pos = XCDR (string);
1703 string = XCAR (string);
1704 if (INTEGERP (pos)
1705 && XINT (pos) >= 0
1706 && XINT (pos) < SCHARS (string))
1707 {
1708 map = Fget_text_property (pos, Qlocal_map, string);
1709 if (!NILP (map))
1710 local_map = map;
1711
1712 map = Fget_text_property (pos, Qkeymap, string);
1713 if (!NILP (map))
1714 keymap = map;
1715 }
1716 }
1717
1718 }
1719
1720 if (! NILP (keymap))
1721 {
1722 value = Flookup_key (keymap, key, accept_default);
1593 if (! NILP (value) && !INTEGERP (value)) 1723 if (! NILP (value) && !INTEGERP (value))
1594 goto done; 1724 goto done;
1595 } 1725 }
@@ -1606,10 +1736,9 @@ is non-nil, `key-binding' returns the unmapped command. */)
1606 goto done; 1736 goto done;
1607 } 1737 }
1608 1738
1609 local = get_local_map (PT, current_buffer, Qlocal_map); 1739 if (! NILP (local_map))
1610 if (! NILP (local))
1611 { 1740 {
1612 value = Flookup_key (local, key, accept_default); 1741 value = Flookup_key (local_map, key, accept_default);
1613 if (! NILP (value) && !INTEGERP (value)) 1742 if (! NILP (value) && !INTEGERP (value))
1614 goto done; 1743 goto done;
1615 } 1744 }
@@ -1618,6 +1747,8 @@ is non-nil, `key-binding' returns the unmapped command. */)
1618 value = Flookup_key (current_global_map, key, accept_default); 1747 value = Flookup_key (current_global_map, key, accept_default);
1619 1748
1620 done: 1749 done:
1750 unbind_to (count, Qnil);
1751
1621 UNGCPRO; 1752 UNGCPRO;
1622 if (NILP (value) || INTEGERP (value)) 1753 if (NILP (value) || INTEGERP (value))
1623 return Qnil; 1754 return Qnil;
@@ -1628,7 +1759,7 @@ is non-nil, `key-binding' returns the unmapped command. */)
1628 if (NILP (no_remap) && SYMBOLP (value)) 1759 if (NILP (no_remap) && SYMBOLP (value))
1629 { 1760 {
1630 Lisp_Object value1; 1761 Lisp_Object value1;
1631 if (value1 = Fcommand_remapping (value), !NILP (value1)) 1762 if (value1 = Fcommand_remapping (value, position), !NILP (value1))
1632 value = value1; 1763 value = value1;
1633 } 1764 }
1634 1765
@@ -2247,16 +2378,29 @@ around function keys and event symbols. */)
2247 else 2378 else
2248 SPLIT_CHAR (without_bits, charset, c1, c2); 2379 SPLIT_CHAR (without_bits, charset, c1, c2);
2249 2380
2250 if (charset 2381 if (! CHAR_VALID_P (without_bits, 1))
2251 && CHARSET_DEFINED_P (charset) 2382 {
2252 && ((c1 >= 0 && c1 < 32) 2383 char buf[256];
2253 || (c2 >= 0 && c2 < 32))) 2384
2385 sprintf (buf, "Invalid char code %d", XINT (key));
2386 return build_string (buf);
2387 }
2388 else if (charset
2389 && ((c1 == 0 && c2 == -1) || c2 == 0))
2254 { 2390 {
2255 /* Handle a generic character. */ 2391 /* Handle a generic character. */
2256 Lisp_Object name; 2392 Lisp_Object name;
2257 name = CHARSET_TABLE_INFO (charset, CHARSET_LONG_NAME_IDX); 2393 char buf[256];
2394
2395 name = CHARSET_TABLE_INFO (charset, CHARSET_SHORT_NAME_IDX);
2258 CHECK_STRING (name); 2396 CHECK_STRING (name);
2259 return concat2 (build_string ("Character set "), name); 2397 if (c1 == 0)
2398 /* Only a charset is specified. */
2399 sprintf (buf, "Generic char %d: all of ", without_bits);
2400 else
2401 /* 1st code-point of 2-dimensional charset is specified. */
2402 sprintf (buf, "Generic char %d: row %d of ", without_bits, c1);
2403 return concat2 (build_string (buf), name);
2260 } 2404 }
2261 else 2405 else
2262 { 2406 {
@@ -2429,7 +2573,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2429 if (NILP (no_remap) && SYMBOLP (definition)) 2573 if (NILP (no_remap) && SYMBOLP (definition))
2430 { 2574 {
2431 Lisp_Object tem; 2575 Lisp_Object tem;
2432 if (tem = Fcommand_remapping (definition), !NILP (tem)) 2576 if (tem = Fcommand_remapping (definition, Qnil), !NILP (tem))
2433 return Qnil; 2577 return Qnil;
2434 } 2578 }
2435 2579