Mercurial > emacs
comparison src/keymap.c @ 17036:7e4c52fd4430
Include charset.h.
(push_key_description): If enable-multibyte-characters is t, use
octal representation for a code of range 128..255 as binary.
(Ftext_char_description): Handle multibyte characters.
(describe_vector): Provide prettier description of a char table
which contains multibyte characters.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Thu, 20 Feb 1997 06:51:14 +0000 |
parents | d9956cf6699b |
children | 60ad27660a65 |
comparison
equal
deleted
inserted
replaced
17035:275c20d27886 | 17036:7e4c52fd4430 |
---|---|
23 #include <stdio.h> | 23 #include <stdio.h> |
24 #undef NULL | 24 #undef NULL |
25 #include "lisp.h" | 25 #include "lisp.h" |
26 #include "commands.h" | 26 #include "commands.h" |
27 #include "buffer.h" | 27 #include "buffer.h" |
28 #include "charset.h" | |
28 #include "keyboard.h" | 29 #include "keyboard.h" |
29 #include "termhooks.h" | 30 #include "termhooks.h" |
30 #include "blockinput.h" | 31 #include "blockinput.h" |
31 #include "puresize.h" | 32 #include "puresize.h" |
32 | 33 |
1592 { | 1593 { |
1593 *p++ = 'S'; | 1594 *p++ = 'S'; |
1594 *p++ = 'P'; | 1595 *p++ = 'P'; |
1595 *p++ = 'C'; | 1596 *p++ = 'C'; |
1596 } | 1597 } |
1598 else if (c < 128) | |
1599 *p++ = c; | |
1597 else if (c < 256) | 1600 else if (c < 256) |
1598 *p++ = c; | 1601 { |
1602 if (current_buffer->enable_multibyte_characters) | |
1603 *p++ = c; | |
1604 else | |
1605 { | |
1606 *p++ = '\\'; | |
1607 *p++ = (7 & (c >> 6)) + '0'; | |
1608 *p++ = (7 & (c >> 3)) + '0'; | |
1609 *p++ = (7 & (c >> 0)) + '0'; | |
1610 } | |
1611 } | |
1599 else | 1612 else |
1600 { | 1613 { |
1601 *p++ = '\\'; | 1614 *p++ = '\\'; |
1602 *p++ = (7 & (c >> 15)) + '0'; | 1615 *p++ = (7 & (c >> 15)) + '0'; |
1603 *p++ = (7 & (c >> 12)) + '0'; | 1616 *p++ = (7 & (c >> 12)) + '0'; |
1670 Lisp_Object character; | 1683 Lisp_Object character; |
1671 { | 1684 { |
1672 char tem[6]; | 1685 char tem[6]; |
1673 | 1686 |
1674 CHECK_NUMBER (character, 0); | 1687 CHECK_NUMBER (character, 0); |
1688 | |
1689 if (!SINGLE_BYTE_CHAR_P (XFASTINT (character))) | |
1690 { | |
1691 char *str; | |
1692 int len = non_ascii_char_to_string (XFASTINT (character), tem, &str); | |
1693 | |
1694 return make_string (str, len); | |
1695 } | |
1675 | 1696 |
1676 *push_text_char_description (XINT (character) & 0377, tem) = 0; | 1697 *push_text_char_description (XINT (character) & 0377, tem) = 0; |
1677 | 1698 |
1678 return build_string (tem); | 1699 return build_string (tem); |
1679 } | 1700 } |
2489 int (*elt_describer) (); | 2510 int (*elt_describer) (); |
2490 int partial; | 2511 int partial; |
2491 Lisp_Object shadow; | 2512 Lisp_Object shadow; |
2492 Lisp_Object entire_map; | 2513 Lisp_Object entire_map; |
2493 { | 2514 { |
2494 Lisp_Object this; | |
2495 Lisp_Object dummy; | 2515 Lisp_Object dummy; |
2496 Lisp_Object definition; | 2516 Lisp_Object definition; |
2497 Lisp_Object tem2; | 2517 Lisp_Object tem2; |
2498 register int i; | 2518 register int i; |
2499 Lisp_Object suppress; | 2519 Lisp_Object suppress; |
2500 Lisp_Object kludge; | 2520 Lisp_Object kludge; |
2501 Lisp_Object chartable_kludge; | 2521 Lisp_Object chartable_kludge; |
2502 int first = 1; | 2522 int first = 1; |
2503 int size; | |
2504 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 2523 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
2524 /* Range of elements to be handled. */ | |
2525 int from, to; | |
2526 /* The current depth of VECTOR if it is char-table. */ | |
2527 int this_level; | |
2528 /* Array of indices to access each level of char-table. | |
2529 The elements are charset, code1, and code2. */ | |
2530 int idx[3]; | |
2531 /* A flag to tell if a leaf in this level of char-table is not a | |
2532 generic character (i.e. a complete multibyte character). */ | |
2533 int complete_char; | |
2505 | 2534 |
2506 definition = Qnil; | 2535 definition = Qnil; |
2507 chartable_kludge = Qnil; | |
2508 | 2536 |
2509 /* This vector gets used to present single keys to Flookup_key. Since | 2537 /* This vector gets used to present single keys to Flookup_key. Since |
2510 that is done once per vector element, we don't want to cons up a | 2538 that is done once per vector element, we don't want to cons up a |
2511 fresh vector every time. */ | 2539 fresh vector every time. */ |
2512 kludge = Fmake_vector (make_number (1), Qnil); | 2540 kludge = Fmake_vector (make_number (1), Qnil); |
2513 GCPRO4 (elt_prefix, definition, kludge, chartable_kludge); | 2541 GCPRO4 (elt_prefix, definition, kludge, chartable_kludge); |
2514 | 2542 |
2515 if (partial) | 2543 if (partial) |
2516 suppress = intern ("suppress-keymap"); | 2544 suppress = intern ("suppress-keymap"); |
2517 | 2545 |
2518 /* This does the right thing for char-tables as well as ordinary vectors. */ | 2546 if (CHAR_TABLE_P (vector)) |
2519 size = XFASTINT (Flength (vector)); | 2547 { |
2520 | 2548 /* Prepare for handling a nested char-table. */ |
2521 for (i = 0; i < size; i++) | 2549 if (NILP (elt_prefix)) |
2550 { | |
2551 /* VECTOR is the top level of char-table. */ | |
2552 this_level = 0; | |
2553 complete_char = 0; | |
2554 from = 0; | |
2555 to = CHAR_TABLE_ORDINARY_SLOTS; | |
2556 } | |
2557 else | |
2558 { | |
2559 /* VECTOR is the deeper level of char-table. */ | |
2560 this_level = XVECTOR (elt_prefix)->size; | |
2561 if (this_level >= 3) | |
2562 /* A char-table is not that deep. */ | |
2563 wrong_type_argument (Qchar_table_p, vector); | |
2564 | |
2565 for (i = 0; i < this_level; i++) | |
2566 idx[i] = XINT (XVECTOR (elt_prefix)->contents[i]); | |
2567 complete_char | |
2568 = (CHARSET_VALID_P (idx[0]) | |
2569 && ((CHARSET_DIMENSION (idx[0]) == 1 && this_level == 1) | |
2570 || this_level == 2)); | |
2571 | |
2572 /* Meaningful elements are from 32th to 127th. */ | |
2573 from = 32; | |
2574 to = 128; | |
2575 } | |
2576 chartable_kludge = Fmake_vector (make_number (this_level + 1), Qnil); | |
2577 if (this_level != 0) | |
2578 bcopy (XVECTOR (elt_prefix)->contents, | |
2579 XVECTOR (chartable_kludge)->contents, | |
2580 this_level * sizeof (Lisp_Object)); | |
2581 } | |
2582 else | |
2583 { | |
2584 this_level = 0; | |
2585 from = 0; | |
2586 /* This does the right thing for ordinary vectors. */ | |
2587 to = XFASTINT (Flength (vector)); | |
2588 /* Now, can this be just `XVECTOR (vector)->size'? -- K.Handa */ | |
2589 } | |
2590 | |
2591 for (i = from; i < to; i++) | |
2522 { | 2592 { |
2523 QUIT; | 2593 QUIT; |
2524 definition = get_keyelt (XVECTOR (vector)->contents[i], 0); | 2594 definition = get_keyelt (XVECTOR (vector)->contents[i], 0); |
2525 | 2595 |
2526 if (NILP (definition)) continue; | 2596 if (NILP (definition)) continue; |
2527 | 2597 |
2528 /* Don't mention suppressed commands. */ | 2598 /* Don't mention suppressed commands. */ |
2529 if (SYMBOLP (definition) && partial) | 2599 if (SYMBOLP (definition) && partial) |
2530 { | 2600 { |
2531 this = Fget (definition, suppress); | 2601 Lisp_Object tem; |
2532 if (!NILP (this)) | 2602 |
2533 continue; | 2603 tem = Fget (definition, suppress); |
2604 | |
2605 if (!NILP (tem)) continue; | |
2534 } | 2606 } |
2535 | 2607 |
2536 /* If this binding is shadowed by some other map, ignore it. */ | 2608 /* If this binding is shadowed by some other map, ignore it. */ |
2537 if (!NILP (shadow)) | 2609 if (!NILP (shadow)) |
2538 { | 2610 { |
2555 | 2627 |
2556 if (! EQ (tem, definition)) | 2628 if (! EQ (tem, definition)) |
2557 continue; | 2629 continue; |
2558 } | 2630 } |
2559 | 2631 |
2632 if (first) | |
2633 { | |
2634 if (this_level == 0) | |
2635 insert ("\n", 1); | |
2636 first = 0; | |
2637 } | |
2638 | |
2639 /* If VECTOR is a deeper char-table, show the depth by indentation. | |
2640 THIS_LEVEL can be greater than 0 only for char-table. */ | |
2641 if (this_level > 0) | |
2642 insert (" ", this_level * 2); /* THIS_LEVEL is 1 or 2. */ | |
2643 | |
2644 /* Get a Lisp object for the character I. */ | |
2645 XSETFASTINT (dummy, i); | |
2646 | |
2647 if (CHAR_TABLE_P (vector)) | |
2648 { | |
2649 if (complete_char) | |
2650 { | |
2651 /* Combine ELT_PREFIX with I to produce a character code, | |
2652 then insert that character's description. */ | |
2653 idx[this_level] = i; | |
2654 insert_char (MAKE_NON_ASCII_CHAR (idx[0], idx[1], idx[2])); | |
2655 } | |
2656 else if (this_level > 0) | |
2657 { | |
2658 /* We need an octal representation. */ | |
2659 char work[5]; | |
2660 sprintf (work, "\\%03o", i & 255); | |
2661 insert (work, 4); | |
2662 } | |
2663 else | |
2664 insert1 (Fsingle_key_description (dummy)); | |
2665 } | |
2666 else | |
2667 { | |
2668 /* Output the prefix that applies to every entry in this map. */ | |
2669 if (!NILP (elt_prefix)) | |
2670 insert1 (elt_prefix); | |
2671 | |
2672 /* Get the string to describe the character DUMMY, and print it. */ | |
2673 insert1 (Fsingle_key_description (dummy)); | |
2674 } | |
2675 | |
2560 /* If we find a char-table within a char-table, | 2676 /* If we find a char-table within a char-table, |
2561 scan it recursively; it defines the details for | 2677 scan it recursively; it defines the details for |
2562 a character set or a portion of a character set. */ | 2678 a character set or a portion of a character set. */ |
2563 if (CHAR_TABLE_P (vector) && CHAR_TABLE_P (definition)) | 2679 if (CHAR_TABLE_P (vector) && CHAR_TABLE_P (definition)) |
2564 { | 2680 { |
2565 int outer_level | 2681 if (this_level == 0 |
2566 = !NILP (elt_prefix) ? XVECTOR (elt_prefix)->size : 0; | 2682 && CHARSET_VALID_P (i)) |
2567 if (NILP (chartable_kludge)) | |
2568 { | 2683 { |
2569 chartable_kludge | 2684 /* Before scanning the deeper table, print the |
2570 = Fmake_vector (make_number (outer_level + 1), Qnil); | 2685 information for this character set. */ |
2571 if (outer_level != 0) | 2686 insert_string ("\t\t<charset:"); |
2572 bcopy (XVECTOR (elt_prefix)->contents, | 2687 tem2 = CHARSET_TABLE_INFO (i, CHARSET_SHORT_NAME_IDX); |
2573 XVECTOR (chartable_kludge)->contents, | 2688 insert_from_string (tem2, 0 , XSTRING (tem2)->size, 0); |
2574 outer_level * sizeof (Lisp_Object)); | 2689 insert (">", 1); |
2575 } | 2690 } |
2576 XVECTOR (chartable_kludge)->contents[outer_level] | 2691 |
2577 = make_number (i); | 2692 insert ("\n", 1); |
2693 XVECTOR (chartable_kludge)->contents[this_level] = make_number (i); | |
2578 describe_vector (definition, chartable_kludge, elt_describer, | 2694 describe_vector (definition, chartable_kludge, elt_describer, |
2579 partial, shadow, entire_map); | 2695 partial, shadow, entire_map); |
2580 continue; | 2696 continue; |
2581 } | 2697 } |
2582 | 2698 |
2583 if (first) | |
2584 { | |
2585 insert ("\n", 1); | |
2586 first = 0; | |
2587 } | |
2588 | |
2589 if (CHAR_TABLE_P (vector)) | |
2590 { | |
2591 if (!NILP (elt_prefix)) | |
2592 { | |
2593 /* Must combine elt_prefix with i to produce a character | |
2594 code, then insert that character's description. */ | |
2595 } | |
2596 else | |
2597 { | |
2598 /* Get the string to describe the character I, and print it. */ | |
2599 XSETFASTINT (dummy, i); | |
2600 | |
2601 /* THIS gets the string to describe the character DUMMY. */ | |
2602 this = Fsingle_key_description (dummy); | |
2603 insert1 (this); | |
2604 } | |
2605 } | |
2606 else | |
2607 { | |
2608 /* Output the prefix that applies to every entry in this map. */ | |
2609 if (!NILP (elt_prefix)) | |
2610 insert1 (elt_prefix); | |
2611 | |
2612 /* Get the string to describe the character I, and print it. */ | |
2613 XSETFASTINT (dummy, i); | |
2614 | |
2615 /* THIS gets the string to describe the character DUMMY. */ | |
2616 this = Fsingle_key_description (dummy); | |
2617 insert1 (this); | |
2618 } | |
2619 | |
2620 /* Find all consecutive characters that have the same definition. */ | 2699 /* Find all consecutive characters that have the same definition. */ |
2621 while (i + 1 < XVECTOR (vector)->size | 2700 while (i + 1 < to |
2622 && (tem2 = get_keyelt (XVECTOR (vector)->contents[i+1], 0), | 2701 && (tem2 = get_keyelt (XVECTOR (vector)->contents[i+1], 0), |
2623 EQ (tem2, definition))) | 2702 !NILP (tem2)) |
2703 && !NILP (Fequal (tem2, definition))) | |
2624 i++; | 2704 i++; |
2625 | 2705 |
2626 /* If we have a range of more than one character, | 2706 /* If we have a range of more than one character, |
2627 print where the range reaches to. */ | 2707 print where the range reaches to. */ |
2628 | 2708 |
2629 if (i != XINT (dummy)) | 2709 if (i != XINT (dummy)) |
2630 { | 2710 { |
2631 insert (" .. ", 4); | 2711 insert (" .. ", 4); |
2632 if (CHAR_TABLE_P (vector)) | 2712 if (CHAR_TABLE_P (vector)) |
2633 { | 2713 { |
2634 if (!NILP (elt_prefix)) | 2714 if (complete_char) |
2635 { | 2715 { |
2636 /* Must combine elt_prefix with i to produce a character | 2716 idx[this_level] = i; |
2637 code, then insert that character's description. */ | 2717 insert_char (MAKE_NON_ASCII_CHAR (idx[0], idx[1], idx[2])); |
2718 } | |
2719 else if (this_level > 0) | |
2720 { | |
2721 char work[5]; | |
2722 sprintf (work, "\\%03o", i & 255); | |
2723 insert (work, 4); | |
2638 } | 2724 } |
2639 else | 2725 else |
2640 { | 2726 { |
2641 XSETFASTINT (dummy, i); | 2727 XSETFASTINT (dummy, i); |
2642 | 2728 insert1 (Fsingle_key_description (dummy)); |
2643 this = Fsingle_key_description (dummy); | |
2644 insert1 (this); | |
2645 } | 2729 } |
2646 } | 2730 } |
2647 else | 2731 else |
2648 { | 2732 { |
2649 if (!NILP (elt_prefix)) | 2733 if (!NILP (elt_prefix) && !CHAR_TABLE_P (vector)) |
2650 insert1 (elt_prefix); | 2734 insert1 (elt_prefix); |
2651 | 2735 |
2652 XSETFASTINT (dummy, i); | 2736 XSETFASTINT (dummy, i); |
2653 insert1 (Fsingle_key_description (dummy)); | 2737 insert1 (Fsingle_key_description (dummy)); |
2654 } | 2738 } |
2656 | 2740 |
2657 /* Print a description of the definition of this character. | 2741 /* Print a description of the definition of this character. |
2658 elt_describer will take care of spacing out far enough | 2742 elt_describer will take care of spacing out far enough |
2659 for alignment purposes. */ | 2743 for alignment purposes. */ |
2660 (*elt_describer) (definition); | 2744 (*elt_describer) (definition); |
2745 } | |
2746 | |
2747 /* For char-table, print `defalt' slot at last. */ | |
2748 if (CHAR_TABLE_P (vector) && !NILP (XCHAR_TABLE (vector)->defalt)) | |
2749 { | |
2750 insert (" ", this_level * 2); | |
2751 insert_string ("<<default>>"); | |
2752 (*elt_describer) (XCHAR_TABLE (vector)->defalt); | |
2661 } | 2753 } |
2662 | 2754 |
2663 UNGCPRO; | 2755 UNGCPRO; |
2664 } | 2756 } |
2665 | 2757 |