aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorRichard M. Stallman1993-07-02 05:21:05 +0000
committerRichard M. Stallman1993-07-02 05:21:05 +0000
commit53c8f9fa142160aeb89f6cb8a3acc2d2a53db617 (patch)
tree11b8fdfd21417c00a229692118ea608c6643a8b2 /src/keymap.c
parent6cc35d868b003f2d3a617994dadd1bf7c9fd4d50 (diff)
downloademacs-53c8f9fa142160aeb89f6cb8a3acc2d2a53db617.tar.gz
emacs-53c8f9fa142160aeb89f6cb8a3acc2d2a53db617.zip
(describe_map_tree): Insert key_heading here.
New arg TITLE. (describe_buffer_bindings): Corresponding changes. (shadow_lookup): New function. (describe_map_2): Call it. SHADOW is now a list of maps. (describe_vector): Likewise. (describe_map): SHADOW is now a list of maps. (describe_map_tree): Likewise. (describe_buffer_bindings): Build suitable list to pass as SHADOW. (Faccessible_keymaps): New arg PREFIX. Callers changed. (describe_map_tree): New arg PREFIX. (Fdescribe_bindings): New arg PREFIX. Pass to describe_buffer_bindings along with buffer. (describe_buffer_bindings): Extract PREFIX and pass along.
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c233
1 files changed, 158 insertions, 75 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 9cef916565b..f3567a8d13b 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1044,15 +1044,19 @@ DEFUN ("current-minor-mode-maps", Fcurrent_minor_mode_maps, Scurrent_minor_mode_
1044/* Help functions for describing and documenting keymaps. */ 1044/* Help functions for describing and documenting keymaps. */
1045 1045
1046DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps, 1046DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
1047 1, 1, 0, 1047 1, 2, 0,
1048 "Find all keymaps accessible via prefix characters from KEYMAP.\n\ 1048 "Find all keymaps accessible via prefix characters from KEYMAP.\n\
1049Returns a list of elements of the form (KEYS . MAP), where the sequence\n\ 1049Returns a list of elements of the form (KEYS . MAP), where the sequence\n\
1050KEYS starting from KEYMAP gets you to MAP. These elements are ordered\n\ 1050KEYS starting from KEYMAP gets you to MAP. These elements are ordered\n\
1051so that the KEYS increase in length. The first element is (\"\" . KEYMAP).") 1051so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
1052 (startmap) 1052 (startmap, prefix)
1053 Lisp_Object startmap; 1053 Lisp_Object startmap, prefix;
1054{ 1054{
1055 Lisp_Object maps, tail; 1055 Lisp_Object maps, good_maps, tail;
1056 int prefixlen = 0;
1057
1058 if (!NILP (prefix))
1059 prefixlen = XINT (Flength (prefix));
1056 1060
1057 maps = Fcons (Fcons (Fmake_vector (make_number (0), Qnil), 1061 maps = Fcons (Fcons (Fmake_vector (make_number (0), Qnil),
1058 get_keymap (startmap)), 1062 get_keymap (startmap)),
@@ -1131,7 +1135,7 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
1131 else if (CONSP (elt)) 1135 else if (CONSP (elt))
1132 { 1136 {
1133 register Lisp_Object cmd = get_keyelt (XCONS (elt)->cdr); 1137 register Lisp_Object cmd = get_keyelt (XCONS (elt)->cdr);
1134 register Lisp_Object tem; 1138 register Lisp_Object tem, filter;
1135 1139
1136 /* Ignore definitions that aren't keymaps themselves. */ 1140 /* Ignore definitions that aren't keymaps themselves. */
1137 tem = Fkeymapp (cmd); 1141 tem = Fkeymapp (cmd);
@@ -1142,7 +1146,7 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
1142 tem = Frassq (cmd, maps); 1146 tem = Frassq (cmd, maps);
1143 if (NILP (tem)) 1147 if (NILP (tem))
1144 { 1148 {
1145 /* let elt be the event defined by this map entry. */ 1149 /* Let elt be the event defined by this map entry. */
1146 elt = XCONS (elt)->car; 1150 elt = XCONS (elt)->car;
1147 1151
1148 /* If the last key in thisseq is meta-prefix-char, and 1152 /* If the last key in thisseq is meta-prefix-char, and
@@ -1157,8 +1161,8 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
1157 /* This new sequence is the same length as 1161 /* This new sequence is the same length as
1158 thisseq, so stick it in the list right 1162 thisseq, so stick it in the list right
1159 after this one. */ 1163 after this one. */
1160 XCONS (tail)->cdr = 1164 XCONS (tail)->cdr
1161 Fcons (Fcons (tem, cmd), XCONS (tail)->cdr); 1165 = Fcons (Fcons (tem, cmd), XCONS (tail)->cdr);
1162 } 1166 }
1163 else 1167 else
1164 nconc2 (tail, 1168 nconc2 (tail,
@@ -1170,7 +1174,35 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
1170 } 1174 }
1171 } 1175 }
1172 1176
1173 return maps; 1177 if (NILP (prefix))
1178 return maps;
1179
1180 /* Now find just the maps whose access prefixes start with PREFIX. */
1181
1182 good_maps = Qnil;
1183 for (; CONSP (maps); maps = XCONS (maps)->cdr)
1184 {
1185 Lisp_Object elt, thisseq;
1186 elt = XCONS (maps)->car;
1187 thisseq = XCONS (elt)->car;
1188 /* The access prefix must be at least as long as PREFIX,
1189 and the first elements must match those of PREFIX. */
1190 if (XINT (Flength (thisseq)) >= prefixlen)
1191 {
1192 int i;
1193 for (i = 0; i < prefixlen; i++)
1194 {
1195 Lisp_Object i1;
1196 XFASTINT (i1) = i;
1197 if (!EQ (Faref (thisseq, i1), Faref (prefix, i1)))
1198 break;
1199 }
1200 if (i == prefixlen)
1201 good_maps = Fcons (elt, good_maps);
1202 }
1203 }
1204
1205 return Fnreverse (good_maps);
1174} 1206}
1175 1207
1176Lisp_Object Qsingle_key_description, Qkey_description; 1208Lisp_Object Qsingle_key_description, Qkey_description;
@@ -1424,10 +1456,10 @@ indirect definition itself.")
1424 global_keymap = current_global_map; 1456 global_keymap = current_global_map;
1425 1457
1426 if (!NILP (local_keymap)) 1458 if (!NILP (local_keymap))
1427 maps = nconc2 (Faccessible_keymaps (get_keymap (local_keymap)), 1459 maps = nconc2 (Faccessible_keymaps (get_keymap (local_keymap), Qnil),
1428 Faccessible_keymaps (get_keymap (global_keymap))); 1460 Faccessible_keymaps (get_keymap (global_keymap), Qnil));
1429 else 1461 else
1430 maps = Faccessible_keymaps (get_keymap (global_keymap)); 1462 maps = Faccessible_keymaps (get_keymap (global_keymap), Qnil);
1431 1463
1432 found = Qnil; 1464 found = Qnil;
1433 1465
@@ -1616,35 +1648,40 @@ Argument is a command definition, usually a symbol with a function definition.")
1616 1648
1617/* describe-bindings - summarizing all the bindings in a set of keymaps. */ 1649/* describe-bindings - summarizing all the bindings in a set of keymaps. */
1618 1650
1619DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 0, "", 1651DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 1, "",
1620 "Show a list of all defined keys, and their definitions.\n\ 1652 "Show a list of all defined keys, and their definitions.\n\
1621The list is put in a buffer, which is displayed.") 1653The list is put in a buffer, which is displayed.\n\
1622 () 1654An optional argument PREFIX, if non-nil, should be a key sequence;\n\
1655then we display only bindings that start with that prefix.")
1656 (prefix)
1657 Lisp_Object prefix;
1623{ 1658{
1624 register Lisp_Object thisbuf; 1659 register Lisp_Object thisbuf;
1625 XSET (thisbuf, Lisp_Buffer, current_buffer); 1660 XSET (thisbuf, Lisp_Buffer, current_buffer);
1626 internal_with_output_to_temp_buffer ("*Help*", 1661 internal_with_output_to_temp_buffer ("*Help*",
1627 describe_buffer_bindings, 1662 describe_buffer_bindings,
1628 thisbuf); 1663 Fcons (thisbuf, prefix));
1629 return Qnil; 1664 return Qnil;
1630} 1665}
1631 1666
1667/* ARG is (BUFFER . PREFIX). */
1668
1632static Lisp_Object 1669static Lisp_Object
1633describe_buffer_bindings (descbuf) 1670describe_buffer_bindings (arg)
1634 Lisp_Object descbuf; 1671 Lisp_Object arg;
1635{ 1672{
1673 Lisp_Object descbuf, prefix, shadow;
1636 register Lisp_Object start1, start2; 1674 register Lisp_Object start1, start2;
1637 1675
1638 char *key_heading
1639 = "\
1640key binding\n\
1641--- -------\n";
1642 char *alternate_heading 1676 char *alternate_heading
1643 = "\ 1677 = "\
1644Alternate Characters (use anywhere the nominal character is listed):\n\ 1678Alternate Characters (use anywhere the nominal character is listed):\n\
1645nominal alternate\n\ 1679nominal alternate\n\
1646------- ---------\n"; 1680------- ---------\n";
1647 1681
1682 descbuf = XCONS (arg)->car;
1683 prefix = XCONS (arg)->cdr;
1684
1648 Fset_buffer (Vstandard_output); 1685 Fset_buffer (Vstandard_output);
1649 1686
1650 /* Report on alternates for keys. */ 1687 /* Report on alternates for keys. */
@@ -1681,6 +1718,9 @@ nominal alternate\n\
1681 { 1718 {
1682 int i, nmaps; 1719 int i, nmaps;
1683 Lisp_Object *modes, *maps; 1720 Lisp_Object *modes, *maps;
1721 Lisp_Object shadow;
1722
1723 shadow = Qnil;
1684 1724
1685 /* Temporarily switch to descbuf, so that we can get that buffer's 1725 /* Temporarily switch to descbuf, so that we can get that buffer's
1686 minor modes correctly. */ 1726 minor modes correctly. */
@@ -1688,6 +1728,9 @@ nominal alternate\n\
1688 nmaps = current_minor_maps (&modes, &maps); 1728 nmaps = current_minor_maps (&modes, &maps);
1689 Fset_buffer (Vstandard_output); 1729 Fset_buffer (Vstandard_output);
1690 1730
1731 shadow = Qnil;
1732
1733 /* Print the minor mode maps. */
1691 for (i = 0; i < nmaps; i++) 1734 for (i = 0; i < nmaps; i++)
1692 { 1735 {
1693 if (XTYPE (modes[i]) == Lisp_Symbol) 1736 if (XTYPE (modes[i]) == Lisp_Symbol)
@@ -1699,26 +1742,24 @@ nominal alternate\n\
1699 else 1742 else
1700 insert_string ("Strangely Named"); 1743 insert_string ("Strangely Named");
1701 insert_string (" Minor Mode Bindings:\n"); 1744 insert_string (" Minor Mode Bindings:\n");
1702 insert_string (key_heading); 1745 describe_map_tree (maps[i], 0, shadow, prefix, 0);
1703 describe_map_tree (maps[i], 0, Qnil); 1746 shadow = Fcons (maps[i], shadow);
1704 insert_char ('\n'); 1747 insert_char ('\n');
1705 } 1748 }
1706 } 1749 }
1707 1750
1751 /* Print the (major mode) local map. */
1708 start1 = XBUFFER (descbuf)->keymap; 1752 start1 = XBUFFER (descbuf)->keymap;
1709 if (!NILP (start1)) 1753 if (!NILP (start1))
1710 { 1754 {
1711 insert_string ("Local Bindings:\n"); 1755 describe_map_tree (start1, 0, shadow, prefix,
1712 insert_string (key_heading); 1756 "Major Mode Bindings:\n");
1713 describe_map_tree (start1, 0, Qnil); 1757 shadow = Fcons (start1, shadow);
1714 insert_string ("\n"); 1758 insert_string ("\n");
1715 } 1759 }
1716 1760
1717 insert_string ("Global Bindings:\n"); 1761 describe_map_tree (current_global_map, 0, shadow, prefix,
1718 if (NILP (start1)) 1762 "Global Bindings:\n");
1719 insert_string (key_heading);
1720
1721 describe_map_tree (current_global_map, 0, XBUFFER (descbuf)->keymap);
1722 1763
1723 Fset_buffer (descbuf); 1764 Fset_buffer (descbuf);
1724 return Qnil; 1765 return Qnil;
@@ -1728,55 +1769,79 @@ nominal alternate\n\
1728 followed by those of all maps reachable through STARTMAP. 1769 followed by those of all maps reachable through STARTMAP.
1729 If PARTIAL is nonzero, omit certain "uninteresting" commands 1770 If PARTIAL is nonzero, omit certain "uninteresting" commands
1730 (such as `undefined'). 1771 (such as `undefined').
1731 If SHADOW is non-nil, it is another map; 1772 If SHADOW is non-nil, it is a list of maps;
1732 don't mention keys which would be shadowed by it. */ 1773 don't mention keys which would be shadowed by any of them.
1774 PREFIX, if non-nil, says mention only keys that start with PREFIX.
1775 TITLE, if not 0, is a string to insert at the beginning. */
1733 1776
1734void 1777void
1735describe_map_tree (startmap, partial, shadow) 1778describe_map_tree (startmap, partial, shadow, prefix, title)
1736 Lisp_Object startmap, shadow; 1779 Lisp_Object startmap, shadow, prefix;
1737 int partial; 1780 int partial;
1781 char *title;
1738{ 1782{
1739 register Lisp_Object elt, sh;
1740 Lisp_Object maps; 1783 Lisp_Object maps;
1741 struct gcpro gcpro1; 1784 struct gcpro gcpro1;
1785 char *key_heading
1786 = "\
1787key binding\n\
1788--- -------\n";
1742 1789
1743 maps = Faccessible_keymaps (startmap); 1790 maps = Faccessible_keymaps (startmap, prefix);
1744 GCPRO1 (maps); 1791 GCPRO1 (maps);
1745 1792
1793 if (!NILP (maps))
1794 {
1795 if (title)
1796 insert_string (title);
1797 insert_string (key_heading);
1798 }
1799
1746 for (; !NILP (maps); maps = Fcdr (maps)) 1800 for (; !NILP (maps); maps = Fcdr (maps))
1747 { 1801 {
1802 register Lisp_Object elt, prefix, sub_shadows, tail;
1803
1748 elt = Fcar (maps); 1804 elt = Fcar (maps);
1749 sh = Fcar (elt); 1805 prefix = Fcar (elt);
1750 1806
1751 /* If there is no shadow keymap given, don't shadow. */ 1807 sub_shadows = Qnil;
1752 if (NILP (shadow)) 1808
1753 sh = Qnil; 1809 for (tail = shadow; CONSP (tail); tail = XCONS (tail)->cdr)
1754
1755 /* If the sequence by which we reach this keymap is zero-length,
1756 then the shadow map for this keymap is just SHADOW. */
1757 else if ((XTYPE (sh) == Lisp_String
1758 && XSTRING (sh)->size == 0)
1759 || (XTYPE (sh) == Lisp_Vector
1760 && XVECTOR (sh)->size == 0))
1761 sh = shadow;
1762
1763 /* If the sequence by which we reach this keymap actually has
1764 some elements, then the sequence's definition in SHADOW is
1765 what we should use. */
1766 else
1767 { 1810 {
1768 sh = Flookup_key (shadow, Fcar (elt), Qt); 1811 Lisp_Object shmap;
1769 if (XTYPE (sh) == Lisp_Int) 1812
1770 sh = Qnil; 1813 shmap = XCONS (tail)->car;
1814
1815 /* If the sequence by which we reach this keymap is zero-length,
1816 then the shadow map for this keymap is just SHADOW. */
1817 if ((XTYPE (prefix) == Lisp_String
1818 && XSTRING (prefix)->size == 0)
1819 || (XTYPE (prefix) == Lisp_Vector
1820 && XVECTOR (prefix)->size == 0))
1821 ;
1822 /* If the sequence by which we reach this keymap actually has
1823 some elements, then the sequence's definition in SHADOW is
1824 what we should use. */
1825 else
1826 {
1827 shmap = Flookup_key (shadow, Fcar (elt), Qt);
1828 if (XTYPE (shmap) == Lisp_Int)
1829 shmap = Qnil;
1830 }
1831
1832 /* If shmap is not nil and not a keymap,
1833 it completely shadows this map, so don't
1834 describe this map at all. */
1835 if (!NILP (shmap) && NILP (Fkeymapp (shmap)))
1836 goto skip;
1837
1838 if (!NILP (shmap))
1839 sub_shadows = Fcons (shmap, sub_shadows);
1771 } 1840 }
1772 1841
1773 /* If sh is null (meaning that the current map is not shadowed), 1842 describe_map (Fcdr (elt), Fcar (elt), partial, sub_shadows);
1774 or a keymap (meaning that bindings from the current map might 1843
1775 show through), describe the map. Otherwise, sh is a command 1844 skip: ;
1776 that completely shadows the current map, and we shouldn't
1777 bother. */
1778 if (NILP (sh) || !NILP (Fkeymapp (sh)))
1779 describe_map (Fcdr (elt), Fcar (elt), partial, sh);
1780 } 1845 }
1781 1846
1782 UNGCPRO; 1847 UNGCPRO;
@@ -1831,6 +1896,24 @@ describe_map (map, keys, partial, shadow)
1831 describe_map_2 (map, keysdesc, describe_command, partial, shadow); 1896 describe_map_2 (map, keysdesc, describe_command, partial, shadow);
1832} 1897}
1833 1898
1899/* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map.
1900 Returns the first non-nil binding found in any of those maps. */
1901
1902static Lisp_Object
1903shadow_lookup (shadow, key, flag)
1904 Lisp_Object shadow, key, flag;
1905{
1906 Lisp_Object tail, value;
1907
1908 for (tail = shadow; CONSP (tail); tail = XCONS (tail)->cdr)
1909 {
1910 value = Flookup_key (XCONS (tail)->car, key, flag);
1911 if (!NILP (value))
1912 return value;
1913 }
1914 return Qnil;
1915}
1916
1834/* Insert a description of KEYMAP into the current buffer. */ 1917/* Insert a description of KEYMAP into the current buffer. */
1835 1918
1836static void 1919static void
@@ -1841,7 +1924,7 @@ describe_map_2 (keymap, elt_prefix, elt_describer, partial, shadow)
1841 int partial; 1924 int partial;
1842 Lisp_Object shadow; 1925 Lisp_Object shadow;
1843{ 1926{
1844 Lisp_Object definition, event; 1927 Lisp_Object tail, definition, event;
1845 Lisp_Object tem; 1928 Lisp_Object tem;
1846 Lisp_Object suppress; 1929 Lisp_Object suppress;
1847 Lisp_Object kludge; 1930 Lisp_Object kludge;
@@ -1859,17 +1942,17 @@ describe_map_2 (keymap, elt_prefix, elt_describer, partial, shadow)
1859 1942
1860 GCPRO3 (elt_prefix, definition, kludge); 1943 GCPRO3 (elt_prefix, definition, kludge);
1861 1944
1862 for (; CONSP (keymap); keymap = Fcdr (keymap)) 1945 for (tail = XCONS (keymap)->cdr; CONSP (tail); tail = Fcdr (tail))
1863 { 1946 {
1864 QUIT; 1947 QUIT;
1865 1948
1866 if (XTYPE (XCONS (keymap)->car) == Lisp_Vector) 1949 if (XTYPE (XCONS (tail)->car) == Lisp_Vector)
1867 describe_vector (XCONS (keymap)->car, 1950 describe_vector (XCONS (tail)->car,
1868 elt_prefix, elt_describer, partial, shadow); 1951 elt_prefix, elt_describer, partial, shadow);
1869 else 1952 else
1870 { 1953 {
1871 event = Fcar_safe (Fcar (keymap)); 1954 event = Fcar_safe (Fcar (tail));
1872 definition = get_keyelt (Fcdr_safe (Fcar (keymap))); 1955 definition = get_keyelt (Fcdr_safe (Fcar (tail)));
1873 1956
1874 /* Don't show undefined commands or suppressed commands. */ 1957 /* Don't show undefined commands or suppressed commands. */
1875 if (NILP (definition)) continue; 1958 if (NILP (definition)) continue;
@@ -1886,11 +1969,11 @@ describe_map_2 (keymap, elt_prefix, elt_describer, partial, shadow)
1886 XVECTOR (kludge)->contents[0] = event; 1969 XVECTOR (kludge)->contents[0] = event;
1887 if (!NILP (shadow)) 1970 if (!NILP (shadow))
1888 { 1971 {
1889 tem = Flookup_key (shadow, kludge, Qt); 1972 tem = shadow_lookup (shadow, kludge, Qt);
1890 if (!NILP (tem)) continue; 1973 if (!NILP (tem)) continue;
1891 } 1974 }
1892 1975
1893 tem = Flookup_key (map, kludge, Qt); 1976 tem = Flookup_key (keymap, kludge, Qt);
1894 if (! EQ (tem, definition)) continue; 1977 if (! EQ (tem, definition)) continue;
1895 1978
1896 if (first) 1979 if (first)
@@ -1988,7 +2071,7 @@ describe_vector (vector, elt_prefix, elt_describer, partial, shadow)
1988 Lisp_Object tem; 2071 Lisp_Object tem;
1989 2072
1990 XVECTOR (kludge)->contents[0] = make_number (i); 2073 XVECTOR (kludge)->contents[0] = make_number (i);
1991 tem = Flookup_key (shadow, kludge, Qt); 2074 tem = shadow_lookup (shadow, kludge, Qt);
1992 2075
1993 if (!NILP (tem)) continue; 2076 if (!NILP (tem)) continue;
1994 } 2077 }