Mercurial > emacs
comparison src/keymap.c @ 50189:c7ce12a3b9c2
(accessible_keymaps_1): Break cycles but without preventing
multiple occurrences of the same keymap under different prefixes.
(Faccessible_keymaps): Remove code redundant since rev 1.82.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Tue, 18 Mar 2003 19:34:31 +0000 |
parents | 3770fda038d0 |
children | 615d7388f725 |
comparison
equal
deleted
inserted
replaced
50188:334078c4c044 | 50189:c7ce12a3b9c2 |
---|---|
1657 Lisp_Object maps, tail, thisseq, key, cmd; | 1657 Lisp_Object maps, tail, thisseq, key, cmd; |
1658 int is_metized; /* If 1, `key' is assumed to be INTEGERP. */ | 1658 int is_metized; /* If 1, `key' is assumed to be INTEGERP. */ |
1659 { | 1659 { |
1660 Lisp_Object tem; | 1660 Lisp_Object tem; |
1661 | 1661 |
1662 cmd = get_keyelt (cmd, 0); | 1662 cmd = get_keymap (get_keyelt (cmd, 0), 0, 0); |
1663 if (NILP (cmd)) | 1663 if (NILP (cmd)) |
1664 return; | 1664 return; |
1665 | 1665 |
1666 tem = get_keymap (cmd, 0, 0); | 1666 /* Look for and break cycles. */ |
1667 if (CONSP (tem)) | 1667 while (!NILP (tem = Frassq (cmd, maps))) |
1668 { | 1668 { |
1669 cmd = tem; | 1669 Lisp_Object prefix = XCAR (tem); |
1670 /* Ignore keymaps that are already added to maps. */ | 1670 int lim = XINT (Flength (XCAR (tem))); |
1671 tem = Frassq (cmd, maps); | 1671 if (lim <= XINT (Flength (thisseq))) |
1672 if (NILP (tem)) | 1672 { /* This keymap was already seen with a smaller prefix. */ |
1673 { | 1673 int i = 0; |
1674 /* If the last key in thisseq is meta-prefix-char, | 1674 while (i < lim && EQ (Faref (prefix, make_number (i)), |
1675 turn it into a meta-ized keystroke. We know | 1675 Faref (thisseq, make_number (i)))) |
1676 that the event we're about to append is an | 1676 i++; |
1677 ascii keystroke since we're processing a | 1677 if (i >= lim) |
1678 keymap table. */ | 1678 /* `prefix' is a prefix of `thisseq' => there's a cycle. */ |
1679 if (is_metized) | 1679 return; |
1680 { | 1680 } |
1681 int meta_bit = meta_modifier; | 1681 /* This occurrence of `cmd' in `maps' does not correspond to a cycle, |
1682 Lisp_Object last = make_number (XINT (Flength (thisseq)) - 1); | 1682 but maybe `cmd' occurs again further down in `maps', so keep |
1683 tem = Fcopy_sequence (thisseq); | 1683 looking. */ |
1684 | 1684 maps = XCDR (Fmemq (tem, maps)); |
1685 Faset (tem, last, make_number (XINT (key) | meta_bit)); | 1685 } |
1686 | 1686 |
1687 /* This new sequence is the same length as | 1687 /* If the last key in thisseq is meta-prefix-char, |
1688 thisseq, so stick it in the list right | 1688 turn it into a meta-ized keystroke. We know |
1689 after this one. */ | 1689 that the event we're about to append is an |
1690 XSETCDR (tail, | 1690 ascii keystroke since we're processing a |
1691 Fcons (Fcons (tem, cmd), XCDR (tail))); | 1691 keymap table. */ |
1692 } | 1692 if (is_metized) |
1693 else | 1693 { |
1694 { | 1694 int meta_bit = meta_modifier; |
1695 tem = append_key (thisseq, key); | 1695 Lisp_Object last = make_number (XINT (Flength (thisseq)) - 1); |
1696 nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil)); | 1696 tem = Fcopy_sequence (thisseq); |
1697 } | 1697 |
1698 } | 1698 Faset (tem, last, make_number (XINT (key) | meta_bit)); |
1699 | |
1700 /* This new sequence is the same length as | |
1701 thisseq, so stick it in the list right | |
1702 after this one. */ | |
1703 XSETCDR (tail, | |
1704 Fcons (Fcons (tem, cmd), XCDR (tail))); | |
1705 } | |
1706 else | |
1707 { | |
1708 tem = append_key (thisseq, key); | |
1709 nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil)); | |
1699 } | 1710 } |
1700 } | 1711 } |
1701 | 1712 |
1702 static void | 1713 static void |
1703 accessible_keymaps_char_table (args, index, cmd) | 1714 accessible_keymaps_char_table (args, index, cmd) |
1827 is_metized && INTEGERP (XCAR (elt))); | 1838 is_metized && INTEGERP (XCAR (elt))); |
1828 | 1839 |
1829 } | 1840 } |
1830 } | 1841 } |
1831 | 1842 |
1832 if (NILP (prefix)) | 1843 return maps; |
1833 return maps; | |
1834 | |
1835 /* Now find just the maps whose access prefixes start with PREFIX. */ | |
1836 | |
1837 good_maps = Qnil; | |
1838 for (; CONSP (maps); maps = XCDR (maps)) | |
1839 { | |
1840 Lisp_Object elt, thisseq; | |
1841 elt = XCAR (maps); | |
1842 thisseq = XCAR (elt); | |
1843 /* The access prefix must be at least as long as PREFIX, | |
1844 and the first elements must match those of PREFIX. */ | |
1845 if (XINT (Flength (thisseq)) >= prefixlen) | |
1846 { | |
1847 int i; | |
1848 for (i = 0; i < prefixlen; i++) | |
1849 { | |
1850 Lisp_Object i1; | |
1851 XSETFASTINT (i1, i); | |
1852 if (!EQ (Faref (thisseq, i1), Faref (prefix, i1))) | |
1853 break; | |
1854 } | |
1855 if (i == prefixlen) | |
1856 good_maps = Fcons (elt, good_maps); | |
1857 } | |
1858 } | |
1859 | |
1860 return Fnreverse (good_maps); | |
1861 } | 1844 } |
1862 | 1845 |
1863 Lisp_Object Qsingle_key_description, Qkey_description; | 1846 Lisp_Object Qsingle_key_description, Qkey_description; |
1864 | 1847 |
1865 /* This function cannot GC. */ | 1848 /* This function cannot GC. */ |