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); |
