* calendar/todo-mode.el (todo-set-top-priorities): Fix logic to
[bpt/emacs.git] / lisp / international / quail.el
index f47d73a..d670191 100644 (file)
@@ -1,6 +1,6 @@
 ;;; quail.el --- provides simple input method for multilingual text
 
-;; Copyright (C) 1997-1998, 2000-201 Free Software Foundation, Inc.
+;; Copyright (C) 1997-1998, 2000-2014 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."
@@ -445,10 +445,11 @@ user's keyboard layout to the standard keyboard layout.  See the
 documentation of `quail-keyboard-layout' and
 `quail-keyboard-layout-standard' for more detail.
 
-SHOW-LAYOUT non-nil means the `quail-help' command should show
-the user's keyboard layout visually with translated characters.
-If KBD-TRANSLATE is set, it is desirable to set also this flag unless
-this package defines no translations for single character keys.
+SHOW-LAYOUT non-nil means the function `quail-help' (as used by
+the command `describe-input-method') should show the user's keyboard
+layout visually with translated characters.  If KBD-TRANSLATE is
+set, it is desirable to also set this flag, unless this package
+defines no translations for single character keys.
 
 CREATE-DECODE-MAP non-nil means decode map is also created.  A decode
 map is an alist of translations and corresponding original keys.
@@ -486,19 +487,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 +541,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 +580,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 +594,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 +725,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 +810,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 +836,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 +870,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 +1039,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 +1208,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 +1222,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)))
 
@@ -1282,7 +1302,7 @@ The returned value is a Quail map specific to KEY."
        (setcdr map (funcall (cdr map) key len)))
     map))
 
-(put 'quail-error 'error-conditions '(quail-error error))
+(define-error 'quail-error nil)
 (defun quail-error (&rest args)
   (signal 'quail-error (apply 'format args)))
 
@@ -1377,7 +1397,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 +1463,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 +2031,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 +2145,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 +2155,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 +2404,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")
@@ -2467,7 +2487,6 @@ should be made by `quail-build-decode-map' (which see)."
   "Show brief description of the current Quail package.
 Optional arg PACKAGE specifies the name of alternative Quail
 package to describe."
-  (interactive)
   (require 'help-mode)
   (let ((help-xref-mule-regexp help-xref-mule-regexp-template)
        (mb enable-multibyte-characters)
@@ -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)
@@ -2519,7 +2543,9 @@ Assuming that your actual keyboard has the `")
           'quail-keyboard-layout-button
           quail-keyboard-layout-type)
          (insert "' layout,
-translation results in the following \"virtual\" keyboard layout:
+translation results in the following \"virtual\" keyboard layout
+\(the labels on the keys indicate what character will be produced
+by each key, with and without holding Shift):
 ")
          (setq done-list
                (quail-insert-kbd-layout quail-keyboard-layout))
@@ -2701,9 +2727,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 +2813,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 +2858,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 +2872,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 +3000,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)))