(cleanall-other-dirs-nmake):
[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.
cda74479 5;; Copyright (C) 2000 Free Software Foundation, Inc.
4ed46869
KH
6
7;; Keywords: mule, multilingual
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
369314dc
KH
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
4ed46869
KH
25
26;;; Code:
27
cda74479
DL
28(eval-when-compile (defvar dos-codepage))
29
4ed46869
KH
30;;; MULE related key bindings and menus.
31
0709d285 32(defvar mule-keymap (make-sparse-keymap)
33d17698 33 "Keymap for Mule (Multilingual environment) specific commands.")
4ed46869 34
8f81f784 35;; Keep "C-x C-m ..." for mule specific commands.
0709d285 36(define-key ctl-x-map "\C-m" mule-keymap)
ef8a8c8c 37
4ed46869
KH
38(define-key mule-keymap "f" 'set-buffer-file-coding-system)
39(define-key mule-keymap "t" 'set-terminal-coding-system)
15b3e511
KH
40(define-key mule-keymap "k" 'set-keyboard-coding-system)
41(define-key mule-keymap "p" 'set-buffer-process-coding-system)
7624ebb9
KH
42(define-key mule-keymap "x" 'set-selection-coding-system)
43(define-key mule-keymap "X" 'set-next-selection-coding-system)
8b784951 44(define-key mule-keymap "\C-\\" 'set-input-method)
15b3e511 45(define-key mule-keymap "c" 'universal-coding-system-argument)
b4fba33f 46(define-key mule-keymap "l" 'set-language-environment)
4ed46869 47
281d03ec 48(define-key help-map "\C-L" 'describe-language-environment)
ac4a3a2d 49(define-key help-map "L" 'describe-language-environment)
4ed46869 50(define-key help-map "\C-\\" 'describe-input-method)
ac4a3a2d 51(define-key help-map "I" 'describe-input-method)
d0b9c3ab 52(define-key help-map "C" 'describe-coding-system)
4ed46869
KH
53(define-key help-map "h" 'view-hello-file)
54
538d88fb
EZ
55(defvar mule-menu-keymap
56 (make-sparse-keymap "Mule (Multilingual Environment)")
33d17698 57 "Keymap for Mule (Multilingual environment) menu specific commands.")
15b3e511 58
dcad02bc
EZ
59(defvar describe-language-environment-map
60 (make-sparse-keymap "Describe Language Environment"))
15b3e511 61
dcad02bc
EZ
62(defvar setup-language-environment-map
63 (make-sparse-keymap "Set Language Environment"))
15b3e511 64
dcad02bc
EZ
65(defvar set-coding-system-map
66 (make-sparse-keymap "Set Coding System"))
15b3e511 67
15b3e511 68(define-key-after mule-menu-keymap [set-language-environment]
cda74479
DL
69 (list 'menu-item "Set Language Environment" setup-language-environment-map
70 :help "Multilingual environment suitable for a specific language"))
a61f401d 71(define-key-after mule-menu-keymap [mouse-set-font]
538d88fb 72 '(menu-item "Set Font/Fontset" mouse-set-font
cda74479
DL
73 :visible (fboundp 'generate-fontset-menu)
74 :help "Select a font from list of known fonts/fontsets"))
15b3e511
KH
75(define-key-after mule-menu-keymap [separator-mule]
76 '("--")
77 t)
78(define-key-after mule-menu-keymap [toggle-input-method]
538d88fb 79 '(menu-item "Toggle Input Method" toggle-input-method)
15b3e511 80 t)
8b784951 81(define-key-after mule-menu-keymap [set-input-method]
538d88fb 82 '(menu-item "Select Input Method..." set-input-method)
15b3e511 83 t)
cda74479
DL
84(define-key-after mule-menu-keymap [describe-input-method]
85 '(menu-item "Describe Input Method" describe-input-method))
15b3e511
KH
86(define-key-after mule-menu-keymap [separator-input-method]
87 '("--")
88 t)
15b3e511 89(define-key-after mule-menu-keymap [set-various-coding-system]
cda74479
DL
90 (list 'menu-item "Set Coding Systems" set-coding-system-map
91 :enable 'enable-multibyte-characters))
538d88fb
EZ
92(define-key-after mule-menu-keymap [view-hello-file]
93 '(menu-item "Show Multi-lingual Text" view-hello-file
94 :enable (file-readable-p
95 (expand-file-name "HELLO" data-directory))
96 :help "Display file which says HELLO in many languages")
15b3e511
KH
97 t)
98(define-key-after mule-menu-keymap [separator-coding-system]
99 '("--")
100 t)
538d88fb
EZ
101(define-key-after mule-menu-keymap [describe-language-environment]
102 (list 'menu-item "Describe Language Environment"
103 describe-language-environment-map
cda74479 104 :help "Show multilingual settings for a specific language")
15b3e511 105 t)
538d88fb
EZ
106(define-key-after mule-menu-keymap [describe-input-method]
107 '(menu-item "Describe Input Method..." describe-input-method
cda74479 108 :help "Keyboard layout for a specific input method")
538d88fb
EZ
109 t)
110(define-key-after mule-menu-keymap [describe-coding-system]
111 '(menu-item "Describe Coding System..." describe-coding-system)
112 t)
cda74479
DL
113(define-key-after mule-menu-keymap [list-character-sets]
114 '(menu-item "List Character Sets" list-character-sets
115 :help "Show table of available character sets"))
538d88fb
EZ
116(define-key-after mule-menu-keymap [mule-diag]
117 '(menu-item "Show All of Mule Status" mule-diag
118 :help "Display multilingual environment settings")
15b3e511
KH
119 t)
120
121(define-key-after set-coding-system-map [set-buffer-file-coding-system]
538d88fb
EZ
122 '(menu-item "For Saving this Buffer" set-buffer-file-coding-system
123 :help "How to encode this buffer on disk")
15b3e511 124 t)
3a151e98 125(define-key-after set-coding-system-map [universal-coding-system-argument]
538d88fb
EZ
126 '(menu-item "For Next Command" universal-coding-system-argument
127 :help "Coding system to be used by next command")
3a151e98 128 t)
15b3e511 129(define-key-after set-coding-system-map [set-terminal-coding-system]
538d88fb
EZ
130 '(menu-item "For Terminal" set-terminal-coding-system
131 :enable (null (memq window-system '(x w32 mac)))
132 :help "How to encode terminal output")
15b3e511
KH
133 t)
134(define-key-after set-coding-system-map [set-keyboard-coding-system]
538d88fb
EZ
135 '(menu-item "For Keyboard" set-keyboard-coding-system
136 :help "How to decode keyboard input")
15b3e511
KH
137 t)
138(define-key-after set-coding-system-map [set-buffer-process-coding-system]
538d88fb
EZ
139 '(menu-item "For I/O with Subprocess" set-buffer-process-coding-system
140 :visible (fboundp 'start-process)
141 :enable (get-buffer-process (current-buffer))
142 :help "How to en/decode I/O from/to subprocess connected to this buffer")
15b3e511 143 t)
7624ebb9 144(define-key-after set-coding-system-map [set-selection-coding-system]
538d88fb
EZ
145 '(menu-item "For X Selections/Clipboard" set-selection-coding-system
146 :visible (display-selections-p)
147 :help "How to en/decode data to/from selection/clipboard")
7624ebb9
KH
148 t)
149(define-key-after set-coding-system-map [set-next-selection-coding-system]
538d88fb
EZ
150 '(menu-item "For Next X Selection" set-next-selection-coding-system
151 :visible (display-selections-p)
152 :help "How to en/decode next selection/clipboard operation")
7624ebb9 153 t)
15b3e511 154(define-key setup-language-environment-map
538d88fb 155 [Default] '(menu-item "Default" setup-specified-language-environment))
4ed46869 156
cda74479
DL
157(define-key describe-language-environment-map
158 [Default] '(menu-item "Default" describe-specified-language-support))
159
4ed46869
KH
160;; This should be a single character key binding because users use it
161;; very frequently while editing multilingual text. Now we can use
162;; only two such keys: "\C-\\" and "\C-^", but the latter is not
163;; convenient because it requires shifting on most keyboards. An
164;; alternative is "\C-\]" which is now bound to `abort-recursive-edit'
165;; but it won't be used that frequently.
166(define-key global-map "\C-\\" 'toggle-input-method)
167
a2ad45b9
RS
168;;; This is no good because people often type Shift-SPC
169;;; meaning to type SPC. -- rms.
170;;; ;; Here's an alternative key binding for X users (Shift-SPACE).
171;;; (define-key global-map [?\S- ] 'toggle-input-method)
b4fba33f 172
464cc130
KH
173;;; Mule related hyperlinks.
174(defconst help-xref-mule-regexp-template
175 (purecopy (concat "\\(\\<\\("
176 "\\(coding system\\)\\|"
d0c40faa
KH
177 "\\(input method\\)\\|"
178 "\\(character set\\)\\|"
179 "\\(charset\\)"
464cc130
KH
180 "\\)\\s-+\\)?"
181 ;; Note starting with word-syntax character:
182 "`\\(\\sw\\(\\sw\\|\\s_\\)+\\)'")))
183
26d87040
EZ
184(defun coding-system-change-eol-conversion (coding-system eol-type)
185 "Return a coding system which differs from CODING-SYSTEM in eol conversion.
186The returned coding system converts end-of-line by EOL-TYPE
187but text as the same way as CODING-SYSTEM.
188EOL-TYPE should be `unix', `dos', `mac', or nil.
189If EOL-TYPE is nil, the returned coding system detects
190how end-of-line is formatted automatically while decoding.
191
192EOL-TYPE can be specified by an integer 0, 1, or 2.
193They means `unix', `dos', and `mac' respectively."
194 (if (symbolp eol-type)
195 (setq eol-type (cond ((eq eol-type 'unix) 0)
196 ((eq eol-type 'dos) 1)
197 ((eq eol-type 'mac) 2)
198 (t eol-type))))
199 (let ((orig-eol-type (coding-system-eol-type coding-system)))
200 (if (vectorp orig-eol-type)
201 (if (not eol-type)
202 coding-system
203 (aref orig-eol-type eol-type))
204 (let ((base (coding-system-base coding-system)))
205 (if (not eol-type)
206 base
207 (if (= eol-type orig-eol-type)
208 coding-system
209 (setq orig-eol-type (coding-system-eol-type base))
210 (if (vectorp orig-eol-type)
211 (aref orig-eol-type eol-type))))))))
212
213(defun coding-system-change-text-conversion (coding-system coding)
214 "Return a coding system which differs from CODING-SYSTEM in text conversion.
215The returned coding system converts text by CODING
216but end-of-line as the same way as CODING-SYSTEM.
217If CODING is nil, the returned coding system detects
218how text is formatted automatically while decoding."
219 (if (not coding)
220 (coding-system-base coding-system)
221 (let ((eol-type (coding-system-eol-type coding-system)))
222 (coding-system-change-eol-conversion
223 coding
224 (if (numberp eol-type) (aref [unix dos mac] eol-type))))))
225
4ed46869 226(defun toggle-enable-multibyte-characters (&optional arg)
6998e1a1
RS
227 "Change whether this buffer uses multibyte characters.
228With arg, use multibyte characters if the arg is positive.
229
230Note that this command does not convert the byte contents of
231the buffer; it only changes the way those bytes are interpreted.
232In general, therefore, this command *changes* the sequence of
233characters that the current buffer contains.
234
235We suggest you avoid using use this command unless you know what you
236are doing. If you use it by mistake, and the buffer is now displayed
237wrong, use this command again to toggle back to the right mode."
4ed46869 238 (interactive "P")
b7079457
RS
239 (let ((new-flag
240 (if (null arg) (null enable-multibyte-characters)
241 (> (prefix-numeric-value arg) 0))))
242 (set-buffer-multibyte new-flag))
4ed46869
KH
243 (force-mode-line-update))
244
245(defun view-hello-file ()
246 "Display the HELLO file which list up many languages and characters."
247 (interactive)
8f81f784
KH
248 ;; We have to decode the file in any environment.
249 (let ((default-enable-multibyte-characters t)
95fa03b4 250 (coding-system-for-read 'iso-2022-7bit))
8f81f784 251 (find-file-read-only (expand-file-name "HELLO" data-directory))))
4ed46869 252
15b3e511
KH
253(defun universal-coding-system-argument ()
254 "Execute an I/O command using the specified coding system."
255 (interactive)
34104362
KH
256 (let* ((default (and buffer-file-coding-system
257 (not (eq (coding-system-type buffer-file-coding-system)
258 t))
259 buffer-file-coding-system))
260 (coding-system (read-coding-system
261 (if default
262 (format "Coding system for following command (default, %s): " default)
263 "Coding system for following command: ")
264 default))
15b3e511 265 (keyseq (read-key-sequence
e14a8f4c 266 (format "Command to execute with %s:" coding-system)))
15b3e511
KH
267 (cmd (key-binding keyseq)))
268 (let ((coding-system-for-read coding-system)
269 (coding-system-for-write coding-system))
270 (message "")
271 (call-interactively cmd))))
272
de94d711 273(defun set-default-coding-systems (coding-system)
0c3154d2 274 "Set default value of various coding systems to CODING-SYSTEM.
387136f6 275This sets the following coding systems:
0c3154d2 276 o coding system of a newly created buffer
8efc03e1
KH
277 o default coding system for subprocess I/O
278This also sets the following values:
387136f6 279 o default value used as file-name-coding-system for converting file names.
03c35c83
EZ
280 o default value for the command `set-terminal-coding-system' (not on MSDOS)
281 o default value for the command `set-keyboard-coding-system'."
de94d711
KH
282 (check-coding-system coding-system)
283 (setq-default buffer-file-coding-system coding-system)
716184d4
RS
284 (if default-enable-multibyte-characters
285 (setq default-file-name-coding-system coding-system))
03c35c83
EZ
286 ;; If coding-system is nil, honor that on MS-DOS as well, so
287 ;; that they could reset the terminal coding system.
288 (unless (and (eq window-system 'pc) coding-system)
289 (setq default-terminal-coding-system coding-system))
de94d711
KH
290 (setq default-keyboard-coding-system coding-system)
291 (setq default-process-coding-system (cons coding-system coding-system)))
292
45d08cb2 293(defalias 'update-iso-coding-systems 'update-coding-systems-internal)
2598a293 294(make-obsolete 'update-iso-coding-systems 'update-coding-systems-internal "20.3")
45d08cb2 295
0c3154d2
KH
296(defun prefer-coding-system (coding-system)
297 "Add CODING-SYSTEM at the front of the priority list for automatic detection.
387136f6 298This also sets the following coding systems:
0c3154d2 299 o coding system of a newly created buffer
8efc03e1
KH
300 o default coding system for subprocess I/O
301This also sets the following values:
387136f6 302 o default value used as file-name-coding-system for converting file names.
03c35c83
EZ
303 o default value for the command `set-terminal-coding-system' (not on MSDOS)
304 o default value for the command `set-keyboard-coding-system'
305
bd3ac67e
EZ
306If CODING-SYSTEM specifies a certain type of EOL conversion, the coding
307systems set by this function will use that type of EOL conversion.
308
03c35c83
EZ
309This command does not change the default value of terminal coding system
310for MS-DOS terminal, because DOS terminals only support a single coding
311system, and Emacs automatically sets the default to that coding system at
5beaa0d1
KH
312startup.
313
314Such a coding system that requires automatic detection of text
315encoding (e.g. undecided, unix) can't be preferred."
0c3154d2
KH
316 (interactive "zPrefer coding system: ")
317 (if (not (and coding-system (coding-system-p coding-system)))
318 (error "Invalid coding system `%s'" coding-system))
319 (let ((coding-category (coding-system-category coding-system))
bd3ac67e
EZ
320 (base (coding-system-base coding-system))
321 (eol-type (coding-system-eol-type coding-system)))
0c3154d2
KH
322 (if (not coding-category)
323 ;; CODING-SYSTEM is no-conversion or undecided.
324 (error "Can't prefer the coding system `%s'" coding-system))
8efc03e1 325 (set coding-category (or base coding-system))
45d08cb2 326 (update-coding-systems-internal)
812cad80 327 (or (eq coding-category (car coding-category-list))
0c3154d2 328 ;; We must change the order.
812cad80 329 (set-coding-priority (list coding-category)))
8efc03e1
KH
330 (if (and base (interactive-p))
331 (message "Highest priority is set to %s (base of %s)"
332 base coding-system))
bd3ac67e 333 ;; If they asked for specific EOL conversion, honor that.
6f9dc4fd 334 (if (memq eol-type '(0 1 2))
bd3ac67e
EZ
335 (setq coding-system
336 (coding-system-change-eol-conversion base eol-type))
337 (setq coding-system base))
338 (set-default-coding-systems coding-system)))
0c3154d2 339
b5edd1d1
KH
340(defvar sort-coding-systems-predicate nil
341 "If non-nil, a predicate function to sort coding systems.
342
343It is called with two coding systems, and should return t if the first
344one is \"less\" than the second.
345
346The function `sort-coding-systems' use it.")
347
348(defun sort-coding-systems (codings)
349 "Sort coding system list CODINGS by a priority of each coding system.
350
351If a coding system is most preferred, it has the highest priority.
352Otherwise, a coding system corresponds to some MIME charset has higher
353priorities. Among them, a coding system included in `coding-system'
354key of the current language environment has higher priorities. See
355also the documentation of `language-info-alist'.
356
357If the variable `sort-coding-systems-predicate' (which see) is
358non-nil, it is used to sort CODINGS in the different way than above."
359 (if sort-coding-systems-predicate
360 (sort codings sort-coding-systems-predicate)
361 (let* ((most-preferred (symbol-value (car coding-category-list)))
362 (lang-preferred (get-language-info current-language-environment
363 'coding-system))
364 (func (function
365 (lambda (x)
366 (let ((base (coding-system-base x)))
367 (+ (if (eq base most-preferred) 64 0)
368 (let ((mime (coding-system-get base 'mime-charset)))
369 (if mime
370 (if (string-match "^x-" (symbol-name mime))
371 16 32)
372 0))
373 (if (memq base lang-preferred) 8 0)
374 (if (string-match "-with-esc$" (symbol-name base))
375 0 4)
376 (if (eq (coding-system-type base) 2)
377 ;; For ISO based coding systems, prefer
378 ;; one that doesn't use escape sequences.
379 (let ((flags (coding-system-flags base)))
380 (if (or (consp (aref flags 0))
381 (consp (aref flags 1))
382 (consp (aref flags 2))
383 (consp (aref flags 3)))
384 (if (or (aref flags 8) (aref flags 9))
385 0
386 1)
387 2))
388 1)))))))
389 (sort codings (function (lambda (x y)
390 (> (funcall func x) (funcall func y))))))))
54b226f7 391
3fc7dfe5 392(defun find-coding-systems-region (from to)
54b226f7
KH
393 "Return a list of proper coding systems to encode a text between FROM and TO.
394All coding systems in the list can safely encode any multibyte characters
395in the text.
396
e8dd0160 397If the text contains no multibyte characters, return a list of a single
3fc7dfe5 398element `undecided'."
b5edd1d1
KH
399 (let ((codings (find-coding-systems-region-internal from to)))
400 (if (eq codings t)
401 ;; The text contains only ASCII characters. Any coding
402 ;; systems are safe.
403 '(undecided)
404 ;; We need copy-sequence because sorting will alter the argument.
405 (sort-coding-systems (copy-sequence codings)))))
54b226f7 406
3fc7dfe5
KH
407(defun find-coding-systems-string (string)
408 "Return a list of proper coding systems to encode STRING.
409All coding systems in the list can safely encode any multibyte characters
410in STRING.
411
e8dd0160 412If STRING contains no multibyte characters, return a list of a single
3fc7dfe5 413element `undecided'."
b5edd1d1 414 (find-coding-systems-region string nil))
3fc7dfe5
KH
415
416(defun find-coding-systems-for-charsets (charsets)
417 "Return a list of proper coding systems to encode characters of CHARSETS.
418CHARSETS is a list of character sets."
b5edd1d1
KH
419 (cond ((or (null charsets)
420 (and (= (length charsets) 1)
421 (eq 'ascii (car charsets))))
422 '(undecided))
423 ((or (memq 'eight-bit-control charsets)
424 (memq 'eight-bit-graphic charsets))
425 '(raw-text emacs-mule))
426 (t
427 (let ((codings t)
428 charset l ll)
429 (while (and codings charsets)
430 (setq charset (car charsets) charsets (cdr charsets))
431 (unless (eq charset 'ascii)
432 (setq l (aref char-coding-system-table (make-char charset)))
433 (if (eq codings t)
434 (setq codings l)
435 (let ((ll nil))
436 (while codings
437 (if (memq (car codings) l)
438 (setq ll (cons (car codings) ll)))
439 (setq codings (cdr codings)))
440 (setq codings ll)))))
441 (append codings
442 (char-table-extra-slot char-coding-system-table 0))))))
54b226f7 443
51ed58ea
KH
444(defun find-multibyte-characters (from to &optional maxcount excludes)
445 "Find multibyte characters in the region specified by FROM and TO.
446If FROM is a string, find multibyte characters in the string.
447The return value is an alist of the following format:
448 ((CHARSET COUNT CHAR ...) ...)
449where
450 CHARSET is a character set,
451 COUNT is a number of characters,
452 CHARs are found characters of the character set.
453Optional 3rd arg MAXCOUNT limits how many CHARs are put in the above list.
251d4f4b
KH
454Optional 4th arg EXCLUDE is a list of character sets to be ignored.
455
456For invalid characters, CHARs are actually strings."
51ed58ea
KH
457 (let ((chars nil)
458 charset char)
459 (if (stringp from)
460 (let ((idx 0))
461 (while (setq idx (string-match "[^\000-\177]" from idx))
462 (setq char (aref from idx)
463 charset (char-charset char))
251d4f4b
KH
464 (if (eq charset 'unknown)
465 (setq char (match-string 0)))
14333e31
KH
466 (if (or (memq charset '(unknown
467 eight-bit-control eight-bit-graphic))
251d4f4b 468 (not (or (eq excludes t) (memq charset excludes))))
51ed58ea
KH
469 (let ((slot (assq charset chars)))
470 (if slot
471 (if (not (memq char (nthcdr 2 slot)))
472 (let ((count (nth 1 slot)))
473 (setcar (cdr slot) (1+ count))
474 (if (or (not maxcount) (< count maxcount))
475 (nconc slot (list char)))))
476 (setq chars (cons (list charset 1 char) chars)))))
477 (setq idx (1+ idx))))
478 (save-excursion
479 (goto-char from)
480 (while (re-search-forward "[^\000-\177]" to t)
481 (setq char (preceding-char)
482 charset (char-charset char))
251d4f4b
KH
483 (if (eq charset 'unknown)
484 (setq char (match-string 0)))
14333e31 485 (if (or (memq charset '(unknown eight-bit-control eight-bit-graphic))
251d4f4b 486 (not (or (eq excludes t) (memq charset excludes))))
51ed58ea
KH
487 (let ((slot (assq charset chars)))
488 (if slot
251d4f4b 489 (if (not (member char (nthcdr 2 slot)))
51ed58ea
KH
490 (let ((count (nth 1 slot)))
491 (setcar (cdr slot) (1+ count))
492 (if (or (not maxcount) (< count maxcount))
493 (nconc slot (list char)))))
494 (setq chars (cons (list charset 1 char) chars))))))))
495 (nreverse chars)))
496
c83c4f60
RS
497(defvar last-coding-system-specified nil
498 "Most recent coding system explicitly specified by the user when asked.
499This variable is set whenever Emacs asks the user which coding system
500to use in order to write a file. If you set it to nil explicitly,
501then call `write-region', then afterward this variable will be non-nil
502only if the user was explicitly asked and specified a coding system.")
503
b5edd1d1
KH
504(defvar select-safe-coding-system-accept-default-p nil
505 "If non-nil, a function to control the behaviour of coding system selection.
506The meaning is the same as the argument ACCEPT-DEFAULT-P of the
507function `select-safe-coding-system' (which see). This variable
508overrides that argument.")
509
510(defun select-safe-coding-system (from to &optional default-coding-system
511 accept-default-p)
d5266ddf
KH
512 "Ask a user to select a safe coding system from candidates.
513The candidates of coding systems which can safely encode a text
b5edd1d1
KH
514between FROM and TO are shown in a popup window. Among them, the most
515proper one is suggested as the default.
516
517The list of `buffer-file-coding-system' of the current buffer and the
518most preferred coding system (if it corresponds to a MIME charset) is
519treated as the default coding system list. Among them, the first one
520that safely encodes the text is silently selected and returned without
521any user interaction. See also the command `prefer-coding-system'.
54b226f7 522
b5edd1d1
KH
523Optional 3rd arg DEFAULT-CODING-SYSTEM specifies a coding system or a
524list of coding systems to be prepended to the default coding system
525list.
54b226f7 526
b5edd1d1
KH
527Optional 4th arg ACCEPT-DEFAULT-P, if non-nil, is a function to
528determine the acceptability of the silently selected coding system.
529It is called with that coding system, and should return nil if it
530should not be silently selected and thus user interaction is required.
531
532The variable `select-safe-coding-system-accept-default-p', if
533non-nil, overrides ACCEPT-DEFAULT-P.
54b226f7
KH
534
535Kludgy feature: if FROM is a string, the string is the target text,
536and TO is ignored."
b5edd1d1
KH
537 (if (and default-coding-system
538 (not (listp default-coding-system)))
539 (setq default-coding-system (list default-coding-system)))
540
541 ;; Change elements of the list to (coding . base-coding).
542 (setq default-coding-system
543 (mapcar (function (lambda (x) (cons x (coding-system-base x))))
544 default-coding-system))
545
546 ;; If buffer-file-coding-system is not nil nor undecided, append it
547 ;; to the defaults.
548 (if buffer-file-coding-system
549 (let ((base (coding-system-base buffer-file-coding-system)))
550 (or (eq base 'undecided)
551 (assq buffer-file-coding-system default-coding-system)
552 (rassq base default-coding-system)
e56d7900 553 (setq default-coding-system
b5edd1d1
KH
554 (append default-coding-system
555 (list (cons buffer-file-coding-system base)))))))
556
557 ;; If the most preferred coding system has the property mime-charset,
558 ;; append it to the defaults.
c24e49a8
KH
559 (let ((tail coding-category-list)
560 preferred base)
561 (while (and tail
562 (not (setq preferred (symbol-name (car tail)))))
563 (setq tail (cdr tail)))
564 (and (coding-system-p preferred)
565 (setq base (coding-system-base preferred))
566 (coding-system-get preferred 'mime-charset)
b5edd1d1
KH
567 (not (assq preferred default-coding-system))
568 (not (rassq base default-coding-system))
569 (setq default-coding-system
570 (append default-coding-system (list (cons preferred base))))))
571
572 (if select-safe-coding-system-accept-default-p
573 (setq accept-default-p select-safe-coding-system-accept-default-p))
574
575 (let ((codings (find-coding-systems-region from to))
576 (coding-system nil)
577 (l default-coding-system))
578 (if (eq (car codings) 'undecided)
579 ;; Any coding system is ok.
580 (setq coding-system t)
581 ;; Try the defaults.
582 (while (and l (not coding-system))
583 (if (memq (cdr (car l)) codings)
584 (setq coding-system (car (car l)))
585 (setq l (cdr l))))
586 (if (and coding-system accept-default-p)
587 (or (funcall accept-default-p coding-system)
588 (setq coding-system (list coding-system)))))
589
590 ;; If all the defaults failed, ask a user.
591 (when (or (not coding-system) (consp coding-system))
34104362 592 ;; At first, change each coding system to the corresponding
b5edd1d1
KH
593 ;; mime-charset name if it is also a coding system. Such a name
594 ;; is more friendly to users.
595 (let ((l codings)
34104362
KH
596 mime-charset)
597 (while l
598 (setq mime-charset (coding-system-get (car l) 'mime-charset))
599 (if (and mime-charset (coding-system-p mime-charset))
600 (setcar l mime-charset))
601 (setq l (cdr l))))
602
b5edd1d1
KH
603 ;; Then ask users to select one form CODINGS.
604 (unwind-protect
605 (save-window-excursion
606 (with-output-to-temp-buffer "*Warning*"
607 (save-excursion
608 (set-buffer standard-output)
a672b7cd
KH
609 (if (not default-coding-system)
610 (insert "No default coding systems to try.")
611 (insert "These default coding systems were tried")
612 (if (stringp from)
613 (insert " to encode \""
614 (if (> (length from) 10)
615 (substring from 0 10)
616 from)
617 "...\""))
618 (insert ":\n")
619 (let ((pos (point))
620 (fill-prefix " "))
621 (mapcar (function (lambda (x)
622 (princ " ") (princ (car x))))
623 default-coding-system)
624 (insert "\n")
625 (fill-region-as-paragraph pos (point)))
626 (insert
627 (if (consp coding-system)
628 (concat (format "%s safely encodes the target text,\n"
629 (car coding-system))
630 "but it is not recommended for encoding text in this context,\n"
631 "e.g., for sending an email message.\n")
632 "However, none of them safely encodes the target text.\n")))
b5edd1d1 633 (insert (if (consp coding-system)
2f1fa038
EZ
634 "\nSelect the above, or "
635 "\nSelect ")
636 "one of the following safe coding systems:\n")
b5edd1d1
KH
637 (let ((pos (point))
638 (fill-prefix " "))
639 (mapcar (function (lambda (x) (princ " ") (princ x)))
640 codings)
641 (insert "\n")
642 (fill-region-as-paragraph pos (point)))))
643
644 ;; Read a coding system.
645 (if (consp coding-system)
646 (setq codings (cons (car coding-system) codings)))
647 (let* ((safe-names (mapcar (lambda (x) (list (symbol-name x)))
648 codings))
649 (name (completing-read
650 (format "Select coding system (default %s): "
651 (car codings))
652 safe-names nil t nil nil
653 (car (car safe-names)))))
654 (setq last-coding-system-specified (intern name)
655 coding-system last-coding-system-specified)))
656 (kill-buffer "*Warning*")))
657
658 (if (vectorp (coding-system-eol-type coding-system))
659 (let ((eol (coding-system-eol-type buffer-file-coding-system)))
660 (if (numberp eol)
661 (setq coding-system
662 (coding-system-change-eol-conversion coding-system eol)))))
663
664 (if (eq coding-system t)
665 (setq coding-system buffer-file-coding-system))
e56d7900 666 coding-system))
54b226f7
KH
667
668(setq select-safe-coding-system-function 'select-safe-coding-system)
669
46babb23
KH
670(defun select-message-coding-system ()
671 "Return a coding system to encode the outgoing message of the current buffer.
672It at first tries the first coding system found in these variables
673in this order:
674 (1) local value of `buffer-file-coding-system'
675 (2) value of `sendmail-coding-system'
b5edd1d1
KH
676 (3) value of `default-sendmail-coding-system'
677 (4) value of `default-buffer-file-coding-system'
46babb23
KH
678If the found coding system can't encode the current buffer,
679or none of them are bound to a coding system,
48e41165 680it asks the user to select a proper coding system."
46babb23 681 (let ((coding (or (and (local-variable-p 'buffer-file-coding-system)
b5edd1d1
KH
682 buffer-file-coding-system)
683 sendmail-coding-system
684 default-sendmail-coding-system
685 default-buffer-file-coding-system)))
46babb23
KH
686 (if (eq coding 'no-conversion)
687 ;; We should never use no-conversion for outgoing mails.
688 (setq coding nil))
689 (if (fboundp select-safe-coding-system-function)
690 (funcall select-safe-coding-system-function
b5edd1d1
KH
691 (point-min) (point-max) coding
692 (function (lambda (x) (coding-system-get x 'mime-charset))))
46babb23 693 coding)))
4ed46869 694\f
03c35c83 695;;; Language support stuff.
4ed46869 696
4ed46869 697(defvar language-info-alist nil
2c395d56 698 "Alist of language environment definitions.
4ed46869
KH
699Each element looks like:
700 (LANGUAGE-NAME . ((KEY . INFO) ...))
2c395d56
RS
701where LANGUAGE-NAME is a string, the name of the language environment,
702KEY is a symbol denoting the kind of information, and
703INFO is the data associated with KEY.
704Meaningful values for KEY include
705
706 documentation value is documentation of what this language environment
707 is meant for, and how to use it.
708 charset value is a list of the character sets used by this
709 language environment.
710 sample-text value is one line of text,
711 written using those character sets,
712 appropriate for this language environment.
713 setup-function value is a function to call to switch to this
714 language environment.
715 exit-function value is a function to call to leave this
716 language environment.
717 coding-system value is a list of coding systems that are good
718 for saving text written in this language environment.
719 This list serves as suggestions to the user;
720 in effect, as a kind of documentation.
721 coding-priority value is a list of coding systems for this language
722 environment, in order of decreasing priority.
723 This is used to set up the coding system priority
45d08cb2 724 list when you switch to this language environment.
ddb5c041 725 nonascii-translation
7624ebb9 726 value is a translation table to be set in the
45d08cb2 727 variable `nonascii-translation-table' in this
7624ebb9
KH
728 language environment, or a character set from
729 which `nonascii-insert-offset' is calculated.
ddb5c041
KH
730 input-method value is a default input method for this language
731 environment.
7624ebb9
KH
732 features value is a list of features requested in this
733 language environment.
ddb5c041
KH
734
735The following keys take effect only when multibyte characters are
736globally disabled, i.e. the value of `default-enable-multibyte-characters'
737is nil.
738
739 unibyte-syntax value is a library name to load to set
e8dd0160 740 unibyte 8-bit character syntaxes for this
ddb5c041
KH
741 language environment.
742
743 unibyte-display value is a coding system to encode characters
744 for the terminal. Characters in the range
745 of 160 to 255 display not as octal escapes,
746 but as non-ASCII characters in this language
747 environment.")
2c395d56
RS
748
749(defun get-language-info (lang-env key)
750 "Return information listed under KEY for language environment LANG-ENV.
751KEY is a symbol denoting the kind of information.
752For a list of useful values for KEY and their meanings,
753see `language-info-alist'."
754 (if (symbolp lang-env)
755 (setq lang-env (symbol-name lang-env)))
756 (let ((lang-slot (assoc-ignore-case lang-env language-info-alist)))
4ed46869
KH
757 (if lang-slot
758 (cdr (assq key (cdr lang-slot))))))
759
f08adf27 760(defun set-language-info (lang-env key info)
2c395d56
RS
761 "Modify part of the definition of language environment LANG-ENV.
762Specifically, this stores the information INFO under KEY
763in the definition of this language environment.
4ed46869 764KEY is a symbol denoting the kind of information.
2c395d56 765INFO is the value for that information.
281d03ec 766
2c395d56 767For a list of useful values for KEY and their meanings,
f08adf27 768see `language-info-alist'."
2c395d56
RS
769 (if (symbolp lang-env)
770 (setq lang-env (symbol-name lang-env)))
4ed46869 771 (let (lang-slot key-slot)
2c395d56 772 (setq lang-slot (assoc lang-env language-info-alist))
4ed46869 773 (if (null lang-slot) ; If no slot for the language, add it.
2c395d56 774 (setq lang-slot (list lang-env)
4ed46869
KH
775 language-info-alist (cons lang-slot language-info-alist)))
776 (setq key-slot (assq key lang-slot))
777 (if (null key-slot) ; If no slot for the key, add it.
778 (progn
779 (setq key-slot (list key))
780 (setcdr lang-slot (cons key-slot (cdr lang-slot)))))
cda74479 781 (setcdr key-slot (purecopy info))))
4ed46869 782
2c395d56
RS
783(defun set-language-info-alist (lang-env alist &optional parents)
784 "Store ALIST as the definition of language environment LANG-ENV.
785ALIST is an alist of KEY and INFO values. See the documentation of
98c6d6ed 786`language-info-alist' for the meanings of KEY and INFO.
54b226f7 787
2c395d56
RS
788Optional arg PARENTS is a list of parent menu names; it specifies
789where to put this language environment in the
790Describe Language Environment and Set Language Environment menus.
791For example, (\"European\") means to put this language environment
792in the European submenu in each of those two menus."
793 (if (symbolp lang-env)
794 (setq lang-env (symbol-name lang-env)))
54b226f7
KH
795 (let ((describe-map describe-language-environment-map)
796 (setup-map setup-language-environment-map))
797 (if parents
798 (let ((l parents)
9deed82f 799 map parent-symbol parent prompt)
54b226f7
KH
800 (while l
801 (if (symbolp (setq parent-symbol (car l)))
802 (setq parent (symbol-name parent))
803 (setq parent parent-symbol parent-symbol (intern parent)))
804 (setq map (lookup-key describe-map (vector parent-symbol)))
9deed82f
EZ
805 ;; This prompt string is for define-prefix-command, so
806 ;; that the map it creates will be suitable for a menu.
807 (or map (setq prompt (format "%s Environment" parent)))
54b226f7
KH
808 (if (not map)
809 (progn
810 (setq map (intern (format "describe-%s-environment-map"
811 (downcase parent))))
9deed82f 812 (define-prefix-command map nil prompt)
54b226f7
KH
813 (define-key-after describe-map (vector parent-symbol)
814 (cons parent map) t)))
815 (setq describe-map (symbol-value map))
816 (setq map (lookup-key setup-map (vector parent-symbol)))
817 (if (not map)
818 (progn
819 (setq map (intern (format "setup-%s-environment-map"
820 (downcase parent))))
9deed82f 821 (define-prefix-command map nil prompt)
54b226f7
KH
822 (define-key-after setup-map (vector parent-symbol)
823 (cons parent map) t)))
824 (setq setup-map (symbol-value map))
825 (setq l (cdr l)))))
f08adf27
RS
826
827 ;; Set up menu items for this language env.
7624ebb9 828 (let ((doc (assq 'documentation alist)))
f08adf27
RS
829 (when doc
830 (define-key-after describe-map (vector (intern lang-env))
7624ebb9
KH
831 (cons lang-env 'describe-specified-language-support) t)))
832 (define-key-after setup-map (vector (intern lang-env))
833 (cons lang-env 'setup-specified-language-environment) t)
f08adf27 834
54b226f7 835 (while alist
f08adf27 836 (set-language-info lang-env (car (car alist)) (cdr (car alist)))
54b226f7 837 (setq alist (cdr alist)))))
4ed46869 838
ae302641 839(defun read-language-name (key prompt &optional default)
2c395d56 840 "Read a language environment name which has information for KEY.
ddb5c041 841If KEY is nil, read any language environment.
2c395d56
RS
842Prompt with PROMPT. DEFAULT is the default choice of language environment.
843This returns a language environment name as a string."
4ed46869
KH
844 (let* ((completion-ignore-case t)
845 (name (completing-read prompt
846 language-info-alist
ddb5c041
KH
847 (and key
848 (function (lambda (elm) (assq key elm))))
ae302641 849 t nil nil default)))
13e82c04 850 (if (and (> (length name) 0)
ddb5c041
KH
851 (or (not key)
852 (get-language-info name key)))
13e82c04 853 name)))
4ed46869
KH
854\f
855;;; Multilingual input methods.
d0c40faa
KH
856(defgroup leim nil
857 "LEIM: Libraries of Emacs Input Methods."
858 :group 'mule)
4ed46869 859
d0b9c3ab
KH
860(defconst leim-list-file-name "leim-list.el"
861 "Name of LEIM list file.
862This file contains a list of libraries of Emacs input methods (LEIM)
863in the format of Lisp expression for registering each input method.
864Emacs loads this file at startup time.")
865
2e224638
SM
866(defvar leim-list-header (format
867";;; %s -- list of LEIM (Library of Emacs Input Method)
d0b9c3ab
KH
868;;
869;; This file contains a list of LEIM (Library of Emacs Input Method)
e8dd0160 870;; in the same directory as this file. Loading this file registers
d0b9c3ab
KH
871;; the whole input methods in Emacs.
872;;
d33d5fbe 873;; Each entry has the form:
d0b9c3ab
KH
874;; (register-input-method
875;; INPUT-METHOD LANGUAGE-NAME ACTIVATE-FUNC
876;; TITLE DESCRIPTION
877;; ARG ...)
878;; See the function `register-input-method' for the meanings of arguments.
879;;
880;; If this directory is included in load-path, Emacs automatically
881;; loads this file at startup time.
882
883"
884 leim-list-file-name)
885 "Header to be inserted in LEIM list file.")
886
e55e92ee 887(defvar leim-list-entry-regexp "^(register-input-method"
d0b9c3ab
KH
888 "Regexp matching head of each entry in LEIM list file.
889See also the variable `leim-list-header'")
890
891(defvar update-leim-list-functions
892 '(quail-update-leim-list-file)
893 "List of functions to call to update LEIM list file.
894Each function is called with one arg, LEIM directory name.")
895
a337fe7f
RS
896(defun update-leim-list-file (&rest dirs)
897 "Update LEIM list file in directories DIRS."
d0b9c3ab
KH
898 (let ((functions update-leim-list-functions))
899 (while functions
a337fe7f 900 (apply (car functions) dirs)
d0b9c3ab
KH
901 (setq functions (cdr functions)))))
902
4ed46869
KH
903(defvar current-input-method nil
904 "The current input method for multilingual text.
96db204a 905If nil, that means no input method is activated now.")
4ed46869
KH
906(make-variable-buffer-local 'current-input-method)
907(put 'current-input-method 'permanent-local t)
908
909(defvar current-input-method-title nil
d0b9c3ab 910 "Title string of the current input method shown in mode line.")
4ed46869
KH
911(make-variable-buffer-local 'current-input-method-title)
912(put 'current-input-method-title 'permanent-local t)
913
b4fba33f 914(defcustom default-input-method nil
8861c593 915 "*Default input method for multilingual text (a string).
b4fba33f 916This is the input method activated automatically by the command
9b10b5a3 917`toggle-input-method' (\\[toggle-input-method])."
8861c593 918 :group 'mule
5806e8a6
GM
919 :type '(choice (const nil) string)
920 :set-after '(current-language-environment))
b4fba33f 921
0f835e87
KH
922(put 'input-method-function 'permanent-local t)
923
723a427a
KH
924(defvar input-method-history nil
925 "History list for some commands that read input methods.")
926(make-variable-buffer-local 'input-method-history)
927(put 'input-method-history 'permanent-local t)
4ed46869
KH
928
929(defvar inactivate-current-input-method-function nil
930 "Function to call for inactivating the current input method.
931Every input method should set this to an appropriate value when activated.
f17ccaee
KH
932This function is called with no argument.
933
934This function should never change the value of `current-input-method'.
935It is set to nil by the function `inactivate-input-method'.")
4ed46869
KH
936(make-variable-buffer-local 'inactivate-current-input-method-function)
937(put 'inactivate-current-input-method-function 'permanent-local t)
938
939(defvar describe-current-input-method-function nil
940 "Function to call for describing the current input method.
941This function is called with no argument.")
942(make-variable-buffer-local 'describe-current-input-method-function)
943(put 'describe-current-input-method-function 'permanent-local t)
944
d0b9c3ab 945(defvar input-method-alist nil
2c395d56 946 "Alist of input method names vs how to use them.
d0b9c3ab 947Each element has the form:
2c395d56
RS
948 (INPUT-METHOD LANGUAGE-ENV ACTIVATE-FUNC TITLE DESCRIPTION ARGS...)
949See the function `register-input-method' for the meanings of the elements.")
950
f08adf27 951(defun register-input-method (input-method lang-env &rest args)
2c395d56 952 "Register INPUT-METHOD as an input method for language environment ENV.
f08adf27 953INPUT-METHOD and LANG-ENV are symbols or strings.
d0b9c3ab 954
d0b9c3ab 955The remaining arguments are:
2c395d56
RS
956 ACTIVATE-FUNC, TITLE, DESCRIPTION, and ARGS...
957ACTIVATE-FUNC is a function to call to activate this method.
958TITLE is a string to show in the mode line when this method is active.
959DESCRIPTION is a string describing this method and what it is good for.
960The ARGS, if any, are passed as arguments to ACTIVATE-FUNC.
205814ee
KH
961All told, the arguments to ACTIVATE-FUNC are INPUT-METHOD and the ARGS.
962
963This function is mainly used in the file \"leim-list.el\" which is
964created at building time of emacs, registering all quail input methods
965contained in the emacs distribution.
966
967In case you want to register a new quail input method by yourself, be
968careful to use the same input method title as given in the third
969parameter of `quail-define-package' (if the values are different, the
970string specified in this function takes precedence).
971
972The commands `describe-input-method' and `list-input-methods' need
973this duplicated values to show some information about input methods
974without loading the affected quail packages."
f08adf27
RS
975 (if (symbolp lang-env)
976 (setq lang-env (symbol-name lang-env)))
4ef06f75
KH
977 (if (symbolp input-method)
978 (setq input-method (symbol-name input-method)))
f08adf27 979 (let ((info (cons lang-env args))
d0b9c3ab
KH
980 (slot (assoc input-method input-method-alist)))
981 (if slot
982 (setcdr slot info)
983 (setq slot (cons input-method info))
984 (setq input-method-alist (cons slot input-method-alist)))))
985
4d5ac029 986(defun read-input-method-name (prompt &optional default inhibit-null)
d0b9c3ab 987 "Read a name of input method from a minibuffer prompting with PROMPT.
4d5ac029
RS
988If DEFAULT is non-nil, use that as the default,
989 and substitute it into PROMPT at the first `%s'.
4ef06f75
KH
990If INHIBIT-NULL is non-nil, null input signals an error.
991
992The return value is a string."
4d5ac029
RS
993 (if default
994 (setq prompt (format prompt default)))
d0b9c3ab 995 (let* ((completion-ignore-case t)
723a427a
KH
996 ;; This binding is necessary because input-method-history is
997 ;; buffer local.
d0b9c3ab 998 (input-method (completing-read prompt input-method-alist
87505a98
RS
999 nil t nil 'input-method-history
1000 default)))
bf294e6e
KH
1001 (if (and input-method (symbolp input-method))
1002 (setq input-method (symbol-name input-method)))
d0b9c3ab
KH
1003 (if (> (length input-method) 0)
1004 input-method
1005 (if inhibit-null
43807b77 1006 (error "No valid input method is specified")))))
d0b9c3ab 1007
d0b9c3ab 1008(defun activate-input-method (input-method)
2c395d56
RS
1009 "Switch to input method INPUT-METHOD for the current buffer.
1010If some other input method is already active, turn it off first.
1011If INPUT-METHOD is nil, deactivate any current input method."
305a3cb6 1012 (if (and input-method (symbolp input-method))
4ef06f75 1013 (setq input-method (symbol-name input-method)))
723a427a
KH
1014 (if (and current-input-method
1015 (not (string= current-input-method input-method)))
305a3cb6 1016 (inactivate-input-method))
2c395d56 1017 (unless (or current-input-method (null input-method))
d0b9c3ab
KH
1018 (let ((slot (assoc input-method input-method-alist)))
1019 (if (null slot)
723a427a 1020 (error "Can't activate input method `%s'" input-method))
8efc03e1
KH
1021 (let ((func (nth 2 slot)))
1022 (if (functionp func)
1023 (apply (nth 2 slot) input-method (nthcdr 5 slot))
1024 (if (and (consp func) (symbolp (car func)) (symbolp (cdr func)))
1025 (progn
1026 (require (cdr func))
1027 (apply (car func) input-method (nthcdr 5 slot)))
1028 (error "Can't activate input method `%s'" input-method))))
d0b9c3ab 1029 (setq current-input-method input-method)
723a427a 1030 (setq current-input-method-title (nth 3 slot))
28885c0e
KH
1031 (unwind-protect
1032 (run-hooks 'input-method-activate-hook)
1033 (force-mode-line-update)))))
15b3e511 1034
15b3e511 1035(defun inactivate-input-method ()
f17ccaee 1036 "Turn off the current input method."
723a427a
KH
1037 (when current-input-method
1038 (if input-method-history
1039 (unless (string= current-input-method (car input-method-history))
1040 (setq input-method-history
1041 (cons current-input-method
1042 (delete current-input-method input-method-history))))
1043 (setq input-method-history (list current-input-method)))
1044 (unwind-protect
1045 (funcall inactivate-current-input-method-function)
15b3e511 1046 (unwind-protect
723a427a
KH
1047 (run-hooks 'input-method-inactivate-hook)
1048 (setq current-input-method nil
28885c0e
KH
1049 current-input-method-title nil)
1050 (force-mode-line-update)))))
4ed46869 1051
8b784951 1052(defun set-input-method (input-method)
2c395d56
RS
1053 "Select and activate input method INPUT-METHOD for the current buffer.
1054This also sets the default input method to the one you specify."
d0b9c3ab 1055 (interactive
723a427a 1056 (let* ((default (or (car input-method-history) default-input-method)))
42395763 1057 (list (read-input-method-name
87505a98 1058 (if default "Select input method (default %s): " "Select input method: ")
42395763 1059 default t))))
d0b9c3ab 1060 (activate-input-method input-method)
42395763 1061 (setq default-input-method input-method))
4ed46869
KH
1062
1063(defun toggle-input-method (&optional arg)
15b3e511 1064 "Turn on or off a multilingual text input method for the current buffer.
723a427a 1065
f2979bdb
KH
1066With no prefix argument, if an input method is currently activated,
1067turn it off. Otherwise, activate an input method -- the one most
1068recently used, or the one specified in `default-input-method', or
1069the one read from the minibuffer.
723a427a 1070
f2979bdb
KH
1071With a prefix argument, read an input method from the minibuffer and
1072turn it on.
723a427a 1073
f2979bdb
KH
1074The default is to use the most recent input method specified
1075\(not including the currently active input method, if any)."
4ed46869 1076 (interactive "P")
7ddbb5bc
RS
1077 (if (and current-input-method (not arg))
1078 (inactivate-input-method)
1079 (let ((default (or (car input-method-history) default-input-method)))
1080 (if (and arg default (equal current-input-method default)
1081 (> (length input-method-history) 1))
1082 (setq default (nth 1 input-method-history)))
723a427a
KH
1083 (activate-input-method
1084 (if (or arg (not default))
7ddbb5bc
RS
1085 (progn
1086 (read-input-method-name
1087 (if default "Input method (default %s): " "Input method: " )
1088 default t))
723a427a
KH
1089 default))
1090 (or default-input-method
1091 (setq default-input-method current-input-method)))))
d0b9c3ab
KH
1092
1093(defun describe-input-method (input-method)
2c395d56 1094 "Describe input method INPUT-METHOD."
d0b9c3ab
KH
1095 (interactive
1096 (list (read-input-method-name
1097 "Describe input method (default, current choice): ")))
78754934 1098 (if (and input-method (symbolp input-method))
4ef06f75 1099 (setq input-method (symbol-name input-method)))
d0b9c3ab
KH
1100 (if (null input-method)
1101 (describe-current-input-method)
464cc130
KH
1102 (let ((current current-input-method))
1103 (condition-case nil
1104 (progn
1105 (save-excursion
1106 (activate-input-method input-method)
1107 (describe-current-input-method))
1108 (activate-input-method current))
1109 (error
1110 (activate-input-method current)
1111 (with-output-to-temp-buffer "*Help*"
1112 (let ((elt (assoc input-method input-method-alist)))
1113 (princ (format
1114 "Input method: %s (`%s' in mode line) for %s\n %s\n"
1115 input-method (nth 3 elt) (nth 1 elt) (nth 4 elt))))))))))
d0b9c3ab
KH
1116
1117(defun describe-current-input-method ()
96db204a 1118 "Describe the input method currently in use."
4ed46869
KH
1119 (if current-input-method
1120 (if (and (symbolp describe-current-input-method-function)
1121 (fboundp describe-current-input-method-function))
1122 (funcall describe-current-input-method-function)
1123 (message "No way to describe the current input method `%s'"
f2979bdb 1124 current-input-method)
4ed46869 1125 (ding))
d0b9c3ab 1126 (error "No input method is activated now")))
4ed46869 1127
d3459641 1128(defun read-multilingual-string (prompt &optional initial-input input-method)
4ed46869
KH
1129 "Read a multilingual string from minibuffer, prompting with string PROMPT.
1130The input method selected last time is activated in minibuffer.
15b3e511 1131If optional second arg INITIAL-INPUT is non-nil, insert it in the minibuffer
d0b9c3ab
KH
1132initially.
1133Optional 3rd argument INPUT-METHOD specifies the input method
4ef06f75
KH
1134to be activated instead of the one selected last time. It is a symbol
1135or a string."
88d559ec
KH
1136 (setq input-method
1137 (or input-method
d3459641 1138 current-input-method
88d559ec
KH
1139 default-input-method
1140 (read-input-method-name "Input method: " nil t)))
3df60841 1141 (if (and input-method (symbolp input-method))
4ef06f75 1142 (setq input-method (symbol-name input-method)))
305a3cb6
KH
1143 (let ((prev-input-method current-input-method))
1144 (unwind-protect
1145 (progn
1146 (activate-input-method input-method)
1147 (read-string prompt initial-input nil nil t))
1148 (activate-input-method prev-input-method))))
4ed46869
KH
1149
1150;; Variables to control behavior of input methods. All input methods
1151;; should react to these variables.
1152
8efc03e1
KH
1153(defcustom input-method-verbose-flag 'default
1154 "*A flag to control extra guidance given by input methods.
1155The value should be nil, t, `complex-only', or `default'.
4ed46869 1156
cb29dfb6 1157The extra guidance is done by showing list of available keys in echo
8efc03e1
KH
1158area. When you use the input method in the minibuffer, the guidance
1159is shown at the bottom short window (split from the existing window).
c27c4ed8 1160
8efc03e1
KH
1161If the value is t, extra guidance is always given, if the value is
1162nil, extra guidance is always suppressed.
1163
1164If the value is `complex-only', only complex input methods such as
1165`chinese-py' and `japanese' give extra guidance.
1166
1167If the value is `default', complex input methods always give extra
1168guidance, but simple input methods give it only when you are not in
1169the minibuffer.
1170
1171See also the variable `input-method-highlight-flag'."
1172 :type '(choice (const t) (const nil) (const complex-only) (const default))
42395763
RS
1173 :group 'mule)
1174
1175(defcustom input-method-highlight-flag t
1176 "*If this flag is non-nil, input methods highlight partially-entered text.
1177For instance, while you are in the middle of a Quail input method sequence,
1178the text inserted so far is temporarily underlined.
8efc03e1
KH
1179The underlining goes away when you finish or abort the input method sequence.
1180See also the variable `input-method-verbose-flag'."
42395763
RS
1181 :type 'boolean
1182 :group 'mule)
4ed46869
KH
1183
1184(defvar input-method-activate-hook nil
f17ccaee
KH
1185 "Normal hook run just after an input method is activated.
1186
1187The variable `current-input-method' keeps the input method name
1188just activated.")
4ed46869
KH
1189
1190(defvar input-method-inactivate-hook nil
f17ccaee
KH
1191 "Normal hook run just after an input method is inactivated.
1192
1193The variable `current-input-method' still keeps the input method name
4d0e6a11 1194just inactivated.")
4ed46869
KH
1195
1196(defvar input-method-after-insert-chunk-hook nil
1197 "Normal hook run just after an input method insert some chunk of text.")
1198
dccca980
KH
1199(defvar input-method-exit-on-first-char nil
1200 "This flag controls a timing when an input method returns.
1201Usually, the input method does not return while there's a possibility
1202that it may find a different translation if a user types another key.
39e643e2
RS
1203But, it this flag is non-nil, the input method returns as soon as
1204the current key sequence gets long enough to have some valid translation.")
dccca980
KH
1205
1206(defvar input-method-use-echo-area nil
1207 "This flag controls how an input method shows an intermediate key sequence.
39e643e2
RS
1208Usually, the input method inserts the intermediate key sequence,
1209or candidate translations corresponding to the sequence,
1210at point in the current buffer.
1211But, if this flag is non-nil, it displays them in echo area instead.")
dccca980 1212
723a427a
KH
1213(defvar input-method-exit-on-invalid-key nil
1214 "This flag controls the behaviour of an input method on invalid key input.
1215Usually, when a user types a key which doesn't start any character
1216handled by the input method, the key is handled by turning off the
e8dd0160 1217input method temporarily. After that key, the input method is re-enabled.
723a427a
KH
1218But, if this flag is non-nil, the input method is never back on.")
1219
4ed46869 1220\f
8efc03e1
KH
1221(defvar set-language-environment-hook nil
1222 "Normal hook run after some language environment is set.
1223
1224When you set some hook function here, that effect usually should not
1225be inherited to another language environment. So, you had better set
1226another function in `exit-language-environment-hook' (which see) to
1227cancel the effect.")
1228
1229(defvar exit-language-environment-hook nil
1230 "Normal hook run after exiting from some language environment.
1231When this hook is run, the variable `current-language-environment'
1232is still bound to the language environment being exited.
1233
e8dd0160 1234This hook is mainly used for canceling the effect of
8efc03e1
KH
1235`set-language-environment-hook' (which-see).")
1236
b0648a00
RS
1237(put 'setup-specified-language-environment 'apropos-inhibit t)
1238
15b3e511 1239(defun setup-specified-language-environment ()
f08adf27 1240 "Switch to a specified language environment."
15b3e511 1241 (interactive)
f850d782 1242 (let (language-name)
15b3e511
KH
1243 (if (and (symbolp last-command-event)
1244 (or (not (eq last-command-event 'Default))
1245 (setq last-command-event 'English))
f850d782
RS
1246 (setq language-name (symbol-name last-command-event)))
1247 (set-language-environment language-name)
15b3e511 1248 (error "Bogus calling sequence"))))
4ed46869 1249
8861c593 1250(defcustom current-language-environment "English"
94d04df6 1251 "The last language environment specified with `set-language-environment'.
ebef6d93
KH
1252This variable should be set only with \\[customize], which is equivalent
1253to using the function `set-language-environment'."
94d04df6 1254 :link '(custom-manual "(emacs)Language Environments")
dff1aa24 1255 :set (lambda (symbol value) (set-language-environment value))
94d04df6
DL
1256 :get (lambda (x)
1257 (or (car-safe (assoc-ignore-case
1258 (if (symbolp current-language-environment)
1259 (symbol-name current-language-environment)
1260 current-language-environment)
1261 language-info-alist))
1262 "English"))
1263 :type (cons 'choice (mapcar (lambda (lang)
1264 (list 'const (car lang)))
1265 language-info-alist))
8861c593
RS
1266 :initialize 'custom-initialize-default
1267 :group 'mule
1268 :type 'string)
f850d782 1269
ddb5c041
KH
1270(defun reset-language-environment ()
1271 "Reset multilingual environment of Emacs to the default status.
1272
1273The default status is as follows:
1274
1275 The default value of buffer-file-coding-system is nil.
1276 The default coding system for process I/O is nil.
1277 The default value for the command `set-terminal-coding-system' is nil.
1278 The default value for the command `set-keyboard-coding-system' is nil.
1279
1280 The order of priorities of coding categories and the coding system
1281 bound to each category are as follows
1282 coding category coding system
1283 --------------------------------------------------
1284 coding-category-iso-8-2 iso-latin-1
1285 coding-category-iso-8-1 iso-latin-1
1286 coding-category-iso-7-tight iso-2022-jp
1287 coding-category-iso-7 iso-2022-7bit
1288 coding-category-iso-7-else iso-2022-7bit-lock
1289 coding-category-iso-8-else iso-2022-8bit-ss2
1290 coding-category-emacs-mule emacs-mule
1291 coding-category-raw-text raw-text
1292 coding-category-sjis japanese-shift-jis
1293 coding-category-big5 chinese-big5
1294 coding-category-ccl nil
e8dd0160 1295 coding-category-binary no-conversion
ddb5c041
KH
1296"
1297 (interactive)
1298 ;; This function formerly set default-enable-multibyte-characters to t,
1299 ;; but that is incorrect. It should not alter the unibyte/multibyte choice.
1300
1301 (setq coding-category-iso-7-tight 'iso-2022-jp
1302 coding-category-iso-7 'iso-2022-7bit
1303 coding-category-iso-8-1 'iso-latin-1
1304 coding-category-iso-8-2 'iso-latin-1
1305 coding-category-iso-7-else 'iso-2022-7bit-lock
1306 coding-category-iso-8-else 'iso-2022-8bit-ss2
1307 coding-category-emacs-mule 'emacs-mule
1308 coding-category-raw-text 'raw-text
1309 coding-category-sjis 'japanese-shift-jis
1310 coding-category-big5 'chinese-big5
9bfcd269
KH
1311 coding-category-utf-8 nil
1312 coding-category-utf-16-be nil
1313 coding-category-utf-16-le nil
ddb5c041
KH
1314 coding-category-ccl nil
1315 coding-category-binary 'no-conversion)
1316
1317 (set-coding-priority
1318 '(coding-category-iso-8-1
1319 coding-category-iso-8-2
1320 coding-category-iso-7-tight
1321 coding-category-iso-7
1322 coding-category-iso-7-else
1323 coding-category-iso-8-else
1324 coding-category-emacs-mule
1325 coding-category-raw-text
1326 coding-category-sjis
1327 coding-category-big5
1328 coding-category-ccl
9bfcd269
KH
1329 coding-category-binary
1330 coding-category-utf-16-be
1331 coding-category-utf-16-le
1332 coding-category-utf-8))
ddb5c041 1333
91693d18
KH
1334 (update-coding-systems-internal)
1335
ddb5c041 1336 (set-default-coding-systems nil)
b5edd1d1 1337 (setq default-sendmail-coding-system 'iso-latin-1)
0c47a7c8 1338 (setq default-process-coding-system '(undecided . iso-latin-1))
b5edd1d1 1339
ddb5c041
KH
1340 ;; Don't alter the terminal and keyboard coding systems here.
1341 ;; The terminal still supports the same coding system
1342 ;; that it supported a minute ago.
1343;;; (set-terminal-coding-system-internal nil)
1344;;; (set-keyboard-coding-system-internal nil)
1345
1346 (setq nonascii-translation-table nil
1347 nonascii-insert-offset 0))
1348
0c47a7c8
KH
1349(reset-language-environment)
1350
40c81f74
PE
1351(defun set-display-table-and-terminal-coding-system (language-name)
1352 "Set up the display table and terminal coding system for LANGUAGE-NAME."
1353 (let ((coding (get-language-info language-name 'unibyte-display)))
1354 (if coding
1355 (standard-display-european-internal)
1356 (standard-display-default (if (eq window-system 'pc) 128 160) 255)
1357 (aset standard-display-table 146 nil))
1358 (or (eq window-system 'pc)
1359 (set-terminal-coding-system coding))))
1360
166246f7 1361(defun set-language-environment (language-name)
6c05d680
RS
1362 "Set up multi-lingual environment for using LANGUAGE-NAME.
1363This sets the coding system priority and the default input method
8861c593
RS
1364and sometimes other things. LANGUAGE-NAME should be a string
1365which is the name of a language environment. For example, \"Latin-1\"
1366specifies the character set for the major languages of Western Europe."
8efc03e1 1367 (interactive (list (read-language-name
ddb5c041 1368 nil
8efc03e1 1369 "Set language environment (default, English): ")))
4ef06f75
KH
1370 (if language-name
1371 (if (symbolp language-name)
1372 (setq language-name (symbol-name language-name)))
1373 (setq language-name "English"))
ddb5c041 1374 (or (assoc-ignore-case language-name language-info-alist)
f850d782 1375 (error "Language environment not defined: %S" language-name))
8efc03e1
KH
1376 (if current-language-environment
1377 (let ((func (get-language-info current-language-environment
1378 'exit-function)))
e63645c2
KH
1379 (run-hooks 'exit-language-environment-hook)
1380 (if (fboundp func) (funcall func))))
03c35c83
EZ
1381 (let ((default-eol-type (coding-system-eol-type
1382 default-buffer-file-coding-system)))
1383 (reset-language-environment)
ddb5c041 1384
03c35c83
EZ
1385 (setq current-language-environment language-name)
1386 (set-language-environment-coding-systems language-name default-eol-type))
ddb5c041
KH
1387 (let ((input-method (get-language-info language-name 'input-method)))
1388 (when input-method
1389 (setq default-input-method input-method)
1390 (if input-method-history
1391 (setq input-method-history
1392 (cons input-method
1393 (delete input-method input-method-history))))))
ec241f58
EZ
1394 (let ((nonascii (get-language-info language-name 'nonascii-translation))
1395 (dos-table
4e2ac2d9
EZ
1396 (if (eq window-system 'pc)
1397 (intern
d9c0a50e 1398 (format "cp%d-nonascii-translation-table" dos-codepage)))))
03c35c83
EZ
1399 (cond
1400 ((char-table-p nonascii)
1401 (setq nonascii-translation-table nonascii))
ec241f58 1402 ((and (eq window-system 'pc) (boundp dos-table))
03c35c83
EZ
1403 ;; DOS terminals' default is to use a special non-ASCII translation
1404 ;; table as appropriate for the installed codepage.
ec241f58 1405 (setq nonascii-translation-table (symbol-value dos-table)))
03c35c83
EZ
1406 ((charsetp nonascii)
1407 (setq nonascii-insert-offset (- (make-char nonascii) 128)))))
ddb5c041 1408
63283a8f 1409 ;; Unibyte setups if necessary.
ddb5c041 1410 (unless default-enable-multibyte-characters
63283a8f 1411 ;; Syntax and case table.
ddb5c041
KH
1412 (let ((syntax (get-language-info language-name 'unibyte-syntax)))
1413 (if syntax
1414 (let ((set-case-syntax-set-multibyte nil))
63283a8f
KH
1415 (load syntax nil t))
1416 ;; No information for syntax and case. Reset to the defaults.
1417 (let ((syntax-table (standard-syntax-table))
1418 (case-table (standard-case-table))
03c35c83 1419 (ch (if (eq window-system 'pc) 128 160)))
63283a8f
KH
1420 (while (< ch 256)
1421 (modify-syntax-entry ch " " syntax-table)
1422 (aset case-table ch ch)
1423 (setq ch (1+ ch)))
1424 (set-char-table-extra-slot case-table 0 nil)
1425 (set-char-table-extra-slot case-table 1 nil)
1426 (set-char-table-extra-slot case-table 2 nil))
1427 (set-standard-case-table (standard-case-table))
1428 (let ((list (buffer-list)))
1429 (while list
1430 (with-current-buffer (car list)
1431 (set-case-table (standard-case-table)))
1432 (setq list (cdr list))))))
40c81f74 1433 (set-display-table-and-terminal-coding-system language-name))
ddb5c041
KH
1434
1435 (let ((required-features (get-language-info language-name 'features)))
1436 (while required-features
1437 (require (car required-features))
1438 (setq required-features (cdr required-features))))
1439 (let ((func (get-language-info language-name 'setup-function)))
1440 (if (fboundp func)
1441 (funcall func)))
8efc03e1 1442 (run-hooks 'set-language-environment-hook)
f850d782 1443 (force-mode-line-update t))
4ed46869 1444
51a8fc1d
RS
1445(defun standard-display-european-internal ()
1446 ;; Actually set up direct output of non-ASCII characters.
03c35c83
EZ
1447 (standard-display-8bit (if (eq window-system 'pc) 128 160) 255)
1448 ;; Unibyte Emacs on MS-DOS wants to display all 8-bit characters with
1449 ;; the native font, and codes 160 and 146 stand for something very
1450 ;; different there.
1451 (or (and (eq window-system 'pc) (not default-enable-multibyte-characters))
1452 (progn
1453 ;; Make non-line-break space display as a plain space.
1454 ;; Most X fonts do the wrong thing for code 160.
1455 (aset standard-display-table 160 [32])
1492f7ac
DL
1456 ;; With luck, non-Latin-1 fonts are more recent and so don't
1457 ;; have this bug.
1458 (aset standard-display-table 2208 [32]) ; Latin-1 NBSP
1459 ;; Most Windows programs send out apostrophes as \222. Most X fonts
03c35c83 1460 ;; don't contain a character at that position. Map it to the ASCII
1492f7ac
DL
1461 ;; apostrophe. [This is actually RIGHT SINGLE QUOTATION MARK
1462 ;; from the cp1252, aka Windows-1252 character set. --fx]
03c35c83
EZ
1463 (aset standard-display-table 146 [39]))))
1464
1465(defun set-language-environment-coding-systems (language-name
1466 &optional eol-type)
1467 "Do various coding system setups for language environment LANGUAGE-NAME.
1468
1469The optional arg EOL-TYPE specifies the eol-type of the default value
1470of buffer-file-coding-system set by this function."
54b226f7
KH
1471 (let* ((priority (get-language-info language-name 'coding-priority))
1472 (default-coding (car priority)))
1473 (if priority
1474 (let ((categories (mapcar 'coding-system-category priority)))
03c35c83
EZ
1475 (set-default-coding-systems
1476 (if (memq eol-type '(0 1 2 unix dos mac))
1477 (coding-system-change-eol-conversion default-coding eol-type)
1478 default-coding))
46babb23 1479 (setq default-sendmail-coding-system default-coding)
54b226f7
KH
1480 (set-coding-priority categories)
1481 (while priority
1482 (set (car categories) (car priority))
1483 (setq priority (cdr priority) categories (cdr categories)))
45d08cb2 1484 (update-coding-systems-internal)))))
54b226f7 1485
4ed46869
KH
1486;; Print all arguments with `princ', then print "\n".
1487(defsubst princ-list (&rest args)
1488 (while args (princ (car args)) (setq args (cdr args)))
1489 (princ "\n"))
1490
b0648a00
RS
1491(put 'describe-specified-language-support 'apropos-inhibit t)
1492
48082651 1493;; Print a language specific information such as input methods,
13e82c04 1494;; charsets, and coding systems. This function is intended to be
48082651 1495;; called from the menu:
281d03ec 1496;; [menu-bar mule describe-language-environment LANGUAGE]
48082651
KH
1497;; and should not run it by `M-x describe-current-input-method-function'.
1498(defun describe-specified-language-support ()
96db204a 1499 "Describe how Emacs supports the specified language environment."
48082651 1500 (interactive)
281d03ec 1501 (let (language-name)
48082651 1502 (if (not (and (symbolp last-command-event)
cda74479
DL
1503 (or (not (eq last-command-event 'Default))
1504 (setq last-command-event 'English))
281d03ec 1505 (setq language-name (symbol-name last-command-event))))
48082651 1506 (error "Bogus calling sequence"))
281d03ec
RS
1507 (describe-language-environment language-name)))
1508
1509(defun describe-language-environment (language-name)
1510 "Describe how Emacs supports language environment LANGUAGE-NAME."
78754934
KH
1511 (interactive
1512 (list (read-language-name
1513 'documentation
8adfa8be 1514 "Describe language environment (default, current choice): ")))
f850d782
RS
1515 (if (null language-name)
1516 (setq language-name current-language-environment))
281d03ec
RS
1517 (if (or (null language-name)
1518 (null (get-language-info language-name 'documentation)))
1519 (error "No documentation for the specified language"))
4ef06f75
KH
1520 (if (symbolp language-name)
1521 (setq language-name (symbol-name language-name)))
464cc130
KH
1522 (let ((doc (get-language-info language-name 'documentation))
1523 pos)
48082651 1524 (with-output-to-temp-buffer "*Help*"
464cc130
KH
1525 (save-excursion
1526 (set-buffer standard-output)
1527 (insert language-name " language environment\n\n")
1528 (if (stringp doc)
1529 (insert doc "\n\n"))
e036b0a6
KH
1530 (condition-case nil
1531 (let ((str (eval (get-language-info language-name 'sample-text))))
1532 (if (stringp str)
1533 (insert "Sample text:\n " str "\n\n")))
1534 (error nil))
464cc130
KH
1535 (let ((input-method (get-language-info language-name 'input-method))
1536 (l (copy-sequence input-method-alist)))
1537 (insert "Input methods")
1538 (when input-method
1539 (insert " (default, " input-method ")")
1540 (setq input-method (assoc input-method input-method-alist))
1541 (setq l (cons input-method (delete input-method l))))
1542 (insert ":\n")
48082651 1543 (while l
464cc130
KH
1544 (when (string= language-name (nth 1 (car l)))
1545 (insert " " (car (car l)))
1546 (search-backward (car (car l)))
1547 (help-xref-button 0 #'describe-input-method (car (car l))
1548 "mouse-2, RET: describe this input method")
1549 (goto-char (point-max))
2fa7e202
KH
1550 (insert " (\""
1551 (if (stringp (nth 3 (car l)))
1552 (nth 3 (car l))
1553 (car (nth 3 (car l))))
1554 "\" in mode line)\n"))
464cc130
KH
1555 (setq l (cdr l)))
1556 (insert "\n"))
1557 (insert "Character sets:\n")
1558 (let ((l (get-language-info language-name 'charset)))
1559 (if (null l)
1560 (insert " nothing specific to " language-name "\n")
1561 (while l
1562 (insert " " (symbol-name (car l)))
1563 (search-backward (symbol-name (car l)))
1564 (help-xref-button 0 #'describe-character-set (car l)
1565 "mouse-2, RET: describe this character set")
1566 (goto-char (point-max))
1567 (insert ": " (charset-description (car l)) "\n")
1568 (setq l (cdr l)))))
1569 (insert "\n")
1570 (insert "Coding systems:\n")
1571 (let ((l (get-language-info language-name 'coding-system)))
1572 (if (null l)
1573 (insert " nothing specific to " language-name "\n")
1574 (while l
1575 (insert " " (symbol-name (car l)))
1576 (search-backward (symbol-name (car l)))
1577 (help-xref-button 0 #'describe-coding-system (car l)
1578 "mouse-2, RET: describe this coding system")
1579 (goto-char (point-max))
1580 (insert " (`"
1581 (coding-system-mnemonic (car l))
1582 "' in mode line):\n\t"
1583 (coding-system-doc-string (car l))
1584 "\n")
1585 (let ((aliases (coding-system-get (car l)
1586 'alias-coding-systems)))
1587 (when aliases
1588 (insert "\t(alias:")
1589 (while aliases
1590 (insert " " (symbol-name (car aliases)))
1591 (setq aliases (cdr aliases)))
1592 (insert ")\n")))
1593 (setq l (cdr l)))))
1594 (help-setup-xref (list #'describe-language-environment language-name)
1595 (interactive-p))))))
4ed46869 1596\f
40c81f74
PE
1597;;; Locales.
1598
0d7c5bb9
DL
1599(defvar locale-translation-file-name nil
1600 "File name for the system's file of locale-name aliases, or nil if none.")
40c81f74
PE
1601
1602(defvar locale-language-names
1603 '(
1604 ;; UTF-8 is not yet implemented.
1605 ;; Put this first, so that e.g. "ko.UTF-8" does not match "ko" below.
1606 (".*[._]utf" . nil)
1607
1608 ;; Locale names of the form LANGUAGE[_TERRITORY][.CODESET][@MODIFIER]
1609 ;; as specified in the Single Unix Spec, Version 2.
1610 ;; LANGUAGE is a language code taken from ISO 639:1988 (E/F)
1611 ;; with additions from ISO 639/RA Newsletter No.1/1989;
1612 ;; see Internet RFC 2165 (1997-06).
1613 ;; TERRITORY is a country code taken from ISO 3166.
1614 ;; CODESET and MODIFIER are implementation-dependent.
1615 ;;
1616 ; aa Afar
1617 ; ab Abkhazian
6ececc4d 1618 ("af" . "Latin-1") ; Afrikaans
40c81f74
PE
1619 ("am" . "Ethiopic") ; Amharic
1620 ; ar Arabic
1621 ; as Assamese
1622 ; ay Aymara
1623 ; az Azerbaijani
1624 ; ba Bashkir
6ececc4d
PE
1625 ("be" . "Latin-5") ; Byelorussian
1626 ("bg" . "Latin-5") ; Bulgarian
40c81f74
PE
1627 ; bh Bihari
1628 ; bi Bislama
1629 ; bn Bengali, Bangla
1630 ("bo" . "Tibetan")
1631 ("br" . "Latin-1") ; Breton
1632 ("ca" . "Latin-1") ; Catalan
1633 ; co Corsican
1634 ("cs" . "Czech")
6ececc4d 1635 ("cy" . "Latin-8") ; Welsh
40c81f74
PE
1636 ("da" . "Latin-1") ; Danish
1637 ("de" . "German")
1638 ; dz Bhutani
1639 ("el" . "Greek")
6ececc4d
PE
1640 ;; Users who specify "en" explicitly typically want Latin-1, not ASCII.
1641 ("en" . "Latin-1") ; English
40c81f74 1642 ("eo" . "Latin-3") ; Esperanto
8c4b6822 1643 ("es" . "Spanish")
40c81f74
PE
1644 ("et" . "Latin-4") ; Estonian
1645 ("eu" . "Latin-1") ; Basque
1646 ; fa Persian
1647 ("fi" . "Latin-1") ; Finnish
1648 ; fj Fiji
1649 ("fo" . "Latin-1") ; Faroese
1650 ("fr" . "Latin-1") ; French
1651 ("fy" . "Latin-1") ; Frisian
6ececc4d
PE
1652 ("ga" . "Latin-1") ; Irish Gaelic (new orthography)
1653 ("gd" . "Latin-1") ; Scots Gaelic
1654 ("gl" . "Latin-1") ; Galician
40c81f74
PE
1655 ; gn Guarani
1656 ; gu Gujarati
1657 ; ha Hausa
1658 ("he" . "Hebrew")
1659 ("hi" . "Devanagari") ; Hindi
1660 ("hr" . "Latin-2") ; Croatian
1661 ("hu" . "Latin-2") ; Hungarian
1662 ; hy Armenian
1663 ; ia Interlingua
1664 ("id" . "Latin-1") ; Indonesian
1665 ; ie Interlingue
1666 ; ik Inupiak
1667 ("is" . "Latin-1") ; Icelandic
1668 ("it" . "Latin-1") ; Italian
1669 ; iu Inuktitut
1670 ("ja" . "Japanese")
1671 ; jw Javanese
1672 ; ka Georgian
1673 ; kk Kazakh
6ececc4d 1674 ("kl" . "Latin-1") ; Greenlandic
40c81f74
PE
1675 ; km Cambodian
1676 ; kn Kannada
1677 ("ko" . "Korean")
1678 ; ks Kashmiri
1679 ; ku Kurdish
1680 ; ky Kirghiz
1681 ("la" . "Latin-1") ; Latin
1682 ; ln Lingala
1683 ("lo" . "Lao") ; Laothian
1684 ("lt" . "Latin-4") ; Lithuanian
1685 ("lv" . "Latin-4") ; Latvian, Lettish
1686 ; mg Malagasy
1687 ; mi Maori
6ececc4d 1688 ("mk" . "Latin-5") ; Macedonian
40c81f74
PE
1689 ; ml Malayalam
1690 ; mn Mongolian
1691 ; mo Moldavian
1692 ("mr" . "Devanagari") ; Marathi
1693 ; ms Malay
1694 ("mt" . "Latin-3") ; Maltese
1695 ; my Burmese
1696 ; na Nauru
1697 ("ne" . "Devanagari") ; Nepali
8c4b6822 1698 ("nl" . "Dutch")
40c81f74
PE
1699 ("no" . "Latin-1") ; Norwegian
1700 ; oc Occitan
1701 ; om (Afan) Oromo
1702 ; or Oriya
1703 ; pa Punjabi
1704 ("pl" . "Latin-2") ; Polish
1705 ; ps Pashto, Pushto
1706 ("pt" . "Latin-1") ; Portuguese
1707 ; qu Quechua
6ececc4d 1708 ("rm" . "Latin-1") ; Rhaeto-Romanic
40c81f74
PE
1709 ; rn Kirundi
1710 ("ro" . "Romanian")
1711 ("ru.*[_.]koi8" . "Cyrillic-KOI8") ; Russian
6ececc4d 1712 ("ru" . "Latin-5") ; Russian
40c81f74
PE
1713 ; rw Kinyarwanda
1714 ("sa" . "Devanagari") ; Sanskrit
1715 ; sd Sindhi
1716 ; sg Sangho
1717 ("sh" . "Latin-2") ; Serbo-Croatian
1718 ; si Sinhalese
1719 ("sk" . "Slovak")
1720 ("sl" . "Slovenian")
1721 ; sm Samoan
1722 ; sn Shona
1723 ; so Somali
6ececc4d 1724 ("sq" . "Latin-1") ; Albanian
40c81f74
PE
1725 ("sr" . "Latin-2") ; Serbian (Latin alphabet)
1726 ; ss Siswati
1727 ; st Sesotho
1728 ; su Sundanese
1729 ("sv" . "Latin-1") ; Swedish
1730 ("sw" . "Latin-1") ; Swahili
1731 ; ta Tamil
1732 ; te Telugu
1733 ; tg Tajik
1734 ("th" . "Thai")
1735 ; ti Tigrinya
1736 ; tk Turkmen
6ececc4d 1737 ("tl" . "Latin-1") ; Tagalog
40c81f74
PE
1738 ; tn Setswana
1739 ; to Tonga
1740 ("tr" . "Latin-5") ; Turkish
1741 ; ts Tsonga
1742 ; tt Tatar
1743 ; tw Twi
1744 ; ug Uighur
6ececc4d 1745 ("uk" . "Latin-5") ; Ukrainian
40c81f74
PE
1746 ; ur Urdu
1747 ; uz Uzbek
1748 ("vi" . "Vietnamese")
1749 ; vo Volapuk
1750 ; wo Wolof
1751 ; xh Xhosa
1752 ; yi Yiddish
1753 ; yo Yoruba
1754 ; za Zhuang
1755 ("zh.*[._]big5" . "Chinese-BIG5")
1756 ("zh.*[._]gbk" . nil) ; Solaris 2.7; has gbk-0 as well as GB 2312.1980-0
1757 ("zh_tw" . "Chinese-CNS")
1758 ("zh" . "Chinese-GB")
1759 ; zu Zulu
1760
1761 ;; ISO standard locales
1762 ("c$" . "ASCII")
1763 ("posix$" . "ASCII")
1764
40c81f74
PE
1765 ;; The "IPA" Emacs language environment does not correspond
1766 ;; to any ISO 639 code, so let it stand for itself.
1767 ("ipa$" . "IPA")
1768
1769 ;; Nonstandard or obsolete language codes
1770 ("cz" . "Czech") ; e.g. Solaris 2.6
1771 ("ee" . "Latin-4") ; Estonian, e.g. X11R6.4
1772 ("iw" . "Hebrew") ; e.g. X11R6.4
6ececc4d 1773 ("sp" . "Latin-5") ; Serbian (Cyrillic alphabet), e.g. X11R6.4
40c81f74 1774 ("su" . "Latin-1") ; Finnish, e.g. Solaris 2.6
2e86ceaa 1775 ("jp" . "Japanese") ; e.g. MS Windows
40c81f74
PE
1776 )
1777 "List of pairs of locale regexps and language names.
6ececc4d
PE
1778The first element whose locale regexp matches the start of a downcased locale
1779specifies the language name corresponding to that locale.
40c81f74
PE
1780If the language name is nil, there is no corresponding language environment.")
1781
6ececc4d
PE
1782(defvar locale-charset-language-names
1783 '((".*8859[-_]?1\\>" . "Latin-1")
1784 (".*8859[-_]?2\\>" . "Latin-2")
1785 (".*8859[-_]?3\\>" . "Latin-3")
1786 (".*8859[-_]?4\\>" . "Latin-4")
1787 (".*8859[-_]?9\\>" . "Latin-5")
1788 (".*8859[-_]?14\\>" . "Latin-8")
1789 (".*8859[-_]?15\\>" . "Latin-9")
da645c53 1790 (".*@euro\\>" . "Latin-9")
6ececc4d
PE
1791 )
1792 "List of pairs of locale regexps and charset language names.
1793The first element whose locale regexp matches the start of a downcased locale
1794specifies the language name whose charsets corresponds to that locale.
1795This language name is used if its charsets disagree with the charsets of
1796the language name that would otherwise be used for this locale.")
1797
40c81f74
PE
1798(defvar locale-preferred-coding-systems
1799 '(("ja.*[._]euc" . japanese-iso-8bit)
1800 ("ja.*[._]jis7" . iso-2022-jp)
1801 ("ja.*[._]pck" . japanese-shift-jis)
1802 ("ja.*[._]sjis" . japanese-shift-jis)
40c81f74 1803 )
6ececc4d
PE
1804 "List of pairs of locale regexps and preferred coding systems.
1805The first element whose locale regexp matches the start of a downcased locale
1806specifies the coding system to prefer when using that locale.")
40c81f74
PE
1807
1808(defun locale-name-match (key alist)
1809 "Search for KEY in ALIST, which should be a list of regexp-value pairs.
1810Return the value corresponding to the first regexp that matches the
1811start of KEY, or nil if there is no match."
1812 (let (element)
1813 (while (and alist (not element))
1814 (if (string-match (concat "^\\(" (car (car alist)) "\\)") key)
1815 (setq element (car alist)))
1816 (setq alist (cdr alist)))
1817 (cdr element)))
1818
1819(defun set-locale-environment (locale-name)
1820 "Set up multi-lingual environment for using LOCALE-NAME.
1821This sets the coding system priority and the default input method
1822and sometimes other things. LOCALE-NAME should be a string
1823which is the name of a locale supported by the system;
1824often it is of the form xx_XX.CODE, where xx is a language,
1825XX is a country, and CODE specifies a character set and coding system.
1826For example, the locale name \"ja_JP.EUC\" might name a locale
1827for Japanese in Japan using the `japanese-iso-8bit' coding-system.
1828
1829If LOCALE-NAME is nil, its value is taken from the environment.
1830
1831The locale names supported by your system can typically be found in a
0812c1e8
DL
1832directory named `/usr/share/locale' or `/usr/lib/locale'. LOCALE-NAME
1833may be translated according to the table specified by
1834`locale-translation-file-name'.
1835
1836See also `locale-charset-language-names', `locale-language-names',
1837`locale-preferred-coding-systems' and `locale-coding-system'."
40c81f74 1838
0d7c5bb9
DL
1839 ;; Do this at runtime for the sake of binaries possibly transported
1840 ;; to a system without X.
1841 (setq locale-translation-file-name
1842 (let ((files
1843 '("/usr/lib/X11/locale/locale.alias" ; e.g. X11R6.4
1844 "/usr/X11R6/lib/X11/locale/locale.alias" ; e.g. RedHat 4.2
1845 "/usr/openwin/lib/locale/locale.alias" ; e.g. Solaris 2.6
1846 ;;
1847 ;; The following name appears after the X-related names above,
1848 ;; since the X-related names are what X actually uses.
1849 "/usr/share/locale/locale.alias" ; GNU/Linux sans X
1850 )))
1851 (while (and files (not (file-exists-p (car files))))
1852 (setq files (cdr files)))
1853 (car files)))
1854
40c81f74
PE
1855 (unless locale-name
1856 ;; Use the first of these three environment variables
1857 ;; that has a nonempty value.
1858 (let ((vars '("LC_ALL" "LC_CTYPE" "LANG")))
1859 (while (and vars (not (setq locale-name (getenv (car vars)))))
1860 (setq vars (cdr vars)))))
1861
1862 (when locale-name
1863
1864 ;; Translate "swedish" into "sv_SE.ISO8859-1", and so on,
1865 ;; using the translation file that many systems have.
1866 (when locale-translation-file-name
1867 (with-temp-buffer
1868 (insert-file-contents locale-translation-file-name)
1869 (when (re-search-forward
1870 (concat "^" (regexp-quote locale-name) ":?[ \t]+") nil t)
1871 (setq locale-name (buffer-substring (point) (line-end-position))))))
1872
1873 (setq locale-name (downcase locale-name))
1874
6ececc4d
PE
1875 (let ((language-name
1876 (locale-name-match locale-name locale-language-names))
1877 (charset-language-name
1878 (locale-name-match locale-name locale-charset-language-names))
1879 (coding-system
1880 (locale-name-match locale-name locale-preferred-coding-systems)))
1881
1882 (if (and charset-language-name
1883 (not
1884 (equal (get-language-info language-name 'charset)
1885 (get-language-info charset-language-name 'charset))))
1886 (setq language-name charset-language-name))
1887
40c81f74
PE
1888 (when language-name
1889
1890 ;; Set up for this character set. This is now the right way
1891 ;; to do it for both unibyte and multibyte modes.
1892 (set-language-environment language-name)
1893
1894 ;; If default-enable-multibyte-characters is nil,
1895 ;; we are using single-byte characters,
1896 ;; so the display table and terminal coding system are irrelevant.
1897 (when default-enable-multibyte-characters
1898 (set-display-table-and-terminal-coding-system language-name))
1899
1900 (setq locale-coding-system
1901 (car (get-language-info language-name 'coding-priority))))
1902
1903 (when coding-system
1904 (prefer-coding-system coding-system)
1905 (setq locale-coding-system coding-system)))))
1906\f
4ed46869
KH
1907;;; Charset property
1908
251d4f4b 1909(defun get-charset-property (charset propname)
4ed46869
KH
1910 "Return the value of CHARSET's PROPNAME property.
1911This is the last value stored with
96db204a 1912 (put-charset-property CHARSET PROPNAME VALUE)."
251d4f4b
KH
1913 (and (not (eq charset 'composition))
1914 (plist-get (charset-plist charset) propname)))
4ed46869 1915
251d4f4b 1916(defun put-charset-property (charset propname value)
4ed46869
KH
1917 "Store CHARSETS's PROPNAME property with value VALUE.
1918It can be retrieved with `(get-charset-property CHARSET PROPNAME)'."
1300d43f
KH
1919 (or (eq charset 'composition)
1920 (set-charset-plist charset
1921 (plist-put (charset-plist charset) propname value))))
4ed46869
KH
1922
1923;;; Character code property
1924(put 'char-code-property-table 'char-table-extra-slots 0)
1925
1926(defvar char-code-property-table
1927 (make-char-table 'char-code-property-table)
1928 "Char-table containing a property list of each character code.
1929
1930See also the documentation of `get-char-code-property' and
96db204a 1931`put-char-code-property'.")
4ed46869
KH
1932
1933(defun get-char-code-property (char propname)
1934 "Return the value of CHAR's PROPNAME property in `char-code-property-table'."
1935 (let ((plist (aref char-code-property-table char)))
1936 (if (listp plist)
1937 (car (cdr (memq propname plist))))))
1938
1939(defun put-char-code-property (char propname value)
1940 "Store CHAR's PROPNAME property with VALUE in `char-code-property-table'.
1941It can be retrieved with `(get-char-code-property CHAR PROPNAME)'."
1942 (let ((plist (aref char-code-property-table char)))
1943 (if plist
1944 (let ((slot (memq propname plist)))
1945 (if slot
1946 (setcar (cdr slot) value)
1947 (nconc plist (list propname value))))
1948 (aset char-code-property-table char (list propname value)))))
1949
a127b764
KH
1950\f
1951;; Pretty description of encoded string
1952
1953;; Alist of ISO 2022 control code vs the corresponding mnemonic string.
1954(defvar iso-2022-control-alist
1955 '((?\x1b . "ESC")
1956 (?\x0e . "SO")
1957 (?\x0f . "SI")
1958 (?\x8e . "SS2")
1959 (?\x8f . "SS3")
1960 (?\x9b . "CSI")))
1961
1962(defun encoded-string-description (str coding-system)
1963 "Return a pretty description of STR that is encoded by CODING-SYSTEM."
1964 (setq str (string-as-unibyte str))
993b2a7d 1965 (mapconcat
8c9d55a9 1966 (if (and coding-system (eq (coding-system-type coding-system) 2))
993b2a7d
KH
1967 ;; Try to get a pretty description for ISO 2022 escape sequences.
1968 (function (lambda (x) (or (cdr (assq x iso-2022-control-alist))
1969 (format "%02X" x))))
5de75f53 1970 (function (lambda (x) (format "0x%02X" x))))
993b2a7d 1971 str " "))
a127b764
KH
1972
1973(defun encode-coding-char (char coding-system)
1974 "Encode CHAR by CODING-SYSTEM and return the resulting string.
1975If CODING-SYSTEM can't safely encode CHAR, return nil."
bd953173
KH
1976 (let ((str1 (string-as-multibyte (char-to-string char)))
1977 (str2 (string-as-multibyte (make-string 2 char)))
a89f541b
KH
1978 (safe-chars (and coding-system
1979 (coding-system-get coding-system 'safe-chars)))
8c9d55a9 1980 (charset (char-charset char))
a127b764 1981 enc1 enc2 i1 i2)
a89f541b 1982 (when (or (eq safe-chars t)
8c9d55a9 1983 (eq charset 'ascii)
a89f541b 1984 (and safe-chars (aref safe-chars char)))
a127b764
KH
1985 ;; We must find the encoded string of CHAR. But, just encoding
1986 ;; CHAR will put extra control sequences (usually to designate
1987 ;; ASCII charaset) at the tail if type of CODING is ISO 2022.
1988 ;; To exclude such tailing bytes, we at first encode one-char
1989 ;; string and two-char string, then check how many bytes at the
1990 ;; tail of both encoded strings are the same.
1991
bd953173 1992 (setq enc1 (encode-coding-string str1 coding-system)
a127b764 1993 i1 (length enc1)
bd953173 1994 enc2 (encode-coding-string str2 coding-system)
a127b764
KH
1995 i2 (length enc2))
1996 (while (and (> i1 0) (= (aref enc1 (1- i1)) (aref enc2 (1- i2))))
1997 (setq i1 (1- i1) i2 (1- i2)))
1998
1999 ;; Now (substring enc1 i1) and (substring enc2 i2) are the same,
2000 ;; and they are the extra control sequences at the tail to
2001 ;; exclude.
2002 (substring enc2 0 i2))))
2003
2004
4ed46869 2005;;; mule-cmds.el ends here