diff options
| author | Kenichi Handa | 1998-07-25 04:23:13 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1998-07-25 04:23:13 +0000 |
| commit | 51ed58ea1289f03709e759fe1a111bd9ce9a366f (patch) | |
| tree | 85a8919d89f56a1ef6cea83ef0acf65dade466c0 | |
| parent | 991a0b3207d7a7943084a5cf0fdb00e4456bc6f0 (diff) | |
| download | emacs-51ed58ea1289f03709e759fe1a111bd9ce9a366f.tar.gz emacs-51ed58ea1289f03709e759fe1a111bd9ce9a366f.zip | |
(find-multibyte-characters): New
function.
(select-safe-coding-system): Highlight characters which can't be
encoded. Show list of such characters also in *Warning* buffer.
| -rw-r--r-- | lisp/international/mule-cmds.el | 154 |
1 files changed, 125 insertions, 29 deletions
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 5352fb02f24..9340dec8074 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el | |||
| @@ -303,6 +303,50 @@ CHARSETS is a list of character sets." | |||
| 303 | (sort codings (function (lambda (x y) (> (car x) (car y)))))) | 303 | (sort codings (function (lambda (x y) (> (car x) (car y)))))) |
| 304 | ))) | 304 | ))) |
| 305 | 305 | ||
| 306 | (defun find-multibyte-characters (from to &optional maxcount excludes) | ||
| 307 | "Find multibyte characters in the region specified by FROM and TO. | ||
| 308 | If FROM is a string, find multibyte characters in the string. | ||
| 309 | The return value is an alist of the following format: | ||
| 310 | ((CHARSET COUNT CHAR ...) ...) | ||
| 311 | where | ||
| 312 | CHARSET is a character set, | ||
| 313 | COUNT is a number of characters, | ||
| 314 | CHARs are found characters of the character set. | ||
| 315 | Optional 3rd arg MAXCOUNT limits how many CHARs are put in the above list. | ||
| 316 | Optioanl 4th arg EXCLUDE is a list of character sets to be ignored." | ||
| 317 | (let ((chars nil) | ||
| 318 | charset char) | ||
| 319 | (if (stringp from) | ||
| 320 | (let ((idx 0)) | ||
| 321 | (while (setq idx (string-match "[^\000-\177]" from idx)) | ||
| 322 | (setq char (aref from idx) | ||
| 323 | charset (char-charset char)) | ||
| 324 | (if (not (memq charset excludes)) | ||
| 325 | (let ((slot (assq charset chars))) | ||
| 326 | (if slot | ||
| 327 | (if (not (memq char (nthcdr 2 slot))) | ||
| 328 | (let ((count (nth 1 slot))) | ||
| 329 | (setcar (cdr slot) (1+ count)) | ||
| 330 | (if (or (not maxcount) (< count maxcount)) | ||
| 331 | (nconc slot (list char))))) | ||
| 332 | (setq chars (cons (list charset 1 char) chars))))) | ||
| 333 | (setq idx (1+ idx)))) | ||
| 334 | (save-excursion | ||
| 335 | (goto-char from) | ||
| 336 | (while (re-search-forward "[^\000-\177]" to t) | ||
| 337 | (setq char (preceding-char) | ||
| 338 | charset (char-charset char)) | ||
| 339 | (if (not (memq charset excludes)) | ||
| 340 | (let ((slot (assq charset chars))) | ||
| 341 | (if slot | ||
| 342 | (if (not (memq char (nthcdr 2 slot))) | ||
| 343 | (let ((count (nth 1 slot))) | ||
| 344 | (setcar (cdr slot) (1+ count)) | ||
| 345 | (if (or (not maxcount) (< count maxcount)) | ||
| 346 | (nconc slot (list char))))) | ||
| 347 | (setq chars (cons (list charset 1 char) chars)))))))) | ||
| 348 | (nreverse chars))) | ||
| 349 | |||
| 306 | (defvar last-coding-system-specified nil | 350 | (defvar last-coding-system-specified nil |
| 307 | "Most recent coding system explicitly specified by the user when asked. | 351 | "Most recent coding system explicitly specified by the user when asked. |
| 308 | This variable is set whenever Emacs asks the user which coding system | 352 | This variable is set whenever Emacs asks the user which coding system |
| @@ -326,9 +370,9 @@ Kludgy feature: if FROM is a string, the string is the target text, | |||
| 326 | and TO is ignored." | 370 | and TO is ignored." |
| 327 | (or default-coding-system | 371 | (or default-coding-system |
| 328 | (setq default-coding-system buffer-file-coding-system)) | 372 | (setq default-coding-system buffer-file-coding-system)) |
| 329 | (let ((safe-coding-systems (if (stringp from) | 373 | (let* ((charsets (if (stringp from) (find-charset-string from) |
| 330 | (find-coding-systems-string from) | 374 | (find-charset-region from to))) |
| 331 | (find-coding-systems-region from to)))) | 375 | (safe-coding-systems (find-coding-systems-for-charsets charsets))) |
| 332 | (if (or (eq (car safe-coding-systems) 'undecided) | 376 | (if (or (eq (car safe-coding-systems) 'undecided) |
| 333 | (and default-coding-system | 377 | (and default-coding-system |
| 334 | (memq (coding-system-base default-coding-system) | 378 | (memq (coding-system-base default-coding-system) |
| @@ -345,34 +389,86 @@ and TO is ignored." | |||
| 345 | (setcar l mime-charset)) | 389 | (setcar l mime-charset)) |
| 346 | (setq l (cdr l)))) | 390 | (setq l (cdr l)))) |
| 347 | 391 | ||
| 348 | ;; Then, ask a user to select a proper coding system. | 392 | (let ((non-safe-chars (find-multibyte-characters |
| 349 | (save-window-excursion | 393 | from to 3 |
| 350 | ;; At first, show a helpful message. | 394 | (and default-coding-system |
| 351 | (with-output-to-temp-buffer "*Warning*" | 395 | (coding-system-get default-coding-system |
| 352 | (save-excursion | 396 | 'safe-charsets)))) |
| 353 | (set-buffer standard-output) | 397 | overlays) |
| 354 | (insert (format "\ | 398 | (save-excursion |
| 355 | The target text contains a multibyte character which can't be | 399 | ;; Highlight characters that default-coding-system can't encode. |
| 356 | encoded safely by the coding system %s. | 400 | (when (integerp from) |
| 401 | (goto-char from) | ||
| 402 | (let ((found nil)) | ||
| 403 | (while (and (not found) | ||
| 404 | (re-search-forward "[^\000-\177]" to t)) | ||
| 405 | (setq found (assq (char-charset (preceding-char)) | ||
| 406 | non-safe-chars)))) | ||
| 407 | (beginning-of-line) | ||
| 408 | (set-window-start (selected-window) (point)) | ||
| 409 | (save-excursion | ||
| 410 | (while (re-search-forward "[^\000-\177]" to t) | ||
| 411 | (let* ((char (preceding-char)) | ||
| 412 | (charset (char-charset char))) | ||
| 413 | (when (assq charset non-safe-chars) | ||
| 414 | (setq overlays (cons (make-overlay (1- (point)) (point)) | ||
| 415 | overlays)) | ||
| 416 | (overlay-put (car overlays) 'face 'highlight)))))) | ||
| 417 | |||
| 418 | ;; At last, ask a user to select a proper coding system. | ||
| 419 | (unwind-protect | ||
| 420 | (save-window-excursion | ||
| 421 | ;; At first, show a helpful message. | ||
| 422 | (with-output-to-temp-buffer "*Warning*" | ||
| 423 | (save-excursion | ||
| 424 | (set-buffer standard-output) | ||
| 425 | (insert "The target text contains the following non ASCII character(s):\n") | ||
| 426 | (let ((len (length non-safe-chars)) | ||
| 427 | (shown 0)) | ||
| 428 | (while (and non-safe-chars (< shown 3)) | ||
| 429 | (when (> (length (car non-safe-chars)) 2) | ||
| 430 | (setq shown (1+ shown)) | ||
| 431 | (insert (format "%25s: " (car (car non-safe-chars)))) | ||
| 432 | (let ((l (nthcdr 2 (car non-safe-chars)))) | ||
| 433 | (while l | ||
| 434 | (insert (car l)) | ||
| 435 | (setq l (cdr l)))) | ||
| 436 | (if (> (nth 1 (car non-safe-chars)) 3) | ||
| 437 | (insert "...")) | ||
| 438 | (insert "\n")) | ||
| 439 | (setq non-safe-chars (cdr non-safe-chars))) | ||
| 440 | (if (< shown len) | ||
| 441 | (insert (format "%27s\n" "...")))) | ||
| 442 | (insert (format "\ | ||
| 443 | These can't be encoded safely by the coding system %s. | ||
| 357 | 444 | ||
| 358 | Please select one from the following safe coding systems:\n" | 445 | Please select one from the following safe coding systems:\n" |
| 359 | default-coding-system)) | 446 | default-coding-system)) |
| 360 | (let ((pos (point)) | 447 | (let ((pos (point)) |
| 361 | (fill-prefix " ")) | 448 | (fill-prefix " ")) |
| 362 | (mapcar (function (lambda (x) (princ " ") (princ x))) | 449 | (mapcar (function (lambda (x) (princ " ") (princ x))) |
| 363 | safe-coding-systems) | 450 | safe-coding-systems) |
| 364 | (fill-region-as-paragraph pos (point))))) | 451 | (fill-region-as-paragraph pos (point))))) |
| 365 | 452 | ||
| 366 | ;; Read a coding system. | 453 | ;; Read a coding system. |
| 367 | (unwind-protect | 454 | (let* ((safe-names (mapcar (lambda (x) (list (symbol-name x))) |
| 368 | (let* ((safe-names (mapcar (lambda (x) (list (symbol-name x))) | 455 | safe-coding-systems)) |
| 369 | safe-coding-systems)) | 456 | (name (completing-read |
| 370 | (name (completing-read | 457 | (format "Select coding system (default %s): " |
| 371 | (format "Select coding system (default %s): " | 458 | (car safe-coding-systems)) |
| 372 | (car safe-coding-systems)) | 459 | safe-names nil t nil nil |
| 373 | safe-names nil t nil nil (car (car safe-names))))) | 460 | (car (car safe-names))))) |
| 374 | (setq last-coding-system-specified (intern name))) | 461 | (setq last-coding-system-specified (intern name)) |
| 375 | (kill-buffer "*Warning*")))))) | 462 | (if (integerp (coding-system-eol-type default-coding-system)) |
| 463 | (setq last-coding-system-specified | ||
| 464 | (coding-system-change-eol-conversion | ||
| 465 | last-coding-system-specified | ||
| 466 | (coding-system-eol-type default-coding-system)))) | ||
| 467 | last-coding-system-specified)) | ||
| 468 | (kill-buffer "*Warning*") | ||
| 469 | (while overlays | ||
| 470 | (delete-overlay (car overlays)) | ||
| 471 | (setq overlays (cdr overlays))))))))) | ||
| 376 | 472 | ||
| 377 | (setq select-safe-coding-system-function 'select-safe-coding-system) | 473 | (setq select-safe-coding-system-function 'select-safe-coding-system) |
| 378 | 474 | ||