aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa1998-01-22 01:42:20 +0000
committerKenichi Handa1998-01-22 01:42:20 +0000
commit54b226f7e59fd83c0f83dc0e76c6dac99d19a1c3 (patch)
tree8b9955cd0b67bf0b35705ef2e789ffa09a99ae54
parent40e98681b4c631b738be593e076881321b5e5efa (diff)
downloademacs-54b226f7e59fd83c0f83dc0e76c6dac99d19a1c3.tar.gz
emacs-54b226f7e59fd83c0f83dc0e76c6dac99d19a1c3.zip
(set-language-info): Doc-string
describes `coding-priority' KEY. (set-language-environment-coding-systems): New function. (list-subset-p): New function. (select-safe-coding-system): New function. (set-language-info): New optional args DESCRIBE-MAP and SETUP-MAP. (set-language-info-alist): New optionla arg PARENTS. Call set-language-info with apropriate DESCRIBE-MAP and SETUP-MAP args. (set-language-environment-coding-systems): New function. (prefer-coding-system): Call update-iso-coding-systems.
-rw-r--r--lisp/international/mule-cmds.el215
1 files changed, 179 insertions, 36 deletions
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 583f0d09c6d..088e388a139 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -213,6 +213,7 @@ This also sets the following values:
213 ;; CODING-SYSTEM is no-conversion or undecided. 213 ;; CODING-SYSTEM is no-conversion or undecided.
214 (error "Can't prefer the coding system `%s'" coding-system)) 214 (error "Can't prefer the coding system `%s'" coding-system))
215 (set coding-category (or base coding-system)) 215 (set coding-category (or base coding-system))
216 (update-iso-coding-systems)
216 (if (not (eq coding-category (car coding-category-list))) 217 (if (not (eq coding-category (car coding-category-list)))
217 ;; We must change the order. 218 ;; We must change the order.
218 (setq coding-category-list 219 (setq coding-category-list
@@ -223,6 +224,113 @@ This also sets the following values:
223 base coding-system)) 224 base coding-system))
224 (set-default-coding-systems (or base coding-system)))) 225 (set-default-coding-systems (or base coding-system))))
225 226
227(defun list-subset-p (list1 list2)
228 "Return non-nil if all elements in LIST1 are included in LIST2.
229Comparison done with EQ."
230 (catch 'tag
231 (while list1
232 (or (memq (car list1) list2)
233 (throw 'tag nil))
234 (setq list1 (cdr list1)))
235 t))
236
237(defun find-safe-coding-system (from to)
238 "Return a list of proper coding systems to encode a text between FROM and TO.
239All coding systems in the list can safely encode any multibyte characters
240in the text.
241
242If the text contains no multibyte charcters, return a list of a single
243element `undecided'.
244
245Kludgy feature: if FROM is a string, the string is the target text,
246and TO is ignored."
247 (let ((charset-list (if (stringp from) (find-charset-string from)
248 (find-charset-region from to))))
249 (if (and (= (length charset-list) 1)
250 (eq 'ascii (car charset-list)))
251 '(undecided)
252 (let ((l coding-system-list)
253 (prefered-codings
254 (mapcar (function
255 (lambda (x)
256 (get-charset-property x 'prefered-coding-system)))
257 charset-list))
258 codings coding safe)
259 (while l
260 (setq coding (car l) l (cdr l))
261 (if (and (eq coding (coding-system-base coding))
262 (setq safe (coding-system-get coding 'safe-charsets))
263 (or (eq safe t)
264 (list-subset-p charset-list safe)))
265 ;; We put the higher priority to coding systems included
266 ;; in PREFERED-CODINGS, and within them, put the higher
267 ;; priority to coding systems which support smaller
268 ;; number of charsets.
269 (let ((priority
270 (logior (if (coding-system-get coding 'mime-charset)
271 256 0)
272 (if (memq coding prefered-codings) 128 0)
273 (if (> (coding-system-type coding) 0) 64 0)
274 (if (consp safe) (- 64 (length safe)) 0))))
275 (setq codings (cons (cons priority coding) codings)))))
276 (mapcar 'cdr
277 (sort codings (function (lambda (x y) (> (car x) (car y))))))
278 ))))
279
280(defun select-safe-coding-system (from to &optional default-coding-system)
281 "Return a coding system which can encode a text between FROM and TO.
282
283Optional arg DEFAULT-CODING-SYSTEM specifies a coding system to be
284checked at first. If omitted, buffer-file-coding-system of the
285current buffer is used.
286
287If the text contains some multibyte characters and
288DEFAULT-CODING-SYSTEM can't encode them, ask a user to select one from
289a list of coding systems which can encode the text, and return the
290selected one.
291
292In other cases, return DEFAULT-CODING-SYSTEM.
293
294Kludgy feature: if FROM is a string, the string is the target text,
295and TO is ignored."
296 (or default-coding-system
297 (setq default-coding-system buffer-file-coding-system))
298 (let ((safe-coding-systems (find-safe-coding-system from to)))
299 (if (or (eq (car safe-coding-systems) 'undecided)
300 (and default-coding-system
301 (memq (coding-system-base default-coding-system)
302 safe-coding-systems)))
303 default-coding-system
304
305 ;; Ask a user to select a proper coding system.
306 (save-window-excursion
307 ;; At first, show a helpful message.
308 (with-output-to-temp-buffer "*Warning*"
309 (save-excursion
310 (set-buffer standard-output)
311 (insert (format "\
312The target text contains a multibyte character which can't be
313encoded safely by the coding system %s.
314
315Please select one from the following safe coding systems:\n"
316 default-coding-system))
317 (let ((pos (point))
318 (fill-prefix " "))
319 (mapcar (function (lambda (x) (princ " ") (princ x)))
320 safe-coding-systems)
321 (fill-region-as-paragraph pos (point)))))
322
323 ;; Read a coding system.
324 (let* ((safe-names (mapcar (lambda (x) (list (symbol-name x)))
325 safe-coding-systems))
326 (name (completing-read
327 (format "Select coding system (default %s): "
328 (car safe-coding-systems))
329 safe-names nil t nil nil (car (car safe-names)))))
330 (intern name))))))
331
332(setq select-safe-coding-system-function 'select-safe-coding-system)
333
226 334
227;;; Language support staffs. 335;;; Language support staffs.
228 336
@@ -244,37 +352,38 @@ KEY is a symbol denoting the kind of required information."
244 (if lang-slot 352 (if lang-slot
245 (cdr (assq key (cdr lang-slot)))))) 353 (cdr (assq key (cdr lang-slot))))))
246 354
247(defun set-language-info (language-name key info) 355(defun set-language-info (language-name key info
356 &optional describe-map setup-map)
248 "Set for LANGUAGE-NAME the information INFO under KEY. 357 "Set for LANGUAGE-NAME the information INFO under KEY.
249KEY is a symbol denoting the kind of information. 358KEY is a symbol denoting the kind of information.
250INFO is any Lisp object which contains the actual information. 359INFO is any Lisp object which contains the actual information specific
360 to LANGUAGE-NAME.
251 361
252Currently, the following KEYs are used by Emacs: 362Currently, the following KEYs are used by Emacs:
253 363
254charset: list of symbols whose values are charsets specific to the language. 364charset: list of charsets.
365
366coding-system: list of coding systems.
255 367
256coding-system: list of coding systems specific to the language. 368coding-priority: list of coding systems ordered by priority.
257 369
258tutorial: a tutorial file name written in the language. 370tutorial: a tutorial file name written in the language.
259 371
260sample-text: one line short text containing characters of the language. 372sample-text: one line short text containing characters of the language.
261 373
262documentation: t or a string describing how Emacs supports the language. 374documentation: t or a string describing how Emacs supports the language.
263 If a string is specified, it is shown before any other information 375 If a string is specified, it is shown before any other information
264 of the language by the command `describe-language-environment'. 376 of the language by the command `describe-language-environment'.
265 377
266setup-function: a function to call for setting up environment 378setup-function: a function to call for setting up environment
267 convenient for a user of the language. 379 convenient for a user of the language.
268
269If KEY is documentation or setup-function, you can also specify
270a cons cell as INFO, in which case, the car part should be
271a normal value as INFO for KEY (as described above),
272and the cdr part should be a symbol whose value is a menu keymap
273in which an entry for the language is defined. But, only the car part
274is actually set as the information.
275 380
276We will define more KEYs in the future. To avoid conflict, 381We will define more KEYs in the future. To avoid conflict,
277if you want to use your own KEY values, make them start with `user-'." 382if you want to use your own KEY values, make them start with `user-'.
383
384Optional 4th and 5th args DESCRIBE-MAP and SETUP-MAP are keymaps to
385register LANGUAGE-NAME in the menu of `Mule'->`Describe Language
386Environment' and `Mule'->`Setup Language Environment' respectively."
278 (if (symbolp language-name) 387 (if (symbolp language-name)
279 (setq language-name (symbol-name language-name))) 388 (setq language-name (symbol-name language-name)))
280 (let (lang-slot key-slot) 389 (let (lang-slot key-slot)
@@ -289,36 +398,57 @@ if you want to use your own KEY values, make them start with `user-'."
289 (setcdr lang-slot (cons key-slot (cdr lang-slot))))) 398 (setcdr lang-slot (cons key-slot (cdr lang-slot)))))
290 ;; Setup menu. 399 ;; Setup menu.
291 (cond ((eq key 'documentation) 400 (cond ((eq key 'documentation)
292 (define-key-after 401 (define-key-after describe-map (vector (intern language-name))
293 (if (consp info) 402 (cons language-name 'describe-specified-language-support) t))
294 (prog1 (symbol-value (cdr info))
295 (setq info (car info)))
296 describe-language-environment-map)
297 (vector (intern language-name))
298 (cons language-name 'describe-specified-language-support)
299 t))
300 ((eq key 'setup-function) 403 ((eq key 'setup-function)
301 (define-key-after 404 (define-key-after setup-map (vector (intern language-name))
302 (if (consp info) 405 (cons language-name 'setup-specified-language-environment) t)))
303 (prog1 (symbol-value (cdr info))
304 (setq info (car info)))
305 setup-language-environment-map)
306 (vector (intern language-name))
307 (cons language-name 'setup-specified-language-environment)
308 t)))
309 406
310 (setcdr key-slot info) 407 (setcdr key-slot info)
311 )) 408 ))
312 409
313(defun set-language-info-alist (language-name alist) 410(defun set-language-info-alist (language-name alist &optional parents)
314 "Set for LANGUAGE-NAME the information in ALIST. 411 "Set for LANGUAGE-NAME the information in ALIST.
315ALIST is an alist of KEY and INFO. See the documentation of 412ALIST is an alist of KEY and INFO. See the documentation of
316`set-langauge-info' for the meanings of KEY and INFO." 413`set-langauge-info' for the meanings of KEY and INFO.
414
415Optional arg PARENTS is a list of parent language environments ordered
416from the highest to the lower. If it is nil, we make LANGUAGE-NAME
417the top level language environment."
317 (if (symbolp language-name) 418 (if (symbolp language-name)
318 (setq language-name (symbol-name language-name))) 419 (setq language-name (symbol-name language-name)))
319 (while alist 420 (let ((describe-map describe-language-environment-map)
320 (set-language-info language-name (car (car alist)) (cdr (car alist))) 421 (setup-map setup-language-environment-map))
321 (setq alist (cdr alist)))) 422 (if parents
423 (let ((l parents)
424 map parent-symbol parent)
425 (while l
426 (if (symbolp (setq parent-symbol (car l)))
427 (setq parent (symbol-name parent))
428 (setq parent parent-symbol parent-symbol (intern parent)))
429 (setq map (lookup-key describe-map (vector parent-symbol)))
430 (if (not map)
431 (progn
432 (setq map (intern (format "describe-%s-environment-map"
433 (downcase parent))))
434 (define-prefix-command map)
435 (define-key-after describe-map (vector parent-symbol)
436 (cons parent map) t)))
437 (setq describe-map (symbol-value map))
438 (setq map (lookup-key setup-map (vector parent-symbol)))
439 (if (not map)
440 (progn
441 (setq map (intern (format "setup-%s-environment-map"
442 (downcase parent))))
443 (define-prefix-command map)
444 (define-key-after setup-map (vector parent-symbol)
445 (cons parent map) t)))
446 (setq setup-map (symbol-value map))
447 (setq l (cdr l)))))
448 (while alist
449 (set-language-info language-name (car (car alist)) (cdr (car alist))
450 describe-map setup-map)
451 (setq alist (cdr alist)))))
322 452
323(defun read-language-name (key prompt &optional default) 453(defun read-language-name (key prompt &optional default)
324 "Read language name which has information for KEY, prompting with PROMPT. 454 "Read language name which has information for KEY, prompting with PROMPT.
@@ -698,6 +828,19 @@ and sometimes other things."
698 (run-hooks 'set-language-environment-hook) 828 (run-hooks 'set-language-environment-hook)
699 (force-mode-line-update t)) 829 (force-mode-line-update t))
700 830
831(defun set-language-environment-coding-systems (language-name)
832 "Do various coding system setups for language environment LANGUAGE-NAME."
833 (let* ((priority (get-language-info language-name 'coding-priority))
834 (default-coding (car priority)))
835 (if priority
836 (let ((categories (mapcar 'coding-system-category priority)))
837 (set-default-coding-systems default-coding)
838 (set-coding-priority categories)
839 (while priority
840 (set (car categories) (car priority))
841 (setq priority (cdr priority) categories (cdr categories)))
842 (update-iso-coding-systems)))))
843
701;; Print all arguments with `princ', then print "\n". 844;; Print all arguments with `princ', then print "\n".
702(defsubst princ-list (&rest args) 845(defsubst princ-list (&rest args)
703 (while args (princ (car args)) (setq args (cdr args))) 846 (while args (princ (car args)) (setq args (cdr args)))