diff options
| author | Karl Heuer | 1997-02-20 06:51:14 +0000 |
|---|---|---|
| committer | Karl Heuer | 1997-02-20 06:51:14 +0000 |
| commit | a98f1d1dbc78aa6b0003eea3e6fa21a9320203a3 (patch) | |
| tree | e74c41fcda7a91a30d529aa344559fa0d8abe573 /src | |
| parent | 37cd9f309e978b17de5dd314d880446c675181f9 (diff) | |
| download | emacs-a98f1d1dbc78aa6b0003eea3e6fa21a9320203a3.tar.gz emacs-a98f1d1dbc78aa6b0003eea3e6fa21a9320203a3.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keymap.c | 208 |
1 files changed, 150 insertions, 58 deletions
diff --git a/src/keymap.c b/src/keymap.c index 71713a1e635..e6c79606eae 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ | |||
| 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" |
| @@ -1594,8 +1595,20 @@ push_key_description (c, p) | |||
| 1594 | *p++ = 'P'; | 1595 | *p++ = 'P'; |
| 1595 | *p++ = 'C'; | 1596 | *p++ = 'C'; |
| 1596 | } | 1597 | } |
| 1597 | else if (c < 256) | 1598 | else if (c < 128) |
| 1598 | *p++ = c; | 1599 | *p++ = c; |
| 1600 | else if (c < 256) | ||
| 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++ = '\\'; |
| @@ -1673,6 +1686,14 @@ Control characters turn into \"^char\", etc.") | |||
| 1673 | 1686 | ||
| 1674 | CHECK_NUMBER (character, 0); | 1687 | CHECK_NUMBER (character, 0); |
| 1675 | 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 | } | ||
| 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); |
| @@ -2491,7 +2512,6 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 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; |
| @@ -2500,11 +2520,19 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 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 |
| @@ -2515,10 +2543,52 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 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 | { |
| 2548 | /* Prepare for handling a nested char-table. */ | ||
| 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 | } | ||
| 2520 | 2590 | ||
| 2521 | for (i = 0; i < size; i++) | 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); |
| @@ -2528,9 +2598,11 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 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. */ |
| @@ -2557,51 +2629,39 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 2557 | continue; | 2629 | continue; |
| 2558 | } | 2630 | } |
| 2559 | 2631 | ||
| 2560 | /* If we find a char-table within a char-table, | ||
| 2561 | scan it recursively; it defines the details for | ||
| 2562 | a character set or a portion of a character set. */ | ||
| 2563 | if (CHAR_TABLE_P (vector) && CHAR_TABLE_P (definition)) | ||
| 2564 | { | ||
| 2565 | int outer_level | ||
| 2566 | = !NILP (elt_prefix) ? XVECTOR (elt_prefix)->size : 0; | ||
| 2567 | if (NILP (chartable_kludge)) | ||
| 2568 | { | ||
| 2569 | chartable_kludge | ||
| 2570 | = Fmake_vector (make_number (outer_level + 1), Qnil); | ||
| 2571 | if (outer_level != 0) | ||
| 2572 | bcopy (XVECTOR (elt_prefix)->contents, | ||
| 2573 | XVECTOR (chartable_kludge)->contents, | ||
| 2574 | outer_level * sizeof (Lisp_Object)); | ||
| 2575 | } | ||
| 2576 | XVECTOR (chartable_kludge)->contents[outer_level] | ||
| 2577 | = make_number (i); | ||
| 2578 | describe_vector (definition, chartable_kludge, elt_describer, | ||
| 2579 | partial, shadow, entire_map); | ||
| 2580 | continue; | ||
| 2581 | } | ||
| 2582 | |||
| 2583 | if (first) | 2632 | if (first) |
| 2584 | { | 2633 | { |
| 2585 | insert ("\n", 1); | 2634 | if (this_level == 0) |
| 2635 | insert ("\n", 1); | ||
| 2586 | first = 0; | 2636 | first = 0; |
| 2587 | } | 2637 | } |
| 2588 | 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 | |||
| 2589 | if (CHAR_TABLE_P (vector)) | 2647 | if (CHAR_TABLE_P (vector)) |
| 2590 | { | 2648 | { |
| 2591 | if (!NILP (elt_prefix)) | 2649 | if (complete_char) |
| 2592 | { | 2650 | { |
| 2593 | /* Must combine elt_prefix with i to produce a character | 2651 | /* Combine ELT_PREFIX with I to produce a character code, |
| 2594 | code, then insert that character's description. */ | 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])); | ||
| 2595 | } | 2655 | } |
| 2596 | else | 2656 | else if (this_level > 0) |
| 2597 | { | 2657 | { |
| 2598 | /* Get the string to describe the character I, and print it. */ | 2658 | /* We need an octal representation. */ |
| 2599 | XSETFASTINT (dummy, i); | 2659 | char work[5]; |
| 2600 | 2660 | sprintf (work, "\\%03o", i & 255); | |
| 2601 | /* THIS gets the string to describe the character DUMMY. */ | 2661 | insert (work, 4); |
| 2602 | this = Fsingle_key_description (dummy); | ||
| 2603 | insert1 (this); | ||
| 2604 | } | 2662 | } |
| 2663 | else | ||
| 2664 | insert1 (Fsingle_key_description (dummy)); | ||
| 2605 | } | 2665 | } |
| 2606 | else | 2666 | else |
| 2607 | { | 2667 | { |
| @@ -2609,18 +2669,38 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 2609 | if (!NILP (elt_prefix)) | 2669 | if (!NILP (elt_prefix)) |
| 2610 | insert1 (elt_prefix); | 2670 | insert1 (elt_prefix); |
| 2611 | 2671 | ||
| 2612 | /* Get the string to describe the character I, and print it. */ | 2672 | /* Get the string to describe the character DUMMY, and print it. */ |
| 2613 | XSETFASTINT (dummy, i); | 2673 | insert1 (Fsingle_key_description (dummy)); |
| 2674 | } | ||
| 2614 | 2675 | ||
| 2615 | /* THIS gets the string to describe the character DUMMY. */ | 2676 | /* If we find a char-table within a char-table, |
| 2616 | this = Fsingle_key_description (dummy); | 2677 | scan it recursively; it defines the details for |
| 2617 | insert1 (this); | 2678 | a character set or a portion of a character set. */ |
| 2679 | if (CHAR_TABLE_P (vector) && CHAR_TABLE_P (definition)) | ||
| 2680 | { | ||
| 2681 | if (this_level == 0 | ||
| 2682 | && CHARSET_VALID_P (i)) | ||
| 2683 | { | ||
| 2684 | /* Before scanning the deeper table, print the | ||
| 2685 | information for this character set. */ | ||
| 2686 | insert_string ("\t\t<charset:"); | ||
| 2687 | tem2 = CHARSET_TABLE_INFO (i, CHARSET_SHORT_NAME_IDX); | ||
| 2688 | insert_from_string (tem2, 0 , XSTRING (tem2)->size, 0); | ||
| 2689 | insert (">", 1); | ||
| 2690 | } | ||
| 2691 | |||
| 2692 | insert ("\n", 1); | ||
| 2693 | XVECTOR (chartable_kludge)->contents[this_level] = make_number (i); | ||
| 2694 | describe_vector (definition, chartable_kludge, elt_describer, | ||
| 2695 | partial, shadow, entire_map); | ||
| 2696 | continue; | ||
| 2618 | } | 2697 | } |
| 2619 | 2698 | ||
| 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, |
| @@ -2631,22 +2711,26 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 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) |
| 2715 | { | ||
| 2716 | idx[this_level] = i; | ||
| 2717 | insert_char (MAKE_NON_ASCII_CHAR (idx[0], idx[1], idx[2])); | ||
| 2718 | } | ||
| 2719 | else if (this_level > 0) | ||
| 2635 | { | 2720 | { |
| 2636 | /* Must combine elt_prefix with i to produce a character | 2721 | char work[5]; |
| 2637 | code, then insert that character's description. */ | 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); |
| @@ -2660,6 +2744,14 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 2660 | (*elt_describer) (definition); | 2744 | (*elt_describer) (definition); |
| 2661 | } | 2745 | } |
| 2662 | 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); | ||
| 2753 | } | ||
| 2754 | |||
| 2663 | UNGCPRO; | 2755 | UNGCPRO; |
| 2664 | } | 2756 | } |
| 2665 | 2757 | ||