I believe my earlier patch was wrong and that I had misconfigured VM. I'm using Emacs 23 with VM 7.19 in a terminal window that's configured to display utf-8. Everything is now working properly for me. I am no longer using iconv to translate some character sets to utf-8. I set vm-mime-default-face-charsets to T. I no longer set vm-mime-charset-converter-alist. However, I did have to make two small changes to vm-mime.el. First, the code was using the wrong function to get raw bytes from the buffer. Second, VM sets text properties that are strings. The default comparison function that Emacs uses for text properties is EQ, which can return NIL for equivalent strings. Here is the patch that I now believe is correct for VM 7.19 on Emacs 23. Some or all of it may also be needed for VM 8. *** vm-mime.el.~1~ Fri Jun 11 21:59:27 2004 --- vm-mime.el Tue Sep 29 13:38:42 2009 *************** *** 595,607 **** (delete-char -1))))) (setq inputpos start) (while (< inputpos end) ! (setq char (char-after inputpos)) (cond ((= char ?\n) (vm-insert-char char 1 nil work-buffer) (setq cols 0)) ((and (= char 32) (not (= (1+ inputpos) end)) ! (not (= ?\n (char-after (1+ inputpos))))) (vm-insert-char char 1 nil work-buffer) (vm-increment cols)) ((or (< char 33) (> char 126) --- 595,607 ---- (delete-char -1))))) (setq inputpos start) (while (< inputpos end) ! (setq char (get-byte inputpos)) (cond ((= char ?\n) (vm-insert-char char 1 nil work-buffer) (setq cols 0)) ((and (= char 32) (not (= (1+ inputpos) end)) ! (not (= ?\n (get-byte (1+ inputpos))))) (vm-insert-char char 1 nil work-buffer) (vm-increment cols)) ((or (< char 33) (> char 126) *************** *** 777,782 **** --- 777,793 ---- (vm-with-string-as-temp-buffer string 'vm-decode-mime-encoded-words) string )) + (defun vm-next-single-property-change (start property) + "Reimplement NEXT-SINGLE-PROPERTY-CHANGE, but compare properties with + EQUAL instead of EQ. This function is necessary because VM uses text + properties that are strings." + (let ((value (get-text-property start property)) + (next (next-single-property-change start property))) + (if (or (null next) + (not (equal value (get-text-property next property)))) + next + (vm-next-single-property-change next property)))) + (defun vm-reencode-mime-encoded-words () (let ((charset nil) start coding pos q-encoding *************** *** 787,793 **** (setq start (point-min)) (while (not done) (setq charset (get-text-property start 'vm-charset)) ! (setq pos (next-single-property-change start 'vm-charset)) (or pos (setq pos (point-max) done t)) (if charset (progn --- 798,804 ---- (setq start (point-min)) (while (not done) (setq charset (get-text-property start 'vm-charset)) ! (setq pos (vm-next-single-property-change start 'vm-charset)) (or pos (setq pos (point-max) done t)) (if charset (progn ========================= ========================= On Mon, Dec 7, 2009 at 12:02 PM, Ulrich Müller