comparison lisp/international/mule-cmds.el @ 58055:005c3ebdd545

(select-safe-coding-system-interactively): New function extracted from select-safe-coding-system. (select-safe-coding-system): Use it.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 08 Nov 2004 23:03:30 +0000
parents 93792c00945b
children 3c8333b3d44d
comparison
equal deleted inserted replaced
58054:b40b27d0c034 58055:005c3ebdd545
1 ;;; mule-cmds.el --- commands for mulitilingual environment -*-coding: iso-2022-7bit -*- 1 ;;; mule-cmds.el --- commands for mulitilingual environment -*-coding: utf-8 -*-
2
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
2 ;; Copyright (C) 1995, 2003 Electrotechnical Laboratory, JAPAN. 4 ;; Copyright (C) 1995, 2003 Electrotechnical Laboratory, JAPAN.
3 ;; Licensed to the Free Software Foundation. 5 ;; Licensed to the Free Software Foundation.
4 ;; Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 6
6 ;; Keywords: mule, multilingual 7 ;; Keywords: mule, multilingual
7 8
8 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
9 10
623 "If non-nil, a function to control the behaviour of coding system selection. 624 "If non-nil, a function to control the behaviour of coding system selection.
624 The meaning is the same as the argument ACCEPT-DEFAULT-P of the 625 The meaning is the same as the argument ACCEPT-DEFAULT-P of the
625 function `select-safe-coding-system' (which see). This variable 626 function `select-safe-coding-system' (which see). This variable
626 overrides that argument.") 627 overrides that argument.")
627 628
629 (defun select-safe-coding-system-interactively (from to codings unsafe
630 &optional rejected default)
631 "Select interactively a coding system for the region FROM ... TO.
632 FROM can be a string, as in `write-region'.
633 CODINGS is the list of base coding systems known to be safe for this region,
634 typically obtained with `find-coding-systems-region'.
635 UNSAFE is a list of coding systems known to be unsafe for this region.
636 REJECTED is a list of coding systems which were safe but for some reason
637 were not recommended in the particular context.
638 DEFAULT is the coding system to use by default in the query."
639 ;; At first, if some defaults are unsafe, record at most 11
640 ;; problematic characters and their positions for them by turning
641 ;; (CODING ...)
642 ;; into
643 ;; ((CODING (POS . CHAR) (POS . CHAR) ...) ...)
644 (if unsafe
645 (setq unsafe
646 (mapcar #'(lambda (coding)
647 (cons coding
648 (if (stringp from)
649 (mapcar #'(lambda (pos)
650 (cons pos (aref from pos)))
651 (unencodable-char-position
652 0 (length from) coding
653 11 from))
654 (mapcar #'(lambda (pos)
655 (cons pos (char-after pos)))
656 (unencodable-char-position
657 from to coding 11)))))
658 unsafe)))
659
660 ;; Change each safe coding system to the corresponding
661 ;; mime-charset name if it is also a coding system. Such a name
662 ;; is more friendly to users.
663 (let ((l codings)
664 mime-charset)
665 (while l
666 (setq mime-charset (coding-system-get (car l) 'mime-charset))
667 (if (and mime-charset (coding-system-p mime-charset))
668 (setcar l mime-charset))
669 (setq l (cdr l))))
670
671 ;; Don't offer variations with locking shift, which you
672 ;; basically never want.
673 (let (l)
674 (dolist (elt codings (setq codings (nreverse l)))
675 (unless (or (eq 'coding-category-iso-7-else
676 (coding-system-category elt))
677 (eq 'coding-category-iso-8-else
678 (coding-system-category elt)))
679 (push elt l))))
680
681 ;; Remove raw-text, emacs-mule and no-conversion unless nothing
682 ;; else is available.
683 (setq codings
684 (or (delq 'raw-text
685 (delq 'emacs-mule
686 (delq 'no-conversion codings)))
687 '(raw-text emacs-mule no-conversion)))
688
689 (let ((window-configuration (current-window-configuration))
690 (bufname (buffer-name))
691 coding-system)
692 (save-excursion
693 ;; If some defaults are unsafe, make sure the offending
694 ;; buffer is displayed.
695 (when (and unsafe (not (stringp from)))
696 (pop-to-buffer bufname)
697 (goto-char (apply 'min (mapcar #'(lambda (x) (car (cadr x)))
698 unsafe))))
699 ;; Then ask users to select one from CODINGS while showing
700 ;; the reason why none of the defaults are not used.
701 (with-output-to-temp-buffer "*Warning*"
702 (with-current-buffer standard-output
703 (if (and (null rejected) (null unsafe))
704 (insert "No default coding systems to try for "
705 (if (stringp from)
706 (format "string \"%s\"." from)
707 (format "buffer `%s'." bufname)))
708 (insert
709 "These default coding systems were tried to encode"
710 (if (stringp from)
711 (concat " \"" (if (> (length from) 10)
712 (concat (substring from 0 10) "...\"")
713 (concat from "\"")))
714 (format " text\nin the buffer `%s'" bufname))
715 ":\n")
716 (let ((pos (point))
717 (fill-prefix " "))
718 (dolist (x (append rejected unsafe))
719 (princ " ") (princ (car x)))
720 (insert "\n")
721 (fill-region-as-paragraph pos (point)))
722 (when rejected
723 (insert "These safely encodes the target text,
724 but it is not recommended for encoding text in this context,
725 e.g., for sending an email message.\n ")
726 (dolist (x rejected)
727 (princ " ") (princ x))
728 (insert "\n"))
729 (when unsafe
730 (insert (if rejected "And the others"
731 "However, each of them")
732 " encountered these problematic characters:\n")
733 (dolist (coding unsafe)
734 (insert (format " %s:" (car coding)))
735 (let ((i 0)
736 (func1
737 #'(lambda (bufname pos)
738 (when (buffer-live-p (get-buffer bufname))
739 (pop-to-buffer bufname)
740 (goto-char pos))))
741 (func2
742 #'(lambda (bufname pos coding)
743 (when (buffer-live-p (get-buffer bufname))
744 (pop-to-buffer bufname)
745 (if (< (point) pos)
746 (goto-char pos)
747 (forward-char 1)
748 (search-unencodable-char coding)
749 (forward-char -1))))))
750 (dolist (elt (cdr coding))
751 (insert " ")
752 (if (stringp from)
753 (insert (if (< i 10) (cdr elt) "..."))
754 (if (< i 10)
755 (insert-text-button
756 (cdr elt)
757 :type 'help-xref
758 'help-echo
759 "mouse-2, RET: jump to this character"
760 'help-function func1
761 'help-args (list bufname (car elt)))
762 (insert-text-button
763 "..."
764 :type 'help-xref
765 'help-echo
766 "mouse-2, RET: next unencodable character"
767 'help-function func2
768 'help-args (list bufname (car elt)
769 (car coding)))))
770 (setq i (1+ i))))
771 (insert "\n"))
772 (insert "\
773 The first problematic character is at point in the displayed buffer,\n"
774 (substitute-command-keys "\
775 and \\[universal-argument] \\[what-cursor-position] will give information about it.\n"))))
776 (insert "\nSelect \
777 one of the following safe coding systems, or edit the buffer:\n")
778 (let ((pos (point))
779 (fill-prefix " "))
780 (dolist (x codings)
781 (princ " ") (princ x))
782 (insert "\n")
783 (fill-region-as-paragraph pos (point)))
784 (insert "Or specify any other coding system
785 at the risk of losing the problematic characters.\n")))
786
787 ;; Read a coding system.
788 (setq coding-system
789 (read-coding-system
790 (format "Select coding system (default %s): " default)
791 default))
792 (setq last-coding-system-specified coding-system))
793
794 (kill-buffer "*Warning*")
795 (set-window-configuration window-configuration)
796 coding-system))
797
628 (defun select-safe-coding-system (from to &optional default-coding-system 798 (defun select-safe-coding-system (from to &optional default-coding-system
629 accept-default-p file) 799 accept-default-p file)
630 "Ask a user to select a safe coding system from candidates. 800 "Ask a user to select a safe coding system from candidates.
631 The candidates of coding systems which can safely encode a text 801 The candidates of coding systems which can safely encode a text
632 between FROM and TO are shown in a popup window. Among them, the most 802 between FROM and TO are shown in a popup window. Among them, the most
719 (if select-safe-coding-system-accept-default-p 889 (if select-safe-coding-system-accept-default-p
720 (setq accept-default-p select-safe-coding-system-accept-default-p)) 890 (setq accept-default-p select-safe-coding-system-accept-default-p))
721 891
722 (let ((codings (find-coding-systems-region from to)) 892 (let ((codings (find-coding-systems-region from to))
723 (coding-system nil) 893 (coding-system nil)
724 (bufname (buffer-name))
725 safe rejected unsafe) 894 safe rejected unsafe)
726 (if (eq (car codings) 'undecided) 895 (if (eq (car codings) 'undecided)
727 ;; Any coding system is ok. 896 ;; Any coding system is ok.
728 (setq coding-system t) 897 (setq coding-system t)
729 ;; Classify the defaults into safe, rejected, and unsafe. 898 ;; Classify the defaults into safe, rejected, and unsafe.
737 (if safe 906 (if safe
738 (setq coding-system (car safe)))) 907 (setq coding-system (car safe))))
739 908
740 ;; If all the defaults failed, ask a user. 909 ;; If all the defaults failed, ask a user.
741 (when (not coding-system) 910 (when (not coding-system)
742 ;; At first, if some defaults are unsafe, record at most 11 911 (setq coding-system (select-safe-coding-system-interactively
743 ;; problematic characters and their positions for them by turning 912 from to codings unsafe rejected (car codings))))
744 ;; (CODING ...)
745 ;; into
746 ;; ((CODING (POS . CHAR) (POS . CHAR) ...) ...)
747 (if unsafe
748 (if (stringp from)
749 (setq unsafe
750 (mapcar #'(lambda (coding)
751 (cons coding
752 (mapcar #'(lambda (pos)
753 (cons pos (aref from pos)))
754 (unencodable-char-position
755 0 (length from) coding
756 11 from))))
757 unsafe))
758 (setq unsafe
759 (mapcar #'(lambda (coding)
760 (cons coding
761 (mapcar #'(lambda (pos)
762 (cons pos (char-after pos)))
763 (unencodable-char-position
764 from to coding 11))))
765 unsafe))))
766
767 ;; Change each safe coding system to the corresponding
768 ;; mime-charset name if it is also a coding system. Such a name
769 ;; is more friendly to users.
770 (let ((l codings)
771 mime-charset)
772 (while l
773 (setq mime-charset (coding-system-get (car l) 'mime-charset))
774 (if (and mime-charset (coding-system-p mime-charset))
775 (setcar l mime-charset))
776 (setq l (cdr l))))
777
778 ;; Don't offer variations with locking shift, which you
779 ;; basically never want.
780 (let (l)
781 (dolist (elt codings (setq codings (nreverse l)))
782 (unless (or (eq 'coding-category-iso-7-else
783 (coding-system-category elt))
784 (eq 'coding-category-iso-8-else
785 (coding-system-category elt)))
786 (push elt l))))
787
788 ;; Remove raw-text, emacs-mule and no-conversion unless nothing
789 ;; else is available.
790 (setq codings
791 (or (delq 'raw-text
792 (delq 'emacs-mule
793 (delq 'no-conversion codings)))
794 '(raw-text emacs-mule no-conversion)))
795
796 (let ((window-configuration (current-window-configuration)))
797 (save-excursion
798 ;; If some defaults are unsafe, make sure the offending
799 ;; buffer is displayed.
800 (when (and unsafe (not (stringp from)))
801 (pop-to-buffer bufname)
802 (goto-char (apply 'min (mapcar #'(lambda (x) (car (cadr x)))
803 unsafe))))
804 ;; Then ask users to select one from CODINGS while showing
805 ;; the reason why none of the defaults are not used.
806 (with-output-to-temp-buffer "*Warning*"
807 (save-excursion
808 (set-buffer standard-output)
809 (if (not default-coding-system)
810 (insert "No default coding systems to try for "
811 (if (stringp from)
812 (format "string \"%s\"." from)
813 (format "buffer `%s'." bufname)))
814 (insert
815 "These default coding systems were tried to encode"
816 (if (stringp from)
817 (concat " \"" (if (> (length from) 10)
818 (concat (substring from 0 10) "...\"")
819 (concat from "\"")))
820 (format " text\nin the buffer `%s'" bufname))
821 ":\n")
822 (let ((pos (point))
823 (fill-prefix " "))
824 (mapc #'(lambda (x) (princ " ") (princ (car x)))
825 default-coding-system)
826 (insert "\n")
827 (fill-region-as-paragraph pos (point)))
828 (when rejected
829 (insert "These safely encodes the target text,
830 but it is not recommended for encoding text in this context,
831 e.g., for sending an email message.\n ")
832 (mapc #'(lambda (x) (princ " ") (princ x)) rejected)
833 (insert "\n"))
834 (when unsafe
835 (insert (if rejected "And the others"
836 "However, each of them")
837 " encountered these problematic characters:\n")
838 (mapc
839 #'(lambda (coding)
840 (insert (format " %s:" (car coding)))
841 (let ((i 0)
842 (func1
843 #'(lambda (bufname pos)
844 (when (buffer-live-p (get-buffer bufname))
845 (pop-to-buffer bufname)
846 (goto-char pos))))
847 (func2
848 #'(lambda (bufname pos coding)
849 (when (buffer-live-p (get-buffer bufname))
850 (pop-to-buffer bufname)
851 (if (< (point) pos)
852 (goto-char pos)
853 (forward-char 1)
854 (search-unencodable-char coding)
855 (forward-char -1))))))
856 (dolist (elt (cdr coding))
857 (insert " ")
858 (if (stringp from)
859 (insert (if (< i 10) (cdr elt) "..."))
860 (if (< i 10)
861 (insert-text-button
862 (cdr elt)
863 :type 'help-xref
864 'help-echo
865 "mouse-2, RET: jump to this character"
866 'help-function func1
867 'help-args (list bufname (car elt)))
868 (insert-text-button
869 "..."
870 :type 'help-xref
871 'help-echo
872 "mouse-2, RET: next unencodable character"
873 'help-function func2
874 'help-args (list bufname (car elt)
875 (car coding)))))
876 (setq i (1+ i))))
877 (insert "\n"))
878 unsafe)
879 (insert "\
880 The first problematic character is at point in the displayed buffer,\n"
881 (substitute-command-keys "\
882 and \\[universal-argument] \\[what-cursor-position] will give information about it.\n"))))
883 (insert (if safe
884 "\nSelect the above, or "
885 "\nSelect ")
886 "\
887 one of the following safe coding systems, or edit the buffer:\n")
888 (let ((pos (point))
889 (fill-prefix " "))
890 (mapcar (function (lambda (x) (princ " ") (princ x)))
891 codings)
892 (insert "\n")
893 (fill-region-as-paragraph pos (point)))
894 (insert "Or specify any other coding system
895 at the risk of losing the problematic characters.\n")))
896
897 ;; Read a coding system.
898 (setq default-coding-system (or (car safe) (car codings)))
899 (setq coding-system
900 (read-coding-system
901 (format "Select coding system (default %s): "
902 default-coding-system)
903 default-coding-system))
904 (setq last-coding-system-specified coding-system))
905
906 (kill-buffer "*Warning*")
907 (set-window-configuration window-configuration)))
908 913
909 (if (vectorp (coding-system-eol-type coding-system)) 914 (if (vectorp (coding-system-eol-type coding-system))
910 (let ((eol (coding-system-eol-type buffer-file-coding-system))) 915 (let ((eol (coding-system-eol-type buffer-file-coding-system)))
911 (if (numberp eol) 916 (if (numberp eol)
912 (setq coding-system 917 (setq coding-system
1882 (string= "The XFree86 Project, Inc" (x-server-vendor)) 1887 (string= "The XFree86 Project, Inc" (x-server-vendor))
1883 (> (aref (number-to-string (nth 2 (x-server-version))) 0) 1888 (> (aref (number-to-string (nth 2 (x-server-version))) 0)
1884 ?3)) 1889 ?3))
1885 ;; We suppress these setting for the moment because the 1890 ;; We suppress these setting for the moment because the
1886 ;; above assumption is wrong. 1891 ;; above assumption is wrong.
1887 ;; (aset standard-display-table ?' [?$,1ry(B]) 1892 ;; (aset standard-display-table ?' [?’])
1888 ;; (aset standard-display-table ?` [?$,1rx(B]) 1893 ;; (aset standard-display-table ?` [?‘])
1889 ;; The fonts don't have the relevant bug. 1894 ;; The fonts don't have the relevant bug.
1890 (aset standard-display-table 160 nil) 1895 (aset standard-display-table 160 nil)
1891 (aset standard-display-table (make-char 'latin-iso8859-1 160) 1896 (aset standard-display-table (make-char 'latin-iso8859-1 160)
1892 nil))))) 1897 nil)))))
1893 1898
2564 ;; and they are the extra control sequences at the tail to 2569 ;; and they are the extra control sequences at the tail to
2565 ;; exclude. 2570 ;; exclude.
2566 (substring enc2 0 i2)))) 2571 (substring enc2 0 i2))))
2567 2572
2568 2573
2569 ;;; arch-tag: b382c432-4b36-460e-bf4c-05efd0bb18dc 2574 ;; arch-tag: b382c432-4b36-460e-bf4c-05efd0bb18dc
2570 ;;; mule-cmds.el ends here 2575 ;;; mule-cmds.el ends here