Undo previous censorship changes.
[bpt/emacs.git] / lisp / international / mule.el
CommitLineData
4ed46869
KH
1;;; mule.el --- basic commands for mulitilingual environment
2
4ed46869
KH
3;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN.
4
5;; Keywords: mule, multilingual, character set, coding system
6
7;; This file is part of GNU Emacs.
8
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
369314dc
KH
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
4ed46869
KH
23
24;;; Code:
25
26(defconst mule-version "3.0 (MOMIJINOGA)" "\
27Version number and name of this version of MULE (multilingual environment).")
28
29(defconst mule-version-date "1998.1.1" "\
30Distribution date of this version of MULE (multilingual environment).")
31
32(defun load-with-code-conversion (fullname file &optional noerror nomessage)
33 "Execute a file of Lisp code named FILE whose absolute path is FULLNAME.
34The FILE is decoded before evaluation if necessary.
35If optional second arg NOERROR is non-nil,
36 report no error if FILE doesn't exist.
37Print messages at start and end of loading unless
38 optional third arg NOMESSAGE is non-nil.
39Return t if file exists."
40 (if (null (file-readable-p fullname))
41 (and (null noerror)
42 (signal 'file-error (list "Cannot open load file" file)))
43 ;; Read file with code conversion, and then eval.
44 (let* ((buffer
45 ;; To avoid any autoloading, set default-major-mode to
46 ;; fundamental-mode.
47 (let ((default-major-mode 'fundamental-mode))
48 ;; We can't use `generate-new-buffer' because files.el
49 ;; is not yet loaded.
50 (get-buffer-create (generate-new-buffer-name " *load*"))))
51 (load-in-progress t))
52 (or nomessage (message "Loading %s..." file))
53 (unwind-protect
54 (progn
55 (save-excursion
56 (set-buffer buffer)
57 (insert-file-contents fullname)
58 ;; We must set `buffer-file-name' for `eval-buffer' and
59 ;; `load-history'.
60 (setq buffer-file-name file)
61 ;; Make `kill-buffer' quiet.
62 (set-buffer-modified-p nil))
63 ;; Eval in the original buffer.
64 (eval-buffer buffer))
65 (kill-buffer buffer))
66 (let ((hook (assoc file after-load-alist)))
67 (if hook
68 (mapcar (function eval) (cdr hook))))
69 (or nomessage noninteractive
70 (message "Loading %s...done" file))
71 t)))
72
73;; API (Application Program Interface) for charsets.
74
75;; Return t if OBJ is a quoted symbol.
76(defsubst quoted-symbol-p (obj)
77 (and (listp obj) (eq (car obj) 'quote)))
78
79(defsubst charsetp (object)
80 "T is OBJECT is a charset."
81 (and (symbolp object) (vectorp (get object 'charset))))
82
83(defsubst charset-info (charset)
84 "Return a vector of information of CHARSET.
85The elements of the vector are:
86 CHARSET-ID, BYTES, DIMENSION, CHARS, WIDTH, DIRECTION,
87 LEADING-CODE-BASE, LEADING-CODE-EXT,
88 ISO-FINAL-CHAR, ISO-GRAPHIC-PLANE,
89 REVERSE-CHARSET, SHORT-NAME, LONG-NAME, DESCRIPTION,
90 PLIST,
91where
92CHARSET-ID (integer) is the identification number of the charset.
93DIMENSION (integer) is the number of bytes to represent a character of
94the charset: 1 or 2.
95CHARS (integer) is the number of characters in a dimension: 94 or 96.
96BYTE (integer) is the length of multi-byte form of a character in
97 the charset: one of 1, 2, 3, and 4.
98WIDTH (integer) is the number of columns a character in the charset
99 occupies on the screen: one of 0, 1, and 2.
100DIRECTION (integer) is the rendering direction of characters in the
101 charset when rendering. If 0, render from right to left, else
102 render from left to right.
103LEADING-CODE-BASE (integer) is the base leading-code for the
104 charset.
105LEADING-CODE-EXT (integer) is the extended leading-code for the
106 charset. All charsets of less than 0xA0 has the value 0.
107ISO-FINAL-CHAR (character) is the final character of the
108 corresponding ISO 2022 charset.
109ISO-GRAPHIC-PLANE (integer) is the graphic plane to be invoked
110 while encoding to variants of ISO 2022 coding system, one of the
111 following: 0/graphic-plane-left(GL), 1/graphic-plane-right(GR).
112REVERSE-CHARSET (integer) is the charset which differs only in
113 LEFT-TO-RIGHT value from the charset. If there's no such a
114 charset, the value is -1.
115SHORT-NAME (string) is the short name to refer to the charset.
116LONG-NAME (string) is the long name to refer to the charset
117DESCRIPTION (string) is the description string of the charset.
118PLIST (property list) may contain any type of information a user
119 want to put and get by functions `put-charset-property' and
120 `get-charset-property' respectively."
121 (get charset 'charset))
122
123(defmacro charset-id (charset)
124 "Return charset identification number of CHARSET."
125 (if (and (listp charset) (eq (car charset) 'quote))
126 (aref (charset-info (nth 1 charset)) 0)
127 `(aref (charset-info ,charset) 0)))
128
129(defmacro charset-bytes (charset)
130 (if (quoted-symbol-p charset)
131 (aref (charset-info (nth 1 charset)) 1)
132 `(aref (charset-info ,charset) 1)))
133
134(defmacro charset-dimension (charset)
135 (if (quoted-symbol-p charset)
136 (aref (charset-info (nth 1 charset)) 2)
137 `(aref (charset-info ,charset) 2)))
138
139(defmacro charset-chars (charset)
140 (if (quoted-symbol-p charset)
141 (aref (charset-info (nth 1 charset)) 3)
142 `(aref (charset-info ,charset) 3)))
143
144(defmacro charset-width (charset)
145 (if (quoted-symbol-p charset)
146 (aref (charset-info (nth 1 charset)) 4)
147 `(aref (charset-info ,charset) 4)))
148
149(defmacro charset-direction (charset)
150 (if (quoted-symbol-p charset)
151 (aref (charset-info (nth 1 charset)) 5)
152 `(aref (charset-info ,charset) 5)))
153
154(defmacro charset-iso-final-char (charset)
155 (if (quoted-symbol-p charset)
156 (aref (charset-info (nth 1 charset)) 8)
157 `(aref (charset-info ,charset) 8)))
158
159(defmacro charset-iso-graphic-plane (charset)
160 (if (quoted-symbol-p charset)
161 (aref (charset-info (nth 1 charset)) 9)
162 `(aref (charset-info ,charset) 9)))
163
164(defmacro charset-reverse-charset (charset)
165 (if (quoted-symbol-p charset)
166 (aref (charset-info (nth 1 charset)) 10)
167 `(aref (charset-info ,charset) 10)))
168
169(defmacro charset-short-name (charset)
170 (if (quoted-symbol-p charset)
171 (aref (charset-info (nth 1 charset)) 11)
172 `(aref (charset-info ,charset) 11)))
173
174(defmacro charset-long-name (charset)
175 (if (quoted-symbol-p charset)
176 (aref (charset-info (nth 1 charset)) 12)
177 `(aref (charset-info ,charset) 12)))
178
179(defmacro charset-description (charset)
180 (if (quoted-symbol-p charset)
181 (aref (charset-info (nth 1 charset)) 13)
182 `(aref (charset-info ,charset) 13)))
183
184(defmacro charset-plist (charset)
185 (if (quoted-symbol-p charset)
f98e2797 186 `(aref ,(charset-info (nth 1 charset)) 14)
4ed46869
KH
187 `(aref (charset-info ,charset) 14)))
188
189(defun set-charset-plist (charset plist)
190 (aset (charset-info charset) 14 plist))
191
192(defmacro make-char (charset &optional c1 c2)
f98e2797
KH
193 "Return a character of CHARSET and position-codes CODE1 and CODE2.
194CODE1 and CODE2 are optional, but if you don't supply
195 sufficient position-codes, return a generic character which stands for
196all characters or group of characters in the character sets.
a73a8c89 197A generic character can be used to index a char table (e.g. syntax-table)."
4ed46869
KH
198 (if (quoted-symbol-p charset)
199 `(make-char-internal ,(charset-id (nth 1 charset)) ,c1 ,c2)
200 `(make-char-internal (charset-id ,charset) ,c1 ,c2)))
201
69eba008
KH
202(defmacro charset-list ()
203 "Return list of charsets ever defined."
13d5617d
KH
204 'charset-list)
205
206(defsubst generic-char-p (char)
207 "Return t if and only if CHAR is a generic character.
208See also the documentation of make-char."
209 (let ((l (split-char char)))
210 (and (or (= (nth 1 l) 0) (eq (nth 2 l) 0))
211 (not (eq (car l) 'composition)))))
69eba008 212
8057896b 213;; Coding system staffs
4ed46869 214
8057896b 215;; Coding system is a symbol that has the property `coding-system'.
4ed46869 216;;
8057896b
KH
217;; The value of the property `coding-system' is a vector of the
218;; following format:
219;; [TYPE MNEMONIC DOC-STRING NOT-USED-NOW FLAGS]
220;; We call this vector as coding-spec. See comments in src/coding.c
221;; for more detail. The property value may be another coding system,
222;; in which case, the coding-spec should be taken from that
223;; coding-system. The 4th element NOT-USED-NOW is kept just for
224;; backward compatibility with old version of Mule.
225
226(defconst coding-spec-type-idx 0)
227(defconst coding-spec-mnemonic-idx 1)
228(defconst coding-spec-doc-string-idx 2)
229(defconst coding-spec-flags-idx 4)
230
231;; Coding system may have proerpty `eol-type'. The value of the
232;; property `eol-type' is integer 0..2 or a vector of three coding
233;; systems. The integer value 0, 1, and 2 indicate the format of
4ed46869
KH
234;; end-of-line LF, CRLF, and CR respectively. The vector value
235;; indicates that the format of end-of-line should be detected
8057896b
KH
236;; automatically. Nth element of the vector is the subsidiary coding
237;; system whose `eol-type' property is N.
4ed46869 238;;
8057896b
KH
239;; Coding system may also have properties `post-read-conversion' and
240;; `pre-write-conversion. Values of these properties are functions.
4ed46869
KH
241;;
242;; The function in `post-read-conversion' is called after some text is
8057896b 243;; inserted and decoded along the coding system and before any
4ed46869
KH
244;; functions in `after-insert-functions' are called. The arguments to
245;; this function is the same as those of a function in
246;; `after-insert-functions', i.e. LENGTH of a text while putting point
247;; at the head of the text to be decoded
248;;
249;; The function in `pre-write-conversion' is called after all
250;; functions in `write-region-annotate-functions' and
251;; `buffer-file-format' are called, and before the text is encoded by
8057896b 252;; the coding system. The arguments to this function is the same as
4ed46869
KH
253;; those of a function in `write-region-annotate-functions', i.e. FROM
254;; and TO specifying region of a text.
255
8057896b
KH
256;; Return Nth element of coding-spec of CODING-SYSTEM.
257(defun coding-system-spec-ref (coding-system n)
258 (check-coding-system coding-system)
259 (let ((vec (coding-system-spec coding-system)))
260 (and vec (aref vec n))))
4ed46869 261
4ed46869 262(defun coding-system-type (coding-system)
6e9722b0 263 "Return TYPE element in coding-spec of CODING-SYSTEM."
8057896b 264 (coding-system-spec-ref coding-system coding-spec-type-idx))
4ed46869 265
4ed46869 266(defun coding-system-mnemonic (coding-system)
8057896b
KH
267 "Return MNEMONIC element in coding-spec of CODING-SYSTEM."
268 (or (coding-system-spec-ref coding-system coding-spec-mnemonic-idx)
269 ?-))
4ed46869 270
8057896b
KH
271(defun coding-system-doc-string (coding-system)
272 "Return DOC-STRING element in coding-spec of CODING-SYSTEM."
273 (coding-system-spec-ref coding-system coding-spec-doc-string-idx))
4ed46869 274
4ed46869 275(defun coding-system-flags (coding-system)
8057896b
KH
276 "Return FLAGS element in coding-spec of CODING-SYSTEM."
277 (coding-system-spec-ref coding-system coding-spec-flags-idx))
4ed46869 278
8057896b
KH
279(defun coding-system-eol-type (coding-system)
280 "Return eol-type property of CODING-SYSTEM."
69eba008 281 (check-coding-system coding-system)
4ed46869
KH
282 (and coding-system
283 (or (get coding-system 'eol-type)
8057896b 284 (coding-system-eol-type (get coding-system 'coding-system)))))
4ed46869 285
6e9722b0
KH
286(defun coding-system-category (coding-system)
287 "Return coding category of CODING-SYSTEM."
288 (and coding-system
289 (symbolp coding-system)
290 (or (get coding-system 'coding-category)
291 (coding-system-category (get coding-system 'coding-system)))))
292
bd882697
KH
293(defun coding-system-parent (coding-system)
294 "Return parent of CODING-SYSTEM."
295 (let ((parent (get coding-system 'parent-coding-system)))
296 (and parent
297 (or (coding-system-parent parent)
298 parent))))
299
6e9722b0
KH
300;; Make subsidiary coding systems (eol-type variants) of CODING-SYSTEM.
301(defun make-subsidiary-coding-system (coding-system)
8057896b
KH
302 (let ((subsidiaries (vector (intern (format "%s-unix" coding-system))
303 (intern (format "%s-dos" coding-system))
304 (intern (format "%s-mac" coding-system))))
305 (i 0))
306 (while (< i 3)
6e9722b0 307 (put (aref subsidiaries i) 'coding-system coding-system)
8057896b
KH
308 (put (aref subsidiaries i) 'eol-type i)
309 (put (aref subsidiaries i) 'eol-variant t)
310 (setq i (1+ i)))
311 subsidiaries))
4ed46869 312
8057896b
KH
313(defun make-coding-system (coding-system type mnemonic doc-string
314 &optional flags)
4ed46869 315 "Define a new CODING-SYSTEM (symbol).
8057896b
KH
316Remaining arguments are TYPE, MNEMONIC, DOC-STRING, and FLAGS (optional) which
317construct a coding-spec of CODING-SYSTEM in the following format:
318 [TYPE MNEMONIC DOC-STRING nil FLAGS]
4ed46869
KH
319TYPE is an integer value indicating the type of coding-system as follows:
320 0: Emacs internal format,
321 1: Shift-JIS (or MS-Kanji) used mainly on Japanese PC,
322 2: ISO-2022 including many variants,
323 3: Big5 used mainly on Chinese PC,
324 4: private, CCL programs provide encoding/decoding algorithm.
325MNEMONIC is a character to be displayed on mode line for the coding-system.
8057896b 326DOC-STRING is a documentation string for the coding-system.
4ed46869
KH
327FLAGS specifies more precise information of each TYPE.
328 If TYPE is 2 (ISO-2022), FLAGS should be a list of:
329 CHARSET0, CHARSET1, CHARSET2, CHARSET3, SHORT-FORM,
330 ASCII-EOL, ASCII-CNTL, SEVEN, LOCKING-SHIFT, SINGLE-SHIFT,
a73a8c89 331 USE-ROMAN, USE-OLDJIS, NO-ISO6429, INIT-BOL, DESIGNATION-BOL.
4ed46869
KH
332 CHARSETn are character sets initially designated to Gn graphic registers.
333 If CHARSETn is nil, Gn is never used.
334 If CHARSETn is t, Gn can be used but nothing designated initially.
335 If CHARSETn is a list of character sets, those character sets are
336 designated to Gn on output, but nothing designated to Gn initially.
337 SHORT-FORM non-nil means use short designation sequence on output.
338 ASCII-EOL non-nil means designate ASCII to g0 at end of line on output.
339 ASCII-CNTL non-nil means designate ASCII to g0 before control codes and
340 SPACE on output.
341 SEVEN non-nil means use 7-bit code only on output.
342 LOCKING-SHIFT non-nil means use locking-shift.
343 SINGLE-SHIFT non-nil means use single-shift.
344 USE-ROMAN non-nil means designate JIS0201-1976-Roman instead of ASCII.
345 USE-OLDJIS non-nil means designate JIS0208-1976 instead of JIS0208-1983.
346 NO-ISO6429 non-nil means not use ISO6429's direction specification.
69eba008
KH
347 INIT-BOL non-nil means any designation state is assumed to be reset
348 to initial at each beginning of line on output.
349 DESIGNATION-BOL non-nil means designation sequences should be placed
350 at beginning of line on output.
4ed46869
KH
351 If TYPE is 4 (private), FLAGS should be a cons of CCL programs,
352 for encoding and decoding. See the documentation of CCL for more detail."
353
354 ;; At first, set a value of `coding-system' property.
6e9722b0
KH
355 (let ((coding-spec (make-vector 5 nil))
356 coding-category)
8057896b
KH
357 (if (or (not (integerp type)) (< type 0) (> type 4))
358 (error "TYPE argument must be 0..4"))
359 (if (or (not (integerp mnemonic)) (<= mnemonic ? ) (> mnemonic 127))
360 (error "MNEMONIC arguemnt must be a printable character."))
361 (aset coding-spec 0 type)
362 (aset coding-spec 1 mnemonic)
363 (aset coding-spec 2 (if (stringp doc-string) doc-string ""))
364 (aset coding-spec 3 nil) ; obsolete element
6e9722b0
KH
365 (cond ((= type 0)
366 (setq coding-category 'coding-category-emacs-mule))
367 ((= type 1)
368 (setq coding-category 'coding-category-sjis))
369 ((= type 2) ; ISO2022
4ed46869 370 (let ((i 0)
6e9722b0
KH
371 (vec (make-vector 32 nil))
372 (no-initial-designation t)
373 (g1-designation nil))
4ed46869
KH
374 (while (< i 4)
375 (let ((charset (car flags)))
6e9722b0
KH
376 (if (and no-initial-designation
377 (> i 0)
378 (or (charsetp charset)
379 (and (consp charset)
380 (charsetp (car charset)))))
381 (setq no-initial-designation nil))
382 (if (charsetp charset)
383 (if (= i 1) (setq g1-designation charset))
384 (if (consp charset)
385 (let ((tail charset)
386 elt)
387 (while tail
388 (setq elt (car tail))
69eba008
KH
389 (or (not elt) (eq elt t) (charsetp elt)
390 (error "Invalid charset: %s" elt))
6e9722b0
KH
391 (setq tail (cdr tail)))
392 (setq g1-designation (car charset)))
393 (if (and charset (not (eq charset t)))
394 (error "Invalid charset: %s" charset))))
4ed46869
KH
395 (aset vec i charset))
396 (setq flags (cdr flags) i (1+ i)))
397 (while (and (< i 32) flags)
398 (aset vec i (car flags))
399 (setq flags (cdr flags) i (1+ i)))
6e9722b0
KH
400 (aset coding-spec 4 vec)
401 (if no-initial-designation
402 (put coding-system 'no-initial-designation t))
403 (setq coding-category
404 (if (aref vec 8) ; Use locking-shift.
405 'coding-category-iso-else
406 (if (aref vec 7) ; 7-bit only.
407 (if (aref vec 9) ; Use single-shift.
408 'coding-category-iso-else
409 'coding-category-iso-7)
410 (if no-initial-designation
411 'coding-category-iso-else
412 (if (and (charsetp g1-designation)
413 (= (charset-dimension g1-designation) 2))
414 'coding-category-iso-8-2
415 'coding-category-iso-8-1)))))))
416 ((= type 3)
417 (setq coding-category 'coding-category-big5))
418 ((= type 4) ; private
419 (setq coding-category 'coding-category-binary)
4ed46869
KH
420 (if (and (consp flags)
421 (vectorp (car flags))
422 (vectorp (cdr flags)))
8057896b 423 (aset coding-spec 4 flags)
6e9722b0
KH
424 (error "Invalid FLAGS argument for TYPE 4 (CCL)"))))
425 (put coding-system 'coding-system coding-spec)
426 (put coding-system 'coding-category coding-category)
427 (put coding-category 'coding-systems
428 (cons coding-system (get coding-category 'coding-systems))))
4ed46869
KH
429
430 ;; Next, set a value of `eol-type' property. The value is a vector
6e9722b0 431 ;; of subsidiary coding systems, each corresponds to a coding system
4ed46869 432 ;; for the detected end-of-line format.
8057896b
KH
433 (put coding-system 'eol-type
434 (if (<= type 3)
6e9722b0 435 (make-subsidiary-coding-system coding-system)
8057896b
KH
436 0)))
437
438(defun define-coding-system-alias (coding-system alias)
439 "Define ALIAS as an alias coding system of CODING-SYSTEM."
440 (check-coding-system coding-system)
6e9722b0
KH
441 (let ((parent (coding-system-parent coding-system)))
442 (if parent
443 (setq coding-system parent)))
8057896b 444 (put alias 'coding-system coding-system)
6e9722b0
KH
445 (put alias 'parent-coding-system coding-system)
446 (put coding-system 'alias-coding-systems
447 (cons alias (get coding-system 'alias-coding-systems)))
448 (let ((eol-variants (coding-system-eol-type coding-system))
449 subsidiaries)
450 (if (vectorp eol-variants)
451 (let ((i 0))
452 (setq subsidiaries (make-subsidiary-coding-system alias))
453 (while (< i 3)
454 (put (aref subsidiaries i) 'parent-coding-system
455 (aref eol-variants i))
456 (put (aref eol-variants i) 'alias-coding-systems
457 (cons (aref subsidiaries i) (get (aref eol-variants i)
458 'alias-coding-systems)))
459 (setq i (1+ i)))))))
4ed46869
KH
460
461(defun set-buffer-file-coding-system (coding-system &optional force)
462 "Set buffer-file-coding-system of the current buffer to CODING-SYSTEM.
463If eol-type of the current buffer-file-coding-system is an integer value N, and
a73a8c89 464 eol-type of CODING-SYSTEM is a vector, the Nth element of the vector is used
4ed46869
KH
465 instead of CODING-SYSTEM itself.
466Optional prefix argument FORCE non-nil means CODING-SYSTEM is set
467 regardless of eol-type of the current buffer-file-coding-system."
468 (interactive "zBuffer-file-coding-system: \nP")
469 (check-coding-system coding-system)
470 (if (null force)
8057896b
KH
471 (let ((x (coding-system-eol-type buffer-file-coding-system))
472 (y (coding-system-eol-type coding-system)))
4ed46869
KH
473 (if (and (numberp x) (>= x 0) (<= x 2) (vectorp y))
474 (setq coding-system (aref y x)))))
475 (setq buffer-file-coding-system coding-system)
476 (set-buffer-modified-p t)
477 (force-mode-line-update))
478
df100398
KH
479(defun set-terminal-coding-system (coding-system)
480 "Set coding system of your terminal to CODING-SYSTEM.
481All outputs to terminal are encoded by the specified coding system."
482 (interactive "zCoding-system for terminal display: ")
483 (set-terminal-coding-system-internal coding-system)
484 (redraw-frame (selected-frame)))
485
486(defun set-keyboard-coding-system (coding-system)
487 "Set coding system of codes sent from terminal keyboard to CODING-SYSTEM.
488In addition, this command toggles Encoded-kbd minor mode.
489If the specified coding system is nil, Encoded-bkd mode is turned off,
490else it is turned on so that user inputs are decoded by the
491specified coding system."
492 (interactive "zCoding-system for keyboard input: ")
493 (set-keyboard-coding-system-internal coding-system)
494 (encoded-kbd-mode (if coding-system 1 0)))
495
496(defun set-buffer-process-coding-system (decoding encoding)
497 "Set coding systems to the process associated with the current buffer.
498DECODING is the coding system to be used to decode input from the process,
499ENCODING is to be used to encode output to the process."
4ed46869
KH
500 (interactive
501 "zCoding-system for process input: \nzCoding-system for process output: ")
502 (let ((proc (get-buffer-process (current-buffer))))
503 (if (null proc)
504 (error "no process")
df100398
KH
505 (check-coding-system decoding)
506 (check-coding-system encoding)
507 (set-process-coding-system proc decoding encoding)))
4ed46869
KH
508 (force-mode-line-update))
509
4ed46869
KH
510(defun set-coding-priority (arg)
511 "Set priority of coding-category according to LIST.
512LIST is a list of coding-categories ordered by priority."
513 (let (l)
514 ;; Put coding-categories listed in ARG to L while checking the
515 ;; validity. We assume that `coding-category-list' contains whole
516 ;; coding-categories.
517 (while arg
518 (if (null (memq (car arg) coding-category-list))
519 (error "Invalid element in argument: %s" (car arg)))
520 (setq l (cons (car arg) l))
521 (setq arg (cdr arg)))
522 ;; Put coding-category not listed in ARG to L.
523 (while coding-category-list
524 (if (null (memq (car coding-category-list) l))
525 (setq l (cons (car coding-category-list) l)))
526 (setq coding-category-list (cdr coding-category-list)))
527 ;; Update `coding-category-list' and return it.
528 (setq coding-category-list (nreverse l))))
529
530;;; FILE I/O
531
532;; Set buffer-file-coding-system of the current buffer after some text
533;; is inserted.
534(defun after-insert-file-set-buffer-file-coding-system (inserted)
535 (if last-coding-system-used
536 (let ((coding-system
537 (find-new-buffer-file-coding-system last-coding-system-used))
538 (modified-p (buffer-modified-p)))
539 (if coding-system
540 (set-buffer-file-coding-system coding-system))
541 (set-buffer-modified-p modified-p)))
542 nil)
543
544(setq after-insert-file-functions
545 (cons 'after-insert-file-set-buffer-file-coding-system
546 after-insert-file-functions))
547
8057896b 548;; The coding-spec and eol-type of coding-system returned is decided
4ed46869
KH
549;; independently in the following order.
550;; 1. That of buffer-file-coding-system locally bound.
551;; 2. That of CODING.
552
553(defun find-new-buffer-file-coding-system (coding)
554 "Return a coding system for a buffer when a file of CODING is inserted.
a73a8c89
KH
555The local variable `buffer-file-coding-system' of the current buffer
556is set to the returned value.
df100398 557Return nil if there's no need of setting new buffer-file-coding-system."
4ed46869
KH
558 (let (local-coding local-eol
559 found-eol
560 new-coding new-eol)
561 (if (null coding)
562 ;; Nothing found about coding.
563 nil
564
565 ;; Get information of the current local value of
566 ;; `buffer-file-coding-system' in LOCAL-EOL and LOCAL-CODING.
567 (if (local-variable-p 'buffer-file-coding-system)
568 ;; Something already set locally.
569 (progn
8057896b 570 (setq local-eol (coding-system-eol-type buffer-file-coding-system))
4ed46869
KH
571 (if (null (numberp local-eol))
572 ;; But eol-type is not yet set.
573 (setq local-eol nil))
574 (if (null (eq (coding-system-type buffer-file-coding-system) t))
13d5617d 575 ;; This is not `undecided'.
4ed46869
KH
576 (progn
577 (setq local-coding buffer-file-coding-system)
578 (while (symbolp (get local-coding 'coding-system))
579 (setq local-coding (get local-coding 'coding-system))))
580 )))
581
582 (if (and local-eol local-coding)
583 ;; The current buffer has already set full coding-system, we
584 ;; had better not change it.
585 nil
586
8057896b 587 (setq found-eol (coding-system-eol-type coding))
4ed46869
KH
588 (if (null (numberp found-eol))
589 ;; But eol-type is not found.
590 (setq found-eol nil))
591 (if (eq (coding-system-type coding) t)
13d5617d
KH
592 ;; This is `undecided', which means nothing found except
593 ;; for eol-type.
4ed46869
KH
594 (setq coding nil))
595
596 ;; The local setting takes precedence over the found one.
597 (setq new-coding (or local-coding coding))
598 (setq new-eol (or local-eol found-eol))
599 (if (and (numberp new-eol)
8057896b 600 (vectorp (coding-system-eol-type new-coding)))
4ed46869 601 (setq new-coding
8057896b 602 (aref (coding-system-eol-type new-coding) new-eol)))
4ed46869
KH
603 new-coding))))
604
a73a8c89
KH
605(defun make-unification-table (&rest args)
606 "Make a unification table (char table) from arguments.
13d5617d
KH
607Each argument is a list of the form (FROM . TO),
608where FROM is a character to be unified to TO.
609
610FROM can be a generic character (see make-char). In this case, TO is
611a generic character containing the same number of charcters or a
612oridinal character. If FROM and TO are both generic characters, all
613characters belonging to FROM are unified to characters belonging to TO
614without changing their position code(s)."
a73a8c89
KH
615 (let ((table (make-char-table 'character-unification-table))
616 revlist)
617 (while args
618 (let ((elts (car args)))
619 (while elts
13d5617d
KH
620 (let* ((from (car (car elts)))
621 (from-i 0) ; degree of freedom of FROM
622 (from-rev (nreverse (split-char from)))
623 (to (cdr (car elts)))
624 (to-i 0) ; degree of freedom of TO
625 (to-rev (nreverse (split-char to))))
626 ;; Check numbers of heading 0s in FROM-REV and TO-REV.
627 (while (eq (car from-rev) 0)
628 (setq from-i (1+ from-i) from-rev (cdr from-rev)))
629 (while (eq (car to-rev) 0)
630 (setq to-i (1+ to-i) to-rev (cdr to-rev)))
631 (if (and (/= from-i to-i) (/= to-i 0))
632 (error "Invalid character pair (%d . %d)" from to))
633 ;; If we have already unified TO to TO-ALT, FROM should
634 ;; also be unified to TO-ALT. But, this is only if TO is
635 ;; a generic character or TO-ALT is not a generic
636 ;; character.
637 (let ((to-alt (aref table to)))
638 (if (and to-alt
639 (or (> to-i 0) (not (generic-char-p to-alt))))
640 (setq to to-alt)))
641 (if (> from-i 0)
642 (set-char-table-default table from to)
643 (aset table from to))
a73a8c89
KH
644 ;; If we have already unified some chars to FROM, they
645 ;; should also be unified to TO.
646 (let ((l (assq from revlist)))
647 (if l
648 (let ((ch (car l)))
649 (setcar l to)
650 (setq l (cdr l))
651 (while l
652 (aset table ch to)
653 (setq l (cdr l)) ))))
654 ;; Now update REVLIST.
655 (let ((l (assq to revlist)))
656 (if l
657 (setcdr l (cons from (cdr l)))
658 (setq revlist (cons (list to from) revlist)))))
659 (setq elts (cdr elts))))
660 (setq args (cdr args)))
661 ;; Return TABLE just created.
662 table))
663
69eba008
KH
664;;; Initialize some variables.
665
666(put 'use-default-ascent 'char-table-extra-slots 0)
667(setq use-default-ascent (make-char-table 'use-default-ascent))
668
669;;;
4ed46869
KH
670(provide 'mule)
671
672;;; mule.el ends here