Mercurial > emacs
comparison src/keymap.c @ 17788:208d71ea3a4f
(get_keyelt): Handle an indirect entry with meta char.
(describe_vector): Rewrite char-table handling.
(Fmake_keymap): Make a char-table.
(access_keymap, store_in_keymap): Likewise,
(describe_map, Fset_keymap_parent, Faccessible_keymaps): Likewise.
(Fwhere_is_internal, Fcopy_keymap): Handle a char-table.
(copy_keymap_1, accessible_keymaps_char_table): New subroutines.
(where_is_internal_1, where_is_internal_2): New functions.
(syms_of_keymap): Set up Qchar_table_extra_slots prop on Qkeymap.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Tue, 13 May 1997 19:41:21 +0000 |
parents | 10ead0052174 |
children | 41b7d56b62fb |
comparison
equal
deleted
inserted
replaced
17787:eacf563a6d0d | 17788:208d71ea3a4f |
---|---|
116 if (!NILP (string)) | 116 if (!NILP (string)) |
117 tail = Fcons (string, Qnil); | 117 tail = Fcons (string, Qnil); |
118 else | 118 else |
119 tail = Qnil; | 119 tail = Qnil; |
120 return Fcons (Qkeymap, | 120 return Fcons (Qkeymap, |
121 Fcons (Fmake_vector (make_number (DENSE_TABLE_SIZE), Qnil), | 121 Fcons (Fmake_char_table (Qkeymap, Qnil), tail)); |
122 tail)); | |
123 } | 122 } |
124 | 123 |
125 DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0, | 124 DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0, |
126 "Construct and return a new sparse-keymap list.\n\ | 125 "Construct and return a new sparse-keymap list.\n\ |
127 Its car is `keymap' and its cdr is an alist of (CHAR . DEFINITION),\n\ | 126 Its car is `keymap' and its cdr is an alist of (CHAR . DEFINITION),\n\ |
336 if (VECTORP (XCONS (list)->car)) | 335 if (VECTORP (XCONS (list)->car)) |
337 for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++) | 336 for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++) |
338 if (CONSP (XVECTOR (XCONS (list)->car)->contents[i])) | 337 if (CONSP (XVECTOR (XCONS (list)->car)->contents[i])) |
339 fix_submap_inheritance (keymap, make_number (i), | 338 fix_submap_inheritance (keymap, make_number (i), |
340 XVECTOR (XCONS (list)->car)->contents[i]); | 339 XVECTOR (XCONS (list)->car)->contents[i]); |
340 | |
341 if (CHAR_TABLE_P (XCONS (list)->car)) | |
342 { | |
343 Lisp_Object *indices | |
344 = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object)); | |
345 | |
346 map_char_table (fix_submap_inheritance, Qnil, XCONS (list)->car, | |
347 keymap, 0, indices); | |
348 } | |
341 } | 349 } |
342 | 350 |
343 return parent; | 351 return parent; |
344 } | 352 } |
345 | 353 |
471 if (CONSP (val)) | 479 if (CONSP (val)) |
472 fix_submap_inheritance (map, idx, val); | 480 fix_submap_inheritance (map, idx, val); |
473 return val; | 481 return val; |
474 } | 482 } |
475 } | 483 } |
484 else if (CHAR_TABLE_P (binding)) | |
485 { | |
486 if (NATNUMP (idx)) | |
487 { | |
488 val = Faref (binding, idx); | |
489 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap)) | |
490 return Qnil; | |
491 if (CONSP (val)) | |
492 fix_submap_inheritance (map, idx, val); | |
493 return val; | |
494 } | |
495 } | |
476 | 496 |
477 QUIT; | 497 QUIT; |
478 } | 498 } |
479 | 499 |
480 return t_binding; | 500 return t_binding; |
504 | 524 |
505 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ | 525 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ |
506 map = get_keymap_1 (Fcar_safe (object), 0, autoload); | 526 map = get_keymap_1 (Fcar_safe (object), 0, autoload); |
507 tem = Fkeymapp (map); | 527 tem = Fkeymapp (map); |
508 if (!NILP (tem)) | 528 if (!NILP (tem)) |
509 object = access_keymap (map, Fcdr (object), 0, 0); | 529 { |
510 | 530 Lisp_Object key; |
531 key = Fcdr (object); | |
532 if (INTEGERP (key) && (XINT (key) & meta_modifier)) | |
533 { | |
534 object = access_keymap (map, make_number (meta_prefix_char), | |
535 0, 0); | |
536 map = get_keymap_1 (object, 0, autoload); | |
537 object = access_keymap (map, | |
538 make_number (XINT (key) & ~meta_modifier), | |
539 0, 0); | |
540 } | |
541 else | |
542 object = access_keymap (map, key, 0, 0); | |
543 } | |
544 | |
511 /* If the keymap contents looks like (STRING . DEFN), | 545 /* If the keymap contents looks like (STRING . DEFN), |
512 use DEFN. | 546 use DEFN. |
513 Keymap alist elements like (CHAR MENUSTRING . DEFN) | 547 Keymap alist elements like (CHAR MENUSTRING . DEFN) |
514 will be used by HierarKey menus. */ | 548 will be used by HierarKey menus. */ |
515 else if (CONSP (object) | 549 else if (CONSP (object) |
586 if (VECTORP (elt)) | 620 if (VECTORP (elt)) |
587 { | 621 { |
588 if (NATNUMP (idx) && XFASTINT (idx) < XVECTOR (elt)->size) | 622 if (NATNUMP (idx) && XFASTINT (idx) < XVECTOR (elt)->size) |
589 { | 623 { |
590 XVECTOR (elt)->contents[XFASTINT (idx)] = def; | 624 XVECTOR (elt)->contents[XFASTINT (idx)] = def; |
625 return def; | |
626 } | |
627 insertion_point = tail; | |
628 } | |
629 else if (CHAR_TABLE_P (elt)) | |
630 { | |
631 if (NATNUMP (idx)) | |
632 { | |
633 Faset (elt, idx, def); | |
591 return def; | 634 return def; |
592 } | 635 } |
593 insertion_point = tail; | 636 insertion_point = tail; |
594 } | 637 } |
595 else if (CONSP (elt)) | 638 else if (CONSP (elt)) |
621 } | 664 } |
622 | 665 |
623 return def; | 666 return def; |
624 } | 667 } |
625 | 668 |
669 Lisp_Object | |
670 copy_keymap_1 (chartable, idx, elt) | |
671 Lisp_Object chartable, idx, elt; | |
672 { | |
673 Faset (chartable, idx, Fcopy_keymap (elt)); | |
674 } | |
626 | 675 |
627 DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0, | 676 DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0, |
628 "Return a copy of the keymap KEYMAP.\n\ | 677 "Return a copy of the keymap KEYMAP.\n\ |
629 The copy starts out with the same definitions of KEYMAP,\n\ | 678 The copy starts out with the same definitions of KEYMAP,\n\ |
630 but changing either the copy or KEYMAP does not affect the other.\n\ | 679 but changing either the copy or KEYMAP does not affect the other.\n\ |
641 for (tail = copy; CONSP (tail); tail = XCONS (tail)->cdr) | 690 for (tail = copy; CONSP (tail); tail = XCONS (tail)->cdr) |
642 { | 691 { |
643 Lisp_Object elt; | 692 Lisp_Object elt; |
644 | 693 |
645 elt = XCONS (tail)->car; | 694 elt = XCONS (tail)->car; |
646 if (VECTORP (elt)) | 695 if (CHAR_TABLE_P (elt)) |
696 { | |
697 Lisp_Object *indices | |
698 = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object)); | |
699 | |
700 elt = Fcopy_sequence (elt); | |
701 map_char_table (copy_keymap_1, Qnil, elt, elt, 0, indices); | |
702 } | |
703 else if (VECTORP (elt)) | |
647 { | 704 { |
648 int i; | 705 int i; |
649 | 706 |
650 elt = Fcopy_sequence (elt); | 707 elt = Fcopy_sequence (elt); |
651 XCONS (tail)->car = elt; | 708 XCONS (tail)->car = elt; |
652 | 709 |
653 for (i = 0; i < XVECTOR (elt)->size; i++) | 710 for (i = 0; i < XVECTOR (elt)->size; i++) |
654 if (!SYMBOLP (XVECTOR (elt)->contents[i]) | 711 if (!SYMBOLP (XVECTOR (elt)->contents[i]) |
655 && ! NILP (Fkeymapp (XVECTOR (elt)->contents[i]))) | 712 && ! NILP (Fkeymapp (XVECTOR (elt)->contents[i]))) |
656 XVECTOR (elt)->contents[i] = | 713 XVECTOR (elt)->contents[i] |
657 Fcopy_keymap (XVECTOR (elt)->contents[i]); | 714 = Fcopy_keymap (XVECTOR (elt)->contents[i]); |
658 } | 715 } |
659 else if (CONSP (elt)) | 716 else if (CONSP (elt)) |
660 { | 717 { |
661 /* Skip the optional menu string. */ | 718 /* Skip the optional menu string. */ |
662 if (CONSP (XCONS (elt)->cdr) | 719 if (CONSP (XCONS (elt)->cdr) |
1266 return Flist (nmaps, maps); | 1323 return Flist (nmaps, maps); |
1267 } | 1324 } |
1268 | 1325 |
1269 /* Help functions for describing and documenting keymaps. */ | 1326 /* Help functions for describing and documenting keymaps. */ |
1270 | 1327 |
1328 static Lisp_Object accessible_keymaps_char_table (); | |
1329 | |
1271 /* This function cannot GC. */ | 1330 /* This function cannot GC. */ |
1272 | 1331 |
1273 DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps, | 1332 DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps, |
1274 1, 2, 0, | 1333 1, 2, 0, |
1275 "Find all keymaps accessible via prefix characters from KEYMAP.\n\ | 1334 "Find all keymaps accessible via prefix characters from KEYMAP.\n\ |
1356 | 1415 |
1357 elt = XCONS (thismap)->car; | 1416 elt = XCONS (thismap)->car; |
1358 | 1417 |
1359 QUIT; | 1418 QUIT; |
1360 | 1419 |
1361 if (VECTORP (elt)) | 1420 if (CHAR_TABLE_P (elt)) |
1421 { | |
1422 Lisp_Object *indices | |
1423 = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object)); | |
1424 | |
1425 map_char_table (accessible_keymaps_char_table, Qnil, | |
1426 elt, Fcons (maps, Fcons (tail, thisseq)), | |
1427 0, indices); | |
1428 } | |
1429 else if (VECTORP (elt)) | |
1362 { | 1430 { |
1363 register int i; | 1431 register int i; |
1364 | 1432 |
1365 /* Vector keymap. Scan all the elements. */ | 1433 /* Vector keymap. Scan all the elements. */ |
1366 for (i = 0; i < XVECTOR (elt)->size; i++) | 1434 for (i = 0; i < XVECTOR (elt)->size; i++) |
1402 nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil)); | 1470 nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil)); |
1403 } | 1471 } |
1404 } | 1472 } |
1405 } | 1473 } |
1406 } | 1474 } |
1407 } | 1475 } |
1408 else if (CONSP (elt)) | 1476 else if (CONSP (elt)) |
1409 { | 1477 { |
1410 register Lisp_Object cmd, tem, filter; | 1478 register Lisp_Object cmd, tem, filter; |
1411 | 1479 |
1412 cmd = get_keyelt (XCONS (elt)->cdr, 0); | 1480 cmd = get_keyelt (XCONS (elt)->cdr, 0); |
1479 } | 1547 } |
1480 | 1548 |
1481 return Fnreverse (good_maps); | 1549 return Fnreverse (good_maps); |
1482 } | 1550 } |
1483 | 1551 |
1552 static Lisp_Object | |
1553 accessible_keymaps_char_table (args, index, cmd) | |
1554 Lisp_Object args, index, cmd; | |
1555 { | |
1556 Lisp_Object tem; | |
1557 Lisp_Object maps, tail, thisseq; | |
1558 | |
1559 if (NILP (cmd)) | |
1560 return Qnil; | |
1561 | |
1562 maps = XCONS (args)->car; | |
1563 tail = XCONS (XCONS (args)->cdr)->car; | |
1564 thisseq = XCONS (XCONS (args)->cdr)->cdr; | |
1565 | |
1566 tem = Fkeymapp (cmd); | |
1567 if (!NILP (tem)) | |
1568 { | |
1569 cmd = get_keymap (cmd); | |
1570 /* Ignore keymaps that are already added to maps. */ | |
1571 tem = Frassq (cmd, maps); | |
1572 if (NILP (tem)) | |
1573 { | |
1574 tem = append_key (thisseq, index); | |
1575 nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil)); | |
1576 } | |
1577 } | |
1578 return Qnil; | |
1579 } | |
1580 | |
1484 Lisp_Object Qsingle_key_description, Qkey_description; | 1581 Lisp_Object Qsingle_key_description, Qkey_description; |
1485 | 1582 |
1486 /* This function cannot GC. */ | 1583 /* This function cannot GC. */ |
1487 | 1584 |
1488 DEFUN ("key-description", Fkey_description, Skey_description, 1, 1, 0, | 1585 DEFUN ("key-description", Fkey_description, Skey_description, 1, 1, 0, |
1744 return 1; | 1841 return 1; |
1745 } | 1842 } |
1746 | 1843 |
1747 | 1844 |
1748 /* where-is - finding a command in a set of keymaps. */ | 1845 /* where-is - finding a command in a set of keymaps. */ |
1846 | |
1847 static Lisp_Object where_is_internal_1 (); | |
1848 static Lisp_Object where_is_internal_2 (); | |
1749 | 1849 |
1750 /* This function can GC if Flookup_key autoloads any keymaps. */ | 1850 /* This function can GC if Flookup_key autoloads any keymaps. */ |
1751 | 1851 |
1752 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0, | 1852 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0, |
1753 "Return list of keys that invoke DEFINITION.\n\ | 1853 "Return list of keys that invoke DEFINITION.\n\ |
1767 (definition, keymap, firstonly, noindirect) | 1867 (definition, keymap, firstonly, noindirect) |
1768 Lisp_Object definition, keymap; | 1868 Lisp_Object definition, keymap; |
1769 Lisp_Object firstonly, noindirect; | 1869 Lisp_Object firstonly, noindirect; |
1770 { | 1870 { |
1771 Lisp_Object maps; | 1871 Lisp_Object maps; |
1772 Lisp_Object found, sequence; | 1872 Lisp_Object found, sequences; |
1773 int keymap_specified = !NILP (keymap); | 1873 int keymap_specified = !NILP (keymap); |
1774 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 1874 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
1775 /* 1 means ignore all menu bindings entirely. */ | 1875 /* 1 means ignore all menu bindings entirely. */ |
1776 int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii); | 1876 int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii); |
1777 | 1877 |
1803 maps); | 1903 maps); |
1804 minors = XCONS (minors)->cdr; | 1904 minors = XCONS (minors)->cdr; |
1805 } | 1905 } |
1806 } | 1906 } |
1807 | 1907 |
1808 GCPRO5 (definition, keymap, maps, found, sequence); | 1908 GCPRO5 (definition, keymap, maps, found, sequences); |
1809 found = Qnil; | 1909 found = Qnil; |
1810 sequence = Qnil; | 1910 sequences = Qnil; |
1811 | 1911 |
1812 for (; !NILP (maps); maps = Fcdr (maps)) | 1912 for (; !NILP (maps); maps = Fcdr (maps)) |
1813 { | 1913 { |
1814 /* Key sequence to reach map, and the map that it reaches */ | 1914 /* Key sequence to reach map, and the map that it reaches */ |
1815 register Lisp_Object this, map; | 1915 register Lisp_Object this, map; |
1816 | |
1817 /* If Fcar (map) is a VECTOR, the current element within that vector. */ | |
1818 int i = 0; | |
1819 | 1916 |
1820 /* In order to fold [META-PREFIX-CHAR CHAR] sequences into | 1917 /* In order to fold [META-PREFIX-CHAR CHAR] sequences into |
1821 [M-CHAR] sequences, check if last character of the sequence | 1918 [M-CHAR] sequences, check if last character of the sequence |
1822 is the meta-prefix char. */ | 1919 is the meta-prefix char. */ |
1823 Lisp_Object last; | 1920 Lisp_Object last; |
1839 loop body over both keymap and vector bindings. | 1936 loop body over both keymap and vector bindings. |
1840 | 1937 |
1841 For this reason, if Fcar (map) is a vector, we don't | 1938 For this reason, if Fcar (map) is a vector, we don't |
1842 advance map to the next element until i indicates that we | 1939 advance map to the next element until i indicates that we |
1843 have finished off the vector. */ | 1940 have finished off the vector. */ |
1844 | |
1845 Lisp_Object elt, key, binding; | 1941 Lisp_Object elt, key, binding; |
1846 elt = XCONS (map)->car; | 1942 elt = XCONS (map)->car; |
1943 map = XCONS (map)->cdr; | |
1944 | |
1945 sequences = Qnil; | |
1847 | 1946 |
1848 QUIT; | 1947 QUIT; |
1849 | 1948 |
1850 /* Set key and binding to the current key and binding, and | 1949 /* Set key and binding to the current key and binding, and |
1851 advance map and i to the next binding. */ | 1950 advance map and i to the next binding. */ |
1852 if (VECTORP (elt)) | 1951 if (VECTORP (elt)) |
1853 { | 1952 { |
1953 Lisp_Object sequence; | |
1954 int i; | |
1854 /* In a vector, look at each element. */ | 1955 /* In a vector, look at each element. */ |
1855 binding = XVECTOR (elt)->contents[i]; | 1956 for (i = 0; i < XVECTOR (elt)->size; i++) |
1856 XSETFASTINT (key, i); | |
1857 i++; | |
1858 | |
1859 /* If we've just finished scanning a vector, advance map | |
1860 to the next element, and reset i in anticipation of the | |
1861 next vector we may find. */ | |
1862 if (i >= XVECTOR (elt)->size) | |
1863 { | 1957 { |
1864 map = XCONS (map)->cdr; | 1958 binding = XVECTOR (elt)->contents[i]; |
1865 i = 0; | 1959 XSETFASTINT (key, i); |
1960 sequence = where_is_internal_1 (binding, key, definition, | |
1961 noindirect, keymap, this, | |
1962 last, nomenus, last_is_meta); | |
1963 if (!NILP (sequence)) | |
1964 sequences = Fcons (sequence, sequences); | |
1866 } | 1965 } |
1966 } | |
1967 else if (CHAR_TABLE_P (elt)) | |
1968 { | |
1969 Lisp_Object *indices | |
1970 = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object)); | |
1971 Lisp_Object args; | |
1972 args = Fcons (Fcons (Fcons (definition, noindirect), | |
1973 Fcons (keymap, Qnil)), | |
1974 Fcons (Fcons (this, last), | |
1975 Fcons (make_number (nomenus), | |
1976 make_number (last_is_meta)))); | |
1977 | |
1978 map_char_table (where_is_internal_2, Qnil, elt, args, | |
1979 0, indices); | |
1980 sequences = XCONS (XCONS (XCONS (args)->car)->cdr)->cdr; | |
1867 } | 1981 } |
1868 else if (CONSP (elt)) | 1982 else if (CONSP (elt)) |
1869 { | 1983 { |
1870 key = Fcar (Fcar (map)); | 1984 Lisp_Object sequence; |
1871 binding = Fcdr (Fcar (map)); | 1985 |
1872 | 1986 key = XCONS (elt)->car; |
1873 map = XCONS (map)->cdr; | 1987 binding = XCONS (elt)->cdr; |
1988 | |
1989 sequence = where_is_internal_1 (binding, key, definition, | |
1990 noindirect, keymap, this, | |
1991 last, nomenus, last_is_meta); | |
1992 if (!NILP (sequence)) | |
1993 sequences = Fcons (sequence, sequences); | |
1874 } | 1994 } |
1875 else | 1995 |
1876 /* We want to ignore keymap elements that are neither | 1996 |
1877 vectors nor conses. */ | 1997 for (; ! NILP (sequences); sequences = XCONS (sequences)->cdr) |
1878 { | 1998 { |
1879 map = XCONS (map)->cdr; | 1999 Lisp_Object sequence; |
1880 continue; | 2000 |
2001 sequence = XCONS (sequences)->car; | |
2002 | |
2003 /* It is a true unshadowed match. Record it, unless it's already | |
2004 been seen (as could happen when inheriting keymaps). */ | |
2005 if (NILP (Fmember (sequence, found))) | |
2006 found = Fcons (sequence, found); | |
2007 | |
2008 /* If firstonly is Qnon_ascii, then we can return the first | |
2009 binding we find. If firstonly is not Qnon_ascii but not | |
2010 nil, then we should return the first ascii-only binding | |
2011 we find. */ | |
2012 if (EQ (firstonly, Qnon_ascii)) | |
2013 RETURN_UNGCPRO (sequence); | |
2014 else if (! NILP (firstonly) && ascii_sequence_p (sequence)) | |
2015 RETURN_UNGCPRO (sequence); | |
1881 } | 2016 } |
1882 | |
1883 /* Search through indirections unless that's not wanted. */ | |
1884 if (NILP (noindirect)) | |
1885 { | |
1886 if (nomenus) | |
1887 { | |
1888 while (1) | |
1889 { | |
1890 Lisp_Object map, tem; | |
1891 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ | |
1892 map = get_keymap_1 (Fcar_safe (definition), 0, 0); | |
1893 tem = Fkeymapp (map); | |
1894 if (!NILP (tem)) | |
1895 definition = access_keymap (map, Fcdr (definition), 0, 0); | |
1896 else | |
1897 break; | |
1898 } | |
1899 /* If the contents are (STRING ...), reject. */ | |
1900 if (CONSP (definition) | |
1901 && STRINGP (XCONS (definition)->car)) | |
1902 continue; | |
1903 } | |
1904 else | |
1905 binding = get_keyelt (binding, 0); | |
1906 } | |
1907 | |
1908 /* End this iteration if this element does not match | |
1909 the target. */ | |
1910 | |
1911 if (CONSP (definition)) | |
1912 { | |
1913 Lisp_Object tem; | |
1914 tem = Fequal (binding, definition); | |
1915 if (NILP (tem)) | |
1916 continue; | |
1917 } | |
1918 else | |
1919 if (!EQ (binding, definition)) | |
1920 continue; | |
1921 | |
1922 /* We have found a match. | |
1923 Construct the key sequence where we found it. */ | |
1924 if (INTEGERP (key) && last_is_meta) | |
1925 { | |
1926 sequence = Fcopy_sequence (this); | |
1927 Faset (sequence, last, make_number (XINT (key) | meta_modifier)); | |
1928 } | |
1929 else | |
1930 sequence = append_key (this, key); | |
1931 | |
1932 /* Verify that this key binding is not shadowed by another | |
1933 binding for the same key, before we say it exists. | |
1934 | |
1935 Mechanism: look for local definition of this key and if | |
1936 it is defined and does not match what we found then | |
1937 ignore this key. | |
1938 | |
1939 Either nil or number as value from Flookup_key | |
1940 means undefined. */ | |
1941 if (keymap_specified) | |
1942 { | |
1943 binding = Flookup_key (keymap, sequence, Qnil); | |
1944 if (!NILP (binding) && !INTEGERP (binding)) | |
1945 { | |
1946 if (CONSP (definition)) | |
1947 { | |
1948 Lisp_Object tem; | |
1949 tem = Fequal (binding, definition); | |
1950 if (NILP (tem)) | |
1951 continue; | |
1952 } | |
1953 else | |
1954 if (!EQ (binding, definition)) | |
1955 continue; | |
1956 } | |
1957 } | |
1958 else | |
1959 { | |
1960 binding = Fkey_binding (sequence, Qnil); | |
1961 if (!EQ (binding, definition)) | |
1962 continue; | |
1963 } | |
1964 | |
1965 /* It is a true unshadowed match. Record it, unless it's already | |
1966 been seen (as could happen when inheriting keymaps). */ | |
1967 if (NILP (Fmember (sequence, found))) | |
1968 found = Fcons (sequence, found); | |
1969 | |
1970 /* If firstonly is Qnon_ascii, then we can return the first | |
1971 binding we find. If firstonly is not Qnon_ascii but not | |
1972 nil, then we should return the first ascii-only binding | |
1973 we find. */ | |
1974 if (EQ (firstonly, Qnon_ascii)) | |
1975 RETURN_UNGCPRO (sequence); | |
1976 else if (! NILP (firstonly) && ascii_sequence_p (sequence)) | |
1977 RETURN_UNGCPRO (sequence); | |
1978 } | 2017 } |
1979 } | 2018 } |
1980 | 2019 |
1981 UNGCPRO; | 2020 UNGCPRO; |
1982 | 2021 |
1987 return the best we could find. */ | 2026 return the best we could find. */ |
1988 if (! NILP (firstonly)) | 2027 if (! NILP (firstonly)) |
1989 return Fcar (found); | 2028 return Fcar (found); |
1990 | 2029 |
1991 return found; | 2030 return found; |
2031 } | |
2032 | |
2033 /* This is the function that Fwhere_is_internal calls using map_char_table. | |
2034 ARGS has the form | |
2035 (((DEFINITION . NOINDIRECT) . (KEYMAP . RESULT)) | |
2036 . | |
2037 ((THIS . LAST) . (NOMENUS . LAST_IS_META))) | |
2038 Since map_char_table doesn't really use the return value from this function, | |
2039 we the result append to RESULT, the slot in ARGS. */ | |
2040 | |
2041 static Lisp_Object | |
2042 where_is_internal_2 (args, key, binding) | |
2043 Lisp_Object args, key, binding; | |
2044 { | |
2045 Lisp_Object definition, noindirect, keymap, this, last; | |
2046 Lisp_Object result, sequence; | |
2047 int nomenus, last_is_meta; | |
2048 | |
2049 result = XCONS (XCONS (XCONS (args)->car)->cdr)->cdr; | |
2050 definition = XCONS (XCONS (XCONS (args)->car)->car)->car; | |
2051 noindirect = XCONS (XCONS (XCONS (args)->car)->car)->cdr; | |
2052 keymap = XCONS (XCONS (XCONS (args)->car)->cdr)->car; | |
2053 this = XCONS (XCONS (XCONS (args)->cdr)->car)->car; | |
2054 last = XCONS (XCONS (XCONS (args)->cdr)->car)->cdr; | |
2055 nomenus = XFASTINT (XCONS (XCONS (XCONS (args)->cdr)->cdr)->car); | |
2056 last_is_meta = XFASTINT (XCONS (XCONS (XCONS (args)->cdr)->cdr)->cdr); | |
2057 | |
2058 sequence = where_is_internal_1 (binding, key, definition, noindirect, keymap, | |
2059 this, last, nomenus, last_is_meta); | |
2060 | |
2061 if (!NILP (sequence)) | |
2062 XCONS (XCONS (XCONS (args)->car)->cdr)->cdr | |
2063 = Fcons (sequence, result); | |
2064 | |
2065 return Qnil; | |
2066 } | |
2067 | |
2068 static Lisp_Object | |
2069 where_is_internal_1 (binding, key, definition, noindirect, keymap, this, last, | |
2070 nomenus, last_is_meta) | |
2071 Lisp_Object binding, key, definition, noindirect, keymap, this, last; | |
2072 int nomenus, last_is_meta; | |
2073 { | |
2074 Lisp_Object sequence; | |
2075 int keymap_specified = !NILP (keymap); | |
2076 | |
2077 /* Search through indirections unless that's not wanted. */ | |
2078 if (NILP (noindirect)) | |
2079 { | |
2080 if (nomenus) | |
2081 { | |
2082 while (1) | |
2083 { | |
2084 Lisp_Object map, tem; | |
2085 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ | |
2086 map = get_keymap_1 (Fcar_safe (definition), 0, 0); | |
2087 tem = Fkeymapp (map); | |
2088 if (!NILP (tem)) | |
2089 definition = access_keymap (map, Fcdr (definition), 0, 0); | |
2090 else | |
2091 break; | |
2092 } | |
2093 /* If the contents are (STRING ...), reject. */ | |
2094 if (CONSP (definition) | |
2095 && STRINGP (XCONS (definition)->car)) | |
2096 return Qnil; | |
2097 } | |
2098 else | |
2099 binding = get_keyelt (binding, 0); | |
2100 } | |
2101 | |
2102 /* End this iteration if this element does not match | |
2103 the target. */ | |
2104 | |
2105 if (CONSP (definition)) | |
2106 { | |
2107 Lisp_Object tem; | |
2108 tem = Fequal (binding, definition); | |
2109 if (NILP (tem)) | |
2110 return Qnil; | |
2111 } | |
2112 else | |
2113 if (!EQ (binding, definition)) | |
2114 return Qnil; | |
2115 | |
2116 /* We have found a match. | |
2117 Construct the key sequence where we found it. */ | |
2118 if (INTEGERP (key) && last_is_meta) | |
2119 { | |
2120 sequence = Fcopy_sequence (this); | |
2121 Faset (sequence, last, make_number (XINT (key) | meta_modifier)); | |
2122 } | |
2123 else | |
2124 sequence = append_key (this, key); | |
2125 | |
2126 /* Verify that this key binding is not shadowed by another | |
2127 binding for the same key, before we say it exists. | |
2128 | |
2129 Mechanism: look for local definition of this key and if | |
2130 it is defined and does not match what we found then | |
2131 ignore this key. | |
2132 | |
2133 Either nil or number as value from Flookup_key | |
2134 means undefined. */ | |
2135 if (keymap_specified) | |
2136 { | |
2137 binding = Flookup_key (keymap, sequence, Qnil); | |
2138 if (!NILP (binding) && !INTEGERP (binding)) | |
2139 { | |
2140 if (CONSP (definition)) | |
2141 { | |
2142 Lisp_Object tem; | |
2143 tem = Fequal (binding, definition); | |
2144 if (NILP (tem)) | |
2145 return Qnil; | |
2146 } | |
2147 else | |
2148 if (!EQ (binding, definition)) | |
2149 return Qnil; | |
2150 } | |
2151 } | |
2152 else | |
2153 { | |
2154 binding = Fkey_binding (sequence, Qnil); | |
2155 if (!EQ (binding, definition)) | |
2156 return Qnil; | |
2157 } | |
2158 | |
2159 return sequence; | |
1992 } | 2160 } |
1993 | 2161 |
1994 /* describe-bindings - summarizing all the bindings in a set of keymaps. */ | 2162 /* describe-bindings - summarizing all the bindings in a set of keymaps. */ |
1995 | 2163 |
1996 DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 1, "", | 2164 DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 1, "", |
2401 | 2569 |
2402 for (tail = map; CONSP (tail); tail = XCONS (tail)->cdr) | 2570 for (tail = map; CONSP (tail); tail = XCONS (tail)->cdr) |
2403 { | 2571 { |
2404 QUIT; | 2572 QUIT; |
2405 | 2573 |
2406 if (VECTORP (XCONS (tail)->car)) | 2574 if (VECTORP (XCONS (tail)->car) |
2575 || CHAR_TABLE_P (XCONS (tail)->car)) | |
2407 describe_vector (XCONS (tail)->car, | 2576 describe_vector (XCONS (tail)->car, |
2408 elt_prefix, elt_describer, partial, shadow, map); | 2577 elt_prefix, elt_describer, partial, shadow, map, |
2578 (int *)0, 0); | |
2409 else if (CONSP (XCONS (tail)->car)) | 2579 else if (CONSP (XCONS (tail)->car)) |
2410 { | 2580 { |
2411 event = XCONS (XCONS (tail)->car)->car; | 2581 event = XCONS (XCONS (tail)->car)->car; |
2412 | 2582 |
2413 /* Ignore bindings whose "keys" are not really valid events. | 2583 /* Ignore bindings whose "keys" are not really valid events. |
2492 { | 2662 { |
2493 int count = specpdl_ptr - specpdl; | 2663 int count = specpdl_ptr - specpdl; |
2494 | 2664 |
2495 specbind (Qstandard_output, Fcurrent_buffer ()); | 2665 specbind (Qstandard_output, Fcurrent_buffer ()); |
2496 CHECK_VECTOR_OR_CHAR_TABLE (vector, 0); | 2666 CHECK_VECTOR_OR_CHAR_TABLE (vector, 0); |
2497 describe_vector (vector, Qnil, describe_vector_princ, 0, Qnil, Qnil); | 2667 describe_vector (vector, Qnil, describe_vector_princ, 0, |
2668 Qnil, Qnil, (int *)0, 0); | |
2498 | 2669 |
2499 return unbind_to (count, Qnil); | 2670 return unbind_to (count, Qnil); |
2500 } | 2671 } |
2501 | 2672 |
2502 /* Insert in the current buffer a description of the contents of VECTOR. | 2673 /* Insert in the current buffer a description of the contents of VECTOR. |
2503 We call ELT_DESCRIBER to insert the description of one value found | 2674 We call ELT_DESCRIBER to insert the description of one value found |
2504 in VECTOR. | 2675 in VECTOR. |
2505 | 2676 |
2506 ELT_PREFIX describes what "comes before" the keys or indices defined | 2677 ELT_PREFIX describes what "comes before" the keys or indices defined |
2507 by this vector. | 2678 by this vector. This is a human-readable string whose size |
2679 is not necessarily related to the situation. | |
2508 | 2680 |
2509 If the vector is in a keymap, ELT_PREFIX is a prefix key which | 2681 If the vector is in a keymap, ELT_PREFIX is a prefix key which |
2510 leads to this keymap. | 2682 leads to this keymap. |
2511 | 2683 |
2512 If the vector is a chartable, ELT_PREFIX is the vector | 2684 If the vector is a chartable, ELT_PREFIX is the vector |
2520 If it is non-nil, then we look up the key in those maps | 2692 If it is non-nil, then we look up the key in those maps |
2521 and we don't mention it now if it is defined by any of them. | 2693 and we don't mention it now if it is defined by any of them. |
2522 | 2694 |
2523 ENTIRE_MAP is the keymap in which this vector appears. | 2695 ENTIRE_MAP is the keymap in which this vector appears. |
2524 If the definition in effect in the whole map does not match | 2696 If the definition in effect in the whole map does not match |
2525 the one in this vector, we ignore this one. */ | 2697 the one in this vector, we ignore this one. |
2698 | |
2699 When describing a sub-char-table, INDICES is a list of | |
2700 indices at higher levels in this char-table, | |
2701 and CHAR_TABLE_DEPTH says how many levels down we have gone. */ | |
2526 | 2702 |
2527 describe_vector (vector, elt_prefix, elt_describer, | 2703 describe_vector (vector, elt_prefix, elt_describer, |
2528 partial, shadow, entire_map) | 2704 partial, shadow, entire_map, |
2705 indices, char_table_depth) | |
2529 register Lisp_Object vector; | 2706 register Lisp_Object vector; |
2530 Lisp_Object elt_prefix; | 2707 Lisp_Object elt_prefix; |
2531 int (*elt_describer) (); | 2708 int (*elt_describer) (); |
2532 int partial; | 2709 int partial; |
2533 Lisp_Object shadow; | 2710 Lisp_Object shadow; |
2534 Lisp_Object entire_map; | 2711 Lisp_Object entire_map; |
2535 { | 2712 int *indices; |
2536 Lisp_Object dummy; | 2713 int char_table_depth; |
2714 { | |
2537 Lisp_Object definition; | 2715 Lisp_Object definition; |
2538 Lisp_Object tem2; | 2716 Lisp_Object tem2; |
2539 register int i; | 2717 register int i; |
2540 Lisp_Object suppress; | 2718 Lisp_Object suppress; |
2541 Lisp_Object kludge; | 2719 Lisp_Object kludge; |
2542 Lisp_Object chartable_kludge; | |
2543 int first = 1; | 2720 int first = 1; |
2544 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 2721 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
2545 /* Range of elements to be handled. */ | 2722 /* Range of elements to be handled. */ |
2546 int from, to; | 2723 int from, to; |
2547 /* The current depth of VECTOR if it is char-table. */ | |
2548 int this_level; | |
2549 /* Flag to tell if we should handle multibyte characters. */ | 2724 /* Flag to tell if we should handle multibyte characters. */ |
2550 int multibyte = !NILP (current_buffer->enable_multibyte_characters); | 2725 int multibyte = !NILP (current_buffer->enable_multibyte_characters); |
2551 /* Array of indices to access each level of char-table. | |
2552 The elements are charset, code1, and code2. */ | |
2553 int idx[3]; | |
2554 /* A flag to tell if a leaf in this level of char-table is not a | 2726 /* A flag to tell if a leaf in this level of char-table is not a |
2555 generic character (i.e. a complete multibyte character). */ | 2727 generic character (i.e. a complete multibyte character). */ |
2556 int complete_char; | 2728 int complete_char; |
2729 int character; | |
2730 int starting_i; | |
2731 | |
2732 if (indices == 0) | |
2733 indices = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object)); | |
2557 | 2734 |
2558 definition = Qnil; | 2735 definition = Qnil; |
2559 | 2736 |
2560 /* This vector gets used to present single keys to Flookup_key. Since | 2737 /* This vector gets used to present single keys to Flookup_key. Since |
2561 that is done once per vector element, we don't want to cons up a | 2738 that is done once per vector element, we don't want to cons up a |
2562 fresh vector every time. */ | 2739 fresh vector every time. */ |
2563 kludge = Fmake_vector (make_number (1), Qnil); | 2740 kludge = Fmake_vector (make_number (1), Qnil); |
2564 GCPRO4 (elt_prefix, definition, kludge, chartable_kludge); | 2741 GCPRO3 (elt_prefix, definition, kludge); |
2565 | 2742 |
2566 if (partial) | 2743 if (partial) |
2567 suppress = intern ("suppress-keymap"); | 2744 suppress = intern ("suppress-keymap"); |
2568 | 2745 |
2569 if (CHAR_TABLE_P (vector)) | 2746 if (CHAR_TABLE_P (vector)) |
2570 { | 2747 { |
2571 /* Prepare for handling a nested char-table. */ | 2748 if (char_table_depth == 0) |
2572 if (NILP (elt_prefix)) | |
2573 { | 2749 { |
2574 /* VECTOR is a top level char-table. */ | 2750 /* VECTOR is a top level char-table. */ |
2575 this_level = 0; | 2751 complete_char = 1; |
2576 complete_char = 0; | |
2577 from = 0; | 2752 from = 0; |
2578 to = CHAR_TABLE_ORDINARY_SLOTS; | 2753 to = CHAR_TABLE_ORDINARY_SLOTS; |
2579 } | 2754 } |
2580 else | 2755 else |
2581 { | 2756 { |
2582 /* VECTOR is a sub char-table. */ | 2757 /* VECTOR is a sub char-table. */ |
2583 this_level = XVECTOR (elt_prefix)->size; | 2758 if (char_table_depth >= 3) |
2584 if (this_level >= 3) | 2759 /* A char-table is never that deep. */ |
2585 /* A char-table is not that deep. */ | |
2586 error ("Too deep char table"); | 2760 error ("Too deep char table"); |
2587 | 2761 |
2588 /* For multibyte characters, the top level index for | |
2589 charsets starts from 256. */ | |
2590 idx[0] = XINT (XVECTOR (elt_prefix)->contents[0]) - 128; | |
2591 for (i = 1; i < this_level; i++) | |
2592 idx[i] = XINT (XVECTOR (elt_prefix)->contents[i]); | |
2593 complete_char | 2762 complete_char |
2594 = (CHARSET_VALID_P (idx[0]) | 2763 = (CHARSET_VALID_P (indices[0]) |
2595 && ((CHARSET_DIMENSION (idx[0]) == 1 && this_level == 1) | 2764 && ((CHARSET_DIMENSION (indices[0]) == 1 |
2596 || this_level == 2)); | 2765 && char_table_depth == 1) |
2766 || char_table_depth == 2)); | |
2597 | 2767 |
2598 /* Meaningful elements are from 32th to 127th. */ | 2768 /* Meaningful elements are from 32th to 127th. */ |
2599 from = 32; | 2769 from = 32; |
2600 to = SUB_CHAR_TABLE_ORDINARY_SLOTS; | 2770 to = SUB_CHAR_TABLE_ORDINARY_SLOTS; |
2601 } | 2771 } |
2602 chartable_kludge = Fmake_vector (make_number (this_level + 1), Qnil); | |
2603 if (this_level != 0) | |
2604 bcopy (XVECTOR (elt_prefix)->contents, | |
2605 XVECTOR (chartable_kludge)->contents, | |
2606 this_level * sizeof (Lisp_Object)); | |
2607 } | 2772 } |
2608 else | 2773 else |
2609 { | 2774 { |
2610 this_level = 0; | 2775 /* This does the right thing for ordinary vectors. */ |
2776 | |
2777 complete_char = 1; | |
2611 from = 0; | 2778 from = 0; |
2612 /* This does the right thing for ordinary vectors. */ | 2779 to = XVECTOR (vector)->size; |
2613 to = XFASTINT (Flength (vector)); | |
2614 /* Now, can this be just `XVECTOR (vector)->size'? -- K.Handa */ | |
2615 } | 2780 } |
2616 | 2781 |
2617 for (i = from; i < to; i++) | 2782 for (i = from; i < to; i++) |
2618 { | 2783 { |
2619 QUIT; | 2784 QUIT; |
2620 | 2785 |
2621 if (CHAR_TABLE_P (vector)) | 2786 if (CHAR_TABLE_P (vector)) |
2622 { | 2787 { |
2788 if (char_table_depth == 0 && i >= CHAR_TABLE_SINGLE_BYTE_SLOTS) | |
2789 complete_char = 0; | |
2790 | |
2623 if (i >= CHAR_TABLE_SINGLE_BYTE_SLOTS | 2791 if (i >= CHAR_TABLE_SINGLE_BYTE_SLOTS |
2624 && !CHARSET_DEFINED_P (i - 128)) | 2792 && !CHARSET_DEFINED_P (i - 128)) |
2625 continue; | 2793 continue; |
2626 definition = get_keyelt (XCHAR_TABLE (vector)->contents[i], 0); | 2794 |
2795 definition | |
2796 = get_keyelt (XCHAR_TABLE (vector)->contents[i], 0); | |
2627 } | 2797 } |
2628 else | 2798 else |
2629 definition = get_keyelt (XVECTOR (vector)->contents[i], 0); | 2799 definition = get_keyelt (XVECTOR (vector)->contents[i], 0); |
2630 | 2800 |
2631 if (NILP (definition)) continue; | 2801 if (NILP (definition)) continue; |
2638 tem = Fget (definition, suppress); | 2808 tem = Fget (definition, suppress); |
2639 | 2809 |
2640 if (!NILP (tem)) continue; | 2810 if (!NILP (tem)) continue; |
2641 } | 2811 } |
2642 | 2812 |
2813 /* Set CHARACTER to the character this entry describes, if any. | |
2814 Also update *INDICES. */ | |
2815 if (CHAR_TABLE_P (vector)) | |
2816 { | |
2817 indices[char_table_depth] = i; | |
2818 | |
2819 if (char_table_depth == 0) | |
2820 { | |
2821 character = i; | |
2822 indices[0] = i - 128; | |
2823 } | |
2824 else if (complete_char) | |
2825 { | |
2826 character | |
2827 = MAKE_NON_ASCII_CHAR (indices[0], indices[1], indices[2]); | |
2828 } | |
2829 else | |
2830 character = 0; | |
2831 } | |
2832 else | |
2833 character = i; | |
2834 | |
2643 /* If this binding is shadowed by some other map, ignore it. */ | 2835 /* If this binding is shadowed by some other map, ignore it. */ |
2644 if (!NILP (shadow)) | 2836 if (!NILP (shadow) && complete_char) |
2645 { | 2837 { |
2646 Lisp_Object tem; | 2838 Lisp_Object tem; |
2647 | 2839 |
2648 XVECTOR (kludge)->contents[0] = make_number (i); | 2840 XVECTOR (kludge)->contents[0] = make_number (character); |
2649 tem = shadow_lookup (shadow, kludge, Qt); | 2841 tem = shadow_lookup (shadow, kludge, Qt); |
2650 | 2842 |
2651 if (!NILP (tem)) continue; | 2843 if (!NILP (tem)) continue; |
2652 } | 2844 } |
2653 | 2845 |
2654 /* Ignore this definition if it is shadowed by an earlier | 2846 /* Ignore this definition if it is shadowed by an earlier |
2655 one in the same keymap. */ | 2847 one in the same keymap. */ |
2656 if (!NILP (entire_map)) | 2848 if (!NILP (entire_map) && complete_char) |
2657 { | 2849 { |
2658 Lisp_Object tem; | 2850 Lisp_Object tem; |
2659 | 2851 |
2660 XVECTOR (kludge)->contents[0] = make_number (i); | 2852 XVECTOR (kludge)->contents[0] = make_number (character); |
2661 tem = Flookup_key (entire_map, kludge, Qt); | 2853 tem = Flookup_key (entire_map, kludge, Qt); |
2662 | 2854 |
2663 if (! EQ (tem, definition)) | 2855 if (! EQ (tem, definition)) |
2664 continue; | 2856 continue; |
2665 } | 2857 } |
2666 | 2858 |
2667 if (first) | 2859 if (first) |
2668 { | 2860 { |
2669 if (this_level == 0) | 2861 if (char_table_depth == 0) |
2670 insert ("\n", 1); | 2862 insert ("\n", 1); |
2671 first = 0; | 2863 first = 0; |
2672 } | 2864 } |
2673 | 2865 |
2674 /* If VECTOR is a sub char-table, show the depth by indentation. | 2866 /* For a sub char-table, show the depth by indentation. |
2675 THIS_LEVEL can be greater than 0 only for char-table. */ | 2867 CHAR_TABLE_DEPTH can be greater than 0 only for a char-table. */ |
2676 if (this_level > 0) | 2868 if (char_table_depth > 0) |
2677 insert (" ", this_level * 2); /* THIS_LEVEL is 1 or 2. */ | 2869 insert (" ", char_table_depth * 2); /* depth is 1 or 2. */ |
2678 | 2870 |
2679 /* Get a Lisp object for the character I. */ | 2871 /* Output the prefix that applies to every entry in this map. */ |
2680 XSETFASTINT (dummy, i); | 2872 if (!NILP (elt_prefix)) |
2681 | 2873 insert1 (elt_prefix); |
2682 if (this_level == 0 && CHAR_TABLE_P (vector)) | 2874 |
2683 { | 2875 /* Insert or describe the character this slot is for, |
2684 if (i < CHAR_TABLE_SINGLE_BYTE_SLOTS) | 2876 or a description of what it is for. */ |
2685 insert1 (Fsingle_key_description (dummy)); | 2877 if (SUB_CHAR_TABLE_P (vector)) |
2878 { | |
2879 if (complete_char) | |
2880 insert_char (character); | |
2881 else | |
2882 { | |
2883 /* We need an octal representation for this block of | |
2884 characters. */ | |
2885 char work[5]; | |
2886 sprintf (work, "\\%03o", i & 255); | |
2887 insert (work, 4); | |
2888 } | |
2889 } | |
2890 else if (CHAR_TABLE_P (vector)) | |
2891 { | |
2892 if (complete_char) | |
2893 insert1 (Fsingle_key_description (make_number (character))); | |
2686 else | 2894 else |
2687 { | 2895 { |
2688 /* Print the information for this character set. */ | 2896 /* Print the information for this character set. */ |
2689 insert_string ("<"); | 2897 insert_string ("<"); |
2690 tem2 = CHARSET_TABLE_INFO (i - 128, CHARSET_SHORT_NAME_IDX); | 2898 tem2 = CHARSET_TABLE_INFO (i - 128, CHARSET_SHORT_NAME_IDX); |
2693 else | 2901 else |
2694 insert ("?", 1); | 2902 insert ("?", 1); |
2695 insert (">", 1); | 2903 insert (">", 1); |
2696 } | 2904 } |
2697 } | 2905 } |
2698 else if (this_level > 0 && SUB_CHAR_TABLE_P (vector)) | |
2699 { | |
2700 if (complete_char) | |
2701 { | |
2702 /* Combine ELT_PREFIX with I to produce a character code, | |
2703 then insert that character's description. */ | |
2704 idx[this_level] = i; | |
2705 insert_char (MAKE_NON_ASCII_CHAR (idx[0], idx[1], idx[2])); | |
2706 } | |
2707 else | |
2708 { | |
2709 /* We need an octal representation for this block of | |
2710 characters. */ | |
2711 char work[5]; | |
2712 sprintf (work, "\\%03o", i & 255); | |
2713 insert (work, 4); | |
2714 } | |
2715 } | |
2716 else | 2906 else |
2717 { | 2907 { |
2718 /* Output the prefix that applies to every entry in this map. */ | 2908 insert1 (Fsingle_key_description (make_number (character))); |
2719 if (!NILP (elt_prefix)) | |
2720 insert1 (elt_prefix); | |
2721 | |
2722 /* Get the string to describe the character DUMMY, and print it. */ | |
2723 insert1 (Fsingle_key_description (dummy)); | |
2724 } | 2909 } |
2725 | 2910 |
2726 /* If we find a sub char-table within a char-table, | 2911 /* If we find a sub char-table within a char-table, |
2727 scan it recursively; it defines the details for | 2912 scan it recursively; it defines the details for |
2728 a character set or a portion of a character set. */ | 2913 a character set or a portion of a character set. */ |
2729 if (multibyte && CHAR_TABLE_P (vector) && SUB_CHAR_TABLE_P (definition)) | 2914 if (multibyte && CHAR_TABLE_P (vector) && SUB_CHAR_TABLE_P (definition)) |
2730 { | 2915 { |
2731 insert ("\n", 1); | 2916 insert ("\n", 1); |
2732 XVECTOR (chartable_kludge)->contents[this_level] = make_number (i); | 2917 describe_vector (definition, elt_prefix, elt_describer, |
2733 describe_vector (definition, chartable_kludge, elt_describer, | 2918 partial, shadow, entire_map, |
2734 partial, shadow, entire_map); | 2919 indices, char_table_depth + 1); |
2735 continue; | 2920 continue; |
2736 } | 2921 } |
2922 | |
2923 starting_i = i; | |
2737 | 2924 |
2738 /* Find all consecutive characters that have the same | 2925 /* Find all consecutive characters that have the same |
2739 definition. But, for elements of a top level char table, if | 2926 definition. But, for elements of a top level char table, if |
2740 they are for charsets, we had better describe one by one even | 2927 they are for charsets, we had better describe one by one even |
2741 if they have the same definition. */ | 2928 if they have the same definition. */ |
2742 if (CHAR_TABLE_P (vector)) | 2929 if (CHAR_TABLE_P (vector)) |
2743 { | 2930 { |
2744 if (this_level == 0) | 2931 int limit = to; |
2745 while (i + 1 < CHAR_TABLE_SINGLE_BYTE_SLOTS | 2932 |
2746 && (tem2 | 2933 if (char_table_depth == 0) |
2747 = get_keyelt (XCHAR_TABLE (vector)->contents[i + 1], 0), | 2934 limit = CHAR_TABLE_SINGLE_BYTE_SLOTS; |
2748 !NILP (tem2)) | 2935 |
2749 && !NILP (Fequal (tem2, definition))) | 2936 while (i + 1 < limit |
2750 i++; | 2937 && (tem2 = get_keyelt (XCHAR_TABLE (vector)->contents[i + 1], 0), |
2751 else | 2938 !NILP (tem2)) |
2752 while (i + 1 < to | 2939 && !NILP (Fequal (tem2, definition))) |
2753 && (tem2 = get_keyelt (XCHAR_TABLE (vector)->contents[i + 1], 0), | 2940 i++; |
2754 !NILP (tem2)) | |
2755 && !NILP (Fequal (tem2, definition))) | |
2756 i++; | |
2757 } | 2941 } |
2758 else | 2942 else |
2759 while (i + 1 < CHAR_TABLE_SINGLE_BYTE_SLOTS | 2943 while (i + 1 < to |
2760 && (tem2 = get_keyelt (XVECTOR (vector)->contents[i + 1], 0), | 2944 && (tem2 = get_keyelt (XVECTOR (vector)->contents[i + 1], 0), |
2761 !NILP (tem2)) | 2945 !NILP (tem2)) |
2762 && !NILP (Fequal (tem2, definition))) | 2946 && !NILP (Fequal (tem2, definition))) |
2763 i++; | 2947 i++; |
2764 | 2948 |
2765 | 2949 |
2766 /* If we have a range of more than one character, | 2950 /* If we have a range of more than one character, |
2767 print where the range reaches to. */ | 2951 print where the range reaches to. */ |
2768 | 2952 |
2769 if (i != XINT (dummy)) | 2953 if (i != starting_i) |
2770 { | 2954 { |
2771 insert (" .. ", 4); | 2955 insert (" .. ", 4); |
2956 | |
2957 if (!NILP (elt_prefix)) | |
2958 insert1 (elt_prefix); | |
2959 | |
2772 if (CHAR_TABLE_P (vector)) | 2960 if (CHAR_TABLE_P (vector)) |
2773 { | 2961 { |
2774 if (complete_char) | 2962 if (char_table_depth == 0) |
2775 { | 2963 { |
2776 idx[this_level] = i; | 2964 insert1 (Fsingle_key_description (make_number (i))); |
2777 insert_char (MAKE_NON_ASCII_CHAR (idx[0], idx[1], idx[2])); | |
2778 } | 2965 } |
2779 else if (this_level > 0) | 2966 else if (complete_char) |
2967 { | |
2968 indices[char_table_depth] = i; | |
2969 character | |
2970 = MAKE_NON_ASCII_CHAR (indices[0], indices[1], indices[2]); | |
2971 insert_char (character); | |
2972 } | |
2973 else | |
2780 { | 2974 { |
2781 char work[5]; | 2975 char work[5]; |
2782 sprintf (work, "\\%03o", i & 255); | 2976 sprintf (work, "\\%03o", i & 255); |
2783 insert (work, 4); | 2977 insert (work, 4); |
2784 } | 2978 } |
2785 else | |
2786 { | |
2787 XSETFASTINT (dummy, i); | |
2788 insert1 (Fsingle_key_description (dummy)); | |
2789 } | |
2790 } | 2979 } |
2791 else | 2980 else |
2792 { | 2981 { |
2793 if (!NILP (elt_prefix) && !CHAR_TABLE_P (vector)) | 2982 insert1 (Fsingle_key_description (make_number (i))); |
2794 insert1 (elt_prefix); | |
2795 | |
2796 XSETFASTINT (dummy, i); | |
2797 insert1 (Fsingle_key_description (dummy)); | |
2798 } | 2983 } |
2799 } | 2984 } |
2800 | 2985 |
2801 /* Print a description of the definition of this character. | 2986 /* Print a description of the definition of this character. |
2802 elt_describer will take care of spacing out far enough | 2987 elt_describer will take care of spacing out far enough |
2805 } | 2990 } |
2806 | 2991 |
2807 /* For (sub) char-table, print `defalt' slot at last. */ | 2992 /* For (sub) char-table, print `defalt' slot at last. */ |
2808 if (CHAR_TABLE_P (vector) && !NILP (XCHAR_TABLE (vector)->defalt)) | 2993 if (CHAR_TABLE_P (vector) && !NILP (XCHAR_TABLE (vector)->defalt)) |
2809 { | 2994 { |
2810 insert (" ", this_level * 2); | 2995 insert (" ", char_table_depth * 2); |
2811 insert_string ("<<default>>"); | 2996 insert_string ("<<default>>"); |
2812 (*elt_describer) (XCHAR_TABLE (vector)->defalt); | 2997 (*elt_describer) (XCHAR_TABLE (vector)->defalt); |
2813 } | 2998 } |
2814 | 2999 |
2815 UNGCPRO; | 3000 UNGCPRO; |
2856 Lisp_Object tem; | 3041 Lisp_Object tem; |
2857 | 3042 |
2858 Qkeymap = intern ("keymap"); | 3043 Qkeymap = intern ("keymap"); |
2859 staticpro (&Qkeymap); | 3044 staticpro (&Qkeymap); |
2860 | 3045 |
2861 /* Initialize the keymaps standardly used. | 3046 /* Now we are ready to set up this property, so we can |
2862 Each one is the value of a Lisp variable, and is also | 3047 create char tables. */ |
2863 pointed to by a C variable */ | 3048 Fput (Qkeymap, Qchar_table_extra_slots, make_number (0)); |
2864 | 3049 |
2865 global_map = Fcons (Qkeymap, | 3050 /* Initialize the keymaps standardly used. |
2866 Fcons (Fmake_vector (make_number (0400), Qnil), Qnil)); | 3051 Each one is the value of a Lisp variable, and is also |
3052 pointed to by a C variable */ | |
3053 | |
3054 global_map = Fmake_keymap (Qnil); | |
2867 Fset (intern ("global-map"), global_map); | 3055 Fset (intern ("global-map"), global_map); |
2868 | 3056 |
2869 current_global_map = global_map; | 3057 current_global_map = global_map; |
2870 staticpro (&global_map); | 3058 staticpro (&global_map); |
2871 staticpro (¤t_global_map); | 3059 staticpro (¤t_global_map); |