| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 |
|
|---|
| 58 |
(require 'help-mode) |
|---|
| 59 |
|
|---|
| 60 |
(defgroup quail nil |
|---|
| 61 |
"Quail: multilingual input method." |
|---|
| 62 |
:group 'leim) |
|---|
| 63 |
|
|---|
| 64 |
|
|---|
| 65 |
|
|---|
| 66 |
(defvar quail-current-package nil |
|---|
| 67 |
"The current Quail package, which depends on the current input method. |
|---|
| 68 |
See the documentation of `quail-package-alist' for the format.") |
|---|
| 69 |
(make-variable-buffer-local 'quail-current-package) |
|---|
| 70 |
(put 'quail-current-package 'permanent-local t) |
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 |
(defvar quail-guidance-str nil) |
|---|
| 75 |
|
|---|
| 76 |
(defvar quail-completion-buf nil) |
|---|
| 77 |
|
|---|
| 78 |
(defvar quail-guidance-buf nil) |
|---|
| 79 |
(defvar quail-guidance-frame nil) |
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
(make-variable-buffer-local 'quail-guidance-str) |
|---|
| 84 |
(put 'quail-guidance-str 'permanent-local t) |
|---|
| 85 |
|
|---|
| 86 |
(defvar quail-overlay nil |
|---|
| 87 |
"Overlay which covers the current translation region of Quail.") |
|---|
| 88 |
(make-variable-buffer-local 'quail-overlay) |
|---|
| 89 |
|
|---|
| 90 |
(defvar quail-conv-overlay nil |
|---|
| 91 |
"Overlay which covers the text to be converted in Quail mode.") |
|---|
| 92 |
(make-variable-buffer-local 'quail-conv-overlay) |
|---|
| 93 |
|
|---|
| 94 |
(defvar quail-current-key nil |
|---|
| 95 |
"Current key for translation in Quail mode.") |
|---|
| 96 |
(make-variable-buffer-local 'quail-current-key) |
|---|
| 97 |
|
|---|
| 98 |
(defvar quail-current-str nil |
|---|
| 99 |
"Currently selected translation of the current key.") |
|---|
| 100 |
(make-variable-buffer-local 'quail-current-str) |
|---|
| 101 |
|
|---|
| 102 |
(defvar quail-current-translations nil |
|---|
| 103 |
"Cons of indices and vector of possible translations of the current key. |
|---|
| 104 |
Indices is a list of (CURRENT START END BLOCK BLOCKS), where |
|---|
| 105 |
CURRENT is an index of the current translation, |
|---|
| 106 |
START and END are indices of the start and end of the current block, |
|---|
| 107 |
BLOCK is the current block index, |
|---|
| 108 |
BLOCKS is a number of blocks of translation.") |
|---|
| 109 |
(make-variable-buffer-local 'quail-current-translations) |
|---|
| 110 |
|
|---|
| 111 |
(defvar quail-current-data nil |
|---|
| 112 |
"Any Lisp object holding information of current translation status. |
|---|
| 113 |
When a key sequence is mapped to TRANS and TRANS is a cons |
|---|
| 114 |
of actual translation and some Lisp object to be referred |
|---|
| 115 |
for translating the longer key sequence, this variable is set |
|---|
| 116 |
to that Lisp object.") |
|---|
| 117 |
(make-variable-buffer-local 'quail-current-data) |
|---|
| 118 |
|
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
(defvar quail-package-alist nil |
|---|
| 122 |
"List of Quail packages. |
|---|
| 123 |
A Quail package is a list of these elements: |
|---|
| 124 |
NAME, TITLE, QUAIL-MAP, GUIDANCE, DOCSTRING, TRANSLATION-KEYS, |
|---|
| 125 |
FORGET-LAST-SELECTION, DETERMINISTIC, KBD-TRANSLATE, SHOW-LAYOUT, |
|---|
| 126 |
DECODE-MAP, MAXIMUM-SHORTEST, OVERLAY-PLIST, UPDATE-TRANSLATION-FUNCTION, |
|---|
| 127 |
CONVERSION-KEYS, SIMPLE. |
|---|
| 128 |
|
|---|
| 129 |
QUAIL-MAP is a data structure to map key strings to translations. For |
|---|
| 130 |
the format, see the documentation of `quail-map-p'. |
|---|
| 131 |
|
|---|
| 132 |
DECODE-MAP is an alist of translations and corresponding keys. |
|---|
| 133 |
|
|---|
| 134 |
See the documentation of `quail-define-package' for the other elements.") |
|---|
| 135 |
|
|---|
| 136 |
|
|---|
| 137 |
|
|---|
| 138 |
(defsubst quail-name () |
|---|
| 139 |
"Return the name of the current Quail package." |
|---|
| 140 |
(nth 0 quail-current-package)) |
|---|
| 141 |
|
|---|
| 142 |
(defun quail-title () |
|---|
| 143 |
"Return the title of the current Quail package." |
|---|
| 144 |
(let ((title (nth 1 quail-current-package))) |
|---|
| 145 |
|
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| 148 |
(if (stringp title) |
|---|
| 149 |
title |
|---|
| 150 |
(condition-case nil |
|---|
| 151 |
(mapconcat |
|---|
| 152 |
(lambda (x) |
|---|
| 153 |
(cond ((stringp x) x) |
|---|
| 154 |
((and (listp x) (symbolp (car x)) (= (length x) 3)) |
|---|
| 155 |
(if (symbol-value (car x)) |
|---|
| 156 |
(nth 1 x) (nth 2 x))) |
|---|
| 157 |
(t ""))) |
|---|
| 158 |
title "") |
|---|
| 159 |
(error ""))))) |
|---|
| 160 |
(defsubst quail-map () |
|---|
| 161 |
"Return the translation map of the current Quail package." |
|---|
| 162 |
(nth 2 quail-current-package)) |
|---|
| 163 |
(defsubst quail-guidance () |
|---|
| 164 |
"Return an object used for `guidance' feature of the current Quail package. |
|---|
| 165 |
See also the documentation of `quail-define-package'." |
|---|
| 166 |
(nth 3 quail-current-package)) |
|---|
| 167 |
(defsubst quail-docstring () |
|---|
| 168 |
"Return the documentation string of the current Quail package." |
|---|
| 169 |
(nth 4 quail-current-package)) |
|---|
| 170 |
(defsubst quail-translation-keymap () |
|---|
| 171 |
"Return translation keymap in the current Quail package. |
|---|
| 172 |
Translation keymap is a keymap used while translation region is active." |
|---|
| 173 |
(nth 5 quail-current-package)) |
|---|
| 174 |
(defsubst quail-forget-last-selection () |
|---|
| 175 |
"Return `forget-last-selection' flag of the current Quail package. |
|---|
| 176 |
See also the documentation of `quail-define-package'." |
|---|
| 177 |
(nth 6 quail-current-package)) |
|---|
| 178 |
(defsubst quail-deterministic () |
|---|
| 179 |
"Return `deterministic' flag of the current Quail package. |
|---|
| 180 |
See also the documentation of `quail-define-package'." |
|---|
| 181 |
(nth 7 quail-current-package)) |
|---|
| 182 |
(defsubst quail-kbd-translate () |
|---|
| 183 |
"Return `kbd-translate' flag of the current Quail package. |
|---|
| 184 |
See also the documentation of `quail-define-package'." |
|---|
| 185 |
(nth 8 quail-current-package)) |
|---|
| 186 |
(defsubst quail-show-layout () |
|---|
| 187 |
"Return `show-layout' flag of the current Quail package. |
|---|
| 188 |
See also the documentation of `quail-define-package'." |
|---|
| 189 |
(nth 9 quail-current-package)) |
|---|
| 190 |
(defsubst quail-decode-map () |
|---|
| 191 |
"Return decode map of the current Quail package. |
|---|
| 192 |
It is an alist of translations and corresponding keys." |
|---|
| 193 |
(nth 10 quail-current-package)) |
|---|
| 194 |
(defsubst quail-maximum-shortest () |
|---|
| 195 |
"Return `maximum-shortest' flag of the current Quail package. |
|---|
| 196 |
See also the documentation of `quail-define-package'." |
|---|
| 197 |
(nth 11 quail-current-package)) |
|---|
| 198 |
(defsubst quail-overlay-plist () |
|---|
| 199 |
"Return property list of an overly used in the current Quail package." |
|---|
| 200 |
(nth 12 quail-current-package)) |
|---|
| 201 |
(defsubst quail-update-translation-function () |
|---|
| 202 |
"Return a function for updating translation in the current Quail package." |
|---|
| 203 |
(nth 13 quail-current-package)) |
|---|
| 204 |
(defsubst quail-conversion-keymap () |
|---|
| 205 |
"Return conversion keymap in the current Quail package. |
|---|
| 206 |
Conversion keymap is a keymap used while conversion region is active |
|---|
| 207 |
but translation region is not active." |
|---|
| 208 |
(nth 14 quail-current-package)) |
|---|
| 209 |
(defsubst quail-simple () |
|---|
| 210 |
"Return t if the current Quail package is simple." |
|---|
| 211 |
(nth 15 quail-current-package)) |
|---|
| 212 |
|
|---|
| 213 |
(defsubst quail-package (name) |
|---|
| 214 |
"Return Quail package named NAME." |
|---|
| 215 |
(assoc name quail-package-alist)) |
|---|
| 216 |
|
|---|
| 217 |
(defun quail-add-package (package) |
|---|
| 218 |
"Add Quail package PACKAGE to `quail-package-alist'." |
|---|
| 219 |
(let ((pac (quail-package (car package)))) |
|---|
| 220 |
(if pac |
|---|
| 221 |
(setcdr pac (cdr package)) |
|---|
| 222 |
(setq quail-package-alist (cons package quail-package-alist))))) |
|---|
| 223 |
|
|---|
| 224 |
(defun quail-select-package (name) |
|---|
| 225 |
"Select Quail package named NAME as the current Quail package." |
|---|
| 226 |
(let ((package (quail-package name))) |
|---|
| 227 |
(if (null package) |
|---|
| 228 |
(error "No Quail package `%s'" name)) |
|---|
| 229 |
(setq quail-current-package package) |
|---|
| 230 |
(setq-default quail-current-package package) |
|---|
| 231 |
name)) |
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
(defun quail-use-package (package-name &rest libraries) |
|---|
| 235 |
"Start using Quail package PACKAGE-NAME. |
|---|
| 236 |
The remaining arguments are libraries to be loaded before using the package. |
|---|
| 237 |
|
|---|
| 238 |
This activates input method defined by PACKAGE-NAME by running |
|---|
| 239 |
`quail-activate', which see." |
|---|
| 240 |
(let ((package (quail-package package-name))) |
|---|
| 241 |
(if (null package) |
|---|
| 242 |
|
|---|
| 243 |
(while libraries |
|---|
| 244 |
(if (not (load (car libraries) t)) |
|---|
| 245 |
(progn |
|---|
| 246 |
(with-output-to-temp-buffer "*Help*" |
|---|
| 247 |
(princ "Quail package \"") |
|---|
| 248 |
(princ package-name) |
|---|
| 249 |
(princ "\" can't be activated\n because library \"") |
|---|
| 250 |
(princ (car libraries)) |
|---|
| 251 |
(princ "\" is not in `load-path'. |
|---|
| 252 |
|
|---|
| 253 |
The most common case is that you have not yet installed appropriate |
|---|
| 254 |
libraries in LEIM (Libraries of Emacs Input Method) which is |
|---|
| 255 |
distributed separately from Emacs. |
|---|
| 256 |
|
|---|
| 257 |
LEIM is available from the same ftp directory as Emacs.")) |
|---|
| 258 |
(error "Can't use the Quail package `%s'" package-name)) |
|---|
| 259 |
(setq libraries (cdr libraries)))))) |
|---|
| 260 |
(quail-select-package package-name) |
|---|
| 261 |
(setq current-input-method-title (quail-title)) |
|---|
| 262 |
(quail-activate) |
|---|
| 263 |
|
|---|
| 264 |
(message nil)) |
|---|
| 265 |
|
|---|
| 266 |
(defvar quail-translation-keymap |
|---|
| 267 |
(let ((map (make-keymap)) |
|---|
| 268 |
(i 0)) |
|---|
| 269 |
(while (< i ?\ ) |
|---|
| 270 |
(define-key map (char-to-string i) 'quail-other-command) |
|---|
| 271 |
(setq i (1+ i))) |
|---|
| 272 |
(while (< i 127) |
|---|
| 273 |
(define-key map (char-to-string i) 'quail-self-insert-command) |
|---|
| 274 |
(setq i (1+ i))) |
|---|
| 275 |
(setq i 128) |
|---|
| 276 |
(while (< i 256) |
|---|
| 277 |
(define-key map (vector i) 'quail-self-insert-command) |
|---|
| 278 |
(setq i (1+ i))) |
|---|
| 279 |
(define-key map "\177" 'quail-delete-last-char) |
|---|
| 280 |
(define-key map "\C-f" 'quail-next-translation) |
|---|
| 281 |
(define-key map "\C-b" 'quail-prev-translation) |
|---|
| 282 |
(define-key map "\C-n" 'quail-next-translation-block) |
|---|
| 283 |
(define-key map "\C-p" 'quail-prev-translation-block) |
|---|
| 284 |
(define-key map [right] 'quail-next-translation) |
|---|
| 285 |
(define-key map [left] 'quail-prev-translation) |
|---|
| 286 |
(define-key map [down] 'quail-next-translation-block) |
|---|
| 287 |
(define-key map [up] 'quail-prev-translation-block) |
|---|
| 288 |
(define-key map "\C-i" 'quail-completion) |
|---|
| 289 |
(define-key map "\C-@" 'quail-select-current) |
|---|
| 290 |
|
|---|
| 291 |
|
|---|
| 292 |
|
|---|
| 293 |
(define-key map [kp-enter] 'quail-select-current) |
|---|
| 294 |
(define-key map [mouse-2] 'quail-mouse-choose-completion) |
|---|
| 295 |
(define-key map [down-mouse-2] nil) |
|---|
| 296 |
(define-key map "\C-h" 'quail-translation-help) |
|---|
| 297 |
(define-key map [?\C- ] 'quail-select-current) |
|---|
| 298 |
(define-key map [tab] 'quail-completion) |
|---|
| 299 |
(define-key map [delete] 'quail-delete-last-char) |
|---|
| 300 |
(define-key map [backspace] 'quail-delete-last-char) |
|---|
| 301 |
map) |
|---|
| 302 |
"Keymap used processing translation in complex Quail modes. |
|---|
| 303 |
Only a few especially complex input methods use this map; |
|---|
| 304 |
most use `quail-simple-translation-keymap' instead. |
|---|
| 305 |
This map is activated while translation region is active.") |
|---|
| 306 |
|
|---|
| 307 |
(defvar quail-translation-docstring |
|---|
| 308 |
"When you type keys, the echo area shows the possible characters |
|---|
| 309 |
which correspond to that key sequence, each preceded by a digit. You |
|---|
| 310 |
can select one of the characters shown by typing the corresponding |
|---|
| 311 |
digit. Alternatively, you can use C-f and C-b to move through the |
|---|
| 312 |
line to select the character you want, then type a letter to begin |
|---|
| 313 |
entering another Chinese character or type a space or punctuation |
|---|
| 314 |
character. |
|---|
| 315 |
|
|---|
| 316 |
If there are more than ten possible characters for the given spelling, |
|---|
| 317 |
the echo area shows ten characters at a time; you can use C-n to move |
|---|
| 318 |
to the next group of ten, and C-p to move back to the previous group |
|---|
| 319 |
of ten.") |
|---|
| 320 |
|
|---|
| 321 |
|
|---|
| 322 |
|
|---|
| 323 |
|
|---|
| 324 |
|
|---|
| 325 |
|
|---|
| 326 |
(let ((l '((quail-other-command . hide) |
|---|
| 327 |
(quail-self-insert-command . hide) |
|---|
| 328 |
(quail-delete-last-char . hide) |
|---|
| 329 |
(quail-next-translation . non-deterministic) |
|---|
| 330 |
(quail-prev-translation . non-deterministic) |
|---|
| 331 |
(quail-next-translation-block . non-deterministic) |
|---|
| 332 |
(quail-prev-translation-block . non-deterministic)))) |
|---|
| 333 |
(while l |
|---|
| 334 |
(put (car (car l)) 'quail-help (cdr (car l))) |
|---|
| 335 |
(setq l (cdr l)))) |
|---|
| 336 |
|
|---|
| 337 |
(defvar quail-simple-translation-keymap |
|---|
| 338 |
(let ((map (make-keymap)) |
|---|
| 339 |
(i 0)) |
|---|
| 340 |
(while (< i ?\ ) |
|---|
| 341 |
(define-key map (char-to-string i) 'quail-other-command) |
|---|
| 342 |
(setq i (1+ i))) |
|---|
| 343 |
(while (< i 127) |
|---|
| 344 |
(define-key map (char-to-string i) 'quail-self-insert-command) |
|---|
| 345 |
(setq i (1+ i))) |
|---|
| 346 |
(setq i 128) |
|---|
| 347 |
(while (< i 256) |
|---|
| 348 |
(define-key map (vector i) 'quail-self-insert-command) |
|---|
| 349 |
(setq i (1+ i))) |
|---|
| 350 |
(define-key map "\177" 'quail-delete-last-char) |
|---|
| 351 |
(define-key map [delete] 'quail-delete-last-char) |
|---|
| 352 |
(define-key map [backspace] 'quail-delete-last-char) |
|---|
| 353 |
|
|---|
| 354 |
|
|---|
| 355 |
|
|---|
| 356 |
map) |
|---|
| 357 |
"Keymap used while processing translation in simple Quail modes. |
|---|
| 358 |
A few especially complex input methods use `quail-translation-keymap' instead. |
|---|
| 359 |
This map is activated while translation region is active.") |
|---|
| 360 |
|
|---|
| 361 |
(defvar quail-conversion-keymap |
|---|
| 362 |
(let ((map (make-keymap)) |
|---|
| 363 |
(i ?\ )) |
|---|
| 364 |
(while (< i 127) |
|---|
| 365 |
(define-key map (char-to-string i) 'quail-self-insert-command) |
|---|
| 366 |
(setq i (1+ i))) |
|---|
| 367 |
(setq i 128) |
|---|
| 368 |
(while (< i 256) |
|---|
| 369 |
(define-key map (vector i) 'quail-self-insert-command) |
|---|
| 370 |
(setq i (1+ i))) |
|---|
| 371 |
(define-key map "\C-b" 'quail-conversion-backward-char) |
|---|
| 372 |
(define-key map "\C-f" 'quail-conversion-forward-char) |
|---|
| 373 |
(define-key map "\C-a" 'quail-conversion-beginning-of-region) |
|---|
| 374 |
(define-key map "\C-e" 'quail-conversion-end-of-region) |
|---|
| 375 |
(define-key map "\C-d" 'quail-conversion-delete-char) |
|---|
| 376 |
(define-key map "\C-k" 'quail-conversion-delete-tail) |
|---|
| 377 |
(define-key map "\C-h" 'quail-translation-help) |
|---|
| 378 |
(define-key map "\177" 'quail-conversion-backward-delete-char) |
|---|
| 379 |
(define-key map [delete] 'quail-conversion-backward-delete-char) |
|---|
| 380 |
(define-key map [backspace] 'quail-conversion-backward-delete-char) |
|---|
| 381 |
map) |
|---|
| 382 |
"Keymap used for processing conversion in Quail mode. |
|---|
| 383 |
This map is activated while conversion region is active but translation |
|---|
| 384 |
region is not active.") |
|---|
| 385 |
|
|---|
| 386 |
|
|---|
| 387 |
(defun quail-other-command () |
|---|
| 388 |
(interactive) |
|---|
| 389 |
) |
|---|
| 390 |
|
|---|
| 391 |
|
|---|
| 392 |
(defun quail-define-package (name language title |
|---|
| 393 |
&optional guidance docstring translation-keys |
|---|
| 394 |
forget-last-selection deterministic |
|---|
| 395 |
kbd-translate show-layout create-decode-map |
|---|
| 396 |
maximum-shortest overlay-plist |
|---|
| 397 |
update-translation-function |
|---|
| 398 |
conversion-keys simple) |
|---|
| 399 |
"Define NAME as a new Quail package for input LANGUAGE. |
|---|
| 400 |
TITLE is a string to be displayed at mode-line to indicate this package. |
|---|
| 401 |
Optional arguments are GUIDANCE, DOCSTRING, TRANSLATION-KEYS, |
|---|
| 402 |
FORGET-LAST-SELECTION, DETERMINISTIC, KBD-TRANSLATE, SHOW-LAYOUT, |
|---|
| 403 |
CREATE-DECODE-MAP, MAXIMUM-SHORTEST, OVERLAY-PLIST, |
|---|
| 404 |
UPDATE-TRANSLATION-FUNCTION, CONVERSION-KEYS and SIMPLE. |
|---|
| 405 |
|
|---|
| 406 |
GUIDANCE specifies how a guidance string is shown in echo area. |
|---|
| 407 |
If it is t, list of all possible translations for the current key is shown |
|---|
| 408 |
with the currently selected translation being highlighted. |
|---|
| 409 |
If it is an alist, the element has the form (CHAR . STRING). Each character |
|---|
| 410 |
in the current key is searched in the list and the corresponding string is |
|---|
| 411 |
shown. |
|---|
| 412 |
If it is nil, the current key is shown. |
|---|
| 413 |
|
|---|
| 414 |
DOCSTRING is the documentation string of this package. The command |
|---|
| 415 |
`describe-input-method' shows this string while replacing the form |
|---|
| 416 |
\\=\\<VAR> in the string by the value of VAR. That value should be a |
|---|
| 417 |
string. For instance, the form \\=\\<quail-translation-docstring> is |
|---|
| 418 |
replaced by a description about how to select a translation from a |
|---|
| 419 |
list of candidates. |
|---|
| 420 |
|
|---|
| 421 |
TRANSLATION-KEYS specifies additional key bindings used while translation |
|---|
| 422 |
region is active. It is an alist of single key character vs. corresponding |
|---|
| 423 |
command to be called. |
|---|
| 424 |
|
|---|
| 425 |
FORGET-LAST-SELECTION non-nil means a selected translation is not kept |
|---|
| 426 |
for the future to translate the same key. If this flag is nil, a |
|---|
| 427 |
translation selected for a key is remembered so that it can be the |
|---|
| 428 |
first candidate when the same key is entered later. |
|---|
| 429 |
|
|---|
| 430 |
DETERMINISTIC non-nil means the first candidate of translation is |
|---|
| 431 |
selected automatically without allowing users to select another |
|---|
| 432 |
translation for a key. In this case, unselected translations are of |
|---|
| 433 |
no use for an interactive use of Quail but can be used by some other |
|---|
| 434 |
programs. If this flag is non-nil, FORGET-LAST-SELECTION is also set |
|---|
| 435 |
to t. |
|---|
| 436 |
|
|---|
| 437 |
KBD-TRANSLATE non-nil means input characters are translated from a |
|---|
| 438 |
user's keyboard layout to the standard keyboard layout. See the |
|---|
| 439 |
documentation of `quail-keyboard-layout' and |
|---|
| 440 |
`quail-keyboard-layout-standard' for more detail. |
|---|
| 441 |
|
|---|
| 442 |
SHOW-LAYOUT non-nil means the `quail-help' command should show |
|---|
| 443 |
the user's keyboard layout visually with translated characters. |
|---|
| 444 |
If KBD-TRANSLATE is set, it is desirable to set also this flag unless |
|---|
| 445 |
this package defines no translations for single character keys. |
|---|
| 446 |
|
|---|
| 447 |
CREATE-DECODE-MAP non-nil means decode map is also created. A decode |
|---|
| 448 |
map is an alist of translations and corresponding original keys. |
|---|
| 449 |
Although this map is not used by Quail itself, it can be used by some |
|---|
| 450 |
other programs. For instance, Vietnamese supporting needs this map to |
|---|
| 451 |
convert Vietnamese text to VIQR format which uses only ASCII |
|---|
| 452 |
characters to represent Vietnamese characters. |
|---|
| 453 |
|
|---|
| 454 |
MAXIMUM-SHORTEST non-nil means break key sequence to get maximum |
|---|
| 455 |
length of the shortest sequence. When we don't have a translation of |
|---|
| 456 |
key \"..ABCD\" but have translations of \"..AB\" and \"CD..\", break |
|---|
| 457 |
the key at \"..AB\" and start translation of \"CD..\". Hangul |
|---|
| 458 |
packages, for instance, use this facility. If this flag is nil, we |
|---|
| 459 |
break the key just at \"..ABC\" and start translation of \"D..\". |
|---|
| 460 |
|
|---|
| 461 |
OVERLAY-PLIST if non-nil is a property list put on an overlay which |
|---|
| 462 |
covers Quail translation region. |
|---|
| 463 |
|
|---|
| 464 |
UPDATE-TRANSLATION-FUNCTION if non-nil is a function to call to update |
|---|
| 465 |
the current translation region according to a new translation data. By |
|---|
| 466 |
default, a translated text or a user's key sequence (if no translation |
|---|
| 467 |
for it) is inserted. |
|---|
| 468 |
|
|---|
| 469 |
CONVERSION-KEYS specifies additional key bindings used while |
|---|
| 470 |
conversion region is active. It is an alist of single key character |
|---|
| 471 |
vs. corresponding command to be called. |
|---|
| 472 |
|
|---|
| 473 |
If SIMPLE is non-nil, then we do not alter the meanings of |
|---|
| 474 |
commands such as C-f, C-b, C-n, C-p and TAB; they are treated as |
|---|
| 475 |
non-Quail commands." |
|---|
| 476 |
(let (translation-keymap conversion-keymap) |
|---|
| 477 |
(if deterministic (setq forget-last-selection t)) |
|---|
| 478 |
(if translation-keys |
|---|
| 479 |
(progn |
|---|
| 480 |
(setq translation-keymap (copy-keymap |
|---|
| 481 |
(if simple quail-simple-translation-keymap |
|---|
| 482 |
quail-translation-keymap))) |
|---|
| 483 |
(while translation-keys |
|---|
| 484 |
(define-key translation-keymap |
|---|
| 485 |
(car (car translation-keys)) (cdr (car translation-keys))) |
|---|
| 486 |
(setq translation-keys (cdr translation-keys)))) |
|---|
| 487 |
(setq translation-keymap |
|---|
| 488 |
(if simple quail-simple-translation-keymap |
|---|
| 489 |
quail-translation-keymap))) |
|---|
| 490 |
(when conversion-keys |
|---|
| 491 |
(setq conversion-keymap (copy-keymap quail-conversion-keymap)) |
|---|
| 492 |
(while conversion-keys |
|---|
| 493 |
(define-key conversion-keymap |
|---|
| 494 |
(car (car conversion-keys)) (cdr (car conversion-keys))) |
|---|
| 495 |
(setq conversion-keys (cdr conversion-keys)))) |
|---|
| 496 |
(quail-add-package |
|---|
| 497 |
(list name title (list nil) guidance (or docstring "") |
|---|
| 498 |
translation-keymap |
|---|
| 499 |
forget-last-selection deterministic kbd-translate show-layout |
|---|
| 500 |
(if create-decode-map (list 'decode-map) nil) |
|---|
| 501 |
maximum-shortest overlay-plist update-translation-function |
|---|
| 502 |
conversion-keymap simple)) |
|---|
| 503 |
|
|---|
| 504 |
|
|---|
| 505 |
(let ((slot (assoc name input-method-alist)) |
|---|
| 506 |
(val (list language 'quail-use-package title docstring))) |
|---|
| 507 |
(if slot (setcdr slot val) |
|---|
| 508 |
(setq input-method-alist (cons (cons name val) input-method-alist))))) |
|---|
| 509 |
|
|---|
| 510 |
(quail-select-package name)) |
|---|
| 511 |
|
|---|
| 512 |
|
|---|
| 513 |
|
|---|
| 514 |
|
|---|
| 515 |
(defun quail-setup-overlays (conversion-mode) |
|---|
| 516 |
(let ((pos (point))) |
|---|
| 517 |
(if (overlayp quail-overlay) |
|---|
| 518 |
(move-overlay quail-overlay pos pos) |
|---|
| 519 |
(setq quail-overlay (make-overlay pos pos)) |
|---|
| 520 |
(if input-method-highlight-flag |
|---|
| 521 |
(overlay-put quail-overlay 'face 'underline)) |
|---|
| 522 |
(let ((l (quail-overlay-plist))) |
|---|
| 523 |
(while l |
|---|
| 524 |
(overlay-put quail-overlay (car l) (car (cdr l))) |
|---|
| 525 |
(setq l (cdr (cdr l)))))) |
|---|
| 526 |
(if conversion-mode |
|---|
| 527 |
(if (overlayp quail-conv-overlay) |
|---|
| 528 |
(if (not (overlay-start quail-conv-overlay)) |
|---|
| 529 |
(move-overlay quail-conv-overlay pos pos)) |
|---|
| 530 |
(setq quail-conv-overlay (make-overlay pos pos)) |
|---|
| 531 |
(if input-method-highlight-flag |
|---|
| 532 |
(overlay-put quail-conv-overlay 'face 'underline)))))) |
|---|
| 533 |
|
|---|
| 534 |
|
|---|
| 535 |
(defun quail-delete-overlays () |
|---|
| 536 |
(if (and (overlayp quail-overlay) (overlay-start quail-overlay)) |
|---|
| 537 |
(delete-overlay quail-overlay)) |
|---|
| 538 |
(if (and (overlayp quail-conv-overlay) (overlay-start quail-conv-overlay)) |
|---|
| 539 |
(delete-overlay quail-conv-overlay))) |
|---|
| 540 |
|
|---|
| 541 |
(defun quail-inactivate () |
|---|
| 542 |
"Inactivate Quail input method. |
|---|
| 543 |
|
|---|
| 544 |
This function runs the normal hook `quail-inactivate-hook'." |
|---|
| 545 |
(interactive) |
|---|
| 546 |
(quail-activate -1)) |
|---|
| 547 |
|
|---|
| 548 |
(defun quail-activate (&optional arg) |
|---|
| 549 |
"Activate Quail input method. |
|---|
| 550 |
With arg, activate Quail input method if and only if arg is positive. |
|---|
| 551 |
|
|---|
| 552 |
This function runs `quail-activate-hook' if it activates the input |
|---|
| 553 |
method, `quail-inactivate-hook' if it deactivates it. |
|---|
| 554 |
|
|---|
| 555 |
While this input method is active, the variable |
|---|
| 556 |
`input-method-function' is bound to the function `quail-input-method'." |
|---|
| 557 |
(if (and arg |
|---|
| 558 |
(< (prefix-numeric-value arg) 0)) |
|---|
| 559 |
|
|---|
| 560 |
(unwind-protect |
|---|
| 561 |
(progn |
|---|
| 562 |
(quail-delete-overlays) |
|---|
| 563 |
(setq describe-current-input-method-function nil) |
|---|
| 564 |
(quail-hide-guidance) |
|---|
| 565 |
(remove-hook 'post-command-hook 'quail-show-guidance t) |
|---|
| 566 |
(run-hooks 'quail-inactivate-hook)) |
|---|
| 567 |
(kill-local-variable 'input-method-function)) |
|---|
| 568 |
|
|---|
| 569 |
(if (null quail-current-package) |
|---|
| 570 |
|
|---|
| 571 |
(let (name) |
|---|
| 572 |
(if quail-package-alist |
|---|
| 573 |
(setq name (car (car quail-package-alist))) |
|---|
| 574 |
(error "No Quail package loaded")) |
|---|
| 575 |
(quail-select-package name))) |
|---|
| 576 |
(setq inactivate-current-input-method-function 'quail-inactivate) |
|---|
| 577 |
(setq describe-current-input-method-function 'quail-help) |
|---|
| 578 |
(quail-delete-overlays) |
|---|
| 579 |
(setq quail-guidance-str "") |
|---|
| 580 |
(quail-show-guidance) |
|---|
| 581 |
|
|---|
| 582 |
|
|---|
| 583 |
(when (eq (selected-window) (minibuffer-window)) |
|---|
| 584 |
(add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer) |
|---|
| 585 |
(add-hook 'post-command-hook 'quail-show-guidance nil t)) |
|---|
| 586 |
(run-hooks 'quail-activate-hook) |
|---|
| 587 |
(make-local-variable 'input-method-function) |
|---|
| 588 |
(setq input-method-function 'quail-input-method))) |
|---|
| 589 |
|
|---|
| 590 |
(defun quail-exit-from-minibuffer () |
|---|
| 591 |
(inactivate-input-method) |
|---|
| 592 |
(if (<= (minibuffer-depth) 1) |
|---|
| 593 |
(remove-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer))) |
|---|
| 594 |
|
|---|
| 595 |
|
|---|
| 596 |
|
|---|
| 597 |
|
|---|
| 598 |
|
|---|
| 599 |
|
|---|
| 600 |
|
|---|
| 601 |
|
|---|
| 602 |
|
|---|
| 603 |
|
|---|
| 604 |
|
|---|
| 605 |
|
|---|
| 606 |
(defconst quail-keyboard-layout-standard |
|---|
| 607 |
"\ |
|---|
| 608 |
\ |
|---|
| 609 |
1!2@3#4$5%6^7&8*9(0)-_=+`~ \ |
|---|
| 610 |
qQwWeErRtTyYuUiIoOpP[{]} \ |
|---|
| 611 |
aAsSdDfFgGhHjJkKlL;:'\"\\| \ |
|---|
| 612 |
zZxXcCvVbBnNmM,<.>/? \ |
|---|
| 613 |
" |
|---|
| 614 |
"Standard keyboard layout of printable characters Quail assumes. |
|---|
| 615 |
See the documentation of `quail-keyboard-layout' for this format. |
|---|
| 616 |
This layout is almost the same as that of VT100, |
|---|
| 617 |
but the location of key \\ (backslash) is just right of key ' (single-quote), |
|---|
| 618 |
not right of RETURN key.") |
|---|
| 619 |
|
|---|
| 620 |
(defconst quail-keyboard-layout-len 180) |
|---|
| 621 |
|
|---|
| 622 |
|
|---|
| 623 |
|
|---|
| 624 |
(defvar quail-keyboard-layout-alist |
|---|
| 625 |
(list |
|---|
| 626 |
(cons "standard" quail-keyboard-layout-standard) |
|---|
| 627 |
'("sun-type3" . "\ |
|---|
| 628 |
\ |
|---|
| 629 |
1!2@3#4$5%6^7&8*9(0)-_=+\\|`~\ |
|---|
| 630 |
qQwWeErRtTyYuUiIoOpP[{]} \ |
|---|
| 631 |
aAsSdDfFgGhHjJkKlL;:'\" \ |
|---|
| 632 |
zZxXcCvVbBnNmM,<.>/? \ |
|---|
| 633 |
") |
|---|
| 634 |
'("atari-german" . "\ |
|---|
| 635 |
\ |
|---|
| 636 |
1!2\"3\2474$5%6&7/8(9)0=\337?'`#^ \ |
|---|
| 637 |
qQwWeErRtTzZuUiIoOpP\374\334+* \ |
|---|
| 638 |
aAsSdDfFgGhHjJkKlL\366\326\344\304~| \ |
|---|
| 639 |
<>yYxXcCvVbBnNmM,;.:-_ \ |
|---|
| 640 |
") |
|---|
| 641 |
|
|---|
| 642 |
'("pc102-de" . "\ |
|---|
| 643 |
\ |
|---|
| 644 |
^\2601!2\"3\2474$5%6&7/8(9)0=\337?\264`#' \ |
|---|
| 645 |
qQwWeErRtTzZuUiIoOpP\374\334+* \ |
|---|
| 646 |
aAsSdDfFgGhHjJkKlL\366\326\344\304 \ |
|---|
| 647 |
<>yYxXcCvVbBnNmM,;.:-_ \ |
|---|
| 648 |
") |
|---|
| 649 |
|
|---|
| 650 |
'("jp106" . "\ |
|---|
| 651 |
\ |
|---|
| 652 |
1!2\"3#4$5%6&7'8(9)0~-=^~\\| \ |
|---|
| 653 |
qQwWeErRtTyYuUiIoOpP@`[{ \ |
|---|
| 654 |
aAsSdDfFgGhHjJkKlL;+:*]} \ |
|---|
| 655 |
zZxXcCvVbBnNmM,<.>/?\\_ \ |
|---|
| 656 |
") |
|---|
| 657 |
'("pc105-uk" . "\ |
|---|
| 658 |
\ |
|---|
| 659 |
`\2541!2\"3\2434$5%6^7&8*9(0)-_=+ \ |
|---|
| 660 |
qQwWeErRtTyYuUiIoOpP[{]} \ |
|---|
| 661 |
aAsSdDfFgGhHjJkKlL;:'@#~ \ |
|---|
| 662 |
\\|zZxXcCvVbBnNmM,<.>/? \ |
|---|
| 663 |
") |
|---|
| 664 |
) |
|---|
| 665 |
"Alist of keyboard names and corresponding layout strings. |
|---|
| 666 |
See the documentation of `quail-keyboard-layout' for the format of |
|---|
| 667 |
the layout string.") |
|---|
| 668 |
|
|---|
| 669 |
(defcustom quail-keyboard-layout quail-keyboard-layout-standard |
|---|
| 670 |
"A string which represents physical key layout of a particular keyboard. |
|---|
| 671 |
We assume there are six rows and each row has 15 keys (columns), |
|---|
| 672 |
the first row is above the `1' - `0' row, |
|---|
| 673 |
the first column of the second row is left of key `1', |
|---|
| 674 |
the first column of the third row is left of key `q', |
|---|
| 675 |
the first column of the fourth row is left of key `a', |
|---|
| 676 |
the first column of the fifth row is left of key `z', |
|---|
| 677 |
the sixth row is below the `z' - `/' row. |
|---|
| 678 |
Nth (N is even) and (N+1)th characters in the string are non-shifted |
|---|
| 679 |
and shifted characters respectively at the same location. |
|---|
| 680 |
The location of Nth character is row (N / 30) and column ((N mod 30) / 2). |
|---|
| 681 |
The command `quail-set-keyboard-layout' usually sets this variable." |
|---|
| 682 |
:group 'quail |
|---|
| 683 |
:type `(choice |
|---|
| 684 |
,@(mapcar (lambda (pair) |
|---|
| 685 |
(list 'const :tag (car pair) (cdr pair))) |
|---|
| 686 |
quail-keyboard-layout-alist) |
|---|
| 687 |
(string :tag "Other"))) |
|---|
| 688 |
|
|---|
| 689 |
|
|---|
| 690 |
|
|---|
| 691 |
|
|---|
| 692 |
|
|---|
| 693 |
|
|---|
| 694 |
(defvar quail-keyboard-layout-substitution nil) |
|---|
| 695 |
|
|---|
| 696 |
(defun quail-update-keyboard-layout (kbd-type) |
|---|
| 697 |
(let ((layout (assoc kbd-type quail-keyboard-layout-alist))) |
|---|
| 698 |
(if (null layout) |
|---|
| 699 |
|
|---|
| 700 |
|
|---|
| 701 |
(error "Unknown keyboard type `%s'" kbd-type)) |
|---|
| 702 |
(setq quail-keyboard-layout (cdr layout)) |
|---|
| 703 |
(let ((i quail-keyboard-layout-len) |
|---|
| 704 |
subst-list missing-list) |
|---|
| 705 |
|
|---|
| 706 |
|
|---|
| 707 |
(while (> i 0) |
|---|
| 708 |
(setq i (1- i)) |
|---|
| 709 |
(if (= (aref quail-keyboard-layout i) ? ) |
|---|
| 710 |
(if (/= (aref quail-keyboard-layout-standard i) ? ) |
|---|
| 711 |
(setq missing-list (cons i missing-list))) |
|---|
| 712 |
(if (= (aref quail-keyboard-layout-standard i) ? ) |
|---|
| 713 |
(setq subst-list (cons (cons i nil) subst-list))))) |
|---|
| 714 |
(setq quail-keyboard-layout-substitution subst-list) |
|---|
| 715 |
|
|---|
| 716 |
|
|---|
| 717 |
(while missing-list |
|---|
| 718 |
(while (and subst-list (cdr (car subst-list))) |
|---|
| 719 |
(setq subst-list (cdr subst-list))) |
|---|
| 720 |
(if subst-list |
|---|
| 721 |
(setcdr (car subst-list) (car missing-list))) |
|---|
| 722 |
(setq missing-list (cdr missing-list)))))) |
|---|
| 723 |
|
|---|
| 724 |
(defcustom quail-keyboard-layout-type "standard" |
|---|
| 725 |
"Type of keyboard layout used in Quail base input method. |
|---|
| 726 |
Available types are listed in the variable `quail-keyboard-layout-alist'." |
|---|
| 727 |
:group 'quail |
|---|
| 728 |
:type (cons 'choice (mapcar (lambda (elt) |
|---|
| 729 |
(list 'const (car elt))) |
|---|
| 730 |
quail-keyboard-layout-alist)) |
|---|
| 731 |
:set #'(lambda (symbol value) |
|---|
| 732 |
(quail-update-keyboard-layout value) |
|---|
| 733 |
(set symbol value))) |
|---|
| 734 |
|
|---|
| 735 |
|
|---|
| 736 |
(defun quail-set-keyboard-layout (kbd-type) |
|---|
| 737 |
"Set the current keyboard layout to the same as keyboard KBD-TYPE. |
|---|
| 738 |
|
|---|
| 739 |
Since some Quail packages depends on a physical layout of keys (not |
|---|
| 740 |
characters generated by them), those are created by assuming the |
|---|
| 741 |
standard layout defined in `quail-keyboard-layout-standard'. This |
|---|
| 742 |
function tells Quail system the layout of your keyboard so that what |
|---|
| 743 |
you type is correctly handled." |
|---|
| 744 |
(interactive |
|---|
| 745 |
(let* ((completion-ignore-case t) |
|---|
| 746 |
(type (completing-read "Keyboard type: " |
|---|
| 747 |
quail-keyboard-layout-alist))) |
|---|
| 748 |
(list type))) |
|---|
| 749 |
(quail-update-keyboard-layout kbd-type) |
|---|
| 750 |
(setq quail-keyboard-layout-type kbd-type)) |
|---|
| 751 |
|
|---|
| 752 |
(defun quail-keyboard-translate (char) |
|---|
| 753 |
"Translate CHAR to the one in the standard keyboard layout." |
|---|
| 754 |
(if (eq quail-keyboard-layout quail-keyboard-layout-standard) |
|---|
| 755 |
|
|---|
| 756 |
|
|---|
| 757 |
char |
|---|
| 758 |
(let ((i 0)) |
|---|
| 759 |
|
|---|
| 760 |
(while (and (< i quail-keyboard-layout-len) |
|---|
| 761 |
(/= char (aref quail-keyboard-layout i))) |
|---|
| 762 |
(setq i (1+ i))) |
|---|
| 763 |
(if (= i quail-keyboard-layout-len) |
|---|
| 764 |
|
|---|
| 765 |
|
|---|
| 766 |
|
|---|
| 767 |
|
|---|
| 768 |
char |
|---|
| 769 |
(let ((ch (aref quail-keyboard-layout-standard i))) |
|---|
| 770 |
(if (= ch ?\ ) |
|---|
| 771 |
|
|---|
| 772 |
|
|---|
| 773 |
|
|---|
| 774 |
(if (setq i (cdr (assq i quail-keyboard-layout-substitution))) |
|---|
| 775 |
(aref quail-keyboard-layout-standard i) |
|---|
| 776 |
|
|---|
| 777 |
char) |
|---|
| 778 |
ch)))))) |
|---|
| 779 |
|
|---|
| 780 |
(defun quail-keyseq-translate (keyseq) |
|---|
| 781 |
(apply 'string |
|---|
| 782 |
(mapcar (function (lambda (x) (quail-keyboard-translate x))) |
|---|
| 783 |
keyseq))) |
|---|
| 784 |
|
|---|
| 785 |
(defun quail-insert-kbd-layout (kbd-layout) |
|---|
| 786 |
"Insert the visual keyboard layout table according to KBD-LAYOUT. |
|---|
| 787 |
The format of KBD-LAYOUT is the same as `quail-keyboard-layout'." |
|---|
| 788 |
(let (done-list layout i ch) |
|---|
| 789 |
|
|---|
| 790 |
|
|---|
| 791 |
(setq layout (string-to-vector kbd-layout) |
|---|
| 792 |
i 0) |
|---|
| 793 |
(while (< i quail-keyboard-layout-len) |
|---|
| 794 |
(setq ch (aref kbd-layout i)) |
|---|
| 795 |
(if (quail-kbd-translate) |
|---|
| 796 |
(setq ch (quail-keyboard-translate ch))) |
|---|
| 797 |
(let* ((map (cdr (assq ch (cdr (quail-map))))) |
|---|
| 798 |
(translation (and map (quail-get-translation |
|---|
| 799 |
(car map) (char-to-string ch) 1)))) |
|---|
| 800 |
(if translation |
|---|
| 801 |
(progn |
|---|
| 802 |
(if (consp translation) |
|---|
| 803 |
(setq translation (aref (cdr translation) 0))) |
|---|
| 804 |
(setq done-list (cons translation done-list))) |
|---|
| 805 |
(setq translation ch)) |
|---|
| 806 |
(aset layout i translation)) |
|---|
| 807 |
(setq i (1+ i))) |
|---|
| 808 |
|
|---|
| 809 |
(let ((pos (point)) |
|---|
| 810 |
(bar "|") |
|---|
| 811 |
lower upper row) |
|---|
| 812 |
|
|---|
| 813 |
|
|---|
| 814 |
|
|---|
| 815 |
|
|---|
| 816 |
(put-text-property 0 1 'face 'bold bar) |
|---|
| 817 |
(setq i 0) |
|---|
| 818 |
(while (< i quail-keyboard-layout-len) |
|---|
| 819 |
(when (= (% i 30) 0) |
|---|
| 820 |
(setq row (/ i 30)) |
|---|
| 821 |
(if (> row 1) |
|---|
| 822 |
(insert-char 32 (+ row (/ (- row 2) 2))))) |
|---|
| 823 |
(setq lower (aref layout i) |
|---|
| 824 |
upper (aref layout (1+ i))) |
|---|
| 825 |
(if (and (integerp lower) (>= lower 128) (< lower 256)) |
|---|
| 826 |
(setq lower (unibyte-char-to-multibyte lower))) |
|---|
| 827 |
(if (and (integerp upper) (>= upper 128) (< upper 256)) |
|---|
| 828 |
(setq upper (unibyte-char-to-multibyte upper))) |
|---|
| 829 |
(insert bar) |
|---|
| 830 |
(if (= (if (stringp lower) (string-width lower) (char-width lower)) 1) |
|---|
| 831 |
(insert " " |
|---|