X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/275a5dd65098a2d6fcc14c21f805fc8d5e4479ee..2a1e24765bc3de7bf72e7117893307f6f6c441be:/lisp/international/quail.el diff --git a/lisp/international/quail.el b/lisp/international/quail.el index f47d73a950..4669528c9a 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -1,6 +1,6 @@ ;;; quail.el --- provides simple input method for multilingual text -;; Copyright (C) 1997-1998, 2000-2011 Free Software Foundation, Inc. +;; Copyright (C) 1997-1998, 2000-2012 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ;; 2005, 2006, 2007, 2008, 2009, 2010, 2011 ;; National Institute of Advanced Industrial Science and Technology (AIST) @@ -43,7 +43,7 @@ ;; CONVERSION-KEYS argument of the Quail package. ;; [There was an input method for Mule 2.3 called `Tamago' from the -;; Japanese `TAkusan MAtasete GOmenasai', or `Sorry for having you +;; Japanese `TAkusan MAtasete GOmen-nasai', or `Sorry for having you ;; wait so long'; this couldn't be included in Emacs 20. `Tamago' is ;; Japanese for `egg' (implicitly a hen's egg). Handa-san made a ;; smaller and simpler system; the smaller quail egg is also eaten in @@ -53,7 +53,7 @@ ;;; Code: (require 'help-mode) -(eval-when-compile (require 'cl)) +(eval-when-compile (require 'cl-lib)) (defgroup quail nil "Quail: multilingual input method." @@ -486,19 +486,15 @@ non-Quail commands." (setq translation-keymap (copy-keymap (if simple quail-simple-translation-keymap quail-translation-keymap))) - (while translation-keys - (define-key translation-keymap - (car (car translation-keys)) (cdr (car translation-keys))) - (setq translation-keys (cdr translation-keys)))) + (dolist (trans translation-keys) + (define-key translation-keymap (car trans) (cdr trans)))) (setq translation-keymap (if simple quail-simple-translation-keymap quail-translation-keymap))) (when conversion-keys (setq conversion-keymap (copy-keymap quail-conversion-keymap)) - (while conversion-keys - (define-key conversion-keymap - (car (car conversion-keys)) (cdr (car conversion-keys))) - (setq conversion-keys (cdr conversion-keys)))) + (dolist (conv conversion-keys) + (define-key conversion-keymap (car conv) (cdr conv)))) (quail-add-package (list name title (list nil) guidance (or docstring "") translation-keymap @@ -544,32 +540,36 @@ non-Quail commands." (if (and (overlayp quail-conv-overlay) (overlay-start quail-conv-overlay)) (delete-overlay quail-conv-overlay))) -(defun quail-inactivate () - "Inactivate Quail input method. +(defun quail-deactivate () + "Deactivate Quail input method. -This function runs the normal hook `quail-inactivate-hook'." +This function runs the normal hook `quail-deactivate-hook'." (interactive) (quail-activate -1)) +(define-obsolete-function-alias 'quail-inactivate 'quail-deactivate "24.3") + (defun quail-activate (&optional arg) "Activate Quail input method. With ARG, activate Quail input method if and only if arg is positive. This function runs `quail-activate-hook' if it activates the input -method, `quail-inactivate-hook' if it deactivates it. +method, `quail-deactivate-hook' if it deactivates it. While this input method is active, the variable `input-method-function' is bound to the function `quail-input-method'." (if (and arg (< (prefix-numeric-value arg) 0)) - ;; Let's inactivate Quail input method. + ;; Let's deactivate Quail input method. (unwind-protect (progn (quail-delete-overlays) (setq describe-current-input-method-function nil) (quail-hide-guidance) (remove-hook 'post-command-hook 'quail-show-guidance t) - (run-hooks 'quail-inactivate-hook)) + (run-hooks + 'quail-inactivate-hook ; for backward compatibility + 'quail-deactivate-hook)) (kill-local-variable 'input-method-function)) ;; Let's activate Quail input method. (if (null quail-current-package) @@ -579,7 +579,7 @@ While this input method is active, the variable (setq name (car (car quail-package-alist))) (error "No Quail package loaded")) (quail-select-package name))) - (setq inactivate-current-input-method-function 'quail-inactivate) + (setq deactivate-current-input-method-function 'quail-deactivate) (setq describe-current-input-method-function 'quail-help) (quail-delete-overlays) (setq quail-guidance-str "") @@ -593,8 +593,12 @@ While this input method is active, the variable (make-local-variable 'input-method-function) (setq input-method-function 'quail-input-method))) +(define-obsolete-variable-alias + 'quail-inactivate-hook + 'quail-deactivate-hook "24.3") + (defun quail-exit-from-minibuffer () - (inactivate-input-method) + (deactivate-input-method) (if (<= (minibuffer-depth) 1) (remove-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer))) @@ -720,12 +724,11 @@ The command `quail-set-keyboard-layout' usually sets this variable." (setq quail-keyboard-layout-substitution subst-list) ;; If there are additional key locations, map them to missing ;; key locations. - (while missing-list + (dolist (missing missing-list) (while (and subst-list (cdr (car subst-list))) (setq subst-list (cdr subst-list))) (if subst-list - (setcdr (car subst-list) (car missing-list))) - (setq missing-list (cdr missing-list)))))) + (setcdr (car subst-list) missing)))))) (defcustom quail-keyboard-layout-type "standard" "Type of keyboard layout used in Quail base input method. @@ -806,9 +809,10 @@ The format of KBD-LAYOUT is the same as `quail-keyboard-layout'." (if translation (progn (if (consp translation) - (if (> (length (cdr translation)) 0) - (setq translation (aref (cdr translation) 0)) - (setq translation " "))) + (setq translation + (if (> (length (cdr translation)) 0) + (aref (cdr translation) 0) + " "))) (setq done-list (cons translation done-list))) (setq translation (aref kbd-layout i))) (aset layout i translation)) @@ -831,10 +835,26 @@ The format of KBD-LAYOUT is the same as `quail-keyboard-layout'." (setq lower (aref layout i) upper (aref layout (1+ i))) (insert bar) - (if (= (if (stringp lower) (string-width lower) (char-width lower)) 1) + (if (< (if (stringp lower) (string-width lower) (char-width lower)) 2) (insert " ")) - (insert lower upper) - (if (= (if (stringp upper) (string-width upper) (char-width upper)) 1) + (if (characterp lower) + (setq lower + (if (eq (get-char-code-property lower 'general-category) 'Mn) + ;; Pad the left and right of non-spacing characters. + (compose-string (string lower) 0 1 + (format "\t%c\t" lower)) + (string lower)))) + (if (characterp upper) + (setq upper + (if (eq (get-char-code-property upper 'general-category) 'Mn) + ;; Pad the left and right of non-spacing characters. + (compose-string (string upper) 0 1 + (format "\t%c\t" upper)) + (string upper)))) + (insert (bidi-string-mark-left-to-right lower) + (propertize " " 'invisible t) + (bidi-string-mark-left-to-right upper)) + (if (< (string-width upper) 2) (insert " ")) (setq i (+ i 2)) (if (= (% i 30) 0) @@ -849,20 +869,21 @@ The format of KBD-LAYOUT is the same as `quail-keyboard-layout'." ;;(delete-region pos (point))) (let ((from1 100) (to1 0) from2 to2) (while (not (eobp)) - (if (looking-at "[| ]*$") + (if (looking-at "[| \u202c\u202d]*$") ;; The entire row is blank. (delete-region (point) (match-end 0)) ;; Delete blank key columns at the head. - (if (looking-at " *\\(| \\)+") + (if (looking-at "\u202d? *\\(| \\)+") (subst-char-in-region (point) (match-end 0) ?| ? )) ;; Delete blank key columns at the tail. - (if (re-search-forward "\\( |\\)+$" (line-end-position) t) + (if (re-search-forward "\\( |\\)+\u202c?$" + (line-end-position) t) (delete-region (match-beginning 0) (point))) (beginning-of-line)) ;; Calculate the start and end columns of a horizontal line. (if (eolp) (setq from2 from1 to2 to1) - (skip-chars-forward " ") + (skip-chars-forward " \u202d") (setq from2 (current-column)) (end-of-line) (setq to2 (current-column)) @@ -1017,8 +1038,8 @@ the following annotation types are supported. (let ((map (list nil)) (decode-map (if (not no-decode-map) (list 'decode-map))) key trans) - (while l - (setq key (car (car l)) trans (car (cdr (car l))) l (cdr l)) + (dolist (el l) + (setq key (car el) trans (car (cdr el))) (quail-defrule-internal key trans map t decode-map props)) `(if (prog1 (quail-decode-map) (quail-install-map ',map)) @@ -1186,7 +1207,7 @@ function `quail-define-rules' for the detail." (if (stringp trans) (setq trans (string-to-vector trans)))) (let ((new (quail-vunion prevchars trans))) - (setq trans + (setq trans (if (equal new prevchars) ;; Nothing to change, get back to orig value. prev @@ -1200,10 +1221,8 @@ where VECTOR is a vector of candidates (character or string) for the translation, and INDEX points into VECTOR to specify the currently selected translation." (if (and def (symbolp def)) - (if (functionp def) - ;; DEF is a symbol of a function which returns valid translation. - (setq def (funcall def key len)) - (setq def nil))) + ;; DEF is a symbol of a function which returns valid translation. + (setq def (if (functionp def) (funcall def key len)))) (if (and (consp def) (not (vectorp (cdr def)))) (setq def (car def))) @@ -1377,7 +1396,7 @@ Return the input string." (set-buffer-modified-p modified-p) (quail-show-guidance) (let* ((prompt (if input-method-use-echo-area - (format "%s%s %s" + (format "%s%s %s" (or input-method-previous-message "") quail-current-str quail-guidance-str))) @@ -1443,7 +1462,7 @@ Return the input string." (quail-setup-overlays nil))) (quail-show-guidance) (let* ((prompt (if input-method-use-echo-area - (format "%s%s%s %s" + (format "%s%s%s %s" (or input-method-previous-message "") quail-conversion-str quail-current-str @@ -2011,7 +2030,7 @@ minibuffer and the selected frame has no other windows)." (set-window-dedicated-p win t)) (quail-minibuffer-message (format " [%s]" current-input-method-title))) - ;; Show the guidance in the next line of the currrent + ;; Show the guidance in the next line of the current ;; minibuffer. (quail-minibuffer-message (format " [%s]\n%s" @@ -2125,7 +2144,7 @@ minibuffer and the selected frame has no other windows)." (- quail-guidance-translations-starting-column 7 (string-width str)) 32)))) - (setq str (format "%s(%02d/%s)" + (setq str (format "%s(%02d/%s)" str (nth 3 indices) (if (nth 4 indices) (format "%02d" (nth 4 indices)) @@ -2135,7 +2154,7 @@ minibuffer and the selected frame has no other windows)." (trans (aref (cdr quail-current-translations) idx))) (or (stringp trans) (setq trans (string trans))) - (setq str (format "%s %d.%s" + (setq str (format "%s %d.%s" str (if (= (- idx start) 9) 0 (1+ (- idx start))) @@ -2384,10 +2403,10 @@ should be made by `quail-build-decode-map' (which see)." (let ((last-col-elt (or (nth (1- (* (1+ col) newrows)) single-list) (car (last single-list))))) - (incf width (+ (max 3 (length (car last-col-elt))) - 1 single-trans-width 1)))) + (cl-incf width (+ (max 3 (length (car last-col-elt))) + 1 single-trans-width 1)))) (< width window-width)) - (incf cols)) + (cl-incf cols)) (setq rows (/ (+ len cols -1) cols)) ;Round up. (let ((key-width (max 3 (length (car (nth (1- rows) single-list)))))) (insert "key") @@ -2485,6 +2504,11 @@ package to describe." ;; the width of the window in which the buffer displayed. (with-current-buffer (help-buffer) (setq buffer-read-only nil) + ;; Without this, a keyboard layout with R2L characters might be + ;; displayed reversed, right to left. See the thread starting at + ;; http://lists.gnu.org/archive/html/emacs-devel/2012-03/msg00062.html + ;; for a description of one such situation. + (setq bidi-paragraph-direction 'left-to-right) (insert "Input method: " (quail-name) " (mode line indicator:" (quail-title) @@ -2701,9 +2725,9 @@ KEY BINDINGS FOR CONVERSION (put 'quail-decode-map 'char-table-extra-slots 0) -;; Generate a halfly-cooked decode map (char-table) for the current +;; Generate a half-cooked decode map (char-table) for the current ;; Quail map. An element for a character C is a key string or a list -;; of a key strings to type to input C. The lenth of key string is at +;; of a key strings to type to input C. The length of key string is at ;; most 2. If it is 2, more keys may be required to input C. (defun quail-gen-decode-map () @@ -2787,7 +2811,7 @@ If CHAR is an ASCII character and can be input by typing itself, return t." (cdr decode-map))) (let ((key-head (aref decode-map char))) (if (stringp key-head) - (setq key-list (quail-find-key1 + (setq key-list (quail-find-key1 (quail-lookup-key key-head nil t) key-head char nil)) (mapc #'(lambda (elt) @@ -2832,7 +2856,7 @@ STATE-n are symbols to denote state. STATE-0 is the initial state. TRANSITION-n-m are transition rules from STATE-n, and have the form \(RULES . STATE-x) or RULES, where STATE-x is one of STATE-n above, RULES is a symbol whose value is an alist of keys \(string) vs the -correponding characters or strings. The format of the symbol value of +corresponding characters or strings. The format of the symbol value of RULES is the same as arguments to `quail-define-rules'. If TRANSITION-n-m has the form (RULES . STATE-x), it means that @@ -2846,7 +2870,7 @@ The generated map can be set for the current Quail package by the function `quail-install-map' (which see)." (let ((state-alist (mapcar (lambda (x) (list (car x))) table)) tail elt) - ;; STATE-ALIST is an alist of states vs the correponding sub Quail + ;; STATE-ALIST is an alist of states vs the corresponding sub Quail ;; map. It is now initialized to ((STATE-0) (STATE-1) ...). ;; Set key sequence mapping rules in cdr part of each element. (while table @@ -2974,7 +2998,7 @@ of each directory." (if (not (re-search-forward leim-list-entry-regexp nil t)) nil - ;; Remove garbages after the header. + ;; Remove garbage after the header. (goto-char (match-beginning 0)) (if (< pos (point)) (delete-region pos (point)))