diff options
Diffstat (limited to 'src/keymap.c')
| -rw-r--r-- | src/keymap.c | 204 |
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) | |||
| 739 | DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0, | 743 | DEFUN ("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. |
| 741 | FUNCTION is called with two arguments: the event that is bound, and | 745 | FUNCTION is called with two arguments: the event that is bound, and |
| 742 | the definition it is bound to. | 746 | the definition it is bound to. If the event is an integer, it may be |
| 747 | a generic character (see Info node `(elisp)Splitting Characters'), and | ||
| 748 | that means that all actual character events belonging to that generic | ||
| 749 | character are bound to the definition. | ||
| 743 | 750 | ||
| 744 | If KEYMAP has a parent, the parent's bindings are included as well. | 751 | If KEYMAP has a parent, the parent's bindings are included as well. |
| 745 | This works recursively: if the parent has itself a parent, then the | 752 | This 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 | ||
| 1212 | DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 1, 0, | 1219 | DEFUN ("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. |
| 1214 | Returns nil if COMMAND is not remapped (or not a symbol). */) | 1221 | Returns nil if COMMAND is not remapped (or not a symbol). |
| 1215 | (command) | 1222 | |
| 1216 | Lisp_Object command; | 1223 | If the optional argument POSITION is non-nil, it specifies a mouse |
| 1224 | position as returned by `event-start' and `event-end', and the | ||
| 1225 | remapping occurs in the keymaps associated with it. It can also be a | ||
| 1226 | number or marker, in which case the keymap properties at the specified | ||
| 1227 | buffer 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 | ||
| 1548 | DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 3, 0, | 1561 | DEFUN ("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. |
| 1550 | KEY is a string or vector, a sequence of keystrokes. | 1563 | KEY is a string or vector, a sequence of keystrokes. |
| 1551 | The binding is probably a symbol with a function definition. | 1564 | The binding is probably a symbol with a function definition. |
| @@ -1559,24 +1572,82 @@ recognize the default bindings, just as `read-key-sequence' does. | |||
| 1559 | Like the normal command loop, `key-binding' will remap the command | 1572 | Like the normal command loop, `key-binding' will remap the command |
| 1560 | resulting from looking up KEY by looking up the command in the | 1573 | resulting from looking up KEY by looking up the command in the |
| 1561 | current keymaps. However, if the optional third argument NO-REMAP | 1574 | current keymaps. However, if the optional third argument NO-REMAP |
| 1562 | is non-nil, `key-binding' returns the unmapped command. */) | 1575 | is non-nil, `key-binding' returns the unmapped command. |
| 1563 | (key, accept_default, no_remap) | 1576 | |
| 1564 | Lisp_Object key, accept_default, no_remap; | 1577 | If KEY is a key sequence initiated with the mouse, the used keymaps |
| 1578 | will depend on the clicked mouse position with regard to the buffer | ||
| 1579 | and possible local keymaps on strings. | ||
| 1580 | |||
| 1581 | If the optional argument POSITION is non-nil, it specifies a mouse | ||
| 1582 | position as returned by `event-start' and `event-end', and the lookup | ||
| 1583 | occurs in the keymaps associated with it instead of KEY. It can also | ||
| 1584 | be a number or marker, in which case the keymap properties at the | ||
| 1585 | specified 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 | ||