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