diff options
| -rw-r--r-- | lisp/international/mule-cmds.el | 289 |
1 files changed, 166 insertions, 123 deletions
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 5e4dfe69604..94e8ac37518 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el | |||
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | (define-key help-map "\C-L" 'describe-language-environment) | 44 | (define-key help-map "\C-L" 'describe-language-environment) |
| 45 | (define-key help-map "\C-\\" 'describe-input-method) | 45 | (define-key help-map "\C-\\" 'describe-input-method) |
| 46 | (define-key help-map "C" 'describe-current-coding-system) | 46 | (define-key help-map "C" 'describe-coding-system) |
| 47 | (define-key help-map "h" 'view-hello-file) | 47 | (define-key help-map "h" 'view-hello-file) |
| 48 | 48 | ||
| 49 | (defvar mule-menu-keymap nil | 49 | (defvar mule-menu-keymap nil |
| @@ -87,8 +87,8 @@ | |||
| 87 | (define-key-after mule-menu-keymap [separator-input-method] | 87 | (define-key-after mule-menu-keymap [separator-input-method] |
| 88 | '("--") | 88 | '("--") |
| 89 | t) | 89 | t) |
| 90 | (define-key-after mule-menu-keymap [describe-current-coding-system] | 90 | (define-key-after mule-menu-keymap [describe-coding-system] |
| 91 | '("Describe coding systems" . describe-current-coding-system) | 91 | '("Describe coding systems" . describe-coding-system) |
| 92 | t) | 92 | t) |
| 93 | (define-key-after mule-menu-keymap [set-various-coding-system] | 93 | (define-key-after mule-menu-keymap [set-various-coding-system] |
| 94 | '("Set coding systems" . set-coding-system-map) | 94 | '("Set coding systems" . set-coding-system-map) |
| @@ -124,6 +124,9 @@ | |||
| 124 | '(null window-system)) | 124 | '(null window-system)) |
| 125 | (put 'set-keyboard-coding-system 'menu-enable | 125 | (put 'set-keyboard-coding-system 'menu-enable |
| 126 | '(null window-system)) | 126 | '(null window-system)) |
| 127 | ;; This is meaningless when the current buffer has no process. | ||
| 128 | (put 'set-buffer-process-coding-system 'menu-enable | ||
| 129 | '(get-buffer-process (current-buffer))) | ||
| 127 | 130 | ||
| 128 | ;; This should be a single character key binding because users use it | 131 | ;; This should be a single character key binding because users use it |
| 129 | ;; very frequently while editing multilingual text. Now we can use | 132 | ;; very frequently while editing multilingual text. Now we can use |
| @@ -202,10 +205,6 @@ tutorial: a tutorial file name written in the language. | |||
| 202 | 205 | ||
| 203 | sample-text: one line short text containing characters of the language. | 206 | sample-text: one line short text containing characters of the language. |
| 204 | 207 | ||
| 205 | input-method: alist of input method names for the language vs information | ||
| 206 | for activating them. Use `register-input-method' (which see) | ||
| 207 | to add a new input method to the alist. | ||
| 208 | |||
| 209 | documentation: t or a string describing how Emacs supports the language. | 208 | documentation: t or a string describing how Emacs supports the language. |
| 210 | If a string is specified, it is shown before any other information | 209 | If a string is specified, it is shown before any other information |
| 211 | of the language by the command `describe-language-environment'. | 210 | of the language by the command `describe-language-environment'. |
| @@ -277,34 +276,78 @@ ALIST is an alist of KEY and INFO. See the documentation of | |||
| 277 | 276 | ||
| 278 | ;;; Multilingual input methods. | 277 | ;;; Multilingual input methods. |
| 279 | 278 | ||
| 279 | (defconst leim-list-file-name "leim-list.el" | ||
| 280 | "Name of LEIM list file. | ||
| 281 | This file contains a list of libraries of Emacs input methods (LEIM) | ||
| 282 | in the format of Lisp expression for registering each input method. | ||
| 283 | Emacs loads this file at startup time.") | ||
| 284 | |||
| 285 | (defvar leim-list-header (format "\ | ||
| 286 | ;;; %s -- list of LEIM (Library of Emacs Input Method) | ||
| 287 | ;; | ||
| 288 | ;; This file contains a list of LEIM (Library of Emacs Input Method) | ||
| 289 | ;; in the same directory as this file. Loading this file registeres | ||
| 290 | ;; the whole input methods in Emacs. | ||
| 291 | ;; | ||
| 292 | ;; Each entry is has the form: | ||
| 293 | ;; (register-input-method | ||
| 294 | ;; INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC | ||
| 295 | ;; TITLE DESCRIPTION | ||
| 296 | ;; ARG ...) | ||
| 297 | ;; See the function `register-input-method' for the meanings of arguments. | ||
| 298 | ;; | ||
| 299 | ;; If this directory is included in load-path, Emacs automatically | ||
| 300 | ;; loads this file at startup time. | ||
| 301 | |||
| 302 | " | ||
| 303 | leim-list-file-name) | ||
| 304 | "Header to be inserted in LEIM list file.") | ||
| 305 | |||
| 306 | (defvar leim-list-entry-regexp "(register-input-method" | ||
| 307 | "Regexp matching head of each entry in LEIM list file. | ||
| 308 | See also the variable `leim-list-header'") | ||
| 309 | |||
| 310 | (defvar update-leim-list-functions | ||
| 311 | '(quail-update-leim-list-file) | ||
| 312 | "List of functions to call to update LEIM list file. | ||
| 313 | Each function is called with one arg, LEIM directory name.") | ||
| 314 | |||
| 315 | (defun update-leim-list-file (dir) | ||
| 316 | "Update LEIM list file in directory DIR." | ||
| 317 | (let ((functions update-leim-list-functions)) | ||
| 318 | (while functions | ||
| 319 | (funcall (car functions) (expand-file-name dir)) | ||
| 320 | (setq functions (cdr functions))))) | ||
| 321 | |||
| 322 | (defun update-all-leim-list-files () | ||
| 323 | "Update all the LEIM list files." | ||
| 324 | (interactive) | ||
| 325 | (let ((l load-path)) | ||
| 326 | (while l | ||
| 327 | (if (string-match "leim" (car l)) | ||
| 328 | (update-leim-list-file (car l))) | ||
| 329 | (setq l (cdr l))))) | ||
| 330 | |||
| 280 | (defvar current-input-method nil | 331 | (defvar current-input-method nil |
| 281 | "The current input method for multilingual text. | 332 | "The current input method for multilingual text. |
| 282 | The value is a cons of language name and input method name. | ||
| 283 | If nil, it means no input method is activated now.") | 333 | If nil, it means no input method is activated now.") |
| 284 | (make-variable-buffer-local 'current-input-method) | 334 | (make-variable-buffer-local 'current-input-method) |
| 285 | (put 'current-input-method 'permanent-local t) | 335 | (put 'current-input-method 'permanent-local t) |
| 286 | 336 | ||
| 287 | (defvar current-input-method-title nil | 337 | (defvar current-input-method-title nil |
| 288 | "Title string of the current input method shown in mode line. | 338 | "Title string of the current input method shown in mode line.") |
| 289 | Every input method should set this to an appropriate value when activated.") | ||
| 290 | (make-variable-buffer-local 'current-input-method-title) | 339 | (make-variable-buffer-local 'current-input-method-title) |
| 291 | (put 'current-input-method-title 'permanent-local t) | 340 | (put 'current-input-method-title 'permanent-local t) |
| 292 | 341 | ||
| 293 | (defvar default-input-method nil | 342 | (defvar default-input-method nil |
| 294 | "Default input method. | 343 | "Default input method for multilingual text. |
| 295 | The default input method is the one activated automatically by the command | 344 | The default input method is the one activated automatically by the command |
| 296 | `toggle-input-method' (\\[toggle-input-method]). | 345 | `toggle-input-method' (\\[toggle-input-method]).") |
| 297 | The value is a cons of language name and input method name.") | ||
| 298 | (make-variable-buffer-local 'default-input-method) | 346 | (make-variable-buffer-local 'default-input-method) |
| 299 | (put 'default-input-method 'permanent-local t) | 347 | (put 'default-input-method 'permanent-local t) |
| 300 | 348 | ||
| 301 | (defvar default-input-method-title nil | ||
| 302 | "Title string of the default input method.") | ||
| 303 | (make-variable-buffer-local 'default-input-method-title) | ||
| 304 | (put 'default-input-method-title 'permanent-local t) | ||
| 305 | |||
| 306 | (defvar previous-input-method nil | 349 | (defvar previous-input-method nil |
| 307 | "Input method selected previously. | 350 | "Input method selected previously in the current buffer. |
| 308 | This is the one selected before the current input method is selected. | 351 | This is the one selected before the current input method is selected. |
| 309 | See also the documentation of `default-input-method'.") | 352 | See also the documentation of `default-input-method'.") |
| 310 | (make-variable-buffer-local 'previous-input-method) | 353 | (make-variable-buffer-local 'previous-input-method) |
| @@ -323,66 +366,59 @@ This function is called with no argument.") | |||
| 323 | (make-variable-buffer-local 'describe-current-input-method-function) | 366 | (make-variable-buffer-local 'describe-current-input-method-function) |
| 324 | (put 'describe-current-input-method-function 'permanent-local t) | 367 | (put 'describe-current-input-method-function 'permanent-local t) |
| 325 | 368 | ||
| 326 | (defun register-input-method (language-name input-method) | 369 | (defvar input-method-alist nil |
| 327 | "Register INPUT-METHOD as an input method of LANGUAGE-NAME. | 370 | "Alist of input method names vs the corresponding information to use it. |
| 328 | LANGUAGE-NAME is a string. | 371 | Each element has the form: |
| 329 | INPUT-METHOD is a list of the form: | 372 | (INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC TITLE DESCRIPTION ...) |
| 330 | (METHOD-NAME ACTIVATE-FUNC ARG ...) | 373 | See the function `register-input-method' for the meanings of each elements.") |
| 331 | where METHOD-NAME is the name of this method, | 374 | |
| 332 | ACTIVATE-FUNC is the function to call for activating this method. | 375 | (defun register-input-method (input-method language-name &rest args) |
| 333 | Arguments for the function are METHOD-NAME and ARGs." | 376 | "Register INPUT-METHOD as an input method for LANGUAGE-NAME. |
| 334 | (let ((slot (get-language-info language-name 'input-method)) | 377 | INPUT-METHOD and LANGUAGE-NAME are strings. |
| 335 | method-slot) | 378 | The remaining arguments are: |
| 336 | (if (null slot) | 379 | ACTIVATE-FUNC, TITLE, DESCRIPTION, and ARG ... |
| 337 | (set-language-info language-name 'input-method (list input-method)) | 380 | where, |
| 338 | (setq method-slot (assoc (car input-method) slot)) | 381 | ACTIVATE-FUNC is a function to call for activating this method. |
| 339 | (if method-slot | 382 | TITLE is a string shown in mode-line while this method is active, |
| 340 | (setcdr method-slot (cdr input-method)) | 383 | DESCRIPTION is a string describing about this method, |
| 341 | (set-language-info language-name 'input-method | 384 | Arguments to ACTIVATE-FUNC are INPUT-METHOD and ARGs." |
| 342 | (cons input-method slot)))))) | 385 | (let ((info (cons language-name args)) |
| 343 | 386 | (slot (assoc input-method input-method-alist))) | |
| 344 | (defun read-language-and-input-method-name () | 387 | (if slot |
| 345 | "Read a language name and the corresponding input method from a minibuffer. | 388 | (setcdr slot info) |
| 346 | Return a list of those names." | 389 | (setq slot (cons input-method info)) |
| 347 | (let* ((default-val (or previous-input-method default-input-method)) | 390 | (setq input-method-alist (cons slot input-method-alist))))) |
| 348 | (language-name (read-language-name | 391 | |
| 349 | 'input-method "Language: " | 392 | (defun read-input-method-name (prompt &optional initial-input inhibit-null) |
| 350 | (if default-val (cons (car default-val) 0))))) | 393 | "Read a name of input method from a minibuffer prompting with PROMPT. |
| 351 | (if (null language-name) | 394 | If INITIAL-INPUT is non-nil, insert it in the minibuffer initially. |
| 352 | (error "No input method for the specified language")) | 395 | If it is (STRING . POSITION), the initial input |
| 353 | (if (not (string= language-name (car default-val))) | 396 | is STRING, but point is placed POSITION characters into the string. |
| 354 | ;; Now the default value has no meaning. | 397 | If INHIBIT-NULL is non-nil, null input signals an error." |
| 355 | (setq default-val nil)) | 398 | (let* ((completion-ignore-case t) |
| 356 | (let* ((completion-ignore-case t) | 399 | (input-method (completing-read prompt input-method-alist |
| 357 | (key-slot (cdr (assq 'input-method | 400 | nil t initial-input))) |
| 358 | (assoc language-name language-info-alist)))) | 401 | (if (> (length input-method) 0) |
| 359 | (method-name | 402 | input-method |
| 360 | (completing-read "Input method: " key-slot nil t | 403 | (if inhibit-null |
| 361 | (if default-val (cons (cdr default-val) 0))))) | 404 | (error "The specified input method is not avairable"))))) |
| 362 | (if (= (length method-name) 0) | 405 | |
| 363 | (error "No input method specified")) | 406 | ;; Actvate INPUT-METHOD. |
| 364 | (list language-name | 407 | (defun activate-input-method (input-method) |
| 365 | (car (assoc-ignore-case method-name key-slot)))))) | ||
| 366 | |||
| 367 | ;; Actvate input method METHOD-NAME for langauge LANGUAGE-NAME. | ||
| 368 | (defun activate-input-method (language-name method-name) | ||
| 369 | (if (and current-input-method | 408 | (if (and current-input-method |
| 370 | (or (not (string= (car current-input-method) language-name)) | 409 | (not (string= current-input-method input-method))) |
| 371 | (not (string= (cdr current-input-method) method-name)))) | ||
| 372 | (inactivate-input-method)) | 410 | (inactivate-input-method)) |
| 373 | (or current-input-method | 411 | (if current-input-method |
| 374 | (let* ((key-slot (get-language-info language-name 'input-method)) | 412 | nil ; We have nothing to do. |
| 375 | (method-slot (cdr (assoc method-name key-slot)))) | 413 | (let ((slot (assoc input-method input-method-alist))) |
| 376 | (if (null method-slot) | 414 | (if (null slot) |
| 377 | (error "Invalid input method `%s' for %s" | 415 | (error "Invalid input method `%s'" input-method)) |
| 378 | method-name language-name)) | 416 | (apply (nth 2 slot) input-method (nthcdr 5 slot)) |
| 379 | (apply (car method-slot) method-name (cdr method-slot)) | 417 | (setq current-input-method input-method) |
| 380 | (setq current-input-method (cons language-name method-name)) | 418 | (setq current-input-method-title (nth 3 slot)) |
| 381 | (if (not (equal default-input-method current-input-method)) | 419 | (if (not (string= default-input-method current-input-method)) |
| 382 | (progn | 420 | (setq previous-input-method default-input-method |
| 383 | (setq previous-input-method default-input-method) | 421 | default-input-method current-input-method))))) |
| 384 | (setq default-input-method current-input-method) | ||
| 385 | (setq default-input-method-title current-input-method-title)))))) | ||
| 386 | 422 | ||
| 387 | ;; Inactivate the current input method. | 423 | ;; Inactivate the current input method. |
| 388 | (defun inactivate-input-method () | 424 | (defun inactivate-input-method () |
| @@ -391,44 +427,52 @@ Return a list of those names." | |||
| 391 | (funcall inactivate-current-input-method-function) | 427 | (funcall inactivate-current-input-method-function) |
| 392 | (setq current-input-method nil)))) | 428 | (setq current-input-method nil)))) |
| 393 | 429 | ||
| 394 | (defun select-input-method (language-name method-name) | 430 | (defun select-input-method (input-method) |
| 395 | "Select and activate input method METHOD-NAME for inputting LANGUAGE-NAME. | 431 | "Select and activate INPUT-METHOD. |
| 396 | Both the default and local values of default-input-method are | 432 | Both the default and local values of default-input-method are |
| 397 | set to the selected input method. | 433 | set to the selected input method. |
| 398 | 434 | See also the function `register-input-method'." | |
| 399 | The information for activating METHOD-NAME is stored | 435 | (interactive |
| 400 | in `language-info-alist' under the key 'input-method. | 436 | (let* ((default (or previous-input-method default-input-method)) |
| 401 | The format of the information has the form: | 437 | (initial (if default (cons default 0)))) |
| 402 | ((METHOD-NAME ACTIVATE-FUNC ARG ...) ...) | 438 | (list (read-input-method-name "Input method: " initial t)))) |
| 403 | where ACTIVATE-FUNC is a function to call for activating this method. | 439 | (activate-input-method input-method) |
| 404 | Arguments for the function are METHOD-NAME and ARGs." | 440 | (setq-default default-input-method default-input-method)) |
| 405 | (interactive (read-language-and-input-method-name)) | ||
| 406 | (activate-input-method language-name method-name) | ||
| 407 | (setq-default default-input-method default-input-method) | ||
| 408 | (setq-default default-input-method-title default-input-method-title)) | ||
| 409 | 441 | ||
| 410 | (defun toggle-input-method (&optional arg) | 442 | (defun toggle-input-method (&optional arg) |
| 411 | "Turn on or off a multilingual text input method for the current buffer. | 443 | "Turn on or off a multilingual text input method for the current buffer. |
| 412 | With arg, turn on an input method specified interactively. | 444 | With arg, read an input method from minibuffer and turn it on. |
| 413 | Without arg, if some input method is currently activated, turn it off, | 445 | Without arg, if some input method is currently activated, turn it off, |
| 414 | else turn on default-input-method (which see). | 446 | else turn on default-input-method (which see). |
| 415 | In the latter case, if default-input-method is nil, select an input method | 447 | In the latter case, if default-input-method is nil, select an input method |
| 416 | interactively." | 448 | interactively." |
| 417 | (interactive "P") | 449 | (interactive "P") |
| 418 | (if arg | 450 | (let* ((default (or previous-input-method default-input-method)) |
| 419 | (let ((input-method (read-language-and-input-method-name))) | 451 | (initial (if default (cons default 0)))) |
| 420 | (activate-input-method (car input-method) (nth 1 input-method))) | 452 | (if arg |
| 421 | (if current-input-method | 453 | (activate-input-method |
| 422 | (inactivate-input-method) | 454 | (read-input-method-name "Input method: " initial t)) |
| 423 | (if default-input-method | 455 | (if current-input-method |
| 424 | (activate-input-method (car default-input-method) | 456 | (inactivate-input-method) |
| 425 | (cdr default-input-method)) | 457 | (if default-input-method |
| 426 | (let ((input-method (read-language-and-input-method-name))) | 458 | (activate-input-method default-input-method) |
| 427 | (activate-input-method (car input-method) (nth 1 input-method))))))) | 459 | (activate-input-method |
| 428 | 460 | (read-input-method-name "Input method: " initial t))))))) | |
| 429 | (defun describe-input-method () | 461 | |
| 462 | (defun describe-input-method (input-method) | ||
| 430 | "Describe the current input method." | 463 | "Describe the current input method." |
| 431 | (interactive) | 464 | (interactive |
| 465 | (list (read-input-method-name | ||
| 466 | "Describe input method (default, current choice): "))) | ||
| 467 | (if (null input-method) | ||
| 468 | (describe-current-input-method) | ||
| 469 | (with-output-to-temp-buffer "*Help*" | ||
| 470 | (let ((elt (assoc input-method input-method-alist))) | ||
| 471 | (princ (format "Input method: %s (`%s' in mode line) for %s\n %s\n" | ||
| 472 | input-method (nth 3 elt) (nth 1 elt) (nth 4 elt))))))) | ||
| 473 | |||
| 474 | (defun describe-current-input-method () | ||
| 475 | "Describe the input method currently turned on." | ||
| 432 | (if current-input-method | 476 | (if current-input-method |
| 433 | (if (and (symbolp describe-current-input-method-function) | 477 | (if (and (symbolp describe-current-input-method-function) |
| 434 | (fboundp describe-current-input-method-function)) | 478 | (fboundp describe-current-input-method-function)) |
| @@ -436,24 +480,20 @@ interactively." | |||
| 436 | (message "No way to describe the current input method `%s'" | 480 | (message "No way to describe the current input method `%s'" |
| 437 | (cdr current-input-method)) | 481 | (cdr current-input-method)) |
| 438 | (ding)) | 482 | (ding)) |
| 439 | (message "No input method is activated now") | 483 | (error "No input method is activated now"))) |
| 440 | (ding))) | ||
| 441 | 484 | ||
| 442 | (defun read-multilingual-string (prompt &optional initial-input | 485 | (defun read-multilingual-string (prompt &optional initial-input |
| 443 | language-name method-name) | 486 | input-method) |
| 444 | "Read a multilingual string from minibuffer, prompting with string PROMPT. | 487 | "Read a multilingual string from minibuffer, prompting with string PROMPT. |
| 445 | The input method selected last time is activated in minibuffer. | 488 | The input method selected last time is activated in minibuffer. |
| 446 | If optional second arg INITIAL-INPUT is non-nil, insert it in the minibuffer | 489 | If optional second arg INITIAL-INPUT is non-nil, insert it in the minibuffer |
| 447 | initially | 490 | initially. |
| 448 | Optional 3rd and 4th arguments LANGUAGE-NAME and METHOD-NAME specify | 491 | Optional 3rd argument INPUT-METHOD specifies the input method |
| 449 | the input method to be activated instead of the one selected last time." | 492 | to be activated instead of the one selected last time." |
| 450 | (let ((default-input-method default-input-method)) | 493 | (let ((default-input-method |
| 451 | (if (and language-name method-name) | 494 | (or input-method |
| 452 | (setq default-input-method (cons language-name method-name)) | 495 | default-input-method |
| 453 | (or default-input-method | 496 | (read-input-method-name "Input method: " nil t)))) |
| 454 | (let ((lang-and-input-method (read-language-and-input-method-name))) | ||
| 455 | (setq default-input-method (cons (car lang-and-input-method) | ||
| 456 | (nth 1 lang-and-input-method)))))) | ||
| 457 | (let ((minibuffer-setup-hook '(toggle-input-method))) | 497 | (let ((minibuffer-setup-hook '(toggle-input-method))) |
| 458 | (read-string prompt initial-input)))) | 498 | (read-string prompt initial-input)))) |
| 459 | 499 | ||
| @@ -530,18 +570,21 @@ and sometimes other things." | |||
| 530 | (let ((doc (get-language-info language-name 'documentation))) | 570 | (let ((doc (get-language-info language-name 'documentation))) |
| 531 | (with-output-to-temp-buffer "*Help*" | 571 | (with-output-to-temp-buffer "*Help*" |
| 532 | (if (stringp doc) | 572 | (if (stringp doc) |
| 533 | (princ-list doc)) | 573 | (progn |
| 534 | (terpri) | 574 | (princ-list doc) |
| 575 | (terpri))) | ||
| 535 | (let ((str (get-language-info language-name 'sample-text))) | 576 | (let ((str (get-language-info language-name 'sample-text))) |
| 536 | (if (stringp str) | 577 | (if (stringp str) |
| 537 | (progn | 578 | (progn |
| 538 | (princ "Sample text:\n") | 579 | (princ "Sample text:\n") |
| 539 | (princ-list " " str)))) | 580 | (princ-list " " str) |
| 540 | (terpri) | 581 | (terpri)))) |
| 541 | (princ "Input methods:\n") | 582 | (princ "Input methods:\n") |
| 542 | (let ((l (get-language-info language-name 'input-method))) | 583 | (let ((l input-method-alist)) |
| 543 | (while l | 584 | (while l |
| 544 | (princ-list " " (car (car l))) | 585 | (if (string= language-name (nth 1 (car l))) |
| 586 | (princ-list " " (car (car l)) | ||
| 587 | (format " (`%s' in mode line)" (nth 3 (car l))))) | ||
| 545 | (setq l (cdr l)))) | 588 | (setq l (cdr l)))) |
| 546 | (terpri) | 589 | (terpri) |
| 547 | (princ "Character sets:\n") | 590 | (princ "Character sets:\n") |