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