diff options
| author | Kenichi Handa | 2000-09-07 02:38:46 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-09-07 02:38:46 +0000 |
| commit | 95109387d74c66fe02402bddb3fb5009b0550919 (patch) | |
| tree | 5f380284a277f13e42cb8f14379d6431acd397db | |
| parent | d0c40faabe3650a9f8c1ee1d11b3ac1b6cc09d25 (diff) | |
| download | emacs-95109387d74c66fe02402bddb3fb5009b0550919.tar.gz emacs-95109387d74c66fe02402bddb3fb5009b0550919.zip | |
Don't require face.
(quail): New group.
(quail-other-command): Dummy command to make quail-help works
better.
(quail-keyboard-layout-alist): Add Keyboard type "jp106".
(quail-keyboard-layout-substitution): New variable.
(quail-update-keyboard-layout): New function.
(quail-keyboard-layout-type): New customizable variable.
(quail-set-keyboard-layout): Call quail-update-keyboard-layout.
(quail-keyboard-translate): Pay attention to
quail-keyboard-layout-substitution.
(quail-insert-kbd-layout): New function.
(quail-show-keyboard-layout): New function.
(quail-get-translation): If the definition is a vector of length
1, and the element is a string of lenght 1, return the character
in that string.
(quail-update-current-translations): Fix the case of
relative-index out of range.
(quail-build-decode-map, quail-insert-decode-map): New Functions.
(quail-help): Show keyboard layout by quail-insert-kbd-layout.
Show key sequences for all avairable characters.
(quail-help-insert-keymap-description): Don't show such verbose
key bindings as quail-self-insert-command.
| -rw-r--r-- | lisp/international/quail.el | 525 |
1 files changed, 430 insertions, 95 deletions
diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 710f8c87d54..22e24f3fa37 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el | |||
| @@ -43,7 +43,9 @@ | |||
| 43 | 43 | ||
| 44 | ;;; Code: | 44 | ;;; Code: |
| 45 | 45 | ||
| 46 | (require 'faces) | 46 | (defgroup quail nil |
| 47 | "Quail: multilingual input method." | ||
| 48 | :group 'leim) | ||
| 47 | 49 | ||
| 48 | ;; Buffer local variables | 50 | ;; Buffer local variables |
| 49 | 51 | ||
| @@ -270,6 +272,15 @@ Only a few especially complex input methods use this map; | |||
| 270 | most use `quail-simple-translation-keymap' instead. | 272 | most use `quail-simple-translation-keymap' instead. |
| 271 | This map is activated while translation region is active.") | 273 | This map is activated while translation region is active.") |
| 272 | 274 | ||
| 275 | ;; Hide some verbose commands to make the output of quail-help | ||
| 276 | ;; concise. | ||
| 277 | (let ((l '(quail-other-command | ||
| 278 | quail-self-insert-command | ||
| 279 | quail-delete-last-char))) | ||
| 280 | (while l | ||
| 281 | (put (car l) 'quail-help-hide t) | ||
| 282 | (setq l (cdr l)))) | ||
| 283 | |||
| 273 | (defvar quail-simple-translation-keymap | 284 | (defvar quail-simple-translation-keymap |
| 274 | (let ((map (make-keymap)) | 285 | (let ((map (make-keymap)) |
| 275 | (i 0)) | 286 | (i 0)) |
| @@ -319,6 +330,11 @@ This map is activated while translation region is active.") | |||
| 319 | This map is activated while conversion region is active but translation | 330 | This map is activated while conversion region is active but translation |
| 320 | region is not active.") | 331 | region is not active.") |
| 321 | 332 | ||
| 333 | ;; Just a dummy definition. | ||
| 334 | (defun quail-other-command () | ||
| 335 | (interactive) | ||
| 336 | ) | ||
| 337 | |||
| 322 | ;;;###autoload | 338 | ;;;###autoload |
| 323 | (defun quail-define-package (name language title | 339 | (defun quail-define-package (name language title |
| 324 | &optional guidance docstring translation-keys | 340 | &optional guidance docstring translation-keys |
| @@ -562,6 +578,7 @@ The command `quail-set-keyboard-layout' usually sets this variable.") | |||
| 562 | 578 | ||
| 563 | (defvar quail-keyboard-layout-alist | 579 | (defvar quail-keyboard-layout-alist |
| 564 | (list | 580 | (list |
| 581 | (cons "standard" quail-keyboard-layout-standard) | ||
| 565 | '("sun-type3" . "\ | 582 | '("sun-type3" . "\ |
| 566 | \ | 583 | \ |
| 567 | 1!2@3#4$5%6^7&8*9(0)-_=+\\|`~\ | 584 | 1!2@3#4$5%6^7&8*9(0)-_=+\\|`~\ |
| @@ -585,10 +602,61 @@ The command `quail-set-keyboard-layout' usually sets this variable.") | |||
| 585 | <>yYxXcCvVbBnNmM,;.:-_ \ | 602 | <>yYxXcCvVbBnNmM,;.:-_ \ |
| 586 | ") | 603 | ") |
| 587 | 604 | ||
| 588 | (cons "standard" quail-keyboard-layout-standard)) | 605 | '("jp106" . "\ |
| 606 | \ | ||
| 607 | 1!2\"3#4$5%6&7'8(9)0~-=^~\\| \ | ||
| 608 | qQwWeErRtTyYuUiIoOpP@`[{ \ | ||
| 609 | aAsSdDfFgGhHjJkKlL;+:*]} \ | ||
| 610 | zZxXcCvVbBnNmM,<.>/?\\_ \ | ||
| 611 | ") | ||
| 612 | ) | ||
| 589 | "Alist of keyboard names and corresponding layout strings. | 613 | "Alist of keyboard names and corresponding layout strings. |
| 590 | See the documentation of `quail-keyboard-layout' for the format of | 614 | See the documentation of `quail-keyboard-layout' for the format of |
| 591 | the layout string.") | 615 | the layout string.") |
| 616 | |||
| 617 | ;; A non-standard keyboard layout may miss some key locations of the | ||
| 618 | ;; standard layout while having additional key locations not in the | ||
| 619 | ;; standard layout. This alist maps those additional key locations to | ||
| 620 | ;; the missing locations. The value is updated automatically by | ||
| 621 | ;; quail-set-keyboard-layout. | ||
| 622 | (defvar quail-keyboard-layout-substitution nil) | ||
| 623 | |||
| 624 | (defun quail-update-keyboard-layout (kbd-type) | ||
| 625 | (let ((layout (assoc kbd-type quail-keyboard-layout-alist))) | ||
| 626 | (if (null layout) | ||
| 627 | ;; Here, we had better ask a user to define his own keyboard | ||
| 628 | ;; layout interactively. | ||
| 629 | (error "Unknown keyboard type `%s'" kbd-type)) | ||
| 630 | (setq quail-keyboard-layout (cdr layout)) | ||
| 631 | (let ((i quail-keyboard-layout-len) | ||
| 632 | subst-list missing-list) | ||
| 633 | ;; Sum up additional key locations not in the standard layout in | ||
| 634 | ;; subst-list, and missing key locations in missing-list. | ||
| 635 | (while (> i 0) | ||
| 636 | (setq i (1- i)) | ||
| 637 | (if (= (aref quail-keyboard-layout i) ? ) | ||
| 638 | (if (/= (aref quail-keyboard-layout-standard i) ? ) | ||
| 639 | (setq missing-list (cons i missing-list))) | ||
| 640 | (if (= (aref quail-keyboard-layout-standard i) ? ) | ||
| 641 | (setq subst-list (cons (cons i nil) subst-list))))) | ||
| 642 | (setq quail-keyboard-layout-substitution subst-list) | ||
| 643 | ;; If there are additional key locations, map them to missing | ||
| 644 | ;; key locations. | ||
| 645 | (while missing-list | ||
| 646 | (while (and subst-list (cdr (car subst-list))) | ||
| 647 | (setq subst-list (cdr subst-list))) | ||
| 648 | (if subst-list | ||
| 649 | (setcdr (car subst-list) (car missing-list))) | ||
| 650 | (setq missing-list (cdr missing-list)))))) | ||
| 651 | |||
| 652 | (defcustom quail-keyboard-layout-type "standard" | ||
| 653 | "Type of keyboard layout used in Quail base input method. | ||
| 654 | Available types are listed in the variable `quail-keyboard-layout-alist'." | ||
| 655 | :group 'quail | ||
| 656 | :type 'string | ||
| 657 | :set #'(lambda (symbol value) | ||
| 658 | (quail-update-keyboard-layout value) | ||
| 659 | (set symbol value))) | ||
| 592 | 660 | ||
| 593 | ;;;###autoload | 661 | ;;;###autoload |
| 594 | (defun quail-set-keyboard-layout (kbd-type) | 662 | (defun quail-set-keyboard-layout (kbd-type) |
| @@ -604,36 +672,166 @@ you type is correctly handled." | |||
| 604 | (type (completing-read "Keyboard type: " | 672 | (type (completing-read "Keyboard type: " |
| 605 | quail-keyboard-layout-alist))) | 673 | quail-keyboard-layout-alist))) |
| 606 | (list type))) | 674 | (list type))) |
| 607 | (let ((layout (assoc kbd-type quail-keyboard-layout-alist))) | 675 | (quail-update-keyboard-layout kbd-type) |
| 608 | (if (null layout) | 676 | (setq quail-keyboard-layout-type kbd-type)) |
| 609 | ;; Here, we had better ask a user to define his own keyboard | ||
| 610 | ;; layout interactively. | ||
| 611 | (error "Unknown keyboard type `%s'" kbd-type)) | ||
| 612 | (setq quail-keyboard-layout (cdr layout)))) | ||
| 613 | 677 | ||
| 614 | (defun quail-keyboard-translate (ch) | 678 | (defun quail-keyboard-translate (char) |
| 615 | "Translate CHAR according to `quail-keyboard-layout' and return the result." | 679 | "Translate CHAR to the one in the standard keyboard layout." |
| 616 | (if (eq quail-keyboard-layout quail-keyboard-layout-standard) | 680 | (if (eq quail-keyboard-layout quail-keyboard-layout-standard) |
| 617 | ;; All Quail packages are designed based on | 681 | ;; All Quail packages are designed based on |
| 618 | ;; `quail-keyboard-layout-standard'. | 682 | ;; `quail-keyboard-layout-standard'. |
| 619 | ch | 683 | char |
| 620 | (let ((i 0)) | 684 | (let ((i 0)) |
| 685 | ;; Find the key location on the current keyboard layout. | ||
| 621 | (while (and (< i quail-keyboard-layout-len) | 686 | (while (and (< i quail-keyboard-layout-len) |
| 622 | (/= ch (aref quail-keyboard-layout i))) | 687 | (/= char (aref quail-keyboard-layout i))) |
| 623 | (setq i (1+ i))) | 688 | (setq i (1+ i))) |
| 624 | (if (= i quail-keyboard-layout-len) | 689 | (if (= i quail-keyboard-layout-len) |
| 625 | ;; CH is not in quail-keyboard-layout, which means that a | 690 | ;; CHAR is not in quail-keyboard-layout, which means that a |
| 626 | ;; user typed a key which generated a character code to be | 691 | ;; user typed a key which generated a character code to be |
| 627 | ;; handled out of Quail. Just return CH and make | 692 | ;; handled out of Quail. Just return CHAR and make |
| 628 | ;; quail-execute-non-quail-command handle it correctly. | 693 | ;; quail-execute-non-quail-command handle it correctly. |
| 629 | ch | 694 | char |
| 630 | (let ((char (aref quail-keyboard-layout-standard i))) | 695 | (let ((ch (aref quail-keyboard-layout-standard i))) |
| 631 | (if (= char ?\ ) | 696 | (if (= ch ?\ ) |
| 632 | ;; A user typed a key at the location not converted by | 697 | ;; This location not available in the standard keyboard |
| 633 | ;; quail-keyboard-layout-standard. Just return CH as | 698 | ;; layout. Check if the location is used to substitute |
| 634 | ;; well as above. | 699 | ;; for the other location of the standard layout. |
| 635 | ch | 700 | (if (setq i (cdr (assq i quail-keyboard-layout-substitution))) |
| 636 | char)))))) | 701 | (aref quail-keyboard-layout-standard i) |
| 702 | ;; Just return CHAR as well as above. | ||
| 703 | char) | ||
| 704 | ch)))))) | ||
| 705 | |||
| 706 | ;; Insert the visual keyboard layout table according to KBD-LAYOUT. | ||
| 707 | ;; The format of KBD-LAYOUT is the same as `quail-keyboard-layout'. | ||
| 708 | (defun quail-insert-kbd-layout (kbd-layout) | ||
| 709 | (let (done-list layout i ch) | ||
| 710 | ;; At first, convert KBD-LAYOUT to the same size vector that | ||
| 711 | ;; contains translated character or string. | ||
| 712 | (setq layout (string-to-vector kbd-layout) | ||
| 713 | i 0) | ||
| 714 | (while (< i quail-keyboard-layout-len) | ||
| 715 | (setq ch (aref kbd-layout i)) | ||
| 716 | (if (quail-kbd-translate) | ||
| 717 | (setq ch (quail-keyboard-translate ch))) | ||
| 718 | (let* ((map (cdr (assq ch (cdr (quail-map))))) | ||
| 719 | (translation (and map (quail-get-translation | ||
| 720 | (car map) (char-to-string ch) 1)))) | ||
| 721 | (if translation | ||
| 722 | (progn | ||
| 723 | (if (consp translation) | ||
| 724 | (setq translation (aref (cdr translation) 0))) | ||
| 725 | (setq done-list (cons translation done-list))) | ||
| 726 | (setq translation ch)) | ||
| 727 | (aset layout i translation)) | ||
| 728 | (setq i (1+ i))) | ||
| 729 | |||
| 730 | (let ((pos (point)) | ||
| 731 | (bar "|") | ||
| 732 | lower upper row) | ||
| 733 | ;; Make table without horizontal lines. Each column for a key | ||
| 734 | ;; has the form "| LU |" where L is for lower key and and U is | ||
| 735 | ;; for a upper key. If width of L (U) is greater than 1, | ||
| 736 | ;; preceding (following) space is not inserted. | ||
| 737 | (put-text-property 0 1 'face 'bold bar) | ||
| 738 | (setq i 0) | ||
| 739 | (while (< i quail-keyboard-layout-len) | ||
| 740 | (when (= (% i 30) 0) | ||
| 741 | (setq row (/ i 30)) | ||
| 742 | (if (> row 1) | ||
| 743 | (insert-char 32 (+ row (/ (- row 2) 2))))) | ||
| 744 | (setq lower (aref layout i) | ||
| 745 | upper (aref layout (1+ i))) | ||
| 746 | (if (and (integerp lower) (>= lower 128) (< lower 256)) | ||
| 747 | (setq lower (unibyte-char-to-multibyte lower))) | ||
| 748 | (if (and (integerp upper) (>= upper 128) (< upper 256)) | ||
| 749 | (setq upper (unibyte-char-to-multibyte upper))) | ||
| 750 | (insert bar) | ||
| 751 | (if (= (if (stringp lower) (string-width lower) (char-width lower)) 1) | ||
| 752 | (insert " ")) | ||
| 753 | (insert lower upper) | ||
| 754 | (if (= (if (stringp upper) (string-width upper) (char-width upper)) 1) | ||
| 755 | (insert " ")) | ||
| 756 | (setq i (+ i 2)) | ||
| 757 | (if (= (% i 30) 0) | ||
| 758 | (insert bar "\n"))) | ||
| 759 | ;; Insert horizontal lines while deleting blank key columns at the | ||
| 760 | ;; beginning and end of each line. | ||
| 761 | (save-restriction | ||
| 762 | (narrow-to-region pos (point)) | ||
| 763 | (goto-char pos) | ||
| 764 | ;;(while (looking-at "[| ]*$") | ||
| 765 | ;;(forward-line 1) | ||
| 766 | ;;(delete-region pos (point))) | ||
| 767 | (let ((from1 100) (to1 0) from2 to2) | ||
| 768 | (while (not (eobp)) | ||
| 769 | (if (looking-at "[| ]*$") | ||
| 770 | ;; The entire row is blank. | ||
| 771 | (delete-region (point) (match-end 0)) | ||
| 772 | ;; Delete blank key columns at the head. | ||
| 773 | (if (looking-at " *\\(| \\)+") | ||
| 774 | (subst-char-in-region (point) (match-end 0) ?| ? )) | ||
| 775 | ;; Delete blank key columns at the tail. | ||
| 776 | (if (re-search-forward "\\( |\\)+$" (line-end-position) t) | ||
| 777 | (delete-region (match-beginning 0) (point))) | ||
| 778 | (beginning-of-line)) | ||
| 779 | ;; Calculate the start and end columns of a horizontal line. | ||
| 780 | (if (eolp) | ||
| 781 | (setq from2 from1 to2 to1) | ||
| 782 | (skip-chars-forward " ") | ||
| 783 | (setq from2 (current-column)) | ||
| 784 | (end-of-line) | ||
| 785 | (setq to2 (current-column)) | ||
| 786 | (if (< from2 from1) | ||
| 787 | (setq from1 from2)) | ||
| 788 | (if (> to2 to1) | ||
| 789 | (setq to1 to2)) | ||
| 790 | (beginning-of-line)) | ||
| 791 | ;; If the previous or the current line has at least one key | ||
| 792 | ;; column, insert a horizontal line. | ||
| 793 | (when (> to1 0) | ||
| 794 | (insert-char 32 from1) | ||
| 795 | (setq pos (point)) | ||
| 796 | (insert "+") | ||
| 797 | (insert-char ?- (- (- to1 from1) 2)) | ||
| 798 | (insert "+") | ||
| 799 | (put-text-property pos (point) 'face 'bold) | ||
| 800 | (insert "\n")) | ||
| 801 | (setq from1 from2 to1 to2) | ||
| 802 | (forward-line 1))) | ||
| 803 | ;; Insert "space bar" box. | ||
| 804 | (forward-line -1) | ||
| 805 | (setq pos (point)) | ||
| 806 | (insert | ||
| 807 | " +-----------------------------+ | ||
| 808 | | space bar | | ||
| 809 | +-----------------------------+ | ||
| 810 | ") | ||
| 811 | (put-text-property pos (point) 'face 'bold) | ||
| 812 | (insert ?\n))) | ||
| 813 | |||
| 814 | done-list)) | ||
| 815 | |||
| 816 | ;;;###autoload | ||
| 817 | (defun quail-show-keyboard-layout (&optional keyboard-type) | ||
| 818 | "Show keyboard layout." | ||
| 819 | (interactive | ||
| 820 | (list (completing-read "Keyboard type (default, current choise): " | ||
| 821 | quail-keyboard-layout-alist | ||
| 822 | nil t))) | ||
| 823 | (or (and keyboard-type (> (length keyboard-type) 0)) | ||
| 824 | (setq keyboard-type quail-keyboard-layout-type)) | ||
| 825 | (let ((layout (assoc keyboard-type quail-keyboard-layout-alist))) | ||
| 826 | (or layout | ||
| 827 | (error "Unknown keyboard type: %s" keyboard-type)) | ||
| 828 | (with-output-to-temp-buffer "*Help*" | ||
| 829 | (save-excursion | ||
| 830 | (set-buffer standard-output) | ||
| 831 | (insert "Keyboard layout (keyboard type: " | ||
| 832 | keyboard-type | ||
| 833 | ")\n") | ||
| 834 | (quail-insert-kbd-layout (cdr layout)))))) | ||
| 637 | 835 | ||
| 638 | ;; Quail map | 836 | ;; Quail map |
| 639 | 837 | ||
| @@ -921,19 +1119,23 @@ selected translation." | |||
| 921 | nil) | 1119 | nil) |
| 922 | 1120 | ||
| 923 | ((stringp def) | 1121 | ((stringp def) |
| 924 | ;; Each character in DEF is a candidate of translation. Reform | 1122 | ;; If the length is 1, we don't need vector but a single candidate |
| 925 | ;; it as (INDICES . VECTOR). | 1123 | ;; as the translation. |
| 926 | (setq def (string-to-vector def)) | ||
| 927 | ;; But if the length is 1, we don't need vector but a single | ||
| 928 | ;; candidate as the translation. | ||
| 929 | (if (= (length def) 1) | 1124 | (if (= (length def) 1) |
| 930 | (aref def 0) | 1125 | (aref def 0) |
| 931 | (cons (list 0 0 0 0 nil) def))) | 1126 | ;; Each character in DEF is a candidate of translation. Reform |
| 1127 | ;; it as (INDICES . VECTOR). | ||
| 1128 | (cons (list 0 0 0 0 nil) (string-to-vector def)))) | ||
| 932 | 1129 | ||
| 933 | ((vectorp def) | 1130 | ((vectorp def) |
| 934 | ;; Each element (string or character) in DEF is a candidate of | 1131 | ;; If the length is 1, and the length of element string is 1, we |
| 935 | ;; translation. Reform it as (INDICES . VECTOR). | 1132 | ;; don't need vector but a single candidate as the translation. |
| 936 | (cons (list 0 0 0 0 nil) def)) | 1133 | (if (and (= (length def) 1) |
| 1134 | (= (length (aref def 0)) 1)) | ||
| 1135 | (aref (aref def 0) 0) | ||
| 1136 | ;; Each element (string or character) in DEF is a candidate of | ||
| 1137 | ;; translation. Reform it as (INDICES . VECTOR). | ||
| 1138 | (cons (list 0 0 0 0 nil) def))) | ||
| 937 | 1139 | ||
| 938 | (t | 1140 | (t |
| 939 | (error "Invalid object in Quail map: %s" def)))) | 1141 | (error "Invalid object in Quail map: %s" def)))) |
| @@ -1346,7 +1548,7 @@ The returned value is a Quail map specific to KEY." | |||
| 1346 | (setcar (nthcdr 2 indices) end))) | 1548 | (setcar (nthcdr 2 indices) end))) |
| 1347 | (if relative-index | 1549 | (if relative-index |
| 1348 | (if (>= (+ start relative-index) end) | 1550 | (if (>= (+ start relative-index) end) |
| 1349 | (setcar indices end) | 1551 | (setcar indices (1- end)) |
| 1350 | (setcar indices (+ start relative-index)))) | 1552 | (setcar indices (+ start relative-index)))) |
| 1351 | (setq quail-current-str | 1553 | (setq quail-current-str |
| 1352 | (aref (cdr quail-current-translations) (car indices))) | 1554 | (aref (cdr quail-current-translations) (car indices))) |
| @@ -1992,92 +2194,225 @@ are shown (at most to the depth specified `quail-completion-max-depth')." | |||
| 1992 | (select-window (active-minibuffer-window)) | 2194 | (select-window (active-minibuffer-window)) |
| 1993 | (exit-minibuffer)))))) | 2195 | (exit-minibuffer)))))) |
| 1994 | 2196 | ||
| 2197 | (defun quail-build-decode-map (map key decode-map num &optional maxnum ignores) | ||
| 2198 | (let ((translation (quail-get-translation (car map) key (length key))) | ||
| 2199 | elt) | ||
| 2200 | (cond ((integerp translation) | ||
| 2201 | (when (and (> translation 255) (not (memq translation ignores))) | ||
| 2202 | (setcdr decode-map | ||
| 2203 | (cons (cons key translation) (cdr decode-map))) | ||
| 2204 | (setq num (1+ num)))) | ||
| 2205 | ((consp translation) | ||
| 2206 | (setq translation (cdr translation)) | ||
| 2207 | (let ((multibyte nil)) | ||
| 2208 | (mapc (function (lambda (x) | ||
| 2209 | (if (and (if (integerp x) (> x 255) | ||
| 2210 | (> (string-bytes x) (length x))) | ||
| 2211 | (not (member x ignores))) | ||
| 2212 | (setq multibyte t)))) | ||
| 2213 | translation) | ||
| 2214 | (when multibyte | ||
| 2215 | (setcdr decode-map | ||
| 2216 | (cons (cons key translation) (cdr decode-map))) | ||
| 2217 | (setq num (+ num (length translation))))))) | ||
| 2218 | (if (and maxnum (> num maxnum)) | ||
| 2219 | (- num) | ||
| 2220 | (setq map (cdr map)) | ||
| 2221 | (while (and map (>= num 0)) | ||
| 2222 | (setq elt (car map) map (cdr map)) | ||
| 2223 | (when (and (integerp (car elt)) (consp (cdr elt))) | ||
| 2224 | (setq num (quail-build-decode-map (cdr elt) | ||
| 2225 | (format "%s%c" key (car elt)) | ||
| 2226 | decode-map num maxnum ignores)))) | ||
| 2227 | num))) | ||
| 2228 | |||
| 2229 | (defun quail-insert-decode-map (decode-map) | ||
| 2230 | (setq decode-map | ||
| 2231 | (sort (cdr decode-map) | ||
| 2232 | (function (lambda (x y) | ||
| 2233 | (setq x (car x) y (car y)) | ||
| 2234 | (or (> (length x) (length y)) | ||
| 2235 | (and (= (length x) (length y)) | ||
| 2236 | (not (string< x y)))))))) | ||
| 2237 | (let ((frame-width (frame-width)) | ||
| 2238 | (short-key-width 3) | ||
| 2239 | (short-trans-width 4) | ||
| 2240 | (long-key-width 3) | ||
| 2241 | (short-list nil) | ||
| 2242 | (long-list nil) | ||
| 2243 | elt trans width pos cols rows col row str col-width) | ||
| 2244 | ;; Divide the decoding map into shorter one and longer one. | ||
| 2245 | (while decode-map | ||
| 2246 | (setq elt (car decode-map) decode-map (cdr decode-map) | ||
| 2247 | trans (cdr elt)) | ||
| 2248 | (if (and (vectorp trans) (= (length trans) 1)) | ||
| 2249 | (setq trans (aref trans 0))) | ||
| 2250 | (if (vectorp trans) | ||
| 2251 | (setq long-list (cons elt long-list)) | ||
| 2252 | (setq short-list (cons (cons (car elt) trans) short-list) | ||
| 2253 | width (if (stringp trans) (string-width trans) | ||
| 2254 | (char-width trans))) | ||
| 2255 | (if (> width short-trans-width) | ||
| 2256 | (setq short-trans-width width))) | ||
| 2257 | (setq width (length (car elt))) | ||
| 2258 | (if (> width short-key-width) | ||
| 2259 | (setq short-key-width width)) | ||
| 2260 | (if (> width long-key-width) | ||
| 2261 | (setq long-key-width width))) | ||
| 2262 | (when short-list | ||
| 2263 | (setq col-width (+ short-key-width 1 short-trans-width 1) | ||
| 2264 | cols (/ frame-width col-width) | ||
| 2265 | rows (/ (length short-list) cols)) | ||
| 2266 | (if (> (% (length short-list) cols) 0) | ||
| 2267 | (setq rows (1+ rows))) | ||
| 2268 | (insert "key") | ||
| 2269 | (indent-to (1+ short-key-width)) | ||
| 2270 | (insert "char") | ||
| 2271 | (indent-to (1+ col-width)) | ||
| 2272 | (insert "[type a key sequence to insert the corresponding character]\n") | ||
| 2273 | (setq pos (point)) | ||
| 2274 | (insert-char ?\n (+ rows 2)) | ||
| 2275 | (goto-char pos) | ||
| 2276 | (setq col (- col-width) row 0) | ||
| 2277 | (while short-list | ||
| 2278 | (setq elt (car short-list) short-list (cdr short-list)) | ||
| 2279 | (when (= (% row rows) 0) | ||
| 2280 | (goto-char pos) | ||
| 2281 | (setq col (+ col col-width)) | ||
| 2282 | (move-to-column col t) | ||
| 2283 | (insert-char ?- short-key-width) | ||
| 2284 | (insert ? ) | ||
| 2285 | (insert-char ?- short-trans-width) | ||
| 2286 | (forward-line 1)) | ||
| 2287 | (move-to-column col t) | ||
| 2288 | (insert (car elt)) | ||
| 2289 | (indent-to (+ col short-key-width 1)) | ||
| 2290 | (insert (cdr elt)) | ||
| 2291 | (forward-line 1) | ||
| 2292 | (setq row (1+ row))) | ||
| 2293 | (goto-char (point-max))) | ||
| 2294 | |||
| 2295 | (when long-list | ||
| 2296 | (insert "key") | ||
| 2297 | (indent-to (1+ long-key-width)) | ||
| 2298 | (insert "character(s) [type a key (sequence) and select one from the list]\n") | ||
| 2299 | (insert-char ?- long-key-width) | ||
| 2300 | (insert " ------------\n") | ||
| 2301 | (while long-list | ||
| 2302 | (setq elt (car long-list) long-list (cdr long-list)) | ||
| 2303 | (insert (car elt)) | ||
| 2304 | (indent-to long-key-width) | ||
| 2305 | (if (vectorp (cdr elt)) | ||
| 2306 | (mapc (function | ||
| 2307 | (lambda (x) | ||
| 2308 | (let ((width (if (integerp x) (char-width x) | ||
| 2309 | (string-width x)))) | ||
| 2310 | (when (> (+ (current-column) 1 width) frame-width) | ||
| 2311 | (insert "\n") | ||
| 2312 | (indent-to long-key-width)) | ||
| 2313 | (insert " " x)))) | ||
| 2314 | (cdr elt)) | ||
| 2315 | (insert " " (cdr elt))) | ||
| 2316 | (insert ?\n)) | ||
| 2317 | (insert ?\n)))) | ||
| 2318 | |||
| 1995 | (defun quail-help (&optional package) | 2319 | (defun quail-help (&optional package) |
| 1996 | "Show brief description of the current Quail package. | 2320 | "Show brief description of the current Quail package. |
| 1997 | Optional 2nd arg PACKAGE specifies the alternative Quail package to describe." | 2321 | Optional 2nd arg PACKAGE specifies the alternative Quail package to describe." |
| 1998 | (interactive) | 2322 | (interactive) |
| 1999 | (or package | 2323 | (if package |
| 2000 | (setq package quail-current-package)) | 2324 | (setq package (assoc package quail-package-alist)) |
| 2325 | (setq package quail-current-package)) | ||
| 2001 | (let ((help-xref-mule-regexp help-xref-mule-regexp-template)) | 2326 | (let ((help-xref-mule-regexp help-xref-mule-regexp-template)) |
| 2002 | (with-output-to-temp-buffer "*Help*" | 2327 | (with-output-to-temp-buffer "*Help*" |
| 2003 | (save-excursion | 2328 | (save-excursion |
| 2004 | (set-buffer standard-output) | 2329 | (set-buffer standard-output) |
| 2005 | (setq quail-current-package package) | 2330 | (setq quail-current-package package) |
| 2006 | (insert "Quail input method (name:" | 2331 | (insert "Input method: " (quail-name) |
| 2007 | (quail-name) | 2332 | " (mode line indicator:" |
| 2008 | ", mode line indicator:[" | ||
| 2009 | (quail-title) | 2333 | (quail-title) |
| 2010 | "])\n\n---- Documentation ----\n" | 2334 | ")\n\n" |
| 2011 | (quail-docstring)) | 2335 | (quail-docstring)) |
| 2012 | (newline) | 2336 | (or (bolp) |
| 2013 | (if (quail-show-layout) (quail-show-kbd-layout)) | 2337 | (insert "\n")) |
| 2338 | (insert "\n") | ||
| 2339 | |||
| 2340 | (let ((done-list nil)) | ||
| 2341 | ;; Show keyboard layout if the current package requests it.. | ||
| 2342 | (when (quail-show-layout) | ||
| 2343 | (insert | ||
| 2344 | "Physical key layout for this input method is as below. | ||
| 2345 | You can input a character in the table by typing a key | ||
| 2346 | at the same location on your keyboard.\n") | ||
| 2347 | (setq done-list | ||
| 2348 | (quail-insert-kbd-layout quail-keyboard-layout)) | ||
| 2349 | (insert "It is assumed that your keyboard type is `") | ||
| 2350 | (help-insert-xref-button | ||
| 2351 | quail-keyboard-layout-type | ||
| 2352 | #'quail-show-keyboard-layout quail-keyboard-layout-type | ||
| 2353 | "mouse-2, RET: show this layout") | ||
| 2354 | (insert "'. | ||
| 2355 | If the layout is different from your keyboard, or you see the | ||
| 2356 | different characters when you type keys according to this layout, | ||
| 2357 | adjust the variable `quail-keyboard-layout-type' ") | ||
| 2358 | (help-insert-xref-button | ||
| 2359 | "[customize it]" | ||
| 2360 | #'customize-variable 'quail-keyboard-layout-type | ||
| 2361 | "mouse-2, RET: set keyboard layout type") | ||
| 2362 | (insert ".\n")) | ||
| 2363 | |||
| 2364 | ;; Show key sequences. | ||
| 2365 | (let ((decode-map (list 'decode-map)) | ||
| 2366 | elt pos num) | ||
| 2367 | (setq num (quail-build-decode-map (quail-map) "" decode-map | ||
| 2368 | 0 512 done-list)) | ||
| 2369 | (when (> num 0) | ||
| 2370 | (insert ?\n) | ||
| 2371 | (if (quail-show-layout) | ||
| 2372 | (insert "You can also input more characters") | ||
| 2373 | (insert "You can input characters")) | ||
| 2374 | (insert " by the following key sequences:\n") | ||
| 2375 | (quail-insert-decode-map decode-map)))) | ||
| 2376 | |||
| 2014 | (quail-help-insert-keymap-description | 2377 | (quail-help-insert-keymap-description |
| 2015 | (quail-translation-keymap) | 2378 | (quail-translation-keymap) |
| 2016 | (format "--- Key bindings%s ---\n" | 2379 | "--- key bindings for selecting a character ---\n") |
| 2017 | (if (quail-conversion-keymap) | 2380 | (insert ?\n) |
| 2018 | " (while translating)" | ||
| 2019 | ""))) | ||
| 2020 | (if (quail-conversion-keymap) | 2381 | (if (quail-conversion-keymap) |
| 2021 | (quail-help-insert-keymap-description | 2382 | (quail-help-insert-keymap-description |
| 2022 | (quail-conversion-keymap) | 2383 | (quail-conversion-keymap) |
| 2023 | "\n--- Key bindings (while converting) ---\n")) | 2384 | "--- Key bindings for converting a character (sequence) ---\n")) |
| 2024 | (setq quail-current-package nil) | 2385 | (setq quail-current-package nil) |
| 2025 | (help-setup-xref (list #'quail-help package) | 2386 | (help-setup-xref (list #'quail-help package) |
| 2026 | (interactive-p)))))) | 2387 | (interactive-p)))))) |
| 2027 | 2388 | ||
| 2028 | (defun quail-help-insert-keymap-description (keymap &optional header) | 2389 | (defun quail-help-insert-keymap-description (keymap &optional header) |
| 2029 | (let (pos) | 2390 | (let (pos1 pos2 eol) |
| 2391 | (setq pos1 (point)) | ||
| 2030 | (if header | 2392 | (if header |
| 2031 | (insert header)) | 2393 | (insert header)) |
| 2032 | (setq pos (point)) | ||
| 2033 | (insert (substitute-command-keys "\\{keymap}")) | 2394 | (insert (substitute-command-keys "\\{keymap}")) |
| 2034 | (goto-char pos) | 2395 | (goto-char pos1) |
| 2035 | (while (search-forward "quail-other-command" nil 'move) | 2396 | ;; Skip headers "--- key bindings ---", etc. |
| 2036 | (delete-region (line-beginning-position) (1+ (line-end-position)))))) | 2397 | (forward-line 3) |
| 2037 | 2398 | (setq pos2 (point)) | |
| 2038 | (defun quail-show-kbd-layout () | 2399 | (with-syntax-table emacs-lisp-mode-syntax-table |
| 2039 | "Show keyboard layout with key tops of multilingual characters." | 2400 | (while (re-search-forward "\\sw\\(\\sw\\|\\s_\\)+" nil t) |
| 2040 | (insert "--- Keyboard layout ---\n") | 2401 | (let ((sym (intern-soft (buffer-substring (match-beginning 0) |
| 2041 | (let ((blink-matching-paren nil) | 2402 | (point))))) |
| 2042 | (i 0) | 2403 | (if (and sym (fboundp sym) |
| 2043 | ch) | 2404 | (get sym 'quail-help-hide)) |
| 2044 | (while (< i quail-keyboard-layout-len) | 2405 | (delete-region (line-beginning-position) |
| 2045 | (if (= (% i 30) 0) | 2406 | (1+ (line-end-position))))))) |
| 2046 | (progn | 2407 | (goto-char pos2) |
| 2047 | (newline) | 2408 | (while (not (eobp)) |
| 2048 | (indent-to (/ i 30))) | 2409 | (if (looking-at "[ \t]*$") |
| 2049 | (if (= (% i 2) 0) | 2410 | (delete-region (point) (1+ (line-end-position))) |
| 2050 | (insert " "))) | 2411 | (forward-line 1))) |
| 2051 | (setq ch (aref quail-keyboard-layout i)) | 2412 | (goto-char pos2) |
| 2052 | (when (and (quail-kbd-translate) | 2413 | (if (eobp) |
| 2053 | (/= ch ?\ )) | 2414 | (delete-region pos1 (point))) |
| 2054 | ;; This is the case that the current input method simulates | 2415 | (goto-char (point-max)))) |
| 2055 | ;; some keyboard layout (which means it requires keyboard | ||
| 2056 | ;; translation) and a key at location `i' exists on users | ||
| 2057 | ;; keyboard. We must translate that key by | ||
| 2058 | ;; `quail-keyboard-layout-standard'. But if if there's no | ||
| 2059 | ;; corresponding key in that standard layout, we must simulate | ||
| 2060 | ;; what is inserted if that key is pressed by setting CH a | ||
| 2061 | ;; minus value. | ||
| 2062 | (setq ch (aref quail-keyboard-layout-standard i)) | ||
| 2063 | (if (= ch ?\ ) | ||
| 2064 | (setq ch (- (aref quail-keyboard-layout i))))) | ||
| 2065 | (if (< ch 0) | ||
| 2066 | (let ((last-command-event (- ch))) | ||
| 2067 | (self-insert-command 1)) | ||
| 2068 | (if (= ch ?\ ) | ||
| 2069 | (insert ch) | ||
| 2070 | (let* ((map (cdr (assq ch (cdr (quail-map))))) | ||
| 2071 | (translation (and map (quail-get-translation | ||
| 2072 | (car map) (char-to-string ch) 1)))) | ||
| 2073 | (if (integerp translation) | ||
| 2074 | (insert translation) | ||
| 2075 | (if (consp translation) | ||
| 2076 | (insert (aref (cdr translation) (car (car translation)))) | ||
| 2077 | (let ((last-command-event ch)) | ||
| 2078 | (self-insert-command 1))))))) | ||
| 2079 | (setq i (1+ i)))) | ||
| 2080 | (newline)) | ||
| 2081 | 2416 | ||
| 2082 | (defun quail-translation-help () | 2417 | (defun quail-translation-help () |
| 2083 | "Show help message while translating in Quail input method." | 2418 | "Show help message while translating in Quail input method." |