diff options
| author | Kenichi Handa | 1998-01-22 01:42:20 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1998-01-22 01:42:20 +0000 |
| commit | 54b226f7e59fd83c0f83dc0e76c6dac99d19a1c3 (patch) | |
| tree | 8b9955cd0b67bf0b35705ef2e789ffa09a99ae54 | |
| parent | 40e98681b4c631b738be593e076881321b5e5efa (diff) | |
| download | emacs-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.el | 215 |
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. | ||
| 229 | Comparison 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. | ||
| 239 | All coding systems in the list can safely encode any multibyte characters | ||
| 240 | in the text. | ||
| 241 | |||
| 242 | If the text contains no multibyte charcters, return a list of a single | ||
| 243 | element `undecided'. | ||
| 244 | |||
| 245 | Kludgy feature: if FROM is a string, the string is the target text, | ||
| 246 | and 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 | |||
| 283 | Optional arg DEFAULT-CODING-SYSTEM specifies a coding system to be | ||
| 284 | checked at first. If omitted, buffer-file-coding-system of the | ||
| 285 | current buffer is used. | ||
| 286 | |||
| 287 | If the text contains some multibyte characters and | ||
| 288 | DEFAULT-CODING-SYSTEM can't encode them, ask a user to select one from | ||
| 289 | a list of coding systems which can encode the text, and return the | ||
| 290 | selected one. | ||
| 291 | |||
| 292 | In other cases, return DEFAULT-CODING-SYSTEM. | ||
| 293 | |||
| 294 | Kludgy feature: if FROM is a string, the string is the target text, | ||
| 295 | and 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 "\ | ||
| 312 | The target text contains a multibyte character which can't be | ||
| 313 | encoded safely by the coding system %s. | ||
| 314 | |||
| 315 | Please 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. |
| 249 | KEY is a symbol denoting the kind of information. | 358 | KEY is a symbol denoting the kind of information. |
| 250 | INFO is any Lisp object which contains the actual information. | 359 | INFO is any Lisp object which contains the actual information specific |
| 360 | to LANGUAGE-NAME. | ||
| 251 | 361 | ||
| 252 | Currently, the following KEYs are used by Emacs: | 362 | Currently, the following KEYs are used by Emacs: |
| 253 | 363 | ||
| 254 | charset: list of symbols whose values are charsets specific to the language. | 364 | charset: list of charsets. |
| 365 | |||
| 366 | coding-system: list of coding systems. | ||
| 255 | 367 | ||
| 256 | coding-system: list of coding systems specific to the language. | 368 | coding-priority: list of coding systems ordered by priority. |
| 257 | 369 | ||
| 258 | tutorial: a tutorial file name written in the language. | 370 | tutorial: a tutorial file name written in the language. |
| 259 | 371 | ||
| 260 | sample-text: one line short text containing characters of the language. | 372 | sample-text: one line short text containing characters of the language. |
| 261 | 373 | ||
| 262 | documentation: t or a string describing how Emacs supports the language. | 374 | documentation: 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 | ||
| 266 | setup-function: a function to call for setting up environment | 378 | setup-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 | |||
| 269 | If KEY is documentation or setup-function, you can also specify | ||
| 270 | a cons cell as INFO, in which case, the car part should be | ||
| 271 | a normal value as INFO for KEY (as described above), | ||
| 272 | and the cdr part should be a symbol whose value is a menu keymap | ||
| 273 | in which an entry for the language is defined. But, only the car part | ||
| 274 | is actually set as the information. | ||
| 275 | 380 | ||
| 276 | We will define more KEYs in the future. To avoid conflict, | 381 | We will define more KEYs in the future. To avoid conflict, |
| 277 | if you want to use your own KEY values, make them start with `user-'." | 382 | if you want to use your own KEY values, make them start with `user-'. |
| 383 | |||
| 384 | Optional 4th and 5th args DESCRIBE-MAP and SETUP-MAP are keymaps to | ||
| 385 | register LANGUAGE-NAME in the menu of `Mule'->`Describe Language | ||
| 386 | Environment' 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. |
| 315 | ALIST is an alist of KEY and INFO. See the documentation of | 412 | ALIST 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 | |||
| 415 | Optional arg PARENTS is a list of parent language environments ordered | ||
| 416 | from the highest to the lower. If it is nil, we make LANGUAGE-NAME | ||
| 417 | the 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))) |