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