Give proper SAFE_CHARSET argument in
[bpt/emacs.git] / lisp / international / mule-cmds.el
CommitLineData
4ed46869
KH
1;;; mule-cmds.el --- Commands for mulitilingual environment
2
4ed46869 3;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN.
fa526c4a 4;; Licensed to the Free Software Foundation.
4ed46869
KH
5
6;; Keywords: mule, multilingual
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
369314dc
KH
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
4ed46869
KH
24
25;;; Code:
26
27;;; MULE related key bindings and menus.
28
0709d285 29(defvar mule-keymap (make-sparse-keymap)
4ed46869 30 "Keymap for MULE (Multilingual environment) specific commands.")
4ed46869 31
8f81f784 32;; Keep "C-x C-m ..." for mule specific commands.
0709d285 33(define-key ctl-x-map "\C-m" mule-keymap)
ef8a8c8c 34
4ed46869
KH
35(define-key mule-keymap "m" 'toggle-enable-multibyte-characters)
36(define-key mule-keymap "f" 'set-buffer-file-coding-system)
37(define-key mule-keymap "t" 'set-terminal-coding-system)
15b3e511
KH
38(define-key mule-keymap "k" 'set-keyboard-coding-system)
39(define-key mule-keymap "p" 'set-buffer-process-coding-system)
0cbb4194 40(define-key mule-keymap "\C-\\" 'select-input-method)
15b3e511 41(define-key mule-keymap "c" 'universal-coding-system-argument)
b4fba33f 42(define-key mule-keymap "l" 'set-language-environment)
4ed46869 43
281d03ec 44(define-key help-map "\C-L" 'describe-language-environment)
ac4a3a2d 45(define-key help-map "L" 'describe-language-environment)
4ed46869 46(define-key help-map "\C-\\" 'describe-input-method)
ac4a3a2d 47(define-key help-map "I" 'describe-input-method)
d0b9c3ab 48(define-key help-map "C" 'describe-coding-system)
4ed46869
KH
49(define-key help-map "h" 'view-hello-file)
50
0709d285 51(defvar mule-menu-keymap (make-sparse-keymap "Mule")
15b3e511 52 "Keymap for MULE (Multilingual environment) menu specific commands.")
15b3e511
KH
53
54(define-key global-map [menu-bar mule] (cons "Mule" mule-menu-keymap))
55
56(setq menu-bar-final-items (cons 'mule menu-bar-final-items))
57
281d03ec
RS
58(defvar describe-language-environment-map nil)
59(define-prefix-command 'describe-language-environment-map)
15b3e511
KH
60
61(defvar setup-language-environment-map nil)
62(define-prefix-command 'setup-language-environment-map)
63
64(defvar set-coding-system-map nil)
65(define-prefix-command 'set-coding-system-map)
66
67(define-key-after mule-menu-keymap [toggle-mule]
8e02924a 68 '("Toggle Multibyte Characters" . toggle-enable-multibyte-characters)
15b3e511 69 t)
281d03ec 70(define-key-after mule-menu-keymap [describe-language-environment]
8e02924a 71 '("Describe Language Environment" . describe-language-environment-map)
15b3e511
KH
72 t)
73(define-key-after mule-menu-keymap [set-language-environment]
8e02924a 74 '("Set Language Environment" . setup-language-environment-map)
15b3e511 75 t)
a61f401d 76(define-key-after mule-menu-keymap [mouse-set-font]
8e02924a 77 '("Set Font/Fontset" . mouse-set-font)
a61f401d 78 t)
15b3e511
KH
79(define-key-after mule-menu-keymap [separator-mule]
80 '("--")
81 t)
82(define-key-after mule-menu-keymap [toggle-input-method]
8e02924a 83 '("Toggle Input Method" . toggle-input-method)
15b3e511
KH
84 t)
85(define-key-after mule-menu-keymap [select-input-method]
8e02924a 86 '("Select Input Method" . select-input-method)
15b3e511
KH
87 t)
88(define-key-after mule-menu-keymap [describe-input-method]
8e02924a 89 '("Describe Input Method" . describe-input-method)
15b3e511
KH
90 t)
91(define-key-after mule-menu-keymap [separator-input-method]
92 '("--")
93 t)
d0b9c3ab 94(define-key-after mule-menu-keymap [describe-coding-system]
8e02924a 95 '("Describe Coding Systems" . describe-coding-system)
15b3e511
KH
96 t)
97(define-key-after mule-menu-keymap [set-various-coding-system]
8e02924a 98 '("Set Coding System" . set-coding-system-map)
15b3e511
KH
99 t)
100(define-key-after mule-menu-keymap [separator-coding-system]
101 '("--")
102 t)
103(define-key-after mule-menu-keymap [mule-diag]
8e02924a 104 '("Show All of MULE Status" . mule-diag)
15b3e511
KH
105 t)
106(define-key-after mule-menu-keymap [view-hello-file]
8e02924a 107 '("Show Script Examples" . view-hello-file)
15b3e511
KH
108 t)
109
110(define-key-after set-coding-system-map [set-buffer-file-coding-system]
8e02924a 111 '("Buffer File" . set-buffer-file-coding-system)
15b3e511 112 t)
3a151e98
RS
113(define-key-after set-coding-system-map [universal-coding-system-argument]
114 '("Next Command" . universal-coding-system-argument)
115 t)
15b3e511
KH
116(define-key-after set-coding-system-map [set-terminal-coding-system]
117 '("Terminal" . set-terminal-coding-system)
118 t)
119(define-key-after set-coding-system-map [set-keyboard-coding-system]
120 '("Keyboard" . set-keyboard-coding-system)
121 t)
122(define-key-after set-coding-system-map [set-buffer-process-coding-system]
8e02924a 123 '("Buffer Process" . set-buffer-process-coding-system)
15b3e511
KH
124 t)
125
126(define-key setup-language-environment-map
127 [Default] '("Default" . setup-specified-language-environment))
4ed46869
KH
128
129;; These are meaningless when running under X.
4ed46869 130(put 'set-terminal-coding-system 'menu-enable
9ba344f7 131 '(not (eq window-system 'x)))
15b3e511 132(put 'set-keyboard-coding-system 'menu-enable
9ba344f7 133 '(not (eq window-system 'x)))
d0b9c3ab
KH
134;; This is meaningless when the current buffer has no process.
135(put 'set-buffer-process-coding-system 'menu-enable
136 '(get-buffer-process (current-buffer)))
4ed46869 137
4ed46869
KH
138;; This should be a single character key binding because users use it
139;; very frequently while editing multilingual text. Now we can use
140;; only two such keys: "\C-\\" and "\C-^", but the latter is not
141;; convenient because it requires shifting on most keyboards. An
142;; alternative is "\C-\]" which is now bound to `abort-recursive-edit'
143;; but it won't be used that frequently.
144(define-key global-map "\C-\\" 'toggle-input-method)
145
a2ad45b9
RS
146;;; This is no good because people often type Shift-SPC
147;;; meaning to type SPC. -- rms.
148;;; ;; Here's an alternative key binding for X users (Shift-SPACE).
149;;; (define-key global-map [?\S- ] 'toggle-input-method)
b4fba33f 150
4ed46869
KH
151(defun toggle-enable-multibyte-characters (&optional arg)
152 "Change whether this buffer enables multibyte characters.
153With arg, make them enable iff arg is positive."
154 (interactive "P")
155 (setq enable-multibyte-characters
156 (if (null arg) (null enable-multibyte-characters)
157 (> (prefix-numeric-value arg) 0)))
158 (force-mode-line-update))
159
160(defun view-hello-file ()
161 "Display the HELLO file which list up many languages and characters."
162 (interactive)
8f81f784
KH
163 ;; We have to decode the file in any environment.
164 (let ((default-enable-multibyte-characters t)
95fa03b4 165 (coding-system-for-read 'iso-2022-7bit))
8f81f784 166 (find-file-read-only (expand-file-name "HELLO" data-directory))))
4ed46869 167
15b3e511
KH
168(defun universal-coding-system-argument ()
169 "Execute an I/O command using the specified coding system."
170 (interactive)
e14a8f4c 171 (let* ((coding-system (read-coding-system "Coding system for following command: "))
15b3e511 172 (keyseq (read-key-sequence
e14a8f4c 173 (format "Command to execute with %s:" coding-system)))
15b3e511
KH
174 (cmd (key-binding keyseq)))
175 (let ((coding-system-for-read coding-system)
176 (coding-system-for-write coding-system))
177 (message "")
178 (call-interactively cmd))))
179
de94d711 180(defun set-default-coding-systems (coding-system)
0c3154d2
KH
181 "Set default value of various coding systems to CODING-SYSTEM.
182The follwing coding systems are set:
183 o coding system of a newly created buffer
184 o default coding system for terminal output
185 o default coding system for keyboard input
186 o default coding system for subprocess I/O"
de94d711
KH
187 (check-coding-system coding-system)
188 (setq-default buffer-file-coding-system coding-system)
189 (setq default-terminal-coding-system coding-system)
190 (setq default-keyboard-coding-system coding-system)
191 (setq default-process-coding-system (cons coding-system coding-system)))
192
0c3154d2
KH
193(defun prefer-coding-system (coding-system)
194 "Add CODING-SYSTEM at the front of the priority list for automatic detection.
195This also sets the following coding systems to CODING-SYSTEM:
196 o coding system of a newly created buffer
197 o default coding system for terminal output
198 o default coding system for keyboard input
199 o default coding system for subprocess I/O"
200 (interactive "zPrefer coding system: ")
201 (if (not (and coding-system (coding-system-p coding-system)))
202 (error "Invalid coding system `%s'" coding-system))
203 (let ((coding-category (coding-system-category coding-system))
204 (parent (coding-system-parent coding-system)))
205 (if (not coding-category)
206 ;; CODING-SYSTEM is no-conversion or undecided.
207 (error "Can't prefer the coding system `%s'" coding-system))
208 (set coding-category (or parent coding-system))
209 (if (not (eq coding-category (car coding-category-list)))
210 ;; We must change the order.
211 (setq coding-category-list
212 (cons coding-category
213 (delq coding-category coding-category-list))))
214 (if (and parent (interactive-p))
215 (message "Highest priority is set to %s (parent of %s)"
216 parent coding-system))
217 (set-default-coding-systems (or parent coding-system))))
218
4ed46869
KH
219\f
220;;; Language support staffs.
221
4ed46869
KH
222(defvar language-info-alist nil
223 "Alist of language names vs the corresponding information of various kind.
224Each element looks like:
225 (LANGUAGE-NAME . ((KEY . INFO) ...))
226where LANGUAGE-NAME is a string,
227KEY is a symbol denoting the kind of information,
228INFO is any Lisp object which contains the actual information related
229to KEY.")
230
231(defun get-language-info (language-name key)
232 "Return the information for LANGUAGE-NAME of the kind KEY.
4ed46869 233KEY is a symbol denoting the kind of required information."
4ef06f75
KH
234 (if (symbolp language-name)
235 (setq language-name (symbol-name language-name)))
15b3e511 236 (let ((lang-slot (assoc-ignore-case language-name language-info-alist)))
4ed46869
KH
237 (if lang-slot
238 (cdr (assq key (cdr lang-slot))))))
239
4ed46869
KH
240(defun set-language-info (language-name key info)
241 "Set for LANGUAGE-NAME the information INFO under KEY.
4ed46869
KH
242KEY is a symbol denoting the kind of information.
243INFO is any Lisp object which contains the actual information.
244
245Currently, the following KEYs are used by Emacs:
281d03ec 246
4ed46869 247charset: list of symbols whose values are charsets specific to the language.
281d03ec 248
4ed46869 249coding-system: list of coding systems specific to the langauge.
281d03ec 250
4ed46869 251tutorial: a tutorial file name written in the language.
281d03ec 252
4ed46869 253sample-text: one line short text containing characters of the language.
281d03ec 254
15b3e511 255documentation: t or a string describing how Emacs supports the language.
281d03ec
RS
256 If a string is specified, it is shown before any other information
257 of the language by the command `describe-language-environment'.
258
13e82c04 259setup-function: a function to call for setting up environment
281d03ec 260 convenient for a user of the language.
15b3e511
KH
261
262If KEY is documentation or setup-function, you can also specify
263a cons cell as INFO, in which case, the car part should be
264a normal value as INFO for KEY (as described above),
265and the cdr part should be a symbol whose value is a menu keymap
266in which an entry for the language is defined. But, only the car part
267is actually set as the information.
13e82c04 268
281d03ec
RS
269We will define more KEYs in the future. To avoid conflict,
270if you want to use your own KEY values, make them start with `user-'."
4ef06f75
KH
271 (if (symbolp language-name)
272 (setq language-name (symbol-name language-name)))
4ed46869
KH
273 (let (lang-slot key-slot)
274 (setq lang-slot (assoc language-name language-info-alist))
275 (if (null lang-slot) ; If no slot for the language, add it.
276 (setq lang-slot (list language-name)
277 language-info-alist (cons lang-slot language-info-alist)))
278 (setq key-slot (assq key lang-slot))
279 (if (null key-slot) ; If no slot for the key, add it.
280 (progn
281 (setq key-slot (list key))
282 (setcdr lang-slot (cons key-slot (cdr lang-slot)))))
4ed46869 283 ;; Setup menu.
48082651 284 (cond ((eq key 'documentation)
15b3e511
KH
285 (define-key-after
286 (if (consp info)
287 (prog1 (symbol-value (cdr info))
288 (setq info (car info)))
281d03ec 289 describe-language-environment-map)
ef8a8c8c 290 (vector (intern language-name))
48082651 291 (cons language-name 'describe-specified-language-support)
13e82c04 292 t))
ef8a8c8c 293 ((eq key 'setup-function)
15b3e511
KH
294 (define-key-after
295 (if (consp info)
296 (prog1 (symbol-value (cdr info))
297 (setq info (car info)))
298 setup-language-environment-map)
ef8a8c8c 299 (vector (intern language-name))
15b3e511 300 (cons language-name 'setup-specified-language-environment)
13e82c04 301 t)))
15b3e511
KH
302
303 (setcdr key-slot info)
4ed46869
KH
304 ))
305
306(defun set-language-info-alist (language-name alist)
307 "Set for LANGUAGE-NAME the information in ALIST.
308ALIST is an alist of KEY and INFO. See the documentation of
309`set-langauge-info' for the meanings of KEY and INFO."
4ef06f75
KH
310 (if (symbolp language-name)
311 (setq language-name (symbol-name language-name)))
4ed46869
KH
312 (while alist
313 (set-language-info language-name (car (car alist)) (cdr (car alist)))
314 (setq alist (cdr alist))))
315
ae302641 316(defun read-language-name (key prompt &optional default)
4ef06f75 317 "Read language name which has information for KEY, prompting with PROMPT.
ae302641 318DEFAULT is the default choice of language.
fc0678af 319This returns a language name as a string."
4ed46869
KH
320 (let* ((completion-ignore-case t)
321 (name (completing-read prompt
322 language-info-alist
323 (function (lambda (elm) (assq key elm)))
ae302641 324 t nil nil default)))
13e82c04
KH
325 (if (and (> (length name) 0)
326 (get-language-info name key))
327 name)))
4ed46869
KH
328\f
329;;; Multilingual input methods.
330
d0b9c3ab
KH
331(defconst leim-list-file-name "leim-list.el"
332 "Name of LEIM list file.
333This file contains a list of libraries of Emacs input methods (LEIM)
334in the format of Lisp expression for registering each input method.
335Emacs loads this file at startup time.")
336
337(defvar leim-list-header (format "\
338;;; %s -- list of LEIM (Library of Emacs Input Method)
339;;
340;; This file contains a list of LEIM (Library of Emacs Input Method)
341;; in the same directory as this file. Loading this file registeres
342;; the whole input methods in Emacs.
343;;
d33d5fbe 344;; Each entry has the form:
d0b9c3ab
KH
345;; (register-input-method
346;; INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC
347;; TITLE DESCRIPTION
348;; ARG ...)
349;; See the function `register-input-method' for the meanings of arguments.
350;;
351;; If this directory is included in load-path, Emacs automatically
352;; loads this file at startup time.
353
354"
355 leim-list-file-name)
356 "Header to be inserted in LEIM list file.")
357
e55e92ee 358(defvar leim-list-entry-regexp "^(register-input-method"
d0b9c3ab
KH
359 "Regexp matching head of each entry in LEIM list file.
360See also the variable `leim-list-header'")
361
362(defvar update-leim-list-functions
363 '(quail-update-leim-list-file)
364 "List of functions to call to update LEIM list file.
365Each function is called with one arg, LEIM directory name.")
366
a337fe7f
RS
367(defun update-leim-list-file (&rest dirs)
368 "Update LEIM list file in directories DIRS."
d0b9c3ab
KH
369 (let ((functions update-leim-list-functions))
370 (while functions
a337fe7f 371 (apply (car functions) dirs)
d0b9c3ab
KH
372 (setq functions (cdr functions)))))
373
4ed46869
KH
374(defvar current-input-method nil
375 "The current input method for multilingual text.
96db204a 376If nil, that means no input method is activated now.")
4ed46869
KH
377(make-variable-buffer-local 'current-input-method)
378(put 'current-input-method 'permanent-local t)
379
380(defvar current-input-method-title nil
d0b9c3ab 381 "Title string of the current input method shown in mode line.")
4ed46869
KH
382(make-variable-buffer-local 'current-input-method-title)
383(put 'current-input-method-title 'permanent-local t)
384
b4fba33f
KH
385(defcustom default-input-method nil
386 "*Default input method for multilingual text.
387This is the input method activated automatically by the command
9b10b5a3 388`toggle-input-method' (\\[toggle-input-method])."
b4fba33f
KH
389 :group 'mule)
390
723a427a
KH
391(defvar input-method-history nil
392 "History list for some commands that read input methods.")
393(make-variable-buffer-local 'input-method-history)
394(put 'input-method-history 'permanent-local t)
4ed46869
KH
395
396(defvar inactivate-current-input-method-function nil
397 "Function to call for inactivating the current input method.
398Every input method should set this to an appropriate value when activated.
f17ccaee
KH
399This function is called with no argument.
400
401This function should never change the value of `current-input-method'.
402It is set to nil by the function `inactivate-input-method'.")
4ed46869
KH
403(make-variable-buffer-local 'inactivate-current-input-method-function)
404(put 'inactivate-current-input-method-function 'permanent-local t)
405
406(defvar describe-current-input-method-function nil
407 "Function to call for describing the current input method.
408This function is called with no argument.")
409(make-variable-buffer-local 'describe-current-input-method-function)
410(put 'describe-current-input-method-function 'permanent-local t)
411
d0b9c3ab
KH
412(defvar input-method-alist nil
413 "Alist of input method names vs the corresponding information to use it.
414Each element has the form:
415 (INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC TITLE DESCRIPTION ...)
416See the function `register-input-method' for the meanings of each elements.")
417
418(defun register-input-method (input-method language-name &rest args)
419 "Register INPUT-METHOD as an input method for LANGUAGE-NAME.
4ef06f75 420INPUT-METHOD and LANGUAGE-NAME are symbols or strings.
d0b9c3ab
KH
421The remaining arguments are:
422 ACTIVATE-FUNC, TITLE, DESCRIPTION, and ARG ...
423 where,
424ACTIVATE-FUNC is a function to call for activating this method.
425TITLE is a string shown in mode-line while this method is active,
426DESCRIPTION is a string describing about this method,
427Arguments to ACTIVATE-FUNC are INPUT-METHOD and ARGs."
4ef06f75
KH
428 (if (symbolp language-name)
429 (setq language-name (symbol-name language-name)))
430 (if (symbolp input-method)
431 (setq input-method (symbol-name input-method)))
d0b9c3ab
KH
432 (let ((info (cons language-name args))
433 (slot (assoc input-method input-method-alist)))
434 (if slot
435 (setcdr slot info)
436 (setq slot (cons input-method info))
437 (setq input-method-alist (cons slot input-method-alist)))))
438
4d5ac029 439(defun read-input-method-name (prompt &optional default inhibit-null)
d0b9c3ab 440 "Read a name of input method from a minibuffer prompting with PROMPT.
4d5ac029
RS
441If DEFAULT is non-nil, use that as the default,
442 and substitute it into PROMPT at the first `%s'.
4ef06f75
KH
443If INHIBIT-NULL is non-nil, null input signals an error.
444
445The return value is a string."
4d5ac029
RS
446 (if default
447 (setq prompt (format prompt default)))
d0b9c3ab 448 (let* ((completion-ignore-case t)
723a427a
KH
449 ;; This binding is necessary because input-method-history is
450 ;; buffer local.
d0b9c3ab 451 (input-method (completing-read prompt input-method-alist
87505a98
RS
452 nil t nil 'input-method-history
453 default)))
d0b9c3ab
KH
454 (if (> (length input-method) 0)
455 input-method
456 (if inhibit-null
43807b77 457 (error "No valid input method is specified")))))
d0b9c3ab 458
d0b9c3ab 459(defun activate-input-method (input-method)
f17ccaee
KH
460 "Turn INPUT-METHOD on.
461If some input method is already on, turn it off at first."
4ef06f75
KH
462 (if (symbolp input-method)
463 (setq input-method (symbol-name input-method)))
723a427a
KH
464 (if (and current-input-method
465 (not (string= current-input-method input-method)))
42395763
RS
466 (inactivate-input-method))
467 (unless current-input-method
d0b9c3ab
KH
468 (let ((slot (assoc input-method input-method-alist)))
469 (if (null slot)
723a427a 470 (error "Can't activate input method `%s'" input-method))
d0b9c3ab
KH
471 (apply (nth 2 slot) input-method (nthcdr 5 slot))
472 (setq current-input-method input-method)
723a427a
KH
473 (setq current-input-method-title (nth 3 slot))
474 (run-hooks 'input-method-activate-hook))))
15b3e511 475
15b3e511 476(defun inactivate-input-method ()
f17ccaee 477 "Turn off the current input method."
723a427a
KH
478 (when current-input-method
479 (if input-method-history
480 (unless (string= current-input-method (car input-method-history))
481 (setq input-method-history
482 (cons current-input-method
483 (delete current-input-method input-method-history))))
484 (setq input-method-history (list current-input-method)))
485 (unwind-protect
486 (funcall inactivate-current-input-method-function)
15b3e511 487 (unwind-protect
723a427a
KH
488 (run-hooks 'input-method-inactivate-hook)
489 (setq current-input-method nil
490 current-input-method-title nil)))))
4ed46869 491
d0b9c3ab 492(defun select-input-method (input-method)
723a427a
KH
493 "Select and turn on INPUT-METHOD.
494This sets the default input method to what you specify,
495and turn it on for the current buffer."
d0b9c3ab 496 (interactive
723a427a 497 (let* ((default (or (car input-method-history) default-input-method)))
42395763 498 (list (read-input-method-name
87505a98 499 (if default "Select input method (default %s): " "Select input method: ")
42395763 500 default t))))
d0b9c3ab 501 (activate-input-method input-method)
42395763 502 (setq default-input-method input-method))
4ed46869
KH
503
504(defun toggle-input-method (&optional arg)
15b3e511 505 "Turn on or off a multilingual text input method for the current buffer.
723a427a 506
d0b9c3ab 507With arg, read an input method from minibuffer and turn it on.
723a427a 508
15b3e511 509Without arg, if some input method is currently activated, turn it off,
723a427a
KH
510else turn on an input method selected last time
511or the default input method (see `default-input-method').
512
513When there's no input method to turn on, turn on what read from minibuffer."
4ed46869 514 (interactive "P")
723a427a 515 (let* ((default (or (car input-method-history) default-input-method)))
b4fba33f
KH
516 (if (and current-input-method (not arg))
517 (inactivate-input-method)
723a427a
KH
518 (activate-input-method
519 (if (or arg (not default))
520 (read-input-method-name
521 (if default "Input method (default %s): " "Input method: " )
522 default t)
523 default))
524 (or default-input-method
525 (setq default-input-method current-input-method)))))
d0b9c3ab
KH
526
527(defun describe-input-method (input-method)
4ef06f75 528 "Describe input method INPUT-METHOD."
d0b9c3ab
KH
529 (interactive
530 (list (read-input-method-name
531 "Describe input method (default, current choice): ")))
78754934 532 (if (and input-method (symbolp input-method))
4ef06f75 533 (setq input-method (symbol-name input-method)))
d0b9c3ab
KH
534 (if (null input-method)
535 (describe-current-input-method)
536 (with-output-to-temp-buffer "*Help*"
537 (let ((elt (assoc input-method input-method-alist)))
538 (princ (format "Input method: %s (`%s' in mode line) for %s\n %s\n"
539 input-method (nth 3 elt) (nth 1 elt) (nth 4 elt)))))))
540
541(defun describe-current-input-method ()
96db204a 542 "Describe the input method currently in use."
4ed46869
KH
543 (if current-input-method
544 (if (and (symbolp describe-current-input-method-function)
545 (fboundp describe-current-input-method-function))
546 (funcall describe-current-input-method-function)
547 (message "No way to describe the current input method `%s'"
548 (cdr current-input-method))
549 (ding))
d0b9c3ab 550 (error "No input method is activated now")))
4ed46869 551
d3459641 552(defun read-multilingual-string (prompt &optional initial-input input-method)
4ed46869
KH
553 "Read a multilingual string from minibuffer, prompting with string PROMPT.
554The input method selected last time is activated in minibuffer.
15b3e511 555If optional second arg INITIAL-INPUT is non-nil, insert it in the minibuffer
d0b9c3ab
KH
556initially.
557Optional 3rd argument INPUT-METHOD specifies the input method
4ef06f75
KH
558to be activated instead of the one selected last time. It is a symbol
559or a string."
88d559ec
KH
560 (setq input-method
561 (or input-method
d3459641 562 current-input-method
88d559ec
KH
563 default-input-method
564 (read-input-method-name "Input method: " nil t)))
3df60841 565 (if (and input-method (symbolp input-method))
4ef06f75 566 (setq input-method (symbol-name input-method)))
d3459641
KH
567 (let ((previous-input-method current-input-method))
568 (unwind-protect
569 (progn
570 (activate-input-method input-method)
571 (read-string prompt initial-input nil nil t))
572 (if previous-input-method
573 (activate-input-method previous-input-method)
574 (inactivate-input-method)))))
4ed46869
KH
575
576;; Variables to control behavior of input methods. All input methods
577;; should react to these variables.
578
42395763
RS
579(defcustom input-method-verbose-flag t
580 "*If this flag is non-nil, input methods give extra guidance.
4ed46869 581
cb29dfb6 582The extra guidance is done by showing list of available keys in echo
c27c4ed8
KH
583area.
584
cb29dfb6
RS
585For complex input methods such as `chinese-py' and `japanese',
586when you use the input method in the minibuffer, the guidance is
587shown at the bottom short window (split from the existing window).
588For simple input methods, guidance is not shown
589when you are in the minibuffer."
42395763
RS
590 :type 'boolean
591 :group 'mule)
592
593(defcustom input-method-highlight-flag t
594 "*If this flag is non-nil, input methods highlight partially-entered text.
595For instance, while you are in the middle of a Quail input method sequence,
596the text inserted so far is temporarily underlined.
597The underlining goes away when you finish or abort the input method sequence."
598 :type 'boolean
599 :group 'mule)
4ed46869
KH
600
601(defvar input-method-activate-hook nil
f17ccaee
KH
602 "Normal hook run just after an input method is activated.
603
604The variable `current-input-method' keeps the input method name
605just activated.")
4ed46869
KH
606
607(defvar input-method-inactivate-hook nil
f17ccaee
KH
608 "Normal hook run just after an input method is inactivated.
609
610The variable `current-input-method' still keeps the input method name
611just inacitvated.")
4ed46869
KH
612
613(defvar input-method-after-insert-chunk-hook nil
614 "Normal hook run just after an input method insert some chunk of text.")
615
723a427a
KH
616(defvar input-method-exit-on-invalid-key nil
617 "This flag controls the behaviour of an input method on invalid key input.
618Usually, when a user types a key which doesn't start any character
619handled by the input method, the key is handled by turning off the
620input method temporalily. After the key is handled, the input method is
621back on.
622But, if this flag is non-nil, the input method is never back on.")
623
4ed46869 624\f
15b3e511 625(defun setup-specified-language-environment ()
f850d782 626 "Set up multi-lingual environment convenient for the specified language."
15b3e511 627 (interactive)
f850d782 628 (let (language-name)
15b3e511
KH
629 (if (and (symbolp last-command-event)
630 (or (not (eq last-command-event 'Default))
631 (setq last-command-event 'English))
f850d782
RS
632 (setq language-name (symbol-name last-command-event)))
633 (set-language-environment language-name)
15b3e511 634 (error "Bogus calling sequence"))))
4ed46869 635
f850d782
RS
636(defvar current-language-environment "English"
637 "The last language environment specified with `set-language-environment'.")
638
166246f7 639(defun set-language-environment (language-name)
6c05d680
RS
640 "Set up multi-lingual environment for using LANGUAGE-NAME.
641This sets the coding system priority and the default input method
642and sometimes other things."
b4fba33f 643 (interactive (list (read-language-name 'setup-function
fc0678af 644 "Set language environment: ")))
4ef06f75
KH
645 (if language-name
646 (if (symbolp language-name)
647 (setq language-name (symbol-name language-name)))
648 (setq language-name "English"))
b4fba33f 649 (if (null (get-language-info language-name 'setup-function))
f850d782
RS
650 (error "Language environment not defined: %S" language-name))
651 (funcall (get-language-info language-name 'setup-function))
652 (setq current-language-environment language-name)
653 (force-mode-line-update t))
4ed46869
KH
654
655;; Print all arguments with `princ', then print "\n".
656(defsubst princ-list (&rest args)
657 (while args (princ (car args)) (setq args (cdr args)))
658 (princ "\n"))
659
48082651 660;; Print a language specific information such as input methods,
13e82c04 661;; charsets, and coding systems. This function is intended to be
48082651 662;; called from the menu:
281d03ec 663;; [menu-bar mule describe-language-environment LANGUAGE]
48082651
KH
664;; and should not run it by `M-x describe-current-input-method-function'.
665(defun describe-specified-language-support ()
96db204a 666 "Describe how Emacs supports the specified language environment."
48082651 667 (interactive)
281d03ec 668 (let (language-name)
48082651 669 (if (not (and (symbolp last-command-event)
281d03ec 670 (setq language-name (symbol-name last-command-event))))
48082651 671 (error "Bogus calling sequence"))
281d03ec
RS
672 (describe-language-environment language-name)))
673
674(defun describe-language-environment (language-name)
675 "Describe how Emacs supports language environment LANGUAGE-NAME."
78754934
KH
676 (interactive
677 (list (read-language-name
678 'documentation
8adfa8be 679 "Describe language environment (default, current choice): ")))
f850d782
RS
680 (if (null language-name)
681 (setq language-name current-language-environment))
281d03ec
RS
682 (if (or (null language-name)
683 (null (get-language-info language-name 'documentation)))
684 (error "No documentation for the specified language"))
4ef06f75
KH
685 (if (symbolp language-name)
686 (setq language-name (symbol-name language-name)))
281d03ec 687 (let ((doc (get-language-info language-name 'documentation)))
48082651 688 (with-output-to-temp-buffer "*Help*"
13e82c04 689 (if (stringp doc)
d0b9c3ab
KH
690 (progn
691 (princ-list doc)
692 (terpri)))
15b3e511
KH
693 (let ((str (get-language-info language-name 'sample-text)))
694 (if (stringp str)
695 (progn
281d03ec 696 (princ "Sample text:\n")
d0b9c3ab
KH
697 (princ-list " " str)
698 (terpri))))
281d03ec 699 (princ "Input methods:\n")
d0b9c3ab 700 (let ((l input-method-alist))
15b3e511 701 (while l
d0b9c3ab
KH
702 (if (string= language-name (nth 1 (car l)))
703 (princ-list " " (car (car l))
704 (format " (`%s' in mode line)" (nth 3 (car l)))))
15b3e511 705 (setq l (cdr l))))
281d03ec
RS
706 (terpri)
707 (princ "Character sets:\n")
15b3e511
KH
708 (let ((l (get-language-info language-name 'charset)))
709 (if (null l)
710 (princ-list " nothing specific to " language-name)
711 (while l
712 (princ-list " " (car l) ": "
713 (charset-description (car l)))
714 (setq l (cdr l)))))
281d03ec
RS
715 (terpri)
716 (princ "Coding systems:\n")
15b3e511
KH
717 (let ((l (get-language-info language-name 'coding-system)))
718 (if (null l)
719 (princ-list " nothing specific to " language-name)
48082651 720 (while l
281d03ec
RS
721 (princ (format " %s (`%c' in mode line):\n\t%s\n"
722 (car l)
723 (coding-system-mnemonic (car l))
a904b20b 724 (coding-system-doc-string (car l))))
15b3e511 725 (setq l (cdr l))))))))
4ed46869
KH
726\f
727;;; Charset property
728
729(defsubst get-charset-property (charset propname)
730 "Return the value of CHARSET's PROPNAME property.
731This is the last value stored with
96db204a 732 (put-charset-property CHARSET PROPNAME VALUE)."
4ed46869
KH
733 (plist-get (charset-plist charset) propname))
734
735(defsubst put-charset-property (charset propname value)
736 "Store CHARSETS's PROPNAME property with value VALUE.
737It can be retrieved with `(get-charset-property CHARSET PROPNAME)'."
738 (set-charset-plist charset
739 (plist-put (charset-plist charset) propname value)))
740
741;;; Character code property
742(put 'char-code-property-table 'char-table-extra-slots 0)
743
744(defvar char-code-property-table
745 (make-char-table 'char-code-property-table)
746 "Char-table containing a property list of each character code.
747
748See also the documentation of `get-char-code-property' and
96db204a 749`put-char-code-property'.")
4ed46869
KH
750
751(defun get-char-code-property (char propname)
752 "Return the value of CHAR's PROPNAME property in `char-code-property-table'."
753 (let ((plist (aref char-code-property-table char)))
754 (if (listp plist)
755 (car (cdr (memq propname plist))))))
756
757(defun put-char-code-property (char propname value)
758 "Store CHAR's PROPNAME property with VALUE in `char-code-property-table'.
759It can be retrieved with `(get-char-code-property CHAR PROPNAME)'."
760 (let ((plist (aref char-code-property-table char)))
761 (if plist
762 (let ((slot (memq propname plist)))
763 (if slot
764 (setcar (cdr slot) value)
765 (nconc plist (list propname value))))
766 (aset char-code-property-table char (list propname value)))))
767
768;;; mule-cmds.el ends here