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. */