(titdic-convert): Set
[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 "f" 'set-buffer-file-coding-system)
36(define-key mule-keymap "t" 'set-terminal-coding-system)
15b3e511
KH
37(define-key mule-keymap "k" 'set-keyboard-coding-system)
38(define-key mule-keymap "p" 'set-buffer-process-coding-system)
8b784951 39(define-key mule-keymap "\C-\\" 'set-input-method)
15b3e511 40(define-key mule-keymap "c" 'universal-coding-system-argument)
b4fba33f 41(define-key mule-keymap "l" 'set-language-environment)
4ed46869 42
281d03ec 43(define-key help-map "\C-L" 'describe-language-environment)
ac4a3a2d 44(define-key help-map "L" 'describe-language-environment)
4ed46869 45(define-key help-map "\C-\\" 'describe-input-method)
ac4a3a2d 46(define-key help-map "I" 'describe-input-method)
d0b9c3ab 47(define-key help-map "C" 'describe-coding-system)
4ed46869
KH
48(define-key help-map "h" 'view-hello-file)
49
0709d285 50(defvar mule-menu-keymap (make-sparse-keymap "Mule")
15b3e511 51 "Keymap for MULE (Multilingual environment) menu specific commands.")
15b3e511
KH
52
53(define-key global-map [menu-bar mule] (cons "Mule" mule-menu-keymap))
54
55(setq menu-bar-final-items (cons 'mule menu-bar-final-items))
56
281d03ec
RS
57(defvar describe-language-environment-map nil)
58(define-prefix-command 'describe-language-environment-map)
15b3e511
KH
59
60(defvar setup-language-environment-map nil)
61(define-prefix-command 'setup-language-environment-map)
62
63(defvar set-coding-system-map nil)
64(define-prefix-command 'set-coding-system-map)
65
281d03ec 66(define-key-after mule-menu-keymap [describe-language-environment]
8e02924a 67 '("Describe Language Environment" . describe-language-environment-map)
15b3e511
KH
68 t)
69(define-key-after mule-menu-keymap [set-language-environment]
8e02924a 70 '("Set Language Environment" . setup-language-environment-map)
15b3e511 71 t)
a61f401d 72(define-key-after mule-menu-keymap [mouse-set-font]
8e02924a 73 '("Set Font/Fontset" . mouse-set-font)
a61f401d 74 t)
15b3e511
KH
75(define-key-after mule-menu-keymap [separator-mule]
76 '("--")
77 t)
78(define-key-after mule-menu-keymap [toggle-input-method]
8e02924a 79 '("Toggle Input Method" . toggle-input-method)
15b3e511 80 t)
8b784951
KH
81(define-key-after mule-menu-keymap [set-input-method]
82 '("Select Input Method" . set-input-method)
15b3e511
KH
83 t)
84(define-key-after mule-menu-keymap [describe-input-method]
8e02924a 85 '("Describe Input Method" . describe-input-method)
15b3e511
KH
86 t)
87(define-key-after mule-menu-keymap [separator-input-method]
88 '("--")
89 t)
d0b9c3ab 90(define-key-after mule-menu-keymap [describe-coding-system]
8e02924a 91 '("Describe Coding Systems" . describe-coding-system)
15b3e511
KH
92 t)
93(define-key-after mule-menu-keymap [set-various-coding-system]
8e02924a 94 '("Set Coding System" . set-coding-system-map)
15b3e511
KH
95 t)
96(define-key-after mule-menu-keymap [separator-coding-system]
97 '("--")
98 t)
99(define-key-after mule-menu-keymap [mule-diag]
8e02924a 100 '("Show All of MULE Status" . mule-diag)
15b3e511
KH
101 t)
102(define-key-after mule-menu-keymap [view-hello-file]
8e02924a 103 '("Show Script Examples" . view-hello-file)
15b3e511
KH
104 t)
105
106(define-key-after set-coding-system-map [set-buffer-file-coding-system]
8e02924a 107 '("Buffer File" . set-buffer-file-coding-system)
15b3e511 108 t)
3a151e98
RS
109(define-key-after set-coding-system-map [universal-coding-system-argument]
110 '("Next Command" . universal-coding-system-argument)
111 t)
15b3e511
KH
112(define-key-after set-coding-system-map [set-terminal-coding-system]
113 '("Terminal" . set-terminal-coding-system)
114 t)
115(define-key-after set-coding-system-map [set-keyboard-coding-system]
116 '("Keyboard" . set-keyboard-coding-system)
117 t)
118(define-key-after set-coding-system-map [set-buffer-process-coding-system]
8e02924a 119 '("Buffer Process" . set-buffer-process-coding-system)
15b3e511
KH
120 t)
121
122(define-key setup-language-environment-map
123 [Default] '("Default" . setup-specified-language-environment))
4ed46869
KH
124
125;; These are meaningless when running under X.
4ed46869 126(put 'set-terminal-coding-system 'menu-enable
9ba344f7 127 '(not (eq window-system 'x)))
15b3e511 128(put 'set-keyboard-coding-system 'menu-enable
9ba344f7 129 '(not (eq window-system 'x)))
d0b9c3ab
KH
130;; This is meaningless when the current buffer has no process.
131(put 'set-buffer-process-coding-system 'menu-enable
132 '(get-buffer-process (current-buffer)))
4ed46869 133
4ed46869
KH
134;; This should be a single character key binding because users use it
135;; very frequently while editing multilingual text. Now we can use
136;; only two such keys: "\C-\\" and "\C-^", but the latter is not
137;; convenient because it requires shifting on most keyboards. An
138;; alternative is "\C-\]" which is now bound to `abort-recursive-edit'
139;; but it won't be used that frequently.
140(define-key global-map "\C-\\" 'toggle-input-method)
141
a2ad45b9
RS
142;;; This is no good because people often type Shift-SPC
143;;; meaning to type SPC. -- rms.
144;;; ;; Here's an alternative key binding for X users (Shift-SPACE).
145;;; (define-key global-map [?\S- ] 'toggle-input-method)
b4fba33f 146
4ed46869 147(defun toggle-enable-multibyte-characters (&optional arg)
6998e1a1
RS
148 "Change whether this buffer uses multibyte characters.
149With arg, use multibyte characters if the arg is positive.
150
151Note that this command does not convert the byte contents of
152the buffer; it only changes the way those bytes are interpreted.
153In general, therefore, this command *changes* the sequence of
154characters that the current buffer contains.
155
156We suggest you avoid using use this command unless you know what you
157are doing. If you use it by mistake, and the buffer is now displayed
158wrong, use this command again to toggle back to the right mode."
4ed46869
KH
159 (interactive "P")
160 (setq enable-multibyte-characters
161 (if (null arg) (null enable-multibyte-characters)
162 (> (prefix-numeric-value arg) 0)))
163 (force-mode-line-update))
164
165(defun view-hello-file ()
166 "Display the HELLO file which list up many languages and characters."
167 (interactive)
8f81f784
KH
168 ;; We have to decode the file in any environment.
169 (let ((default-enable-multibyte-characters t)
95fa03b4 170 (coding-system-for-read 'iso-2022-7bit))
8f81f784 171 (find-file-read-only (expand-file-name "HELLO" data-directory))))
4ed46869 172
15b3e511
KH
173(defun universal-coding-system-argument ()
174 "Execute an I/O command using the specified coding system."
175 (interactive)
e14a8f4c 176 (let* ((coding-system (read-coding-system "Coding system for following command: "))
15b3e511 177 (keyseq (read-key-sequence
e14a8f4c 178 (format "Command to execute with %s:" coding-system)))
15b3e511
KH
179 (cmd (key-binding keyseq)))
180 (let ((coding-system-for-read coding-system)
181 (coding-system-for-write coding-system))
182 (message "")
183 (call-interactively cmd))))
184
de94d711 185(defun set-default-coding-systems (coding-system)
0c3154d2 186 "Set default value of various coding systems to CODING-SYSTEM.
8efc03e1 187This sets the follwing coding systems:
0c3154d2 188 o coding system of a newly created buffer
8efc03e1
KH
189 o default coding system for subprocess I/O
190This also sets the following values:
191 o default value for the command `set-terminal-coding-system'
192 o default value for the command `set-keyboard-coding-system'"
de94d711
KH
193 (check-coding-system coding-system)
194 (setq-default buffer-file-coding-system coding-system)
195 (setq default-terminal-coding-system coding-system)
196 (setq default-keyboard-coding-system coding-system)
197 (setq default-process-coding-system (cons coding-system coding-system)))
198
0c3154d2
KH
199(defun prefer-coding-system (coding-system)
200 "Add CODING-SYSTEM at the front of the priority list for automatic detection.
8efc03e1 201This also sets the follwing coding systems:
0c3154d2 202 o coding system of a newly created buffer
8efc03e1
KH
203 o default coding system for subprocess I/O
204This also sets the following values:
205 o default value for the command `set-terminal-coding-system'
206 o default value for the command `set-keyboard-coding-system'"
0c3154d2
KH
207 (interactive "zPrefer coding system: ")
208 (if (not (and coding-system (coding-system-p coding-system)))
209 (error "Invalid coding system `%s'" coding-system))
210 (let ((coding-category (coding-system-category coding-system))
8efc03e1 211 (base (coding-system-base coding-system)))
0c3154d2
KH
212 (if (not coding-category)
213 ;; CODING-SYSTEM is no-conversion or undecided.
214 (error "Can't prefer the coding system `%s'" coding-system))
8efc03e1 215 (set coding-category (or base coding-system))
54b226f7 216 (update-iso-coding-systems)
0c3154d2
KH
217 (if (not (eq coding-category (car coding-category-list)))
218 ;; We must change the order.
219 (setq coding-category-list
220 (cons coding-category
221 (delq coding-category coding-category-list))))
8efc03e1
KH
222 (if (and base (interactive-p))
223 (message "Highest priority is set to %s (base of %s)"
224 base coding-system))
225 (set-default-coding-systems (or base coding-system))))
0c3154d2 226
54b226f7
KH
227(defun list-subset-p (list1 list2)
228 "Return non-nil if all elements in LIST1 are included in LIST2.
229Comparison done with EQ."
230 (catch 'tag
231 (while list1
232 (or (memq (car list1) list2)
233 (throw 'tag nil))
234 (setq list1 (cdr list1)))
235 t))
236
237(defun find-safe-coding-system (from to)
238 "Return a list of proper coding systems to encode a text between FROM and TO.
239All coding systems in the list can safely encode any multibyte characters
240in the text.
241
242If the text contains no multibyte charcters, return a list of a single
243element `undecided'.
244
245Kludgy feature: if FROM is a string, the string is the target text,
246and TO is ignored."
247 (let ((charset-list (if (stringp from) (find-charset-string from)
248 (find-charset-region from to))))
249 (if (and (= (length charset-list) 1)
250 (eq 'ascii (car charset-list)))
251 '(undecided)
252 (let ((l coding-system-list)
253 (prefered-codings
254 (mapcar (function
255 (lambda (x)
256 (get-charset-property x 'prefered-coding-system)))
257 charset-list))
258 codings coding safe)
259 (while l
260 (setq coding (car l) l (cdr l))
261 (if (and (eq coding (coding-system-base coding))
262 (setq safe (coding-system-get coding 'safe-charsets))
263 (or (eq safe t)
264 (list-subset-p charset-list safe)))
265 ;; We put the higher priority to coding systems included
266 ;; in PREFERED-CODINGS, and within them, put the higher
267 ;; priority to coding systems which support smaller
268 ;; number of charsets.
269 (let ((priority
270 (logior (if (coding-system-get coding 'mime-charset)
271 256 0)
272 (if (memq coding prefered-codings) 128 0)
273 (if (> (coding-system-type coding) 0) 64 0)
274 (if (consp safe) (- 64 (length safe)) 0))))
275 (setq codings (cons (cons priority coding) codings)))))
276 (mapcar 'cdr
277 (sort codings (function (lambda (x y) (> (car x) (car y))))))
278 ))))
279
280(defun select-safe-coding-system (from to &optional default-coding-system)
281 "Return a coding system which can encode a text between FROM and TO.
282
283Optional arg DEFAULT-CODING-SYSTEM specifies a coding system to be
284checked at first. If omitted, buffer-file-coding-system of the
285current buffer is used.
286
287If the text contains some multibyte characters and
288DEFAULT-CODING-SYSTEM can't encode them, ask a user to select one from
289a list of coding systems which can encode the text, and return the
290selected one.
291
292In other cases, return DEFAULT-CODING-SYSTEM.
293
294Kludgy feature: if FROM is a string, the string is the target text,
295and TO is ignored."
296 (or default-coding-system
297 (setq default-coding-system buffer-file-coding-system))
298 (let ((safe-coding-systems (find-safe-coding-system from to)))
299 (if (or (eq (car safe-coding-systems) 'undecided)
300 (and default-coding-system
301 (memq (coding-system-base default-coding-system)
302 safe-coding-systems)))
303 default-coding-system
304
305 ;; Ask a user to select a proper coding system.
306 (save-window-excursion
307 ;; At first, show a helpful message.
308 (with-output-to-temp-buffer "*Warning*"
309 (save-excursion
310 (set-buffer standard-output)
311 (insert (format "\
312The target text contains a multibyte character which can't be
313encoded safely by the coding system %s.
314
315Please select one from the following safe coding systems:\n"
316 default-coding-system))
317 (let ((pos (point))
318 (fill-prefix " "))
319 (mapcar (function (lambda (x) (princ " ") (princ x)))
320 safe-coding-systems)
321 (fill-region-as-paragraph pos (point)))))
322
323 ;; Read a coding system.
324 (let* ((safe-names (mapcar (lambda (x) (list (symbol-name x)))
325 safe-coding-systems))
326 (name (completing-read
327 (format "Select coding system (default %s): "
328 (car safe-coding-systems))
329 safe-names nil t nil nil (car (car safe-names)))))
330 (intern name))))))
331
332(setq select-safe-coding-system-function 'select-safe-coding-system)
333
4ed46869
KH
334\f
335;;; Language support staffs.
336
4ed46869
KH
337(defvar language-info-alist nil
338 "Alist of language names vs the corresponding information of various kind.
339Each element looks like:
340 (LANGUAGE-NAME . ((KEY . INFO) ...))
341where LANGUAGE-NAME is a string,
342KEY is a symbol denoting the kind of information,
343INFO is any Lisp object which contains the actual information related
344to KEY.")
345
346(defun get-language-info (language-name key)
347 "Return the information for LANGUAGE-NAME of the kind KEY.
4ed46869 348KEY is a symbol denoting the kind of required information."
4ef06f75
KH
349 (if (symbolp language-name)
350 (setq language-name (symbol-name language-name)))
15b3e511 351 (let ((lang-slot (assoc-ignore-case language-name language-info-alist)))
4ed46869
KH
352 (if lang-slot
353 (cdr (assq key (cdr lang-slot))))))
354
54b226f7
KH
355(defun set-language-info (language-name key info
356 &optional describe-map setup-map)
4ed46869 357 "Set for LANGUAGE-NAME the information INFO under KEY.
4ed46869 358KEY is a symbol denoting the kind of information.
54b226f7
KH
359INFO is any Lisp object which contains the actual information specific
360 to LANGUAGE-NAME.
4ed46869
KH
361
362Currently, the following KEYs are used by Emacs:
281d03ec 363
54b226f7
KH
364charset: list of charsets.
365
366coding-system: list of coding systems.
281d03ec 367
54b226f7 368coding-priority: list of coding systems ordered by priority.
281d03ec 369
4ed46869 370tutorial: a tutorial file name written in the language.
281d03ec 371
4ed46869 372sample-text: one line short text containing characters of the language.
281d03ec 373
15b3e511 374documentation: t or a string describing how Emacs supports the language.
54b226f7
KH
375 If a string is specified, it is shown before any other information
376 of the language by the command `describe-language-environment'.
281d03ec 377
13e82c04 378setup-function: a function to call for setting up environment
54b226f7 379 convenient for a user of the language.
13e82c04 380
281d03ec 381We will define more KEYs in the future. To avoid conflict,
54b226f7
KH
382if you want to use your own KEY values, make them start with `user-'.
383
384Optional 4th and 5th args DESCRIBE-MAP and SETUP-MAP are keymaps to
385register LANGUAGE-NAME in the menu of `Mule'->`Describe Language
386Environment' and `Mule'->`Setup Language Environment' respectively."
4ef06f75
KH
387 (if (symbolp language-name)
388 (setq language-name (symbol-name language-name)))
4ed46869
KH
389 (let (lang-slot key-slot)
390 (setq lang-slot (assoc language-name language-info-alist))
391 (if (null lang-slot) ; If no slot for the language, add it.
392 (setq lang-slot (list language-name)
393 language-info-alist (cons lang-slot language-info-alist)))
394 (setq key-slot (assq key lang-slot))
395 (if (null key-slot) ; If no slot for the key, add it.
396 (progn
397 (setq key-slot (list key))
398 (setcdr lang-slot (cons key-slot (cdr lang-slot)))))
4ed46869 399 ;; Setup menu.
48082651 400 (cond ((eq key 'documentation)
54b226f7
KH
401 (define-key-after describe-map (vector (intern language-name))
402 (cons language-name 'describe-specified-language-support) t))
ef8a8c8c 403 ((eq key 'setup-function)
54b226f7
KH
404 (define-key-after setup-map (vector (intern language-name))
405 (cons language-name 'setup-specified-language-environment) t)))
15b3e511
KH
406
407 (setcdr key-slot info)
4ed46869
KH
408 ))
409
54b226f7 410(defun set-language-info-alist (language-name alist &optional parents)
4ed46869
KH
411 "Set for LANGUAGE-NAME the information in ALIST.
412ALIST is an alist of KEY and INFO. See the documentation of
54b226f7
KH
413`set-langauge-info' for the meanings of KEY and INFO.
414
415Optional arg PARENTS is a list of parent language environments ordered
416from the highest to the lower. If it is nil, we make LANGUAGE-NAME
417the top level language environment."
4ef06f75
KH
418 (if (symbolp language-name)
419 (setq language-name (symbol-name language-name)))
54b226f7
KH
420 (let ((describe-map describe-language-environment-map)
421 (setup-map setup-language-environment-map))
422 (if parents
423 (let ((l parents)
424 map parent-symbol parent)
425 (while l
426 (if (symbolp (setq parent-symbol (car l)))
427 (setq parent (symbol-name parent))
428 (setq parent parent-symbol parent-symbol (intern parent)))
429 (setq map (lookup-key describe-map (vector parent-symbol)))
430 (if (not map)
431 (progn
432 (setq map (intern (format "describe-%s-environment-map"
433 (downcase parent))))
434 (define-prefix-command map)
435 (define-key-after describe-map (vector parent-symbol)
436 (cons parent map) t)))
437 (setq describe-map (symbol-value map))
438 (setq map (lookup-key setup-map (vector parent-symbol)))
439 (if (not map)
440 (progn
441 (setq map (intern (format "setup-%s-environment-map"
442 (downcase parent))))
443 (define-prefix-command map)
444 (define-key-after setup-map (vector parent-symbol)
445 (cons parent map) t)))
446 (setq setup-map (symbol-value map))
447 (setq l (cdr l)))))
448 (while alist
449 (set-language-info language-name (car (car alist)) (cdr (car alist))
450 describe-map setup-map)
451 (setq alist (cdr alist)))))
4ed46869 452
ae302641 453(defun read-language-name (key prompt &optional default)
4ef06f75 454 "Read language name which has information for KEY, prompting with PROMPT.
ae302641 455DEFAULT is the default choice of language.
fc0678af 456This returns a language name as a string."
4ed46869
KH
457 (let* ((completion-ignore-case t)
458 (name (completing-read prompt
459 language-info-alist
460 (function (lambda (elm) (assq key elm)))
ae302641 461 t nil nil default)))
13e82c04
KH
462 (if (and (> (length name) 0)
463 (get-language-info name key))
464 name)))
4ed46869
KH
465\f
466;;; Multilingual input methods.
467
d0b9c3ab
KH
468(defconst leim-list-file-name "leim-list.el"
469 "Name of LEIM list file.
470This file contains a list of libraries of Emacs input methods (LEIM)
471in the format of Lisp expression for registering each input method.
472Emacs loads this file at startup time.")
473
474(defvar leim-list-header (format "\
475;;; %s -- list of LEIM (Library of Emacs Input Method)
476;;
477;; This file contains a list of LEIM (Library of Emacs Input Method)
478;; in the same directory as this file. Loading this file registeres
479;; the whole input methods in Emacs.
480;;
d33d5fbe 481;; Each entry has the form:
d0b9c3ab
KH
482;; (register-input-method
483;; INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC
484;; TITLE DESCRIPTION
485;; ARG ...)
486;; See the function `register-input-method' for the meanings of arguments.
487;;
488;; If this directory is included in load-path, Emacs automatically
489;; loads this file at startup time.
490
491"
492 leim-list-file-name)
493 "Header to be inserted in LEIM list file.")
494
e55e92ee 495(defvar leim-list-entry-regexp "^(register-input-method"
d0b9c3ab
KH
496 "Regexp matching head of each entry in LEIM list file.
497See also the variable `leim-list-header'")
498
499(defvar update-leim-list-functions
500 '(quail-update-leim-list-file)
501 "List of functions to call to update LEIM list file.
502Each function is called with one arg, LEIM directory name.")
503
a337fe7f
RS
504(defun update-leim-list-file (&rest dirs)
505 "Update LEIM list file in directories DIRS."
d0b9c3ab
KH
506 (let ((functions update-leim-list-functions))
507 (while functions
a337fe7f 508 (apply (car functions) dirs)
d0b9c3ab
KH
509 (setq functions (cdr functions)))))
510
4ed46869
KH
511(defvar current-input-method nil
512 "The current input method for multilingual text.
96db204a 513If nil, that means no input method is activated now.")
4ed46869
KH
514(make-variable-buffer-local 'current-input-method)
515(put 'current-input-method 'permanent-local t)
516
517(defvar current-input-method-title nil
d0b9c3ab 518 "Title string of the current input method shown in mode line.")
4ed46869
KH
519(make-variable-buffer-local 'current-input-method-title)
520(put 'current-input-method-title 'permanent-local t)
521
b4fba33f
KH
522(defcustom default-input-method nil
523 "*Default input method for multilingual text.
524This is the input method activated automatically by the command
9b10b5a3 525`toggle-input-method' (\\[toggle-input-method])."
b4fba33f
KH
526 :group 'mule)
527
723a427a
KH
528(defvar input-method-history nil
529 "History list for some commands that read input methods.")
530(make-variable-buffer-local 'input-method-history)
531(put 'input-method-history 'permanent-local t)
4ed46869
KH
532
533(defvar inactivate-current-input-method-function nil
534 "Function to call for inactivating the current input method.
535Every input method should set this to an appropriate value when activated.
f17ccaee
KH
536This function is called with no argument.
537
538This function should never change the value of `current-input-method'.
539It is set to nil by the function `inactivate-input-method'.")
4ed46869
KH
540(make-variable-buffer-local 'inactivate-current-input-method-function)
541(put 'inactivate-current-input-method-function 'permanent-local t)
542
543(defvar describe-current-input-method-function nil
544 "Function to call for describing the current input method.
545This function is called with no argument.")
546(make-variable-buffer-local 'describe-current-input-method-function)
547(put 'describe-current-input-method-function 'permanent-local t)
548
d0b9c3ab
KH
549(defvar input-method-alist nil
550 "Alist of input method names vs the corresponding information to use it.
551Each element has the form:
552 (INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC TITLE DESCRIPTION ...)
553See the function `register-input-method' for the meanings of each elements.")
554
555(defun register-input-method (input-method language-name &rest args)
556 "Register INPUT-METHOD as an input method for LANGUAGE-NAME.
4ef06f75 557INPUT-METHOD and LANGUAGE-NAME are symbols or strings.
d0b9c3ab
KH
558The remaining arguments are:
559 ACTIVATE-FUNC, TITLE, DESCRIPTION, and ARG ...
560 where,
561ACTIVATE-FUNC is a function to call for activating this method.
562TITLE is a string shown in mode-line while this method is active,
563DESCRIPTION is a string describing about this method,
564Arguments to ACTIVATE-FUNC are INPUT-METHOD and ARGs."
4ef06f75
KH
565 (if (symbolp language-name)
566 (setq language-name (symbol-name language-name)))
567 (if (symbolp input-method)
568 (setq input-method (symbol-name input-method)))
d0b9c3ab
KH
569 (let ((info (cons language-name args))
570 (slot (assoc input-method input-method-alist)))
571 (if slot
572 (setcdr slot info)
573 (setq slot (cons input-method info))
574 (setq input-method-alist (cons slot input-method-alist)))))
575
4d5ac029 576(defun read-input-method-name (prompt &optional default inhibit-null)
d0b9c3ab 577 "Read a name of input method from a minibuffer prompting with PROMPT.
4d5ac029
RS
578If DEFAULT is non-nil, use that as the default,
579 and substitute it into PROMPT at the first `%s'.
4ef06f75
KH
580If INHIBIT-NULL is non-nil, null input signals an error.
581
582The return value is a string."
4d5ac029
RS
583 (if default
584 (setq prompt (format prompt default)))
d0b9c3ab 585 (let* ((completion-ignore-case t)
723a427a
KH
586 ;; This binding is necessary because input-method-history is
587 ;; buffer local.
d0b9c3ab 588 (input-method (completing-read prompt input-method-alist
87505a98
RS
589 nil t nil 'input-method-history
590 default)))
d0b9c3ab
KH
591 (if (> (length input-method) 0)
592 input-method
593 (if inhibit-null
43807b77 594 (error "No valid input method is specified")))))
d0b9c3ab 595
d0b9c3ab 596(defun activate-input-method (input-method)
f17ccaee
KH
597 "Turn INPUT-METHOD on.
598If some input method is already on, turn it off at first."
4ef06f75
KH
599 (if (symbolp input-method)
600 (setq input-method (symbol-name input-method)))
723a427a
KH
601 (if (and current-input-method
602 (not (string= current-input-method input-method)))
42395763
RS
603 (inactivate-input-method))
604 (unless current-input-method
d0b9c3ab
KH
605 (let ((slot (assoc input-method input-method-alist)))
606 (if (null slot)
723a427a 607 (error "Can't activate input method `%s'" input-method))
8efc03e1
KH
608 (let ((func (nth 2 slot)))
609 (if (functionp func)
610 (apply (nth 2 slot) input-method (nthcdr 5 slot))
611 (if (and (consp func) (symbolp (car func)) (symbolp (cdr func)))
612 (progn
613 (require (cdr func))
614 (apply (car func) input-method (nthcdr 5 slot)))
615 (error "Can't activate input method `%s'" input-method))))
d0b9c3ab 616 (setq current-input-method input-method)
723a427a
KH
617 (setq current-input-method-title (nth 3 slot))
618 (run-hooks 'input-method-activate-hook))))
15b3e511 619
15b3e511 620(defun inactivate-input-method ()
f17ccaee 621 "Turn off the current input method."
723a427a
KH
622 (when current-input-method
623 (if input-method-history
624 (unless (string= current-input-method (car input-method-history))
625 (setq input-method-history
626 (cons current-input-method
627 (delete current-input-method input-method-history))))
628 (setq input-method-history (list current-input-method)))
629 (unwind-protect
630 (funcall inactivate-current-input-method-function)
15b3e511 631 (unwind-protect
723a427a
KH
632 (run-hooks 'input-method-inactivate-hook)
633 (setq current-input-method nil
634 current-input-method-title nil)))))
4ed46869 635
8b784951 636(defun set-input-method (input-method)
723a427a
KH
637 "Select and turn on INPUT-METHOD.
638This sets the default input method to what you specify,
639and turn it on for the current buffer."
d0b9c3ab 640 (interactive
723a427a 641 (let* ((default (or (car input-method-history) default-input-method)))
42395763 642 (list (read-input-method-name
87505a98 643 (if default "Select input method (default %s): " "Select input method: ")
42395763 644 default t))))
d0b9c3ab 645 (activate-input-method input-method)
42395763 646 (setq default-input-method input-method))
4ed46869
KH
647
648(defun toggle-input-method (&optional arg)
15b3e511 649 "Turn on or off a multilingual text input method for the current buffer.
723a427a 650
d0b9c3ab 651With arg, read an input method from minibuffer and turn it on.
723a427a 652
15b3e511 653Without arg, if some input method is currently activated, turn it off,
723a427a
KH
654else turn on an input method selected last time
655or the default input method (see `default-input-method').
656
657When there's no input method to turn on, turn on what read from minibuffer."
4ed46869 658 (interactive "P")
723a427a 659 (let* ((default (or (car input-method-history) default-input-method)))
b4fba33f
KH
660 (if (and current-input-method (not arg))
661 (inactivate-input-method)
723a427a
KH
662 (activate-input-method
663 (if (or arg (not default))
664 (read-input-method-name
665 (if default "Input method (default %s): " "Input method: " )
666 default t)
667 default))
668 (or default-input-method
669 (setq default-input-method current-input-method)))))
d0b9c3ab
KH
670
671(defun describe-input-method (input-method)
4ef06f75 672 "Describe input method INPUT-METHOD."
d0b9c3ab
KH
673 (interactive
674 (list (read-input-method-name
675 "Describe input method (default, current choice): ")))
78754934 676 (if (and input-method (symbolp input-method))
4ef06f75 677 (setq input-method (symbol-name input-method)))
d0b9c3ab
KH
678 (if (null input-method)
679 (describe-current-input-method)
680 (with-output-to-temp-buffer "*Help*"
681 (let ((elt (assoc input-method input-method-alist)))
682 (princ (format "Input method: %s (`%s' in mode line) for %s\n %s\n"
683 input-method (nth 3 elt) (nth 1 elt) (nth 4 elt)))))))
684
685(defun describe-current-input-method ()
96db204a 686 "Describe the input method currently in use."
4ed46869
KH
687 (if current-input-method
688 (if (and (symbolp describe-current-input-method-function)
689 (fboundp describe-current-input-method-function))
690 (funcall describe-current-input-method-function)
691 (message "No way to describe the current input method `%s'"
692 (cdr current-input-method))
693 (ding))
d0b9c3ab 694 (error "No input method is activated now")))
4ed46869 695
d3459641 696(defun read-multilingual-string (prompt &optional initial-input input-method)
4ed46869
KH
697 "Read a multilingual string from minibuffer, prompting with string PROMPT.
698The input method selected last time is activated in minibuffer.
15b3e511 699If optional second arg INITIAL-INPUT is non-nil, insert it in the minibuffer
d0b9c3ab
KH
700initially.
701Optional 3rd argument INPUT-METHOD specifies the input method
4ef06f75
KH
702to be activated instead of the one selected last time. It is a symbol
703or a string."
88d559ec
KH
704 (setq input-method
705 (or input-method
d3459641 706 current-input-method
88d559ec
KH
707 default-input-method
708 (read-input-method-name "Input method: " nil t)))
3df60841 709 (if (and input-method (symbolp input-method))
4ef06f75 710 (setq input-method (symbol-name input-method)))
d3459641
KH
711 (let ((previous-input-method current-input-method))
712 (unwind-protect
713 (progn
714 (activate-input-method input-method)
715 (read-string prompt initial-input nil nil t))
716 (if previous-input-method
717 (activate-input-method previous-input-method)
718 (inactivate-input-method)))))
4ed46869
KH
719
720;; Variables to control behavior of input methods. All input methods
721;; should react to these variables.
722
8efc03e1
KH
723(defcustom input-method-verbose-flag 'default
724 "*A flag to control extra guidance given by input methods.
725The value should be nil, t, `complex-only', or `default'.
4ed46869 726
cb29dfb6 727The extra guidance is done by showing list of available keys in echo
8efc03e1
KH
728area. When you use the input method in the minibuffer, the guidance
729is shown at the bottom short window (split from the existing window).
c27c4ed8 730
8efc03e1
KH
731If the value is t, extra guidance is always given, if the value is
732nil, extra guidance is always suppressed.
733
734If the value is `complex-only', only complex input methods such as
735`chinese-py' and `japanese' give extra guidance.
736
737If the value is `default', complex input methods always give extra
738guidance, but simple input methods give it only when you are not in
739the minibuffer.
740
741See also the variable `input-method-highlight-flag'."
742 :type '(choice (const t) (const nil) (const complex-only) (const default))
42395763
RS
743 :group 'mule)
744
745(defcustom input-method-highlight-flag t
746 "*If this flag is non-nil, input methods highlight partially-entered text.
747For instance, while you are in the middle of a Quail input method sequence,
748the text inserted so far is temporarily underlined.
8efc03e1
KH
749The underlining goes away when you finish or abort the input method sequence.
750See also the variable `input-method-verbose-flag'."
42395763
RS
751 :type 'boolean
752 :group 'mule)
4ed46869
KH
753
754(defvar input-method-activate-hook nil
f17ccaee
KH
755 "Normal hook run just after an input method is activated.
756
757The variable `current-input-method' keeps the input method name
758just activated.")
4ed46869
KH
759
760(defvar input-method-inactivate-hook nil
f17ccaee
KH
761 "Normal hook run just after an input method is inactivated.
762
763The variable `current-input-method' still keeps the input method name
4d0e6a11 764just inactivated.")
4ed46869
KH
765
766(defvar input-method-after-insert-chunk-hook nil
767 "Normal hook run just after an input method insert some chunk of text.")
768
723a427a
KH
769(defvar input-method-exit-on-invalid-key nil
770 "This flag controls the behaviour of an input method on invalid key input.
771Usually, when a user types a key which doesn't start any character
772handled by the input method, the key is handled by turning off the
773input method temporalily. After the key is handled, the input method is
774back on.
775But, if this flag is non-nil, the input method is never back on.")
776
4ed46869 777\f
8efc03e1
KH
778(defvar set-language-environment-hook nil
779 "Normal hook run after some language environment is set.
780
781When you set some hook function here, that effect usually should not
782be inherited to another language environment. So, you had better set
783another function in `exit-language-environment-hook' (which see) to
784cancel the effect.")
785
786(defvar exit-language-environment-hook nil
787 "Normal hook run after exiting from some language environment.
788When this hook is run, the variable `current-language-environment'
789is still bound to the language environment being exited.
790
791This hook is mainly used for cancelling the effect of
792`set-language-environment-hook' (which-see).")
793
15b3e511 794(defun setup-specified-language-environment ()
f850d782 795 "Set up multi-lingual environment convenient for the specified language."
15b3e511 796 (interactive)
f850d782 797 (let (language-name)
15b3e511
KH
798 (if (and (symbolp last-command-event)
799 (or (not (eq last-command-event 'Default))
800 (setq last-command-event 'English))
f850d782
RS
801 (setq language-name (symbol-name last-command-event)))
802 (set-language-environment language-name)
15b3e511 803 (error "Bogus calling sequence"))))
4ed46869 804
f850d782
RS
805(defvar current-language-environment "English"
806 "The last language environment specified with `set-language-environment'.")
807
166246f7 808(defun set-language-environment (language-name)
6c05d680
RS
809 "Set up multi-lingual environment for using LANGUAGE-NAME.
810This sets the coding system priority and the default input method
811and sometimes other things."
8efc03e1
KH
812 (interactive (list (read-language-name
813 'setup-function
814 "Set language environment (default, English): ")))
4ef06f75
KH
815 (if language-name
816 (if (symbolp language-name)
817 (setq language-name (symbol-name language-name)))
818 (setq language-name "English"))
b4fba33f 819 (if (null (get-language-info language-name 'setup-function))
f850d782 820 (error "Language environment not defined: %S" language-name))
8efc03e1
KH
821 (if current-language-environment
822 (let ((func (get-language-info current-language-environment
823 'exit-function)))
e63645c2
KH
824 (run-hooks 'exit-language-environment-hook)
825 (if (fboundp func) (funcall func))))
f850d782 826 (setq current-language-environment language-name)
8efc03e1
KH
827 (funcall (get-language-info language-name 'setup-function))
828 (run-hooks 'set-language-environment-hook)
f850d782 829 (force-mode-line-update t))
4ed46869 830
54b226f7
KH
831(defun set-language-environment-coding-systems (language-name)
832 "Do various coding system setups for language environment LANGUAGE-NAME."
833 (let* ((priority (get-language-info language-name 'coding-priority))
834 (default-coding (car priority)))
835 (if priority
836 (let ((categories (mapcar 'coding-system-category priority)))
837 (set-default-coding-systems default-coding)
838 (set-coding-priority categories)
839 (while priority
840 (set (car categories) (car priority))
841 (setq priority (cdr priority) categories (cdr categories)))
842 (update-iso-coding-systems)))))
843
4ed46869
KH
844;; Print all arguments with `princ', then print "\n".
845(defsubst princ-list (&rest args)
846 (while args (princ (car args)) (setq args (cdr args)))
847 (princ "\n"))
848
48082651 849;; Print a language specific information such as input methods,
13e82c04 850;; charsets, and coding systems. This function is intended to be
48082651 851;; called from the menu:
281d03ec 852;; [menu-bar mule describe-language-environment LANGUAGE]
48082651
KH
853;; and should not run it by `M-x describe-current-input-method-function'.
854(defun describe-specified-language-support ()
96db204a 855 "Describe how Emacs supports the specified language environment."
48082651 856 (interactive)
281d03ec 857 (let (language-name)
48082651 858 (if (not (and (symbolp last-command-event)
281d03ec 859 (setq language-name (symbol-name last-command-event))))
48082651 860 (error "Bogus calling sequence"))
281d03ec
RS
861 (describe-language-environment language-name)))
862
863(defun describe-language-environment (language-name)
864 "Describe how Emacs supports language environment LANGUAGE-NAME."
78754934
KH
865 (interactive
866 (list (read-language-name
867 'documentation
8adfa8be 868 "Describe language environment (default, current choice): ")))
f850d782
RS
869 (if (null language-name)
870 (setq language-name current-language-environment))
281d03ec
RS
871 (if (or (null language-name)
872 (null (get-language-info language-name 'documentation)))
873 (error "No documentation for the specified language"))
4ef06f75
KH
874 (if (symbolp language-name)
875 (setq language-name (symbol-name language-name)))
281d03ec 876 (let ((doc (get-language-info language-name 'documentation)))
48082651 877 (with-output-to-temp-buffer "*Help*"
13e82c04 878 (if (stringp doc)
d0b9c3ab
KH
879 (progn
880 (princ-list doc)
881 (terpri)))
15b3e511
KH
882 (let ((str (get-language-info language-name 'sample-text)))
883 (if (stringp str)
884 (progn
281d03ec 885 (princ "Sample text:\n")
d0b9c3ab
KH
886 (princ-list " " str)
887 (terpri))))
281d03ec 888 (princ "Input methods:\n")
d0b9c3ab 889 (let ((l input-method-alist))
15b3e511 890 (while l
d0b9c3ab
KH
891 (if (string= language-name (nth 1 (car l)))
892 (princ-list " " (car (car l))
893 (format " (`%s' in mode line)" (nth 3 (car l)))))
15b3e511 894 (setq l (cdr l))))
281d03ec
RS
895 (terpri)
896 (princ "Character sets:\n")
15b3e511
KH
897 (let ((l (get-language-info language-name 'charset)))
898 (if (null l)
899 (princ-list " nothing specific to " language-name)
900 (while l
901 (princ-list " " (car l) ": "
902 (charset-description (car l)))
903 (setq l (cdr l)))))
281d03ec
RS
904 (terpri)
905 (princ "Coding systems:\n")
15b3e511
KH
906 (let ((l (get-language-info language-name 'coding-system)))
907 (if (null l)
908 (princ-list " nothing specific to " language-name)
48082651 909 (while l
281d03ec
RS
910 (princ (format " %s (`%c' in mode line):\n\t%s\n"
911 (car l)
912 (coding-system-mnemonic (car l))
a904b20b 913 (coding-system-doc-string (car l))))
8efc03e1
KH
914 (let ((aliases (coding-system-get (car l) 'alias-coding-systems)))
915 (when aliases
916 (princ "\t")
917 (princ (cons 'alias: (cdr aliases)))
918 (terpri)))
15b3e511 919 (setq l (cdr l))))))))
4ed46869
KH
920\f
921;;; Charset property
922
923(defsubst get-charset-property (charset propname)
924 "Return the value of CHARSET's PROPNAME property.
925This is the last value stored with
96db204a 926 (put-charset-property CHARSET PROPNAME VALUE)."
4ed46869
KH
927 (plist-get (charset-plist charset) propname))
928
929(defsubst put-charset-property (charset propname value)
930 "Store CHARSETS's PROPNAME property with value VALUE.
931It can be retrieved with `(get-charset-property CHARSET PROPNAME)'."
932 (set-charset-plist charset
933 (plist-put (charset-plist charset) propname value)))
934
935;;; Character code property
936(put 'char-code-property-table 'char-table-extra-slots 0)
937
938(defvar char-code-property-table
939 (make-char-table 'char-code-property-table)
940 "Char-table containing a property list of each character code.
941
942See also the documentation of `get-char-code-property' and
96db204a 943`put-char-code-property'.")
4ed46869
KH
944
945(defun get-char-code-property (char propname)
946 "Return the value of CHAR's PROPNAME property in `char-code-property-table'."
947 (let ((plist (aref char-code-property-table char)))
948 (if (listp plist)
949 (car (cdr (memq propname plist))))))
950
951(defun put-char-code-property (char propname value)
952 "Store CHAR's PROPNAME property with VALUE in `char-code-property-table'.
953It can be retrieved with `(get-char-code-property CHAR PROPNAME)'."
954 (let ((plist (aref char-code-property-table char)))
955 (if plist
956 (let ((slot (memq propname plist)))
957 (if slot
958 (setcar (cdr slot) value)
959 (nconc plist (list propname value))))
960 (aset char-code-property-table char (list propname value)))))
961
962;;; mule-cmds.el ends here