[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

selecting an inapplicable coding-system

From: Stefan Monnier
Subject: selecting an inapplicable coding-system
Date: Mon, 15 Nov 2004 18:25:12 -0500
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/21.3.50 (gnu/linux)

If I open a new file, insert é and then do the following:

   C-x RET f us-ascii RET
   C-x C-s

the file is saved in latin-1.  This is because when saving
buffer-file-coding-system is just one of several coding-systems used.

Another annoying situation is when you load a utf-8 file containing mostly
latin-1 chars plus a few non-latin-1 chars.  Let's say you don't know that
there are non-latin-1 chars and want to change the file to latin-1.  You do:

   C-x RET f latin-1 RET
   C-x C-s

and the buffer and file is back to utf-8 !?!

I think Emacs should give some feedback at some point between the C-x RET f
and the actual file save that the coding-system specified can't be used.
Ideally, it should also show the offending chars as is done when none of the
default coding systems can be used.

I've been using the patch below for this purpose.

Another problem I've encountered (recently with the iso-2022-7bit ->
utf-8 -> iso-2022-7bit dance in mule-cmds.el) is that iso-2022-7bit cannot
encode eight-bit-control characters, so if you read an iso-2022-7bit file
with invalid sequences in it, you get a buffer that you can't save.
Worse yet, when you try to save it it might say "selected encoding
mule-utf-8 disagrees with iso-2022-7bit-unix specified by file contents" but
if you look at the buffer's modeline it says "J", not "u", so you wonder
what's up with this utf-8 thing.


Index: lisp/international/mule.el
RCS file: /cvsroot/emacs/emacs/lisp/international/mule.el,v
retrieving revision 1.206
diff -u -r1.206 mule.el
--- lisp/international/mule.el  11 Nov 2004 21:39:41 -0000      1.206
+++ lisp/international/mule.el  15 Nov 2004 23:19:43 -0000
@@ -1151,18 +1151,31 @@
 surely saves the buffer with CODING-SYSTEM.  From a program, if you
 don't want to mark the buffer modified, just set the variable
 `buffer-file-coding-system' directly."
+  ;; FIXME: Use find-coding-systems-region to give a subset of all
+  ;; coding-systems in the completion table.  And provide a useful default
+  ;; (e.g. the one that select-safe-coding-system would have chosen, or the
+  ;; next best one if it's already the current coding system).
   (interactive "zCoding system for saving file (default, nil): \nP")
   (check-coding-system coding-system)
-  (if (and coding-system buffer-file-coding-system (null force))
-      (setq coding-system
-           (merge-coding-systems coding-system buffer-file-coding-system)))
-  (setq buffer-file-coding-system coding-system)
+  (let ((cs (if (and coding-system buffer-file-coding-system (null force))
+               (merge-coding-systems coding-system buffer-file-coding-system)
+             coding-system)))
+    (when (interactive-p)
+      ;; Check whether save-buffer would succeed, and if not, jump to the
+      ;; offending char(s) and give the user a chance to change her mind.
+      (let ((css (find-coding-systems-region (point-min) (point-max))))
+       (unless (or (eq (car css) 'undecided)
+                   (memq (coding-system-base cs) css))
+         (setq coding-system (select-safe-coding-system-interactively
+                              (point-min) (point-max) css (list cs)
+                              nil coding-system)))))
+    (setq buffer-file-coding-system cs)
   ;; This is in case of an explicit call.  Normally, `normal-mode' and
   ;; `set-buffer-major-mode-hook' take care of setting the table.
   (if (fboundp 'ucs-set-table-for-input) ; don't lose when building
   (set-buffer-modified-p t)
-  (force-mode-line-update))
+    (force-mode-line-update)))
 (defun revert-buffer-with-coding-system (coding-system &optional force)
   "Visit the current buffer's file again using coding system CODING-SYSTEM.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]