aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorDavid Kastrup2006-09-15 07:19:15 +0000
committerDavid Kastrup2006-09-15 07:19:15 +0000
commitb74e16a384ddbded12eb7e8c7250253614554641 (patch)
tree287d09b973259b6101ae03baec0e0c91c848232a /src/keymap.c
parent6266eb4a51f75b4e31895cd8d8be1ddd5a18e076 (diff)
downloademacs-b74e16a384ddbded12eb7e8c7250253614554641.tar.gz
emacs-b74e16a384ddbded12eb7e8c7250253614554641.zip
* NEWS: explain new behavior and arguments of `key-binding' and
`command-remapping'. * keymaps.texi (Active Keymaps): Adapt description to use `get-char-property' instead `get-text-property'. Explain how mouse events change this. Explain the new optional argument of `key-binding' and its mouse-dependent lookup. (Searching Keymaps): Adapt description similarly. Explain the new optional argument of `command-remapping'. * Makefile.in (keymap.o): Add "keymap.h" and "window.h" dependencies. * keymap.c: include "window.h". (Fcommand_remapping): New optional POSITION argument. (Fkey_binding): New optional POSITION argument. Completely rework handling of mouse clicks to get the same order of keymaps as `read-key-sequence' and heed POSITION. Also temporarily switch buffers to location of mouse click and back. * keyboard.c (command_loop_1): Adjust call of `Fcommand_remapping' for additional argument. (parse_menu_item): Adjust call of `Fkey_binding' for additional argument. (read_key_sequence): If there are both `local-map' and `keymap' text properties at some buffer position, heed both. * keymap.h: Declare additional optional arguments of `Fcommand_remapping' and `Fkey_binding'.
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c193
1 files changed, 146 insertions, 47 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 8b99231a91d..45bcba9a5fc 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA. */
33#include "puresize.h" 33#include "puresize.h"
34#include "intervals.h" 34#include "intervals.h"
35#include "keymap.h" 35#include "keymap.h"
36#include "window.h"
36 37
37/* The number of elements in keymap vectors. */ 38/* The number of elements in keymap vectors. */
38#define DENSE_TABLE_SIZE (0200) 39#define DENSE_TABLE_SIZE (0200)
@@ -1216,17 +1217,23 @@ binding KEY to DEF is added at the front of KEYMAP. */)
1216 1217
1217/* This function may GC (it calls Fkey_binding). */ 1218/* This function may GC (it calls Fkey_binding). */
1218 1219
1219DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 1, 0, 1220DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 2, 0,
1220 doc: /* Return the remapping for command COMMAND in current keymaps. 1221 doc: /* Return the remapping for command COMMAND in current keymaps.
1221Returns nil if COMMAND is not remapped (or not a symbol). */) 1222Returns nil if COMMAND is not remapped (or not a symbol).
1222 (command) 1223
1223 Lisp_Object command; 1224If the optional argument POSITION is non-nil, it specifies a mouse
1225position as returned by `event-start' and `event-end', and the
1226remapping occurs in the keymaps associated with it. It can also be a
1227number or marker, in which case the keymap properties at the specified
1228buffer position instead of point are used. */)
1229 (command, position)
1230 Lisp_Object command, position;
1224{ 1231{
1225 if (!SYMBOLP (command)) 1232 if (!SYMBOLP (command))
1226 return Qnil; 1233 return Qnil;
1227 1234
1228 ASET (command_remapping_vector, 1, command); 1235 ASET (command_remapping_vector, 1, command);
1229 return Fkey_binding (command_remapping_vector, Qnil, Qt); 1236 return Fkey_binding (command_remapping_vector, Qnil, Qt, position);
1230} 1237}
1231 1238
1232/* Value is number if KEY is too long; nil if valid but has no definition. */ 1239/* Value is number if KEY is too long; nil if valid but has no definition. */
@@ -1552,7 +1559,7 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
1552 1559
1553/* GC is possible in this function if it autoloads a keymap. */ 1560/* GC is possible in this function if it autoloads a keymap. */
1554 1561
1555DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 3, 0, 1562DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 4, 0,
1556 doc: /* Return the binding for command KEY in current keymaps. 1563 doc: /* Return the binding for command KEY in current keymaps.
1557KEY is a string or vector, a sequence of keystrokes. 1564KEY is a string or vector, a sequence of keystrokes.
1558The binding is probably a symbol with a function definition. 1565The binding is probably a symbol with a function definition.
@@ -1566,55 +1573,86 @@ recognize the default bindings, just as `read-key-sequence' does.
1566Like the normal command loop, `key-binding' will remap the command 1573Like the normal command loop, `key-binding' will remap the command
1567resulting from looking up KEY by looking up the command in the 1574resulting from looking up KEY by looking up the command in the
1568current keymaps. However, if the optional third argument NO-REMAP 1575current keymaps. However, if the optional third argument NO-REMAP
1569is non-nil, `key-binding' returns the unmapped command. */) 1576is non-nil, `key-binding' returns the unmapped command.
1570 (key, accept_default, no_remap) 1577
1571 Lisp_Object key, accept_default, no_remap; 1578If KEY is a key sequence initiated with the mouse, the used keymaps
1579will depend on the clicked mouse position with regard to the buffer
1580and possible local keymaps on strings.
1581
1582If the optional argument POSITION is non-nil, it specifies a mouse
1583position as returned by `event-start' and `event-end', and the lookup
1584occurs in the keymaps associated with it instead of KEY. It can also
1585be a number or marker, in which case the keymap properties at the
1586specified buffer position instead of point are used.
1587 */)
1588 (key, accept_default, no_remap, position)
1589 Lisp_Object key, accept_default, no_remap, position;
1572{ 1590{
1573 Lisp_Object *maps, value; 1591 Lisp_Object *maps, value;
1574 int nmaps, i; 1592 int nmaps, i;
1575 struct gcpro gcpro1; 1593 struct gcpro gcpro1, gcpro2;
1594 int count = SPECPDL_INDEX ();
1576 1595
1577 GCPRO1 (key); 1596 GCPRO2 (key, position);
1578 1597
1579#ifdef HAVE_MOUSE 1598 if (NILP (position))
1580 if (VECTORP (key) && ASIZE (key) > 0)
1581 { 1599 {
1582 Lisp_Object ev, pos; 1600 Lisp_Object event;
1583 if ((ev = AREF (key, 0), CONSP (ev)) 1601 /* mouse events may have a symbolic prefix indicating the
1584 && SYMBOLP (XCAR (ev)) 1602 scrollbar or mode line */
1585 && CONSP (XCDR (ev)) 1603 if (SYMBOLP (AREF (key, 0)) && ASIZE (key) > 1)
1586 && (pos = XCAR (XCDR (ev)), CONSP (pos)) 1604 event = AREF (key, 1);
1587 && XINT (Flength (pos)) == 10 1605 else
1588 && INTEGERP (XCAR (XCDR (pos)))) 1606 event = AREF (key, 0);
1589 {
1590 Lisp_Object map, object;
1591 1607
1592 object = Fnth (make_number(4), pos); 1608 /* We are not interested in locations without event data */
1593 1609
1594 if (CONSP (object)) 1610 if (EVENT_HAS_PARAMETERS (event)) {
1595 map = Fget_char_property (XCDR (object), Qkeymap, XCAR (object)); 1611 Lisp_Object kind;
1596 else
1597 map = Fget_char_property (XCAR (XCDR (pos)), Qkeymap,
1598 Fwindow_buffer (XCAR (pos)));
1599 1612
1600 if (!NILP (Fkeymapp (map))) 1613 kind = EVENT_HEAD_KIND (EVENT_HEAD (event));
1601 { 1614 if (EQ (kind, Qmouse_click))
1602 value = Flookup_key (map, key, accept_default); 1615 position = EVENT_START (event);
1603 if (! NILP (value) && !INTEGERP (value)) 1616 }
1604 goto done;
1605 }
1606 }
1607 } 1617 }
1608#endif /* HAVE_MOUSE */
1609 1618
1610 if (!NILP (current_kboard->Voverriding_terminal_local_map)) 1619 /* Key sequences beginning with mouse clicks
1620 are read using the keymaps of the buffer clicked on, not
1621 the current buffer. So we may have to switch the buffer
1622 here. */
1623
1624 if (CONSP (position))
1625 {
1626 Lisp_Object window;
1627
1628 window = POSN_WINDOW (position);
1629
1630 if (WINDOWP (window)
1631 && BUFFERP (XWINDOW (window)->buffer)
1632 && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
1633 {
1634 /* Arrange to go back to the original buffer once we're done
1635 processing the key sequence. We don't use
1636 save_excursion_{save,restore} here, in analogy to
1637 `read-key-sequence' to avoid saving point. Maybe this
1638 would not be a problem here, but it is easier to keep
1639 things the same.
1640 */
1641
1642 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1643
1644 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
1645 }
1646 }
1647
1648 if (! NILP (current_kboard->Voverriding_terminal_local_map))
1611 { 1649 {
1612 value = Flookup_key (current_kboard->Voverriding_terminal_local_map, 1650 value = Flookup_key (current_kboard->Voverriding_terminal_local_map,
1613 key, accept_default); 1651 key, accept_default);
1614 if (! NILP (value) && !INTEGERP (value)) 1652 if (! NILP (value) && !INTEGERP (value))
1615 goto done; 1653 goto done;
1616 } 1654 }
1617 else if (!NILP (Voverriding_local_map)) 1655 else if (! NILP (Voverriding_local_map))
1618 { 1656 {
1619 value = Flookup_key (Voverriding_local_map, key, accept_default); 1657 value = Flookup_key (Voverriding_local_map, key, accept_default);
1620 if (! NILP (value) && !INTEGERP (value)) 1658 if (! NILP (value) && !INTEGERP (value))
@@ -1622,12 +1660,72 @@ is non-nil, `key-binding' returns the unmapped command. */)
1622 } 1660 }
1623 else 1661 else
1624 { 1662 {
1625 Lisp_Object local; 1663 Lisp_Object keymap, local_map;
1664 EMACS_INT pt;
1626 1665
1627 local = get_local_map (PT, current_buffer, Qkeymap); 1666 pt = INTEGERP (position) ? XINT (position)
1628 if (! NILP (local)) 1667 : MARKERP (position) ? marker_position (position)
1668 : PT;
1669
1670 local_map = get_local_map (pt, current_buffer, Qlocal_map);
1671 keymap = get_local_map (pt, current_buffer, Qkeymap);
1672
1673 if (CONSP (position))
1629 { 1674 {
1630 value = Flookup_key (local, key, accept_default); 1675 Lisp_Object string, window;
1676
1677 window = POSN_WINDOW (position);
1678
1679 /* For a mouse click, get the local text-property keymap
1680 of the place clicked on, rather than point. */
1681
1682 if (POSN_INBUFFER_P (position))
1683 {
1684 Lisp_Object pos;
1685
1686 pos = POSN_BUFFER_POSN (position);
1687 if (INTEGERP (pos)
1688 && XINT (pos) >= BEG && XINT (pos) <= Z)
1689 {
1690 local_map = get_local_map (XINT (pos),
1691 current_buffer, Qlocal_map);
1692
1693 keymap = get_local_map (XINT (pos),
1694 current_buffer, Qkeymap);
1695 }
1696 }
1697
1698 /* If on a mode line string with a local keymap,
1699 or for a click on a string, i.e. overlay string or a
1700 string displayed via the `display' property,
1701 consider `local-map' and `keymap' properties of
1702 that string. */
1703
1704 if (string = POSN_STRING (position),
1705 (CONSP (string) && STRINGP (XCAR (string))))
1706 {
1707 Lisp_Object pos, map;
1708
1709 pos = XCDR (string);
1710 string = XCAR (string);
1711 if (XINT (pos) >= 0
1712 && XINT (pos) < SCHARS (string))
1713 {
1714 map = Fget_text_property (pos, Qlocal_map, string);
1715 if (!NILP (map))
1716 local_map = map;
1717
1718 map = Fget_text_property (pos, Qkeymap, string);
1719 if (!NILP (map))
1720 keymap = map;
1721 }
1722 }
1723
1724 }
1725
1726 if (! NILP (keymap))
1727 {
1728 value = Flookup_key (keymap, key, accept_default);
1631 if (! NILP (value) && !INTEGERP (value)) 1729 if (! NILP (value) && !INTEGERP (value))
1632 goto done; 1730 goto done;
1633 } 1731 }
@@ -1644,10 +1742,9 @@ is non-nil, `key-binding' returns the unmapped command. */)
1644 goto done; 1742 goto done;
1645 } 1743 }
1646 1744
1647 local = get_local_map (PT, current_buffer, Qlocal_map); 1745 if (! NILP (local_map))
1648 if (! NILP (local))
1649 { 1746 {
1650 value = Flookup_key (local, key, accept_default); 1747 value = Flookup_key (local_map, key, accept_default);
1651 if (! NILP (value) && !INTEGERP (value)) 1748 if (! NILP (value) && !INTEGERP (value))
1652 goto done; 1749 goto done;
1653 } 1750 }
@@ -1656,6 +1753,8 @@ is non-nil, `key-binding' returns the unmapped command. */)
1656 value = Flookup_key (current_global_map, key, accept_default); 1753 value = Flookup_key (current_global_map, key, accept_default);
1657 1754
1658 done: 1755 done:
1756 unbind_to (count, Qnil);
1757
1659 UNGCPRO; 1758 UNGCPRO;
1660 if (NILP (value) || INTEGERP (value)) 1759 if (NILP (value) || INTEGERP (value))
1661 return Qnil; 1760 return Qnil;
@@ -1666,7 +1765,7 @@ is non-nil, `key-binding' returns the unmapped command. */)
1666 if (NILP (no_remap) && SYMBOLP (value)) 1765 if (NILP (no_remap) && SYMBOLP (value))
1667 { 1766 {
1668 Lisp_Object value1; 1767 Lisp_Object value1;
1669 if (value1 = Fcommand_remapping (value), !NILP (value1)) 1768 if (value1 = Fcommand_remapping (value, position), !NILP (value1))
1670 value = value1; 1769 value = value1;
1671 } 1770 }
1672 1771
@@ -2467,7 +2566,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2467 if (NILP (no_remap) && SYMBOLP (definition)) 2566 if (NILP (no_remap) && SYMBOLP (definition))
2468 { 2567 {
2469 Lisp_Object tem; 2568 Lisp_Object tem;
2470 if (tem = Fcommand_remapping (definition), !NILP (tem)) 2569 if (tem = Fcommand_remapping (definition, Qnil), !NILP (tem))
2471 return Qnil; 2570 return Qnil;
2472 } 2571 }
2473 2572